mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
alsa-mixer: Handle the index for ALSA mixer jack identifiers
Some systems have two jacks with same name but different index, we need to take index into consideration to use both jacks. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/272>
This commit is contained in:
parent
3ecea410d7
commit
aad2fca0c9
6 changed files with 73 additions and 58 deletions
|
|
@ -113,7 +113,7 @@ struct description2_map {
|
||||||
pa_device_port_type_t type;
|
pa_device_port_type_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *alsa_id_str(char *dst, size_t dst_len, pa_alsa_mixer_id *id) {
|
char *pa_alsa_mixer_id_to_string(char *dst, size_t dst_len, pa_alsa_mixer_id *id) {
|
||||||
if (id->index > 0) {
|
if (id->index > 0) {
|
||||||
snprintf(dst, dst_len, "'%s',%d", id->name, id->index);
|
snprintf(dst, dst_len, "'%s',%d", id->name, id->index);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -153,7 +153,7 @@ static int alsa_id_decode(const char *src, char *name, int *index) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
pa_alsa_jack *jack;
|
pa_alsa_jack *jack;
|
||||||
|
|
||||||
pa_assert(name);
|
pa_assert(name);
|
||||||
|
|
@ -162,7 +162,8 @@ pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name
|
||||||
jack->path = path;
|
jack->path = path;
|
||||||
jack->mixer_device_name = pa_xstrdup(mixer_device_name);
|
jack->mixer_device_name = pa_xstrdup(mixer_device_name);
|
||||||
jack->name = pa_xstrdup(name);
|
jack->name = pa_xstrdup(name);
|
||||||
jack->alsa_name = pa_sprintf_malloc("%s Jack", name);
|
jack->alsa_id.name = pa_sprintf_malloc("%s Jack", name);
|
||||||
|
jack->alsa_id.index = index;
|
||||||
jack->state_unplugged = PA_AVAILABLE_NO;
|
jack->state_unplugged = PA_AVAILABLE_NO;
|
||||||
jack->state_plugged = PA_AVAILABLE_YES;
|
jack->state_plugged = PA_AVAILABLE_YES;
|
||||||
jack->ucm_devices = pa_dynarray_new(NULL);
|
jack->ucm_devices = pa_dynarray_new(NULL);
|
||||||
|
|
@ -177,7 +178,7 @@ void pa_alsa_jack_free(pa_alsa_jack *jack) {
|
||||||
pa_dynarray_free(jack->ucm_hw_mute_devices);
|
pa_dynarray_free(jack->ucm_hw_mute_devices);
|
||||||
pa_dynarray_free(jack->ucm_devices);
|
pa_dynarray_free(jack->ucm_devices);
|
||||||
|
|
||||||
pa_xfree(jack->alsa_name);
|
pa_xfree(jack->alsa_id.name);
|
||||||
pa_xfree(jack->name);
|
pa_xfree(jack->name);
|
||||||
pa_xfree(jack->mixer_device_name);
|
pa_xfree(jack->mixer_device_name);
|
||||||
pa_xfree(jack);
|
pa_xfree(jack);
|
||||||
|
|
@ -835,7 +836,7 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -861,14 +862,14 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
||||||
if (value < e->db_fix->min_step) {
|
if (value < e->db_fix->min_step) {
|
||||||
value = e->db_fix->min_step;
|
value = e->db_fix->min_step;
|
||||||
snd_mixer_selem_set_playback_volume(me, c, value);
|
snd_mixer_selem_set_playback_volume(me, c, value);
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_debug("Playback volume for element %s channel %i was below the dB fix limit. "
|
pa_log_debug("Playback volume for element %s channel %i was below the dB fix limit. "
|
||||||
"Volume reset to %0.2f dB.", buf, c,
|
"Volume reset to %0.2f dB.", buf, c,
|
||||||
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
||||||
} else if (value > e->db_fix->max_step) {
|
} else if (value > e->db_fix->max_step) {
|
||||||
value = e->db_fix->max_step;
|
value = e->db_fix->max_step;
|
||||||
snd_mixer_selem_set_playback_volume(me, c, value);
|
snd_mixer_selem_set_playback_volume(me, c, value);
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_debug("Playback volume for element %s channel %i was over the dB fix limit. "
|
pa_log_debug("Playback volume for element %s channel %i was over the dB fix limit. "
|
||||||
"Volume reset to %0.2f dB.", buf, c,
|
"Volume reset to %0.2f dB.", buf, c,
|
||||||
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
||||||
|
|
@ -891,14 +892,14 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
||||||
if (value < e->db_fix->min_step) {
|
if (value < e->db_fix->min_step) {
|
||||||
value = e->db_fix->min_step;
|
value = e->db_fix->min_step;
|
||||||
snd_mixer_selem_set_capture_volume(me, c, value);
|
snd_mixer_selem_set_capture_volume(me, c, value);
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_debug("Capture volume for element %s channel %i was below the dB fix limit. "
|
pa_log_debug("Capture volume for element %s channel %i was below the dB fix limit. "
|
||||||
"Volume reset to %0.2f dB.", buf, c,
|
"Volume reset to %0.2f dB.", buf, c,
|
||||||
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
||||||
} else if (value > e->db_fix->max_step) {
|
} else if (value > e->db_fix->max_step) {
|
||||||
value = e->db_fix->max_step;
|
value = e->db_fix->max_step;
|
||||||
snd_mixer_selem_set_capture_volume(me, c, value);
|
snd_mixer_selem_set_capture_volume(me, c, value);
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_debug("Capture volume for element %s channel %i was over the dB fix limit. "
|
pa_log_debug("Capture volume for element %s channel %i was over the dB fix limit. "
|
||||||
"Volume reset to %0.2f dB.", buf, c,
|
"Volume reset to %0.2f dB.", buf, c,
|
||||||
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
|
||||||
|
|
@ -1006,7 +1007,7 @@ static int element_get_switch(pa_alsa_element *e, snd_mixer_t *m, bool *b) {
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1172,7 +1173,7 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1364,7 +1365,7 @@ static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) {
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1375,7 +1376,7 @@ static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) {
|
||||||
r = snd_mixer_selem_set_capture_switch_all(me, b);
|
r = snd_mixer_selem_set_capture_switch_all(me, b);
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
|
pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1419,7 +1420,7 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1464,7 +1465,7 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to set volume of %s: %s", buf, pa_alsa_strerror(errno));
|
pa_log_warn("Failed to set volume of %s: %s", buf, pa_alsa_strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1670,19 +1671,19 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
r = snd_mixer_selem_get_capture_volume_range(me, &e->min_volume, &e->max_volume);
|
r = snd_mixer_selem_get_capture_volume_range(me, &e->min_volume, &e->max_volume);
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to get volume range of %s: %s", buf, pa_alsa_strerror(r));
|
pa_log_warn("Failed to get volume range of %s: %s", buf, pa_alsa_strerror(r));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->min_volume >= e->max_volume) {
|
if (e->min_volume >= e->max_volume) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Your kernel driver is broken for element %s: it reports a volume range from %li to %li which makes no sense.",
|
pa_log_warn("Your kernel driver is broken for element %s: it reports a volume range from %li to %li which makes no sense.",
|
||||||
buf, e->min_volume, e->max_volume);
|
buf, e->min_volume, e->max_volume);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (e->volume_use == PA_ALSA_VOLUME_CONSTANT && (e->min_volume > e->constant_volume || e->max_volume < e->constant_volume)) {
|
if (e->volume_use == PA_ALSA_VOLUME_CONSTANT && (e->min_volume > e->constant_volume || e->max_volume < e->constant_volume)) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Constant volume %li configured for element %s, but the available range is from %li to %li.",
|
pa_log_warn("Constant volume %li configured for element %s, but the available range is from %li to %li.",
|
||||||
e->constant_volume, buf, e->min_volume, e->max_volume);
|
e->constant_volume, buf, e->min_volume, e->max_volume);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1690,7 +1691,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
|
|
||||||
|
|
||||||
if (e->db_fix && ((e->min_volume > e->db_fix->min_step) || (e->max_volume < e->db_fix->max_step))) {
|
if (e->db_fix && ((e->min_volume > e->db_fix->min_step) || (e->max_volume < e->db_fix->max_step))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the "
|
pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the "
|
||||||
"real hardware range (%li-%li). Disabling the decibel fix.", buf,
|
"real hardware range (%li-%li). Disabling the decibel fix.", buf,
|
||||||
e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume);
|
e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume);
|
||||||
|
|
@ -1717,19 +1718,19 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
long max_dB_checked = 0;
|
long max_dB_checked = 0;
|
||||||
|
|
||||||
if (element_ask_vol_dB(me, e->direction, e->min_volume, &min_dB_checked) < 0) {
|
if (element_ask_vol_dB(me, e->direction, e->min_volume, &min_dB_checked) < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->min_volume);
|
pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->min_volume);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB_checked) < 0) {
|
if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB_checked) < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->max_volume);
|
pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->max_volume);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_dB != min_dB_checked || max_dB != max_dB_checked) {
|
if (min_dB != min_dB_checked || max_dB != max_dB_checked) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Your kernel driver is broken: the reported dB range for %s (from %0.2f dB to %0.2f dB) "
|
pa_log_warn("Your kernel driver is broken: the reported dB range for %s (from %0.2f dB to %0.2f dB) "
|
||||||
"doesn't match the dB values at minimum and maximum volume levels: %0.2f dB at level %li, "
|
"doesn't match the dB values at minimum and maximum volume levels: %0.2f dB at level %li, "
|
||||||
"%0.2f dB at level %li.", buf, min_dB / 100.0, max_dB / 100.0,
|
"%0.2f dB at level %li.", buf, min_dB / 100.0, max_dB / 100.0,
|
||||||
|
|
@ -1752,7 +1753,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
|
|
||||||
if (e->volume_limit >= 0) {
|
if (e->volume_limit >= 0) {
|
||||||
if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume) {
|
if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Volume limit for element %s of path %s is invalid: %li isn't within the valid range "
|
pa_log_warn("Volume limit for element %s of path %s is invalid: %li isn't within the valid range "
|
||||||
"%li-%li. The volume limit is ignored.",
|
"%li-%li. The volume limit is ignored.",
|
||||||
buf, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume);
|
buf, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume);
|
||||||
|
|
@ -1764,7 +1765,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
e->db_fix->max_step = e->max_volume;
|
e->db_fix->max_step = e->max_volume;
|
||||||
e->max_dB = ((double) e->db_fix->db_values[e->db_fix->max_step - e->db_fix->min_step]) / 100.0;
|
e->max_dB = ((double) e->db_fix->db_values[e->db_fix->max_step - e->db_fix->min_step]) / 100.0;
|
||||||
} else if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB) < 0) {
|
} else if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB) < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to get dB value of %s: %s", buf, pa_alsa_strerror(r));
|
pa_log_warn("Failed to get dB value of %s: %s", buf, pa_alsa_strerror(r));
|
||||||
e->has_dB = false;
|
e->has_dB = false;
|
||||||
} else
|
} else
|
||||||
|
|
@ -1809,7 +1810,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->n_channels <= 0) {
|
if (e->n_channels <= 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Volume element %s with no channels?", buf);
|
pa_log_warn("Volume element %s with no channels?", buf);
|
||||||
return false;
|
return false;
|
||||||
} else if (e->n_channels > POSITION_MASK_CHANNELS) {
|
} else if (e->n_channels > POSITION_MASK_CHANNELS) {
|
||||||
|
|
@ -1824,7 +1825,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
|
||||||
* Since the array size is fixed at POSITION_MASK_CHANNELS, we obviously
|
* Since the array size is fixed at POSITION_MASK_CHANNELS, we obviously
|
||||||
* don't support elements with more than POSITION_MASK_CHANNELS
|
* don't support elements with more than POSITION_MASK_CHANNELS
|
||||||
* channels... */
|
* channels... */
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", buf, e->n_channels);
|
pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", buf, e->n_channels);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1973,12 +1974,12 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index);
|
new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index);
|
||||||
pa_xfree(j->alsa_name);
|
pa_xfree(j->alsa_id.name);
|
||||||
j->alsa_name = new_name;
|
j->alsa_id.name = new_name;
|
||||||
j->append_pcm_to_name = false;
|
j->append_pcm_to_name = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
has_control = pa_alsa_mixer_find_card(m, j->alsa_name, 0) != NULL;
|
has_control = pa_alsa_mixer_find_card(m, &j->alsa_id, 0) != NULL;
|
||||||
pa_alsa_jack_set_has_control(j, has_control);
|
pa_alsa_jack_set_has_control(j, has_control);
|
||||||
|
|
||||||
if (j->has_control) {
|
if (j->has_control) {
|
||||||
|
|
@ -2041,19 +2042,26 @@ finish:
|
||||||
|
|
||||||
static pa_alsa_jack* jack_get(pa_alsa_path *p, const char *section) {
|
static pa_alsa_jack* jack_get(pa_alsa_path *p, const char *section) {
|
||||||
pa_alsa_jack *j;
|
pa_alsa_jack *j;
|
||||||
|
char *name;
|
||||||
|
int index;
|
||||||
|
|
||||||
if (!pa_startswith(section, "Jack "))
|
if (!pa_startswith(section, "Jack "))
|
||||||
return NULL;
|
return NULL;
|
||||||
section += 5;
|
section += 5;
|
||||||
|
|
||||||
if (p->last_jack && pa_streq(p->last_jack->name, section))
|
name = alloca(strlen(section) + 1);
|
||||||
|
if (alsa_id_decode(section, name, &index))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (p->last_jack && pa_streq(p->last_jack->name, name) &&
|
||||||
|
p->last_jack->alsa_id.index == index)
|
||||||
return p->last_jack;
|
return p->last_jack;
|
||||||
|
|
||||||
PA_LLIST_FOREACH(j, p->jacks)
|
PA_LLIST_FOREACH(j, p->jacks)
|
||||||
if (pa_streq(j->name, section))
|
if (pa_streq(j->name, name) && j->alsa_id.index == index)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
j = pa_alsa_jack_new(p, NULL, section);
|
j = pa_alsa_jack_new(p, NULL, name, index);
|
||||||
PA_LLIST_INSERT_AFTER(pa_alsa_jack, p->jacks, p->last_jack, j);
|
PA_LLIST_INSERT_AFTER(pa_alsa_jack, p->jacks, p->last_jack, j);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
|
@ -2645,7 +2653,7 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx)
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -2658,7 +2666,7 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx)
|
||||||
r = snd_mixer_selem_set_capture_switch_all(me, alsa_idx);
|
r = snd_mixer_selem_set_capture_switch_all(me, alsa_idx);
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
|
pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2666,7 +2674,7 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx)
|
||||||
pa_assert(e->enumeration_use == PA_ALSA_ENUMERATION_SELECT);
|
pa_assert(e->enumeration_use == PA_ALSA_ENUMERATION_SELECT);
|
||||||
|
|
||||||
if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0) {
|
if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Failed to set enumeration of %s: %s", buf, pa_alsa_strerror(errno));
|
pa_log_warn("Failed to set enumeration of %s: %s", buf, pa_alsa_strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2723,7 +2731,7 @@ static int option_verify(pa_alsa_option *o) {
|
||||||
|
|
||||||
if (o->element->enumeration_use != PA_ALSA_ENUMERATION_SELECT &&
|
if (o->element->enumeration_use != PA_ALSA_ENUMERATION_SELECT &&
|
||||||
o->element->switch_use != PA_ALSA_SWITCH_SELECT) {
|
o->element->switch_use != PA_ALSA_SWITCH_SELECT) {
|
||||||
alsa_id_str(buf, sizeof(buf), &o->element->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &o->element->alsa_id);
|
||||||
pa_log("Element %s of option %s not set for select.", buf, o->name);
|
pa_log("Element %s of option %s not set for select.", buf, o->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -2731,7 +2739,7 @@ static int option_verify(pa_alsa_option *o) {
|
||||||
if (o->element->switch_use == PA_ALSA_SWITCH_SELECT &&
|
if (o->element->switch_use == PA_ALSA_SWITCH_SELECT &&
|
||||||
!pa_streq(o->alsa_name, "on") &&
|
!pa_streq(o->alsa_name, "on") &&
|
||||||
!pa_streq(o->alsa_name, "off")) {
|
!pa_streq(o->alsa_name, "off")) {
|
||||||
alsa_id_str(buf, sizeof(buf), &o->element->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &o->element->alsa_id);
|
||||||
pa_log("Switch %s options need be named off or on ", buf);
|
pa_log("Switch %s options need be named off or on ", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -2757,13 +2765,13 @@ static int element_verify(pa_alsa_element *e) {
|
||||||
(e->required_any != PA_ALSA_REQUIRED_IGNORE && e->required_any == e->required_absent) ||
|
(e->required_any != PA_ALSA_REQUIRED_IGNORE && e->required_any == e->required_absent) ||
|
||||||
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required_any != PA_ALSA_REQUIRED_IGNORE) ||
|
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required_any != PA_ALSA_REQUIRED_IGNORE) ||
|
||||||
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required != PA_ALSA_REQUIRED_IGNORE)) {
|
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required != PA_ALSA_REQUIRED_IGNORE)) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log("Element %s cannot be required and absent at the same time.", buf);
|
pa_log("Element %s cannot be required and absent at the same time.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->switch_use == PA_ALSA_SWITCH_SELECT && e->enumeration_use == PA_ALSA_ENUMERATION_SELECT) {
|
if (e->switch_use == PA_ALSA_SWITCH_SELECT && e->enumeration_use == PA_ALSA_ENUMERATION_SELECT) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log("Element %s cannot set select for both switch and enumeration.", buf);
|
pa_log("Element %s cannot set select for both switch and enumeration.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -3168,16 +3176,17 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m
|
||||||
pa_log_debug("Probing path '%s'", p->name);
|
pa_log_debug("Probing path '%s'", p->name);
|
||||||
|
|
||||||
PA_LLIST_FOREACH(j, p->jacks) {
|
PA_LLIST_FOREACH(j, p->jacks) {
|
||||||
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &j->alsa_id);
|
||||||
if (jack_probe(j, mapping, m) < 0) {
|
if (jack_probe(j, mapping, m) < 0) {
|
||||||
p->supported = false;
|
p->supported = false;
|
||||||
pa_log_debug("Probe of jack '%s' failed.", j->alsa_name);
|
pa_log_debug("Probe of jack %s failed.", buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pa_log_debug("Probe of jack '%s' succeeded (%s)", j->alsa_name, j->has_control ? "found!" : "not found");
|
pa_log_debug("Probe of jack %s succeeded (%s)", buf, j->has_control ? "found!" : "not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
PA_LLIST_FOREACH(e, p->elements) {
|
PA_LLIST_FOREACH(e, p->elements) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
if (element_probe(e, m) < 0) {
|
if (element_probe(e, m) < 0) {
|
||||||
p->supported = false;
|
p->supported = false;
|
||||||
pa_log_debug("Probe of element %s failed.", buf);
|
pa_log_debug("Probe of element %s failed.", buf);
|
||||||
|
|
@ -3286,7 +3295,7 @@ void pa_alsa_setting_dump(pa_alsa_setting *s) {
|
||||||
void pa_alsa_jack_dump(pa_alsa_jack *j) {
|
void pa_alsa_jack_dump(pa_alsa_jack *j) {
|
||||||
pa_assert(j);
|
pa_assert(j);
|
||||||
|
|
||||||
pa_log_debug("Jack %s, alsa_name='%s', detection %s", j->name, j->alsa_name, j->has_control ? "possible" : "unavailable");
|
pa_log_debug("Jack %s, alsa_name='%s', index='%d', detection %s", j->name, j->alsa_id.name, j->alsa_id.index, j->has_control ? "possible" : "unavailable");
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa_alsa_option_dump(pa_alsa_option *o) {
|
void pa_alsa_option_dump(pa_alsa_option *o) {
|
||||||
|
|
@ -3306,7 +3315,7 @@ void pa_alsa_element_dump(pa_alsa_element *e) {
|
||||||
pa_alsa_option *o;
|
pa_alsa_option *o;
|
||||||
pa_assert(e);
|
pa_assert(e);
|
||||||
|
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_debug("Element %s, direction=%i, switch=%i, volume=%i, volume_limit=%li, enumeration=%i, required=%i, required_any=%i, required_absent=%i, mask=0x%llx, n_channels=%u, override_map=%02x",
|
pa_log_debug("Element %s, direction=%i, switch=%i, volume=%i, volume_limit=%li, enumeration=%i, required=%i, required_any=%i, required_absent=%i, mask=0x%llx, n_channels=%u, override_map=%02x",
|
||||||
buf,
|
buf,
|
||||||
e->direction,
|
e->direction,
|
||||||
|
|
@ -3366,7 +3375,7 @@ static void element_set_callback(pa_alsa_element *e, snd_mixer_t *m, snd_mixer_e
|
||||||
|
|
||||||
SELEM_INIT(sid, &e->alsa_id);
|
SELEM_INIT(sid, &e->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &e->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &e->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3661,7 +3670,7 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_
|
||||||
|
|
||||||
SELEM_INIT(sid, &a->alsa_id);
|
SELEM_INIT(sid, &a->alsa_id);
|
||||||
if (!(me = snd_mixer_find_selem(m, sid))) {
|
if (!(me = snd_mixer_find_selem(m, sid))) {
|
||||||
alsa_id_str(buf, sizeof(buf), &a->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &a->alsa_id);
|
||||||
pa_log_warn("Element %s seems to have disappeared.", buf);
|
pa_log_warn("Element %s seems to have disappeared.", buf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -3692,7 +3701,7 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_
|
||||||
return false;
|
return false;
|
||||||
for (s = 0; s <= SND_MIXER_SCHN_LAST; s++)
|
for (s = 0; s <= SND_MIXER_SCHN_LAST; s++)
|
||||||
if (a->masks[s][a->n_channels-1] != b->masks[s][b->n_channels-1]) {
|
if (a->masks[s][a->n_channels-1] != b->masks[s][b->n_channels-1]) {
|
||||||
alsa_id_str(buf, sizeof(buf), &a->alsa_id);
|
pa_alsa_mixer_id_to_string(buf, sizeof(buf), &a->alsa_id);
|
||||||
pa_log_debug("Element %s is not a subset - mask a: 0x%" PRIx64 ", mask b: 0x%" PRIx64 ", at channel %d",
|
pa_log_debug("Element %s is not a subset - mask a: 0x%" PRIx64 ", mask b: 0x%" PRIx64 ", at channel %d",
|
||||||
buf, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s);
|
buf, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -3769,7 +3778,8 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
PA_LLIST_FOREACH(jb, p2->jacks) {
|
PA_LLIST_FOREACH(jb, p2->jacks) {
|
||||||
if (jb->has_control && pa_streq(jb->alsa_name, ja->alsa_name) &&
|
if (jb->has_control && pa_streq(ja->alsa_id.name, jb->alsa_id.name) &&
|
||||||
|
(ja->alsa_id.index == jb->alsa_id.index) &&
|
||||||
(ja->state_plugged == jb->state_plugged) &&
|
(ja->state_plugged == jb->state_plugged) &&
|
||||||
(ja->state_unplugged == jb->state_unplugged)) {
|
(ja->state_unplugged == jb->state_unplugged)) {
|
||||||
exists = true;
|
exists = true;
|
||||||
|
|
@ -4459,7 +4469,8 @@ static void profile_set_set_availability_groups(pa_alsa_profile_set *ps) {
|
||||||
PA_LLIST_FOREACH(j2, p2->jacks) {
|
PA_LLIST_FOREACH(j2, p2->jacks) {
|
||||||
if (!j2->has_control || j2->state_plugged == PA_AVAILABLE_NO)
|
if (!j2->has_control || j2->state_plugged == PA_AVAILABLE_NO)
|
||||||
continue;
|
continue;
|
||||||
if (pa_streq(j->alsa_name, j2->alsa_name)) {
|
if (pa_streq(j->alsa_id.name, j2->alsa_id.name) &&
|
||||||
|
j->alsa_id.index == j2->alsa_id.index) {
|
||||||
j->state_plugged = PA_AVAILABLE_UNKNOWN;
|
j->state_plugged = PA_AVAILABLE_UNKNOWN;
|
||||||
j2->state_plugged = PA_AVAILABLE_UNKNOWN;
|
j2->state_plugged = PA_AVAILABLE_UNKNOWN;
|
||||||
found = p2->availability_group;
|
found = p2->availability_group;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ struct pa_alsa_mixer_id {
|
||||||
int index;
|
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
|
/* 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
|
* of the element is an enumeration item, or a switch status if the
|
||||||
* element is a switch item. */
|
* element is a switch item. */
|
||||||
|
|
@ -179,8 +181,8 @@ struct pa_alsa_jack {
|
||||||
snd_mixer_t *mixer_handle;
|
snd_mixer_t *mixer_handle;
|
||||||
char *mixer_device_name;
|
char *mixer_device_name;
|
||||||
|
|
||||||
|
struct pa_alsa_mixer_id alsa_id;
|
||||||
char *name; /* E g "Headphone" */
|
char *name; /* E g "Headphone" */
|
||||||
char *alsa_name; /* E g "Headphone Jack" */
|
|
||||||
bool has_control; /* is the jack itself present? */
|
bool has_control; /* is the jack itself present? */
|
||||||
bool plugged_in; /* is this jack currently plugged in? */
|
bool plugged_in; /* is this jack currently plugged in? */
|
||||||
snd_mixer_elem_t *melem; /* Jack detection handle */
|
snd_mixer_elem_t *melem; /* Jack detection handle */
|
||||||
|
|
@ -196,7 +198,7 @@ struct pa_alsa_jack {
|
||||||
bool append_pcm_to_name;
|
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_free(pa_alsa_jack *jack);
|
||||||
void pa_alsa_jack_set_has_control(pa_alsa_jack *jack, bool has_control);
|
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);
|
void pa_alsa_jack_set_plugged_in(pa_alsa_jack *jack, bool plugged_in);
|
||||||
|
|
|
||||||
|
|
@ -1719,7 +1719,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);
|
pa_log("[%s] No mixer device name for JackControl \"%s\"", device_name, jack_control);
|
||||||
return NULL;
|
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);
|
PA_LLIST_PREPEND(pa_alsa_jack, ucm->jacks, j);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
|
@ -1953,7 +1953,7 @@ static void ucm_mapping_jack_probe(pa_alsa_mapping *m, pa_hashmap *mixers) {
|
||||||
continue;
|
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_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);
|
pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1635,8 +1635,8 @@ static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, name, 0, 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) {
|
snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) {
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ const char* pa_alsa_strerror(int errnum);
|
||||||
|
|
||||||
bool pa_alsa_may_tsched(bool want);
|
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_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);
|
snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe);
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,7 @@ static void init_jacks(struct userdata *u) {
|
||||||
void *state;
|
void *state;
|
||||||
pa_alsa_path* path;
|
pa_alsa_path* path;
|
||||||
pa_alsa_jack* jack;
|
pa_alsa_jack* jack;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
u->jacks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
|
u->jacks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
|
||||||
|
|
||||||
|
|
@ -665,9 +666,10 @@ static void init_jacks(struct userdata *u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pa_alsa_mixer_set_fdlist(u->mixers, jack->mixer_handle, u->core->mainloop);
|
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) {
|
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);
|
pa_alsa_jack_set_has_control(jack, false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue