mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	add new call pa_alsa_open_by_device_id_profile()
This commit is contained in:
		
							parent
							
								
									04e9214065
								
							
						
					
					
						commit
						b88b89a676
					
				
					 4 changed files with 106 additions and 41 deletions
				
			
		| 
						 | 
					@ -574,7 +574,7 @@ static const struct pa_alsa_profile_info device_table[] = {
 | 
				
			||||||
    {{ 0, { 0 }}, NULL, NULL, NULL, 0 }
 | 
					    {{ 0, { 0 }}, NULL, NULL, NULL, 0 }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
snd_pcm_t *pa_alsa_open_by_device_id(
 | 
					snd_pcm_t *pa_alsa_open_by_device_id_auto(
 | 
				
			||||||
        const char *dev_id,
 | 
					        const char *dev_id,
 | 
				
			||||||
        char **dev,
 | 
					        char **dev,
 | 
				
			||||||
        pa_sample_spec *ss,
 | 
					        pa_sample_spec *ss,
 | 
				
			||||||
| 
						 | 
					@ -585,8 +585,7 @@ snd_pcm_t *pa_alsa_open_by_device_id(
 | 
				
			||||||
        snd_pcm_uframes_t tsched_size,
 | 
					        snd_pcm_uframes_t tsched_size,
 | 
				
			||||||
        pa_bool_t *use_mmap,
 | 
					        pa_bool_t *use_mmap,
 | 
				
			||||||
        pa_bool_t *use_tsched,
 | 
					        pa_bool_t *use_tsched,
 | 
				
			||||||
        const char**config_description,
 | 
					        const pa_alsa_profile_info **profile) {
 | 
				
			||||||
        const char **config_name) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
    int direction = 1;
 | 
					    int direction = 1;
 | 
				
			||||||
| 
						 | 
					@ -642,11 +641,8 @@ snd_pcm_t *pa_alsa_open_by_device_id(
 | 
				
			||||||
                *map = device_table[i].map;
 | 
					                *map = device_table[i].map;
 | 
				
			||||||
                pa_assert(map->channels == ss->channels);
 | 
					                pa_assert(map->channels == ss->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (config_description)
 | 
					                if (profile)
 | 
				
			||||||
                    *config_description = device_table[i].description;
 | 
					                    *profile = &device_table[i];
 | 
				
			||||||
                if (config_name)
 | 
					 | 
				
			||||||
                    *config_name = device_table[i].name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return pcm_handle;
 | 
					                return pcm_handle;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -703,10 +699,64 @@ snd_pcm_t *pa_alsa_open_by_device_id(
 | 
				
			||||||
    pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE);
 | 
					    pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE);
 | 
				
			||||||
    pa_xfree(d);
 | 
					    pa_xfree(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pcm_handle) {
 | 
					    if (pcm_handle && profile)
 | 
				
			||||||
        *config_description = NULL;
 | 
					        *profile = NULL;
 | 
				
			||||||
        *config_name = NULL;
 | 
					
 | 
				
			||||||
    }
 | 
					    return pcm_handle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					snd_pcm_t *pa_alsa_open_by_device_id_profile(
 | 
				
			||||||
 | 
					        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,
 | 
				
			||||||
 | 
					        const pa_alsa_profile_info *profile) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *d;
 | 
				
			||||||
 | 
					    snd_pcm_t *pcm_handle;
 | 
				
			||||||
 | 
					    pa_sample_spec try_ss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_assert(dev_id);
 | 
				
			||||||
 | 
					    pa_assert(dev);
 | 
				
			||||||
 | 
					    pa_assert(ss);
 | 
				
			||||||
 | 
					    pa_assert(map);
 | 
				
			||||||
 | 
					    pa_assert(nfrags);
 | 
				
			||||||
 | 
					    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,
 | 
				
			||||||
 | 
					            dev,
 | 
				
			||||||
 | 
					            &try_ss,
 | 
				
			||||||
 | 
					            map,
 | 
				
			||||||
 | 
					            mode,
 | 
				
			||||||
 | 
					            nfrags,
 | 
				
			||||||
 | 
					            period_size,
 | 
				
			||||||
 | 
					            tsched_size,
 | 
				
			||||||
 | 
					            use_mmap,
 | 
				
			||||||
 | 
					            use_tsched,
 | 
				
			||||||
 | 
					            TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_xfree(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pcm_handle)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *ss = try_ss;
 | 
				
			||||||
 | 
					    *map = profile->map;
 | 
				
			||||||
 | 
					    pa_assert(map->channels == ss->channels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pcm_handle;
 | 
					    return pcm_handle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,16 @@ 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);
 | 
					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);
 | 
					snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
snd_pcm_t *pa_alsa_open_by_device_id(
 | 
					typedef struct pa_alsa_profile_info {
 | 
				
			||||||
 | 
					    pa_channel_map map;
 | 
				
			||||||
 | 
					    const char *alsa_name;
 | 
				
			||||||
 | 
					    const char *description;
 | 
				
			||||||
 | 
					    const char *name;
 | 
				
			||||||
 | 
					    unsigned priority;
 | 
				
			||||||
 | 
					} pa_alsa_profile_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Picks a working profile based on the specified ss/map */
 | 
				
			||||||
 | 
					snd_pcm_t *pa_alsa_open_by_device_id_auto(
 | 
				
			||||||
        const char *dev_id,
 | 
					        const char *dev_id,
 | 
				
			||||||
        char **dev,
 | 
					        char **dev,
 | 
				
			||||||
        pa_sample_spec *ss,
 | 
					        pa_sample_spec *ss,
 | 
				
			||||||
| 
						 | 
					@ -65,9 +74,23 @@ snd_pcm_t *pa_alsa_open_by_device_id(
 | 
				
			||||||
        snd_pcm_uframes_t tsched_size,
 | 
					        snd_pcm_uframes_t tsched_size,
 | 
				
			||||||
        pa_bool_t *use_mmap,
 | 
					        pa_bool_t *use_mmap,
 | 
				
			||||||
        pa_bool_t *use_tsched,
 | 
					        pa_bool_t *use_tsched,
 | 
				
			||||||
        const char **config_name,
 | 
					        const pa_alsa_profile_info **profile);
 | 
				
			||||||
        const char **config_description);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Uses the specified profile */
 | 
				
			||||||
 | 
					snd_pcm_t *pa_alsa_open_by_device_id_profile(
 | 
				
			||||||
 | 
					        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,
 | 
				
			||||||
 | 
					        const pa_alsa_profile_info *profile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Opens the explicit ALSA device */
 | 
				
			||||||
snd_pcm_t *pa_alsa_open_by_device_string(
 | 
					snd_pcm_t *pa_alsa_open_by_device_string(
 | 
				
			||||||
        const char *device,
 | 
					        const char *device,
 | 
				
			||||||
        char **dev,
 | 
					        char **dev,
 | 
				
			||||||
| 
						 | 
					@ -81,14 +104,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
 | 
				
			||||||
        pa_bool_t *use_tsched,
 | 
					        pa_bool_t *use_tsched,
 | 
				
			||||||
        pa_bool_t require_exact_channel_number);
 | 
					        pa_bool_t require_exact_channel_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pa_alsa_profile_info {
 | 
					 | 
				
			||||||
    pa_channel_map map;
 | 
					 | 
				
			||||||
    const char *alsa_name;
 | 
					 | 
				
			||||||
    const char *description;
 | 
					 | 
				
			||||||
    const char *name;
 | 
					 | 
				
			||||||
    unsigned priority;
 | 
					 | 
				
			||||||
} pa_alsa_profile_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int pa_alsa_probe_profiles(
 | 
					int pa_alsa_probe_profiles(
 | 
				
			||||||
        const char *dev_id,
 | 
					        const char *dev_id,
 | 
				
			||||||
        const pa_sample_spec *ss,
 | 
					        const pa_sample_spec *ss,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1253,7 +1253,7 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
 | 
					    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
 | 
				
			||||||
    pa_usec_t usec;
 | 
					    pa_usec_t usec;
 | 
				
			||||||
    pa_sink_new_data data;
 | 
					    pa_sink_new_data data;
 | 
				
			||||||
    const char *profile_description = NULL, *profile_name = NULL;
 | 
					    const pa_alsa_profile_info *profile = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    snd_pcm_info_alloca(&pcm_info);
 | 
					    snd_pcm_info_alloca(&pcm_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1332,13 +1332,13 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 | 
					    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!(u->pcm_handle = pa_alsa_open_by_device_id(
 | 
					        if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
 | 
				
			||||||
                      dev_id,
 | 
					                      dev_id,
 | 
				
			||||||
                      &u->device_name,
 | 
					                      &u->device_name,
 | 
				
			||||||
                      &ss, &map,
 | 
					                      &ss, &map,
 | 
				
			||||||
                      SND_PCM_STREAM_PLAYBACK,
 | 
					                      SND_PCM_STREAM_PLAYBACK,
 | 
				
			||||||
                      &nfrags, &period_frames, tsched_frames,
 | 
					                      &nfrags, &period_frames, tsched_frames,
 | 
				
			||||||
                      &b, &d, &profile_description, &profile_name)))
 | 
					                      &b, &d, &profile)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            goto fail;
 | 
					            goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1358,8 +1358,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_assert(u->device_name);
 | 
					    pa_assert(u->device_name);
 | 
				
			||||||
    pa_log_info("Successfully opened device %s.", u->device_name);
 | 
					    pa_log_info("Successfully opened device %s.", u->device_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (profile_description)
 | 
					    if (profile)
 | 
				
			||||||
        pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
 | 
					        pa_log_info("Selected configuration '%s' (%s).", profile->description, profile->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (use_mmap && !b) {
 | 
					    if (use_mmap && !b) {
 | 
				
			||||||
        pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
 | 
					        pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
 | 
				
			||||||
| 
						 | 
					@ -1444,10 +1444,10 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
 | 
					    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
 | 
				
			||||||
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 | 
					    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (profile_name)
 | 
					    if (profile) {
 | 
				
			||||||
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
 | 
					        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile->name);
 | 
				
			||||||
    if (profile_description)
 | 
					        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
 | 
				
			||||||
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
 | 
					    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
 | 
				
			||||||
    pa_sink_new_data_done(&data);
 | 
					    pa_sink_new_data_done(&data);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1087,7 +1087,7 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_bool_t namereg_fail;
 | 
					    pa_bool_t namereg_fail;
 | 
				
			||||||
    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
 | 
					    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
 | 
				
			||||||
    pa_source_new_data data;
 | 
					    pa_source_new_data data;
 | 
				
			||||||
    const char *profile_description = NULL, *profile_name = NULL;
 | 
					    const pa_alsa_profile_info *profile = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    snd_pcm_info_alloca(&pcm_info);
 | 
					    snd_pcm_info_alloca(&pcm_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1161,13 +1161,13 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 | 
					    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!(u->pcm_handle = pa_alsa_open_by_device_id(
 | 
					        if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
 | 
				
			||||||
                      dev_id,
 | 
					                      dev_id,
 | 
				
			||||||
                      &u->device_name,
 | 
					                      &u->device_name,
 | 
				
			||||||
                      &ss, &map,
 | 
					                      &ss, &map,
 | 
				
			||||||
                      SND_PCM_STREAM_CAPTURE,
 | 
					                      SND_PCM_STREAM_CAPTURE,
 | 
				
			||||||
                      &nfrags, &period_frames, tsched_frames,
 | 
					                      &nfrags, &period_frames, tsched_frames,
 | 
				
			||||||
                      &b, &d, &profile_description, &profile_name)))
 | 
					                      &b, &d, &profile)))
 | 
				
			||||||
            goto fail;
 | 
					            goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					@ -1185,8 +1185,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_assert(u->device_name);
 | 
					    pa_assert(u->device_name);
 | 
				
			||||||
    pa_log_info("Successfully opened device %s.", u->device_name);
 | 
					    pa_log_info("Successfully opened device %s.", u->device_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (profile_description)
 | 
					    if (profile)
 | 
				
			||||||
        pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
 | 
					        pa_log_info("Selected configuration '%s' (%s).", profile->description, profile->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (use_mmap && !b) {
 | 
					    if (use_mmap && !b) {
 | 
				
			||||||
        pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
 | 
					        pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
 | 
				
			||||||
| 
						 | 
					@ -1271,10 +1271,10 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
 | 
					    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
 | 
				
			||||||
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 | 
					    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (profile_name)
 | 
					    if (profile) {
 | 
				
			||||||
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
 | 
					        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile->name);
 | 
				
			||||||
    if (profile_description)
 | 
					        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
 | 
				
			||||||
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
 | 
					    u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
 | 
				
			||||||
    pa_source_new_data_done(&data);
 | 
					    pa_source_new_data_done(&data);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue