mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
acp: add a Pro Audio profile
The Pro Audio profile exposes all devices and subdevices with maximum channel count and no channel layout. It also have no hardware volume and is more suited for Pro Audio usage. See #731 #704 #57
This commit is contained in:
parent
91610bd1a9
commit
5892403b01
2 changed files with 138 additions and 0 deletions
|
|
@ -266,6 +266,131 @@ static void profile_free(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static int add_pro_profile(pa_card *impl, uint32_t index)
|
||||
{
|
||||
snd_ctl_t *ctl_hndl;
|
||||
int err, dev;
|
||||
pa_alsa_profile *ap;
|
||||
pa_alsa_profile_set *ps = impl->profile_set;
|
||||
pa_alsa_mapping *m;
|
||||
char *device;
|
||||
snd_pcm_info_t *pcminfo;
|
||||
pa_sample_spec ss;
|
||||
snd_pcm_uframes_t try_period_size, try_buffer_size;
|
||||
|
||||
ss.format = PA_SAMPLE_S32LE;
|
||||
ss.rate = 48000;
|
||||
ss.channels = 64;
|
||||
|
||||
ap = pa_xnew0(pa_alsa_profile, 1);
|
||||
ap->profile_set = ps;
|
||||
ap->profile.name = ap->name = pa_xstrdup("pro-audio");
|
||||
ap->profile.description = ap->description = pa_xstrdup(_("Pro Audio"));
|
||||
ap->profile.available = ACP_AVAILABLE_YES;
|
||||
ap->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
|
||||
ap->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
|
||||
pa_hashmap_put(ps->profiles, ap->name, ap);
|
||||
|
||||
ap->output_name = pa_xstrdup("pro-output");
|
||||
ap->input_name = pa_xstrdup("pro-input");
|
||||
ap->priority = 1;
|
||||
|
||||
asprintf(&device, "hw:%d", index);
|
||||
|
||||
if ((err = snd_ctl_open(&ctl_hndl, device, 0)) < 0) {
|
||||
pa_log_error("can't open control for card %s: %s",
|
||||
device, snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
snd_pcm_info_alloca(&pcminfo);
|
||||
|
||||
dev = -1;
|
||||
while (1) {
|
||||
if ((err = snd_ctl_pcm_next_device(ctl_hndl, &dev)) < 0) {
|
||||
pa_log_error("error iterating devices: %s", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
if (dev < 0)
|
||||
break;
|
||||
|
||||
snd_pcm_info_set_device(pcminfo, dev);
|
||||
snd_pcm_info_set_subdevice(pcminfo, 0);
|
||||
|
||||
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
|
||||
if ((err = snd_ctl_pcm_info(ctl_hndl, pcminfo)) < 0) {
|
||||
if (err != -ENOENT)
|
||||
pa_log_error("error pcm info: %s", snd_strerror(err));
|
||||
}
|
||||
if (err >= 0) {
|
||||
char *devstr, *name, *desc;
|
||||
asprintf(&devstr, "hw:%d,%d", index, dev);
|
||||
asprintf(&name, "Mapping pro-output-%d", dev);
|
||||
asprintf(&desc, "Pro Output %d", dev);
|
||||
m = pa_alsa_mapping_get(ps, name);
|
||||
m->description = desc;
|
||||
m->device_strings = pa_split_spaces_strv(devstr);
|
||||
|
||||
try_period_size = 1024;
|
||||
try_buffer_size = 1024 * 64;
|
||||
m->sample_spec = ss;
|
||||
|
||||
if ((m->output_pcm = pa_alsa_open_by_template(m->device_strings,
|
||||
devstr, NULL, &m->sample_spec,
|
||||
&m->channel_map, SND_PCM_STREAM_PLAYBACK,
|
||||
&try_period_size, &try_buffer_size,
|
||||
0, NULL, NULL, false))) {
|
||||
pa_alsa_init_proplist_pcm(NULL, m->output_proplist, m->output_pcm);
|
||||
snd_pcm_close(m->output_pcm);
|
||||
m->output_pcm = NULL;
|
||||
m->supported = true;
|
||||
pa_channel_map_init_pro(&m->channel_map, m->sample_spec.channels);
|
||||
}
|
||||
pa_idxset_put(ap->output_mappings, m, NULL);
|
||||
free(name);
|
||||
free(devstr);
|
||||
}
|
||||
|
||||
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
|
||||
if ((err = snd_ctl_pcm_info(ctl_hndl, pcminfo)) < 0) {
|
||||
if (err != -ENOENT)
|
||||
pa_log_error("error pcm info: %s", snd_strerror(err));
|
||||
}
|
||||
if (err >= 0) {
|
||||
char *devstr, *name, *desc;
|
||||
asprintf(&devstr, "hw:%d,%d", index, dev);
|
||||
asprintf(&name, "Mapping pro-input-%d", dev);
|
||||
asprintf(&desc, "Mapping Pro Input %d", dev);
|
||||
m = pa_alsa_mapping_get(ps, name);
|
||||
m->description = desc;
|
||||
m->device_strings = pa_split_spaces_strv(devstr);
|
||||
|
||||
try_period_size = 1024;
|
||||
try_buffer_size = 1024 * 64;
|
||||
m->sample_spec = ss;
|
||||
|
||||
if ((m->input_pcm = pa_alsa_open_by_template(m->device_strings,
|
||||
devstr, NULL, &m->sample_spec,
|
||||
&m->channel_map, SND_PCM_STREAM_CAPTURE,
|
||||
&try_period_size, &try_buffer_size,
|
||||
0, NULL, NULL, false))) {
|
||||
pa_alsa_init_proplist_pcm(NULL, m->input_proplist, m->input_pcm);
|
||||
snd_pcm_close(m->input_pcm);
|
||||
m->input_pcm = NULL;
|
||||
m->supported = true;
|
||||
pa_channel_map_init_pro(&m->channel_map, m->sample_spec.channels);
|
||||
}
|
||||
pa_idxset_put(ap->input_mappings, m, NULL);
|
||||
free(devstr);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
snd_ctl_close(ctl_hndl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void add_profiles(pa_card *impl)
|
||||
{
|
||||
pa_alsa_profile *ap;
|
||||
|
|
@ -286,6 +411,8 @@ static void add_profiles(pa_card *impl)
|
|||
ap->profile.flags = ACP_PROFILE_OFF;
|
||||
pa_hashmap_put(impl->profiles, ap->name, ap);
|
||||
|
||||
add_pro_profile(impl, impl->card.index);
|
||||
|
||||
PA_HASHMAP_FOREACH(ap, impl->profile_set->profiles, state) {
|
||||
pa_alsa_mapping *m;
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,17 @@ static inline pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline pa_channel_map* pa_channel_map_init_pro(pa_channel_map *m,
|
||||
unsigned channels)
|
||||
{
|
||||
unsigned i;
|
||||
pa_channel_map_init(m);
|
||||
for (i = 0; i < channels; i++)
|
||||
m->map[i] = PA_CHANNEL_POSITION_INVALID;
|
||||
m->channels = (uint8_t) channels;
|
||||
return m;
|
||||
}
|
||||
|
||||
typedef uint64_t pa_channel_position_mask_t;
|
||||
|
||||
#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue