JACK: detect channel layout based on port names

This commit is contained in:
Andrew Kelley 2015-07-28 14:53:54 -07:00
parent eeae08e1a3
commit 70441184a1
6 changed files with 237 additions and 85 deletions

View file

@ -234,9 +234,6 @@ view `coverage/index.html` in a browser.
0. JACK: input 0. JACK: input
0. Steal PulseAudio's default channel maps per channel count 0. Steal PulseAudio's default channel maps per channel count
0. Ability to parse PulseAudio's "front-left" "front-right" channel label strings
0. When two soundio clients are talking to each other, use port names to
negotiate channel maps.
0. JACK: implement prebuffering 0. JACK: implement prebuffering
0. why does pulseaudio microphone use up all the CPU? 0. why does pulseaudio microphone use up all the CPU?
0. merge in/out stream structures and functions? 0. merge in/out stream structures and functions?

View file

@ -10,14 +10,14 @@
#include <stdio.h> #include <stdio.h>
static struct SoundIoChannelLayout builtin_channel_layouts[] = { static struct SoundIoChannelLayout builtin_channel_layouts[] = {
{ [SoundIoChannelLayoutIdMono] = {
"Mono", "Mono",
1, 1,
{ {
SoundIoChannelIdFrontCenter, SoundIoChannelIdFrontCenter,
}, },
}, },
{ [SoundIoChannelLayoutIdStereo] = {
"Stereo", "Stereo",
2, 2,
{ {
@ -25,7 +25,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdFrontRight, SoundIoChannelIdFrontRight,
}, },
}, },
{ [SoundIoChannelLayoutId2Point1] = {
"2.1", "2.1",
3, 3,
{ {
@ -34,7 +34,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
}, },
}, },
{ [SoundIoChannelLayoutId3Point0] = {
"3.0", "3.0",
3, 3,
{ {
@ -43,7 +43,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdFrontCenter, SoundIoChannelIdFrontCenter,
} }
}, },
{ [SoundIoChannelLayoutId3Point0Back] = {
"3.0 (back)", "3.0 (back)",
3, 3,
{ {
@ -52,7 +52,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackCenter, SoundIoChannelIdBackCenter,
} }
}, },
{ [SoundIoChannelLayoutId3Point1] = {
"3.1", "3.1",
4, 4,
{ {
@ -62,7 +62,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId4Point0] = {
"4.0", "4.0",
4, 4,
{ {
@ -72,7 +72,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackCenter, SoundIoChannelIdBackCenter,
} }
}, },
{ [SoundIoChannelLayoutIdQuad] = {
"Quad", "Quad",
4, 4,
{ {
@ -82,7 +82,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackRight, SoundIoChannelIdBackRight,
}, },
}, },
{ [SoundIoChannelLayoutIdQuadSide] = {
"Quad (side)", "Quad (side)",
4, 4,
{ {
@ -92,7 +92,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdSideRight, SoundIoChannelIdSideRight,
} }
}, },
{ [SoundIoChannelLayoutId4Point1] = {
"4.1", "4.1",
5, 5,
{ {
@ -103,7 +103,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId5Point0] = {
"5.0", "5.0",
5, 5,
{ {
@ -114,7 +114,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdSideRight, SoundIoChannelIdSideRight,
} }
}, },
{ [SoundIoChannelLayoutId5Point0Back] = {
"5.0 (back)", "5.0 (back)",
5, 5,
{ {
@ -125,7 +125,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackRight, SoundIoChannelIdBackRight,
} }
}, },
{ [SoundIoChannelLayoutId5Point1] = {
"5.1", "5.1",
6, 6,
{ {
@ -137,7 +137,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId5Point1Back] = {
"5.1 (back)", "5.1 (back)",
6, 6,
{ {
@ -149,7 +149,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId6Point0] = {
"6.0", "6.0",
6, 6,
{ {
@ -161,7 +161,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackCenter, SoundIoChannelIdBackCenter,
} }
}, },
{ [SoundIoChannelLayoutId6Point0Front] = {
"6.0 (front)", "6.0 (front)",
6, 6,
{ {
@ -173,7 +173,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdFrontRightCenter, SoundIoChannelIdFrontRightCenter,
} }
}, },
{ [SoundIoChannelLayoutIdHexagonal] = {
"Hexagonal", "Hexagonal",
6, 6,
{ {
@ -185,7 +185,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackCenter, SoundIoChannelIdBackCenter,
} }
}, },
{ [SoundIoChannelLayoutId6Point1] = {
"6.1", "6.1",
7, 7,
{ {
@ -198,7 +198,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId6Point1Back] = {
"6.1 (back)", "6.1 (back)",
7, 7,
{ {
@ -211,7 +211,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId6Point1Front] = {
"6.1 (front)", "6.1 (front)",
7, 7,
{ {
@ -224,7 +224,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId7Point0] = {
"7.0", "7.0",
7, 7,
{ {
@ -237,7 +237,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdBackRight, SoundIoChannelIdBackRight,
} }
}, },
{ [SoundIoChannelLayoutId7Point0Front] = {
"7.0 (front)", "7.0 (front)",
7, 7,
{ {
@ -250,7 +250,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdFrontRightCenter, SoundIoChannelIdFrontRightCenter,
} }
}, },
{ [SoundIoChannelLayoutId7Point1] = {
"7.1", "7.1",
8, 8,
{ {
@ -264,7 +264,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId7Point1Wide] = {
"7.1 (wide)", "7.1 (wide)",
8, 8,
{ {
@ -278,7 +278,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutId7Point1WideBack] = {
"7.1 (wide) (back)", "7.1 (wide) (back)",
8, 8,
{ {
@ -292,7 +292,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
SoundIoChannelIdLfe, SoundIoChannelIdLfe,
} }
}, },
{ [SoundIoChannelLayoutIdOctagonal] = {
"Octagonal", "Octagonal",
8, 8,
{ {
@ -308,46 +308,190 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = {
}, },
}; };
const char *soundio_get_channel_name(enum SoundIoChannelId id) { static const int channel_name_alias_count = 3;
switch (id) { static const char *channel_names[][channel_name_alias_count] = {
case SoundIoChannelIdInvalid: return "(Invalid Channel)"; [SoundIoChannelIdInvalid] = {
"(Invalid Channel)",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontLeft] = {
"Front Left",
"FL",
"front-left",
},
[SoundIoChannelIdFrontRight] = {
"Front Right",
"FR",
"front-right",
},
[SoundIoChannelIdFrontCenter] = {
"Front Center",
"FC",
"front-center",
},
[SoundIoChannelIdLfe] = {
"LFE",
"LFE",
"lfe",
},
[SoundIoChannelIdBackLeft] = {
"Back Left",
"BL",
"rear-left",
},
[SoundIoChannelIdBackRight] = {
"Back Right",
"BR",
"rear-right",
},
[SoundIoChannelIdFrontLeftCenter] = {
"Front Left Center",
"FLC",
"front-left-of-center",
},
[SoundIoChannelIdFrontRightCenter] = {
"Front Right Center",
"FRC",
"front-right-of-center",
},
[SoundIoChannelIdBackCenter] = {
"Back Center",
"BC",
"rear-center",
},
[SoundIoChannelIdSideLeft] = {
"Side Left",
"SL",
"side-left",
},
[SoundIoChannelIdSideRight] = {
"Side Right",
"SR",
"side-right",
},
[SoundIoChannelIdTopCenter] = {
"Top Center",
"TC",
"top-center",
},
[SoundIoChannelIdTopFrontLeft] = {
"Top Front Left",
"TFL",
"top-front-left",
},
[SoundIoChannelIdTopFrontCenter] = {
"Top Front Center",
"TFC",
"top-front-center",
},
[SoundIoChannelIdTopFrontRight] = {
"Top Front Right",
"TFR",
"top-front-right",
},
[SoundIoChannelIdTopBackLeft] = {
"Top Back Left",
"TBL",
"top-rear-left",
},
[SoundIoChannelIdTopBackCenter] = {
"Top Back Center",
"TBC",
"top-rear-center",
},
[SoundIoChannelIdTopBackRight] = {
"Top Back Right",
"TBR",
"top-rear-right",
},
[SoundIoChannelIdBackLeftCenter] = {
"Back Left Center",
nullptr,
nullptr,
},
[SoundIoChannelIdBackRightCenter] = {
"Back Right Center",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontLeftWide] = {
"Front Left Wide",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontRightWide] = {
"Front Right Wide",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontLeftHigh] = {
"Front Left High",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontCenterHigh] = {
"Front Center High",
nullptr,
nullptr,
},
[SoundIoChannelIdFrontRightHigh] = {
"Front Right High",
nullptr,
nullptr,
},
[SoundIoChannelIdTopFrontLeftCenter] = {
"Top Front Left Center",
nullptr,
nullptr,
},
[SoundIoChannelIdTopFrontRightCenter] = {
"Top Front Right Center",
nullptr,
nullptr,
},
[SoundIoChannelIdTopSideLeft] = {
"Top Side Left",
nullptr,
nullptr,
},
[SoundIoChannelIdTopSideRight] = {
"Top Side Right",
nullptr,
nullptr,
},
[SoundIoChannelIdLeftLfe] = {
"Left LFE",
nullptr,
nullptr,
},
[SoundIoChannelIdRightLfe] = {
"Right LFE",
nullptr,
nullptr,
},
[SoundIoChannelIdBottomCenter] = {
"Bottom Center",
nullptr,
nullptr,
},
[SoundIoChannelIdBottomLeftCenter] = {
"Bottom Left Center",
nullptr,
nullptr,
},
[SoundIoChannelIdBottomRightCenter] = {
"Bottom Right Center",
nullptr,
nullptr,
},
};
case SoundIoChannelIdFrontLeft: return "Front Left"; const char *soundio_get_channel_name(enum SoundIoChannelId id) {
case SoundIoChannelIdFrontRight: return "Front Right"; if (id < 0 || id > array_length(channel_names))
case SoundIoChannelIdFrontCenter: return "Front Center";
case SoundIoChannelIdLfe: return "LFE";
case SoundIoChannelIdBackLeft: return "Back Left";
case SoundIoChannelIdBackRight: return "Back Right";
case SoundIoChannelIdFrontLeftCenter: return "Front Left Center";
case SoundIoChannelIdFrontRightCenter: return "Front Right Center";
case SoundIoChannelIdBackCenter: return "Back Center";
case SoundIoChannelIdSideLeft: return "Side Left";
case SoundIoChannelIdSideRight: return "Side Right";
case SoundIoChannelIdTopCenter: return "Top Center";
case SoundIoChannelIdTopFrontLeft: return "Top Front Left";
case SoundIoChannelIdTopFrontCenter: return "Top Front Center";
case SoundIoChannelIdTopFrontRight: return "Top Front Right";
case SoundIoChannelIdTopBackLeft: return "Top Back Left";
case SoundIoChannelIdTopBackCenter: return "Top Back Center";
case SoundIoChannelIdTopBackRight: return "Top Back Right";
case SoundIoChannelIdBackLeftCenter: return "Back Left Center";
case SoundIoChannelIdBackRightCenter: return "Back Right Center";
case SoundIoChannelIdFrontLeftWide: return "Front Left Wide";
case SoundIoChannelIdFrontRightWide: return "Front Right Wide";
case SoundIoChannelIdFrontLeftHigh: return "Front Left High";
case SoundIoChannelIdFrontCenterHigh: return "Front Center High";
case SoundIoChannelIdFrontRightHigh: return "Front Right High";
case SoundIoChannelIdTopFrontLeftCenter: return "Top Front Left Center";
case SoundIoChannelIdTopFrontRightCenter: return "Top Front Right Center";
case SoundIoChannelIdTopSideLeft: return "Top Side Left";
case SoundIoChannelIdTopSideRight: return "Top Side Right";
case SoundIoChannelIdLeftLfe: return "Left LFE";
case SoundIoChannelIdRightLfe: return "Right LFE";
case SoundIoChannelIdBottomCenter: return "Bottom Center";
case SoundIoChannelIdBottomLeftCenter: return "Bottom Left Center";
case SoundIoChannelIdBottomRightCenter: return "Bottom Right Center";
}
return "(Invalid Channel)"; return "(Invalid Channel)";
else
return channel_names[id][0];
} }
bool soundio_channel_layout_equal( bool soundio_channel_layout_equal(
@ -412,6 +556,15 @@ const struct SoundIoChannelLayout *soundio_channel_layout_get_default(int channe
} }
enum SoundIoChannelId soundio_parse_channel_id(const char *str, int str_len) { enum SoundIoChannelId soundio_parse_channel_id(const char *str, int str_len) {
// TODO actually parse for (int id = 0; id < array_length(channel_names); id += 1) {
for (int i = 0; i < channel_name_alias_count; i += 1) {
const char *alias = channel_names[id][i];
if (!alias)
break;
int alias_len = strlen(alias);
if (soundio_streql(alias, alias_len, str, str_len))
return (SoundIoChannelId)id;
}
}
return SoundIoChannelIdInvalid; return SoundIoChannelIdInvalid;
} }

View file

@ -351,12 +351,6 @@ static void split_str(const char *input_str, int input_str_len, char c,
} }
} }
static bool eql_str(const char *str1, int str1_len, const char *str2, int str2_len) {
if (str1_len != str2_len)
return false;
return memcmp(str1, str2, str1_len) == 0;
}
static SoundIoJackClient *find_or_create_client(SoundIoList<SoundIoJackClient> *clients, static SoundIoJackClient *find_or_create_client(SoundIoList<SoundIoJackClient> *clients,
SoundIoDevicePurpose purpose, bool is_physical, const char *client_name, int client_name_len) SoundIoDevicePurpose purpose, bool is_physical, const char *client_name, int client_name_len)
{ {
@ -364,7 +358,7 @@ static SoundIoJackClient *find_or_create_client(SoundIoList<SoundIoJackClient> *
SoundIoJackClient *client = &clients->at(i); SoundIoJackClient *client = &clients->at(i);
if (client->is_physical == is_physical && if (client->is_physical == is_physical &&
client->purpose == purpose && client->purpose == purpose &&
eql_str(client->name, client->name_len, client_name, client_name_len)) soundio_streql(client->name, client->name_len, client_name, client_name_len))
{ {
return client; return client;
} }

View file

@ -27,23 +27,23 @@ static const SoundIoBackend available_backends[] = {
}; };
static int (*backend_init_fns[])(SoundIoPrivate *) = { static int (*backend_init_fns[])(SoundIoPrivate *) = {
nullptr, // SoundIoBackendNone [SoundIoBackendNone] = nullptr,
#ifdef SOUNDIO_HAVE_JACK #ifdef SOUNDIO_HAVE_JACK
soundio_jack_init, [SoundIoBackendJack] = soundio_jack_init,
#else #else
nullptr, [SoundIoBackendJack] = nullptr,
#endif #endif
#ifdef SOUNDIO_HAVE_PULSEAUDIO #ifdef SOUNDIO_HAVE_PULSEAUDIO
soundio_pulseaudio_init, [SoundIoBackendPulseAudio] = soundio_pulseaudio_init,
#else #else
nullptr, [SoundIoBackendPulseAudio] = nullptr,
#endif #endif
#ifdef SOUNDIO_HAVE_ALSA #ifdef SOUNDIO_HAVE_ALSA
soundio_alsa_init, [SoundIoBackendAlsa] = soundio_alsa_init,
#else #else
nullptr, [SoundIoBackendAlsa] = nullptr,
#endif #endif
soundio_dummy_init, [SoundIoBackendDummy] = soundio_dummy_init,
}; };
const char *soundio_strerror(int error) { const char *soundio_strerror(int error) {

View file

@ -32,6 +32,7 @@ enum SoundIoError {
}; };
enum SoundIoChannelId { enum SoundIoChannelId {
// These channel ids are more commonly supported.
SoundIoChannelIdInvalid, SoundIoChannelIdInvalid,
SoundIoChannelIdFrontLeft, SoundIoChannelIdFrontLeft,
SoundIoChannelIdFrontRight, SoundIoChannelIdFrontRight,
@ -52,6 +53,7 @@ enum SoundIoChannelId {
SoundIoChannelIdTopBackCenter, SoundIoChannelIdTopBackCenter,
SoundIoChannelIdTopBackRight, SoundIoChannelIdTopBackRight,
// These channel ids are less commonly supported.
SoundIoChannelIdBackLeftCenter, SoundIoChannelIdBackLeftCenter,
SoundIoChannelIdBackRightCenter, SoundIoChannelIdBackRightCenter,
SoundIoChannelIdFrontLeftWide, SoundIoChannelIdFrontLeftWide,
@ -78,9 +80,9 @@ enum SoundIoChannelLayoutId {
SoundIoChannelLayoutId3Point0Back, SoundIoChannelLayoutId3Point0Back,
SoundIoChannelLayoutId3Point1, SoundIoChannelLayoutId3Point1,
SoundIoChannelLayoutId4Point0, SoundIoChannelLayoutId4Point0,
SoundIoChannelLayoutId4Point1,
SoundIoChannelLayoutIdQuad, SoundIoChannelLayoutIdQuad,
SoundIoChannelLayoutIdQuadSide, SoundIoChannelLayoutIdQuadSide,
SoundIoChannelLayoutId4Point1,
SoundIoChannelLayoutId5Point0, SoundIoChannelLayoutId5Point0,
SoundIoChannelLayoutId5Point0Back, SoundIoChannelLayoutId5Point0Back,
SoundIoChannelLayoutId5Point1, SoundIoChannelLayoutId5Point1,

View file

@ -88,6 +88,12 @@ void soundio_panic(const char *format, ...)
char *soundio_alloc_sprintf(int *len, const char *format, ...) char *soundio_alloc_sprintf(int *len, const char *format, ...)
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
static inline bool soundio_streql(const char *str1, int str1_len, const char *str2, int str2_len) {
if (str1_len != str2_len)
return false;
return memcmp(str1, str2, str1_len) == 0;
}
template <typename T, long n> template <typename T, long n>
constexpr long array_length(const T (&)[n]) { constexpr long array_length(const T (&)[n]) {