diff options
-rw-r--r-- | TODO | 16 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/ogg_decode.c | 63 |
3 files changed, 73 insertions, 8 deletions
@@ -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; |