summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac30
-rw-r--r--deadbeef.h15
-rw-r--r--plugins/dsp_libsrc/Makefile.am11
-rw-r--r--plugins/dsp_libsrc/src.c (renamed from src.c)132
-rw-r--r--plugins/dsp_libsrc/src.h (renamed from src.h)19
-rwxr-xr-xscripts/quickinstall.sh1
-rw-r--r--streamer.c85
8 files changed, 187 insertions, 107 deletions
diff --git a/Makefile.am b/Makefile.am
index 8219b914..cab4aa3b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,7 +21,6 @@ deadbeef_SOURCES =\
plugins.c plugins.h moduleconf.h\
playlist.c playlist.h \
streamer.c streamer.h\
- src.c src.h\
premix.c premix.h\
messagepump.c messagepump.h\
conf.c conf.h\
diff --git a/configure.ac b/configure.ac
index eacf3af7..5e7a092b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,9 @@ esac
test "x$prefix" = xNONE && prefix=$ac_default_prefix
+
+PKG_CHECK_MODULES(DEPS, samplerate)
+
dnl INSANE_CFLAGS="-Wformat -Wdisabled-optimization -Wcomment -Wchar-subscripts -Wunused-function -Wunused-value -Wuninitialized -Wtype-limits -Wbad-function-cast"
dnl INSANE_CXXFLAGS="-Wcomment -Wchar-subscripts -Wunused-function -Wunused-value -Wuninitialized -Wtype-limits"
@@ -97,6 +100,7 @@ AC_ARG_ENABLE(ao, [AS_HELP_STRING([--disable-ao ], [disable audio ove
AC_ARG_ENABLE(mpris, [AS_HELP_STRING([ --enable-mpris enable Ubuntu Sound Menu plugin (default: disabled)])], [enable_mpris=$enableval], [enable_mpris=no])
AC_ARG_ENABLE(staticlink, [AS_HELP_STRING([ --enable-staticlink link everything statically (default: disabled)])], [enable_staticlink=$enableval], [enable_staticlink=no])
AC_ARG_ENABLE(portable, [AS_HELP_STRING([ --enable-portable make portable build (default: disabled, opts: yes,no,full)])], [enable_portable=$enableval], [enable_portable=no])
+AC_ARG_ENABLE(src, [AS_HELP_STRING([ --enable-src build libsamplerate (SRC) plugin (default: auto)])], [enable_src=$enableval], [enable_src=yes])
if test "x$enable_staticlink" != "xno" ; then
AC_DEFINE_UNQUOTED([STATICLINK], [1], [Define if building static version])
@@ -121,14 +125,6 @@ fi
CXXFLAGS="$CXXFLAGS $INSANE_CXXFLAGS -D_GNU_SOURCE $PREFIXFLAGS"
CFLAGS="$CFLAGS $INSANE_CFLAGS -D_GNU_SOURCE $PREFIXFLAGS"
-PKG_CHECK_MODULES(DEPS, samplerate)
-if test "x$enable_staticlink" != "xno" ; then
- DEPS_LIBS="$LIB/libsamplerate.a -lpthread -ldl"
- AC_SUBST(DEPS_LIBS)
-else
- PKG_CHECK_MODULES(DEPS, samplerate)
-fi
-
if test "x$enable_gtkui" != "xno" ; then
if test "x$enable_gtk3" == "xyes" ; then
PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-3.0 >= 2.90 gthread-2.0 glib-2.0, HAVE_GTK=yes, HAVE_GTK=no)
@@ -411,6 +407,19 @@ if test "x$enable_nullout" != "xno" ; then
HAVE_NULLOUT=yes
fi
+if test "x$enable_src" != "xno" ; then
+if test "x$enable_staticlink" != "xno" ; then
+ LIBSAMPLERATE_DEPS_LIBS="$LIB/libsamplerate.a -lpthread -ldl"
+ AC_SUBST(LIBSAMPLERATE_DEPS_LIBS)
+ HAVE_DSP_SRC=yes
+else
+ PKG_CHECK_MODULES(LIBSAMPLERATE_DEPS, samplerate, HAVE_LIBSAMPLERATE=yes, HAVE_LIBSAMPLERATE=no)
+ if test "x$HAVE_LIBSAMPLERATE" = "xyes" ; then
+ HAVE_DSP_SRC=yes
+ fi
+fi
+fi
+
if test "x$enable_supereq" != "xno" ; then
HAVE_SUPEREQ=yes
fi
@@ -494,7 +503,7 @@ if test "x$enable_mpris" != "xno" ; then
PKG_CHECK_MODULES(MPRIS_DEPS, indicate >= 0.4.4 glib-2.0 >= 2.26.0, HAVE_MPRIS=yes, HAVE_MPRIS=no)
fi
-PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/mpris"
+PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/mpris plugins/dsp_libsrc"
AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBISPLUGIN" = "xyes")
AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLACPLUGIN" = "xyes")
@@ -533,6 +542,7 @@ AM_CONDITIONAL(HAVE_MPRIS, test "x$HAVE_MPRIS" = "xyes")
AM_CONDITIONAL(STATICLINK, test "x$STATICLINK" = "xyes")
AM_CONDITIONAL(PORTABLE, test "x$PORTABLE" = "xyes")
AM_CONDITIONAL(PORTABLE_FULL, test "x$PORTABLE_FULL" = "xyes")
+AM_CONDITIONAL(HAVE_DSP_SRC, test "x$HAVE_DSP_SRC" = "xyes")
AC_SUBST(PLUGINS_DIRS)
@@ -594,6 +604,7 @@ PRINT_PLUGIN_INFO([mms],[mms streaming support],[test "x$HAVE_MMS" = "xyes"])
PRINT_PLUGIN_INFO([shn],[shorten player based on xmms-shn],[test "x$HAVE_SHN" = "xyes"])
PRINT_PLUGIN_INFO([ao],[psf1/psf2/spu/ssf player using Audio Overload],[test "x$HAVE_AO" = "xyes"])
PRINT_PLUGIN_INFO([mpris],[Ubuntu Sound Menu integration],[test "x$HAVE_MPRIS" = "xyes"])
+PRINT_PLUGIN_INFO([dsp_src],[High quality samplerate conversion using libsamplerate],[test "x$HAVE_DSP_SRC" = "xyes"])
echo
@@ -635,6 +646,7 @@ plugins/mms/Makefile
plugins/shn/Makefile
plugins/ao/Makefile
plugins/mpris/Makefile
+plugins/dsp_libsrc/Makefile
intl/Makefile
po/Makefile.in
deadbeef.desktop
diff --git a/deadbeef.h b/deadbeef.h
index ce77478c..049cfa2e 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -740,8 +740,14 @@ typedef struct DB_output_s {
} DB_output_t;
// dsp plugin
+#define DDB_INIT_DSP_INSTANCE(var,type) {\
+ memset(var,0,sizeof(type));\
+ strncpy (var->inst.id, id, 9);\
+ var->inst.id[9]=0;\
+}
typedef struct DB_dsp_instance_s {
+ char id[10];
struct DB_dsp_instance_s *next;
unsigned enabled : 1;
} DB_dsp_instance_t;
@@ -749,15 +755,16 @@ typedef struct DB_dsp_instance_s {
typedef struct DB_dsp_s {
DB_plugin_t plugin;
- DB_dsp_instance_t (*open) (void);
+ // id is a unique name used to get configuration settings
+ DB_dsp_instance_t* (*open) (const char *id);
void (*close) (DB_dsp_instance_t *inst);
- // process gets called before SRC
- // stereo samples are stored in interleaved format
- // stereo sample is counted as 1 sample
+ // samples are interleaved
+ // returned value is number of output frames
int (*process) (DB_dsp_instance_t *inst, float *samples, int frames, int channels);
} DB_dsp_t;
+
// misc plugin
// purpose is to provide extra services
// e.g. scrobbling, converting, tagging, custom gui, etc.
diff --git a/plugins/dsp_libsrc/Makefile.am b/plugins/dsp_libsrc/Makefile.am
new file mode 100644
index 00000000..90a5ec19
--- /dev/null
+++ b/plugins/dsp_libsrc/Makefile.am
@@ -0,0 +1,11 @@
+if HAVE_DSP_SRC
+pkglib_LTLIBRARIES = dsp_libsrc.la
+
+dsp_libsrc_la_SOURCES = src.c src.h
+
+dsp_libsrc_la_LDFLAGS = -module
+
+dsp_libsrc_la_LIBADD = $(LDADD)
+
+AM_CFLAGS = -std=c99
+endif
diff --git a/src.c b/plugins/dsp_libsrc/src.c
index edeccff4..19317b68 100644
--- a/src.c
+++ b/plugins/dsp_libsrc/src.c
@@ -22,16 +22,21 @@
#include <assert.h>
#include "conf.h"
#include "threading.h"
+#include "deadbeef.h"
#include "src.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
+DB_functions_t *deadbeef;
+
#define SRC_BUFFER 16000
#define SRC_MAX_CHANNELS 8
+ddb_dsp_src_t plugin;
+
typedef struct {
- ddb_src_t ddb_src;
+ DB_dsp_instance_t inst;
int quality;
SRC_STATE *src;
@@ -42,25 +47,27 @@ typedef struct {
uintptr_t mutex;
} ddb_src_libsamplerate_t;
-ddb_src_t *
-ddb_src_init (void) {
+DB_dsp_instance_t* ddb_src_open (const char *id) {
ddb_src_libsamplerate_t *src = malloc (sizeof (ddb_src_libsamplerate_t));
- memset (src, 0, sizeof (ddb_src_libsamplerate_t));
- src->mutex = mutex_create ();
- src->quality = conf_get_int ("src->quality", 2);
+ DDB_INIT_DSP_INSTANCE (src,ddb_src_libsamplerate_t);
+
+ src->mutex = deadbeef->mutex_create ();
+ char var[20];
+ snprintf (var, sizeof (var), "%s.quality");
+ src->quality = deadbeef->conf_get_int (var, 2);
src->src = src_new (src->quality, 2, NULL);
if (!src->src) {
- ddb_src_free ((ddb_src_t *)src);
+ plugin.dsp.close ((DB_dsp_instance_t *)src);
return NULL;
}
- return (ddb_src_t *)src;
+ return (DB_dsp_instance_t *)src;
}
void
-ddb_src_free (ddb_src_t *_src) {
+ddb_src_close (DB_dsp_instance_t *_src) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
if (src->mutex) {
- mutex_free (src->mutex);
+ deadbeef->mutex_free (src->mutex);
src->mutex = 0;
}
if (src->src) {
@@ -71,50 +78,62 @@ ddb_src_free (ddb_src_t *_src) {
}
void
-ddb_src_lock (ddb_src_t *_src) {
+ddb_src_lock (DB_dsp_instance_t *_src) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
- mutex_lock (src->mutex);
+ deadbeef->mutex_lock (src->mutex);
}
void
-ddb_src_unlock (ddb_src_t *_src) {
+ddb_src_unlock (DB_dsp_instance_t *_src) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
- mutex_unlock (src->mutex);
+ deadbeef->mutex_unlock (src->mutex);
}
void
-ddb_src_reset (ddb_src_t *_src, int full) {
+ddb_src_reset (DB_dsp_instance_t *_src, int full) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
src->remaining = 0;
if (full) {
- src_reset (src->src);
+ char var[20];
+ snprintf (var, sizeof (var), "%s.quality");
+ int q = deadbeef->conf_get_int (var, 2);
+ if (q != src->quality && q >= SRC_SINC_BEST_QUALITY && q <= SRC_LINEAR) {
+ ddb_src_lock (_src);
+ trace ("changing src->quality from %d to %d\n", src->quality, q);
+ src->quality = q;
+ if (src) {
+ src_delete (src->src);
+ src->src = NULL;
+ }
+ memset (&src->srcdata, 0, sizeof (src->srcdata));
+ src->src = src_new (src->quality, 2, NULL);
+ ddb_src_unlock (_src);
+ }
+ else {
+ src_reset (src->src);
+ }
}
}
void
-ddb_src_confchanged (ddb_src_t *_src) {
+ddb_src_set_ratio (DB_dsp_instance_t *_src, float ratio) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
- int q = conf_get_int ("src->quality", 2);
- if (q != src->quality && q >= SRC_SINC_BEST_QUALITY && q <= SRC_LINEAR) {
- ddb_src_lock (_src);
- trace ("changing src->quality from %d to %d\n", src->quality, q);
- src->quality = q;
- if (src) {
- src_delete (src->src);
- src->src = NULL;
- }
- memset (&src->srcdata, 0, sizeof (src->srcdata));
- src->src = src_new (src->quality, 2, NULL);
- ddb_src_unlock (_src);
- }
+ src->srcdata.src_ratio = ratio;
+ src_set_ratio (src->src, ratio);
}
int
-ddb_src_process (ddb_src_t *_src, const char * restrict input, int nframes, char * restrict output, int buffersize, float ratio, int nchannels) {
+//ddb_src_process (DB_dsp_instance_t *_src, const char * restrict input, int nframes, char * restrict output, int buffersize, float ratio, int nchannels) {
+ddb_src_process (DB_dsp_instance_t *_src, float *samples, int nframes, int nchannels) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
-extern FILE *out;
- int initsize = buffersize;
+ int numoutframes = nframes * src->srcdata.src_ratio;
+ float outbuf[numoutframes*nchannels];
+ int buffersize = sizeof (outbuf);
+ char *output = outbuf;
+ float *input = samples;
+ int inputsize = numoutframes;
+
int samplesize = nchannels * sizeof (float);
do {
@@ -125,10 +144,10 @@ extern FILE *out;
}
if (n > 0) {
- memcpy (&src->in_fbuffer[src->remaining*samplesize], input, n * samplesize);
+ memcpy (&src->in_fbuffer[src->remaining*samplesize], samples, n * samplesize);
src->remaining += n;
- input += n * nchannels;
+ samples += n * nchannels;
nframes -= n;
}
if (!src->remaining) {
@@ -140,12 +159,10 @@ extern FILE *out;
src->srcdata.data_in = (float *)src->in_fbuffer;
src->srcdata.data_out = (float *)output;
src->srcdata.input_frames = src->remaining;
- src->srcdata.output_frames = buffersize/samplesize;
- src->srcdata.src_ratio = ratio;
+ src->srcdata.output_frames = inputsize;
src->srcdata.end_of_input = 0;
ddb_src_lock (_src);
- src_set_ratio (src->src, ratio);
- trace ("src input: %d, ratio %f, buffersize: %d\n", src->srcdata.input_frames, ratio, buffersize);
+ trace ("src input: %d, ratio %f, buffersize: %d\n", src->srcdata.input_frames, src->srcdata.src_ratio, buffersize);
int src_err = src_process (src->src, &src->srcdata);
trace ("src output: %d, used: %d\n", src->srcdata.output_frames_gen, src->srcdata.input_frames_used);
@@ -153,11 +170,11 @@ extern FILE *out;
if (src_err) {
const char *err = src_strerror (src_err) ;
fprintf (stderr, "src_process error %s\n"
- "srcdata.data_in=%p, srcdata.data_out=%p, srcdata.input_frames=%d, srcdata.output_frames=%d, srcdata.src_ratio=%f", err, src->srcdata.data_in, src->srcdata.data_out, (int)src->srcdata.input_frames, (int)src->srcdata.output_frames, ratio);
+ "srcdata.data_in=%p, srcdata.data_out=%p, srcdata.input_frames=%d, srcdata.output_frames=%d, srcdata.src_ratio=%f", err, src->srcdata.data_in, src->srcdata.data_out, (int)src->srcdata.input_frames, (int)src->srcdata.output_frames, src->srcdata.src_ratio);
exit (-1);
}
- buffersize -= src->srcdata.output_frames_gen * samplesize;
+ inputsize -= src->srcdata.output_frames_gen;
output += src->srcdata.output_frames_gen * samplesize;
// calculate how many unused input samples left
@@ -171,7 +188,36 @@ extern FILE *out;
}
} while (nframes > 0);
- trace ("src processed: %d bytes\n", initsize-buffersize);
- return initsize - buffersize;
+ memcpy (input, outbuf, sizeof (outbuf));
+ //static FILE *out = NULL;
+ //if (!out) {
+ // out = fopen ("out.raw", "w+b");
+ //}
+ //fwrite (input, 1, numoutframes*sizeof(float)*nchannels, out);
+
+ return numoutframes;
}
+ddb_dsp_src_t plugin = {
+ .dsp.plugin.api_vmajor = DB_API_VERSION_MAJOR,
+ .dsp.plugin.api_vminor = DB_API_VERSION_MINOR,
+ .dsp.open = ddb_src_open,
+ .dsp.close = ddb_src_close,
+ .dsp.process = ddb_src_process,
+ .dsp.plugin.version_major = 0,
+ .dsp.plugin.version_minor = 1,
+ .dsp.plugin.id = "dsp_src",
+ .dsp.plugin.name = "dsp_src",
+ .dsp.plugin.descr = "Samplerate converter using libsamplerate",
+ .dsp.plugin.author = "Alexey Yakovenko",
+ .dsp.plugin.email = "waker@users.sf.net",
+ .dsp.plugin.website = "http://deadbeef.sf.net",
+ .reset = ddb_src_reset,
+ .set_ratio = ddb_src_set_ratio,
+};
+
+DB_plugin_t *
+dsp_libsrc_load (DB_functions_t *f) {
+ deadbeef = f;
+ return &plugin.dsp.plugin;
+}
diff --git a/src.h b/plugins/dsp_libsrc/src.h
index 74bf9e75..09f6a27f 100644
--- a/src.h
+++ b/plugins/dsp_libsrc/src.h
@@ -20,20 +20,12 @@
#define __SRC_H
typedef struct {
-} ddb_src_t;
-
-ddb_src_t *
-ddb_src_init (void);
-
-void
-ddb_src_free (ddb_src_t *src);
-
-void
-ddb_src_lock (ddb_src_t *_src);
-
-void
-ddb_src_unlock (ddb_src_t *src);
+ DB_dsp_t dsp;
+ void (*reset) (DB_dsp_instance_t *inst, int full);
+ void (*set_ratio) (DB_dsp_instance_t *inst, float ratio);
+} ddb_dsp_src_t;
+#if 0
void
ddb_src_reset (ddb_src_t *src, int full);
@@ -42,5 +34,6 @@ ddb_src_confchanged (ddb_src_t *src);
int
ddb_src_process (ddb_src_t *_src, const char * restrict input, int nframes, char * restrict output, int buffersize, float ratio, int nchannels);
+#endif
#endif
diff --git a/scripts/quickinstall.sh b/scripts/quickinstall.sh
index 28fccb1c..3806e3db 100755
--- a/scripts/quickinstall.sh
+++ b/scripts/quickinstall.sh
@@ -34,4 +34,5 @@ cp ./plugins/mms/.libs/mms.so /usr/local/lib/deadbeef/
cp ./plugins/shn/.libs/shn.so /usr/local/lib/deadbeef/
cp ./plugins/ao/.libs/ao.so /usr/local/lib/deadbeef/
cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/
+cp ./plugins/dsp_libsrc/.libs/dsp_libsrc.so /usr/local/lib/deadbeef/
diff --git a/streamer.c b/streamer.c
index d19cbe74..c26a1f61 100644
--- a/streamer.c
+++ b/streamer.c
@@ -36,7 +36,7 @@
#include "volume.h"
#include "vfs.h"
#include "premix.h"
-#include "src.h"
+#include "plugins/dsp_libsrc/src.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -48,7 +48,8 @@ FILE *out;
#endif
static intptr_t streamer_tid;
-static ddb_src_t *src;
+static ddb_dsp_src_t *srcplug;
+static DB_dsp_instance_t *src;
static int conf_replaygain_mode = 0;
static int conf_replaygain_scale = 1;
@@ -747,7 +748,7 @@ streamer_start_new_song (void) {
int initsng = nextsong;
int pstate = nextsong_pstate;
nextsong = -1;
- ddb_src_reset (src, 0);
+ srcplug->reset (src, 0);
streamer_unlock ();
if (badsong == sng) {
trace ("looped to bad file. stopping...\n");
@@ -844,7 +845,7 @@ streamer_thread (void *ctx) {
#ifdef __linux__
prctl (PR_SET_NAME, "deadbeef-stream", 0, 0, 0, 0);
#endif
- ddb_src_reset (src, 0);
+// srcplug->reset (src, 0);
while (!streaming_terminate) {
struct timeval tm1;
@@ -1061,7 +1062,7 @@ streamer_thread (void *ctx) {
int alloc_time = 1000 / (bytes_in_one_second * output->fmt.channels / blocksize);
streamer_lock ();
- if (streambuffer_fill < (STREAM_BUFFER_SIZE-blocksize)) {
+ if (streambuffer_fill < (STREAM_BUFFER_SIZE-blocksize*2)) {
int sz = STREAM_BUFFER_SIZE - streambuffer_fill;
int minsize = blocksize;
@@ -1072,7 +1073,7 @@ streamer_thread (void *ctx) {
}
sz = min (minsize, sz);
assert ((sz&3) == 0);
- char buf[sz];
+ char buf[sz*2]; // buffer must be 2x large to accomodate resamplers/pitchers/...
streamer_unlock ();
// ensure that size is possible with current format
@@ -1083,7 +1084,7 @@ streamer_thread (void *ctx) {
int bytesread = streamer_read_async (buf,sz);
streamer_lock ();
- memcpy (streambuffer+streambuffer_fill, buf, sz);
+ memcpy (streambuffer+streambuffer_fill, buf, bytesread);
if (bytesread > 0) {
streambuffer_fill += bytesread;
}
@@ -1132,10 +1133,13 @@ streamer_init (void) {
#endif
mutex = mutex_create ();
decodemutex = mutex_create ();
- src = ddb_src_init ();
- if (!src) {
- return -1;
+
+ // find src plugin, and use it if found
+ srcplug = (ddb_dsp_src_t*)plug_get_for_id ("dsp_src");
+ if (srcplug) {
+ src = srcplug->dsp.open ("strm_src");
}
+
conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
streamer_tid = thread_start (streamer_thread, NULL);
@@ -1167,8 +1171,8 @@ streamer_free (void) {
decodemutex = 0;
mutex_free (mutex);
mutex = 0;
- if (src) {
- ddb_src_free (src);
+ if (srcplug && src) {
+ srcplug->dsp.close (src);
src = NULL;
}
}
@@ -1179,14 +1183,13 @@ streamer_reset (int full) { // must be called when current song changes by exter
fprintf (stderr, "ERROR: someone called streamer_reset after exit\n");
return; // failsafe, in case someone calls streamer reset after deinit
}
- ddb_src_lock (src);
if (full) {
streamer_lock ();
streambuffer_pos = 0;
streambuffer_fill = 0;
streamer_unlock ();
}
- ddb_src_reset (src, 1);
+ srcplug->reset (src, 1);
#if 0 // !!!! FIXME !!!!
// reset dsp
DB_dsp_t **dsp = deadbeef->plug_get_dsp_list ();
@@ -1197,7 +1200,6 @@ streamer_reset (int full) { // must be called when current song changes by exter
}
}
#endif
- ddb_src_unlock (src);
}
int replaygain = 1;
@@ -1328,8 +1330,6 @@ streamer_read_async (char *bytes, int size) {
#define SRC_NUM_SAMPLES 1024
char outbuf[SRC_NUM_SAMPLES * output->fmt.channels * sizeof (float)];
- char *src_data = NULL;
- int src_data_size = 0;
bytesread = 0;
ddb_waveformat_t srcfmt;
memcpy (&srcfmt, &output->fmt, sizeof (srcfmt));
@@ -1337,9 +1337,15 @@ streamer_read_async (char *bytes, int size) {
srcfmt.is_float = 1;
int inputsize = (ftoi (SRC_NUM_SAMPLES * ratio) + 100) * inputsamplesize;
char input[inputsize];
- char tempbuf[inputsize/inputsamplesize * sizeof (float) * output->fmt.channels];
+ char tempbuf[inputsize/inputsamplesize * sizeof (float) * output->fmt.channels * 2];
while (1) {
- int converted_bytes = 0;
+ // read more samples for src
+ inputsize = fileinfo->plugin->read (fileinfo, input, (ftoi (SRC_NUM_SAMPLES * ratio) + 100) * inputsamplesize);
+ // convert to float
+ int tempsize = pcm_convert (&fileinfo->fmt, input, &srcfmt, tempbuf, inputsize);
+ assert (tempsize <= sizeof (tempbuf)/2);
+
+ int converted_frames = 0;
// drain src
int n = sizeof (outbuf);
@@ -1347,31 +1353,28 @@ streamer_read_async (char *bytes, int size) {
if (n > remaining) {
n = remaining;
}
- converted_bytes = ddb_src_process (src, src_data, src_data_size/(sizeof(float)*output->fmt.channels), outbuf, n, ratio, srcfmt.channels);
-
- src_data = NULL;
- src_data_size = 0;
- if (converted_bytes > 0) {
- bytesread += pcm_convert (&srcfmt, outbuf, &output->fmt, bytes + bytesread, converted_bytes);
- assert (bytesread <= size);
- if (bytesread == size) {
+ srcplug->set_ratio (src, ratio);
+ //printf ("asked for %d frames\n", src_data_size/(sizeof(float)*output->fmt.channels));
+ converted_frames = srcplug->dsp.process (src, (float *)tempbuf, tempsize/(sizeof(float)*output->fmt.channels), srcfmt.channels);
+ //printf ("received %d frames\n", converted_frames);
+
+ if (converted_frames > 0) {
+ //fwrite (tempbuf, 1, converted_frames * sizeof(float)*output->fmt.channels, out);
+ int n = pcm_convert (&srcfmt, tempbuf, &output->fmt, bytes + bytesread, converted_frames * (sizeof(float)*output->fmt.channels));
+ //fwrite (bytes + bytesread, 1, n, out);
+
+ bytesread += n;
+ assert (bytesread <= (size * 2));
+ if (bytesread >= size) {
break;
}
continue;
}
- // read more samples for src
- inputsize = fileinfo->plugin->read (fileinfo, input, (ftoi (SRC_NUM_SAMPLES * ratio) + 100) * inputsamplesize);
- if (!inputsize && !converted_bytes) {
+ if (!inputsize && !converted_frames) {
break; // eof
}
- // convert to float
- int tempsize = pcm_convert (&fileinfo->fmt, input, &srcfmt, tempbuf, inputsize);
- assert (tempsize <= sizeof (tempbuf));
-
- src_data = tempbuf;
- src_data_size = tempsize;
}
}
else {
@@ -1446,6 +1449,8 @@ streamer_read_async (char *bytes, int size) {
return initsize;
}
else {
+ break;
+#if 0
// that means EOF
trace ("streamer: EOF! buns: %d\n", bytes_until_next_song);
@@ -1461,6 +1466,7 @@ streamer_read_async (char *bytes, int size) {
}
}
break;
+#endif
}
}
return initsize - size;
@@ -1560,11 +1566,16 @@ streamer_is_buffering (void) {
}
void
+src_conf_changed (void) {
+
+}
+
+void
streamer_configchanged (void) {
conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
- ddb_src_confchanged (src);
+ srcplug->reset (src, 1);
}
void