Search code examples
c#audiosignal-processingbass

Stream loudness normalization using BASS.NET in c#


I need to normalize a playing audio stream using BASS. For this, I'm following these steps:

  1. Play the stream
  2. Create another stream from the file, and determine the peak value in a background worker
  3. Apply DSP_Gain with the appropriate gain value to the stream that is playing.

I realize the normalization will only occur after the worker is done with the task, which can seem ugly, but that isn't the point.

The trouble is, when determining the peak value of the stream, the resulting value is an integer between 0 and 32768 (the bigger the value, the louder the sound), however DSP_Gain has two variables for setting the amplification value, none of which are integers. The first one is Gain - a double between 0 and 1024, and the second is Gain_dBV - a double between -infinity and 60. Trying to pass the peak value as a factor resulted in enormous clipping inside the playing stream. My question is, how do I translate this peak value into the correct parameter for DSP_Gain? Below is the code for getting peak value:

int strm = Bass.BASS_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE);
//initialized stream for getting peak value

int peak=0; //This value will be between 0 and 32768

while (System.Convert.ToBoolean(Bass.BASS_ChannelIsActive(strm)))
{
    //calculates peak from a 20ms frame and advances, loops till stream over

    int level = Bass.BASS_ChannelGetLevel(strm);
    int left = Utils.LowWord32(level); // the left level
    int right = Utils.HighWord32(level); // the right level

    if (peak < left) peak = left;
    if (peak < right) peak = right;
}

Applying the DSP_Gain:

DSPGain = new DSP_Gain();
DSPGain.ChannelHandle = stream; //this stream is the already playing one
DSPGain.Gain = *SOME VALUE*
DSPGain.Start();

Solution

  • Just reading the links you posted it seems gain is a multiplying factor being applied to the signal - values below 1.0 will reduce the level of the signal, values above 1.0 will increase the level. So you need to calculate how much you want to reduce the level by - say you want a max peak value of 30000 & your calculated peak value is 32000 - then your gain is likely to be (30000 / 32000) = 0.9375.

    Gain_dBV is the gain ratio expressed in decibels - this is typically calculated as either 10 * log( power out / power in) or 20 * log(p-p Volts Out / p-p Volts In). The dB is converted back to the actual Gain before being applied to the signal as above - in the example the Gain dB would be 20 * log(0.9375) = -0.56