| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- /*
- * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
- * http://www.trevorwishart.co.uk
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The CDP System 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 Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <globcon.h>
- #include <filters.h>
- #include <math.h>
- #include <osbind.h>
- static int setup_lphp_filter(dataptr dz);
- static int calc_frqs(dataptr dz);
- static void randomise_frqs(dataptr dz);
- static int allocate_internal_params_lphp(int chans,dataptr dz);
- static void calculate_filter_poles_lphp(double signd,int filter_order,dataptr dz);
- static void initialise_filter_coeffs_lphp(int chans,dataptr dz);
- static int allocate_filter_internalparam_arrays(int fltcnt,dataptr dz);
- static int initialise_filter_params(dataptr dz);
- static int establish_order_of_filter(dataptr dz);
- static int initialise_fltbankv2(dataptr dz);
- /************************** FILTER_PREPROCESS **************************/
- int filter_preprocess(dataptr dz)
- {
- int exit_status;
- int n;
- if(dz->process == FLTBANKV2) {
- if((exit_status = initialise_fltbankv2(dz))<0)
- return exit_status;
- }
- switch(dz->process) {
- case(EQ):
- case(FSTATVAR):
- case(FLTSWEEP):
- case(ALLPASS):
- break;
- case(LPHP):
- if((exit_status = setup_lphp_filter(dz))<0)
- return(exit_status);
- break;
- case(FLTBANKC):
- return calc_frqs(dz);
- case(FLTBANKN):
- if((exit_status = calc_frqs(dz))<0)
- return(exit_status);
- for(n=0;n<dz->iparam[FLT_CNT];n++)
- dz->parray[FLT_AMP][n] = 1.0;
- /* fall thro */
- case(FLTBANKU):
- case(FLTBANKV2):
- case(FLTBANKV):
- case(FLTITER):
- if((exit_status = allocate_filter_internalparam_arrays(dz->iparam[FLT_CNT],dz))<0)
- return(exit_status);
- if((exit_status = initialise_filter_params(dz))<0)
- return(exit_status);
- break;
- default:
- sprintf(errstr,"Unknown case in filter_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /********************************* SETUP_LPHP_FILTER *****************************/
- int setup_lphp_filter(dataptr dz)
- {
- int exit_status;
- int filter_order;
- double signd = 1.0;
- if (dz->param[FLT_PASSFRQ] < dz->param[FLT_STOPFRQ]) /* low pass */
- signd = -1.0;
- filter_order = establish_order_of_filter(dz);
- if((exit_status = allocate_internal_params_lphp(dz->infile->channels,dz))<0)
- return(exit_status);
- calculate_filter_poles_lphp(signd,filter_order,dz);
- initialise_filter_coeffs_lphp(dz->infile->channels,dz);
- return(FINISHED);
- }
- /***************************** CALC_FRQS **********************************/
- int calc_frqs(dataptr dz)
- {
- double interval, one_over_total_steps;
- int n;
- switch(dz->mode) {
- case(FLT_EQUALSPAN):
- one_over_total_steps = 1.0/(double)dz->iparam[FLT_CNT];
- for(n=0;n<dz->iparam[FLT_CNT];n++) {
- interval = dz->param[FLT_HIFRQ]/dz->param[FLT_LOFRQ];
- dz->parray[FLT_FRQ][n] = dz->param[FLT_LOFRQ] * pow(interval,(double)n * one_over_total_steps);
- }
- break;
- case(FLT_EQUALINT):
- dz->parray[FLT_FRQ][0] = dz->param[FLT_LOFRQ];
- for(n=1;n<dz->iparam[FLT_CNT];n++)
- dz->parray[FLT_FRQ][n] = dz->parray[FLT_FRQ][n-1] * dz->param[FLT_INTSIZE];
- break;
- case(FLT_HARMONIC): /* offset = 0.0 */
- case(FLT_LINOFFSET):
- dz->parray[FLT_FRQ][0] = dz->param[FLT_LOFRQ];
- for(n=1;n<dz->iparam[FLT_CNT];n++)
- dz->parray[FLT_FRQ][n] = (dz->param[FLT_LOFRQ] * (double)(n+1))+dz->param[FLT_OFFSET];
- break;
- case(FLT_ALTERNATE):
- dz->parray[FLT_FRQ][0] = dz->param[FLT_LOFRQ];
- for(n=1;n<dz->iparam[FLT_CNT];n++)
- dz->parray[FLT_FRQ][n] = dz->param[FLT_LOFRQ] * (double)((n*2)+1);
- break;
- case(FLT_SUBHARM): /* dz->param[FLT_LOFRQ] already reset at top */
- dz->parray[FLT_FRQ][0] = dz->param[FLT_HIFRQ];
- for(n=1;n<dz->iparam[FLT_CNT];n++)
- dz->parray[FLT_FRQ][n] = dz->param[FLT_HIFRQ]/(double)(n+1);
- break;
- default:
- sprintf(errstr,"Unknown mode in calc_frqs()\n");
- return(PROGRAM_ERROR);
- }
- if(!flteq(dz->param[FLT_RANDFACT],0.0))
- randomise_frqs(dz);
- return(FINISHED);
- }
- /************************ RANDOMISE_FRQS *******************************/
- void randomise_frqs(dataptr dz)
- {
- int n;
- double thisrand, frqratio, interval;
- for(n=1;n<dz->iparam[FLT_CNT]-1;n++) {
- thisrand = drand48(); /* RANGE 0 - 1 */
- if(thisrand >= 0.5) { /* IF IN TOP 1/2 */
- thisrand -= 0.5; /* REDUCE BY 1/2 */
- thisrand *= dz->param[FLT_RANDFACT]; /* SCALE BY randfact */
- frqratio = dz->parray[FLT_FRQ][n+1]/dz->parray[FLT_FRQ][n];
- interval = log(frqratio) * thisrand;
- frqratio = exp(interval);
- dz->parray[FLT_FRQ][n] *= frqratio;
- /* SCATTER FRQ IN 1/2 INTERVAL ABOVE CURRENT VAL */
- } else {
- thisrand *= dz->param[FLT_RANDFACT]; /* SCALE BY randfact */
- frqratio = dz->parray[FLT_FRQ][n]/dz->parray[FLT_FRQ][n-1];
- interval = log(frqratio) * (1.0 - thisrand);
- frqratio = exp(interval);
- dz->parray[FLT_FRQ][n] = dz->parray[FLT_FRQ][n-1] * frqratio;
- /* SCATTER FRQ IN 1/2 INTERVAL BELOW CURRENT VAL */
- }
- }
- }
- /********************************* ALLOCATE_INTERNAL_PARAMS_LPHP *****************************/
- //int allocate_internal_params_lphp(int chans,dataptr dz)
- //{
- // if((dz->parray[FLT_DEN1] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_DEN2] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_CN] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_S1] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_E1] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_S2] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_E2] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL) {
- // sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
- // return(MEMORY_ERROR);
- // }
- // if(chans==2) {
- // if((dz->parray[FLT_S1S] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_E1S] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_S2S] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
- // || (dz->parray[FLT_E2S] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL) {
- // sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter stereo parameters.\n");
- // return(MEMORY_ERROR);
- // }
- // }
- // return(FINISHED);
- //}
- //
- // TW MULTICHAN 2010
- int allocate_internal_params_lphp(int chans,dataptr dz)
- {
- int i;
- if((dz->parray[FLT_DEN1] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_DEN2] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_CN] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_S1_BASE] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_E1_BASE] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_S2_BASE] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_E2_BASE] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
- return(MEMORY_ERROR);
- }
- for(i = 1; i < chans;i++) {
- int index = i*FLT_LPHP_ARRAYS_PER_FILTER;
- if((dz->parray[FLT_S1_BASE + index] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_E1_BASE + index] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_S2_BASE + index] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_E2_BASE + index] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for arrays of %d-channel filter parameters.\n",chans);
- return(MEMORY_ERROR);
- }
- }
- return(FINISHED);
- }
- /********************************* CALCULATE_FILTER_POLES_LPHP *****************************/
- void calculate_filter_poles_lphp(double signd,int filter_order,dataptr dz)
- {
- double ss, xx, aa, tppwr, x1, x2, cc;
- double pii = 4.0 * atan(1.0);
- double tp = tan(dz->param[FLT_PASSFRQ]);
- int k;
- ss = pii / (double)(2 * filter_order);
- for (k = 0; k < dz->iparam[FLT_CNT]; k++ ) {
- //TW : RWD CORRECTION TALLIES WITH MY UPDATES
- xx = (double) ((2.0 * (k+1)) - 1.0);
- aa = -sin(xx * ss);
- tppwr = pow(tp,2.0);
- cc = 1.0 - (2.0 * aa * tp) + tppwr;
- x1 = 2.0 * (tppwr - 1.0)/cc ;
- x2 = (1.0 + (2.0 * aa * tp) + tppwr)/cc ;
- dz->parray[FLT_DEN1][k] = signd * x1;
- dz->parray[FLT_DEN2][k] = -x2 ;
- dz->parray[FLT_CN][k] = pow(tp,2.0)/cc ;
- }
- }
- /********************************* INITIALISE_FILTER_COEFFS_LPHP *****************************/
- //void initialise_filter_coeffs_lphp(int chans,dataptr dz)
- //{
- // int k;
- // for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
- // dz->parray[FLT_S1][k] = 0.0;
- // dz->parray[FLT_S2][k] = 0.0;
- // dz->parray[FLT_E1][k] = 0.0;
- // dz->parray[FLT_E2][k] = 0.0;
- // }
- // if(chans==STEREO) {
- // for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
- // dz->parray[FLT_S1S][k] = 0.0;
- // dz->parray[FLT_S2S][k] = 0.0;
- // dz->parray[FLT_E1S][k] = 0.0;
- // dz->parray[FLT_E2S][k] = 0.0;
- // }
- // }
- //}
- //
- // TW MULTICHAN 2010
- void initialise_filter_coeffs_lphp(int chans,dataptr dz)
- {
- int k;
- int i,index;
- for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
- dz->parray[FLT_S1_BASE][k] = 0.0;
- dz->parray[FLT_S2_BASE][k] = 0.0;
- dz->parray[FLT_E1_BASE][k] = 0.0;
- dz->parray[FLT_E2_BASE][k] = 0.0;
- }
- for(i=1;i < chans; i++){
- index = i * FLT_LPHP_ARRAYS_PER_FILTER;
- for (k = 0 ; k < dz->iparam[FLT_CNT]; k++) {
- dz->parray[FLT_S1_BASE + index][k] = 0.0;
- dz->parray[FLT_S2_BASE + index][k] = 0.0;
- dz->parray[FLT_E1_BASE + index][k] = 0.0;
- dz->parray[FLT_E2_BASE + index][k] = 0.0;
- }
- }
- }
- /**************************** ALLOCATE_FILTER_INTERNALPARAM_ARRAYS *******************************/
- int allocate_filter_internalparam_arrays(int fltcnt,dataptr dz)
- {
- int chans = dz->infile->channels;
- if((dz->parray[FLT_AMPL] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_A] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_B] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_WW] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_COSW] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_SINW] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_Y] = (double *)calloc(fltcnt * chans * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_Z] = (double *)calloc(fltcnt * chans * sizeof(double),sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for arrays of filter parameters.\n");
- return(MEMORY_ERROR);
- }
- if(dz->vflag[FLT_DBLFILT]) {
- if((dz->parray[FLT_D] = (double *)calloc(fltcnt * chans * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_E] = (double *)calloc(fltcnt * chans * sizeof(double),sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for double filtering parameters.\n");
- return(MEMORY_ERROR);
- }
- }
- return(FINISHED);
- }
- /************************ INITIALISE_FILTER_PARAMS ***************************/
- int initialise_filter_params(dataptr dz)
- {
- int n, chno, k;
- int chans = dz->infile->channels;
- for(n=0;n<dz->iparam[FLT_CNT];n++) {
- get_coeffs1(n,dz);
- get_coeffs2(n,dz);
- for(chno=0;chno<chans;chno++) {
- k = (n*chans)+chno;
- if(dz->vflag[FLT_DBLFILT]) {
- dz->parray[FLT_D][k] = 0.0;
- dz->parray[FLT_E][k] = 0.0;
- }
- dz->parray[FLT_Y][k] = 0.0;
- dz->parray[FLT_Z][k] = 0.0;
- }
- }
- return(FINISHED);
- }
- /********************************* ESTABLISH_ORDER_OF_FILTER *****************************/
- int establish_order_of_filter(dataptr dz)
- {
- int filter_order;
- double tc, tp, tt, pii, xx, yy;
- double sr = (double)dz->infile->srate;
- if (dz->param[FLT_PASSFRQ] < dz->param[FLT_STOPFRQ]) /* low pass */
- dz->param[FLT_MUL] = 2.0;
- else {
- dz->param[FLT_MUL] = -2.0;
- dz->param[FLT_PASSFRQ] = dz->nyquist - dz->param[FLT_PASSFRQ];
- dz->param[FLT_STOPFRQ] = dz->nyquist - dz->param[FLT_STOPFRQ];
- }
- pii = 4.0 * atan(1.0);
- dz->param[FLT_PASSFRQ] = pii * dz->param[FLT_PASSFRQ]/sr;
- tp = tan(dz->param[FLT_PASSFRQ]);
- dz->param[FLT_STOPFRQ] = pii * dz->param[FLT_STOPFRQ]/sr;
- tc = tan(dz->param[FLT_STOPFRQ]);
- tt = tc / tp ;
- tt = (tt * tt);
- dz->param[FLT_GAIN] = fabs(dz->param[FLT_GAIN]);
- dz->param[FLT_GAIN] = dz->param[FLT_GAIN] * log(10.0)/10.0 ;
- dz->param[FLT_GAIN] = exp(dz->param[FLT_GAIN]) - 1.0 ;
- xx = log(dz->param[FLT_GAIN])/log(tt) ;
- yy = floor(xx);
- if ((xx - yy) == 0.0 )
- yy = yy - 1.0 ;
- filter_order = ((int)yy) + 1;
- if (filter_order <= 1)
- filter_order = 2;
- dz->iparam[FLT_CNT] = filter_order/2 ;
- filter_order = 2 * dz->iparam[FLT_CNT] ;
- fprintf(stdout,"INFO: Order of filter is %d\n", filter_order);
- fflush(stdout);
- dz->iparam[FLT_CNT] = min(dz->iparam[FLT_CNT],FLT_LBF);
- filter_order = 2 * dz->iparam[FLT_CNT];
- return(filter_order);
- }
- /**************************** INITIALISE_FLTBANKV2 *******************************/
- int initialise_fltbankv2(dataptr dz)
- {
- int n, k/*, z*/;
- memset((char *)dz->parray[FLT_INFRQ],0,dz->iparam[FLT_CNT] * sizeof(double));
- memset((char *)dz->parray[FLT_INAMP],0,dz->iparam[FLT_CNT] * sizeof(double));
- for(n = 1,k = 0; n < dz->iparam[FLT_ENTRYCNT];n+=2,k += dz->iparam[FLT_HARMCNT]) {
- dz->parray[FLT_INFRQ][k] = dz->parray[FLT_FBRK][n]; /* Get frqs of fundamentals into array, leaving space for harmonics */
- dz->parray[FLT_INAMP][k] = dz->parray[FLT_FBRK][n+1]; /* Get amps of fundamentals into array, leaving space for harmonics */
- }
- for(n = 1,k=0; n < dz->iparam[HRM_ENTRYCNT];n+=2,k++) {
- dz->parray[HARM_FRQ_CALC][k] = dz->parray[FLT_HBRK][n];
- dz->parray[HARM_AMP_CALC][k] = dz->parray[FLT_HBRK][n+1];
- }
- for(n=0;n<dz->iparam[FLT_CNT];n+=dz->iparam[FLT_HARMCNT]) {
- // z = 0;
- for(k=0; k < dz->iparam[FLT_HARMCNT];k++) { /* calc vals for partials from basefrq vals */
- dz->parray[FLT_INFRQ][n+k] = dz->parray[FLT_INFRQ][n] * dz->parray[HARM_FRQ_CALC][k];
- dz->parray[FLT_INAMP][n+k] = dz->parray[FLT_INAMP][n] * dz->parray[HARM_AMP_CALC][k];
- }
- }
- return(FINISHED);
- }
|