misantronic misantronic - 7 months ago 28
Javascript Question

AudioContext: Increase volume by x decibel

I'm working with the AudioContext() on a hearing-test and I was wondering how to raise/lower the volume by x dB. Is it even possible?

At the moment, I have a gainNode connected to my AudioContext, which looks (in short) like this:

var context = new AudioContext(), gainNode;
context.decodeAudioData(req.target.response, function(buffer) {
gainNode = context.createGain();
...
}


To change the volume I do this:

gainNode.gain.value = {-1 to 1}


Here, I don't have a chance to exactly define a dB value.
Are there other ways?

I think the problem is, the browser never knows the exact volume of the sound coming out of the speakers, therefore there is no base to calculate a new dB-volume.

An approach to determine the current dB-value is via the difference of 2 sounds, such as a test sound (white noise) and spoken numbers. To calculate the difference I found the formula:

20 * Math.log10(gainNoise / gainSpeech);


Then I have a basis of e.g. -6 dB, when speech is -0.6 and noise is -0.3.
But how do I raise this value by a certain dB value?

Example: I raise -6 dB by 5 dB to -1 dB. How do I recalculate speech / noise?

Answer

Gain generally refers to a linear increase or decrease in the amplitude of a signal. For example, you can double the amplitude of a signal by multiplying by 2 without regard to the original signal level. Likewise, you can halve the signal by multiplying by 0.5. In digital, the gain is applied by multiplying each sample of the input signal by the desired ratio. Gain is applied equally to the signal and the noise.

Your question implies that the gain has a range of -1 to 1. I've read the documentation and can't find any evidence that is the case. I'd suspect that it is more like 0 to N. A gain of -1 would be nonsense as it would just have the effect of inverting the signal. A gain range of 0 to 1 would only allow you to reduce the gain.

It is common practice to talk about gain in terms of dB. There is a simple conversion between gain in ratio and gain in dB.

dB = 20 * log10(ratio)
ratio = 10^(dB/20)

To set the gain from a value in dB you simply have to apply the conversion to ratio.

dBgain = 20;
gainNode.gain.value = 10^(dBgain/20);