diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/alsa/alsa-util.c | 126 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.h | 1 |
2 files changed, 90 insertions, 37 deletions
diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 18d6880e..a3a04508 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -528,7 +528,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min) { static const struct pa_alsa_profile_info device_table[] = { {{ 1, { PA_CHANNEL_POSITION_MONO }}, - "hw", + "hw", NULL, N_("Analog Mono"), "analog-mono", 1, @@ -536,7 +536,7 @@ static const struct pa_alsa_profile_info device_table[] = { "Capture", "Mic" }, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, - "front", + "front", "hw", N_("Analog Stereo"), "analog-stereo", 10, @@ -544,7 +544,7 @@ static const struct pa_alsa_profile_info device_table[] = { "Capture", "Mic" }, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, - "iec958", + "iec958", NULL, N_("Digital Stereo (IEC958)"), "iec958-stereo", 5, @@ -552,7 +552,7 @@ static const struct pa_alsa_profile_info device_table[] = { "IEC958 In", NULL }, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, - "hdmi", + "hdmi", NULL, N_("Digital Stereo (HDMI)"), "hdmi-stereo", 4, @@ -561,7 +561,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, - "surround40", + "surround40", NULL, N_("Analog Surround 4.0"), "analog-surround-40", 7, @@ -570,7 +570,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, - "a52", + "a52", NULL, N_("Digital Surround 4.0 (IEC958/AC3)"), "iec958-ac3-surround-40", 2, @@ -580,7 +580,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_LFE }}, - "surround41", + "surround41", NULL, N_("Analog Surround 4.1"), "analog-surround-41", 7, @@ -590,7 +590,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_CENTER }}, - "surround50", + "surround50", NULL, N_("Analog Surround 5.0"), "analog-surround-50", 7, @@ -600,7 +600,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE }}, - "surround51", + "surround51", NULL, N_("Analog Surround 5.1"), "analog-surround-51", 8, @@ -610,7 +610,7 @@ static const struct pa_alsa_profile_info device_table[] = { {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE}}, - "a52", + "a52", NULL, N_("Digital Surround 5.1 (IEC958/AC3)"), "iec958-ac3-surround-51", 3, @@ -621,16 +621,72 @@ static const struct pa_alsa_profile_info device_table[] = { PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE, PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT }}, - "surround71", + "surround71", NULL, N_("Analog Surround 7.1"), "analog-surround-71", 7, "Master", "PCM", "Capture", "Mic" }, - {{ 0, { 0 }}, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL } + {{ 0, { 0 }}, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL } }; +static snd_pcm_t *open_by_device_string_with_fallback( + const char *prefix, + const char *prefix_fallback, + const char *dev_id, + char **dev, + pa_sample_spec *ss, + pa_channel_map* map, + int mode, + uint32_t *nfrags, + snd_pcm_uframes_t *period_size, + snd_pcm_uframes_t tsched_size, + pa_bool_t *use_mmap, + pa_bool_t *use_tsched, + pa_bool_t require_exact_channel_number) { + + snd_pcm_t *pcm_handle; + char *d; + + d = pa_sprintf_malloc("%s:%s", prefix, dev_id); + + pcm_handle = pa_alsa_open_by_device_string( + d, + dev, + ss, + map, + mode, + nfrags, + period_size, + tsched_size, + use_mmap, + use_tsched, + require_exact_channel_number); + pa_xfree(d); + + if (!pcm_handle && prefix_fallback) { + + d = pa_sprintf_malloc("%s:%s", prefix_fallback, dev_id); + + pcm_handle = pa_alsa_open_by_device_string( + d, + dev, + ss, + map, + mode, + nfrags, + period_size, + tsched_size, + use_mmap, + use_tsched, + require_exact_channel_number); + pa_xfree(d); + } + + return pcm_handle; +} + snd_pcm_t *pa_alsa_open_by_device_id_auto( const char *dev_id, char **dev, @@ -671,14 +727,14 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( pa_log_debug("Checking for %s (%s)", device_table[i].name, device_table[i].alsa_name); - d = pa_sprintf_malloc("%s:%s", device_table[i].alsa_name, dev_id); - try_ss.channels = device_table[i].map.channels; try_ss.rate = ss->rate; try_ss.format = ss->format; - pcm_handle = pa_alsa_open_by_device_string( - d, + pcm_handle = open_by_device_string_with_fallback( + device_table[i].alsa_name, + device_table[i].alsa_name_fallback, + dev_id, dev, &try_ss, map, @@ -690,8 +746,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( use_tsched, TRUE); - pa_xfree(d); - if (pcm_handle) { *ss = try_ss; @@ -703,6 +757,7 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto( return pcm_handle; } + } if (direction > 0) { @@ -775,7 +830,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile( pa_bool_t *use_tsched, const pa_alsa_profile_info *profile) { - char *d; snd_pcm_t *pcm_handle; pa_sample_spec try_ss; @@ -787,14 +841,14 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile( pa_assert(period_size); pa_assert(profile); - d = pa_sprintf_malloc("%s:%s", profile->alsa_name, dev_id); - try_ss.channels = profile->map.channels; try_ss.rate = ss->rate; try_ss.format = ss->format; - pcm_handle = pa_alsa_open_by_device_string( - d, + pcm_handle = open_by_device_string_with_fallback( + profile->alsa_name, + profile->alsa_name_fallback, + dev_id, dev, &try_ss, map, @@ -806,8 +860,6 @@ snd_pcm_t *pa_alsa_open_by_device_id_profile( use_tsched, TRUE); - pa_xfree(d); - if (!pcm_handle) return NULL; @@ -860,6 +912,8 @@ snd_pcm_t *pa_alsa_open_by_device_string( goto fail; } + pa_log_debug("Managed to open %s", d); + if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, require_exact_channel_number)) < 0) { if (!reformat) { @@ -928,26 +982,25 @@ int pa_alsa_probe_profiles( snd_pcm_t *pcm_i = NULL; if (i->alsa_name) { - char *id; pa_sample_spec try_ss; pa_channel_map try_map; pa_log_debug("Checking for playback on %s (%s)", i->name, i->alsa_name); - id = pa_sprintf_malloc("%s:%s", i->alsa_name, dev_id); try_ss = *ss; try_ss.channels = i->map.channels; try_map = i->map; - pcm_i = pa_alsa_open_by_device_string( - id, NULL, + pcm_i = open_by_device_string_with_fallback( + i->alsa_name, + i->alsa_name_fallback, + dev_id, + NULL, &try_ss, &try_map, SND_PCM_STREAM_PLAYBACK, NULL, NULL, 0, NULL, NULL, TRUE); - pa_xfree(id); - if (!pcm_i) continue; } @@ -956,26 +1009,25 @@ int pa_alsa_probe_profiles( snd_pcm_t *pcm_j = NULL; if (j->alsa_name) { - char *jd; pa_sample_spec try_ss; pa_channel_map try_map; pa_log_debug("Checking for capture on %s (%s)", j->name, j->alsa_name); - jd = pa_sprintf_malloc("%s:%s", j->alsa_name, dev_id); try_ss = *ss; try_ss.channels = j->map.channels; try_map = j->map; - pcm_j = pa_alsa_open_by_device_string( - jd, NULL, + pcm_j = open_by_device_string_with_fallback( + j->alsa_name, + j->alsa_name_fallback, + dev_id, + NULL, &try_ss, &try_map, SND_PCM_STREAM_CAPTURE, NULL, NULL, 0, NULL, NULL, TRUE); - pa_xfree(jd); - if (!pcm_j) continue; } diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 77ac8a7f..4c5d336d 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -56,6 +56,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min); typedef struct pa_alsa_profile_info { pa_channel_map map; const char *alsa_name; + const char *alsa_name_fallback; const char *description; /* internationalized */ const char *name; unsigned priority; |