All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Anssi Hannula <anssi.hannula@iki.fi>
Cc: Yao-Wen Mao <yaowen@google.com>,
	alsa-devel@alsa-project.org, stable@vger.kernel.org
Subject: Re: [PATCH 1/2] ALSA: usb-audio: Add a volume scale quirk for AudioQuest DragonFly
Date: Mon, 17 Aug 2015 18:20:14 +0200	[thread overview]
Message-ID: <s5h1tf1khtt.wl-tiwai@suse.de> (raw)
In-Reply-To: <55D20548.2060004@iki.fi>

On Mon, 17 Aug 2015 18:01:12 +0200,
Anssi Hannula wrote:
> 
> Hi,
> 
> 17.08.2015, 17:16, Takashi Iwai kirjoitti:
> > On Sun, 16 Aug 2015 14:50:12 +0200,
> > Anssi Hannula wrote:
> >>
> >> AudioQuest DragonFly DAC reports a volume control range of 0..50
> >> (0x0000..0x0032) which in USB Audio means a range of 0 .. 0.2dB, which
> >> is obviously incorrect and causes software using the dB information in
> >> e.g. volume sliders to have a massive volume difference in 100..102%
> >> range.
> >>
> >> The actual volume mapping seems to be neither linear volume nor linear
> >> dB scale, but instead quite close to the cubic mapping e.g. alsamixer
> >> uses, with a range of -53...0 dB.
> >>
> >> Add a quirk for DragonFly to use a custom dB mapping, based on my
> >> measurements, using a 10-item range TLV (so it still fits in alsa-lib
> >> MAX_TLV_RANGE_SIZE).
> >>
> >> Tested on AudioQuest DragonFly HW v1.2. The quirk is only applied if the
> >> range is 0..50, so if this gets fixed/changed in later HW revisions it
> >> will no longer be applied.
> >>
> >> Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
> >> Cc: <stable@vger.kernel.org>
> >> ---
> >>  sound/usb/mixer_quirks.c | 37 +++++++++++++++++++++++++++++++++++++
> >>  1 file changed, 37 insertions(+)
> >>
> >> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> >> index 337c317ead6f..39d7f34e44e6 100644
> >> --- a/sound/usb/mixer_quirks.c
> >> +++ b/sound/usb/mixer_quirks.c
> >> @@ -37,6 +37,7 @@
> >>  #include <sound/control.h>
> >>  #include <sound/hwdep.h>
> >>  #include <sound/info.h>
> >> +#include <sound/tlv.h>
> >>  
> >>  #include "usbaudio.h"
> >>  #include "mixer.h"
> >> @@ -1733,6 +1734,38 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
> >>  	return 0;
> >>  }
> >>  
> >> +static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer)
> >> +{
> >> +	struct usb_mixer_elem_list *list;
> >> +	struct usb_mixer_elem_info *cval;
> >> +	static const int unit_id = 7;
> >> +
> >> +	/* approximation using 10 ranges based on output measurement on hw v1.2 */
> >> +	static const DECLARE_TLV_DB_RANGE(scale,
> >> +		 0,  1, TLV_DB_MINMAX_ITEM(-5300, -4970),
> >> +		 2,  5, TLV_DB_MINMAX_ITEM(-4710, -4160),
> >> +		 6,  7, TLV_DB_MINMAX_ITEM(-3884, -3710),
> >> +		 8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
> >> +		15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
> >> +		17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
> >> +		20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
> >> +		27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
> >> +		32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
> >> +		41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
> >> +	);
> >> +
> >> +	for (list = mixer->id_elems[unit_id]; list; list = list->next_id_elem) {
> >> +		cval = (struct usb_mixer_elem_info *)list;
> >> +		if (cval->control == UAC_FU_VOLUME &&
> >> +		    cval->min == 0 && cval->max == 50) {
> >> +			usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
> >> +			list->kctl->tlv.p = scale;
> >> +			list->kctl->vd[0].access |=  SNDRV_CTL_ELEM_ACCESS_TLV_READ;
> >> +			list->kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
> >> +		}
> >> +	}
> > 
> > Instead of looking through the list, just hooking at
> > build_feature_ctl() would be simpler in the end, I think.
> > E.g. something like:
> > 
> > --- a/sound/usb/mixer.c
> > +++ b/sound/usb/mixer.c
> > @@ -1334,6 +1334,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
> >  				SNDRV_CTL_ELEM_ACCESS_TLV_READ |
> >  				SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
> >  		}
> > +		mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl);
> >  	}
> >  
> >  	range = (cval->max - cval->min) / cval->res;
> > 
> > ... and the quirk implementation in mixer_quirks.c like
> > 
> > static void snd_dragonfly_quirk_db_scale(mixer, kctl)
> > {
> > 	usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
> > 	kctl->tlv.p = scale;
> > 	kctl->vd[0].access |=  SNDRV_CTL_ELEM_ACCESS_TLV_READ;
> > 	list->kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;	
> > }
> > 
> > void mixer_fu_apply_quirk(mixer, cval, unitid, kctl)
> > {
> > 	switch (mixer->chip->usb_id) {
> > 	case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
> > 		if (unitid == 7 && cval->min == 0 && cval->max == 50)
> > 			snd_dragonfly_quirk_db_scale(mixer, kctl);
> > 		break;
> > 	}
> > }
> 
> OK, seems like a good idea.
> 
> However, I just noticed another volume quirk for DragonFly has already
> been merged since I started looking into this:
> https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/?id=2d1cb7f658fb9c3ba8f9dab8aca297d4dfdec835
> 
> It sets a fixed dB linear range map of 0...50dB via mixer_maps.c, which
> doesn't seem 100% right to me. While it is much better than the
> unquirked 0...0.2dB, it causes e.g. pulseaudio mixer to show the nearly
> inaudible raw 0 as the "base" level. And, unless I made some silly
> mistake, the volume scale is not actually linear dB AFAICS.
> 
> Yao-Wen, did you have some basis for the assumption "dB conversion
> factor is 1" on DragonFly other than that it sounded approximately right?
> 
> Takashi, should I add removal of that "duplicate" quirk in the same
> commit (or a separate one)? (assuming my quirk turns out to be actually
> better/correct, of course)

Yes, it sounds good.


thanks,

Takashi

  reply	other threads:[~2015-08-17 16:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-16 12:50 [PATCH 1/2] ALSA: usb-audio: Add a volume scale quirk for AudioQuest DragonFly Anssi Hannula
2015-08-16 12:50 ` Anssi Hannula
2015-08-16 12:50 ` [PATCH 2/2] ALSA: usb-audio: Add sample rate inquiry " Anssi Hannula
2015-08-16 12:50   ` Anssi Hannula
2015-08-17 14:16 ` [PATCH 1/2] ALSA: usb-audio: Add a volume scale " Takashi Iwai
2015-08-17 14:16   ` Takashi Iwai
2015-08-17 16:01   ` Anssi Hannula
2015-08-17 16:20     ` Takashi Iwai [this message]
2015-12-13 18:49       ` [PATCH 1/2 v2] ALSA: usb-audio: Add a more accurate volume " Anssi Hannula
2015-12-13 18:49         ` Anssi Hannula
2015-12-13 18:49         ` [PATCH 2/2] ALSA: usb-audio: Add sample rate inquiry " Anssi Hannula
2015-12-13 18:49           ` Anssi Hannula
2015-12-14  9:42           ` Takashi Iwai
2015-12-14  9:42             ` Takashi Iwai
2015-12-14  9:41         ` [PATCH 1/2 v2] ALSA: usb-audio: Add a more accurate volume " Takashi Iwai
2015-12-14  9:41           ` Takashi Iwai
2015-08-19  3:00     ` [PATCH 1/2] ALSA: usb-audio: Add a volume scale " Yao-Wen Mao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5h1tf1khtt.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=anssi.hannula@iki.fi \
    --cc=stable@vger.kernel.org \
    --cc=yaowen@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.