1
0
Fork 0
pipewire/spa/plugins/alsa/acp/alsa-ucm.h
Daniel Baumann 6b016a712f
Adding upstream version 1.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 21:40:42 +02:00

318 lines
11 KiB
C

#ifndef fooalsaucmhfoo
#define fooalsaucmhfoo
/***
This file is part of PulseAudio.
Copyright 2011 Wolfson Microelectronics PLC
Author Margarita Olaya <magi@slimlogic.co.uk>
Copyright 2012 Feng Wei <wei.feng@freescale.com>, Freescale Ltd.
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_ALSA_UCM
#include <alsa/use-case.h>
#else
typedef void snd_use_case_mgr_t;
#endif
#include "compat.h"
#include "alsa-mixer.h"
/** For devices: List of verbs, devices or modifiers available */
#define PA_ALSA_PROP_UCM_NAME "alsa.ucm.name"
/** For devices: List of supported devices per verb*/
#define PA_ALSA_PROP_UCM_DESCRIPTION "alsa.ucm.description"
/** For devices: Playback device name e.g PlaybackPCM */
#define PA_ALSA_PROP_UCM_SINK "alsa.ucm.sink"
/** For devices: Capture device name e.g CapturePCM*/
#define PA_ALSA_PROP_UCM_SOURCE "alsa.ucm.source"
/** For devices: Playback roles */
#define PA_ALSA_PROP_UCM_PLAYBACK_ROLES "alsa.ucm.playback.roles"
/** For devices: Playback control device name */
#define PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE "alsa.ucm.playback.ctldev"
/** For devices: Playback control volume ID string. e.g PlaybackVolume */
#define PA_ALSA_PROP_UCM_PLAYBACK_VOLUME "alsa.ucm.playback.volume"
/** For devices: Playback switch e.g PlaybackSwitch */
#define PA_ALSA_PROP_UCM_PLAYBACK_SWITCH "alsa.ucm.playback.switch"
/** For devices: Playback mixer device name */
#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE "alsa.ucm.playback.mixer.device"
/** For devices: Playback mixer identifier */
#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM "alsa.ucm.playback.mixer.element"
/** For devices: Playback mixer master identifier */
#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM "alsa.ucm.playback.master.element"
/** For devices: Playback mixer master type */
#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type"
/** For devices: Playback mixer master identifier */
#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ID "alsa.ucm.playback.master.id"
/** For devices: Playback mixer master type */
#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type"
/** For devices: Playback priority */
#define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY "alsa.ucm.playback.priority"
/** For devices: Playback rate */
#define PA_ALSA_PROP_UCM_PLAYBACK_RATE "alsa.ucm.playback.rate"
/** For devices: Playback channels */
#define PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS "alsa.ucm.playback.channels"
/** For devices: Capture roles */
#define PA_ALSA_PROP_UCM_CAPTURE_ROLES "alsa.ucm.capture.roles"
/** For devices: Capture control device name */
#define PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE "alsa.ucm.capture.ctldev"
/** For devices: Capture controls volume ID string. e.g CaptureVolume */
#define PA_ALSA_PROP_UCM_CAPTURE_VOLUME "alsa.ucm.capture.volume"
/** For devices: Capture switch e.g CaptureSwitch */
#define PA_ALSA_PROP_UCM_CAPTURE_SWITCH "alsa.ucm.capture.switch"
/** For devices: Capture mixer device name */
#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE "alsa.ucm.capture.mixer.device"
/** For devices: Capture mixer identifier */
#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM "alsa.ucm.capture.mixer.element"
/** For devices: Capture mixer identifier */
#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM "alsa.ucm.capture.master.element"
/** For devices: Capture mixer identifier */
#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type"
/** For devices: Capture mixer identifier */
#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ID "alsa.ucm.capture.master.id"
/** For devices: Capture mixer identifier */
#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type"
/** For devices: Capture priority */
#define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY "alsa.ucm.capture.priority"
/** For devices: Capture rate */
#define PA_ALSA_PROP_UCM_CAPTURE_RATE "alsa.ucm.capture.rate"
/** For devices: Capture channels */
#define PA_ALSA_PROP_UCM_CAPTURE_CHANNELS "alsa.ucm.capture.channels"
/** For devices: Quality of Service */
#define PA_ALSA_PROP_UCM_QOS "alsa.ucm.qos"
/** For devices: The modifier (if any) that this device corresponds to */
#define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier"
/* Corresponds to the "JackCTL" UCM value. */
#define PA_ALSA_PROP_UCM_JACK_DEVICE "alsa.ucm.jack_device"
/* Corresponds to the "JackControl" UCM value. */
#define PA_ALSA_PROP_UCM_JACK_CONTROL "alsa.ucm.jack_control"
/* Corresponds to the "JackHWMute" UCM value. */
#define PA_ALSA_PROP_UCM_JACK_HW_MUTE "alsa.ucm.jack_hw_mute"
typedef struct pa_alsa_ucm_verb pa_alsa_ucm_verb;
typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
typedef struct pa_alsa_ucm_profile_context pa_alsa_ucm_profile_context;
typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
typedef struct pa_alsa_ucm_split pa_alsa_ucm_split;
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_profile *new_profile, pa_alsa_profile *old_profile);
int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
void pa_alsa_ucm_add_ports(
pa_hashmap **hash,
pa_proplist *proplist,
pa_alsa_ucm_mapping_context *context,
bool is_sink,
pa_card *card,
snd_pcm_t *pcm_handle,
bool ignore_dB);
void pa_alsa_ucm_add_port(
pa_hashmap *hash,
pa_alsa_ucm_mapping_context *context,
bool is_sink,
pa_hashmap *ports,
pa_card_profile *cp,
pa_core *core);
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port);
void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
/* UCM - Use Case Manager is available on some audio cards */
struct pa_alsa_ucm_split {
/* UCM SplitPCM channel remapping */
bool leader;
int hw_channels;
int channels;
int idx[PA_CHANNELS_MAX];
enum snd_pcm_chmap_position pos[PA_CHANNELS_MAX];
bool broken;
};
struct pa_alsa_ucm_device {
PA_LLIST_FIELDS(pa_alsa_ucm_device);
pa_proplist *proplist;
pa_device_port_type_t type;
unsigned playback_priority;
unsigned capture_priority;
unsigned playback_rate;
unsigned capture_rate;
unsigned playback_channels;
unsigned capture_channels;
/* These may be different per verb, so we store this as a hashmap of verb -> volume_control. We might eventually want to
* make this a hashmap of verb -> per-verb-device-properties-struct. */
pa_hashmap *playback_volumes;
pa_hashmap *capture_volumes;
pa_alsa_mapping *playback_mapping;
pa_alsa_mapping *capture_mapping;
pa_idxset *conflicting_devices;
pa_idxset *supported_devices;
/* One device may be part of multiple ports, since each device has
* a dedicated port, and in addition to that we sometimes generate ports
* that represent combinations of devices. */
pa_dynarray *ucm_ports; /* struct ucm_port */
pa_alsa_jack *jack;
pa_dynarray *hw_mute_jacks; /* pa_alsa_jack */
pa_available_t available;
char *eld_mixer_device_name;
int eld_device;
pa_alsa_ucm_split *playback_split;
pa_alsa_ucm_split *capture_split;
};
void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device);
struct pa_alsa_ucm_modifier {
PA_LLIST_FIELDS(pa_alsa_ucm_modifier);
pa_proplist *proplist;
pa_idxset *conflicting_devices;
pa_idxset *supported_devices;
pa_direction_t action_direction;
char *media_role;
/* Non-NULL if the modifier has its own PlaybackPCM/CapturePCM */
pa_alsa_mapping *playback_mapping;
pa_alsa_mapping *capture_mapping;
/* Count how many role matched streams are running */
int enabled_counter;
};
struct pa_alsa_ucm_verb {
PA_LLIST_FIELDS(pa_alsa_ucm_verb);
pa_proplist *proplist;
unsigned priority;
PA_LLIST_HEAD(pa_alsa_ucm_device, devices);
PA_LLIST_HEAD(pa_alsa_ucm_modifier, modifiers);
};
struct pa_alsa_ucm_config {
pa_sample_spec default_sample_spec;
pa_channel_map default_channel_map;
unsigned default_fragment_size_msec;
unsigned default_n_fragments;
bool split_enable;
snd_use_case_mgr_t *ucm_mgr;
pa_alsa_ucm_verb *active_verb;
char *alib_prefix;
pa_hashmap *mixers;
PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs);
PA_LLIST_HEAD(pa_alsa_jack, jacks);
};
struct pa_alsa_ucm_mapping_context {
pa_alsa_ucm_config *ucm;
pa_direction_t direction;
pa_alsa_ucm_device *ucm_device;
pa_alsa_ucm_modifier *ucm_modifier;
};
struct pa_alsa_ucm_profile_context {
pa_alsa_ucm_verb *verb;
};
struct pa_alsa_ucm_port_data {
pa_alsa_ucm_config *ucm;
pa_device_port *core_port;
pa_alsa_ucm_device *device;
/* verb name -> pa_alsa_path for volume control */
pa_hashmap *paths;
/* Current path, set when activating verb */
pa_alsa_path *path;
/* ELD info */
char *eld_mixer_device_name;
int eld_device; /* PCM device number */
};
long pa_alsa_ucm_port_device_status(pa_alsa_ucm_port_data *data);
struct pa_alsa_ucm_volume {
char *mixer_elem; /* mixer element identifier */
char *master_elem; /* master mixer element identifier */
char *master_type;
};
#endif