[alsa-devel] Maximum 50 dB gain in ALSA softvol plugin
Hi,
The ALSA softvol plugin has a maximum gain of 50 dB (MAX_DB_UPPER_LIMIT is fixed to 50 in pcm/pcm_softvol.c). Is there some technical reason for this limit? These days when >16 bit audio is becoming common, it's not unreasonable to have large gain figures, and that is in fact a usecase I have right now.
I'm looking through the CONVERT_AREA and MULTI_DIV_foo macros to see if there's something there that degenerates when the gain factor becomes too large, but I'd thought I'd ask too rather than just do reverse engineering.
/Ricard
On Fri, 12 Jan 2018 17:02:03 +0100, Ricard Wanderlof wrote:
Hi,
The ALSA softvol plugin has a maximum gain of 50 dB (MAX_DB_UPPER_LIMIT is fixed to 50 in pcm/pcm_softvol.c). Is there some technical reason for this limit? These days when >16 bit audio is becoming common, it's not unreasonable to have large gain figures, and that is in fact a usecase I have right now.
I'm looking through the CONVERT_AREA and MULTI_DIV_foo macros to see if there's something there that degenerates when the gain factor becomes too large, but I'd thought I'd ask too rather than just do reverse engineering.
There is no more reason than "some reasonable limit".
Takashi
On Fri, 12 Jan 2018, Takashi Iwai wrote:
The ALSA softvol plugin has a maximum gain of 50 dB (MAX_DB_UPPER_LIMIT is fixed to 50 in pcm/pcm_softvol.c). Is there some technical reason for this limit? These days when >16 bit audio is becoming common, it's not unreasonable to have large gain figures, and that is in fact a usecase I have right now.
I'm looking through the CONVERT_AREA and MULTI_DIV_foo macros to see if there's something there that degenerates when the gain factor becomes too large, but I'd thought I'd ask too rather than just do reverse engineering.
There is no more reason than "some reasonable limit".
Ok, my suggestion would be set MAX_DB_UPPER_LIMIT to 90 dB. 90 dB comes out as 31622, which still is manageable when shifted up by VOL_SCALE_SHIFT (= 16), fitting in a 32-bit int. Thus it works in MULTI_DIV_short() too, where it is multiplied with the 16-bit sample value yielding an int.
I'll try it out and prepare a patch.
/Ricard
On Mon, 15 Jan 2018 14:14:13 +0100, Ricard Wanderlof wrote:
On Fri, 12 Jan 2018, Takashi Iwai wrote:
The ALSA softvol plugin has a maximum gain of 50 dB (MAX_DB_UPPER_LIMIT is fixed to 50 in pcm/pcm_softvol.c). Is there some technical reason for this limit? These days when >16 bit audio is becoming common, it's not unreasonable to have large gain figures, and that is in fact a usecase I have right now.
I'm looking through the CONVERT_AREA and MULTI_DIV_foo macros to see if there's something there that degenerates when the gain factor becomes too large, but I'd thought I'd ask too rather than just do reverse engineering.
There is no more reason than "some reasonable limit".
Ok, my suggestion would be set MAX_DB_UPPER_LIMIT to 90 dB. 90 dB comes out as 31622, which still is manageable when shifted up by VOL_SCALE_SHIFT (= 16), fitting in a 32-bit int. Thus it works in MULTI_DIV_short() too, where it is multiplied with the 16-bit sample value yielding an int.
I'll try it out and prepare a patch.
Well, but +90dB gain doesn't look like a normal usage pattern. Why do you have to use softvol plugin for achieving that specific purpose?
Takashi
On Mon, 15 Jan 2018, Takashi Iwai wrote:
Ok, my suggestion would be set MAX_DB_UPPER_LIMIT to 90 dB. 90 dB comes out as 31622, which still is manageable when shifted up by VOL_SCALE_SHIFT (= 16), fitting in a 32-bit int. Thus it works in MULTI_DIV_short() too, where it is multiplied with the 16-bit sample value yielding an int.
I'll try it out and prepare a patch.
Well, but +90dB gain doesn't look like a normal usage pattern. Why do you have to use softvol plugin for achieving that specific purpose?
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
/Ricard
On Mon, 15 Jan 2018 14:49:38 +0100, Ricard Wanderlof wrote:
On Mon, 15 Jan 2018, Takashi Iwai wrote:
Ok, my suggestion would be set MAX_DB_UPPER_LIMIT to 90 dB. 90 dB comes out as 31622, which still is manageable when shifted up by VOL_SCALE_SHIFT (= 16), fitting in a 32-bit int. Thus it works in MULTI_DIV_short() too, where it is multiplied with the 16-bit sample value yielding an int.
I'll try it out and prepare a patch.
Well, but +90dB gain doesn't look like a normal usage pattern. Why do you have to use softvol plugin for achieving that specific purpose?
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
But why do you need 90dB? "Because it can" is no good reason to increase such a safe limit.
Takashi
On Mon, 15 Jan 2018, Takashi Iwai wrote:
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
But why do you need 90dB? "Because it can" is no good reason to increase such a safe limit.
No, I don't need 90 dB. The specific usecase I have calls for 55 dB, so I could of course just change the maximum from 50 to 55 dB. Or perhaps with a bit of margin, such as 60 dB or 70 dB.
They way I see it though, softvol is just an amplifier component. It's up to the user to use it for whatever purpose they want. And there is no inharent danger in allowing large gains, as the signal will just clip at full scale, it's not like having a power amplifier with infinite power resources. So the upper limit should be bound by something technical, like an internal processing stage overflowing, which is why I suggested 90 dB, as it is at slightly more than 90 dB that a 16 bit signed short overflows, 16-bit shorts being part of the current set of calculations in the MULTI_DIV_ macros. So 90 dB seemed to me a limit that is related to the technical limitations of the algorithm employed.
Note that I'm not suggesting changing the default gain range which I believe is -50 to 0 dB. In order to utilize the large gain, someone must purposefully enter a 'max_dB' value in /etc/asound.conf and then set the gain to that value, so there would seem little risk of setting a large gain by mistake.
/Ricard
On Mon, 15 Jan 2018 15:32:13 +0100, Ricard Wanderlof wrote:
On Mon, 15 Jan 2018, Takashi Iwai wrote:
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
But why do you need 90dB? "Because it can" is no good reason to increase such a safe limit.
No, I don't need 90 dB. The specific usecase I have calls for 55 dB, so I could of course just change the maximum from 50 to 55 dB. Or perhaps with a bit of margin, such as 60 dB or 70 dB.
They way I see it though, softvol is just an amplifier component. It's up to the user to use it for whatever purpose they want. And there is no inharent danger in allowing large gains, as the signal will just clip at full scale, it's not like having a power amplifier with infinite power resources. So the upper limit should be bound by something technical, like an internal processing stage overflowing, which is why I suggested 90 dB, as it is at slightly more than 90 dB that a 16 bit signed short overflows, 16-bit shorts being part of the current set of calculations in the MULTI_DIV_ macros. So 90 dB seemed to me a limit that is related to the technical limitations of the algorithm employed.
Note that I'm not suggesting changing the default gain range which I believe is -50 to 0 dB. In order to utilize the large gain, someone must purposefully enter a 'max_dB' value in /etc/asound.conf and then set the gain to that value, so there would seem little risk of setting a large gain by mistake.
Sure, the default shouldn't be changed, otherwise we'll hit many complaints :)
OTOH, the amplification in softvol is really dumb, and such a high gain like 90dB is doubtful whether it's really useful. As Jaroslav already suggested, we need a better setup to get more meaningful results.
Takashi
On Mon, 15 Jan 2018, Jaroslav Kysela wrote:
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
Wow, the signal quality from few bits per sample must be really good ;-) It would be better to use ADC with higher resolution (24-bit) and low noise floor (but I see the possible costs requirements). This is why we have such good audio in collaborative conferences :-)
Ok, I wasn't expecting this kind of discussion on this subject ...
It's true that for best performance, analog microphones (even analog MEMS) trump digital MEMS microphones when it comes to SNR, but in many cases, the SNR of the room itself will be the limiting factor anyway.
The point is this: a typical digital MEMS microphone has 0 dBFS output at 120 dB SPL. Looking at one typical recording usecase, the background noise level in a quiet room is 40 or 50 dB SPL, with speech at a distance of a meter or so being around 60 dB SPL. So in this case we're 60 dB below full scale for the speech signal, with the acoustic noise floor being 10 or 20 dB below that. The noise floor of a MEMS microphone of this type is equivalent to about 30 dB SPL, so the acoustic noise is still higher than the electrical noise in the system.
Now, assuming we actually want to hear what is going on, so we bring up the gain by 60 dB in order to get the speech to full scale. That means that the noise floor comes up too, and there's not much we can do about that anyway as it's part of the acoustic scene we're capturing. The fact that we loose bit depth is not of much consequence, as the acoustic noise in the scene is above the resulting quantization noise anyway, in much the same way that adding dither to a signal masks the quantization noise. The acoustic SNR is 10-20 dB so we could actually represent the resulting signal with 8 bits and still be fine.
A side note here is that many PC's, especially laptops, do not provide much playback gain, so there is a point in bringing up signals to close to 0 dBFS.
The bottom line is that, yes, we loose bit depth when we apply gain, but that itself doesn't impact the sound quality, as long as the noise level is above the quantization noise to start with, which it is in many microphone cases. And we really might need a large gain in certain situations.
On Mon, 15 Jan 2018, Takashi Iwai wrote:
[ ... ] the amplification in softvol is really dumb, and such a high gain like 90dB is doubtful whether it's really useful. As Jaroslav already suggested, we need a better setup to get more meaningful results.
In what way is it dumb? Amplification is just a multiplication with a gain factor, and the softvol plugin seems to do that fine. I just tested patching it to 90 dB gain max, and applying a (24 bit) sine wave at -90 dB and amplifying it by 90 dB using softvol, and I couldn't see any odd artfacts.
Of course, for the usecase I described, an AGC of some form, or dynamic compressor would probably be better, but for a static gain, softvol could very well be employed.
Ok ... bottom line ... I'd like to increase the maximum potential gain for softvol above the current 50 dB. I suggested 90 dB because that's how much the algorithm can handle, and that's what I figured the MAX_DB_UPPER_LIMIT in pcm/pcm_softvol.c should reflect. Furthermore, I can't see any problem with increasing the limit; it does not degenerate the algorithm or cause potential problems for existing users. Admittedly, this is not kernel code, but if it were I would expect that the point of view would be that the code should not make assumptions on user's policies but only its own technical limitations. And if the input is 32 bit audio, we'd still end up with about 16 bits of resolution when applying 90 dB of gain, so mathematically it's not unreasonable.
The only problem I can foresee is that it means that all future changes to the algorithm might need to accommodate the specified maximum gain to avoid annoying users who are actually using it, which might be a problem somewhere down the line.
But for my usecase I'd be happy just pushing the limit to 60 or 70 dB if that's more acceptable.
/Ricard
On Mon, 15 Jan 2018, Takashi Iwai wrote:
OTOH, the amplification in softvol is really dumb, and such a high gain like 90dB is doubtful whether it's really useful. As Jaroslav already suggested, we need a better setup to get more meaningful results.
Hi Takashi,
I didn't really get a definitive response to my elaboration last week regarding the maximum allowable gain value for the softvol plugin.
First of all, regarding the algorithm itself used, as it stands today it can handle a maximum of 90.3 dB gain without falling apart (as the gain factor is held in a signed integer). Changing the maximum allowable gain from 50 dB to 90 dB does not impact the algorithm or existing functionality in any way, it just changes the allowable maximum to correspond to the technical limit of the current algorithm. The limit is not visible to the user anyway until he tries to configure a max_dB that is above 50 (and then only in the shape of an error message). So from a purely technical viewpoint I cannot understand any opposition.
You mentioned that the amplification is really dumb, I'm not sure what the problem is, perhaps you could elaborate, essentially a gain is a multiplication with a gain factor, and that's what softvol does.
Another issue is if such a large gain is useful. I would say that is up to the user, and of course, if you have a weak signal to start with, with, say, only 8 bits of resolution, adding 90 dB of gain is going to mean there's a lot of noise bits there, but the signal quality is of course not worse than it was to start with, just louder, and that's how any signal (digital or analog) behaves when gain is added.
But the bottom line of course is that you are the maintainer. So what would you consider a reasonable maximum gain that's more than 50 dB. 70 dB?
/Ricard
Dne 15.1.2018 v 14:49 Ricard Wanderlof napsal(a):
On Mon, 15 Jan 2018, Takashi Iwai wrote:
Ok, my suggestion would be set MAX_DB_UPPER_LIMIT to 90 dB. 90 dB comes out as 31622, which still is manageable when shifted up by VOL_SCALE_SHIFT (= 16), fitting in a 32-bit int. Thus it works in MULTI_DIV_short() too, where it is multiplied with the 16-bit sample value yielding an int.
I'll try it out and prepare a patch.
Well, but +90dB gain doesn't look like a normal usage pattern. Why do you have to use softvol plugin for achieving that specific purpose?
The usecase we have actually calls for 55 dB of gain maximum, but I was thinking that looking at the code the maths can actually handle 90 dB so it would be good 'reasonable limit' - it's a nice round number and fits in 16 bits (signed).
The usecase we have is using digital MEMS microphones ((2S connected, with no integral amplification) and when the sound source is far away, a fair amount of gain can be needed.
Wow, the signal quality from few bits per sample must be really good ;-) It would be better to use ADC with higher resolution (24-bit) and low noise floor (but I see the possible costs requirements). This is why we have such good audio in collaborative conferences :-)
Jaroslav
participants (3)
-
Jaroslav Kysela
-
Ricard Wanderlof
-
Takashi Iwai