alsa: store mixer controls to use in profile data

This allows us to easily use different mixer controls for analog and
spdif output.
This commit is contained in:
Lennart Poettering 2009-04-13 22:46:39 +02:00
parent 89f74cb858
commit 6fd8fd18c2
4 changed files with 48 additions and 19 deletions

View file

@ -1664,7 +1664,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
/* ALSA might tweak the sample spec, so recalculate the frame size */ /* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss); frame_size = pa_frame_size(&ss);
pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL)); pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL), profile);
pa_sink_new_data_init(&data); pa_sink_new_data_init(&data);
data.driver = driver; data.driver = driver;

View file

@ -1519,7 +1519,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
/* ALSA might tweak the sample spec, so recalculate the frame size */ /* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss); frame_size = pa_frame_size(&ss);
pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL)); pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL), profile);
pa_source_new_data_init(&data); pa_source_new_data_init(&data);
data.driver = driver; data.driver = driver;

View file

@ -529,39 +529,51 @@ static const struct pa_alsa_profile_info device_table[] = {
"hw", "hw",
N_("Analog Mono"), N_("Analog Mono"),
"analog-mono", "analog-mono",
1 }, 1,
"Master", "PCM",
"Capture", "Mic" },
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
"front", "front",
N_("Analog Stereo"), N_("Analog Stereo"),
"analog-stereo", "analog-stereo",
10 }, 10,
"Master", "PCM",
"Capture", "Mic" },
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
"iec958", "iec958",
N_("Digital Stereo (IEC958)"), N_("Digital Stereo (IEC958)"),
"iec958-stereo", "iec958-stereo",
5 }, 5,
"IEC958", NULL,
"IEC958 In", NULL },
{{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }}, {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT }},
"hdmi", "hdmi",
N_("Digital Stereo (HDMI)"), N_("Digital Stereo (HDMI)"),
"hdmi-stereo", "hdmi-stereo",
4 }, 4,
"IEC958", NULL,
"IEC958 In", NULL },
{{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
"surround40", "surround40",
N_("Analog Surround 4.0"), N_("Analog Surround 4.0"),
"analog-surround-40", "analog-surround-40",
7 }, 7,
"Master", "PCM",
"Capture", "Mic" },
{{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }},
"a52", "a52",
N_("Digital Surround 4.0 (IEC958/AC3)"), N_("Digital Surround 4.0 (IEC958/AC3)"),
"iec958-ac3-surround-40", "iec958-ac3-surround-40",
2 }, 2,
"Master", "PCM",
"Capture", "Mic" },
{{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
@ -569,7 +581,9 @@ static const struct pa_alsa_profile_info device_table[] = {
"surround41", "surround41",
N_("Analog Surround 4.1"), N_("Analog Surround 4.1"),
"analog-surround-41", "analog-surround-41",
7 }, 7,
"Master", "PCM",
"Capture", "Mic" },
{{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
@ -577,7 +591,9 @@ static const struct pa_alsa_profile_info device_table[] = {
"surround50", "surround50",
N_("Analog Surround 5.0"), N_("Analog Surround 5.0"),
"analog-surround-50", "analog-surround-50",
7 }, 7,
"Master", "PCM",
"Capture", "Mic" },
{{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
@ -585,7 +601,9 @@ static const struct pa_alsa_profile_info device_table[] = {
"surround51", "surround51",
N_("Analog Surround 5.1"), N_("Analog Surround 5.1"),
"analog-surround-51", "analog-surround-51",
8 }, 8,
"Master", "PCM",
"Capture", "Mic" },
{{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
@ -593,7 +611,9 @@ static const struct pa_alsa_profile_info device_table[] = {
"a52", "a52",
N_("Digital Surround 5.1 (IEC958/AC3)"), N_("Digital Surround 5.1 (IEC958/AC3)"),
"iec958-ac3-surround-51", "iec958-ac3-surround-51",
3 }, 3,
"IEC958", NULL,
"IEC958 In", NULL },
{{ 8, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, {{ 8, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
@ -602,9 +622,11 @@ static const struct pa_alsa_profile_info device_table[] = {
"surround71", "surround71",
N_("Analog Surround 7.1"), N_("Analog Surround 7.1"),
"analog-surround-71", "analog-surround-71",
7 }, 7,
"Master", "PCM",
"Capture", "Mic" },
{{ 0, { 0 }}, NULL, NULL, NULL, 0 } {{ 0, { 0 }}, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
}; };
snd_pcm_t *pa_alsa_open_by_device_id_auto( snd_pcm_t *pa_alsa_open_by_device_id_auto(
@ -1095,7 +1117,8 @@ int pa_alsa_find_mixer_and_elem(
snd_pcm_t *pcm, snd_pcm_t *pcm,
snd_mixer_t **_m, snd_mixer_t **_m,
snd_mixer_elem_t **_e, snd_mixer_elem_t **_e,
const char *control_name) { const char *control_name,
const pa_alsa_profile_info *profile) {
int err; int err;
snd_mixer_t *m; snd_mixer_t *m;
@ -1154,6 +1177,8 @@ int pa_alsa_find_mixer_and_elem(
case SND_PCM_STREAM_PLAYBACK: case SND_PCM_STREAM_PLAYBACK:
if (control_name) if (control_name)
e = pa_alsa_find_elem(m, control_name, NULL, TRUE); e = pa_alsa_find_elem(m, control_name, NULL, TRUE);
else if (profile)
e = pa_alsa_find_elem(m, profile->playback_control_name, profile->playback_control_fallback, TRUE);
else else
e = pa_alsa_find_elem(m, "Master", "PCM", TRUE); e = pa_alsa_find_elem(m, "Master", "PCM", TRUE);
break; break;
@ -1161,6 +1186,8 @@ int pa_alsa_find_mixer_and_elem(
case SND_PCM_STREAM_CAPTURE: case SND_PCM_STREAM_CAPTURE:
if (control_name) if (control_name)
e = pa_alsa_find_elem(m, control_name, NULL, FALSE); e = pa_alsa_find_elem(m, control_name, NULL, FALSE);
else if (profile)
e = pa_alsa_find_elem(m, profile->record_control_name, profile->record_control_fallback, FALSE);
else else
e = pa_alsa_find_elem(m, "Capture", "Mic", FALSE); e = pa_alsa_find_elem(m, "Capture", "Mic", FALSE);
break; break;

View file

@ -53,18 +53,20 @@ int pa_alsa_set_hw_params(
int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min); int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min);
int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback);
int pa_alsa_find_mixer_and_elem(snd_pcm_t *pcm, snd_mixer_t **_m, snd_mixer_elem_t **_e, const char *control_name);
typedef struct pa_alsa_profile_info { typedef struct pa_alsa_profile_info {
pa_channel_map map; pa_channel_map map;
const char *alsa_name; const char *alsa_name;
const char *description; /* internationalized */ const char *description; /* internationalized */
const char *name; const char *name;
unsigned priority; unsigned priority;
const char *playback_control_name, *playback_control_fallback;
const char *record_control_name, *record_control_fallback;
} pa_alsa_profile_info; } pa_alsa_profile_info;
int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback);
int pa_alsa_find_mixer_and_elem(snd_pcm_t *pcm, snd_mixer_t **_m, snd_mixer_elem_t **_e, const char *control_name, const pa_alsa_profile_info*profile);
/* Picks a working profile based on the specified ss/map */ /* Picks a working profile based on the specified ss/map */
snd_pcm_t *pa_alsa_open_by_device_id_auto( snd_pcm_t *pa_alsa_open_by_device_id_auto(
const char *dev_id, const char *dev_id,