On July 27, 2010 01:00:31 am you wrote:
On Mon, Jul 26, 2010 at 5:15 PM, Tim E. Real
<termtech(a)rogers.com> wrote:
On July 16, 2010 10:10:48 pm Tim E. Real wrote:
> Here we go!
snd_mixer_selem_get_playback_dB( )
>
> Problem solved? Accurate or not?
Not accurate with AK4524 chip. Read on...
[...]
Yikes! It's all coming back to me now, this
can of worms.
In my case the Delta101LT card has the AK4524 ADCs.
The dB step of the IPGA stage is constant at 0.5dB, but the
dB step of the DATT stage is not - anywhere from 6dB to 0.28dB !
And remember the IPGA and DATT controls were combined, complicating
things. Meanwhile, other AK chips' DATT stages are constant step.
So does this mean 'alsamixer' has a bug for those card models with
combined IPGA? Which would that be?
Note the code in 'alsamixer' which prints out dB-values -- is this
correct or not?
Apparently there is a more advanced TLV based dB conversion.
snd_tlv_convert_to_dB()
If it is true, then in that respect, could we say this code should
be updated to use the TLV dB functions, for better accuracy?
Because at constant 0.5dB steps, the dB labels in alsamixer and
envy24control sure don't seem to correspond closely to what's
in the AK4524 datasheet dB table.
I do hope I'm reading that datasheet right !
Now, a question is: If TLV proves more accurate, do we really want
these odd value yet more accurate markings. Like -18.32 not -18.
Ie maybe pseudo 0.5 dB steps are better, visually.
I'm starting to think so.
It's a compromise after all. Not terribly accurate but it works.
It would become a problem if large inaccuracies arise with some chip.
Ah, maybe a user switch - regular constant, or TLV based for accuracy.
But I need to study that TLV stuff more...
See my other post about successful experiments with other dB funcs.
alsa-utils-1.0.23/alsamixer/mixer_display.c :
... if (control->flags & (TYPE_PVOLUME | TYPE_CVOLUME)) {
int (*get_vol_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t,
long *);
if (control->flags & TYPE_PVOLUME)
get_vol_func = snd_mixer_selem_get_playback_dB;
else
get_vol_func = snd_mixer_selem_get_capture_dB;
if (!(control->flags & HAS_VOLUME_1)) {
err = get_vol_func(control->elem, control->volume_channels[0], &db);
if (err >= 0) {
dbs = format_gain(db);
value_info = casprintf(" [%s %s]", _("dB gain:"), dbs);
free(dbs);
}
} else {
err = get_vol_func(control->elem, control->volume_channels[0], &db);
if (err >= 0)
err = get_vol_func(control->elem, control->volume_channels[1], &db2);
if (err >= 0) {
dbs = format_gain(db);
dbs2 = format_gain(db2);
value_info = casprintf(_(" [%s %s, %s]"), _("dB gain:"), dbs,
dbs2);
free(dbs);
free(dbs2);
}
}
}
----------------
Hey look what I found: A bunch of other dB related funcs like:
snd_mixer_selem_get_playback_dB_range (snd_mixer_elem_t *elem,
long *min, long *max)
"Get range in dB for playback volume of a mixer simple element. "
Now, this would certainly help with markings - if the dB step were
constant. We would know by the number of integer steps where the 0dB
point was etc.
But even better, look at this one! :
snd_mixer_selem_ask_playback_vol_dB (snd_mixer_elem_t *elem, long value,
long *dBvalue)
"Return corresponding dB value to an integer playback volume for a
mixer simple element. "
The thing is, for the AK4524, ALSA reports only a single constant
step of 0.5, and says the minimum is -63.5dB, with 163 integer steps
and a max of +18.5dB.
It does kinda sorta all work out, but in a average step sort of way...
ALSA would need to use a dB table (exists?) to be accurate here.
So, we're basing our scales on somewhat dubious info.
But no doubt these dB functions should be very helpful in drawing
scales for all ADC chips on ice1712 cards, no?
The "impossible" is possible?
Hope this helps. Tim.
Either that or make the scales optional and document them as being
potentially inaccurate in the manual page :-). Or just get rid of them
as more trouble than they're worth -- which might be the reason it
didn't have scales prior to my modification :-).
Yeah I know, I realised the
same thing.
I now have some hope for them.
Hope. Change. Yes we can... Sorry rambling on there.
And of course a switch to turn them on/off is a good idea.
The fundamental "scale" that we most need to be concerned about is
"127" representing unity gain on the ADC. Is that at least constant
across devices in the ice1712 family?
That was my original golden question. This
looks possible now.
I initially thought I'd do that,
but then got carried away once I realized how much space it was
wasting just to mark 0dB and (off).
Any examples of this inaccuracy in action?
As in the new 'envycontrol'
returned value, versus 'alsamixer', versus what it is supposed to be?
I thought that we could at least identify any that might be wildly out
of range by comparing against 'alsamixer' or 'amixer' values. But now
I'm wondering if those
are reliable given what you mentioned.
Given the fininte # of ADC/DACs and finite# of device models affected
by this, one could also decide to not get overly theoretical about
this and code-in any special values for specific card models that
aren't behaving properly.
Chip-specific code. Nah, let's try to stick with
what ALSA gives us to
work with. We'd surely want to check that TLV thing first.
Careful, "finite" today, but tomorrow maybe a new ADC chip, eh?
We'll see. The saga continues.... Tim.
I'll look into your ALSA API findings as
well.
Comments?
-- Niels
http://nielsmayer.com