diff options
author | Andreas Claesson <andreas.claesson@gmail.com> | 2005-05-22 21:40:23 +0000 |
---|---|---|
committer | Andreas Claesson <andreas.claesson@gmail.com> | 2005-05-22 21:40:23 +0000 |
commit | 422410c46de81cec8872a9b91d07a7c9eca96b82 (patch) | |
tree | 36597b9d2d6c487d7becf01fba056e1dda23ff6c /src/replayGain.c | |
parent | c2616b44581f9cef1509a91ca5eb663ed9f0db1b (diff) | |
download | mpd-422410c46de81cec8872a9b91d07a7c9eca96b82.tar.gz mpd-422410c46de81cec8872a9b91d07a7c9eca96b82.tar.xz mpd-422410c46de81cec8872a9b91d07a7c9eca96b82.zip |
Addin floating point modifications
git-svn-id: https://svn.musicpd.org/mpd/branches/ancl@3274 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/replayGain.c')
-rw-r--r-- | src/replayGain.c | 110 |
1 files changed, 80 insertions, 30 deletions
diff --git a/src/replayGain.c b/src/replayGain.c index ea521d728..f052c68bc 100644 --- a/src/replayGain.c +++ b/src/replayGain.c @@ -107,13 +107,20 @@ void freeReplayGainInfo(ReplayGainInfo * info) { void doReplayGain(ReplayGainInfo * info, char * buffer, int bufferSize, AudioFormat * format) { - mpd_sint16 * buffer16; - mpd_sint8 * buffer8; - mpd_sint32 temp32; + float * bufferFloat = (float *)buffer; + mpd_sint32 * buffer32 = (mpd_sint32 *)buffer; + mpd_sint16 * buffer16 = (mpd_sint16 *)buffer; + mpd_sint8 * buffer8 = (mpd_sint8 *)buffer; float scale; + mpd_sint32 iScale; if(replayGainState == REPLAYGAIN_OFF || !info) return; +/* DEBUG */ + if(bufferSize % (format->channels * 4)) + ERROR("doReplayGain: bufferSize=%i not multipel of %i\n", + bufferSize, format->channels); +/* /DEBUG */ if(info->scale < 0) { switch(replayGainState) { case REPLAYGAIN_TRACK: @@ -127,35 +134,78 @@ void doReplayGain(ReplayGainInfo * info, char * buffer, int bufferSize, } } - if(info->scale <= 1.01 && info->scale >= 0.99) return; - - buffer16 = (mpd_sint16 *)buffer; - buffer8 = (mpd_sint8 *)buffer; +#ifdef MPD_FIXED_POINT + if(format->bits!=16 || format.channels!=2 || format->floatSamples) { + ERROR("Only 16 bit stereo is supported in fixed point mode!\n"); + exit(EXIT_FAILURE); + } + + /* If the volume change is very small then we hardly here the + * difference anyway, and if the change is positiv then clipping + * may occur. We don't want that. */ + if(info->scale > 0.99) return; + + iScale = scale * 32768.0; /* << 15 */ + + while(bufferSize) { + sample32 = (mpd_sint32)(*buffer16) * iScale; + /* no need to check boundaries - we only lower the volume*/ + /* It would be good to add some kind of dither here... TODO?! */ + *buffer16 = (sample32 >> 15); + bufferSize -= 2; + } + return; +#else scale = info->scale; - - switch(format->bits) { - case 16: - while(bufferSize > 0){ - temp32 = *buffer16; - temp32 *= scale; - *buffer16 = temp32>32767 ? 32767 : - (temp32<-32768 ? -32768 : temp32); - buffer16++; - bufferSize-=2; - } - break; - case 8: - while(bufferSize>0){ - temp32 = *buffer8; - temp32 *= scale; - *buffer8 = temp32>127 ? 127 : - (temp32<-128 ? -128 : temp32); - buffer8++; - bufferSize--; + + if(format->floatSamples) { + if(format->bits==32) { + while(bufferSize) { + *bufferFloat *= scale; + bufferFloat++; + bufferSize-=4; } - break; - default: - ERROR("%i bits not supported by doReplaygain!\n", format->bits); + return; + } + else { + ERROR("%i bit float not supported by doReplaygain!\n", + format->bits); + exit(EXIT_FAILURE); + } + } + + switch(format->bits) { + case 32: + while(bufferSize) { + double sample = (double)(*buffer32) * scale; + if(sample>2147483647.0) *buffer32 = 2147483647; + else if(sample<-2147483647.0) *buffer32 = -2147483647; + else *buffer32 = rintf(sample); + *buffer32++; + bufferSize-=4; + } + break; + case 16: + while(bufferSize){ + float sample = *buffer16 * scale; + *buffer16 = sample>32767.0 ? 32767 : + (sample<-32768.0 ? -32768 : rintf(sample)); + buffer16++; + bufferSize-=2; + } + break; + case 8: + while(bufferSize){ + float sample = *buffer8 * scale; + *buffer8 = sample>127.0 ? 127 : + (sample<-128.0 ? -128 : rintf(sample)); + buffer8++; + bufferSize--; + } + break; + default: + ERROR("%i bits not supported by doReplaygain!\n", format->bits); } +#endif } |