summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-11-28 17:24:14 +0100
committerGravatar waker <wakeroid@gmail.com>2010-11-28 17:24:14 +0100
commit0cf1d57bc3dab11f773d23a25db0c3d18f6cfe52 (patch)
treefb00bd49e8bdbccbe6643cddf3319878396be237 /plugins
parent78cebdb0a267effe32fe196c04124692b04ec9db (diff)
ported supereq to new api; converted to float; added reentrancy support
Diffstat (limited to 'plugins')
-rw-r--r--plugins/dsp_libsrc/src.c5
-rw-r--r--plugins/gtkui/eq.c127
-rw-r--r--plugins/gtkui/eq.h4
-rw-r--r--plugins/gtkui/gtkui.c2
-rw-r--r--plugins/supereq/Equ.cpp309
-rw-r--r--plugins/supereq/Equ.h44
-rw-r--r--plugins/supereq/supereq.c251
-rw-r--r--plugins/supereq/supereq.h8
8 files changed, 501 insertions, 249 deletions
diff --git a/plugins/dsp_libsrc/src.c b/plugins/dsp_libsrc/src.c
index 946ef3f4..0e71ef6e 100644
--- a/plugins/dsp_libsrc/src.c
+++ b/plugins/dsp_libsrc/src.c
@@ -47,7 +47,8 @@ typedef struct {
uintptr_t mutex;
} ddb_src_libsamplerate_t;
-DB_dsp_instance_t* ddb_src_open (const char *id) {
+DB_dsp_instance_t*
+ddb_src_open (const char *id) {
ddb_src_libsamplerate_t *src = malloc (sizeof (ddb_src_libsamplerate_t));
DDB_INIT_DSP_INSTANCE (src,ddb_src_libsamplerate_t,&plugin.dsp);
@@ -115,7 +116,7 @@ ddb_src_set_ratio (DB_dsp_instance_t *_src, float ratio) {
}
int
-ddb_src_process (DB_dsp_instance_t *_src, float *samples, int nframes, int nchannels) {
+ddb_src_process (DB_dsp_instance_t *_src, float *samples, int nframes, int samplerate, int nchannels) {
ddb_src_libsamplerate_t *src = (ddb_src_libsamplerate_t*)_src;
ddb_src_lock (_src);
diff --git a/plugins/gtkui/eq.c b/plugins/gtkui/eq.c
index a40e1900..c7a82dea 100644
--- a/plugins/gtkui/eq.c
+++ b/plugins/gtkui/eq.c
@@ -40,79 +40,88 @@ amp_to_db (float amp) {
return 20*log10 (amp);
}
-DB_supereq_dsp_t *
-get_supereq_plugin (void) {
- DB_dsp_t **plugs = deadbeef->plug_get_dsp_list ();
- for (int i = 0; plugs[i]; i++) {
- if (plugs[i]->plugin.id && !strcmp (plugs[i]->plugin.id, "supereq")) {
- return (DB_supereq_dsp_t *)plugs[i];
+DB_dsp_instance_t *
+get_supereq (void) {
+ DB_dsp_instance_t *dsp = deadbeef->streamer_get_dsp_chain ();
+ while (dsp) {
+ if (!strcmp (dsp->plugin->plugin.id, "supereq")) {
+ return dsp;
}
+ dsp = dsp->next;
}
+
return NULL;
}
void
eq_value_changed (DdbEqualizer *widget)
{
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- eq->set_band (i, db_to_amp (ddb_equalizer_get_band (widget, i)));
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ for (int i = 0; i < 18; i++) {
+ plugin->set_band (eq, i, db_to_amp (ddb_equalizer_get_band (widget, i)));
+ }
+ plugin->set_preamp (eq, db_to_amp (ddb_equalizer_get_preamp (widget)));
}
- eq->set_preamp (db_to_amp (ddb_equalizer_get_preamp (widget)));
}
void
on_enable_toggled (GtkToggleButton *togglebutton,
gpointer user_data) {
-#if 0 // !!!! FIXME !!!!
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->dsp.enabled = gtk_toggle_button_get_active (togglebutton) ? 1 : 0;
-#endif
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ plugin->dsp.enable (eq, gtk_toggle_button_get_active (togglebutton) ? 1 : 0);
+ }
}
void
on_zero_all_clicked (GtkButton *button,
gpointer user_data) {
-#if 0 // !!!! FIXME !!!!
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->set_preamp (1);
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
- for (int i = 0; i < 18; i++) {
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
- eq->set_band (i, 1);
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ plugin->set_preamp (eq, 1);
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
+ for (int i = 0; i < 18; i++) {
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
+ plugin->set_band (eq, i, 1);
+ }
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
-#endif
}
void
on_zero_preamp_clicked (GtkButton *button,
gpointer user_data) {
-#if 0 // !!!! FIXME !!!!
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- eq->set_preamp (1);
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ plugin->set_preamp (eq, 1);
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
+ }
}
-#endif
}
void
on_zero_bands_clicked (GtkButton *button,
gpointer user_data) {
-#if 0 // !!!! FIXME !!!!
if (eqwin) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
- eq->set_band (i, 1);
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ for (int i = 0; i < 18; i++) {
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0);
+ plugin->set_band (eq, i, 1);
+ }
+ gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
- gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
}
-#endif
}
void
@@ -138,11 +147,14 @@ on_save_preset_clicked (GtkButton *button,
if (fname) {
FILE *fp = fopen (fname, "w+b");
if (fp) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- for (int i = 0; i < 18; i++) {
- fprintf (fp, "%f\n", amp_to_db (eq->get_band (i)));
+ DB_dsp_instance_t *eq = get_supereq ();
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ for (int i = 0; i < 18; i++) {
+ fprintf (fp, "%f\n", amp_to_db (plugin->get_band (eq, i)));
+ }
+ fprintf (fp, "%f\n", amp_to_db (plugin->get_preamp (eq)));
}
- fprintf (fp, "%f\n", amp_to_db (eq->get_preamp ()));
fclose (fp);
}
g_free (fname);
@@ -194,13 +206,14 @@ on_load_preset_clicked (GtkButton *button,
fclose (fp);
if (i == 19) {
// apply and save config
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
+ DB_dsp_instance_t *eq = get_supereq ();
if (eq) {
- eq->set_preamp (db_to_amp (vals[18]));
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ plugin->set_preamp (eq, db_to_amp (vals[18]));
ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), vals[18]);
for (int i = 0; i < 18; i++) {
ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]);
- eq->set_band (i, db_to_amp (vals[i]));
+ plugin->set_band (eq, i, db_to_amp (vals[i]));
}
gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
deadbeef->conf_save ();
@@ -257,13 +270,14 @@ on_import_fb2k_preset_clicked (GtkButton *button,
fclose (fp);
if (i == 18) {
// apply and save config
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
+ DB_dsp_instance_t *eq = get_supereq ();
if (eq) {
- eq->set_preamp (1);
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ plugin->set_preamp (eq, 1);
ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0);
for (int i = 0; i < 18; i++) {
ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]);
- eq->set_band (i, db_to_amp (vals[i]));
+ plugin->set_band (eq, i, db_to_amp (vals[i]));
}
gdk_window_invalidate_rect (eqwin->window, NULL, FALSE);
deadbeef->conf_save ();
@@ -281,10 +295,6 @@ on_import_fb2k_preset_clicked (GtkButton *button,
void
eq_window_show (void) {
- DB_supereq_dsp_t *eq = get_supereq_plugin ();
- if (!eq) {
- return;
- }
if (!eqcont) {
eqcont = gtk_vbox_new (FALSE, 8);
GtkWidget *parent= lookup_widget (mainwin, "plugins_bottom_vbox");
@@ -300,7 +310,8 @@ eq_window_show (void) {
eqenablebtn = button = gtk_check_button_new_with_label (_("Enable"));
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (eqenablebtn), deadbeef->conf_get_int ("supereq.enable", 0));
+ DB_dsp_instance_t *eq = get_supereq ();
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (eqenablebtn), eq ? eq->enabled : 0);
g_signal_connect ((gpointer) button, "toggled",
G_CALLBACK (on_enable_toggled),
NULL);
@@ -351,12 +362,14 @@ eq_window_show (void) {
g_signal_connect (eqwin, "on_changed", G_CALLBACK (eq_value_changed), 0);
gtk_widget_set_size_request (eqwin, -1, 200);
-
- ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), amp_to_db (eq->get_preamp ()));
- for (int i = 0; i < 18; i++) {
- if (eq) {
- float val = eq->get_band (i);
- ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (val));
+ if (eq) {
+ DB_supereq_dsp_t *plugin = (DB_supereq_dsp_t *)eq->plugin;
+ ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), amp_to_db (plugin->get_preamp (eq)));
+ for (int i = 0; i < 18; i++) {
+ if (eq) {
+ float val = plugin->get_band (eq, i);
+ ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (val));
+ }
}
}
diff --git a/plugins/gtkui/eq.h b/plugins/gtkui/eq.h
index 9e54916e..6169123a 100644
--- a/plugins/gtkui/eq.h
+++ b/plugins/gtkui/eq.h
@@ -29,8 +29,8 @@ eq_window_hide (void);
void
eq_window_destroy (void);
-struct DB_supereq_dsp_s *
-get_supereq_plugin (void);
+DB_dsp_instance_t *
+get_supereq (void);
void
eq_redraw (void);
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index a2da9d74..e6a31da0 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -1137,7 +1137,7 @@ gboolean
gtkui_connect_cb (void *none) {
// equalizer
GtkWidget *eq_mi = lookup_widget (mainwin, "view_eq");
- if (!get_supereq_plugin ()) {
+ if (!deadbeef->plug_get_for_id ("supereq")) {
gtk_widget_hide (GTK_WIDGET (eq_mi));
}
else {
diff --git a/plugins/supereq/Equ.cpp b/plugins/supereq/Equ.cpp
index 4411dbd9..62ebfd70 100644
--- a/plugins/supereq/Equ.cpp
+++ b/plugins/supereq/Equ.cpp
@@ -3,6 +3,7 @@
#include <math.h>
#include <assert.h>
#include "paramlist.hpp"
+#include "Equ.h"
int _Unwind_Resume_or_Rethrow;
int _Unwind_RaiseException;
@@ -16,33 +17,22 @@ int _Unwind_GetRegionStart;
int _Unwind_SetGR;
int _Unwind_GetIPInfo;
-typedef float REAL;
void rfft(int n,int isign,REAL x[]);
-#define M 15
-
#define PI 3.1415926535897932384626433832795
+#if ENABLE_INT
#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
+#endif
#define DITHERLEN 65536
-// play -c 2 -r 44100 -fs -sw
-
+#define M 15
static REAL fact[M+1];
static REAL aa = 96;
-static REAL iza;
-static REAL *lires,*lires1,*lires2,*rires,*rires1,*rires2,*irest;
-static REAL *fsamples;
-static REAL *ditherbuf;
-static int ditherptr = 0;
-static volatile int chg_ires,cur_ires;
-static int winlen,winlenbit,tabsize,nbufsamples;
-static short *inbuf;
-static REAL *outbuf;
-static int maxamp;
-int enable = 1, dither = 0;
+static REAL iza = 0;
+// play -c 2 -r 44100 -fs -sw
#define NCH 2
#define NBANDS 17
@@ -74,49 +64,64 @@ static REAL izero(REAL x)
return ret;
}
-extern "C" void equ_init(int wb)
+extern "C" void equ_init(SuperEqState *state, int wb)
{
int i,j;
- if (lires1 != NULL) free(lires1);
- if (lires2 != NULL) free(lires2);
- if (rires1 != NULL) free(rires1);
- if (rires2 != NULL) free(rires2);
- if (irest != NULL) free(irest);
- if (fsamples != NULL) free(fsamples);
- if (inbuf != NULL) free(inbuf);
- if (outbuf != NULL) free(outbuf);
- if (ditherbuf != NULL) free(ditherbuf);
-
- winlen = (1 << (wb-1))-1;
- winlenbit = wb;
- tabsize = 1 << wb;
-
- lires1 = (REAL *)malloc(sizeof(REAL)*tabsize);
- lires2 = (REAL *)malloc(sizeof(REAL)*tabsize);
- rires1 = (REAL *)malloc(sizeof(REAL)*tabsize);
- rires2 = (REAL *)malloc(sizeof(REAL)*tabsize);
- irest = (REAL *)malloc(sizeof(REAL)*tabsize);
- fsamples = (REAL *)malloc(sizeof(REAL)*tabsize);
- inbuf = (short *)calloc(winlen*NCH,sizeof(int));
- outbuf = (REAL *)calloc(tabsize*NCH,sizeof(REAL));
- ditherbuf = (REAL *)malloc(sizeof(REAL)*DITHERLEN);
-
- lires = lires1;
- rires = rires1;
- cur_ires = 1;
- chg_ires = 1;
+ if (state->lires1 != NULL) free(state->lires1);
+ if (state->lires2 != NULL) free(state->lires2);
+ if (state->rires1 != NULL) free(state->rires1);
+ if (state->rires2 != NULL) free(state->rires2);
+ if (state->irest != NULL) free(state->irest);
+ if (state->fsamples != NULL) free(state->fsamples);
+#if ENABLE_INT
+ if (state->inbuf != NULL) free(state->inbuf);
+#endif
+#if ENABLE_REAL
+ if (state->finbuf != NULL) free(state->finbuf);
+#endif
+ if (state->outbuf != NULL) free(state->outbuf);
+ if (state->ditherbuf != NULL) free(state->ditherbuf);
- for(i=0;i<DITHERLEN;i++)
- ditherbuf[i] = (float(rand())/RAND_MAX-0.5);
- for(i=0;i<=M;i++)
- {
- fact[i] = 1;
- for(j=1;j<=i;j++) fact[i] *= j;
- }
+ memset (state, 0, sizeof (SuperEqState));
+ state->enable = 1;
+
+ state->winlen = (1 << (wb-1))-1;
+ state->winlenbit = wb;
+ state->tabsize = 1 << wb;
+
+ state->lires1 = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+ state->lires2 = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+ state->rires1 = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+ state->rires2 = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+ state->irest = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+ state->fsamples = (REAL *)malloc(sizeof(REAL)*state->tabsize);
+#if ENABLE_INT
+ state->inbuf = (short *)calloc(state->winlen*NCH,sizeof(int));
+#endif
+#if ENABLE_REAL
+ state->finbuf = (REAL *)calloc(state->winlen*NCH,sizeof(REAL));
+#endif
+ state->outbuf = (REAL *)calloc(state->tabsize*NCH,sizeof(REAL));
+ state->ditherbuf = (REAL *)malloc(sizeof(REAL)*DITHERLEN);
- iza = izero(alpha(aa));
+ state->lires = state->lires1;
+ state->rires = state->rires1;
+ state->cur_ires = 1;
+ state->chg_ires = 1;
+
+ for(i=0;i<DITHERLEN;i++)
+ state->ditherbuf[i] = (float(rand())/RAND_MAX-0.5);
+
+ if (fact[0] < 1) {
+ for(i=0;i<=M;i++)
+ {
+ fact[i] = 1;
+ for(j=1;j<=i;j++) fact[i] *= j;
+ }
+ iza = izero(alpha(aa));
+ }
}
// -(N-1)/2 <= n <= (N-1)/2
@@ -243,9 +248,10 @@ void process_param(REAL *bc,paramlist *param,paramlist &param2,REAL fs,int ch)
}
}
-extern "C" void equ_makeTable(REAL *lbc,REAL *rbc,paramlist *param,REAL fs)
+extern "C" void equ_makeTable(SuperEqState *state, REAL *lbc,REAL *rbc,void *_param,REAL fs)
{
- int i,cires = cur_ires;
+ paramlist *param = (paramlist *)_param;
+ int i,cires = state->cur_ires;
REAL *nires;
if (fs <= 0) return;
@@ -256,73 +262,187 @@ extern "C" void equ_makeTable(REAL *lbc,REAL *rbc,paramlist *param,REAL fs)
process_param(lbc,param,param2,fs,0);
- for(i=0;i<winlen;i++)
- irest[i] = hn(i-winlen/2,param2,fs)*win(i-winlen/2,winlen);
+ for(i=0;i<state->winlen;i++)
+ state->irest[i] = hn(i-state->winlen/2,param2,fs)*win(i-state->winlen/2,state->winlen);
- for(;i<tabsize;i++)
- irest[i] = 0;
+ for(;i<state->tabsize;i++)
+ state->irest[i] = 0;
- rfft(tabsize,1,irest);
+ rfft(state->tabsize,1,state->irest);
- nires = cires == 1 ? lires2 : lires1;
+ nires = cires == 1 ? state->lires2 : state->lires1;
- for(i=0;i<tabsize;i++)
- nires[i] = irest[i];
+ for(i=0;i<state->tabsize;i++)
+ nires[i] = state->irest[i];
process_param(rbc,param,param2,fs,1);
// R
- for(i=0;i<winlen;i++)
- irest[i] = hn(i-winlen/2,param2,fs)*win(i-winlen/2,winlen);
+ for(i=0;i<state->winlen;i++)
+ state->irest[i] = hn(i-state->winlen/2,param2,fs)*win(i-state->winlen/2,state->winlen);
- for(;i<tabsize;i++)
- irest[i] = 0;
+ for(;i<state->tabsize;i++)
+ state->irest[i] = 0;
- rfft(tabsize,1,irest);
+ rfft(state->tabsize,1,state->irest);
- nires = cires == 1 ? rires2 : rires1;
+ nires = cires == 1 ? state->rires2 : state->rires1;
- for(i=0;i<tabsize;i++)
- nires[i] = irest[i];
+ for(i=0;i<state->tabsize;i++)
+ nires[i] = state->irest[i];
//
- chg_ires = cires == 1 ? 2 : 1;
+ state->chg_ires = cires == 1 ? 2 : 1;
}
-extern "C" void equ_quit(void)
+extern "C" void equ_quit(SuperEqState *state)
{
- free(lires1);
- free(lires2);
- free(rires1);
- free(rires2);
- free(irest);
- free(fsamples);
- free(inbuf);
- free(outbuf);
- free(ditherbuf);
-
- lires1 = NULL;
- lires2 = NULL;
- rires1 = NULL;
- rires2 = NULL;
- irest = NULL;
- fsamples = NULL;
- inbuf = NULL;
- outbuf = NULL;
+ free(state->lires1);
+ free(state->lires2);
+ free(state->rires1);
+ free(state->rires2);
+ free(state->irest);
+ free(state->fsamples);
+#if ENABLE_INT
+ free(state->inbuf);
+#endif
+#if ENABLE_REAL
+ free(state->finbuf);
+#endif
+ free(state->outbuf);
+ free(state->ditherbuf);
+
+ state->lires1 = NULL;
+ state->lires2 = NULL;
+ state->rires1 = NULL;
+ state->rires2 = NULL;
+ state->irest = NULL;
+ state->fsamples = NULL;
+#if ENABLE_INT
+ state->inbuf = NULL;
+#endif
+#if ENABLE_REAL
+ state->finbuf = NULL;
+#endif
+ state->outbuf = NULL;
rfft(0,0,NULL);
}
-extern "C" void equ_clearbuf(int bps,int srate)
+extern "C" void equ_clearbuf(SuperEqState *state)
{
int i;
- nbufsamples = 0;
- for(i=0;i<tabsize*NCH;i++) outbuf[i] = 0;
+ state->nbufsamples = 0;
+ for(i=0;i<state->tabsize*NCH;i++) state->outbuf[i] = 0;
+}
+
+#if ENABLE_REAL
+extern "C" int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamples,int nch)
+{
+ int i,p,ch;
+ REAL *ires;
+ float amax = 1.0f;
+ float amin = -1.0f;
+ static float hm1 = 0, hm2 = 0;
+
+ if (state->chg_ires) {
+ state->cur_ires = state->chg_ires;
+ state->lires = state->cur_ires == 1 ? state->lires1 : state->lires2;
+ state->rires = state->cur_ires == 1 ? state->rires1 : state->rires2;
+ state->chg_ires = 0;
+ }
+
+ p = 0;
+
+ while(state->nbufsamples+nsamples >= state->winlen)
+ {
+ for(i=0;i<(state->winlen-state->nbufsamples)*nch;i++)
+ {
+ state->finbuf[state->nbufsamples*nch+i] = ((float *)buf)[i+p*nch];
+ float s = state->outbuf[state->nbufsamples*nch+i];
+ //if (dither) s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
+ if (s < amin) s = amin;
+ if (amax < s) s = amax;
+ ((float *)buf)[i+p*nch] = s;
+ }
+ for(i=state->winlen*nch;i<state->tabsize*nch;i++)
+ state->outbuf[i-state->winlen*nch] = state->outbuf[i];
+
+
+ p += state->winlen-state->nbufsamples;
+ nsamples -= state->winlen-state->nbufsamples;
+ state->nbufsamples = 0;
+
+ for(ch=0;ch<nch;ch++)
+ {
+ ires = ch == 0 ? state->lires : state->rires;
+
+ for(i=0;i<state->winlen;i++)
+ state->fsamples[i] = state->finbuf[nch*i+ch];
+
+ for(i=state->winlen;i<state->tabsize;i++)
+ state->fsamples[i] = 0;
+
+ if (state->enable) {
+ rfft(state->tabsize,1,state->fsamples);
+
+ state->fsamples[0] = ires[0]*state->fsamples[0];
+ state->fsamples[1] = ires[1]*state->fsamples[1];
+
+ for(i=1;i<state->tabsize/2;i++)
+ {
+ REAL re,im;
+
+ re = ires[i*2 ]*state->fsamples[i*2] - ires[i*2+1]*state->fsamples[i*2+1];
+ im = ires[i*2+1]*state->fsamples[i*2] + ires[i*2 ]*state->fsamples[i*2+1];
+
+ state->fsamples[i*2 ] = re;
+ state->fsamples[i*2+1] = im;
+ }
+
+ rfft(state->tabsize,-1,state->fsamples);
+ } else {
+ for(i=state->winlen-1+state->winlen/2;i>=state->winlen/2;i--) state->fsamples[i] = state->fsamples[i-state->winlen/2]*state->tabsize/2;
+ for(;i>=0;i--) state->fsamples[i] = 0;
+ }
+
+ for(i=0;i<state->winlen;i++) state->outbuf[i*nch+ch] += state->fsamples[i]/state->tabsize*2;
+
+ for(i=state->winlen;i<state->tabsize;i++) state->outbuf[i*nch+ch] = state->fsamples[i]/state->tabsize*2;
+ }
+ }
+
+ for(i=0;i<nsamples*nch;i++)
+ {
+ state->finbuf[state->nbufsamples*nch+i] = ((float *)buf)[i+p*nch];
+ float s = state->outbuf[state->nbufsamples*nch+i];
+ if (state->dither) {
+ float u;
+ s -= hm1;
+ u = s;
+// s += ditherbuf[(ditherptr++) & (DITHERLEN-1)];
+ if (s < amin) s = amin;
+ if (amax < s) s = amax;
+ hm1 = s - u;
+ ((float *)buf)[i+p*nch] = s;
+ } else {
+ if (s < amin) s = amin;
+ if (amax < s) s = amax;
+ ((float *)buf)[i+p*nch] = s;
+ }
+ }
+
+ p += nsamples;
+ state->nbufsamples += nsamples;
+
+ return p;
}
+#endif
+#if ENABLE_INT
extern "C" int equ_modifySamples(char *buf,int nsamples,int nch,int bps)
{
int i,p,ch;
@@ -546,6 +666,7 @@ extern "C" int equ_modifySamples(char *buf,int nsamples,int nch,int bps)
return p;
}
+#endif
#if 0
void usage(void)
diff --git a/plugins/supereq/Equ.h b/plugins/supereq/Equ.h
new file mode 100644
index 00000000..3018c411
--- /dev/null
+++ b/plugins/supereq/Equ.h
@@ -0,0 +1,44 @@
+#ifndef __EQU_H
+#define __EQU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ENABLE_REAL 1
+#define ENABLE_INT 0
+
+typedef float REAL;
+typedef struct {
+ REAL *lires,*lires1,*lires2,*rires,*rires1,*rires2,*irest;
+ REAL *fsamples;
+ REAL *ditherbuf;
+ int ditherptr;
+ volatile int chg_ires,cur_ires;
+ int winlen,winlenbit,tabsize,nbufsamples;
+#if ENABLE_INT
+ short *inbuf;
+#endif
+#if ENABLE_REAL
+ REAL *finbuf;
+#endif
+ REAL *outbuf;
+ int maxamp;
+ int dither;
+ int enable;
+} SuperEqState;
+
+void *paramlist_alloc (void);
+void paramlist_free (void *);
+void equ_makeTable(SuperEqState *state, float *lbc,float *rbc,void *param,float fs);
+int equ_modifySamples(SuperEqState *state, char *buf,int nsamples,int nch,int bps);
+int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamples,int nch);
+void equ_clearbuf(SuperEqState *state);
+void equ_init(SuperEqState *state, int wb);
+void equ_quit(SuperEqState *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c
index 6ebf9b24..498b01e1 100644
--- a/plugins/supereq/supereq.c
+++ b/plugins/supereq/supereq.c
@@ -18,34 +18,59 @@
*/
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "../../deadbeef.h"
#include "supereq.h"
+#include "Equ.h"
static DB_functions_t *deadbeef;
static DB_supereq_dsp_t plugin;
-void *paramlist_alloc (void);
-void paramlist_free (void *);
-void equ_makeTable(float *lbc,float *rbc,void *param,float fs);
-int equ_modifySamples(char *buf,int nsamples,int nch,int bps);
-void equ_clearbuf(int bps,int srate);
-void equ_init(int wb);
-void equ_quit(void);
+typedef struct {
+ DB_dsp_instance_t inst;
+ float last_srate;
+ int last_nch;
+ float lbands[18];
+ float rbands[18];
+ float preamp;
+ void *paramsroot;
+ int params_changed;
+ intptr_t tid;
+ uintptr_t mutex;
+ SuperEqState state;
+} ddb_supereq_instance_t;
-void supereq_reset (void);
+static float
+dsp_conf_get_float (DB_dsp_instance_t *inst, const char *name, float def) {
+ char key[100];
+ snprintf (key, sizeof (key), "%s.%s", inst->id, name);
+ return deadbeef->conf_get_float (key, def);
+}
-static float last_srate = 0;
-static int last_nch = 0, last_bps = 0;
-static float lbands[18] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
-static float rbands[18] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
-static float preamp = 1;
-static void *paramsroot;
+static int
+dsp_conf_get_int (DB_dsp_instance_t *inst, const char *name, int def) {
+ char key[100];
+ snprintf (key, sizeof (key), "%s.%s", inst->id, name);
+ return deadbeef->conf_get_int (key, def);
+}
-static int params_changed = 0;
-static intptr_t tid = 0;
-static uintptr_t mutex = 0;
-static int enabled = 0;
+static void
+dsp_conf_set_float (DB_dsp_instance_t *inst, const char *name, float value) {
+ char key[100];
+ snprintf (key, sizeof (key), "%s.%s", inst->id, name);
+ return deadbeef->conf_set_float (key, value);
+}
+static void
+dsp_conf_set_int (DB_dsp_instance_t *inst, const char *name, int value) {
+ char key[100];
+ snprintf (key, sizeof (key), "%s.%s", inst->id, name);
+ return deadbeef->conf_set_int (key, value);
+}
+
+void supereq_reset (DB_dsp_instance_t *inst);
+
+#if 0
static int
supereq_on_configchanged (DB_event_t *ev, uintptr_t data) {
int e = deadbeef->conf_get_int ("supereq.enable", 0);
@@ -58,33 +83,35 @@ supereq_on_configchanged (DB_event_t *ev, uintptr_t data) {
return 0;
}
+#endif
void
-recalc_table (void) {
+recalc_table (ddb_supereq_instance_t *eq) {
void *params = paramlist_alloc ();
- deadbeef->mutex_lock (mutex);
+ deadbeef->mutex_lock (eq->mutex);
float lbands_copy[18];
float rbands_copy[18];
- float srate = last_srate;
- memcpy (lbands_copy, lbands, sizeof (lbands));
- memcpy (rbands_copy, rbands, sizeof (rbands));
+ float srate = eq->last_srate;
+ memcpy (lbands_copy, eq->lbands, sizeof (eq->lbands));
+ memcpy (rbands_copy, eq->rbands, sizeof (eq->rbands));
for (int i = 0; i < 18; i++) {
- lbands_copy[i] *= preamp;
- rbands_copy[i] *= preamp;
+ lbands_copy[i] *= eq->preamp;
+ rbands_copy[i] *= eq->preamp;
}
- deadbeef->mutex_unlock (mutex);
+ deadbeef->mutex_unlock (eq->mutex);
- equ_makeTable (lbands_copy, rbands_copy, params, srate);
+ equ_makeTable (&eq->state, lbands_copy, rbands_copy, params, srate);
- deadbeef->mutex_lock (mutex);
- paramlist_free (paramsroot);
- paramsroot = params;
- deadbeef->mutex_unlock (mutex);
+ deadbeef->mutex_lock (eq->mutex);
+ paramlist_free (eq->paramsroot);
+ eq->paramsroot = params;
+ deadbeef->mutex_unlock (eq->mutex);
}
int
supereq_plugin_start (void) {
+#if 0
enabled = deadbeef->conf_get_int ("supereq.enable", 0);
// load bands from config
preamp = deadbeef->conf_get_float ("eq.preamp", 1);
@@ -98,16 +125,17 @@ supereq_plugin_start (void) {
paramsroot = paramlist_alloc ();
last_srate = 44100;
last_nch = 2;
- last_bps = 16;
mutex = deadbeef->mutex_create ();
recalc_table ();
- equ_clearbuf (last_bps,last_srate);
- deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
+ equ_clearbuf ();
+// deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
+#endif
return 0;
}
int
supereq_plugin_stop (void) {
+#if 0
deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
if (tid) {
deadbeef->thread_join (tid);
@@ -119,94 +147,138 @@ supereq_plugin_stop (void) {
}
equ_quit ();
paramlist_free (paramsroot);
+#endif
return 0;
}
void
supereq_regen_table_thread (void *param) {
- recalc_table ();
- tid = 0;
+ ddb_supereq_instance_t *inst = param;
+ recalc_table (inst);
+ inst->tid = 0;
}
int
-supereq_process (char * restrict samples, ddb_waveformat_t * restrict fmt) {
- if ((nch != 1 && nch != 2) || (bps != 8 && bps != 16 && bps != 24)) return nsamples;
- if (params_changed && !tid) {
- tid = deadbeef->thread_start (supereq_regen_table_thread, NULL);
- params_changed = 0;
+supereq_process (DB_dsp_instance_t *inst, float *samples, int frames, int samplerate, int channels) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ if (supereq->params_changed && !supereq->tid) {
+ supereq->tid = deadbeef->thread_start (supereq_regen_table_thread, inst);
+ supereq->params_changed = 0;
}
- if (last_srate != srate) {
- deadbeef->mutex_lock (mutex);
+ if (supereq->last_srate != samplerate) {
+ deadbeef->mutex_lock (supereq->mutex);
//equ_makeTable (lbands, rbands, paramsroot, srate);
- last_srate = srate;
- last_nch = nch;
- last_bps = bps;
- recalc_table ();
- deadbeef->mutex_unlock (mutex);
- equ_clearbuf(bps,srate);
+ supereq->last_srate = samplerate;
+ supereq->last_nch = channels;
+ recalc_table ((ddb_supereq_instance_t *)inst);
+ deadbeef->mutex_unlock (supereq->mutex);
+ equ_clearbuf(&supereq->state);
}
- else if (last_nch != nch || last_bps != bps) {
- deadbeef->mutex_lock (mutex);
- last_nch = nch;
- last_bps = bps;
- deadbeef->mutex_unlock (mutex);
- equ_clearbuf(bps,srate);
+ else if (supereq->last_nch != channels) {
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->last_nch = channels;
+ deadbeef->mutex_unlock (supereq->mutex);
+ equ_clearbuf(&supereq->state);
}
- equ_modifySamples((char *)samples,nsamples,nch,bps);
- return nsamples;
+ equ_modifySamples_float(&supereq->state, (char *)samples,frames,channels);
+ return frames;
}
float
-supereq_get_band (int band) {
- return lbands[band];
+supereq_get_band (DB_dsp_instance_t *inst, int band) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ return supereq->lbands[band];
}
void
-supereq_set_band (int band, float value) {
- deadbeef->mutex_lock (mutex);
- lbands[band] = rbands[band] = value;
- deadbeef->mutex_unlock (mutex);
- params_changed = 1;
+supereq_set_band (DB_dsp_instance_t *inst, int band, float value) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->lbands[band] = supereq->rbands[band] = value;
+ deadbeef->mutex_unlock (supereq->mutex);
+ supereq->params_changed = 1;
char key[100];
- snprintf (key, sizeof (key), "eq.band%d", band);
- deadbeef->conf_set_float (key, value);
+ snprintf (key, sizeof (key), "band%d", band);
+ dsp_conf_set_float (inst, key, value);
}
float
-supereq_get_preamp (void) {
- return preamp;
+supereq_get_preamp (DB_dsp_instance_t *inst) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ return supereq->preamp;
}
void
-supereq_set_preamp (float value) {
- deadbeef->mutex_lock (mutex);
- preamp = value;
- deadbeef->mutex_unlock (mutex);
- params_changed = 1;
- deadbeef->conf_set_float ("eq.preamp", value);
+supereq_set_preamp (DB_dsp_instance_t *inst, float value) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ deadbeef->mutex_lock (supereq->mutex);
+ supereq->preamp = value;
+ deadbeef->mutex_unlock (supereq->mutex);
+ supereq->params_changed = 1;
+ dsp_conf_set_float (inst, "preamp", value);
}
void
-supereq_reset (void) {
- deadbeef->mutex_lock (mutex);
- equ_clearbuf(last_bps,last_srate);
- deadbeef->mutex_unlock (mutex);
+supereq_reset (DB_dsp_instance_t *inst) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ deadbeef->mutex_lock (supereq->mutex);
+ equ_clearbuf(&supereq->state);
+ deadbeef->mutex_unlock (supereq->mutex);
}
void
-supereq_enable (int e) {
- if (e != enabled) {
- deadbeef->conf_set_int ("supereq.enable", e);
- if (e && !enabled) {
- supereq_reset ();
+supereq_enable (DB_dsp_instance_t *inst, int e) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ if (e != supereq->inst.enabled) {
+ dsp_conf_set_int (inst, "enabled", e);
+ if (e && !supereq->inst.enabled) {
+ supereq_reset (inst);
}
- enabled = e;
+ supereq->inst.enabled = e;
}
}
-int
-supereq_enabled (void) {
- return enabled;
+DB_dsp_instance_t*
+supereq_open (const char *id) {
+ ddb_supereq_instance_t *supereq = malloc (sizeof (ddb_supereq_instance_t));
+ DDB_INIT_DSP_INSTANCE (supereq,ddb_supereq_instance_t,&plugin.dsp);
+
+ supereq->preamp = dsp_conf_get_float (&supereq->inst, "preamp", 1);
+ for (int i = 0; i < 18; i++) {
+ char key[100];
+ snprintf (key, sizeof (key), "band%d", i);
+ supereq->lbands[i] = supereq->rbands[i] = dsp_conf_get_float (&supereq->inst, key, 1);
+ }
+
+ supereq->inst.enabled = dsp_conf_get_int (&supereq->inst, "enabled", 0);
+
+ equ_init (&supereq->state, 14);
+ supereq->paramsroot = paramlist_alloc ();
+ supereq->last_srate = 44100;
+ supereq->last_nch = 2;
+ supereq->mutex = deadbeef->mutex_create ();
+ recalc_table (supereq);
+ equ_clearbuf (&supereq->state);
+// deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0);
+
+
+ return (DB_dsp_instance_t*)supereq;
+}
+
+void
+supereq_close (DB_dsp_instance_t *inst) {
+ ddb_supereq_instance_t *supereq = (ddb_supereq_instance_t *)inst;
+ if (supereq->tid) {
+ deadbeef->thread_join (supereq->tid);
+ supereq->tid = 0;
+ }
+ if (supereq->mutex) {
+ deadbeef->mutex_free (supereq->mutex);
+ supereq->mutex = 0;
+ }
+ equ_quit (&supereq->state);
+ paramlist_free (supereq->paramsroot);
+ free (inst);
}
static DB_supereq_dsp_t plugin = {
@@ -223,10 +295,11 @@ static DB_supereq_dsp_t plugin = {
.dsp.plugin.website = "http://deadbeef.sf.net",
.dsp.plugin.start = supereq_plugin_start,
.dsp.plugin.stop = supereq_plugin_stop,
- .dsp.process_int16 = supereq_process_int16,
+ .dsp.open = supereq_open,
+ .dsp.close = supereq_close,
+ .dsp.process = supereq_process,
.dsp.reset = supereq_reset,
.dsp.enable = supereq_enable,
- .dsp.enabled = supereq_enabled,
.get_band = supereq_get_band,
.set_band = supereq_set_band,
.get_preamp = supereq_get_preamp,
diff --git a/plugins/supereq/supereq.h b/plugins/supereq/supereq.h
index 32298ef1..2588df91 100644
--- a/plugins/supereq/supereq.h
+++ b/plugins/supereq/supereq.h
@@ -22,10 +22,10 @@
typedef struct DB_supereq_dsp_s {
DB_dsp_t dsp;
- float (*get_band) (int band);
- void (*set_band) (int band, float value);
- float (*get_preamp) (void);
- void (*set_preamp) (float value);
+ float (*get_band) (DB_dsp_instance_t *inst, int band);
+ void (*set_band) (DB_dsp_instance_t *inst, int band, float value);
+ float (*get_preamp) (DB_dsp_instance_t *inst);
+ void (*set_preamp) (DB_dsp_instance_t *inst, float value);
} DB_supereq_dsp_t;
#endif