Index: NuppelVideoPlayer.cpp =================================================================== --- NuppelVideoPlayer.cpp (revision 17338) +++ NuppelVideoPlayer.cpp (working copy) @@ -3782,6 +3782,96 @@ #endif } +/** \fn agc(T, float) + * \brief Auto Gain Control (AGC) for audio samples + * + * Implements a simple Auto Gain Control (AGC) for audio. + * it detects when it's output is too large + * (caused by large periods of silence) and scales back the gain + * appropriately. In normal operation there will be 2 floating point + * multiplicatioons and 2 floating point add/subtracks. + * Implemented as a template to avoid indencial code for 8 and 16 bit + * versions. + * + */ +template +inline +T agc(const T yin, float NUM_MAX) +{ + const static float spoint = 0.05f * NUM_MAX; + const static float gain = 1e-9; + float yout; + static float iout=4; + float err; + float abs_yout; + + /* Voltage controlled amplifier is just a multiplier here */ + yout=yin*iout; + + /* error */ + abs_yout = fabsf(yout); + err=spoint-abs_yout; + + // make sure the gain doesn't over drive the maximum value + if (abs_yout> NUM_MAX) + { + iout = 0.95f*NUM_MAX/fabsf(yin); + yout = yin*iout; // do multiplication to keep the sign + + // printf("yin %d, err %f, iout %f, spoint %f, abs_yout %f, yout %f\n", + // (int)yin, err, iout, spoint, abs_yout, yout); + } + else + { + /* Integrate */ + iout += gain*err ; + } + + /* round and return */ + yout = rintf(yout); + + return (T) yout; +} + +/** \fn ManageAGC(T, int int int); + * \brief Runs AGC on all samples in a buffer + * + * Calculates the number of individual samples in the audio + * buffer and then runs Auto Gain Control (AGC) on each sample + * to equalise the audio. It is coded as a template to reduce + * the amount of identical code where only the the buffer pointer + * varies. + */ +template +void ManageAGC(T *buffer, int audio_bits, int audio_channels, int samples) +{ + int s, sc; + sc = samples * audio_channels; + + if (audio_bits == 16 ) + { + short *p = (short *) buffer; + + for (s=0; sDrain(); } + ManageAGC(buffer, audio_bits, audio_channels, samples); + // If there is no warping, just send it to the audioOutput. if (!usevideotimebase) { @@ -3866,6 +3958,9 @@ if (!audioOutput) return; + ManageAGC(lbuffer, audio_bits, audio_channels, samples); + ManageAGC(rbuffer, audio_bits, audio_channels, samples); + // If there is no warping, just send it to the audioOutput. if (!usevideotimebase) {