update upstream-2021-08-15

This commit is contained in:
Chengyi Zhao 2021-08-15 02:35:23 +08:00
parent c8653c13fa
commit 1703683def
297 changed files with 91782 additions and 54869 deletions

View file

@ -19,6 +19,7 @@ SUBSYSTEM!="sound", GOTO="pulseaudio_end"
ACTION!="change", GOTO="pulseaudio_end"
KERNEL!="card*", GOTO="pulseaudio_end"
SUBSYSTEMS=="usb", GOTO="pulseaudio_check_usb"
SUBSYSTEMS=="pci", GOTO="pulseaudio_check_pci"
SUBSYSTEMS=="firewire", GOTO="pulseaudio_firewire_quirk"
SUBSYSTEMS=="platform", DRIVERS=="thinkpad_acpi", ENV{PULSE_IGNORE}="1"
@ -104,12 +105,17 @@ ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="041d", ENV{PULSE_PROFILE_SET}="nativ
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1010", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio6.conf"
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1011", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio6.conf"
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1001", ENV{PULSE_PROFILE_SET}="native-instruments-komplete-audio6.conf"
ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio10.conf"
ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf"
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="402e", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
ATTRS{idVendor}=="08bb", ATTRS{idProduct}=="2902", ENV{PULSE_PROFILE_SET}="behringer-umc22.conf"
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0269", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-120w-g2.conf"
ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0567", ENV{PULSE_PROFILE_SET}="hp-tbt-dock-audio-module.conf"
# ID 1038:12ad is for the 2018 refresh of the Arctis 7.
# ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7 configuration).
@ -117,8 +123,15 @@ ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="usb-g
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
# ID 1038:12c4 is for Arctis 9
ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12c4", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
# Lucidsound LS31
ATTRS{idVendor}=="2f12", ATTRS{idProduct}=="0109", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
# ID 9886:002c is for the Astro A50 Gen4
ATTRS{idVendor}=="9886", ATTRS{idProduct}=="002c", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
# ID 1532:0520 is for the Razer Kraken Tournament Edition
ATTRS{idVendor}=="1532", ATTRS{idProduct}=="0520", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
# ID 1038:1250 is for the Arctis 5
# ID 1037:12aa is for the Arctis 5 2019
@ -129,17 +142,51 @@ ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1252", ENV{PULSE_PROFILE_SET}="steel
ATTRS{idVendor}=="147a", ATTRS{idProduct}=="e055", ENV{PULSE_PROFILE_SET}="cmedia-high-speed-true-hdaudio.conf"
# HyperX Cloud Orbit S has three modes. Each mode has a separate product ID.
# ID_SERIAL for this device is the device name + mode repeated three times.
# ID_SERIAL is used for the ID_ID property, and the ID_ID property is used in
# the card name in PulseAudio. The resulting card name is too long for the name
# length limit, so we set a more sensible ID_ID here (the same as the default
# ID_ID, but without repetition in the serial part).
ATTRS{idVendor}=="0951", ATTRS{idProduct}=="16ff", ENV{ID_ID}="usb-HyperX_Cloud_Orbit_S_2Ch-$env{ID_USB_INTERFACE_NUM}"
ATTRS{idVendor}=="0951", ATTRS{idProduct}=="1702", ENV{ID_ID}="usb-HyperX_Cloud_Orbit_S_Hi-Res_2Ch-$env{ID_USB_INTERFACE_NUM}"
ATTRS{idVendor}=="0951", ATTRS{idProduct}=="1703", ENV{ID_ID}="usb-HyperX_Cloud_Orbit_S_3D_8Ch-$env{ID_USB_INTERFACE_NUM}"
# OnePlus Type-C Bullets (ED117)
ATTRS{idVendor}=="2a70", ATTRS{idProduct}=="1881", ENV{PULSE_PROFILE_SET}="simple-headphones-mic.conf"
# ID 1395:005e is for Sennheiser GSX 1000
# ID 1395:00a0 is for Sennheiser GSX 1000
# ID 1395:005f is for Sennheiser GSX 1200
# ID 1395:00a1 is for Sennheiser GSX 1200
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="005e", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a0", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="005f", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
ATTRS{idVendor}=="1395", ATTRS{idProduct}=="00a1", ENV{PULSE_PROFILE_SET}="sennheiser-gsx.conf"
GOTO="pulseaudio_end"
LABEL="pulseaudio_check_pci"
# Creative SoundBlaster Audigy-based cards
# EMU10k2/CA0100/CA0102/CA10200
ATTRS{vendor}=="0x1102", ATTRS{device}=="0x0004", ENV{PULSE_PROFILE_SET}="audigy.conf"
# CA0108/CA10300
ATTRS{vendor}=="0x1102", ATTRS{device}=="0x0008", ENV{PULSE_PROFILE_SET}="audigy.conf"
GOTO="pulseaudio_end"
LABEL="pulseaudio_firewire_quirk"
# Focusrite Saffire Pro 10/26 i/o has a quirk to disappear from IEEE 1394 bus when losing connections.
# https://bugzilla.kernel.org/show_bug.cgi?id=199365
ENV{ID_VENDOR_ID}=="0x00130e", ENV{ID_MODEL_ID}=="0x000003", ENV{PULSE_IGNORE}="1"
# Both of Saffire Pro 10 i/o and Liquid Saffire 56 have the same ID_MODEL_ID
# (0x000006), but Liquid Saffire 56 doesn't suffer from the problem, so we
# can't use ID_MODEL_ID to identify the problematic card. ID_MODEL works
# better here.
ENV{ID_VENDOR_ID}=="0x00130e", ENV{ID_MODEL}=="Pro10IO" ENV{PULSE_IGNORE}="1"
# Focusrite Saffire Pro 10 i/o and Pro 26 i/o have a quirk to disappear from
# IEEE 1394 bus when breaking connections. This brings an issue for PulseAudio
# to continue the routine for ever that:
# - detecting sound card
# - starting PCM substream
# - stopping the PCM substream
# - the card disappears
# - the card appears
# In detail, see: https://bugzilla.kernel.org/show_bug.cgi?id=199365
ATTRS{vendor}=="0x00130e", ATTRS{model}=="0x00000[36]", ATTRS{units}=="0x00a02d:0x010001", ENV{PULSE_IGNORE}="1"
LABEL="pulseaudio_end"

File diff suppressed because it is too large Load diff

View file

@ -50,6 +50,8 @@ typedef struct pa_alsa_port_data pa_alsa_port_data;
#include "alsa-util.h"
#include "alsa-ucm.h"
#define POSITION_MASK_CHANNELS 8
typedef enum pa_alsa_switch_use {
PA_ALSA_SWITCH_IGNORE,
PA_ALSA_SWITCH_MUTE, /* make this switch follow mute status */
@ -113,6 +115,8 @@ struct pa_alsa_mixer_id {
int index;
};
char *pa_alsa_mixer_id_to_string(char *dst, size_t dst_len, pa_alsa_mixer_id *id);
/* An option belongs to an element and refers to one enumeration item
* of the element is an enumeration item, or a switch status if the
* element is a switch item. */
@ -152,7 +156,7 @@ struct pa_alsa_element {
long constant_volume;
bool override_map:1;
unsigned int override_map;
bool direction_try_other:1;
bool has_dB:1;
@ -160,7 +164,7 @@ struct pa_alsa_element {
long volume_limit; /* -1 for no configured limit */
double min_dB, max_dB;
pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][2];
pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][POSITION_MASK_CHANNELS];
unsigned n_channels;
pa_channel_position_mask_t merged_mask;
@ -177,8 +181,8 @@ struct pa_alsa_jack {
snd_mixer_t *mixer_handle;
char *mixer_device_name;
struct pa_alsa_mixer_id alsa_id;
char *name; /* E g "Headphone" */
char *alsa_name; /* E g "Headphone Jack" */
bool has_control; /* is the jack itself present? */
bool plugged_in; /* is this jack currently plugged in? */
snd_mixer_elem_t *melem; /* Jack detection handle */
@ -194,7 +198,7 @@ struct pa_alsa_jack {
bool append_pcm_to_name;
};
pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name);
pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name, int index);
void pa_alsa_jack_free(pa_alsa_jack *jack);
void pa_alsa_jack_set_has_control(pa_alsa_jack *jack, bool has_control);
void pa_alsa_jack_set_plugged_in(pa_alsa_jack *jack, bool plugged_in);
@ -211,7 +215,7 @@ struct pa_alsa_path {
char *name;
char *description_key;
char *description;
char *available_group;
char *availability_group;
pa_device_port_type_t device_port_type;
unsigned priority;
bool autodetect_eld_device;
@ -281,6 +285,7 @@ struct pa_alsa_mapping {
char *name;
char *description;
char *description_key;
unsigned priority;
pa_alsa_direction_t direction;
/* These are copied over to the resultant sink/source */
@ -322,6 +327,7 @@ struct pa_alsa_profile {
char *name;
char *description;
char *description_key;
unsigned priority;
char *input_name;

View file

@ -1494,6 +1494,7 @@ static void sink_set_volume_cb(pa_sink *s) {
pa_cvolume r;
char volume_buf[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
bool deferred_volume = !!(s->flags & PA_SINK_DEFERRED_VOLUME);
bool write_to_hw = !deferred_volume;
pa_assert(u);
pa_assert(u->mixer_path);
@ -1502,7 +1503,14 @@ static void sink_set_volume_cb(pa_sink *s) {
/* Shift up by the base volume */
pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
/* If the set_volume() is called because of ucm active_port changing, the
* volume should be written to hw immediately, otherwise this volume will be
* overridden by calling get_volume_cb() which is called by
* _disdev/_enadev() -> io_mixer_callback() */
if (u->ucm_context && s->port_changing)
write_to_hw = true;
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, write_to_hw) < 0)
return;
/* Shift down by the base volume, so that 0dB becomes maximum volume */
@ -1825,6 +1833,9 @@ static int process_rewind(struct userdata *u) {
pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
if (rewind_nbytes == 0)
goto rewind_done;
if (PA_UNLIKELY((unused = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
if ((err = try_recover(u, "snd_pcm_avail", (int) unused)) < 0) {
pa_log_warn("Trying to recover from underrun failed during rewind");
@ -1877,8 +1888,11 @@ static int process_rewind(struct userdata *u) {
u->after_rewind = true;
return 0;
}
} else
} else {
pa_log_debug("Mhmm, actually there is nothing to rewind.");
if (u->use_tsched)
increase_watermark(u);
}
rewind_done:
pa_sink_process_rewind(u->sink, 0);
@ -2107,7 +2121,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
NULL, (pa_free_cb_t) pa_alsa_mixer_free);
mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
mdev = mapping ? pa_proplist_gets(mapping->proplist, "alsa.mixer_device") : NULL;
if (mdev) {
u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, true);
} else {
@ -2267,7 +2281,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
bool volume_is_set;
bool mute_is_set;
pa_alsa_profile_set *profile_set = NULL;
void *state = NULL;
void *state;
pa_assert(m);
pa_assert(ma);
@ -2563,6 +2577,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, mapping->name);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, mapping->description);
state = NULL;
while ((key = pa_proplist_iterate(mapping->proplist, &state)))
pa_proplist_sets(data.proplist, key, pa_proplist_gets(mapping->proplist, key));
}
@ -2600,7 +2615,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
if (u->ucm_context) {
pa_device_port *port;
void *state;
unsigned h_prio = 0;
PA_HASHMAP_FOREACH(port, u->sink->ports, state) {
if (!h_prio || port->priority > h_prio)

View file

@ -1365,6 +1365,7 @@ static void source_set_volume_cb(pa_source *s) {
pa_cvolume r;
char volume_buf[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
bool deferred_volume = !!(s->flags & PA_SOURCE_DEFERRED_VOLUME);
bool write_to_hw = !deferred_volume;
pa_assert(u);
pa_assert(u->mixer_path);
@ -1373,7 +1374,14 @@ static void source_set_volume_cb(pa_source *s) {
/* Shift up by the base volume */
pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
/* If the set_volume() is called because of ucm active_port changing, the
* volume should be written to hw immediately, otherwise this volume will be
* overridden by calling get_volume_cb() which is called by
* _disdev/_enadev() -> io_mixer_callback() */
if (u->ucm_context && s->port_changing)
write_to_hw = true;
if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, write_to_hw) < 0)
return;
/* Shift down by the base volume, so that 0dB becomes maximum volume */
@ -1813,7 +1821,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
NULL, (pa_free_cb_t) pa_alsa_mixer_free);
mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
mdev = mapping ? pa_proplist_gets(mapping->proplist, "alsa.mixer_device") : NULL;
if (mdev) {
u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, false);
} else {
@ -1972,7 +1980,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
bool volume_is_set;
bool mute_is_set;
pa_alsa_profile_set *profile_set = NULL;
void *state = NULL;
void *state;
pa_assert(m);
pa_assert(ma);
@ -2250,6 +2258,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, mapping->name);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, mapping->description);
state = NULL;
while ((key = pa_proplist_iterate(mapping->proplist, &state)))
pa_proplist_sets(data.proplist, key, pa_proplist_gets(mapping->proplist, key));
}
@ -2286,7 +2295,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
if (u->ucm_context) {
pa_device_port *port;
void *state;
unsigned h_prio = 0;
PA_HASHMAP_FOREACH(port, u->source->ports, state) {
if (!h_prio || port->priority > h_prio)

View file

@ -691,7 +691,7 @@ static char *modifier_name_to_role(const char *mod_name, bool *is_sink) {
if (!sub || !*sub) {
pa_xfree(sub);
pa_log_warn("Can't match media roles for modifer %s", mod_name);
pa_log_warn("Can't match media roles for modifier %s", mod_name);
return NULL;
}
@ -757,13 +757,11 @@ static void append_lost_relationship(pa_alsa_ucm_device *dev) {
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
char *card_name;
const char **verb_list;
const char **verb_list, *value;
int num_verbs, i, err = 0;
/* support multiple card instances, address card directly by index */
card_name = pa_sprintf_malloc("hw:%i", card_index);
if (card_name == NULL)
return -ENOMEM;
err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
if (err < 0) {
/* fallback longname: is UCM available for this card ? */
@ -771,22 +769,36 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
err = snd_card_get_name(card_index, &card_name);
if (err < 0) {
pa_log("Card can't get card_name from card_index %d", card_index);
err = -PA_ALSA_ERR_UNSPECIFIED;
goto name_fail;
}
err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
if (err < 0) {
pa_log_info("UCM not available for card %s", card_name);
err = -PA_ALSA_ERR_UCM_OPEN;
goto ucm_mgr_fail;
}
}
err = snd_use_case_get(ucm->ucm_mgr, "=Linked", &value);
if (err >= 0) {
if (strcasecmp(value, "true") == 0 || strcasecmp(value, "1") == 0) {
free((void *)value);
pa_log_info("Empty (linked) UCM for card %s", card_name);
err = -PA_ALSA_ERR_UCM_LINKED;
goto ucm_verb_fail;
}
free((void *)value);
}
pa_log_info("UCM available for card %s", card_name);
/* get a list of all UCM verbs (profiles) for this card */
num_verbs = snd_use_case_verb_list(ucm->ucm_mgr, &verb_list);
if (num_verbs < 0) {
pa_log("UCM verb list not found for %s", card_name);
err = -PA_ALSA_ERR_UNSPECIFIED;
goto ucm_verb_fail;
}
@ -806,7 +818,7 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
if (!ucm->verbs) {
pa_log("No UCM verb is valid for %s", card_name);
err = -1;
err = -PA_ALSA_ERR_UCM_NO_VERB;
}
snd_use_case_free_list(verb_list, num_verbs);
@ -950,10 +962,10 @@ static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle,
PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) {
if (pa_alsa_path_probe(path, NULL, mixer_handle, ignore_dB) < 0) {
pa_log_warn("Could not probe path: %s, using s/w volume", data->path->name);
pa_log_warn("Could not probe path: %s, using s/w volume", path->name);
pa_hashmap_remove(data->paths, profile);
} else if (!path->has_volume) {
pa_log_warn("Path %s is not a volume control", data->path->name);
pa_log_warn("Path %s is not a volume control", path->name);
pa_hashmap_remove(data->paths, profile);
} else
pa_log_debug("Set up h/w volume using '%s' for %s:%s", path->name, profile, port->name);
@ -1065,7 +1077,7 @@ static void ucm_add_port_combination(
pa_device_port_new_data_set_type(&port_data, type);
pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
if (jack)
pa_device_port_new_data_set_available_group(&port_data, jack->name);
pa_device_port_new_data_set_availability_group(&port_data, jack->name);
port = pa_device_port_new(core, &port_data, sizeof(pa_alsa_ucm_port_data));
pa_device_port_new_data_done(&port_data);
@ -1526,6 +1538,32 @@ static void alsa_mapping_add_ucm_modifier(pa_alsa_mapping *m, pa_alsa_ucm_modifi
pa_channel_map_init(&m->channel_map);
}
static pa_alsa_mapping* ucm_alsa_mapping_get(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps, const char *verb_name, const char *device_str, bool is_sink) {
pa_alsa_mapping *m;
char *mapping_name;
size_t ucm_alibpref_len = 0;
const char *value;
/* find private alsa-lib's configuration device prefix */
if (snd_use_case_get(ucm->ucm_mgr, "_alibpref", &value) == 0) {
if (value[0] && pa_startswith(device_str, value))
ucm_alibpref_len = strlen(value);
free((void *)value);
}
mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str + ucm_alibpref_len, is_sink ? "sink" : "source");
m = pa_alsa_mapping_get(ps, mapping_name);
if (!m)
pa_log("No mapping for %s", mapping_name);
pa_xfree(mapping_name);
return m;
}
static int ucm_create_mapping_direction(
pa_alsa_ucm_config *ucm,
pa_alsa_profile_set *ps,
@ -1537,19 +1575,14 @@ static int ucm_create_mapping_direction(
bool is_sink) {
pa_alsa_mapping *m;
char *mapping_name;
unsigned priority, rate, channels;
mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str, is_sink ? "sink" : "source");
m = ucm_alsa_mapping_get(ucm, ps, verb_name, device_str, is_sink);
m = pa_alsa_mapping_get(ps, mapping_name);
if (!m) {
pa_log("No mapping for %s", mapping_name);
pa_xfree(mapping_name);
if (!m)
return -1;
}
pa_log_debug("UCM mapping: %s dev %s", mapping_name, device_name);
pa_xfree(mapping_name);
pa_log_debug("UCM mapping: %s dev %s", m->name, device_name);
priority = is_sink ? device->playback_priority : device->capture_priority;
rate = is_sink ? device->playback_rate : device->capture_rate;
@ -1594,18 +1627,13 @@ static int ucm_create_mapping_for_modifier(
bool is_sink) {
pa_alsa_mapping *m;
char *mapping_name;
mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str, is_sink ? "sink" : "source");
m = ucm_alsa_mapping_get(ucm, ps, verb_name, device_str, is_sink);
m = pa_alsa_mapping_get(ps, mapping_name);
if (!m) {
pa_log("no mapping for %s", mapping_name);
pa_xfree(mapping_name);
if (!m)
return -1;
}
pa_log_info("ucm mapping: %s modifier %s", mapping_name, mod_name);
pa_xfree(mapping_name);
pa_log_info("UCM mapping: %s modifier %s", m->name, mod_name);
if (!m->ucm_context.ucm_devices && !m->ucm_context.ucm_modifiers) { /* new mapping */
m->ucm_context.ucm_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
@ -1707,7 +1735,7 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d
pa_log("[%s] No mixer device name for JackControl \"%s\"", device_name, jack_control);
return NULL;
}
j = pa_alsa_jack_new(NULL, mixer_device_name, name);
j = pa_alsa_jack_new(NULL, mixer_device_name, name, 0);
PA_LLIST_PREPEND(pa_alsa_jack, ucm->jacks, j);
finish:
@ -1941,7 +1969,7 @@ static void ucm_mapping_jack_probe(pa_alsa_mapping *m, pa_hashmap *mixers) {
continue;
}
has_control = pa_alsa_mixer_find_card(mixer_handle, dev->jack->alsa_name, 0) != NULL;
has_control = pa_alsa_mixer_find_card(mixer_handle, &dev->jack->alsa_id, 0) != NULL;
pa_alsa_jack_set_has_control(dev->jack, has_control);
pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control);
}

View file

@ -731,7 +731,7 @@ snd_pcm_t *pa_alsa_open_by_device_string(
if (!pa_startswith(d, "plug:") && !pa_startswith(d, "plughw:")) {
char *t;
t = pa_sprintf_malloc("plug:%s", d);
t = pa_sprintf_malloc("plug:SLAVE='%s'", d);
pa_xfree(d);
d = t;
@ -1180,7 +1180,7 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa
PA_ONCE_BEGIN {
char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
pa_log(ngettext("snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
pa_log_debug(ngettext("snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
@ -1189,7 +1189,7 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa
(unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
pa_strnull(dn));
pa_xfree(dn);
pa_alsa_dump(PA_LOG_ERROR, pcm);
pa_alsa_dump(PA_LOG_DEBUG, pcm);
} PA_ONCE_END;
/* Mhmm, let's try not to fail completely */
@ -1246,7 +1246,7 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes
PA_ONCE_BEGIN {
char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
pa_log(ngettext("snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s%lu ms).\n"
pa_log_debug(ngettext("snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
@ -1256,7 +1256,7 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes
(unsigned long) (pa_bytes_to_usec(abs_k, ss) / PA_USEC_PER_MSEC),
pa_strnull(dn));
pa_xfree(dn);
pa_alsa_dump(PA_LOG_ERROR, pcm);
pa_alsa_dump(PA_LOG_DEBUG, pcm);
} PA_ONCE_END;
/* Mhmm, let's try not to fail completely */
@ -1274,7 +1274,7 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes
PA_ONCE_BEGIN {
char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
pa_log(ngettext("snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
pa_log_debug(ngettext("snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
@ -1283,7 +1283,7 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes
(unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
pa_strnull(dn));
pa_xfree(dn);
pa_alsa_dump(PA_LOG_ERROR, pcm);
pa_alsa_dump(PA_LOG_DEBUG, pcm);
} PA_ONCE_END;
/* Mhmm, let's try not to fail completely */
@ -1336,7 +1336,7 @@ int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas
k >= pa_bytes_per_second(ss)*10))
PA_ONCE_BEGIN {
char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
pa_log(ngettext("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
pa_log_debug(ngettext("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.",
@ -1345,7 +1345,7 @@ int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas
(unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
pa_strnull(dn));
pa_xfree(dn);
pa_alsa_dump(PA_LOG_ERROR, pcm);
pa_alsa_dump(PA_LOG_DEBUG, pcm);
} PA_ONCE_END;
return r;
@ -1635,8 +1635,8 @@ static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
return NULL;
}
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device) {
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, name, 0, device);
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, struct pa_alsa_mixer_id *alsa_id, unsigned int device) {
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, alsa_id->name, alsa_id->index, device);
}
snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) {
@ -1752,7 +1752,7 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo
if (!pm && pa_strneq(dev, "hw:", 3)) {
const char *s = dev + 3;
int card_index;
while (*s && *s >= 0 && *s <= '9') s++;
while (*s && *s >= '0' && *s <= '9') s++;
if (*s == '\0' && pa_atoi(dev + 3, &card_index) >= 0) {
PA_HASHMAP_FOREACH_KV(dev2, pm, mixers, state) {
if (pm->card_index == card_index) {

View file

@ -33,6 +33,13 @@
#include "alsa-mixer.h"
enum {
PA_ALSA_ERR_UNSPECIFIED = 1,
PA_ALSA_ERR_UCM_OPEN = 1000,
PA_ALSA_ERR_UCM_NO_VERB = 1001,
PA_ALSA_ERR_UCM_LINKED = 1002
};
int pa_alsa_set_hw_params(
snd_pcm_t *pcm_handle,
pa_sample_spec *ss, /* modified at return */
@ -141,7 +148,7 @@ const char* pa_alsa_strerror(int errnum);
bool pa_alsa_may_tsched(bool want);
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device);
snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, struct pa_alsa_mixer_id *alsa_id, unsigned int device);
snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device);
snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe);

View file

@ -28,6 +28,9 @@ required-any = any
state.plugged = unknown
state.unplugged = unknown
[Jack Line - Input]
required-any = any
[Element Capture]
switch = mute
volume = merge

View file

@ -29,6 +29,9 @@ required-any = any
state.plugged = unknown
state.unplugged = unknown
[Jack Mic - Input]
required-any = any
[Element Capture]
switch = mute
volume = merge

View file

@ -0,0 +1,5 @@
; Some gaming devices have a separate "chat" device, this is for voice chat
; while playing games. This device is just a fairly standard analog mono
; device, but it's nicer to make it clear that this is the "chat" device
; as is mentioned in the marketing info and manual.
.include analog-output.conf.common

View file

@ -13,17 +13,24 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
; Path for mixers that have a 'Headphone2' control
; Path for the second headphone output on dual-headphone machines.
;
; See analog-output.conf.common for an explanation on the directives
[General]
priority = 98
description-key = analog-output-headphones
[Properties]
device.icon_name = audio-headphones
; HP EliteDesk 800 SFF Headphone
[Jack Front Headphone,1]
required-any = any
; HP EliteDesk 800 DM Headphone
[Jack Front Headphone Surround]
required-any = any
[Element Hardware Master]
switch = mute
volume = merge
@ -47,6 +54,13 @@ volume = off
switch = mute
volume = zero
[Element Headphone,1]
required-any = any
switch = mute
volume = merge
override-map.1 = all
override-map.2 = all-left,all-right
[Element Headphone+LO]
switch = mute
volume = zero
@ -56,7 +70,7 @@ switch = off
volume = off
[Element Headphone2]
required = any
required-any = any
switch = mute
volume = merge
override-map.1 = all
@ -70,9 +84,11 @@ volume = off
switch = off
volume = off
; On some machines Front is actually a part of the Headphone path
; On some machines, the Front Volume Control is shared by Headphone and Lineout,
; or Headphone and Speaker, but they have independent Volume Switch. Here only
; use switch to mute Lineout or Speaker.
[Element Front]
switch = mute
switch = off
volume = zero
[Element Rear]

View file

@ -35,6 +35,10 @@ state.unplugged = unknown
[Jack Front Headphone]
required-any = any
; HP EliteDesk 800 DM Headset
[Jack Front Headphone Front]
required-any = any
[Jack Front Headphone Phantom]
required-any = any
state.plugged = unknown
@ -52,6 +56,9 @@ state.unplugged = unknown
[Jack Headphone Mic]
required-any = any
[Jack Headphone - Output]
required-any = any
[Element Hardware Master]
switch = mute
volume = merge
@ -86,6 +93,13 @@ volume = merge
override-map.1 = all
override-map.2 = all-left,all-right
; This path is intended to control the first headphones, not
; the second headphones. But it should not hurt if we leave the second
; headphone jack enabled nonetheless.
[Element Headphone,1]
switch = mute
volume = zero
[Element Headset]
required-any = any
switch = mute
@ -112,9 +126,11 @@ volume = off
switch = off
volume = off
; On some machines Front is actually a part of the Headphone path
; On some machines, the Front Volume Control is shared by Headphone and Lineout,
; or Headphone and Speaker, but they have independent Volume Switch. Here only
; use switch to mute Lineout or Speaker.
[Element Front]
switch = mute
switch = off
volume = zero
[Element Rear]
@ -157,4 +173,8 @@ volume = off
switch = off
volume = off
[Element Speaker Center/LFE]
switch = off
volume = off
.include analog-output.conf.common

View file

@ -127,6 +127,10 @@ required-any = any
switch = off
volume = off
[Element Headphone,1]
switch = off
volume = off
[Element Headphone2]
switch = off
volume = off
@ -181,6 +185,12 @@ volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Center/LFE]
switch = mute
volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Bass Speaker]
switch = off
volume = off

View file

@ -44,6 +44,10 @@ override-map.2 = all-left,all-right
switch = mute
volume = zero
[Element Headphone,1]
switch = mute
volume = zero
[Element Headphone+LO]
switch = mute
volume = zero

View file

@ -76,6 +76,10 @@ volume = off
switch = mute
volume = zero
[Element Headphone,1]
switch = mute
volume = zero
[Element Headphone2]
switch = mute
volume = zero
@ -174,4 +178,10 @@ volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Center/LFE]
switch = mute
volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
.include analog-output.conf.common

View file

@ -69,6 +69,9 @@ required-any = any
state.plugged = unknown
state.unplugged = unknown
[Jack Speaker - Output]
required-any = any
[Element Hardware Master]
switch = mute
volume = merge
@ -85,12 +88,23 @@ override-map.2 = all-left,all-right
switch = off
volume = off
; Make sure the internal speakers are not auto-muted once the system has speakers
[Element Auto-Mute Mode]
enumeration = select
[Option Auto-Mute Mode:Disabled]
name = analog-output-speaker
; This profile path is intended to control the speaker, let's mute headphones
; else there will be a spike when plugging in headphones
[Element Headphone]
switch = off
volume = off
[Element Headphone,1]
switch = off
volume = off
[Element Headphone2]
switch = off
volume = off
@ -217,6 +231,12 @@ volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Center/LFE]
switch = mute
volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Speaker CLFE]
switch = mute
volume = merge

View file

@ -79,4 +79,10 @@ volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
[Element Center/LFE]
switch = mute
volume = merge
override-map.1 = all-center
override-map.2 = all-center,lfe
.include analog-output.conf.common

View file

@ -53,6 +53,8 @@
; [General]
; type = ... # The device type. It's highly recommended to set a type for every path.
; # See parse_type() in alsa-mixer.c for supported values.
; priority = ... # Priority for this path
; description-key = ... # The path description is looked up from a table in path_verify() in
; # src/modules/alsa/alsa-mixer.c. By default the path name (i.e. the file name

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort
type = hdmi
priority = 59
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 2
type = hdmi
priority = 58
eld-device = auto

View file

@ -0,0 +1,12 @@
[General]
description = HDMI / DisplayPort 11
type = hdmi
priority = 49
eld-device = auto
[Properties]
device.icon_name = video-display
[Jack HDMI/DP]
append-pcm-to-name = yes
required = ignore

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 3
type = hdmi
priority = 57
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 4
type = hdmi
priority = 56
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 5
type = hdmi
priority = 55
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 6
type = hdmi
priority = 54
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 7
type = hdmi
priority = 53
eld-device = auto

View file

@ -1,5 +1,6 @@
[General]
description = HDMI / DisplayPort 8
type = hdmi
priority = 52
eld-device = auto

View file

@ -0,0 +1,12 @@
[General]
description = HDMI / DisplayPort 9
type = hdmi
priority = 51
eld-device = auto
[Properties]
device.icon_name = video-display
[Jack HDMI/DP]
append-pcm-to-name = yes
required = ignore

View file

@ -0,0 +1,12 @@
[General]
description = HDMI / DisplayPort 10
type = hdmi
priority = 50
eld-device = auto
[Properties]
device.icon_name = video-display
[Jack HDMI/DP]
append-pcm-to-name = yes
required = ignore

View file

@ -23,10 +23,12 @@
; Steelseries Arctis 7
; Steelseries Arctis Pro Wireless.
; Lucidsound LS31
;
; This path doesn't provide hardware volume control, because the stereo
; output is controlled by the PCM element with index 1, and currently
; PulseAudio only supports elements with index 0.
[General]
description-key = analog-output-headphones
[Element PCM,1]
volume = merge
switch = mute
override-map.1 = all
override-map.2 = all-left,all-right

View file

@ -0,0 +1,5 @@
[Element PCM,1]
switch = mute
volume = merge
override-map.1 = all
override-map.2 = all-left,all-right

View file

@ -0,0 +1,94 @@
# This file is part of PulseAudio.
#
# 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/>.
; Creative Sound Blaster Audigy product line
;
; These are just copies of the mappings we find in default.conf, with the
; small change of making analog-stereo and analog-mono non-fallback mappings.
; This is needed because these cards only support duplex profiles with mono
; inputs, and in the default configuration, with stereo being a fallback
; mapping, the mono mapping is never tried.
;
; See default.conf for an explanation on the directives used here.
[General]
auto-profiles = yes
# Based on stereo-fallback
[Mapping analog-stereo]
device-strings = hw:%f
channel-map = front-left,front-right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 1
# Based on mono-fallback
[Mapping analog-mono]
device-strings = hw:%f
channel-map = mono
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic
priority = 1
# The rest of these are identical to what's in default.conf
[Mapping analog-surround-21]
device-strings = surround21:%f
channel-map = front-left,front-right,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 13
direction = output
[Mapping analog-surround-40]
device-strings = surround40:%f
channel-map = front-left,front-right,rear-left,rear-right
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 12
direction = output
[Mapping analog-surround-41]
device-strings = surround41:%f
channel-map = front-left,front-right,rear-left,rear-right,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 13
direction = output
[Mapping analog-surround-50]
device-strings = surround50:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 12
direction = output
[Mapping analog-surround-51]
device-strings = surround51:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 13
direction = output
[Mapping analog-surround-71]
device-strings = surround71:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
description = Analog Surround 7.1
paths-output = analog-output analog-output-lineout analog-output-speaker
priority = 12
direction = output
[Mapping iec958-stereo]
device-strings = iec958:%f
channel-map = left,right
paths-input = iec958-stereo-input
paths-output = iec958-stereo-output
priority = 5

View file

@ -0,0 +1,68 @@
# This file is part of PulseAudio.
#
# 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/>.
; Behringer U-Phoria UMC22
;
; Default mapping only allows to use stereo input and sound card has two
; physical input channels.
;
; However in case of only using a single input channel (like condenser
; microphone) only one channel will have any sound, which is often
; inconvenient for casual use.
;
; This config includes mono input options which makes it much more
; friendly in single input configuration.
;
; This config also removes default digital input/output mappings that do
; not physically exist on this card.
;
; Added by Nazar Mokrynskyi <nazar@mokrynskyi.com>
[General]
auto-profiles = yes
[Mapping analog-stereo-input]
device-strings = hw:%f
channel-map = left,right
paths-input = analog-input-mic
direction = input
priority = 4
[Mapping analog-mono]
device-strings = hw:%f
channel-map = mono,mono
paths-input = analog-input-mic
direction = input
priority = 3
[Mapping analog-mono-left]
device-strings = hw:%f
channel-map = mono,aux1
paths-input = analog-input-mic
direction = input
priority = 2
[Mapping analog-mono-right]
device-strings = hw:%f
channel-map = aux1,mono
paths-input = analog-input-mic
direction = input
priority = 1
[Mapping analog-stereo-output]
device-strings = front:%f
channel-map = left,right
paths-output = analog-output
direction = output

View file

@ -44,7 +44,11 @@
; [Mapping id]
; device-strings = ... # ALSA device string. %f will be replaced by the card identifier.
; channel-map = ... # Channel mapping to use for this device
; description = ...
; description = ... # Description for the mapping. Note that it's better to set the description
; # in the well_known_descriptions table in alsa-mixer.c than with this
; # option, because the descriptions in alsa-mixer.c are translatable.
; description-key = ... # A custom key for the well_known_descriptions table (by default the mapping
; # name is used).
; paths-input = ... # A list of mixer paths to use. Every path in this list will be probed.
; # If multiple are found to be working they will be available as device ports
; paths-output = ...
@ -58,6 +62,8 @@
; exact-channels = yes | no # If no, and the exact number of channels is not supported,
; # allow device to be opened with another channel count
; fallback = no | yes # This mapping will only be considered if all non-fallback mappings fail
; intended-roles = ... # Set the device.intended_roles property for the sink/source.
;
; [Profile id]
; input-mappings = ... # Lists mappings for sources on this profile, those mapping must be
; # defined in this file too
@ -455,6 +461,102 @@ channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-stereo-extra8]
description = Digital Stereo (HDMI 9)
device-strings = hdmi:%f,8
paths-output = hdmi-output-8
channel-map = left,right
priority = 7
direction = output
[Mapping hdmi-surround-extra8]
description = Digital Surround 5.1 (HDMI 9)
device-strings = hdmi:%f,8
paths-output = hdmi-output-8
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-surround71-extra8]
description = Digital Surround 7.1 (HDMI 9)
device-strings = hdmi:%f,8
paths-output = hdmi-output-8
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
priority = 6
direction = output
[Mapping hdmi-dts-surround-extra8]
description = Digital Surround 5.1 (HDMI 9/DTS)
device-strings = dcahdmi:%f,8
paths-output = hdmi-output-8
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-stereo-extra9]
description = Digital Stereo (HDMI 10)
device-strings = hdmi:%f,9
paths-output = hdmi-output-9
channel-map = left,right
priority = 7
direction = output
[Mapping hdmi-surround-extra9]
description = Digital Surround 5.1 (HDMI 10)
device-strings = hdmi:%f,9
paths-output = hdmi-output-9
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-surround71-extra9]
description = Digital Surround 7.1 (HDMI 10)
device-strings = hdmi:%f,9
paths-output = hdmi-output-9
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
priority = 6
direction = output
[Mapping hdmi-dts-surround-extra9]
description = Digital Surround 5.1 (HDMI 10/DTS)
device-strings = dcahdmi:%f,9
paths-output = hdmi-output-9
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-stereo-extra10]
description = Digital Stereo (HDMI 11)
device-strings = hdmi:%f,10
paths-output = hdmi-output-10
channel-map = left,right
priority = 7
direction = output
[Mapping hdmi-surround-extra10]
description = Digital Surround 5.1 (HDMI 11)
device-strings = hdmi:%f,10
paths-output = hdmi-output-10
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping hdmi-surround71-extra10]
description = Digital Surround 7.1 (HDMI 11)
device-strings = hdmi:%f,10
paths-output = hdmi-output-10
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
priority = 6
direction = output
[Mapping hdmi-dts-surround-extra10]
description = Digital Surround 5.1 (HDMI 11/DTS)
device-strings = dcahdmi:%f,10
paths-output = hdmi-output-10
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 6
direction = output
[Mapping multichannel-output]
device-strings = hw:%f
channel-map = left,right,rear-left,rear-right
@ -462,7 +564,6 @@ exact-channels = false
fallback = yes
priority = 1
direction = output
paths-output = multichannel-output
[Mapping multichannel-input]
device-strings = hw:%f
@ -471,7 +572,6 @@ exact-channels = false
fallback = yes
priority = 1
direction = input
paths-input = multichannel-input
; An example for defining multiple-sink profiles
#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]

View file

@ -0,0 +1,35 @@
# This file is part of PulseAudio.
#
# 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/>.
; HP Thunderbolt Dock 120W G2
;
; This dock has a 3.5mm headset connector. Both input and output are stereo.
;
; There's a separate speakerphone module called "HP Thunderbolt Dock Audio
; Module", which can be attached to this dock. The module will appear in ALSA
; as a separate USB sound card, configuration for it is in
; hp-tbt-dock-audio-module.conf.
[General]
auto-profiles = no
[Mapping analog-stereo-headset]
device-strings = hw:%f,0,0
channel-map = left,right
[Profile output:analog-stereo-headset+input:analog-stereo-headset]
output-mappings = analog-stereo-headset
input-mappings = analog-stereo-headset
skip-probe = yes

View file

@ -0,0 +1,36 @@
# This file is part of PulseAudio.
#
# 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/>.
; HP Thunderbolt Dock Audio Module
;
; This device attaches to the "HP Thunderbolt Dock 120W G2" dock. The audio
; module provides a speakerphone with echo cancellation and appears in ALSA as
; a USB sound card with stereo input and output.
;
; The dock itself has a 3.5mm headset connector and appears as a separate USB
; sound card, configuration for it is in hp-tbt-dock-120w-g2.conf.
[General]
auto-profiles = no
[Mapping analog-stereo-speakerphone]
device-strings = hw:%f,0,0
channel-map = left,right
intended-roles = phone
[Profile output:analog-stereo-speakerphone+input:analog-stereo-speakerphone]
output-mappings = analog-stereo-speakerphone
input-mappings = analog-stereo-speakerphone
skip-probe = yes

View file

@ -0,0 +1,111 @@
# This file is part of PulseAudio.
#
# 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/>.
; Native Instruments Komplete Audio 6
;
; This card has three stereo pairs of input and three stereo pairs of
; output.
;
; We knowingly only define a subset of the theoretically possible
; mapping combinations as profiles here.
;
; See default.conf for an explanation on the directives used here.
[General]
auto-profiles = no
[Mapping analog-stereo-out-ab]
description = Analog Stereo 1/2
device-strings = hw:%f,0,0
channel-map = left,right,aux0,aux1,aux2,aux3
direction = output
[Mapping analog-stereo-out-cd]
description = Analog Stereo 3/4
device-strings = hw:%f,0,0
channel-map = aux0,aux1,left,right,aux2,aux3
direction = output
[Mapping stereo-out-ef]
description = Analog Stereo 5/6
device-strings = hw:%f,0,0
channel-map = aux0,aux1,aux2,aux3,left,right
direction = output
[Mapping analog-mono-in-a]
description = Analog Mono Input 1
device-strings = hw:%f,0,0
channel-map = mono,aux0,aux1,aux2,aux3,aux4
direction = input
[Mapping analog-mono-in-b]
description = Anlog Mono Input 2
device-strings = hw:%f,0,0
channel-map = aux0,mono,aux1,aux2,aux3,aux4
direction = input
[Mapping analog-stereo-in-ab]
description = Analog Stereo Input 1/2
device-strings = hw:%f,0,0
channel-map = left,right,aux0,aux1,aux2,aux3
direction = input
[Mapping analog-stereo-in-cd]
description = Analog Stereo Input 3/4
device-strings = hw:%f,0,0
channel-map = aux0,aux1,left,right,aux2,aux3
direction = input
[Mapping stereo-in-ef]
description = Stereo Input 5/6
device-strings = hw:%f,0,0
channel-map = aux0,aux1,aux2,aux3,left,right
direction = input
[Profile output:analog-stereo-out-ab+input:analog-stereo-in-ab]
description = Analog Stereo Output 1/2, Analog Stereo Input 1/2
output-mappings = analog-stereo-out-ab
input-mappings = analog-stereo-in-ab
priority = 100
skip-probe = yes
[Profile output:analog-stereo-out-ab+input:analog-mono-in-a]
description = Analog Stereo Output 1/2, Analog Mono Input 1
output-mappings = analog-stereo-out-ab
input-mappings = analog-mono-in-a
priority = 95
skip-probe = yes
[Profile output:analog-stereo-out-ab+input:analog-mono-in-b]
description = Analog Stereo Output 1/2, Analog Mono Input 2
output-mappings = analog-stereo-out-ab
input-mappings = analog-mono-in-b
priority = 90
skip-probe = yes
[Profile output:analog-stereo-out-cd+input:analog-stereo-in-cd]
description = Analog Stereo Output 3/4, Analog Stereo Input 3/4
output-mappings = analog-stereo-out-cd
input-mappings = analog-stereo-in-cd
priority = 80
skip-probe = yes
[Profile output:stereo-out-ef+input:stereo-in-ef]
description = Stereo Output 5/6 (S/PDIF), Stereo Input 5/6 (S/PDIF)
output-mappings = stereo-out-ef
input-mappings = stereo-in-ef
priority = 70
skip-probe = yes

View file

@ -0,0 +1,58 @@
# This file is part of PulseAudio.
#
# 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/>.
; USB Gaming DAC.
; These devices have two output devices. The first one is mono, meant for
; voice audio, and the second one is 7.1 surround, meant for everything
; else. The 7.1 surround is mapped to headphones within the device.
; The purpose of the mono/7.1 design is to provide separate volume
; controls for voice and other audio, which can be useful in gaming.
;
; Works with:
; Sennheiser GSX 1000
; Sennheiser GSX 1200
;
; See default.conf for an explanation on the directives used here.
[General]
auto-profiles = no
[Mapping analog-chat-output]
device-strings = hw:%f,0
channel-map = mono
paths-output = analog-chat-output
direction = output
priority = 4000
intended-roles = phone
[Mapping analog-output-surround71]
device-strings = hw:%f,1
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
paths-output = virtual-surround-7.1
priority = 4100
direction = output
[Mapping analog-chat-input]
device-strings = hw:%f,0
channel-map = mono
paths-input = analog-chat-input
priority = 4100
direction = input
[Profile output:analog-output-surround71+output:analog-output-chat+input:analog-input]
output-mappings = analog-output-surround71 analog-chat-output
input-mappings = analog-chat-input
priority = 5100
skip-probe = yes

View file

@ -0,0 +1,42 @@
# This file is part of PulseAudio.
#
# 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/>.
; This is a profile meant for simple (stereo + mic) headphones.
; default.conf also works but using this one will hide some profiles
; that don't make sense like IEC958 and multichannel inputs.
[General]
auto-profiles = yes
[Mapping analog-stereo]
device-strings = front:%f
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 15
# If everything else fails, try to use hw:0 as a stereo device...
[Mapping stereo-fallback]
device-strings = hw:%f
fallback = yes
channel-map = front-left,front-right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 1
[Mapping analog-mono]
device-strings = hw:%f,0,0
channel-map = mono
direction = input

View file

@ -2,7 +2,7 @@
auto-profiles = yes
[Mapping analog-chat]
description = Chat
description-key = gaming-headset-chat
device-strings = hw:%f,0,0
channel-map = left,right
paths-input = analog-input-mic
@ -10,7 +10,7 @@ paths-output = steelseries-arctis-output-chat-common
intended-roles = phone
[Mapping analog-game]
description = Game
description-key = gaming-headset-game
device-strings = hw:%f,1,0
channel-map = left,right
paths-output = steelseries-arctis-output-game-common

View file

@ -14,36 +14,51 @@
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
; USB gaming headset.
; These headsets usually have two output devices. The first one is mono,
; meant for voice audio, and the second one is stereo, meant for everything
; else. The purpose of this unusual design is to provide separate volume
; These headsets usually have two output devices. The first one is meant
; for voice audio, and the second one is meant for everything else.
; The purpose of this unusual design is to provide separate volume
; controls for voice and other audio, which can be useful in gaming.
;
; Works with:
; Steelseries Arctis 7
; Steelseries Arctis Pro Wireless.
; Lucidsound LS31
; Astro A50
;
; See default.conf for an explanation on the directives used here.
[General]
auto-profiles = yes
[Mapping analog-mono]
[Mapping mono-chat]
description-key = gaming-headset-chat
device-strings = hw:%f,0,0
channel-map = mono
paths-output = usb-gaming-headset-output-mono
paths-input = usb-gaming-headset-input
intended-roles = phone
[Mapping analog-stereo]
[Mapping stereo-chat]
description-key = gaming-headset-chat
device-strings = hw:%f,0,0
channel-map = left,right
paths-output = usb-gaming-headset-output-stereo
paths-input = usb-gaming-headset-input
intended-roles = phone
[Mapping stereo-game]
description-key = gaming-headset-game
device-strings = hw:%f,1,0
channel-map = left,right
paths-output = usb-gaming-headset-output-stereo
direction = output
[Profile output:analog-mono+output:analog-stereo+input:analog-mono]
output-mappings = analog-mono analog-stereo
input-mappings = analog-mono
[Profile output:mono-chat+output:stereo-game+input:mono-chat]
output-mappings = mono-chat stereo-game
input-mappings = mono-chat
priority = 5100
[Profile output:stereo-game+output:stereo-chat+input:mono-chat]
output-mappings = stereo-game stereo-chat
input-mappings = mono-chat
priority = 5100
skip-probe = yes

View file

@ -104,6 +104,15 @@ static const char* const valid_modargs[] = {
#define DEFAULT_DEVICE_ID "0"
#define PULSE_MODARGS "PULSE_MODARGS"
/* dynamic profile priority bonus, for all alsa profiles, the original priority
needs to be less than 0x7fff (32767), then could apply the rule of priority
bonus. So far there are 2 kinds of alsa profiles, one is from alsa ucm, the
other is from mixer profile-sets, their priorities are all far less than 0x7fff
*/
#define PROFILE_PRIO_BONUS 0x8000
struct userdata {
pa_core *core;
pa_module *module;
@ -144,7 +153,7 @@ static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
uint32_t idx;
cp = pa_card_profile_new(ap->name, ap->description, sizeof(struct profile_data));
cp->priority = ap->priority;
cp->priority = ap->priority ? ap->priority : 1;
cp->input_name = pa_xstrdup(ap->input_name);
cp->output_name = pa_xstrdup(ap->output_name);
@ -459,9 +468,19 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
* as available (well, "unknown" to be precise, but there's little
* practical difference).
*
* When all output ports are unavailable, we know that all sinks are
* unavailable, and therefore the profile is marked unavailable as well.
* The same applies to input ports as well, of course.
* A profile will be marked unavailable:
* only contains output ports and all ports are unavailable
* only contains input ports and all ports are unavailable
* contains both input and output ports and all ports are unavailable
*
* A profile will be awarded priority bonus:
* only contains output ports and at least one port is available
* only contains input ports and at least one port is available
* contains both output and input ports and at least one output port
* and one input port are available
*
* The rest profiles will not be marked unavailable and will not be
* awarded priority bonus
*
* If there are no output ports at all, but the profile contains at least
* one sink, then the output is considered to be available. */
@ -476,6 +495,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
bool found_available_output_port = false;
pa_available_t available = PA_AVAILABLE_UNKNOWN;
profile->priority &= ~PROFILE_PRIO_BONUS;
PA_HASHMAP_FOREACH(port, u->card->ports, state2) {
if (!pa_hashmap_get(port->profiles, profile->name))
continue;
@ -493,8 +513,15 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
}
}
if ((has_input_port && !found_available_input_port) || (has_output_port && !found_available_output_port))
available = PA_AVAILABLE_NO;
if ((has_input_port && found_available_input_port && !has_output_port) ||
(has_output_port && found_available_output_port && !has_input_port) ||
(has_input_port && found_available_input_port && has_output_port && found_available_output_port))
profile->priority |= PROFILE_PRIO_BONUS;
if ((has_input_port && !found_available_input_port && has_output_port && !found_available_output_port) ||
(has_input_port && !found_available_input_port && !has_output_port) ||
(has_output_port && !found_available_output_port && !has_input_port))
available = PA_AVAILABLE_NO;
/* We want to update the active profile's status last, so logic that
* may change the active profile based on profile availability status
@ -621,6 +648,7 @@ static void init_jacks(struct userdata *u) {
void *state;
pa_alsa_path* path;
pa_alsa_jack* jack;
char buf[64];
u->jacks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
@ -663,9 +691,10 @@ static void init_jacks(struct userdata *u) {
}
}
pa_alsa_mixer_set_fdlist(u->mixers, jack->mixer_handle, u->core->mainloop);
jack->melem = pa_alsa_mixer_find_card(jack->mixer_handle, jack->alsa_name, 0);
jack->melem = pa_alsa_mixer_find_card(jack->mixer_handle, &jack->alsa_id, 0);
if (!jack->melem) {
pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name);
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &jack->alsa_id);
pa_log_warn("Jack %s seems to have disappeared.", buf);
pa_alsa_jack_set_has_control(jack, false);
continue;
}
@ -675,6 +704,42 @@ static void init_jacks(struct userdata *u) {
}
}
static void prune_singleton_availability_groups(pa_hashmap *ports) {
pa_device_port *p;
pa_hashmap *group_counts;
void *state, *count;
const char *group;
/* Collect groups and erase those that don't have more than 1 path */
group_counts = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
PA_HASHMAP_FOREACH(p, ports, state) {
if (p->availability_group) {
count = pa_hashmap_get(group_counts, p->availability_group);
pa_hashmap_remove(group_counts, p->availability_group);
pa_hashmap_put(group_counts, p->availability_group, PA_UINT_TO_PTR(PA_PTR_TO_UINT(count) + 1));
}
}
/* Now we have an availability_group -> count map, let's drop all groups
* that have only one member */
PA_HASHMAP_FOREACH_KV(group, count, group_counts, state) {
if (count == PA_UINT_TO_PTR(1))
pa_hashmap_remove(group_counts, group);
}
PA_HASHMAP_FOREACH(p, ports, state) {
if (p->availability_group && !pa_hashmap_get(group_counts, p->availability_group)) {
pa_log_debug("Pruned singleton availability group %s from port %s", p->availability_group, p->name);
pa_xfree(p->availability_group);
p->availability_group = NULL;
}
}
pa_hashmap_free(group_counts);
}
static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *device_id) {
char *t;
const char *n;
@ -784,7 +849,9 @@ int pa__init(pa_module *m) {
const char *description;
const char *profile_str = NULL;
char *fn = NULL;
char *udev_args = NULL;
bool namereg_fail = false;
int err = -PA_MODULE_ERR_UNSPECIFIED, rval;
pa_alsa_refcnt_inc();
@ -812,6 +879,47 @@ int pa__init(pa_module *m) {
goto fail;
}
#ifdef HAVE_UDEV
udev_args = pa_udev_get_property(u->alsa_card_index, PULSE_MODARGS);
#endif
if (udev_args) {
bool udev_modargs_success = true;
pa_modargs *temp_ma = pa_modargs_new(udev_args, valid_modargs);
if (temp_ma) {
/* do not try to replace device_id */
if (pa_modargs_remove_key(temp_ma, "device_id") == 0) {
pa_log_warn("Unexpected 'device_id' module argument override ignored from udev " PULSE_MODARGS "='%s'", udev_args);
}
/* Implement modargs override by copying original module arguments
* over udev entry arguments ignoring duplicates. */
if (pa_modargs_merge_missing(temp_ma, u->modargs, valid_modargs) == 0) {
/* swap module arguments */
pa_modargs *old_ma = u->modargs;
u->modargs = temp_ma;
temp_ma = old_ma;
pa_log_info("Applied module arguments override from udev " PULSE_MODARGS "='%s'", udev_args);
} else {
pa_log("Failed to apply module arguments override from udev " PULSE_MODARGS "='%s'", udev_args);
udev_modargs_success = false;
}
pa_modargs_free(temp_ma);
} else {
pa_log("Failed to parse module arguments from udev " PULSE_MODARGS "='%s'", udev_args);
udev_modargs_success = false;
}
pa_xfree(udev_args);
if (!udev_modargs_success)
goto fail;
}
if (pa_modargs_get_value_boolean(u->modargs, "ignore_dB", &ignore_dB) < 0) {
pa_log("Failed to parse ignore_dB argument.");
goto fail;
@ -841,7 +949,12 @@ int pa__init(pa_module *m) {
snd_config_update_free_global();
if (u->use_ucm && !pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index)) {
rval = u->use_ucm ? pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index) : -1;
if (rval == -PA_ALSA_ERR_UCM_LINKED) {
err = -PA_MODULE_ERR_SKIP;
goto fail;
}
if (rval == 0) {
pa_log_info("Found UCM profiles");
u->profile_set = pa_alsa_ucm_add_profile_set(&u->ucm, &u->core->default_channel_map);
@ -918,6 +1031,7 @@ int pa__init(pa_module *m) {
}
add_disabled_profile(data.profiles);
prune_singleton_availability_groups(data.ports);
if (pa_modargs_get_proplist(u->modargs, "card_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
pa_log("Invalid properties");
@ -1009,7 +1123,7 @@ fail:
pa__done(m);
return -1;
return err;
}
int pa__get_n_used(pa_module *m) {