Commit 9d85ea6d authored by David Reid's avatar David Reid

PulseAudio: Properly handle default format/channels/rate.

parent 9af027d4
...@@ -7352,12 +7352,12 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -7352,12 +7352,12 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
// Channels. // Channels.
mal_uint32 channels = pConfig->channels; unsigned int channels = pConfig->channels;
if (((mal_snd_pcm_hw_params_set_channels_near_proc)pContext->alsa.snd_pcm_hw_params_set_channels_near)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, &channels) < 0) { if (((mal_snd_pcm_hw_params_set_channels_near_proc)pContext->alsa.snd_pcm_hw_params_set_channels_near)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, &channels) < 0) {
mal_device_uninit__alsa(pDevice); mal_device_uninit__alsa(pDevice);
return mal_post_error(pDevice, "[ALSA] Failed to set channel count. snd_pcm_hw_params_set_channels_near() failed.", MAL_FORMAT_NOT_SUPPORTED); return mal_post_error(pDevice, "[ALSA] Failed to set channel count. snd_pcm_hw_params_set_channels_near() failed.", MAL_FORMAT_NOT_SUPPORTED);
} }
pDevice->internalChannels = channels; pDevice->internalChannels = (mal_uint32)channels;
// Sample Rate. It appears there's either a bug in ALSA, a bug in some drivers, or I'm doing something silly; but having resampling // Sample Rate. It appears there's either a bug in ALSA, a bug in some drivers, or I'm doing something silly; but having resampling
...@@ -7377,12 +7377,12 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -7377,12 +7377,12 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
// this error with. In the future, we may want to restrict the disabling of resampling to only known bad plugins. // this error with. In the future, we may want to restrict the disabling of resampling to only known bad plugins.
((mal_snd_pcm_hw_params_set_rate_resample_proc)pContext->alsa.snd_pcm_hw_params_set_rate_resample)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, 0); ((mal_snd_pcm_hw_params_set_rate_resample_proc)pContext->alsa.snd_pcm_hw_params_set_rate_resample)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, 0);
mal_uint32 sampleRate = pConfig->sampleRate; unsigned int sampleRate = pConfig->sampleRate;
if (((mal_snd_pcm_hw_params_set_rate_near_proc)pContext->alsa.snd_pcm_hw_params_set_rate_near)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, &sampleRate, 0) < 0) { if (((mal_snd_pcm_hw_params_set_rate_near_proc)pContext->alsa.snd_pcm_hw_params_set_rate_near)((mal_snd_pcm_t*)pDevice->alsa.pPCM, pHWParams, &sampleRate, 0) < 0) {
mal_device_uninit__alsa(pDevice); mal_device_uninit__alsa(pDevice);
return mal_post_error(pDevice, "[ALSA] Sample rate not supported. snd_pcm_hw_params_set_rate_near() failed.", MAL_FORMAT_NOT_SUPPORTED); return mal_post_error(pDevice, "[ALSA] Sample rate not supported. snd_pcm_hw_params_set_rate_near() failed.", MAL_FORMAT_NOT_SUPPORTED);
} }
pDevice->internalSampleRate = sampleRate; pDevice->internalSampleRate = (mal_uint32)sampleRate;
// Periods. // Periods.
...@@ -8141,6 +8141,7 @@ static mal_result mal_result_from_pulse(int result) ...@@ -8141,6 +8141,7 @@ static mal_result mal_result_from_pulse(int result)
} }
} }
#if 0
static mal_pa_sample_format_t mal_format_to_pulse(mal_format format) static mal_pa_sample_format_t mal_format_to_pulse(mal_format format)
{ {
switch (format) switch (format)
...@@ -8160,6 +8161,7 @@ static mal_pa_sample_format_t mal_format_to_pulse(mal_format format) ...@@ -8160,6 +8161,7 @@ static mal_pa_sample_format_t mal_format_to_pulse(mal_format format)
default: return MAL_PA_SAMPLE_INVALID; default: return MAL_PA_SAMPLE_INVALID;
} }
} }
#endif
static mal_format mal_format_from_pulse(mal_pa_sample_format_t format) static mal_format mal_format_from_pulse(mal_pa_sample_format_t format)
{ {
...@@ -8241,6 +8243,7 @@ static mal_channel mal_channel_position_from_pulse(mal_pa_channel_position_t pos ...@@ -8241,6 +8243,7 @@ static mal_channel mal_channel_position_from_pulse(mal_pa_channel_position_t pos
} }
} }
#if 0
static mal_pa_channel_position_t mal_channel_position_to_pulse(mal_channel position) static mal_pa_channel_position_t mal_channel_position_to_pulse(mal_channel position)
{ {
switch (position) switch (position)
...@@ -8281,6 +8284,7 @@ static mal_pa_channel_position_t mal_channel_position_to_pulse(mal_channel posit ...@@ -8281,6 +8284,7 @@ static mal_pa_channel_position_t mal_channel_position_to_pulse(mal_channel posit
default: return (mal_pa_channel_position_t)position; default: return (mal_pa_channel_position_t)position;
} }
} }
#endif
static mal_result mal_context_uninit__pulse(mal_context* pContext) static mal_result mal_context_uninit__pulse(mal_context* pContext)
...@@ -8672,6 +8676,30 @@ static void mal_pulse_device_read_callback(mal_pa_stream* pStream, size_t sizeIn ...@@ -8672,6 +8676,30 @@ static void mal_pulse_device_read_callback(mal_pa_stream* pStream, size_t sizeIn
} }
} }
static void mal_device_sink_info_callback(mal_pa_context* pPulseContext, const mal_pa_sink_info* pInfo, int endOfList, void* pUserData)
{
if (endOfList > 0) {
return;
}
mal_pa_sink_info* pInfoOut = (mal_pa_sink_info*)pUserData;
mal_assert(pInfoOut != NULL);
*pInfoOut = *pInfo;
}
static void mal_device_source_info_callback(mal_pa_context* pPulseContext, const mal_pa_source_info* pInfo, int endOfList, void* pUserData)
{
if (endOfList > 0) {
return;
}
mal_pa_source_info* pInfoOut = (mal_pa_source_info*)pUserData;
mal_assert(pInfoOut != NULL);
*pInfoOut = *pInfo;
}
static void mal_device_sink_name_callback(mal_pa_context* pPulseContext, const mal_pa_sink_info* pInfo, int endOfList, void* pUserData) static void mal_device_sink_name_callback(mal_pa_context* pPulseContext, const mal_pa_sink_info* pInfo, int endOfList, void* pUserData)
{ {
if (endOfList > 0) { if (endOfList > 0) {
...@@ -8773,17 +8801,65 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type ...@@ -8773,17 +8801,65 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type
} }
} }
const char* dev = NULL;
if (pDeviceID != NULL) {
dev = pDeviceID->pulse;
}
mal_pa_sink_info sinkInfo;
mal_pa_source_info sourceInfo;
mal_pa_operation* pOP = NULL;
if (type == mal_device_type_playback) {
pOP = ((mal_pa_context_get_sink_info_by_name_proc)pContext->pulse.pa_context_get_sink_info_by_name)((mal_pa_context*)pDevice->pulse.pPulseContext, dev, mal_device_sink_info_callback, &sinkInfo);
} else {
pOP = ((mal_pa_context_get_source_info_by_name_proc)pContext->pulse.pa_context_get_source_info_by_name)((mal_pa_context*)pDevice->pulse.pPulseContext, dev, mal_device_source_info_callback, &sourceInfo);
}
if (pOP != NULL) {
mal_device__wait_for_operation__pulse(pDevice, pOP);
((mal_pa_operation_unref_proc)pContext->pulse.pa_operation_unref)(pOP);
}
#if 0
mal_pa_sample_spec deviceSS;
mal_pa_channel_map deviceCMap;
if (type == mal_device_type_playback) {
deviceSS = sinkInfo.sample_spec;
deviceCMap = sinkInfo.channel_map;
} else {
deviceSS = sourceInfo.sample_spec;
deviceCMap = sourceInfo.channel_map;
}
mal_pa_sample_spec ss; mal_pa_sample_spec ss;
if (pDevice->usingDefaultFormat) {
ss.format = deviceSS.format;
} else {
ss.format = mal_format_to_pulse(pConfig->format); ss.format = mal_format_to_pulse(pConfig->format);
}
if (ss.format == MAL_PA_SAMPLE_INVALID) { if (ss.format == MAL_PA_SAMPLE_INVALID) {
ss.format = MAL_PA_SAMPLE_S16LE; ss.format = MAL_PA_SAMPLE_S16LE;
} }
if (pDevice->usingDefaultChannels) {
ss.channels = deviceSS.channels;
} else {
ss.channels = pConfig->channels; ss.channels = pConfig->channels;
}
if (pDevice->usingDefaultSampleRate) {
ss.rate = deviceSS.rate;
} else {
ss.rate = pConfig->sampleRate; ss.rate = pConfig->sampleRate;
}
mal_pa_channel_map cmap; mal_pa_channel_map cmap;
if (pDevice->usingDefaultChannelMap) {
cmap = deviceCMap;
} else {
cmap.channels = pConfig->channels; cmap.channels = pConfig->channels;
for (mal_uint32 iChannel = 0; iChannel < pConfig->channels; ++iChannel) { for (mal_uint32 iChannel = 0; iChannel < pConfig->channels; ++iChannel) {
cmap.map[iChannel] = mal_channel_position_to_pulse(pConfig->channelMap[iChannel]); cmap.map[iChannel] = mal_channel_position_to_pulse(pConfig->channelMap[iChannel]);
...@@ -8792,6 +8868,18 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type ...@@ -8792,6 +8868,18 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type
if (((mal_pa_channel_map_valid_proc)pContext->pulse.pa_channel_map_valid)(&cmap) == 0 || ((mal_pa_channel_map_compatible_proc)pContext->pulse.pa_channel_map_compatible)(&cmap, &ss) == 0) { if (((mal_pa_channel_map_valid_proc)pContext->pulse.pa_channel_map_valid)(&cmap) == 0 || ((mal_pa_channel_map_compatible_proc)pContext->pulse.pa_channel_map_compatible)(&cmap, &ss) == 0) {
((mal_pa_channel_map_init_extend_proc)pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MAL_PA_CHANNEL_MAP_DEFAULT); // The channel map is invalid, so just fall back to the default. ((mal_pa_channel_map_init_extend_proc)pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, MAL_PA_CHANNEL_MAP_DEFAULT); // The channel map is invalid, so just fall back to the default.
} }
}
#else
mal_pa_sample_spec ss;
mal_pa_channel_map cmap;
if (type == mal_device_type_playback) {
ss = sinkInfo.sample_spec;
cmap = sinkInfo.channel_map;
} else {
ss = sourceInfo.sample_spec;
cmap = sourceInfo.channel_map;
}
#endif
mal_pa_buffer_attr attr; mal_pa_buffer_attr attr;
...@@ -8817,10 +8905,7 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type ...@@ -8817,10 +8905,7 @@ static mal_result mal_device_init__pulse(mal_context* pContext, mal_device_type
goto on_error3; goto on_error3;
} }
const char* dev = NULL;
if (pDeviceID != NULL) {
dev = pDeviceID->pulse;
}
if (type == mal_device_type_playback) { if (type == mal_device_type_playback) {
error = ((mal_pa_stream_connect_playback_proc)pContext->pulse.pa_stream_connect_playback)((mal_pa_stream*)pDevice->pulse.pStream, dev, &attr, MAL_PA_STREAM_START_CORKED, NULL, NULL); error = ((mal_pa_stream_connect_playback_proc)pContext->pulse.pa_stream_connect_playback)((mal_pa_stream*)pDevice->pulse.pStream, dev, &attr, MAL_PA_STREAM_START_CORKED, NULL, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment