From 822be0375e801fb66bd95e18e0d65033f3241a3b Mon Sep 17 00:00:00 2001
From: Warren Dukes <warren.dukes@gmail.com>
Date: Sat, 8 May 2004 12:00:30 +0000
Subject: [PATCH] finish adding AliasMrJones replayGain stuff

git-svn-id: https://svn.musicpd.org/mpd/trunk@953 09075e82-0dd4-0310-85a5-a0d7c8717e4f
---
 TODO             | 16 ++++++------
 src/main.c       |  2 ++
 src/ogg_decode.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/TODO b/TODO
index 886119b83..ce4d03b72 100644
--- a/TODO
+++ b/TODO
@@ -10,9 +10,7 @@ common function and abstrct dealing with DecoderControl * and put
 cycleLogFiles in there, so we cycleLogFiles while decoding, not just when 
 decoding has stopped.
 
-3) reaplygain
-
-4) streaming and playing in general
+3) streaming and playing in general
 	a) determine a clever interface to play, so that play doesn't block
 		until the file is opened, but just returns when the command
 		is accepted.
@@ -21,17 +19,19 @@ decoding has stopped.
 	c) this will help streaming from blocking indefinetly or waiting
 		on a response
 
-5) play streams
+4) play streams
 
-6) ACK error codes
+5) ACK error codes
 
-7) cleanup main()
+6) cleanup main()
 
-8) handle '\n' in filenames
+7) handle '\n' in filenames
 
-9) allow "add" command to load playlists, then depricate "load" command, this 
+8) allow "add" command to load playlists, then depricate "load" command, this 
 	will be benneficial for adding m3u url's
 
+9) compute average replaygain to use for non-replaygain songs
+
 
 Post-1.0
 --------
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;