From 2b1ca23ad9bdeb36747aabc44cafa1d8eca77a1e Mon Sep 17 00:00:00 2001 From: waker Date: Mon, 3 Jan 2011 21:32:26 +0100 Subject: added multichannel support to supereq plugin; cleaned up unused supereq code; added license text to supereq files --- plugins/supereq/Equ.cpp | 455 ++++-------------------------------------- plugins/supereq/Equ.h | 35 ++-- plugins/supereq/paramlist.hpp | 31 +-- plugins/supereq/supereq.c | 32 +-- 4 files changed, 96 insertions(+), 457 deletions(-) (limited to 'plugins/supereq') diff --git a/plugins/supereq/Equ.cpp b/plugins/supereq/Equ.cpp index 62ebfd70..369d0fcc 100644 --- a/plugins/supereq/Equ.cpp +++ b/plugins/supereq/Equ.cpp @@ -1,3 +1,22 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2011 Alexey Yakovenko + Original SuperEQ code (C) Naoki Shibata + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ #include #include #include @@ -21,10 +40,6 @@ void rfft(int n,int isign,REAL x[]); #define PI 3.1415926535897932384626433832795 -#if ENABLE_INT -#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5))) -#endif - #define DITHERLEN 65536 #define M 15 @@ -32,9 +47,6 @@ static REAL fact[M+1]; static REAL aa = 96; static REAL iza = 0; -// play -c 2 -r 44100 -fs -sw -#define NCH 2 - #define NBANDS 17 static REAL bands[] = { 65.406392,92.498606,130.81278,184.99721,261.62557,369.99442,523.25113, @@ -64,50 +76,36 @@ static REAL izero(REAL x) return ret; } -extern "C" void equ_init(SuperEqState *state, int wb) +extern "C" void equ_init(SuperEqState *state, int wb, int channels) { int i,j; 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); memset (state, 0, sizeof (SuperEqState)); + state->channels = channels; 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->lires1 = (REAL *)malloc(sizeof(REAL)*state->tabsize * state->channels); + state->lires2 = (REAL *)malloc(sizeof(REAL)*state->tabsize * state->channels); 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->finbuf = (REAL *)calloc(state->winlen*state->channels,sizeof(REAL)); + state->outbuf = (REAL *)calloc(state->tabsize*state->channels,sizeof(REAL)); state->ditherbuf = (REAL *)malloc(sizeof(REAL)*DITHERLEN); state->lires = state->lires1; - state->rires = state->rires1; state->cur_ires = 1; state->chg_ires = 1; @@ -185,7 +183,6 @@ void process_param(REAL *bc,paramlist *param,paramlist ¶m2,REAL fs,int ch) for(e = param->elm;e != NULL;e = e->next) { - if ((ch == 0 && !e->left) || (ch == 1 && !e->right)) continue; if (e->lower >= e->upper) continue; for(p=param2.elm;p != NULL;p = p->next) @@ -248,9 +245,9 @@ void process_param(REAL *bc,paramlist *param,paramlist ¶m2,REAL fs,int ch) } } -extern "C" void equ_makeTable(SuperEqState *state, REAL *lbc,REAL *rbc,void *_param,REAL fs) +extern "C" void equ_makeTable(SuperEqState *state, REAL *lbc,void *_param,REAL fs) { - paramlist *param = (paramlist *)_param; + paramlist *param = (paramlist *)_param; int i,cires = state->cur_ires; REAL *nires; @@ -258,42 +255,23 @@ extern "C" void equ_makeTable(SuperEqState *state, REAL *lbc,REAL *rbc,void *_pa paramlist param2; - // L - - 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; + for (int ch = 0; ch < state->channels; ch++) { + process_param(lbc,param,param2,fs,ch); - rfft(state->tabsize,1,state->irest); - - 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(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; + for(;itabsize;i++) + state->irest[i] = 0; - rfft(state->tabsize,1,state->irest); + rfft(state->tabsize,1,state->irest); - nires = cires == 1 ? state->rires2 : state->rires1; + nires = cires == 1 ? state->lires2 : state->lires1; + nires += ch * state->tabsize; - for(i=0;itabsize;i++) - nires[i] = state->irest[i]; - - // - + for(i=0;itabsize;i++) + nires[i] = state->irest[i]; + } state->chg_ires = cires == 1 ? 2 : 1; } @@ -301,31 +279,17 @@ extern "C" void equ_quit(SuperEqState *state) { 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); @@ -336,10 +300,9 @@ extern "C" void equ_clearbuf(SuperEqState *state) int i; state->nbufsamples = 0; - for(i=0;itabsize*NCH;i++) state->outbuf[i] = 0; + for(i=0;itabsize*state->channels;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; @@ -351,7 +314,6 @@ extern "C" int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamp 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; } @@ -378,10 +340,10 @@ extern "C" int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamp for(ch=0;chlires : state->rires; + ires = state->lires + ch * state->tabsize; - for(i=0;iwinlen;i++) - state->fsamples[i] = state->finbuf[nch*i+ch]; + for(i=0;iwinlen;i++) + state->fsamples[i] = state->finbuf[nch*i+ch]; for(i=state->winlen;itabsize;i++) state->fsamples[i] = 0; @@ -440,337 +402,6 @@ extern "C" int equ_modifySamples_float (SuperEqState *state, char *buf,int nsamp return p; } -#endif - -#if ENABLE_INT -extern "C" int equ_modifySamples(char *buf,int nsamples,int nch,int bps) -{ - int i,p,ch; - REAL *ires; - int amax = (1 << (bps-1))-1; - int amin = -(1 << (bps-1)); - static float hm1 = 0, hm2 = 0; - - if (chg_ires) { - cur_ires = chg_ires; - lires = cur_ires == 1 ? lires1 : lires2; - rires = cur_ires == 1 ? rires1 : rires2; - chg_ires = 0; - } - - p = 0; - - while(nbufsamples+nsamples >= winlen) - { - switch(bps) - { - case 8: - for(i=0;i<(winlen-nbufsamples)*nch;i++) - { - inbuf[nbufsamples*nch+i] = ((unsigned char *)buf)[i+p*nch] - 0x80; - float s = outbuf[nbufsamples*nch+i]; - if (dither) { - float u; - s -= hm1; - u = s; - s += ditherbuf[(ditherptr++) & (DITHERLEN-1)]; - if (s < amin) s = amin; - if (amax < s) s = amax; - s = RINT(s); - hm1 = s - u; - ((unsigned char *)buf)[i+p*nch] = s + 0x80; - } else { - if (s < amin) s = amin; - if (amax < s) s = amax; - ((unsigned char *)buf)[i+p*nch] = RINT(s) + 0x80; - } - } - for(i=winlen*nch;i>= 8; - ((signed char *)buf)[(i+p*nch)*3+1] = s2 & 255; s2 >>= 8; - ((signed char *)buf)[(i+p*nch)*3+2] = s2 & 255; - } - for(i=winlen*nch;i=winlen/2;i--) fsamples[i] = fsamples[i-winlen/2]*tabsize/2; - for(;i>=0;i--) fsamples[i] = 0; - } - - for(i=0;i>= 8; - ((signed char *)buf)[(i+p*nch)*3+1] = s2 & 255; s2 >>= 8; - ((signed char *)buf)[(i+p*nch)*3+2] = s2 & 255; - } - break; - - default: - assert(0); - } - - p += nsamples; - nbufsamples += nsamples; - - return p; -} -#endif - -#if 0 -void usage(void) -{ - fprintf(stderr,"Ouch!\n"); -} - -int main(int argc,char **argv) -{ - FILE *fpi,*fpo; - char buf[576*2*2]; - - static REAL bc[] = - {1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0,1.0, 0}; - - init(14); - makeTable(bc,44100); - - if (argc != 3 && argc != 4) exit(-1); - - fpi = fopen(argv[1],"r"); - fpo = fopen(argv[2],"w"); - - if (!fpi || !fpo) exit(-1); - - /* generate wav header */ - - { - short word; - int dword; - - fwrite("RIFF",4,1,fpo); - dword = 0; - fwrite(&dword,4,1,fpo); - - fwrite("WAVEfmt ",8,1,fpo); - dword = 16; - fwrite(&dword,4,1,fpo); - word = 1; - fwrite(&word,2,1,fpo); /* format category, PCM */ - word = 2; - fwrite(&word,2,1,fpo); /* channels */ - dword = 44100; - fwrite(&dword,4,1,fpo); /* sampling rate */ - dword = 44100*2*2; - fwrite(&dword,4,1,fpo); /* bytes per sec */ - word = 4; - fwrite(&word,2,1,fpo); /* block alignment */ - word = 16; - fwrite(&word,2,1,fpo); /* ??? */ - - fwrite("data",4,1,fpo); - dword = 0; - fwrite(&dword,4,1,fpo); - } - - preamp = 65536; - maxamp = 0; - - if (argc == 4) { - preamp = 32767*65536/atoi(argv[3]); - fprintf(stderr,"preamp = %d\n",preamp); - } - - for(;;) - { - int n,m; - - n = fread(buf,1,576*2*2,fpi); - if (n <= 0) break; - m = modifySamples((short *)buf,n/4,2); - fwrite(buf,4,m,fpo); - } - -#if 0 - for(;;) - { - int n = flushbuf((short *)buf,576); - if (n == 0) break; - fwrite(buf,4,n,fpo); - } -#endif - - { - short word; - int dword; - int len = ftell(fpo); - - fseek(fpo,4,SEEK_SET); - dword = len-8; - fwrite(&dword,4,1,fpo); - - fseek(fpo,40,SEEK_SET); - dword = len-44; - fwrite(&dword,4,1,fpo); - } - - if (maxamp != 0) { - fprintf(stderr,"maxamp = %d\n",maxamp); - } - - quit(); -} -#endif extern "C" void *paramlist_alloc (void) { return (void *)(new paramlist); diff --git a/plugins/supereq/Equ.h b/plugins/supereq/Equ.h index 3018c411..de90fd17 100644 --- a/plugins/supereq/Equ.h +++ b/plugins/supereq/Equ.h @@ -1,3 +1,21 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2011 Alexey Yakovenko + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ #ifndef __EQU_H #define __EQU_H @@ -5,36 +23,29 @@ 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 *lires,*lires1,*lires2; + REAL *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 channels; int enable; } SuperEqState; void *paramlist_alloc (void); void paramlist_free (void *); -void equ_makeTable(SuperEqState *state, float *lbc,float *rbc,void *param,float fs); +void equ_makeTable(SuperEqState *state, float *lbc,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_init(SuperEqState *state, int wb, int channels); void equ_quit(SuperEqState *state); #ifdef __cplusplus diff --git a/plugins/supereq/paramlist.hpp b/plugins/supereq/paramlist.hpp index 0c513b78..9c5b09c4 100644 --- a/plugins/supereq/paramlist.hpp +++ b/plugins/supereq/paramlist.hpp @@ -1,4 +1,22 @@ -//#include +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2011 Alexey Yakovenko + Original SuperEQ code (C) Naoki Shibata + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ #include #include #include @@ -7,12 +25,10 @@ class paramlistelm { public: class paramlistelm *next; - char left,right; float lower,upper,gain,gain2; int sortindex; paramlistelm(void) { - left = right = 1; lower = upper = gain = 0; next = NULL; }; @@ -21,13 +37,6 @@ public: delete next; next = NULL; }; - - char *getString(void) { - static char str[64]; - sprintf(str,"%gHz to %gHz, %gdB %c%c", - (double)lower,(double)upper,(double)gain,left?'L':' ',right?'R':' '); - return str; - } }; class paramlist { @@ -52,8 +61,6 @@ public: for(p=&elm,q=src.elm;q != NULL;q = q->next,p = &(*p)->next) { *p = new paramlistelm; - (*p)->left = q->left; - (*p)->right = q->right; (*p)->lower = q->lower; (*p)->upper = q->upper; (*p)->gain = q->gain; diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c index 558cbd5d..ca3b4ec3 100644 --- a/plugins/supereq/supereq.c +++ b/plugins/supereq/supereq.c @@ -30,8 +30,7 @@ typedef struct { ddb_dsp_context_t ctx; float last_srate; int last_nch; - float lbands[18]; - float rbands[18]; + float bands[18]; float preamp; void *paramsroot; int params_changed; @@ -47,18 +46,15 @@ recalc_table (ddb_supereq_ctx_t *eq) { void *params = paramlist_alloc (); deadbeef->mutex_lock (eq->mutex); - float lbands_copy[18]; - float rbands_copy[18]; + float bands_copy[18]; float srate = eq->last_srate; - memcpy (lbands_copy, eq->lbands, sizeof (eq->lbands)); - memcpy (rbands_copy, eq->rbands, sizeof (eq->rbands)); + memcpy (bands_copy, eq->bands, sizeof (eq->bands)); for (int i = 0; i < 18; i++) { - lbands_copy[i] *= eq->preamp; - rbands_copy[i] *= eq->preamp; + bands_copy[i] *= eq->preamp; } deadbeef->mutex_unlock (eq->mutex); - equ_makeTable (&eq->state, lbands_copy, rbands_copy, params, srate); + equ_makeTable (&eq->state, bands_copy, params, srate); deadbeef->mutex_lock (eq->mutex); paramlist_free (eq->paramsroot); @@ -96,19 +92,14 @@ supereq_process (ddb_dsp_context_t *ctx, float *samples, int frames, int maxfram recalc_table (supereq); supereq->params_changed = 0; } - if (supereq->last_srate != fmt->samplerate) { + if (supereq->last_srate != fmt->samplerate || supereq->last_nch != fmt->channels) { deadbeef->mutex_lock (supereq->mutex); supereq->last_srate = fmt->samplerate; supereq->last_nch = fmt->channels; + equ_init (&supereq->state, 14, fmt->channels); recalc_table (supereq); - deadbeef->mutex_unlock (supereq->mutex); equ_clearbuf(&supereq->state); - } - else if (supereq->last_nch != fmt->channels) { - deadbeef->mutex_lock (supereq->mutex); - supereq->last_nch = fmt->channels; deadbeef->mutex_unlock (supereq->mutex); - equ_clearbuf(&supereq->state); } equ_modifySamples_float(&supereq->state, (char *)samples,frames,fmt->channels); return frames; @@ -117,14 +108,14 @@ supereq_process (ddb_dsp_context_t *ctx, float *samples, int frames, int maxfram float supereq_get_band (ddb_dsp_context_t *ctx, int band) { ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx; - return supereq->lbands[band]; + return supereq->bands[band]; } void supereq_set_band (ddb_dsp_context_t *ctx, int band, float value) { ddb_supereq_ctx_t *supereq = (ddb_supereq_ctx_t *)ctx; deadbeef->mutex_lock (supereq->mutex); - supereq->lbands[band] = supereq->rbands[band] = value; + supereq->bands[band] = value; deadbeef->mutex_unlock (supereq->mutex); supereq->params_changed = 1; } @@ -230,15 +221,14 @@ supereq_open (void) { ddb_supereq_ctx_t *supereq = malloc (sizeof (ddb_supereq_ctx_t)); DDB_INIT_DSP_CONTEXT (supereq,ddb_supereq_ctx_t,&plugin); - equ_init (&supereq->state, 14); + equ_init (&supereq->state, 14, 2); supereq->paramsroot = paramlist_alloc (); supereq->last_srate = 44100; supereq->last_nch = 2; supereq->mutex = deadbeef->mutex_create (); supereq->preamp = 1; for (int i = 0; i < 18; i++) { - supereq->lbands[i] = 1; - supereq->rbands[i] = 1; + supereq->bands[i] = 1; } recalc_table (supereq); equ_clearbuf (&supereq->state); -- cgit v1.2.3