mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	alsa: include mixer name in sink/source properties
This commit is contained in:
		
							parent
							
								
									21ab720dd1
								
							
						
					
					
						commit
						dfd6b61cd1
					
				
					 4 changed files with 63 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -1508,6 +1508,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 | 
			
		|||
    size_t frame_size;
 | 
			
		||||
    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
 | 
			
		||||
    pa_sink_new_data data;
 | 
			
		||||
    char *control_device = NULL;
 | 
			
		||||
 | 
			
		||||
    pa_assert(m);
 | 
			
		||||
    pa_assert(ma);
 | 
			
		||||
| 
						 | 
				
			
			@ -1664,7 +1665,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 */
 | 
			
		||||
    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), profile);
 | 
			
		||||
    pa_alsa_find_mixer_and_elem(u->pcm_handle, &control_device, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL), profile);
 | 
			
		||||
 | 
			
		||||
    pa_sink_new_data_init(&data);
 | 
			
		||||
    data.driver = driver;
 | 
			
		||||
| 
						 | 
				
			
			@ -1687,6 +1688,11 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 | 
			
		|||
 | 
			
		||||
    pa_alsa_init_description(data.proplist);
 | 
			
		||||
 | 
			
		||||
    if (control_device) {
 | 
			
		||||
        pa_alsa_init_proplist_ctl(data.proplist, control_device);
 | 
			
		||||
        pa_xfree(control_device);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY|(u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0));
 | 
			
		||||
    pa_sink_new_data_done(&data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1366,6 +1366,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
 | 
			
		|||
    size_t frame_size;
 | 
			
		||||
    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
 | 
			
		||||
    pa_source_new_data data;
 | 
			
		||||
    char *control_device = NULL;
 | 
			
		||||
 | 
			
		||||
    pa_assert(m);
 | 
			
		||||
    pa_assert(ma);
 | 
			
		||||
| 
						 | 
				
			
			@ -1519,7 +1520,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 */
 | 
			
		||||
    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), profile);
 | 
			
		||||
    pa_alsa_find_mixer_and_elem(u->pcm_handle, &control_device, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL), profile);
 | 
			
		||||
 | 
			
		||||
    pa_source_new_data_init(&data);
 | 
			
		||||
    data.driver = driver;
 | 
			
		||||
| 
						 | 
				
			
			@ -1542,6 +1543,11 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
 | 
			
		|||
 | 
			
		||||
    pa_alsa_init_description(data.proplist);
 | 
			
		||||
 | 
			
		||||
    if (control_device) {
 | 
			
		||||
        pa_alsa_init_proplist_ctl(data.proplist, control_device);
 | 
			
		||||
        pa_xfree(control_device);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0));
 | 
			
		||||
    pa_source_new_data_done(&data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,15 +189,6 @@ struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) {
 | 
			
		|||
 | 
			
		||||
    fdl = pa_xnew0(struct pa_alsa_fdlist, 1);
 | 
			
		||||
 | 
			
		||||
    fdl->num_fds = 0;
 | 
			
		||||
    fdl->fds = NULL;
 | 
			
		||||
    fdl->work_fds = NULL;
 | 
			
		||||
    fdl->mixer = NULL;
 | 
			
		||||
    fdl->m = NULL;
 | 
			
		||||
    fdl->defer = NULL;
 | 
			
		||||
    fdl->ios = NULL;
 | 
			
		||||
    fdl->polled = FALSE;
 | 
			
		||||
 | 
			
		||||
    return fdl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1176,6 +1167,7 @@ success:
 | 
			
		|||
 | 
			
		||||
int pa_alsa_find_mixer_and_elem(
 | 
			
		||||
        snd_pcm_t *pcm,
 | 
			
		||||
        char **ctl_device,
 | 
			
		||||
        snd_mixer_t **_m,
 | 
			
		||||
        snd_mixer_elem_t **_e,
 | 
			
		||||
        const char *control_name,
 | 
			
		||||
| 
						 | 
				
			
			@ -1203,9 +1195,13 @@ int pa_alsa_find_mixer_and_elem(
 | 
			
		|||
 | 
			
		||||
    /* First, try by name */
 | 
			
		||||
    if ((dev = snd_pcm_name(pcm)))
 | 
			
		||||
        if (pa_alsa_prepare_mixer(m, dev) >= 0)
 | 
			
		||||
        if (pa_alsa_prepare_mixer(m, dev) >= 0) {
 | 
			
		||||
            found = TRUE;
 | 
			
		||||
 | 
			
		||||
            if (ctl_device)
 | 
			
		||||
                *ctl_device = pa_xstrdup(dev);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /* Then, try by card index */
 | 
			
		||||
    if (!found) {
 | 
			
		||||
        snd_pcm_info_t* info;
 | 
			
		||||
| 
						 | 
				
			
			@ -1220,9 +1216,15 @@ int pa_alsa_find_mixer_and_elem(
 | 
			
		|||
                md = pa_sprintf_malloc("hw:%i", card_idx);
 | 
			
		||||
 | 
			
		||||
                if (!dev || !pa_streq(dev, md))
 | 
			
		||||
                    if (pa_alsa_prepare_mixer(m, md) >= 0)
 | 
			
		||||
                    if (pa_alsa_prepare_mixer(m, md) >= 0) {
 | 
			
		||||
                        found = TRUE;
 | 
			
		||||
 | 
			
		||||
                        if (ctl_device) {
 | 
			
		||||
                            *ctl_device = md;
 | 
			
		||||
                            md = NULL;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                pa_xfree(md);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1258,6 +1260,9 @@ int pa_alsa_find_mixer_and_elem(
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (!e) {
 | 
			
		||||
        if (ctl_device)
 | 
			
		||||
            pa_xfree(*ctl_device);
 | 
			
		||||
 | 
			
		||||
        snd_mixer_close(m);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1601,6 +1606,36 @@ void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm, snd_m
 | 
			
		|||
        pa_alsa_init_proplist_pcm_info(c, p, info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name) {
 | 
			
		||||
    int err;
 | 
			
		||||
    snd_ctl_t *ctl;
 | 
			
		||||
    snd_ctl_card_info_t *info;
 | 
			
		||||
    const char *t;
 | 
			
		||||
 | 
			
		||||
    pa_assert(p);
 | 
			
		||||
 | 
			
		||||
    snd_ctl_card_info_alloca(&info);
 | 
			
		||||
 | 
			
		||||
    if ((err = snd_ctl_open(&ctl, name, 0)) < 0) {
 | 
			
		||||
        pa_log_warn("Error opening low-level control device '%s'", name);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((err = snd_ctl_card_info(ctl, info)) < 0) {
 | 
			
		||||
        pa_log_warn("Control device %s card info: %s", name, snd_strerror(err));
 | 
			
		||||
        snd_ctl_close(ctl);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((t = snd_ctl_card_info_get_mixername(info)))
 | 
			
		||||
        pa_proplist_sets(p, "alsa.mixer_name", t);
 | 
			
		||||
 | 
			
		||||
    if ((t = snd_ctl_card_info_get_components(info)))
 | 
			
		||||
        pa_proplist_sets(p, "alsa.components", t);
 | 
			
		||||
 | 
			
		||||
    snd_ctl_close(ctl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
 | 
			
		||||
    snd_pcm_state_t state;
 | 
			
		||||
    int err;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,9 @@ typedef struct 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);
 | 
			
		||||
int pa_alsa_find_mixer_and_elem(snd_pcm_t *pcm, char **ctl_device, snd_mixer_t **_m, snd_mixer_elem_t **_e, const char *control_name, const pa_alsa_profile_info*profile);
 | 
			
		||||
 | 
			
		||||
void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name);
 | 
			
		||||
 | 
			
		||||
/* Picks a working profile based on the specified ss/map */
 | 
			
		||||
snd_pcm_t *pa_alsa_open_by_device_id_auto(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue