From a0fece94bda85861676115dcd942430f77bac253 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Thu, 24 Jul 2008 11:27:37 +0200 Subject: Initial ReplayGain work (including anti-clipping) Could be tuned... --- src/player.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/player.c') diff --git a/src/player.c b/src/player.c index d72979d..086fcad 100644 --- a/src/player.c +++ b/src/player.c @@ -22,6 +22,8 @@ THE SOFTWARE. #include #include +#include +#include #include "player.h" #include "config.h" @@ -40,6 +42,16 @@ unsigned int BarChangeByteorderUI32 (char buf[4]) { return ret; } +/* compute replaygain scale factor + * algo taken from here: http://www.dsprelated.com/showmessage/29246/1.php + * mpd does the same + * @param apply this gain + * @return this * yourvalue = newgain value + */ +inline float computeReplayGainScale (float applyGain) { + return pow (10.0, applyGain / 20.0); +} + /* our heart: plays streamed music * @param streamed data * @param block size @@ -89,6 +101,21 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) { NeAACDecGetErrorMessage (frameInfo.error)); break; } + short int *replayBuf = (short int *) aacDecoded; + int tmpReplayBuf; + size_t i; + for (i = 0; i < frameInfo.samples; i++) { + tmpReplayBuf = (float) (replayBuf[i]) * + computeReplayGainScale (player->gain); + /* avoid clipping */ + if (tmpReplayBuf > INT16_MAX) { + replayBuf[i] = INT16_MAX; + } else if (tmpReplayBuf < INT16_MIN) { + replayBuf[i] = INT16_MIN; + } else { + replayBuf[i] = tmpReplayBuf; + } + } /* ao_play needs bytes: 1 sample = 16 bits = 2 bytes */ ao_play (player->audioOutDevice, aacDecoded, frameInfo.samples * 16 / 8); -- cgit v1.2.3