[alsa-devel] [PATCH] ALSA: usb - Don't create "Speaker" mixer controls on headphones and headsets
A lot of headsets/headphones have a "Speaker" mixer control. This confuses PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
BugLink: https://bugs.launchpad.net/bugs/1082357 Signed-off-by: David Henningsson david.henningsson@canonical.com --- sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
I tried to find a better way of doing this using the existing quirk or map infrastructure but it didn't seem to fit, so added a new explicit check.
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 298070e..63fd758 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1094,6 +1094,32 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); }
+/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we + rename it to "Headphone". We determine if something is a headphone + similar to how udev determines form factor. */ +static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, + struct snd_card *card) +{ + const char *names_to_check[] = { + "Headset", "headset", "Headphone", "headphone", NULL}; + const char **s; + bool found = 0; + + if (strcmp("Speaker", kctl->id.name)) + return; + + for (s = names_to_check; *s; s++) + if (strstr(card->shortname, *s)) { + found = 1; + break; + } + + if (!found) + return; + + strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); +} + static void build_feature_ctl(struct mixer_build *state, void *raw_desc, unsigned int ctl_mask, int control, struct usb_audio_term *iterm, int unitid, @@ -1180,6 +1206,10 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, len = snprintf(kctl->id.name, sizeof(kctl->id.name), "Feature %d", unitid); } + + if (!mapped_name) + check_no_speaker_on_headset(kctl, state->mixer->chip->card); + /* determine the stream direction: * if the connected output is USB stream, then it's likely a * capture stream. otherwise it should be playback (hopefully :)
At Fri, 23 Nov 2012 13:48:55 +0100, David Henningsson wrote:
A lot of headsets/headphones have a "Speaker" mixer control. This confuses PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
BugLink: https://bugs.launchpad.net/bugs/1082357 Signed-off-by: David Henningsson david.henningsson@canonical.com
sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
I tried to find a better way of doing this using the existing quirk or map infrastructure but it didn't seem to fit, so added a new explicit check.
Hrm, indeed it's pretty hackish although it'd work heuristically.
If Clemens and Daniel have no objection, I can take it...
thanks,
Takashi
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 298070e..63fd758 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1094,6 +1094,32 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); }
+/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we
- rename it to "Headphone". We determine if something is a headphone
- similar to how udev determines form factor. */
+static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
struct snd_card *card)
+{
- const char *names_to_check[] = {
"Headset", "headset", "Headphone", "headphone", NULL};
- const char **s;
- bool found = 0;
- if (strcmp("Speaker", kctl->id.name))
return;
- for (s = names_to_check; *s; s++)
if (strstr(card->shortname, *s)) {
found = 1;
break;
}
- if (!found)
return;
- strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
+}
static void build_feature_ctl(struct mixer_build *state, void *raw_desc, unsigned int ctl_mask, int control, struct usb_audio_term *iterm, int unitid, @@ -1180,6 +1206,10 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, len = snprintf(kctl->id.name, sizeof(kctl->id.name), "Feature %d", unitid); }
if (!mapped_name)
check_no_speaker_on_headset(kctl, state->mixer->chip->card);
- /* determine the stream direction:
- if the connected output is USB stream, then it's likely a
- capture stream. otherwise it should be playback (hopefully :)
-- 1.7.9.5
Takashi Iwai wrote:
David Henningsson wrote:
A lot of headsets/headphones have a "Speaker" mixer control. This confuses PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
BugLink: https://bugs.launchpad.net/bugs/1082357 Signed-off-by: David Henningsson david.henningsson@canonical.com
sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
I tried to find a better way of doing this using the existing quirk or map infrastructure but it didn't seem to fit, so added a new explicit check.
Hrm, indeed it's pretty hackish although it'd work heuristically.
This is for devices that have explicitly marked their output terminal as speakers, so I don't see any method to make this less hackish.
Regards, Clemens
At Mon, 26 Nov 2012 11:06:41 +0100, Clemens Ladisch wrote:
Takashi Iwai wrote:
David Henningsson wrote:
A lot of headsets/headphones have a "Speaker" mixer control. This confuses PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
BugLink: https://bugs.launchpad.net/bugs/1082357 Signed-off-by: David Henningsson david.henningsson@canonical.com
sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
I tried to find a better way of doing this using the existing quirk or map infrastructure but it didn't seem to fit, so added a new explicit check.
Hrm, indeed it's pretty hackish although it'd work heuristically.
This is for devices that have explicitly marked their output terminal as speakers, so I don't see any method to make this less hackish.
OK, I merged it now.
thanks,
Takashi
2012-11-23 下午8:49 於 "David Henningsson" david.henningsson@canonical.com 寫道:
A lot of headsets/headphones have a "Speaker" mixer control. This confuses PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
does it really fix the problem since there are
1) usb headsets which has "PCM" volume control 2) some usb headphone support 5.1
does it mean that those non headset usb audio devices have a higher priority than usb headset ?
On 11/26/2012 04:21 PM, Raymond Yau wrote:
2012-11-23 下午8:49 於 "David Henningsson" <david.henningsson@canonical.com mailto:david.henningsson@canonical.com> 寫道:
A lot of headsets/headphones have a "Speaker" mixer control. This
confuses
PulseAudio to think it is a speaker instead of a headphone/headset. Therfore, we rename it to "Headphone".
We determine if something is a headphone similar to how udev determines form factor (see 78-sound-card.rules).
does it really fix the problem
It fixes a problem with a common class of Logitech stereo headsets.
since there are
- usb headsets which has "PCM" volume control
- some usb headphone support 5.1
These devices are unlikely to be affected by the patch. If you have a problem with any of these devices, it's a different bug.
participants (4)
-
Clemens Ladisch
-
David Henningsson
-
Raymond Yau
-
Takashi Iwai