From 0cf1d57bc3dab11f773d23a25db0c3d18f6cfe52 Mon Sep 17 00:00:00 2001 From: waker Date: Sun, 28 Nov 2010 17:24:14 +0100 Subject: ported supereq to new api; converted to float; added reentrancy support --- plugins/dsp_libsrc/src.c | 5 +- plugins/gtkui/eq.c | 127 ++++++++++--------- plugins/gtkui/eq.h | 4 +- plugins/gtkui/gtkui.c | 2 +- plugins/supereq/Equ.cpp | 309 ++++++++++++++++++++++++++++++++-------------- plugins/supereq/Equ.h | 44 +++++++ plugins/supereq/supereq.c | 251 ++++++++++++++++++++++++------------- plugins/supereq/supereq.h | 8 +- 8 files changed, 501 insertions(+), 249 deletions(-) create mode 100644 plugins/supereq/Equ.h (limited to 'plugins') 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 #include #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;ienable = 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;iditherbuf[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 ¶m2,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;iwinlen;i++) + state->irest[i] = hn(i-state->winlen/2,param2,fs)*win(i-state->winlen/2,state->winlen); - for(;itabsize;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;itabsize;i++) + nires[i] = state->irest[i]; process_param(rbc,param,param2,fs,1); // R - for(i=0;iwinlen;i++) + state->irest[i] = hn(i-state->winlen/2,param2,fs)*win(i-state->winlen/2,state->winlen); - for(;itabsize;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;itabsize;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;inbufsamples = 0; + for(i=0;itabsize*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;itabsize*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;chlires : state->rires; + + for(i=0;iwinlen;i++) + state->fsamples[i] = state->finbuf[nch*i+ch]; + + for(i=state->winlen;itabsize;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;itabsize/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;iwinlen;i++) state->outbuf[i*nch+ch] += state->fsamples[i]/state->tabsize*2; + + for(i=state->winlen;itabsize;i++) state->outbuf[i*nch+ch] = state->fsamples[i]/state->tabsize*2; + } + } + + for(i=0;ifinbuf[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 #include +#include #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 -- cgit v1.2.3