summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h2
-rw-r--r--plugins.c1
-rw-r--r--plugins/converter/converter.c2
-rw-r--r--plugins/dsp_libsrc/src.c1
-rw-r--r--plugins/gtkui/dspconfig.c10
-rw-r--r--plugins/gtkui/eq.c11
-rw-r--r--plugins/supereq/supereq.c33
-rw-r--r--streamer.c398
-rw-r--r--streamer.h3
9 files changed, 320 insertions, 141 deletions
diff --git a/deadbeef.h b/deadbeef.h
index cce2d13b..605508e4 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -789,8 +789,6 @@ typedef struct DB_dsp_s {
void (*reset) (ddb_dsp_context_t *ctx);
- void (*enable) (ddb_dsp_context_t *ctx, int e);
-
// num_params can be NULL, to indicate that plugin doesn't expose any params
//
// if num_params is non-NULL -- get_param_name, set_param and get_param must
diff --git a/plugins.c b/plugins.c
index 0e4609d1..5c2f5d97 100644
--- a/plugins.c
+++ b/plugins.c
@@ -89,6 +89,7 @@ static DB_functions_t deadbeef_api = {
.streamer_get_current_fileinfo = streamer_get_current_fileinfo,
.streamer_get_current_playlist = streamer_get_current_playlist,
.streamer_get_dsp_chain = streamer_get_dsp_chain,
+ .streamer_set_dsp_chain = streamer_set_dsp_chain,
// folders
.get_config_dir = plug_get_config_dir,
.get_prefix = plug_get_prefix,
diff --git a/plugins/converter/converter.c b/plugins/converter/converter.c
index 061306b6..78c25d40 100644
--- a/plugins/converter/converter.c
+++ b/plugins/converter/converter.c
@@ -390,7 +390,7 @@ dsp_preset_save (ddb_dsp_preset_t *p, int overwrite) {
}
}
- FILE *fp = fopen (path, "w+b");
+ FILE *fp = fopen (path, "w+t");
if (!fp) {
return -1;
}
diff --git a/plugins/dsp_libsrc/src.c b/plugins/dsp_libsrc/src.c
index fdb96d14..1909fa6e 100644
--- a/plugins/dsp_libsrc/src.c
+++ b/plugins/dsp_libsrc/src.c
@@ -177,6 +177,7 @@ ddb_src_process (ddb_dsp_context_t *_src, float *samples, int nframes, ddb_wavef
//}
//fwrite (input, 1, numoutframes*sizeof(float)*(*nchannels), out);
+ fmt->samplerate = src->samplerate;
return numoutframes;
}
diff --git a/plugins/gtkui/dspconfig.c b/plugins/gtkui/dspconfig.c
index ad2e34a1..6853e8a7 100644
--- a/plugins/gtkui/dspconfig.c
+++ b/plugins/gtkui/dspconfig.c
@@ -47,6 +47,7 @@ dsp_clone (ddb_dsp_context_t *from) {
dsp->plugin->set_param (dsp, i, param);
}
}
+ dsp->enabled = from->enabled;
return dsp;
}
@@ -114,6 +115,11 @@ fill_dsp_plugin_list (GtkListStore *mdl) {
}
}
+static void
+update_streamer (void) {
+ deadbeef->streamer_set_dsp_chain (chain);
+}
+
void
on_dsp_add_clicked (GtkButton *button,
gpointer user_data)
@@ -161,6 +167,7 @@ on_dsp_add_clicked (GtkButton *button,
GtkListStore *mdl = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW(list)));
gtk_list_store_clear (mdl);
fill_dsp_chain (mdl);
+ update_streamer ();
}
else {
fprintf (stderr, "prefwin: failed to add DSP plugin to chain\n");
@@ -216,6 +223,7 @@ on_dsp_remove_clicked (GtkButton *button,
GtkTreeViewColumn *col;
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
gtk_tree_path_free (path);
+ update_streamer ();
}
}
@@ -327,6 +335,7 @@ on_dsp_up_clicked (GtkButton *button,
GtkTreeViewColumn *col;
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
gtk_tree_path_free (path);
+ update_streamer ();
}
@@ -347,5 +356,6 @@ on_dsp_down_clicked (GtkButton *button,
GtkTreeViewColumn *col;
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
gtk_tree_path_free (path);
+ update_streamer ();
}
diff --git a/plugins/gtkui/eq.c b/plugins/gtkui/eq.c
index 1917e871..a985cf50 100644
--- a/plugins/gtkui/eq.c
+++ b/plugins/gtkui/eq.c
@@ -57,14 +57,6 @@ set_param (ddb_dsp_context_t *eq, int i, float v) {
char fv[100];
snprintf (fv, sizeof (fv), "%f", v);
eq->plugin->set_param (eq, i, fv);
- if (i == 0) {
- deadbeef->conf_set_float ("eq.preamp", v);
- }
- else {
- char s[100];
- snprintf (s, sizeof (s), "eq.band%d", i-1);
- deadbeef->conf_set_float (s, v);
- }
}
void
@@ -85,8 +77,7 @@ on_enable_toggled (GtkToggleButton *togglebutton,
ddb_dsp_context_t *eq = get_supereq ();
if (eq) {
int enabled = gtk_toggle_button_get_active (togglebutton) ? 1 : 0;
- eq->plugin->enable (eq, enabled);
- deadbeef->conf_set_int ("eq.enable", enabled);
+ eq->enabled = enabled;
}
}
diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c
index 9e957116..79a0bd5d 100644
--- a/plugins/supereq/supereq.c
+++ b/plugins/supereq/supereq.c
@@ -37,6 +37,7 @@ typedef struct {
int params_changed;
uintptr_t mutex;
SuperEqState state;
+ int enabled;
} ddb_supereq_ctx_t;
void supereq_reset (ddb_dsp_context_t *ctx);
@@ -78,6 +79,19 @@ supereq_plugin_stop (void) {
int
supereq_process (ddb_dsp_context_t *ctx, float *samples, int frames, ddb_waveformat_t *fmt) {
ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
+ if (supereq->enabled != ctx->enabled) {
+ if (ctx->enabled && !supereq->enabled) {
+ supereq_reset (ctx);
+ }
+ supereq->enabled = ctx->enabled;
+
+ DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
+ if (it) {
+ float playpos = deadbeef->streamer_get_playpos ();
+ deadbeef->streamer_seek (playpos);
+ deadbeef->pl_item_unref (it);
+ }
+ }
if (supereq->params_changed) {
recalc_table (supereq);
supereq->params_changed = 0;
@@ -138,24 +152,6 @@ supereq_reset (ddb_dsp_context_t *ctx) {
deadbeef->mutex_unlock (supereq->mutex);
}
-void
-supereq_enable (ddb_dsp_context_t *ctx, int e) {
- ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx;
- if (e != supereq->ctx.enabled) {
- if (e && !supereq->ctx.enabled) {
- supereq_reset (ctx);
- }
- supereq->ctx.enabled = e;
- }
-
- DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
- if (it) {
- float playpos = deadbeef->streamer_get_playpos ();
- deadbeef->streamer_seek (playpos);
- deadbeef->pl_item_unref (it);
- }
-}
-
int
supereq_num_params (void) {
return 19;
@@ -303,7 +299,6 @@ static DB_dsp_t plugin = {
.close = supereq_close,
.process = supereq_process,
.reset = supereq_reset,
- .enable = supereq_enable,
.num_params = supereq_num_params,
.get_param_name = supereq_get_param_name,
.set_param = supereq_set_param,
diff --git a/streamer.c b/streamer.c
index a88dd639..7dcd28ad 100644
--- a/streamer.c
+++ b/streamer.c
@@ -36,7 +36,6 @@
#include "volume.h"
#include "vfs.h"
#include "premix.h"
-#include "plugins/dsp_libsrc/src.h"
#include "ringbuf.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
@@ -49,10 +48,9 @@ FILE *out;
#endif
static intptr_t streamer_tid;
-static DB_dsp_t *srcplug;
-static DB_dsp_t *eqplug;
static ddb_dsp_context_t *dsp_chain;
-static ddb_dsp_context_t *src;
+
+static DB_dsp_t *eqplug;
static ddb_dsp_context_t *eq;
static int conf_replaygain_mode = 0;
@@ -83,7 +81,9 @@ static playlist_t *streamer_playlist;
static playItem_t *playing_track;
static playItem_t *streaming_track;
static playItem_t *playlist_track;
-static ddb_waveformat_t prevformat;
+
+static ddb_waveformat_t output_format;
+static int formatchanged;
static DB_fileinfo_t *fileinfo;
@@ -655,8 +655,6 @@ streamer_set_current (playItem_t *it) {
mutex_unlock (decodemutex);
trace ("bps=%d, channels=%d, samplerate=%d\n", fileinfo->fmt.bps, fileinfo->fmt.channels, fileinfo->fmt.samplerate);
}
-// FIXME: that might break streaming at boundaries between 2 different samplerates
-// streamer_reset (0); // reset SRC
}
else {
trace ("no decoder in playitem!\n");
@@ -809,11 +807,11 @@ streamer_start_new_song (void) {
avg_bitrate = -1;
if (output->state () != OUTPUT_STATE_PLAYING) {
streamer_reset (1);
- if (fileinfo && memcmp (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
- memcpy (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t));
- plug_get_output ()->setformat (&fileinfo->fmt);
+ if (fileinfo && memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ plug_get_output ()->setformat (&output_format);
}
- if (output->play () < 0) {
+ if (0 != output->play ()) {
fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
streamer_set_nextsong (-2, 0);
}
@@ -824,14 +822,9 @@ streamer_start_new_song (void) {
last_bitrate = -1;
avg_bitrate = -1;
streamer_reset (1);
- if (fileinfo && memcmp (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
- memcpy (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t));
- plug_get_output ()->setformat (&fileinfo->fmt);
- }
- if (output->play () < 0) {
- fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
- streamer_set_nextsong (-2, 0);
- return;
+ if (fileinfo && memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
}
}
output->pause ();
@@ -920,53 +913,45 @@ streamer_thread (void *ctx) {
playpos = 0;
seekpos = -1;
- // try to switch samplerate to the closest supported by output plugin
- if (conf_get_int ("playback.dynsamplerate", 0)) {
-
- // don't switch if unchanged
- ddb_waveformat_t prevfmt;
- memcpy (&prevfmt, &output->fmt, sizeof (ddb_waveformat_t));
- if (memcmp (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
- memcpy (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t));
- output->setformat (&fileinfo->fmt);
- // check if the format actually changed
- if (memcmp (&output->fmt, &prevfmt, sizeof (ddb_waveformat_t))) {
- // restart streaming of current track
- trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevfmt.samplerate, output->fmt.samplerate);
- mutex_lock (decodemutex);
- fileinfo->plugin->free (fileinfo);
- fileinfo = NULL;
- DB_decoder_t *dec = NULL;
- dec = plug_get_decoder_for_id (streaming_track->decoder_id);
- if (dec) {
- fileinfo = dec->open (0);
- if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) < 0) {
- dec->free (fileinfo);
- fileinfo = NULL;
- }
- }
- if (!dec || !fileinfo) {
- // FIXME: handle error
+#if 0
+ // don't switch if unchanged
+ ddb_waveformat_t prevfmt;
+ memcpy (&prevfmt, &output->fmt, sizeof (ddb_waveformat_t));
+ if (memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ output->setformat (&fileinfo->fmt);
+ // check if the format actually changed
+ if (memcmp (&output->fmt, &prevfmt, sizeof (ddb_waveformat_t))) {
+ // restart streaming of current track
+ trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevfmt.samplerate, output->fmt.samplerate);
+ mutex_lock (decodemutex);
+ fileinfo->plugin->free (fileinfo);
+ fileinfo = NULL;
+ DB_decoder_t *dec = NULL;
+ dec = plug_get_decoder_for_id (streaming_track->decoder_id);
+ if (dec) {
+ fileinfo = dec->open (0);
+ if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) < 0) {
+ dec->free (fileinfo);
+ fileinfo = NULL;
}
- mutex_unlock (decodemutex);
- bytes_until_next_song = -1;
- streamer_buffering = 1;
- streamer_reset (1);
}
+ if (!dec || !fileinfo) {
+ // FIXME: handle error
+ }
+ mutex_unlock (decodemutex);
+ bytes_until_next_song = -1;
+ streamer_buffering = 1;
+ streamer_reset (1);
}
+ }
+#endif
- // output plugin may stop playback before switching samplerate
- if (output->state () != OUTPUT_STATE_PLAYING) {
- if (fileinfo && memcmp (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
- memcpy (&prevformat, &fileinfo->fmt, sizeof (ddb_waveformat_t));
- plug_get_output ()->setformat (&fileinfo->fmt);
- }
- if (output->play () < 0) {
- fprintf (stderr, "streamer: failed to start playback after samplerate change; output plugin doesn't work\n");
- streamer_set_nextsong (-2, 0);
- streamer_unlock ();
- continue;
- }
+ // output plugin may stop playback before switching samplerate
+ if (output->state () != OUTPUT_STATE_PLAYING) {
+ if (fileinfo && memcmp (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &fileinfo->fmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
}
}
streamer_unlock ();
@@ -1128,44 +1113,185 @@ streamer_thread (void *ctx) {
mutex_unlock (decodemutex);
}
-int
-streamer_init (void) {
-#if WRITE_DUMP
- out = fopen ("out.raw", "w+b");
-#endif
- mutex = mutex_create ();
- decodemutex = mutex_create ();
+void
+streamer_dsp_chain_free (ddb_dsp_context_t *dsp_chain) {
+ while (dsp_chain) {
+ ddb_dsp_context_t *next = dsp_chain->next;
+ dsp_chain->plugin->close (dsp_chain);
+ dsp_chain = next;
+ }
+}
- ringbuf_init (&streamer_ringbuf, streambuffer, STREAM_BUFFER_SIZE);
+ddb_dsp_context_t *
+streamer_dsp_chain_load (const char *fname) {
+ int err = 1;
+ FILE *fp = fopen (fname, "rt");
+ if (!fp) {
+ return NULL;
+ }
+
+ char temp[100];
+ ddb_dsp_context_t *chain = NULL;
+ ddb_dsp_context_t *tail = NULL;
+ for (;;) {
+ // plugin enabled {
+ int enabled = 0;
+ int err = fscanf (fp, "%100s %d {\n", temp, &enabled);
+ if (err == EOF) {
+ break;
+ }
+ else if (2 != err) {
+ fprintf (stderr, "error plugin name\n");
+ goto error;
+ }
- pl_set_order (conf_get_int ("playback.order", 0));
+ DB_dsp_t *plug = (DB_dsp_t *)deadbeef->plug_get_for_id (temp);
+ if (!plug) {
+ fprintf (stderr, "streamer_dsp_chain_load: plugin %s not found. preset will not be loaded\n", temp);
+ goto error;
+ }
+ ddb_dsp_context_t *ctx = plug->open ();
+ if (!ctx) {
+ fprintf (stderr, "streamer_dsp_chain_load: failed to open ctxance of plugin %s\n", temp);
+ goto error;
+ }
+
+ if (tail) {
+ tail->next = ctx;
+ tail = ctx;
+ }
+ else {
+ tail = chain = ctx;
+ }
+
+ int n = 0;
+ for (;;) {
+ char value[1000];
+ if (!fgets (temp, sizeof (temp), fp)) {
+ fprintf (stderr, "streamer_dsp_chain_load: unexpected eof while reading plugin params\n");
+ goto error;
+ }
+ if (!strcmp (temp, "}\n")) {
+ break;
+ }
+ else if (1 != sscanf (temp, "\t%1000[^\n]\n", value)) {
+ fprintf (stderr, "streamer_dsp_chain_load: error loading param %d\n", n);
+ goto error;
+ }
+ if (plug->num_params) {
+ plug->set_param (ctx, n, value);
+ }
+ n++;
+ }
+ ctx->enabled = enabled;
+ }
- // find src plugin, and use it if found
- srcplug = (DB_dsp_t*)plug_get_for_id ("SRC");
- if (srcplug) {
- src = srcplug->open ();
- srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_str ("src_quality", "2"));
- src->next = dsp_chain;
- dsp_chain = src;
+ err = 0;
+error:
+ if (err) {
+ fprintf (stderr, "streamer_dsp_chain_load: error loading %s\n", fname);
}
+ if (fp) {
+ fclose (fp);
+ }
+ if (err && chain) {
+ streamer_dsp_chain_free (chain);
+ chain = NULL;
+ }
+ return chain;
+}
+
+int
+streamer_dsp_chain_save (const char *fname, ddb_dsp_context_t *chain) {
+ FILE *fp = fopen (fname, "w+t");
+ if (!fp) {
+ return -1;
+ }
+
+ ddb_dsp_context_t *ctx = chain;
+ while (ctx) {
+ fprintf (fp, "%s %d {\n", ctx->plugin->plugin.id, (int)ctx->enabled);
+ if (ctx->plugin->num_params) {
+ int n = ctx->plugin->num_params ();
+ int i;
+ for (i = 0; i < n; i++) {
+ char v[1000];
+ ctx->plugin->get_param (ctx, i, v, sizeof (v));
+ fprintf (fp, "\t%s\n", v);
+ }
+ }
+ fprintf (fp, "}\n");
+ ctx = ctx->next;
+ }
+
+ fclose (fp);
+ return 0;
+}
+
+void
+streamer_dsp_postinit (void) {
+ // note about EQ hack:
+ // we 1st check if there's an EQ in dsp chain, and just use it
+ // if not -- we add our own
// eq plug
- eqplug = (DB_dsp_t *)plug_get_for_id ("supereq");
if (eqplug) {
- eq = eqplug->open ();
+ ddb_dsp_context_t *p;
+
+ for (p = dsp_chain; p; p = p->next) {
+ if (!strcmp (p->plugin->plugin.id, "supereq")) {
+ break;
+ }
+ }
+ if (p) {
+ eq = p;
+ }
+ else {
+ eq = eqplug->open ();
+ eq->next = dsp_chain;
+ dsp_chain = eq;
+ }
+
+ }
+}
+
+void
+streamer_dsp_init (void) {
+ // load dsp chain from file
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ dsp_chain = streamer_dsp_chain_load (fname);
+
+ eqplug = (DB_dsp_t *)plug_get_for_id ("supereq");
+ streamer_dsp_postinit ();
- // load settings
- eqplug->enable (eq, deadbeef->conf_get_int ("eq.enable", 0));
- eqplug->set_param (eq, 0, conf_get_str ("eq.preamp", "1"));
+ // load legacy eq settings from pre-0.5
+ if (conf_find ("eq.", NULL)) {
+ eq->enabled = deadbeef->conf_get_int ("eq.enable", 0);
+ eqplug->set_param (eq, 0, conf_get_str ("eq.preamp", "0"));
for (int i = 0; i < 18; i++) {
char key[100];
snprintf (key, sizeof (key), "eq.band%d", i);
- eqplug->set_param (eq, 1+i, conf_get_str (key, "1"));
+ eqplug->set_param (eq, 1+i, conf_get_str (key, "0"));
}
-
- eq->next = dsp_chain;
- dsp_chain = eq;
+ // delete obsolete settings
+ conf_remove_items ("eq.");
}
+}
+
+int
+streamer_init (void) {
+#if WRITE_DUMP
+ out = fopen ("out.raw", "w+b");
+#endif
+ mutex = mutex_create ();
+ decodemutex = mutex_create ();
+
+ ringbuf_init (&streamer_ringbuf, streambuffer, STREAM_BUFFER_SIZE);
+
+ pl_set_order (conf_get_int ("playback.order", 0));
+
+ streamer_dsp_init ();
conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
@@ -1198,16 +1324,16 @@ streamer_free (void) {
decodemutex = 0;
mutex_free (mutex);
mutex = 0;
- if (srcplug && src) {
- srcplug->close (src);
- srcplug = NULL;
- src = NULL;
- }
- if (eqplug && eq) {
- eqplug->close (eq);
- eqplug = NULL;
- eq = NULL;
- }
+
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ streamer_dsp_chain_save (fname, dsp_chain);
+
+ streamer_dsp_chain_free (dsp_chain);
+ dsp_chain = NULL;
+
+ eqplug = NULL;
+ eq = NULL;
}
void
@@ -1385,14 +1511,6 @@ streamer_read_async (char *bytes, int size) {
// convert to float
int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize);
- if (srcplug) {
- // FIXME: update on change only, conversion from float to
- // str and back is slow
- char s[100];
- snprintf (s, sizeof (s), "%d", dspfmt.samplerate);
- srcplug->set_param (src, SRC_PARAM_SAMPLERATE, s);
- }
-
int nframes = inputsize / inputsamplesize;
ddb_dsp_context_t *dsp = dsp_chain;
dspfmt.samplerate = fileinfo->fmt.samplerate;
@@ -1405,6 +1523,17 @@ streamer_read_async (char *bytes, int size) {
int n = pcm_convert (&dspfmt, tempbuf, &output->fmt, bytes, nframes * dspsamplesize);
bytesread = n;
+
+ ddb_waveformat_t outfmt;
+ outfmt.bps = output->fmt.bps;
+ outfmt.is_float = output->fmt.is_float;
+ outfmt.channels = dspfmt.channels;
+ outfmt.samplerate = dspfmt.samplerate;
+ outfmt.channelmask = dspfmt.channelmask;
+ if (memcmp (&output_format, &outfmt, sizeof (ddb_waveformat_t))) {
+ memcpy (&output_format, &outfmt, sizeof (ddb_waveformat_t));
+ formatchanged = 1;
+ }
}
}
else {
@@ -1468,6 +1597,15 @@ streamer_read (char *bytes, int size) {
return -1;
}
DB_output_t *output = plug_get_output ();
+ if (formatchanged && bytes_until_next_song <= 0) {
+ formatchanged = 0;
+ plug_get_output ()->setformat (&output_format);
+ if (0 != output->play ()) {
+ fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
+ streamer_set_nextsong (-2, 0);
+ return -1;
+ }
+ }
streamer_lock ();
int sz = min (size, streamer_ringbuf.remaining);
if (sz) {
@@ -1593,10 +1731,6 @@ streamer_configchanged (void) {
conf_replaygain_mode = conf_get_int ("replaygain_mode", 0);
conf_replaygain_scale = conf_get_int ("replaygain_scale", 1);
pl_set_order (conf_get_int ("playback.order", 0));
-
- if (srcplug) {
- srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_str ("src_quality", "2"));
- }
}
void
@@ -1662,3 +1796,49 @@ ddb_dsp_context_t *
streamer_get_dsp_chain (void) {
return dsp_chain;
}
+
+static ddb_dsp_context_t *
+dsp_clone (ddb_dsp_context_t *from) {
+ ddb_dsp_context_t *dsp = from->plugin->open ();
+ char param[2000];
+ if (from->plugin->num_params) {
+ int n = from->plugin->num_params ();
+ for (int i = 0; i < n; i++) {
+ from->plugin->get_param (from, i, param, sizeof (param));
+ dsp->plugin->set_param (dsp, i, param);
+ }
+ }
+ dsp->enabled = from->enabled;
+ return dsp;
+}
+
+void
+streamer_set_dsp_chain (ddb_dsp_context_t *chain) {
+ mutex_lock (decodemutex);
+ streamer_dsp_chain_free (dsp_chain);
+
+ dsp_chain = NULL;
+ eq = NULL;
+
+ ddb_dsp_context_t *tail = NULL;
+ while (chain) {
+ printf ("copy %s\n", chain->plugin->plugin.id);
+ ddb_dsp_context_t *new = dsp_clone (chain);
+ if (tail) {
+ tail->next = new;
+ tail = new;
+ }
+ else {
+ dsp_chain = tail = new;
+ }
+ chain = chain->next;
+ }
+
+ streamer_dsp_postinit ();
+
+ char fname[PATH_MAX];
+ snprintf (fname, sizeof (fname), "%s/dspconfig", plug_get_config_dir ());
+ streamer_dsp_chain_save (fname, dsp_chain);
+
+ mutex_unlock (decodemutex);
+}
diff --git a/streamer.h b/streamer.h
index 7a65c95c..77165bae 100644
--- a/streamer.h
+++ b/streamer.h
@@ -111,4 +111,7 @@ streamer_notify_playlist_deleted (playlist_t *plt);
struct ddb_dsp_context_s *
streamer_get_dsp_chain (void);
+void
+streamer_set_dsp_chain (struct ddb_dsp_context_s *chain);
+
#endif // __STREAMER_H