summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modules/alsa/alsa-util.c126
-rw-r--r--src/modules/alsa/alsa-util.h1
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;