aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO16
-rw-r--r--src/main.c2
-rw-r--r--src/ogg_decode.c63
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;