0
0

Ok here’s my code for a Automatic Gain Controller and a small instruction.
If someone likes to help to make this code more advanced then post it here.

GainVol: a Slider with minpos 20001 and maxpos 32767 (-5db -> 0db)
AutoGain: Checkbox to (de)activate AGC
chanl, chanr: signed int
gain: float
maxgain: int

File: a structure which contains info about current FMOD instance
-> vuposl, vuposr = maxposition for VU output current buffer
-> MaxVol = Is maximum detected volume
-> gain = current gain amplification (100 = default)

[code:2ejatzc9]

if FMOD_VERSION >= 3.72f

void * __stdcall wa_dsp_callback(void *originalbuffer, void *newbuffer, int length, void *userdata)
{

else

void * __stdcall wa_dsp_callback(void *originalbuffer, void *newbuffer, int length, int param)
{

endif

srcleft  = ((signed short *)newbuffer);
srcright = ((signed short *)newbuffer)+1;
File->vuposl = 0;
File->vuposr = 0;
if (AutoGain->Checked) {
  maxgain = GainVol->Position;
  gain = File->gain;
  gain /= 100;
}
for (buffpos=0; buffpos<length; buffpos+=2) {
  if (Options->AutoGain->Checked) {
    chanl = (signed int)srcleft[buffpos];
    chanr = (signed int)srcright[buffpos];
    chanl *= gain;
    chanr *= gain;
    if (chanl > maxgain || chanr > maxgain) {
      // Oops soundvolume is to high, pull it down
      File->MaxVol = maxgain;
      gain = File->gain--;
      gain /= 100;
    }
    if      (chanl < -32768) chanl = -32768;
    else if (chanl >  32767) chanl =  32767;
    if      (chanr < -32768) chanr = -32768;
    else if (chanr >  32767) chanr =  32767;
    srcleft[buffpos] = (signed short)(chanl);
    srcright[buffpos] = (signed short)(chanr);
  }
  if (srcleft[buffpos] > File->vuposl) {
    File->vuposl = srcleft[buffpos];
  }
  if (srcright[buffpos] > File->vuposr) {
    File->vuposr = srcright[buffpos];
  }
}
if (AutoGain->Checked) {
  // If overall measured volume is lower then maximum, raise the volume
  if (File->MaxVol < maxgain &&
      File->vuposl > 8000 && File->vuposl < maxgain &&
      File->vuposr > 8000 && File->vuposr < maxgain) {
    File->MaxVol = (File->vuposl > File->vuposr  ? File->vuposl : File->vuposr);
    File->gain++;
  }
}[/code:2ejatzc9]

If detected MaxVol (over all played data) is lower then maxgain then amplify the song slowly.
If the song peaks above maxgain the volume will be lowered fast.

This code works but if a song has a peak due to a bad frame or a onetime beat boost it lowers the sound volume and sticks to that.

Now someone create a smart peaks reader, say read the peaks of 50 buffers and measure the global volume peak to create a more accurate AGC.

Any help on that ?

  • You must to post comments
Showing 0 results
Your Answer

Please first to submit.