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/Makefile.am | 2 +- src/main.c | 1 + src/player.c | 27 +++++++++++++++++++++++++++ src/player.h | 1 + 4 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index e3a98a4..06c8e59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ pianobar_CPPFLAGS = ${LIBCURL_CFLAGS} ${LIBAO_CFLAGS} ${LIBXML_CFLAGS} \ -I../libpiano/src -I../libwardrobe/src pianobar_LDADD = ${LIBCURL_LIBS} ${LIBAO_LIBS} ${LIBFAAD_LIBS} \ ${LIBREADLINE_LIBS} ${LIBXML_LIBS} -lpthread \ - ../libpiano/src/libpiano.la ../libwardrobe/src/libwardrobe.la + ../libpiano/src/libpiano.la ../libwardrobe/src/libwardrobe.la -lm dist_man1_MANS = pianobar.1 diff --git a/src/main.c b/src/main.c index 4f3e3b0..eaa93d5 100644 --- a/src/main.c +++ b/src/main.c @@ -438,6 +438,7 @@ int main (int argc, char **argv) { memset (&player, 0, sizeof (player)); player.url = strdup (curSong->audioUrl); + player.gain = curSong->fileGain; /* start player */ pthread_create (&playerThread, NULL, BarPlayerThread, 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); diff --git a/src/player.h b/src/player.h index 9e44bef..9d0908b 100644 --- a/src/player.h +++ b/src/player.h @@ -41,6 +41,7 @@ struct aacPlayer { NeAACDecHandle aacHandle; unsigned long samplerate; unsigned char channels; + float gain; /* audio out */ ao_device *audioOutDevice; char *url; -- cgit v1.2.3