diff --git a/README.md b/README.md index 4476b09..48a3747 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ view `coverage/index.html` in a browser. - pulseaudio has peek() drop() which sucks, but what if libsoundio lets you specify how much to peek() and if you don't peek all of it, save the unused to a buffer for you. + 0. add len arguments to APIs that have char * ## Planned Uses for libsoundio diff --git a/src/alsa.cpp b/src/alsa.cpp index a84fe08..6e411d0 100644 --- a/src/alsa.cpp +++ b/src/alsa.cpp @@ -15,6 +15,8 @@ static snd_pcm_stream_t stream_types[] = {SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_CAPTURE}; +static const int MAX_SAMPLE_RATE = 48000; + struct SoundIoAlsa { SoundIoOsMutex *mutex; SoundIoOsCond *cond; @@ -81,6 +83,169 @@ static char * str_partition_on_char(char *str, char c) { return nullptr; } +static snd_pcm_stream_t purpose_to_stream(SoundIoDevicePurpose purpose) { + switch (purpose) { + case SoundIoDevicePurposeOutput: return SND_PCM_STREAM_PLAYBACK; + case SoundIoDevicePurposeInput: return SND_PCM_STREAM_CAPTURE; + } + soundio_panic("invalid purpose"); +} + +static SoundIoChannelId from_alsa_chmap_pos(unsigned int pos) { + switch ((snd_pcm_chmap_position)pos) { + case SND_CHMAP_UNKNOWN: return SoundIoChannelIdInvalid; + case SND_CHMAP_NA: return SoundIoChannelIdInvalid; + case SND_CHMAP_MONO: return SoundIoChannelIdFrontCenter; + case SND_CHMAP_FL: return SoundIoChannelIdFrontLeft; // front left + case SND_CHMAP_FR: return SoundIoChannelIdFrontRight; // front right + case SND_CHMAP_RL: return SoundIoChannelIdBackLeft; // rear left + case SND_CHMAP_RR: return SoundIoChannelIdBackRight; // rear right + case SND_CHMAP_FC: return SoundIoChannelIdFrontCenter; // front center + case SND_CHMAP_LFE: return SoundIoChannelIdLfe; // LFE + case SND_CHMAP_SL: return SoundIoChannelIdSideLeft; // side left + case SND_CHMAP_SR: return SoundIoChannelIdSideRight; // side right + case SND_CHMAP_RC: return SoundIoChannelIdBackCenter; // rear center + case SND_CHMAP_FLC: return SoundIoChannelIdFrontLeftCenter; // front left center + case SND_CHMAP_FRC: return SoundIoChannelIdFrontRightCenter; // front right center + case SND_CHMAP_RLC: return SoundIoChannelIdBackLeftCenter; // rear left center + case SND_CHMAP_RRC: return SoundIoChannelIdBackRightCenter; // rear right center + case SND_CHMAP_FLW: return SoundIoChannelIdFrontLeftWide; // front left wide + case SND_CHMAP_FRW: return SoundIoChannelIdFrontRightWide; // front right wide + case SND_CHMAP_FLH: return SoundIoChannelIdFrontLeftHigh; // front left high + case SND_CHMAP_FCH: return SoundIoChannelIdFrontCenterHigh; // front center high + case SND_CHMAP_FRH: return SoundIoChannelIdFrontRightHigh; // front right high + case SND_CHMAP_TC: return SoundIoChannelIdTopCenter; // top center + case SND_CHMAP_TFL: return SoundIoChannelIdTopFrontLeft; // top front left + case SND_CHMAP_TFR: return SoundIoChannelIdTopFrontRight; // top front right + case SND_CHMAP_TFC: return SoundIoChannelIdTopFrontCenter; // top front center + case SND_CHMAP_TRL: return SoundIoChannelIdTopBackLeft; // top rear left + case SND_CHMAP_TRR: return SoundIoChannelIdTopBackRight; // top rear right + case SND_CHMAP_TRC: return SoundIoChannelIdTopBackCenter; // top rear center + case SND_CHMAP_TFLC: return SoundIoChannelIdTopFrontLeftCenter; // top front left center + case SND_CHMAP_TFRC: return SoundIoChannelIdTopFrontRightCenter; // top front right center + case SND_CHMAP_TSL: return SoundIoChannelIdTopSideLeft; // top side left + case SND_CHMAP_TSR: return SoundIoChannelIdTopSideRight; // top side right + case SND_CHMAP_LLFE: return SoundIoChannelIdLeftLfe; // left LFE + case SND_CHMAP_RLFE: return SoundIoChannelIdRightLfe; // right LFE + case SND_CHMAP_BC: return SoundIoChannelIdBottomCenter; // bottom center + case SND_CHMAP_BLC: return SoundIoChannelIdBottomLeftCenter; // bottom left center + case SND_CHMAP_BRC: return SoundIoChannelIdBottomRightCenter; // bottom right center + } + return SoundIoChannelIdInvalid; +} + +static void get_channel_layout(SoundIoDevice *device, snd_pcm_chmap_t *chmap) { + int channel_count = min((unsigned int)SOUNDIO_MAX_CHANNELS, chmap->channels); + device->channel_layout.channel_count = channel_count; + device->channel_layout.name = nullptr; + for (int i = 0; i < channel_count; i += 1) { + device->channel_layout.channels[i] = from_alsa_chmap_pos(chmap->pos[i]); + } + soundio_channel_layout_detect_builtin(&device->channel_layout); +} + +static void handle_channel_maps(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { + if (!maps) + return; + snd_pcm_chmap_query_t **p; + snd_pcm_chmap_query_t *v; + snd_pcm_chmap_t *best = nullptr; + for (p = maps; (v = *p); p += 1) { + if (!best || v->map.channels > best->channels) + best = &v->map; + } + get_channel_layout(device, best); + snd_pcm_free_chmaps(maps); +} + +static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { + int err; + snd_pcm_t *handle; + + snd_pcm_hw_params_t *hwparams; + snd_pcm_sw_params_t *swparams; + + snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_sw_params_alloca(&swparams); + + snd_pcm_stream_t stream = purpose_to_stream(device->purpose); + + if ((err = snd_pcm_open(&handle, device->name, stream, 0)) < 0) { + handle_channel_maps(device, maps); + return SoundIoErrorOpeningDevice; + } + + if ((err = snd_pcm_hw_params_any(handle, hwparams)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + + // disable hardware resampling because we're trying to probe + if ((err = snd_pcm_hw_params_set_rate_resample(handle, hwparams, 0)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + + if ((err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + + unsigned int channel_count; + if ((err = snd_pcm_hw_params_set_channels_last(handle, hwparams, &channel_count)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + + unsigned int min_sample_rate; + unsigned int max_sample_rate; + int min_dir; + int max_dir; + + if ((err = snd_pcm_hw_params_get_rate_max(hwparams, &max_sample_rate, &max_dir)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + if (max_dir < 0) + max_sample_rate -= 1; + + if ((err = snd_pcm_hw_params_get_rate_min(hwparams, &min_sample_rate, &min_dir)) < 0) { + snd_pcm_close(handle); + return SoundIoErrorOpeningDevice; + } + if (min_dir > 0) + min_sample_rate += 1; + + + + snd_pcm_chmap_t *chmap = snd_pcm_get_chmap(handle); + if (chmap) { + get_channel_layout(device, chmap); + free(chmap); + } else if (!maps) { + maps = snd_pcm_query_chmaps(handle); + } + handle_channel_maps(device, maps); + + + device->sample_rate_min = min_sample_rate; + device->sample_rate_min = max_sample_rate; + device->sample_rate_default = + (min_sample_rate <= MAX_SAMPLE_RATE && + MAX_SAMPLE_RATE <= max_sample_rate) ? MAX_SAMPLE_RATE : max_sample_rate; + + + snd_pcm_close(handle); + return 0; + + // TODO: device->default_sample_format + // TODO: device->default_latency +} + +static inline bool str_has_prefix(const char *big_str, const char *prefix) { + return strncmp(big_str, prefix, strlen(prefix)) == 0; +} + static int refresh_devices(SoundIo *soundio) { SoundIoAlsa *sia = (SoundIoAlsa *)soundio->backend_data; @@ -173,12 +338,6 @@ static int refresh_devices(SoundIo *soundio) { return SoundIoErrorNoMem; } - - // TODO: device->channel_layout - // TODO: device->default_sample_format - // TODO: device->default_latency - // TODO: device->default_sample_rate - SoundIoList *device_list; if (stream == SND_PCM_STREAM_PLAYBACK) { device->purpose = SoundIoDevicePurposeOutput; @@ -193,6 +352,8 @@ static int refresh_devices(SoundIo *soundio) { devices_info->default_input_index = device_list->length; } + probe_device(device, nullptr); + if (device_list->append(device)) { soundio_device_unref(device); free(name); @@ -289,11 +450,6 @@ static int refresh_devices(SoundIo *soundio) { return SoundIoErrorNoMem; } - // TODO: device->channel_layout - // TODO: device->default_sample_format - // TODO: device->default_latency - // TODO: device->default_sample_rate - SoundIoList *device_list; if (stream == SND_PCM_STREAM_PLAYBACK) { device->purpose = SoundIoDevicePurposeOutput; @@ -304,6 +460,9 @@ static int refresh_devices(SoundIo *soundio) { device_list = &devices_info->input_devices; } + snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps_from_hw(card_index, device_index, -1, stream); + probe_device(device, maps); + if (device_list->append(device)) { soundio_device_unref(device); destroy(devices_info); diff --git a/src/channel_layout.cpp b/src/channel_layout.cpp index 78a2021..8148f65 100644 --- a/src/channel_layout.cpp +++ b/src/channel_layout.cpp @@ -31,7 +31,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { { SoundIoChannelIdFrontLeft, SoundIoChannelIdFrontRight, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, }, }, { @@ -59,7 +59,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontLeft, SoundIoChannelIdFrontRight, SoundIoChannelIdFrontCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -79,7 +79,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontLeft, SoundIoChannelIdFrontRight, SoundIoChannelIdFrontCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -133,7 +133,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontCenter, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -145,7 +145,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontCenter, SoundIoChannelIdBackLeft, SoundIoChannelIdBackRight, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -168,8 +168,8 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontRight, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, } }, { @@ -194,7 +194,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, SoundIoChannelIdBackCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -207,7 +207,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdBackLeft, SoundIoChannelIdBackRight, SoundIoChannelIdBackCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -218,9 +218,9 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontRight, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, + SoundIoChannelIdLfe, } }, { @@ -245,8 +245,8 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontCenter, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, } }, { @@ -260,7 +260,7 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdSideRight, SoundIoChannelIdBackLeft, SoundIoChannelIdBackRight, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, } }, { @@ -272,9 +272,9 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontCenter, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, + SoundIoChannelIdLfe, } }, { @@ -286,9 +286,9 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { SoundIoChannelIdFrontCenter, SoundIoChannelIdBackLeft, SoundIoChannelIdBackRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, + SoundIoChannelIdLfe, } }, { @@ -307,6 +307,49 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { }, }; +const char *soundio_get_channel_name(enum SoundIoChannelId id) { + switch (id) { + case SoundIoChannelIdInvalid: return "(Invalid Channel)"; + case SoundIoChannelIdCount: return "(Invalid Channel)"; + + case SoundIoChannelIdFrontLeft: return "Front Left"; + case SoundIoChannelIdFrontRight: return "Front Right"; + 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)"; +} + bool soundio_channel_layout_equal( const struct SoundIoChannelLayout *a, const struct SoundIoChannelLayout *b) @@ -322,33 +365,6 @@ bool soundio_channel_layout_equal( return true; } -const char *soundio_get_channel_name(enum SoundIoChannelId id) { - switch (id) { - case SoundIoChannelIdInvalid: return "(Invalid Channel)"; - case SoundIoChannelIdCount: return "(Invalid Channel)"; - - case SoundIoChannelIdFrontLeft: return "Front Left"; - case SoundIoChannelIdFrontRight: return "Front Right"; - case SoundIoChannelIdFrontCenter: return "Front Center"; - case SoundIoChannelIdLowFrequency: return "Low Frequency"; - case SoundIoChannelIdBackLeft: return "Back Left"; - case SoundIoChannelIdBackRight: return "Back Right"; - case SoundIoChannelIdFrontLeftOfCenter: return "Front Left of Center"; - case SoundIoChannelIdFrontRightOfCenter: return "Front Right of 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"; - } - return "(Invalid Channel)"; -} - int soundio_channel_layout_builtin_count(void) { return array_length(builtin_channel_layouts); } @@ -381,3 +397,13 @@ int soundio_channel_layout_find_channel( return -1; } +bool soundio_channel_layout_detect_builtin(struct SoundIoChannelLayout *layout) { + for (int i = 0; i < array_length(builtin_channel_layouts); i += 1) { + const struct SoundIoChannelLayout *builtin_layout = &builtin_channel_layouts[i]; + if (soundio_channel_layout_equal(builtin_layout, layout)) { + layout->name = builtin_layout->name; + return true; + } + } + return false; +} diff --git a/src/dummy.cpp b/src/dummy.cpp index 9c7d05a..abc6ece 100644 --- a/src/dummy.cpp +++ b/src/dummy.cpp @@ -297,7 +297,7 @@ int soundio_dummy_init(SoundIo *soundio) { device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono); device->default_sample_format = SoundIoSampleFormatFloat; device->default_latency = 0.01; - device->default_sample_rate = 48000; + device->sample_rate_default = 48000; device->purpose = SoundIoDevicePurposeOutput; if (soundio->safe_devices_info->output_devices.append(device)) { @@ -327,7 +327,7 @@ int soundio_dummy_init(SoundIo *soundio) { device->channel_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono); device->default_sample_format = SoundIoSampleFormatFloat; device->default_latency = 0.01; - device->default_sample_rate = 48000; + device->sample_rate_default = 48000; device->purpose = SoundIoDevicePurposeInput; if (soundio->safe_devices_info->input_devices.append(device)) { diff --git a/src/pulseaudio.cpp b/src/pulseaudio.cpp index 438856f..2b6d536 100644 --- a/src/pulseaudio.cpp +++ b/src/pulseaudio.cpp @@ -161,9 +161,9 @@ static SoundIoChannelId from_pulseaudio_channel_pos(pa_channel_position_t pos) { case PA_CHANNEL_POSITION_REAR_CENTER: return SoundIoChannelIdBackCenter; case PA_CHANNEL_POSITION_REAR_LEFT: return SoundIoChannelIdBackLeft; case PA_CHANNEL_POSITION_REAR_RIGHT: return SoundIoChannelIdBackRight; - case PA_CHANNEL_POSITION_LFE: return SoundIoChannelIdLowFrequency; - case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: return SoundIoChannelIdFrontLeftOfCenter; - case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: return SoundIoChannelIdFrontRightOfCenter; + case PA_CHANNEL_POSITION_LFE: return SoundIoChannelIdLfe; + case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: return SoundIoChannelIdFrontLeftCenter; + case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: return SoundIoChannelIdFrontRightCenter; case PA_CHANNEL_POSITION_SIDE_LEFT: return SoundIoChannelIdSideLeft; case PA_CHANNEL_POSITION_SIDE_RIGHT: return SoundIoChannelIdSideRight; case PA_CHANNEL_POSITION_TOP_CENTER: return SoundIoChannelIdTopCenter; @@ -268,7 +268,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout); device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec); device->default_latency = usec_to_sec(info->configured_latency); - device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec); + device->sample_rate_default = sample_rate_from_pulseaudio(info->sample_spec); device->purpose = SoundIoDevicePurposeOutput; if (sipa->current_devices_info->output_devices.append(device)) @@ -297,7 +297,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout); device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec); device->default_latency = usec_to_sec(info->configured_latency); - device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec); + device->sample_rate_default = sample_rate_from_pulseaudio(info->sample_spec); device->purpose = SoundIoDevicePurposeInput; if (sipa->current_devices_info->input_devices.append(device)) @@ -445,47 +445,46 @@ static pa_sample_format_t to_pulseaudio_sample_format(SoundIoSampleFormat sample static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_id) { switch (channel_id) { - case SoundIoChannelIdInvalid: + case SoundIoChannelIdFrontLeft: return PA_CHANNEL_POSITION_FRONT_LEFT; + case SoundIoChannelIdFrontRight: return PA_CHANNEL_POSITION_FRONT_RIGHT; + case SoundIoChannelIdFrontCenter: return PA_CHANNEL_POSITION_FRONT_CENTER; + case SoundIoChannelIdLfe: return PA_CHANNEL_POSITION_LFE; + case SoundIoChannelIdBackLeft: return PA_CHANNEL_POSITION_REAR_LEFT; + case SoundIoChannelIdBackRight: return PA_CHANNEL_POSITION_REAR_RIGHT; + case SoundIoChannelIdFrontLeftCenter: return PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; + case SoundIoChannelIdFrontRightCenter: return PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; + case SoundIoChannelIdBackCenter: return PA_CHANNEL_POSITION_REAR_CENTER; + case SoundIoChannelIdSideLeft: return PA_CHANNEL_POSITION_SIDE_LEFT; + case SoundIoChannelIdSideRight: return PA_CHANNEL_POSITION_SIDE_RIGHT; + case SoundIoChannelIdTopCenter: return PA_CHANNEL_POSITION_TOP_CENTER; + case SoundIoChannelIdTopFrontLeft: return PA_CHANNEL_POSITION_TOP_FRONT_LEFT; + case SoundIoChannelIdTopFrontCenter: return PA_CHANNEL_POSITION_TOP_FRONT_CENTER; + case SoundIoChannelIdTopFrontRight: return PA_CHANNEL_POSITION_TOP_FRONT_RIGHT; + case SoundIoChannelIdTopBackLeft: return PA_CHANNEL_POSITION_TOP_REAR_LEFT; + case SoundIoChannelIdTopBackCenter: return PA_CHANNEL_POSITION_TOP_REAR_CENTER; + case SoundIoChannelIdTopBackRight: return PA_CHANNEL_POSITION_TOP_REAR_RIGHT; + case SoundIoChannelIdCount: - soundio_panic("invalid channel id"); - case SoundIoChannelIdFrontLeft: - return PA_CHANNEL_POSITION_FRONT_LEFT; - case SoundIoChannelIdFrontRight: - return PA_CHANNEL_POSITION_FRONT_RIGHT; - case SoundIoChannelIdFrontCenter: - return PA_CHANNEL_POSITION_FRONT_CENTER; - case SoundIoChannelIdLowFrequency: - return PA_CHANNEL_POSITION_LFE; - case SoundIoChannelIdBackLeft: - return PA_CHANNEL_POSITION_REAR_LEFT; - case SoundIoChannelIdBackRight: - return PA_CHANNEL_POSITION_REAR_RIGHT; - case SoundIoChannelIdFrontLeftOfCenter: - return PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; - case SoundIoChannelIdFrontRightOfCenter: - return PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; - case SoundIoChannelIdBackCenter: - return PA_CHANNEL_POSITION_REAR_CENTER; - case SoundIoChannelIdSideLeft: - return PA_CHANNEL_POSITION_SIDE_LEFT; - case SoundIoChannelIdSideRight: - return PA_CHANNEL_POSITION_SIDE_RIGHT; - case SoundIoChannelIdTopCenter: - return PA_CHANNEL_POSITION_TOP_CENTER; - case SoundIoChannelIdTopFrontLeft: - return PA_CHANNEL_POSITION_TOP_FRONT_LEFT; - case SoundIoChannelIdTopFrontCenter: - return PA_CHANNEL_POSITION_TOP_FRONT_CENTER; - case SoundIoChannelIdTopFrontRight: - return PA_CHANNEL_POSITION_TOP_FRONT_RIGHT; - case SoundIoChannelIdTopBackLeft: - return PA_CHANNEL_POSITION_TOP_REAR_LEFT; - case SoundIoChannelIdTopBackCenter: - return PA_CHANNEL_POSITION_TOP_REAR_CENTER; - case SoundIoChannelIdTopBackRight: - return PA_CHANNEL_POSITION_TOP_REAR_RIGHT; + case SoundIoChannelIdInvalid: + case SoundIoChannelIdBackLeftCenter: + case SoundIoChannelIdBackRightCenter: + case SoundIoChannelIdFrontLeftWide: + case SoundIoChannelIdFrontRightWide: + case SoundIoChannelIdFrontLeftHigh: + case SoundIoChannelIdFrontCenterHigh: + case SoundIoChannelIdFrontRightHigh: + case SoundIoChannelIdTopFrontLeftCenter: + case SoundIoChannelIdTopFrontRightCenter: + case SoundIoChannelIdTopSideLeft: + case SoundIoChannelIdTopSideRight: + case SoundIoChannelIdLeftLfe: + case SoundIoChannelIdRightLfe: + case SoundIoChannelIdBottomCenter: + case SoundIoChannelIdBottomLeftCenter: + case SoundIoChannelIdBottomRightCenter: + return PA_CHANNEL_POSITION_INVALID; } - soundio_panic("invalid channel id"); + return PA_CHANNEL_POSITION_INVALID; } static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *channel_layout) { diff --git a/src/soundio.cpp b/src/soundio.cpp index 5c6c201..2c1f2b0 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -228,7 +228,7 @@ const struct SoundIoChannelLayout *soundio_device_channel_layout(const struct So } int soundio_device_sample_rate(const struct SoundIoDevice *device) { - return device->default_sample_rate; + return device->sample_rate_default; } void soundio_device_unref(struct SoundIoDevice *device) { diff --git a/src/soundio.h b/src/soundio.h index cfcc51d..35826b9 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -32,11 +32,11 @@ enum SoundIoChannelId { SoundIoChannelIdFrontLeft, SoundIoChannelIdFrontRight, SoundIoChannelIdFrontCenter, - SoundIoChannelIdLowFrequency, + SoundIoChannelIdLfe, SoundIoChannelIdBackLeft, SoundIoChannelIdBackRight, - SoundIoChannelIdFrontLeftOfCenter, - SoundIoChannelIdFrontRightOfCenter, + SoundIoChannelIdFrontLeftCenter, + SoundIoChannelIdFrontRightCenter, SoundIoChannelIdBackCenter, SoundIoChannelIdSideLeft, SoundIoChannelIdSideRight, @@ -48,6 +48,23 @@ enum SoundIoChannelId { SoundIoChannelIdTopBackCenter, SoundIoChannelIdTopBackRight, + SoundIoChannelIdBackLeftCenter, + SoundIoChannelIdBackRightCenter, + SoundIoChannelIdFrontLeftWide, + SoundIoChannelIdFrontRightWide, + SoundIoChannelIdFrontLeftHigh, + SoundIoChannelIdFrontCenterHigh, + SoundIoChannelIdFrontRightHigh, + SoundIoChannelIdTopFrontLeftCenter, + SoundIoChannelIdTopFrontRightCenter, + SoundIoChannelIdTopSideLeft, + SoundIoChannelIdTopSideRight, + SoundIoChannelIdLeftLfe, + SoundIoChannelIdRightLfe, + SoundIoChannelIdBottomCenter, + SoundIoChannelIdBottomLeftCenter, + SoundIoChannelIdBottomRightCenter, + SoundIoChannelIdCount, }; @@ -121,7 +138,10 @@ struct SoundIoDevice { // whether something worked until you try it. // these values can be unknown enum SoundIoSampleFormat default_sample_format; - int default_sample_rate; + + int sample_rate_min; + int sample_rate_max; + int sample_rate_default; double default_latency; enum SoundIoDevicePurpose purpose; @@ -232,6 +252,10 @@ void soundio_debug_print_channel_layout(const struct SoundIoChannelLayout *layou int soundio_channel_layout_find_channel( const struct SoundIoChannelLayout *layout, enum SoundIoChannelId channel); +// merely populates the name field of layout if it matches a builtin one. +// returns whether it found a match +bool soundio_channel_layout_detect_builtin(struct SoundIoChannelLayout *layout); + // Sample Formats diff --git a/src/util.hpp b/src/util.hpp index a619d06..2f64051 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -103,9 +103,4 @@ template static inline T min(T a, T b) { return (a <= b) ? a : b; } - -static inline bool str_has_prefix(const char *big_str, const char *prefix) { - return strncmp(big_str, prefix, strlen(prefix)) == 0; -} - #endif