sound/usb: add dB range mapping quirks.
diff mbox

Message ID 1438070805-52951-1-git-send-email-yaowen@google.com
State New
Headers show

Commit Message

Yao-Wen Mao July 28, 2015, 8:06 a.m. UTC
Some usb audio devices don't follow the specification of the
volume range. Add dB_mapping_quirks to fix some devices' dB
ranges so that the function snd_mixer_selem_set_playback_dB in
alsa-lib can set the correct value for those devices.

Signed-off-by: Yao-Wen Mao <yaowen@google.com>
---
 sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Yao-Wen Mao July 28, 2015, 9:13 a.m. UTC | #1
Thanks for the reply!

Some usb audio devices don't follow the standard specification. (1/256 dB)
I think introducing the dB conversion factor may be a good idea.
Also I think mixer_maps.c is a good place to do this.

By the way, I can't figure out the meanings of FU, MU, SU, ... etc.
Could you tell me the meanings of them?
(I guess FUs are units which have volume controls?)

The devices which I tested has only one volume control shown in alsamixer.
I don't know if there are some devices have more than one volume factor.


thanks again,

Yao-Wen

On Tue, Jul 28, 2015 at 4:17 PM, Takashi Iwai <tiwai@suse.de> wrote:

> On Tue, 28 Jul 2015 10:06:45 +0200,
> Yao-Wen Mao wrote:
> >
> > Some usb audio devices don't follow the specification of the
> > volume range. Add dB_mapping_quirks to fix some devices' dB
> > ranges so that the function snd_mixer_selem_set_playback_dB in
> > alsa-lib can set the correct value for those devices.
> >
> > Signed-off-by: Yao-Wen Mao <yaowen@google.com>
>
> This can be done also by adding to mixer_maps.c.
> The map doesn't have to contain the name string but only with a dB
> entry (I think).
>
> OTOH, this patch shows the value factor to be corrected, so it may
> make more sense -- people can look at these as a reference.
>
> One thing I wonder, though: can it be simplified by introducing the dB
> conversion factor instead?  Do these devices have other FUs that have
> a different volume factor?
>
>
> thanks,
>
> Takashi
>
> > ---
> >  sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> >
> > diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> > index 6b3acba..b6b27dc 100644
> > --- a/sound/usb/mixer.c
> > +++ b/sound/usb/mixer.c
> > @@ -933,6 +933,32 @@ static void volume_control_quirks(struct
> usb_mixer_elem_info *cval,
> >       }
> >  }
> >
> > +/* dB mapping quirks */
> > +static void dB_mapping_quirks(struct usb_mixer_elem_info *cval,
> > +                           struct snd_kcontrol *kctl)
> > +{
> > +     switch (cval->mixer->chip->usb_id) {
> > +     case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
> > +             if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
> > +                     cval->dBmin = (convert_signed_value(cval,
> cval->min) * 100) / 16;
> > +                     cval->dBmax = (convert_signed_value(cval,
> cval->max) * 100) / 16;
> > +             }
> > +             break;
> > +     case USB_ID(0x21b4, 0x0081): /* Dragonfly DAC 1.2 */
> > +             if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
> > +                     cval->dBmin = convert_signed_value(cval,
> cval->min) * 100;
> > +                     cval->dBmax = convert_signed_value(cval,
> cval->max) * 100;
> > +             }
> > +             break;
> > +     case USB_ID(0x046d, 0x0a29): /* Logitech H800 */
> > +             if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
> > +                     cval->dBmin = convert_signed_value(cval,
> cval->min);
> > +                     cval->dBmax = convert_signed_value(cval,
> cval->max);
> > +             }
> > +             break;
> > +     }
> > +}
> > +
> >  /*
> >   * retrieve the minimum and maximum values for the specified control
> >   */
> > @@ -1027,6 +1053,10 @@ static int get_min_max_with_quirks(struct
> usb_mixer_elem_info *cval,
> >        */
> >       cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
> >       cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
> > +
> > +     if (kctl)
> > +             dB_mapping_quirks(cval, kctl);
> > +
> >       if (cval->dBmin > cval->dBmax) {
> >               /* something is wrong; assume it's either from/to 0dB */
> >               if (cval->dBmin < 0)
> > --
> > 2.5.0.rc2.392.g76e840b
> >
> >
>
Yao-Wen Mao July 28, 2015, 9:47 a.m. UTC | #2
On Tue, Jul 28, 2015 at 5:17 PM, Takashi Iwai <tiwai@suse.de> wrote:

> On Tue, 28 Jul 2015 11:13:56 +0200,
> Yao-Wen Mao wrote:
> >
> > Thanks for the reply!
> >
> > Some usb audio devices don't follow the standard specification. (1/256
> dB)
> > I think introducing the dB conversion factor may be a good idea.
> > Also I think mixer_maps.c is a good place to do this.
> >
> > By the way, I can't figure out the meanings of FU, MU, SU, ... etc.
> > Could you tell me the meanings of them?
> > (I guess FUs are units which have volume controls?)
>
> FU = Feature Unit
> MU = Mixer Unit
> SU = Selector Unit


Got it.

I will do this in mixer_maps.c and send PATCH v2.
Do I need to introduce the dB conversion factor?
Or just add the corresponding dBmin and dBmax?

thanks,

Yao-Wen




> > The devices which I tested has only one volume control shown in
> alsamixer.
> > I don't know if there are some devices have more than one volume factor.
> >
> >
> > thanks again,
> >
> > Yao-Wen
> >
> > On Tue, Jul 28, 2015 at 4:17 PM, Takashi Iwai <tiwai@suse.de> wrote:
> >
> > > On Tue, 28 Jul 2015 10:06:45 +0200,
> > > Yao-Wen Mao wrote:
> > > >
> > > > Some usb audio devices don't follow the specification of the
> > > > volume range. Add dB_mapping_quirks to fix some devices' dB
> > > > ranges so that the function snd_mixer_selem_set_playback_dB in
> > > > alsa-lib can set the correct value for those devices.
> > > >
> > > > Signed-off-by: Yao-Wen Mao <yaowen@google.com>
> > >
> > > This can be done also by adding to mixer_maps.c.
> > > The map doesn't have to contain the name string but only with a dB
> > > entry (I think).
> > >
> > > OTOH, this patch shows the value factor to be corrected, so it may
> > > make more sense -- people can look at these as a reference.
> > >
> > > One thing I wonder, though: can it be simplified by introducing the dB
> > > conversion factor instead?  Do these devices have other FUs that have
> > > a different volume factor?
> > >
> > >
> > > thanks,
> > >
> > > Takashi
> > >
> > > > ---
> > > >  sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++
> > > >  1 file changed, 30 insertions(+)
> > > >
> > > > diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> > > > index 6b3acba..b6b27dc 100644
> > > > --- a/sound/usb/mixer.c
> > > > +++ b/sound/usb/mixer.c
> > > > @@ -933,6 +933,32 @@ static void volume_control_quirks(struct
> > > usb_mixer_elem_info *cval,
> > > >       }
> > > >  }
> > > >
> > > > +/* dB mapping quirks */
> > > > +static void dB_mapping_quirks(struct usb_mixer_elem_info *cval,
> > > > +                           struct snd_kcontrol *kctl)
> > > > +{
> > > > +     switch (cval->mixer->chip->usb_id) {
> > > > +     case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
> > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> 0) {
> > > > +                     cval->dBmin = (convert_signed_value(cval,
> > > cval->min) * 100) / 16;
> > > > +                     cval->dBmax = (convert_signed_value(cval,
> > > cval->max) * 100) / 16;
> > > > +             }
> > > > +             break;
> > > > +     case USB_ID(0x21b4, 0x0081): /* Dragonfly DAC 1.2 */
> > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> 0) {
> > > > +                     cval->dBmin = convert_signed_value(cval,
> > > cval->min) * 100;
> > > > +                     cval->dBmax = convert_signed_value(cval,
> > > cval->max) * 100;
> > > > +             }
> > > > +             break;
> > > > +     case USB_ID(0x046d, 0x0a29): /* Logitech H800 */
> > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> 0) {
> > > > +                     cval->dBmin = convert_signed_value(cval,
> > > cval->min);
> > > > +                     cval->dBmax = convert_signed_value(cval,
> > > cval->max);
> > > > +             }
> > > > +             break;
> > > > +     }
> > > > +}
> > > > +
> > > >  /*
> > > >   * retrieve the minimum and maximum values for the specified control
> > > >   */
> > > > @@ -1027,6 +1053,10 @@ static int get_min_max_with_quirks(struct
> > > usb_mixer_elem_info *cval,
> > > >        */
> > > >       cval->dBmin = (convert_signed_value(cval, cval->min) * 100) /
> 256;
> > > >       cval->dBmax = (convert_signed_value(cval, cval->max) * 100) /
> 256;
> > > > +
> > > > +     if (kctl)
> > > > +             dB_mapping_quirks(cval, kctl);
> > > > +
> > > >       if (cval->dBmin > cval->dBmax) {
> > > >               /* something is wrong; assume it's either from/to 0dB
> */
> > > >               if (cval->dBmin < 0)
> > > > --
> > > > 2.5.0.rc2.392.g76e840b
> > > >
> > > >
> > >
> > [2  <text/html; UTF-8 (quoted-printable)>]
> >
>
Takashi Iwai July 28, 2015, 9:49 a.m. UTC | #3
On Tue, 28 Jul 2015 11:47:25 +0200,
Yao-Wen Mao wrote:
> 
> On Tue, Jul 28, 2015 at 5:17 PM, Takashi Iwai <tiwai@suse.de> wrote:
> 
> > On Tue, 28 Jul 2015 11:13:56 +0200,
> > Yao-Wen Mao wrote:
> > >
> > > Thanks for the reply!
> > >
> > > Some usb audio devices don't follow the standard specification. (1/256
> > dB)
> > > I think introducing the dB conversion factor may be a good idea.
> > > Also I think mixer_maps.c is a good place to do this.
> > >
> > > By the way, I can't figure out the meanings of FU, MU, SU, ... etc.
> > > Could you tell me the meanings of them?
> > > (I guess FUs are units which have volume controls?)
> >
> > FU = Feature Unit
> > MU = Mixer Unit
> > SU = Selector Unit
> 
> 
> Got it.
> 
> I will do this in mixer_maps.c and send PATCH v2.
> Do I need to introduce the dB conversion factor?
> Or just add the corresponding dBmin and dBmax?

I think it'd be enough to use dBmin/max as a first step, but it's
still helpful to write the dB scale correction in comments.


thanks,

Takashi


> 
> thanks,
> 
> Yao-Wen
> 
> 
> 
> 
> > > The devices which I tested has only one volume control shown in
> > alsamixer.
> > > I don't know if there are some devices have more than one volume factor.
> > >
> > >
> > > thanks again,
> > >
> > > Yao-Wen
> > >
> > > On Tue, Jul 28, 2015 at 4:17 PM, Takashi Iwai <tiwai@suse.de> wrote:
> > >
> > > > On Tue, 28 Jul 2015 10:06:45 +0200,
> > > > Yao-Wen Mao wrote:
> > > > >
> > > > > Some usb audio devices don't follow the specification of the
> > > > > volume range. Add dB_mapping_quirks to fix some devices' dB
> > > > > ranges so that the function snd_mixer_selem_set_playback_dB in
> > > > > alsa-lib can set the correct value for those devices.
> > > > >
> > > > > Signed-off-by: Yao-Wen Mao <yaowen@google.com>
> > > >
> > > > This can be done also by adding to mixer_maps.c.
> > > > The map doesn't have to contain the name string but only with a dB
> > > > entry (I think).
> > > >
> > > > OTOH, this patch shows the value factor to be corrected, so it may
> > > > make more sense -- people can look at these as a reference.
> > > >
> > > > One thing I wonder, though: can it be simplified by introducing the dB
> > > > conversion factor instead?  Do these devices have other FUs that have
> > > > a different volume factor?
> > > >
> > > >
> > > > thanks,
> > > >
> > > > Takashi
> > > >
> > > > > ---
> > > > >  sound/usb/mixer.c | 30 ++++++++++++++++++++++++++++++
> > > > >  1 file changed, 30 insertions(+)
> > > > >
> > > > > diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> > > > > index 6b3acba..b6b27dc 100644
> > > > > --- a/sound/usb/mixer.c
> > > > > +++ b/sound/usb/mixer.c
> > > > > @@ -933,6 +933,32 @@ static void volume_control_quirks(struct
> > > > usb_mixer_elem_info *cval,
> > > > >       }
> > > > >  }
> > > > >
> > > > > +/* dB mapping quirks */
> > > > > +static void dB_mapping_quirks(struct usb_mixer_elem_info *cval,
> > > > > +                           struct snd_kcontrol *kctl)
> > > > > +{
> > > > > +     switch (cval->mixer->chip->usb_id) {
> > > > > +     case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
> > > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> > 0) {
> > > > > +                     cval->dBmin = (convert_signed_value(cval,
> > > > cval->min) * 100) / 16;
> > > > > +                     cval->dBmax = (convert_signed_value(cval,
> > > > cval->max) * 100) / 16;
> > > > > +             }
> > > > > +             break;
> > > > > +     case USB_ID(0x21b4, 0x0081): /* Dragonfly DAC 1.2 */
> > > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> > 0) {
> > > > > +                     cval->dBmin = convert_signed_value(cval,
> > > > cval->min) * 100;
> > > > > +                     cval->dBmax = convert_signed_value(cval,
> > > > cval->max) * 100;
> > > > > +             }
> > > > > +             break;
> > > > > +     case USB_ID(0x046d, 0x0a29): /* Logitech H800 */
> > > > > +             if (strcmp(kctl->id.name, "PCM Playback Volume") ==
> > 0) {
> > > > > +                     cval->dBmin = convert_signed_value(cval,
> > > > cval->min);
> > > > > +                     cval->dBmax = convert_signed_value(cval,
> > > > cval->max);
> > > > > +             }
> > > > > +             break;
> > > > > +     }
> > > > > +}
> > > > > +
> > > > >  /*
> > > > >   * retrieve the minimum and maximum values for the specified control
> > > > >   */
> > > > > @@ -1027,6 +1053,10 @@ static int get_min_max_with_quirks(struct
> > > > usb_mixer_elem_info *cval,
> > > > >        */
> > > > >       cval->dBmin = (convert_signed_value(cval, cval->min) * 100) /
> > 256;
> > > > >       cval->dBmax = (convert_signed_value(cval, cval->max) * 100) /
> > 256;
> > > > > +
> > > > > +     if (kctl)
> > > > > +             dB_mapping_quirks(cval, kctl);
> > > > > +
> > > > >       if (cval->dBmin > cval->dBmax) {
> > > > >               /* something is wrong; assume it's either from/to 0dB
> > */
> > > > >               if (cval->dBmin < 0)
> > > > > --
> > > > > 2.5.0.rc2.392.g76e840b
> > > > >
> > > > >
> > > >
> > > [2  <text/html; UTF-8 (quoted-printable)>]
> > >
> >

Patch
diff mbox

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6b3acba..b6b27dc 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -933,6 +933,32 @@  static void volume_control_quirks(struct usb_mixer_elem_info *cval,
 	}
 }
 
+/* dB mapping quirks */
+static void dB_mapping_quirks(struct usb_mixer_elem_info *cval,
+			      struct snd_kcontrol *kctl)
+{
+	switch (cval->mixer->chip->usb_id) {
+	case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
+		if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
+			cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 16;
+			cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 16;
+		}
+		break;
+	case USB_ID(0x21b4, 0x0081): /* Dragonfly DAC 1.2 */
+		if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
+			cval->dBmin = convert_signed_value(cval, cval->min) * 100;
+			cval->dBmax = convert_signed_value(cval, cval->max) * 100;
+		}
+		break;
+	case USB_ID(0x046d, 0x0a29): /* Logitech H800 */
+		if (strcmp(kctl->id.name, "PCM Playback Volume") == 0) {
+			cval->dBmin = convert_signed_value(cval, cval->min);
+			cval->dBmax = convert_signed_value(cval, cval->max);
+		}
+		break;
+	}
+}
+
 /*
  * retrieve the minimum and maximum values for the specified control
  */
@@ -1027,6 +1053,10 @@  static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
 	 */
 	cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
 	cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
+
+	if (kctl)
+		dB_mapping_quirks(cval, kctl);
+
 	if (cval->dBmin > cval->dBmax) {
 		/* something is wrong; assume it's either from/to 0dB */
 		if (cval->dBmin < 0)