aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c2
-rw-r--r--src/ogg_decode.c63
2 files changed, 65 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index 7c0a6dbe4..b95e052f2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,7 @@
#include "volume.h"
#include "log.h"
#include "permission.h"
+#include "replayGain.h"
#include "../config.h"
#include <stdio.h>
@@ -322,6 +323,7 @@ int main(int argc, char * argv[]) {
initPaths(options.playlistDirArg,options.musicDirArg);
initPermissions();
+ initReplayGainState();
initTables();
initPlaylist();
diff --git a/src/ogg_decode.c b/src/ogg_decode.c
index 709fbac23..202fd6d4b 100644
--- a/src/ogg_decode.c
+++ b/src/ogg_decode.c
@@ -27,6 +27,7 @@
#include "pcm_utils.h"
#include "inputStream.h"
#include "outputBuffer.h"
+#include "replayGain.h"
#include <stdio.h>
#include <unistd.h>
@@ -83,11 +84,70 @@ long ogg_tell_cb(void * inStream) {
return ((InputStream *)inStream)->offset;
}
+char * ogg_parseComment(char * comment, char * needle) {
+ int len = strlen(needle);
+
+ if(strncasecmp(comment,needle,len)) return comment+len;
+
+ return NULL;
+}
+
+float ogg_getReplayGainScale(char ** comments) {
+ int trackGainFound = 0;
+ int albumGainFound = 0;
+ float trackGain = 1.0;
+ float albumGain = 1.0;
+ float trackPeak = 0.0;
+ float albumPeak = 0.0;
+ char * temp;
+ int replayGainState = getReplayGainState();
+
+ if(replayGainState == REPLAYGAIN_OFF) return 1.0;
+
+ while(*comments) {
+ if((temp = ogg_parseComment(*comments,"replaygain_track_gain")))
+ {
+ trackGain = atof(temp);
+ trackGainFound = 1;
+ }
+ else if((temp = ogg_parseComment(*comments,
+ "replaygain_album_gain")))
+ {
+ albumGain = atof(temp);
+ albumGainFound = 1;
+ }
+ else if((temp = ogg_parseComment(*comments,
+ "replaygain_track_peak")))
+ {
+ trackPeak = atof(temp);
+ }
+ else if((temp = ogg_parseComment(*comments,
+ "replaygain_album_peak")))
+ {
+ albumPeak = atof(temp);
+ }
+
+ comments++;
+ }
+
+ switch(replayGainState) {
+ case REPLAYGAIN_ALBUM:
+ if(albumGainFound) {
+ return computeReplayGainScale(albumGain,albumPeak);
+ }
+ default:
+ return computeReplayGainScale(trackGain,trackPeak);
+ }
+
+ return 1.0;
+}
+
int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
{
OggVorbis_File vf;
ov_callbacks callbacks;
InputStream inStream;
+
callbacks.read_func = ogg_read_cb;
callbacks.seek_func = ogg_seek_cb;
@@ -124,6 +184,8 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
int chunkpos = 0;
long bitRate = 0;
long test;
+ float replayGainScale = ogg_getReplayGainScale(
+ ov_comment(&vf,-1)->user_comments);
while(!eof) {
if(dc->seek) {
@@ -141,6 +203,7 @@ int ogg_decode(OutputBuffer * cb, AudioFormat * af, DecoderControl * dc)
if((test = ov_bitrate_instant(&vf))>0) {
bitRate = test/1000;
}
+ doReplayGain(chunk,ret,af,replayGainScale);
sendDataToOutputBuffer(cb,dc,chunk,ret,
ov_time_tell(&vf),bitRate);
if(dc->stop) break;