summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--replaygain.c265
-rw-r--r--replaygain.h45
-rw-r--r--streamer.c105
4 files changed, 316 insertions, 102 deletions
diff --git a/Makefile.am b/Makefile.am
index 8977b4b5..e6ed3fd1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,7 +33,8 @@ deadbeef_SOURCES =\
metacache.c metacache.h\
gettext.h\
ringbuf.c ringbuf.h\
- dsppreset.c dsppreset.h
+ dsppreset.c dsppreset.h\
+ replaygain.c replaygain.h
sdkdir = $(pkgincludedir)
sdk_HEADERS = deadbeef.h
diff --git a/replaygain.c b/replaygain.c
new file mode 100644
index 00000000..335cd8b0
--- /dev/null
+++ b/replaygain.c
@@ -0,0 +1,265 @@
+
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include "playlist.h"
+#include "volume.h"
+#include "replaygain.h"
+
+static int conf_replaygain_mode = 0;
+static int conf_replaygain_scale = 1;
+
+
+void
+replaygain_apply (ddb_waveformat_t *fmt, playItem_t *it, char *bytes, int bytesread) {
+ // FIXME: separate replaygain DSP plugin?
+ if (fmt->bps == 16) {
+ apply_replay_gain_int16 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 24) {
+ apply_replay_gain_int24 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 8) {
+ apply_replay_gain_int16 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 32 && !fmt->is_float) {
+ apply_replay_gain_int32 (it, bytes, bytesread);
+ }
+ else if (fmt->bps == 32 && fmt->is_float) {
+ apply_replay_gain_float32 (it, bytes, bytesread);
+ }
+}
+
+void
+replaygain_set (int mode, int scale) {
+ conf_replaygain_mode = mode;
+ conf_replaygain_scale = scale;
+}
+
+void
+apply_replay_gain_int8 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int vol = 1000;
+ if (conf_replaygain_mode == 1) {
+ if (it->replaygain_track_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_track_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_track_peak > 1000) {
+ vol = 1000 / it->replaygain_track_peak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (it->replaygain_album_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_album_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_album_peak > 1000) {
+ vol = 1000 / it->replaygain_album_peak;
+ }
+ }
+ }
+ int8_t *s = (int8_t*)bytes;
+ for (int j = 0; j < size; j++) {
+ int32_t sample = ((int8_t)(*s)) * vol / 1000;
+ if (sample > 0x7f) {
+ sample = 0x7f;
+ }
+ else if (sample < -0x80) {
+ sample = -0x80;
+ }
+ *s = (int8_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_int16 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int vol = 1000;
+ if (conf_replaygain_mode == 1) {
+ if (it->replaygain_track_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_track_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_track_peak > 1000) {
+ vol = 1000 / it->replaygain_track_peak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (it->replaygain_album_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_album_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_album_peak > 1000) {
+ vol = 1000 / it->replaygain_album_peak;
+ }
+ }
+ }
+ int16_t *s = (int16_t*)bytes;
+ for (int j = 0; j < size/2; j++) {
+ int32_t sample = ((int32_t)(*s)) * vol / 1000;
+ if (sample > 0x7fff) {
+ sample = 0x7fff;
+ }
+ else if (sample < -0x8000) {
+ sample = -0x8000;
+ }
+ *s = (int16_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_int24 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int64_t vol = 1000;
+ if (conf_replaygain_mode == 1) {
+ if (it->replaygain_track_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_track_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_track_peak > 1000) {
+ vol = 1000 / it->replaygain_track_peak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (it->replaygain_album_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_album_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_album_peak > 1000) {
+ vol = 1000 / it->replaygain_album_peak;
+ }
+ }
+ }
+ char *s = (char*)bytes;
+ for (int j = 0; j < size/3; j++) {
+ int32_t sample = ((unsigned char)s[0]) | ((unsigned char)s[1]<<8) | (s[2]<<16);
+ sample = sample * vol / 1000;
+ if (sample > 0x7fffff) {
+ sample = 0x7fffff;
+ }
+ else if (sample < -0x800000) {
+ sample = -0x800000;
+ }
+ s[0] = (sample&0x0000ff);
+ s[1] = (sample&0x00ff00)>>8;
+ s[2] = (sample&0xff0000)>>16;
+ s += 3;
+ }
+}
+
+void
+apply_replay_gain_int32 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ int64_t vol = 1000;
+ if (conf_replaygain_mode == 1) {
+ if (it->replaygain_track_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_track_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_track_peak > 1000) {
+ vol = 1000 / it->replaygain_track_peak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (it->replaygain_album_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_album_gain) * 1000;
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_album_peak > 1000) {
+ vol = 1000 / it->replaygain_album_peak;
+ }
+ }
+ }
+ int32_t *s = (int32_t*)bytes;
+ for (int j = 0; j < size/4; j++) {
+ int64_t sample = ((int32_t)(*s)) * vol / 1000;
+ if (sample > 0x7fffffff) {
+ sample = 0x7fffffff;
+ }
+ else if (sample < -0x80000000) {
+ sample = -0x80000000;
+ }
+ *s = (int32_t)sample;
+ s++;
+ }
+}
+
+void
+apply_replay_gain_float32 (playItem_t *it, char *bytes, int size) {
+ if (!conf_replaygain_mode) {
+ return;
+ }
+ float vol = 1.f;
+ if (conf_replaygain_mode == 1) {
+ if (it->replaygain_track_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_track_gain);
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_track_peak > 1.f) {
+ vol = 1.f / it->replaygain_track_peak;
+ }
+ }
+ }
+ else if (conf_replaygain_mode == 2) {
+ if (it->replaygain_album_gain == 0) {
+ return;
+ }
+ vol = db_to_amp (it->replaygain_album_gain);
+ if (conf_replaygain_scale) {
+ if (vol * it->replaygain_album_peak > 1.f) {
+ vol = 1.f / it->replaygain_album_peak;
+ }
+ }
+ }
+ float *s = (float*)bytes;
+ for (int j = 0; j < size/4; j++) {
+ float sample = ((float)*s) * vol;
+ if (sample > 1.f) {
+ sample = 1.f;
+ }
+ else if (sample < -1.f) {
+ sample = -1.f;
+ }
+ *s = sample;
+ s++;
+ }
+}
diff --git a/replaygain.h b/replaygain.h
new file mode 100644
index 00000000..5169c99c
--- /dev/null
+++ b/replaygain.h
@@ -0,0 +1,45 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __REPLAYGAIN_H
+#define __REPLAYGAIN_H
+
+#include "deadbeef.h"
+
+void
+replaygain_apply (ddb_waveformat_t *fmt, playItem_t *it, char *bytes, int bytesread);
+
+void
+replaygain_set (int mode, int scale);
+
+void
+apply_replay_gain_int8 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int16 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int24 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_int32 (playItem_t *it, char *bytes, int size);
+
+void
+apply_replay_gain_float32 (playItem_t *it, char *bytes, int size);
+
+#endif
diff --git a/streamer.c b/streamer.c
index 71618a56..9179baba 100644
--- a/streamer.c
+++ b/streamer.c
@@ -36,6 +36,7 @@
#include "vfs.h"
#include "premix.h"
#include "ringbuf.h"
+#include "replaygain.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -62,9 +63,6 @@ static ddb_dsp_context_t *eq;
static int dsp_on = 0;
-static int conf_replaygain_mode = 0;
-static int conf_replaygain_scale = 1;
-
static int streaming_terminate;
// buffer up to 3 seconds at 44100Hz stereo
@@ -1377,8 +1375,7 @@ streamer_init (void) {
streamer_dsp_init ();
- conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
- conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
+ replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1));
streamer_tid = thread_start (streamer_thread, NULL);
return 0;
}
@@ -1442,93 +1439,6 @@ streamer_reset (int full) { // must be called when current song changes by exter
}
}
-int replaygain = 1;
-int replaygain_scale = 1;
-
-static void
-apply_replay_gain_int16 (playItem_t *it, char *bytes, int size) {
- if (!replaygain || !conf_replaygain_mode) {
- return;
- }
- int vol = 1000;
- if (conf_replaygain_mode == 1) {
- if (it->replaygain_track_gain == 0) {
- return;
- }
- vol = db_to_amp (streaming_track->replaygain_track_gain) * 1000;
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * streaming_track->replaygain_track_peak > 1000) {
- vol = 1000 / streaming_track->replaygain_track_peak;
- }
- }
- }
- else if (conf_replaygain_mode == 2) {
- if (it->replaygain_album_gain == 0) {
- return;
- }
- vol = db_to_amp (streaming_track->replaygain_album_gain) * 1000;
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * streaming_track->replaygain_album_peak > 1000) {
- vol = 1000 / streaming_track->replaygain_album_peak;
- }
- }
- }
- int16_t *s = (int16_t*)bytes;
- for (int j = 0; j < size/2; j++) {
- int32_t sample = ((int32_t)(*s)) * vol / 1000;
- if (sample > 0x7fff) {
- sample = 0x7fff;
- }
- else if (sample < -0x8000) {
- sample = -0x8000;
- }
- *s = (int16_t)sample;
- s++;
- }
-}
-
-static void
-apply_replay_gain_float32 (playItem_t *it, char *bytes, int size) {
- if (!replaygain || !conf_replaygain_mode) {
- return;
- }
- float vol = 1.f;
- if (conf_replaygain_mode == 1) {
- if (it->replaygain_track_gain == 0) {
- return;
- }
- vol = db_to_amp (it->replaygain_track_gain);
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * it->replaygain_track_peak > 1.f) {
- vol = 1.f / it->replaygain_track_peak;
- }
- }
- }
- else if (conf_replaygain_mode == 2) {
- if (it->replaygain_album_gain == 0) {
- return;
- }
- vol = db_to_amp (it->replaygain_album_gain);
- if (conf_replaygain_scale && replaygain_scale) {
- if (vol * it->replaygain_album_peak > 1.f) {
- vol = 1.f / it->replaygain_album_peak;
- }
- }
- }
- float *s = (float*)bytes;
- for (int j = 0; j < size/4; j++) {
- float sample = ((float)*s) * vol;
- if (sample > 1.f) {
- sample = 1.f;
- }
- else if (sample < -1.f) {
- sample = -1.f;
- }
- *s = sample;
- s++;
- }
-}
-
static int
streamer_set_output_format (void) {
DB_output_t *output = plug_get_output ();
@@ -1653,13 +1563,7 @@ streamer_read_async (char *bytes, int size) {
}
#endif
- // FIXME: separate replaygain DSP plugin?
- if (output->fmt.bps == 16) {
- apply_replay_gain_int16 (streaming_track, bytes, bytesread);
- }
- else if (output->fmt.bps == 32 && output->fmt.is_float) {
- apply_replay_gain_float32 (streaming_track, bytes, bytesread);
- }
+ replaygain_apply (&output->fmt, streaming_track, bytes, bytesread);
}
mutex_unlock (decodemutex);
if (!is_eof) {
@@ -1814,8 +1718,7 @@ streamer_ok_to_read (int len) {
void
streamer_configchanged (void) {
- conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
- conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
+ replaygain_set (conf_get_int ("replaygain_mode", 0), conf_get_int ("replaygain_scale", 1));
pl_set_order (conf_get_int ("playback.order", 0));
if (playing_track) {
playing_track->played = 1;