aboutsummaryrefslogtreecommitdiffstats
path: root/src/replayGain.c
diff options
context:
space:
mode:
authorAndreas Claesson <andreas.claesson@gmail.com>2005-05-22 21:40:23 +0000
committerAndreas Claesson <andreas.claesson@gmail.com>2005-05-22 21:40:23 +0000
commit422410c46de81cec8872a9b91d07a7c9eca96b82 (patch)
tree36597b9d2d6c487d7becf01fba056e1dda23ff6c /src/replayGain.c
parentc2616b44581f9cef1509a91ca5eb663ed9f0db1b (diff)
downloadmpd-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.c110
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
}