diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | configure.ac | 30 | ||||
-rw-r--r-- | deadbeef.h | 15 | ||||
-rw-r--r-- | plugins/dsp_libsrc/Makefile.am | 11 | ||||
-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-x | scripts/quickinstall.sh | 1 | ||||
-rw-r--r-- | streamer.c | 85 |
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 @@ -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/ @@ -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 |