| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404 |
- /*
- * Copyright (c) 1983-2013 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
- *
- */
- /* floatsams version*/
- /*RWD Apr 2011 corrected usage message. Rebuilt with fixed (?) library for extra array element */
- #include <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <cdpmain.h>
- #include <tkglobals.h>
- #include <pnames.h>
- #include <filters.h>
- #include <processno.h>
- #include <modeno.h>
- #include <globcon.h>
- #include <logic.h>
- #include <filetype.h>
- #include <mixxcon.h>
- #include <arrays.h>
- #include <flags.h>
- #include <speccon.h>
- #include <arrays.h>
- #include <special.h>
- #include <filters1.h>
- #include <formants.h>
- #include <sfsys.h>
- #include <osbind.h>
- #include <string.h>
- #include <math.h>
- #include <srates.h>
- /*RWD April 2004*/
- #include <filtcon.h>
- //#ifdef unix
- #define round(x) lround((x))
- //#endif
- /********************************************************************************************/
- /********************************** FORMERLY IN buffers.c ***********************************/
- /********************************************************************************************/
- static int create_fltiter_buffer(dataptr dz);
- /********************************************************************************************/
- /********************************** FORMERLY IN specialin.c *********************************/
- /********************************************************************************************/
- static int read_filter_data(char *filename,dataptr dz);
- static int read_time_varying_filter_data(char *filename,dataptr dz);
- static int get_data_from_tvary_infile(char *filename,dataptr dz);
- static int getmaxlinelen(int *maxcnt,FILE *fp);
- static int check_filter_data(int wordcnt_in_line,dataptr dz);
- static int check_seq_and_range_of_filter_data(double *fbrk,int wordcnt_in_line,dataptr dz);
- static int check_seq_and_range_of_filter_data2(double *fbrk,double *hbrk,dataptr dz);
- static int getmaxlinelen2(int *maxcnt,FILE *fp);
- static int read_data_from_t_and_p_vary_infile(char *filename,dataptr dz);
- /***************************************************************************************/
- /****************************** FORMERLY IN aplinit.c **********************************/
- /***************************************************************************************/
- /***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/
- int establish_bufptrs_and_extra_buffers(dataptr dz)
- {
- // int is_spec = FALSE;
- dz->extra_bufcnt = -1; /* ENSURE EVERY CASE HAS A PAIR OF ENTRIES !! */
- dz->bptrcnt = 0;
- dz->bufcnt = 0;
- switch(dz->process) {
- case(EQ):
- case(LPHP):
- case(FSTATVAR):
- case(FLTBANKN):
- case(FLTBANKC):
- case(FLTBANKU):
- case(FLTBANKV):
- case(FLTBANKV2):
- case(FLTSWEEP):
- case(ALLPASS): dz->extra_bufcnt = 0; dz->bufcnt = 1; break;
- case(FLTITER): dz->extra_bufcnt = 0; dz->bufcnt = 4; break;
- case(MAKE_VFILT): dz->extra_bufcnt = 0; dz->bufcnt = 0; break;
- default:
- sprintf(errstr,"Unknown program type [%d] in establish_bufptrs_and_extra_buffers()\n",dz->process);
- return(PROGRAM_ERROR);
- }
- if(dz->extra_bufcnt < 0) {
- sprintf(errstr,"bufcnts have not been set: establish_bufptrs_and_extra_buffers()\n");
- return(PROGRAM_ERROR);
- }
- return establish_groucho_bufptrs_and_extra_buffers(dz);
- }
- /***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
- int setup_internal_arrays_and_array_pointers(dataptr dz)
- {
- int n;
- dz->ptr_cnt = -1; /* base constructor...process */
- dz->array_cnt = -1;
- dz->iarray_cnt = -1;
- dz->larray_cnt = -1;
- switch(dz->process) {
- case(FLTBANKC): dz->array_cnt = 2; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(ALLPASS): dz->array_cnt = 2; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- // case(LPHP): dz->array_cnt = 11; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- // TW MULTICHAN 2010
- case(LPHP):
- dz->array_cnt = 0; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;
- break;
- case(EQ): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FSTATVAR): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTSWEEP): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTBANKN): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTBANKU): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTBANKV): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 1; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTBANKV2):dz->array_cnt = 22; dz->iarray_cnt= 0; dz->larray_cnt = 1; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(FLTITER): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- case(MAKE_VFILT): dz->array_cnt= 1; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
- }
- /*** WARNING ***
- ANY APPLICATION DEALING WITH A NUMLIST INPUT: MUST establish AT LEAST 1 double array: i.e. dz->array_cnt = at least 1
- **** WARNING ***/
- if(dz->array_cnt < 0 || dz->iarray_cnt < 0 || dz->larray_cnt < 0 || dz->ptr_cnt < 0 || dz->fptr_cnt < 0) {
- sprintf(errstr,"array_cnt not set in setup_internal_arrays_and_array_pointers()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->array_cnt > 0) {
- if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->array_cnt;n++)
- dz->parray[n] = NULL;
- }
- if(dz->iarray_cnt > 0) {
- if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->iarray_cnt;n++)
- dz->iparray[n] = NULL;
- }
- if(dz->larray_cnt > 0) {
- if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->larray_cnt;n++)
- dz->lparray[n] = NULL;
- }
- if(dz->ptr_cnt > 0) {
- if((dz->ptr = (double **)malloc(dz->ptr_cnt * sizeof(double *)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->ptr_cnt;n++)
- dz->ptr[n] = NULL;
- }
- if(dz->fptr_cnt > 0) {
- if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->fptr_cnt;n++)
- dz->fptr[n] = NULL;
- }
- return(FINISHED);
- }
- /****************************** ASSIGN_PROCESS_LOGIC *********************************/
- int assign_process_logic(dataptr dz)
- {
- switch(dz->process) {
- case(EQ): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(LPHP): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FSTATVAR): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FLTBANKN): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FLTBANKC): setup_process_logic(SNDFILES_ONLY, TO_TEXTFILE, TEXTFILE_OUT, dz); break;
- case(FLTBANKU): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FLTBANKV2):
- case(FLTBANKV): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FLTITER): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(FLTSWEEP): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(ALLPASS): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
- case(MAKE_VFILT): setup_process_logic(WORDLIST_ONLY, TO_TEXTFILE, NO_OUTPUTFILE, dz); break;
- default:
- sprintf(errstr,"Unknown process: assign_process_logic()\n");
- return(PROGRAM_ERROR);
- break;
- }
- if(dz->has_otherfile) {
- switch(dz->input_data_type) {
- case(ALL_FILES):
- case(TWO_SNDFILES):
- case(SNDFILE_AND_ENVFILE):
- case(SNDFILE_AND_BRKFILE):
- case(SNDFILE_AND_UNRANGED_BRKFILE):
- case(SNDFILE_AND_DB_BRKFILE):
- break;
- case(MANY_SNDFILES):
- if(dz->process==INFO_TIMELIST)
- break;
- /* fall thro */
- default:
- sprintf(errstr,"Most processes accepting files with different properties\n"
- "can only take 2 sound infiles.\n");
- return(PROGRAM_ERROR);
- }
- }
- return(FINISHED);
- }
- /***************************** SET_LEGAL_INFILE_STRUCTURE **************************
- *
- * Allows 2nd infile to have different props to first infile.
- */
- void set_legal_infile_structure(dataptr dz)
- {
- switch(dz->process) {
- default:
- dz->has_otherfile = FALSE;
- break;
- }
- }
- /***************************************************************************************/
- /****************************** FORMERLY IN internal.c *********************************/
- /***************************************************************************************/
- /****************************** SET_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
- int set_legal_internalparam_structure(int process,int mode,aplptr ap)
- {
- int exit_status = FINISHED;
- switch(process) {
- case(EQ): exit_status = set_internalparam_data( "000dddiddd",ap); break;
- case(LPHP): exit_status = set_internalparam_data( "000didi",ap); break;
- case(FSTATVAR): exit_status = set_internalparam_data("0000diiiiididd",ap); break;
- case(FLTBANKN): exit_status = set_internalparam_data( "000diiiiid",ap); break;
- case(FLTBANKC): exit_status = set_internalparam_data( "000di",ap); break;
- case(FLTBANKU): exit_status = set_internalparam_data("0000diiiiid",ap); break;
- case(FLTBANKV): exit_status = set_internalparam_data("00iidiiiiididiiid",ap); break;
- case(FLTBANKV2):exit_status = set_internalparam_data("i000iidiiiiididiiidiidd",ap); break;
- case(FLTITER): exit_status = set_internalparam_data( "diiiiiiiiiiid",ap); break;
- case(FLTSWEEP): exit_status = set_internalparam_data( "000diiiiiddddddddd",ap); break;
- case(ALLPASS): exit_status = set_internalparam_data( "000diiiiiid",ap); break;
- case(MAKE_VFILT): break;
- default:
- sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n");
- return(PROGRAM_ERROR);
- }
- return(exit_status);
- }
- /***************************************************************************************/
- /******************************* FORMERLY IN sndlib.c **********************************/
- /***************************************************************************************/
- /*********************** GET_COEFFS1 *************************/
- void get_coeffs1(int n,dataptr dz)
- {
- dz->parray[FLT_WW][n] = 2.0 * PI * dz->parray[FLT_FRQ][n] * dz->param[FLT_INV_SR];
- dz->parray[FLT_COSW][n] = cos(dz->parray[FLT_WW][n]);
- dz->parray[FLT_SINW][n] = sin(dz->parray[FLT_WW][n]);
- }
- /*********************** GET_COEFFS2 ***************************/
- void get_coeffs2(int n,dataptr dz)
- {
- double g, r;
- r = exp( -(dz->parray[FLT_WW][n])/(2.0 * dz->param[FLT_Q]));
- dz->parray[FLT_A][n] = 2.0 * r * dz->parray[FLT_COSW][n];
- dz->parray[FLT_B][n] = -(r) * r;
- g = 1.0 / ((1.0 + dz->parray[FLT_B][n]) * dz->parray[FLT_SINW][n]);
- dz->parray[FLT_AMPL][n] = dz->parray[FLT_AMP][n]/g;
- if(dz->vflag[FLT_DBLFILT])
- dz->parray[FLT_AMPL][n] /= g;
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN specialin.c *********************************/
- /********************************************************************************************/
- /********************** READ_SPECIAL_DATA ************************/
- int read_special_data(char *str,dataptr dz)
- {
- // int exit_status = FINISHED;
- aplptr ap = dz->application;
- switch(ap->special_data) {
- case(FILTERBANK): return read_filter_data(str,dz);
- case(TIMEVARYING_FILTERBANK): return read_time_varying_filter_data(str,dz);
- case(TIMEVARY2_FILTERBANK): return read_data_from_t_and_p_vary_infile(str,dz);
- default:
- sprintf(errstr,"Unknown special_data type: read_special_data()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED); /* NOTREACHED */
- }
- /************************** READ_FILTER_DATA ********************************/
- int read_filter_data(char *filename,dataptr dz)
- {
- int exit_status;
- int n = 0, valcnt;
- char temp[200], *p, *thisword;
- double *frq, *amp;
- int is_frq = TRUE;
- if((dz->fp = fopen(filename,"r"))==NULL) {
- sprintf(errstr,"Cannot open datafile %s\n",filename);
- return(DATA_ERROR);
- }
- while(fgets(temp,200,dz->fp)!=NULL) {
- p = temp;
- if(is_an_empty_line_or_a_comment(p))
- continue;
- n++;
- }
- if(n==0) {
- sprintf(errstr,"No data in file %s\n",filename);
- return(DATA_ERROR);
- }
- dz->iparam[FLT_CNT] = n;
- if((exit_status = allocate_filter_frq_amp_arrays(dz->iparam[FLT_CNT],dz))<0)
- return(exit_status);
- frq = dz->parray[FLT_FRQ];
- amp = dz->parray[FLT_AMP];
- if(fseek(dz->fp,0,0)<0) {
- sprintf(errstr,"fseek() failed in read_filter_data()\n");
- return(SYSTEM_ERROR);
- }
- n = 0;
- while(fgets(temp,200,dz->fp)!=NULL) {
- p = temp;
- if(is_an_empty_line_or_a_comment(temp))
- continue;
- if(n >= dz->iparam[FLT_CNT]) {
- sprintf(errstr,"Accounting problem reading Frq & Amp: read_filter_data()\n");
- return(PROGRAM_ERROR);
- }
- valcnt = 0;
- while(get_word_from_string(&p,&thisword)) {
- if(valcnt>=2) {
- sprintf(errstr,"Too many values on line %d: file %s\n",n+1,filename);
- return(DATA_ERROR);
- }
- if(is_frq) {
- if(sscanf(thisword,"%lf",&(frq[n]))!=1) {
- sprintf(errstr,"Problem reading Frq data: line %d: file %s\n",n+1,filename);
- return(DATA_ERROR);
- }
- if(frq[n]<dz->application->min_special || frq[n]>dz->application->max_special) {
- sprintf(errstr,"frq (%.3lf) on line %d out of range (%.1lf to %.1lf):file %s\n",
- frq[n],n+1,dz->application->min_special,dz->application->max_special,filename);
- return(DATA_ERROR);
- }
- if(dz->mode==FLT_MIDI)
- frq[n] = miditohz(frq[n]);
- } else {
- if((exit_status = get_level(thisword,&(amp[n])))<0)
- return(exit_status);
- if(amp[n]<FLT_MINGAIN || amp[n]>FLT_MAXGAIN) {
- sprintf(errstr,"amp (%lf) out of range (%lf to %.1lf) on line %d: file %s\n",
- amp[n],FLT_MINGAIN,FLT_MAXGAIN,n+1,filename);
- return(DATA_ERROR);
- }
- }
- is_frq = !is_frq;
- valcnt++;
- }
- if(valcnt<2) {
- sprintf(errstr,"Not enough values on line %d: file %s\n",n+1,filename);
- return(DATA_ERROR);
- }
- n++;
- }
- if(fclose(dz->fp)<0) {
- fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
- fflush(stdout);
- }
- return(FINISHED);
- }
- /**************************** ALLOCATE_FILTER_FRQ_AMP_ARRAYS *******************************/
- int allocate_filter_frq_amp_arrays(int fltcnt,dataptr dz)
- {
- // int chans = dz->infile->channels;
- /*RWD 9:2001 must have empty arrays */
- if((dz->parray[FLT_AMP] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
- || (dz->parray[FLT_FRQ] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for filter amp and frq arrays.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /************************** READ_TIME_VARYING_FILTER_DATA ********************************/
- int read_time_varying_filter_data(char *filename,dataptr dz)
- {
- int exit_status;
- // int cnt = 0;
- if((exit_status = get_data_from_tvary_infile(filename,dz))<0)
- return(exit_status);
- if((exit_status = check_filter_data(dz->iparam[FLT_ENTRYCNT],dz))<0)
- return(exit_status);
- return(FINISHED);
- }
- /**************************** GET_DATA_FROM_TVARY_INFILE *******************************/
- int get_data_from_tvary_infile(char *filename,dataptr dz)
- {
- int exit_status;
- char *temp, *p, *thisword;
- int maxlinelen, frqcnt;
- int total_wordcnt = 0;
- int columns_in_this_row, columns_in_row = 0, number_of_rows = 0;
- /* NEW CODE */
- int n, m, k, old_wordcnt;
- double filedur = (double)(dz->insams[0]/dz->infile->channels)/(double)(dz->infile->srate);
- double far_time = filedur + FLT_TAIL + 1.0;
- /* NEW CODE */
- double val;
- if((dz->fp = fopen(filename,"r"))==NULL) {
- sprintf(errstr,"Cannot open datafile %s\n",filename);
- return(DATA_ERROR);
- }
- if((exit_status = getmaxlinelen(&maxlinelen,dz->fp))<0)
- return(exit_status);
- if((fseek(dz->fp,0,0))<0) {
- sprintf(errstr,"Seek failed in get_data_from_tvary_infile()\n");
- return(SYSTEM_ERROR);
- }
- if((temp = (char *)malloc((maxlinelen+2) * sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for temporary line storage.\n");
- return(MEMORY_ERROR);
- }
- while(fgets(temp,maxlinelen,dz->fp)!=NULL) {
- columns_in_this_row = 0;
- if(is_an_empty_line_or_a_comment(temp))
- continue;
- p = temp;
- while(get_word_from_string(&p,&thisword)) {
- if((exit_status = get_level(thisword,&val))<0) { /* reads vals or dB vals */
- free(temp);
- return(exit_status);
- }
- if((total_wordcnt==0 && ((dz->parray[FLT_FBRK] = (double *)malloc(sizeof(double)))==NULL))
- || (dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt+1) * sizeof(double)))==NULL) {
- free(temp);
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
- return(MEMORY_ERROR);
- }
- dz->parray[FLT_FBRK][total_wordcnt] = val;
- columns_in_this_row++;
- total_wordcnt++;
- }
- if(number_of_rows==0) {
- if((columns_in_row = columns_in_this_row)<3) {
- sprintf(errstr,"Insufficient filter data in row 1 of file %s.\n",filename);
- free(temp);
- return(DATA_ERROR);
- } else if (ODD(columns_in_row - 1)) {
- sprintf(errstr,"Frq and Amp data not paired correctly (or no Time) in row 1 of file %s.\n",filename);
- free(temp);
- return(DATA_ERROR);
- }
- } else if(columns_in_this_row!=columns_in_row) {
- free(temp);
- if(columns_in_this_row < columns_in_row)
- sprintf(errstr,"Not enough entries in row %d of file %s\n",number_of_rows+1,filename);
- else
- sprintf(errstr,"Too many entries in row %d of file %s\n",number_of_rows+1,filename);
- return(DATA_ERROR);
- }
- number_of_rows++;
- }
- dz->iparam[FLT_WORDCNT] = total_wordcnt;
- free(temp);
- if(columns_in_row<3) {
- sprintf(errstr,"Insufficient data in each row, to define filters.\n");
- return(DATA_ERROR);
- }
- dz->iparam[FLT_ENTRYCNT] = columns_in_row;
- frqcnt = columns_in_row - 1;
- if(ODD(frqcnt)) {
- sprintf(errstr,"amplitude and freq data not correctly paired in rows.\n");
- return(DATA_ERROR);
- }
- dz->iparam[FLT_CNT] = frqcnt/2;
- dz->iparam[FLT_TIMESLOTS] = number_of_rows;
- if(fclose(dz->fp)<0) {
- fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
- fflush(stdout);
- }
- /* NEW CODE */
- if(dz->parray[FLT_FBRK][0] !=0.0) {
- if(flteq(dz->parray[FLT_FBRK][0],0.0))
- dz->parray[FLT_FBRK][0] = 0.0;
- else {
- dz->iparam[FLT_TIMESLOTS]++;
- old_wordcnt = dz->iparam[FLT_WORDCNT];
- k = old_wordcnt-1;
- dz->iparam[FLT_WORDCNT] += dz->iparam[FLT_ENTRYCNT];
- m = dz->iparam[FLT_WORDCNT] - 1;
- if((dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],dz->iparam[FLT_WORDCNT] * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<old_wordcnt;n++,m--,k--)
- dz->parray[FLT_FBRK][m] = dz->parray[FLT_FBRK][k];
- dz->parray[FLT_FBRK][0] = 0.0;
- total_wordcnt = dz->iparam[FLT_WORDCNT];
- }
- }
- if(dz->parray[FLT_FBRK][total_wordcnt - dz->iparam[FLT_ENTRYCNT]] < far_time) {
- dz->iparam[FLT_TIMESLOTS]++;
- m = dz->iparam[FLT_WORDCNT];
- k = m - dz->iparam[FLT_ENTRYCNT];
- dz->iparam[FLT_WORDCNT] += dz->iparam[FLT_ENTRYCNT];
- if((dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],dz->iparam[FLT_WORDCNT] * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
- return(MEMORY_ERROR);
- }
- dz->parray[FLT_FBRK][m] = far_time;
- m++;
- k++;
- for(n=1;n<dz->iparam[FLT_ENTRYCNT];n++,m++,k++)
- dz->parray[FLT_FBRK][m] = dz->parray[FLT_FBRK][k];
- }
- /* NEW CODE */
- return(FINISHED);
- }
- /**************************** GETMAXLINELEN *******************************/
- int getmaxlinelen(int *maxcnt,FILE *fp)
- {
- int thiscnt = 0;
- char c;
- *maxcnt = 0;
- while((c= (char)fgetc(fp))!=EOF) {
- if(c=='\n' || c == ENDOFSTR) {
- *maxcnt = max(*maxcnt,thiscnt);
- thiscnt = 0;
- } else
- thiscnt++;
- }
- *maxcnt = (int)max(*maxcnt,thiscnt);
- *maxcnt += 4; /* NEWLINE, ENDOFSTR and safety!! */
- return(FINISHED);
- }
- /**************************** CHECK_FILTER_DATA *******************************/
- int check_filter_data(int wordcnt_in_line,dataptr dz)
- {
- int exit_status;
- int n, lastfilt, new_total_wordcnt;
- double endtime;
- int total_wordcnt = dz->iparam[FLT_WORDCNT];
- if(dz->parray[FLT_FBRK][0] < 0.0) {
- sprintf(errstr,"Negative time value (%lf) on line 1.\n",dz->parray[FLT_FBRK][0]);
- return(DATA_ERROR);
- }
- if(flteq(dz->parray[FLT_FBRK][0],0.0))
- dz->parray[FLT_FBRK][0] = 0.0; /* FORCE A FILTER SETTING AT TIME ZERO */
- else {
- if((dz->parray[FLT_FBRK] =
- (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt+wordcnt_in_line) * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
- return(MEMORY_ERROR);
- }
- for(n=total_wordcnt-1; n>=0; n--)
- dz->parray[FLT_FBRK][n + wordcnt_in_line] = dz->parray[FLT_FBRK][n];
- total_wordcnt += wordcnt_in_line;
- dz->parray[FLT_FBRK][0] = 0.0;
- dz->iparam[FLT_TIMESLOTS]++;
- }
- dz->iparam[FLT_WORDCNT] = total_wordcnt;
- if((exit_status = check_seq_and_range_of_filter_data(dz->parray[FLT_FBRK],wordcnt_in_line,dz))<0)
- return(exit_status);
- /* FORCE A FILTER SETTING AT (BEYOND) END OF FILE */
- lastfilt = total_wordcnt - wordcnt_in_line;
- endtime = (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
- if(dz->parray[FLT_FBRK][lastfilt] <= endtime) {
- if((dz->parray[FLT_FBRK] =
- (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt + wordcnt_in_line) * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
- return(MEMORY_ERROR);
- }
- new_total_wordcnt = total_wordcnt + wordcnt_in_line;
- for(n=total_wordcnt;n<new_total_wordcnt;n++)
- dz->parray[FLT_FBRK][n] = dz->parray[FLT_FBRK][n - wordcnt_in_line];
- dz->parray[FLT_FBRK][total_wordcnt] = endtime + 1.0;
- total_wordcnt = new_total_wordcnt;
- dz->iparam[FLT_TIMESLOTS]++;
- }
- if(dz->iparam[FLT_TIMESLOTS]<2) {
- sprintf(errstr,"Error in timeslot logic: check_filter_data()\n");
- return(PROGRAM_ERROR);
- }
- dz->iparam[FLT_WORDCNT] = total_wordcnt;
- return(FINISHED);
- }
- /**************************** CHECK_SEQ_AND_RANGE_OF_FILTER_DATA *******************************/
- int check_seq_and_range_of_filter_data(double *fbrk,int wordcnt_in_line,dataptr dz)
- {
- double lasttime = 0.0;
- int n, m, lineno;
- for(n=1;n<dz->iparam[FLT_WORDCNT];n++) {
- m = n%wordcnt_in_line;
- lineno = (n/wordcnt_in_line)+1; /* original line-no : ignoring comments */
- if(m==0) {
- if(fbrk[n] <= lasttime) {
- sprintf(errstr,"Time is out of sequence on line %d\n",lineno);
- return(DATA_ERROR);
- //NEW AUGUST 2006
- // } else if(fbrk[n] > dz->duration) {
- // fbrk[n] = dz->duration + 1.0;
- // dz->iparam[FLT_WORDCNT] = lineno * wordcnt_in_line;
- }
- lasttime = fbrk[n];
- } else if(ODD(m)) {
- if(fbrk[n]<dz->application->min_special || fbrk[n]>dz->application->max_special) {
- sprintf(errstr,"frq_or_midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
- fbrk[n],dz->application->min_special,dz->application->max_special,lineno);
- return(DATA_ERROR);
- }
- if(dz->mode==FLT_MIDI)
- fbrk[n] = miditohz(fbrk[n]);
- } else
- fbrk[n] = max(fbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
- }
- return(FINISHED);
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN preprocess.c ********************************/
- /********************************************************************************************/
- /****************************** PARAM_PREPROCESS *********************************/
- int param_preprocess(dataptr dz)
- {
- // int exit_status = FINISHED;
- switch(dz->process) {
- case(EQ): case(LPHP): case(FSTATVAR):
- case(FLTBANKN): case(FLTBANKU): case(FLTBANKV):
- case(FLTSWEEP): case(ALLPASS): case(FLTITER):
- case(FLTBANKC): case(FLTBANKV2):
- return filter_preprocess(dz);
- case(MAKE_VFILT): break;
- default:
- sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED); /* NOTREACHED */
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN procgrou.c **********************************/
- /********************************************************************************************/
- /**************************** GROUCHO_PROCESS_FILE ****************************/
- int groucho_process_file(dataptr dz) /* FUNCTIONS FOUND IN PROCESS.C */
- {
- // int exit_status = FINISHED;
- if(dz->process!= FLTBANKC)
- display_virtual_time(0L,dz);
- switch(dz->process) {
- case(LPHP):
- case(EQ): case(FSTATVAR): case(FLTSWEEP): case(ALLPASS):
- case(FLTBANKN): case(FLTBANKC): case(FLTBANKU): case(FLTBANKV):
- case(FLTBANKV2):
- return filter_process(dz);
- case(FLTITER):
- return iterating_filter(dz);
- case(MAKE_VFILT):
- return make_vfilt_data(dz);
- default:
- sprintf(errstr,"Unknown case in process_file()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED); /* NOTREACHED */
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN pconsistency.c ******************************/
- /********************************************************************************************/
- /****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
- int check_param_validity_and_consistency(dataptr dz)
- {
- // int exit_status = FINISHED;
- handle_pitch_zeros(dz);
- switch(dz->process) {
- case(EQ): case(LPHP): case(FSTATVAR): case(FLTBANKN):
- case(FLTBANKU): case(FLTBANKV): case(FLTSWEEP): case(ALLPASS):
- case(FLTITER): case(FLTBANKC): case(FLTBANKV2):
- return filter_pconsistency(dz);
- }
- return(FINISHED);
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN buffers.c ***********************************/
- /********************************************************************************************/
- /**************************** ALLOCATE_LARGE_BUFFERS ******************************/
- int allocate_large_buffers(dataptr dz)
- {
- switch(dz->process) {
- case(EQ): case(LPHP): case(FSTATVAR):
- case(FLTBANKN): case(FLTBANKU): case(FLTBANKV): case(FLTBANKV2):
- case(FLTSWEEP): case(ALLPASS):
- return create_sndbufs(dz);
- case(FLTITER):
- return create_fltiter_buffer(dz);
- case(FLTBANKC):
- case(MAKE_VFILT):
- return(FINISHED);
- default:
- sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED); /* NOTREACHED */
- }
- /*************************** CREATE_FLTITER_BUFFER **************************
- *
- * (1) Create extra spaces for interpolation guard points at end of infile.
- *
- * (2) Allow for any cumulative addition errors in interpolation.
- *
- * (3) Output buffer must be at least as big as the overflow buffer.
- * Output buffer must be big enough for the whole of any possible
- * data overflow (in overflow_size buff) to be copied back into it.
- * This is because the overflow buffer is ZEROED after such a copy
- * and if a 2nd copy of the overflow back into the main buffer
- * were necessary, we would be copying zeroes rather than true data.
- *
- * Output buffer must be bigger than the maximum possible delay.
- * When write_start is beyond end of buffer, we copy the overflow buffer
- * data back into the true buffer and reset the pointers by subtracting
- * buflen (length of output buffer). We must be sure that 'write_start'
- * will then be located WITHIN the true buffer. In the worst possible
- * case the write_start pointer is at the very end of the true buffer,
- * and is then delayed to its maximum possible extent, maxdelay_size (Z),
- * which will be Z samps into the overflow buffer. After the copy-back,
- * the 'write_start' pointer must lie WITHIN the true buffer.
- * Hence the true buflen must be >= maximum delay.
- *
- * true buffer overflow
- * |-----------------------------|------------------------------------------|
- * worst^ ^
- * possible case^ ^
- * ^----->-delayed by maxdelay_size to ->-----^
- * ^<-restored by -buffer_size into truebuf-<-^
- * |<-------- BUFFER_SIZE------->
- *
- */
- int create_fltiter_buffer(dataptr dz)
- {
- int big_buffer_size;
- size_t bigbufsize;
- double k;
- int chans = dz->infile->channels;
- int bufminimum, infilesamps;
- dz->iparam[FLT_INFILESPACE] = dz->insams[0];
- if(dz->param[FLT_PSHIFT]>0.0) {
- dz->iparam[FLT_INFILESPACE] += chans; /* 1 */
- k = pow(2.0,dz->param[FLT_PSHIFT]);
- dz->iparam[FLT_OVFLWSIZE] = ((round((dz->insams[0]/chans) * k) * chans) + chans);
- dz->iparam[FLT_OVFLWSIZE] += FLT_SAFETY; /* 2 */
- } else
- dz->iparam[FLT_OVFLWSIZE] = dz->iparam[FLT_INFILESPACE] + FLT_SAFETY;
- infilesamps = dz->iparam[FLT_INFILESPACE];
- bufminimum = dz->iparam[FLT_OVFLWSIZE];
- bigbufsize = (size_t)Malloc(-1);
- bigbufsize /= sizeof(float);
- bigbufsize -= (dz->iparam[FLT_INFILESPACE] * 2) + dz->iparam[FLT_OVFLWSIZE];
- if(bigbufsize<bufminimum)
- bigbufsize = bufminimum;
- //TW COMMENT: filters don't sfseek: so old buffer protocol can be abandoned
- dz->buflen = (int) bigbufsize;
- big_buffer_size = (dz->iparam[FLT_INFILESPACE] * 2) + dz->buflen + dz->iparam[FLT_OVFLWSIZE];
- if((dz->bigbuf = (float *) malloc((size_t)(big_buffer_size * sizeof(float)))) == NULL) {
- sprintf(errstr, "INSUFFICIENT MEMORY to create sound buffers.\n");
- return(MEMORY_ERROR);
- }
- dz->sampbuf[0] = dz->bigbuf;
- dz->sampbuf[1] = dz->sampbuf[0] + infilesamps;
- dz->sampbuf[FLT_OUTBUF] = dz->sampbuf[1] + infilesamps;
- dz->sampbuf[FLT_OVFLWBUF] = dz->sampbuf[FLT_OUTBUF] + dz->buflen;
- memset((char *)dz->bigbuf,0,(size_t)(big_buffer_size * sizeof(float)));
- return(FINISHED);
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN cmdline.c ***********************************/
- /********************************************************************************************/
- int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
- {
- if (!strcmp(prog_identifier_from_cmdline,"fixed")) dz->process = EQ;
- else if(!strcmp(prog_identifier_from_cmdline,"lohi")) dz->process = LPHP;
- else if(!strcmp(prog_identifier_from_cmdline,"variable")) dz->process = FSTATVAR;
- else if(!strcmp(prog_identifier_from_cmdline,"bank")) dz->process = FLTBANKN;
- else if(!strcmp(prog_identifier_from_cmdline,"bankfrqs")) dz->process = FLTBANKC;
- else if(!strcmp(prog_identifier_from_cmdline,"userbank")) dz->process = FLTBANKU;
- else if(!strcmp(prog_identifier_from_cmdline,"varibank")) dz->process = FLTBANKV;
- else if(!strcmp(prog_identifier_from_cmdline,"varibank2")) dz->process = FLTBANKV2;
- else if(!strcmp(prog_identifier_from_cmdline,"iterated")) dz->process = FLTITER;
- else if(!strcmp(prog_identifier_from_cmdline,"sweeping")) dz->process = FLTSWEEP;
- else if(!strcmp(prog_identifier_from_cmdline,"phasing")) dz->process = ALLPASS;
- else if(!strcmp(prog_identifier_from_cmdline,"vfilters")) dz->process = MAKE_VFILT;
- else {
- sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
- return(USAGE_ONLY);
- }
- return FINISHED;
- }
- /********************************************************************************************/
- /********************************** FORMERLY IN usage.c *************************************/
- /********************************************************************************************/
- /******************************** USAGE1 ********************************/
- int usage1(void)
- {
- sprintf(errstr,
- "USAGE: filter NAME (mode) infile outfile (datafile) parameters\n"
- "\n"
- "where NAME can be any one of\n"
- "\n"
- "fixed lohi variable\n"
- "bank bankfrqs userbank varibank varibank2\n"
- "iterated sweeping phasing vfilters\n"
- "\n"
- "Type 'filter userbank' for more info on filter userbank... ETC.\n");
- return(USAGE_ONLY);
- }
- /******************************** USAGE2 ********************************/
- int usage2(char *str)
- {
- if (!strcmp(str,"fixed")) { /* EQ */
- fprintf(stdout,
- "CUT OR BOOST, ABOVE, BELOW OR AROUND A GIVEN FRQ\n\n"
- "USAGE: filter fixed 1-2 infile outfile boost/cut freq [-ttail] [-sprescale]\n"
- "OR: filter fixed 3 infile outfile bwidth boost/cut freq [-ttail] [-sprescale]\n\n"
- "MODES ARE...\n"
- "1) BOOST OR CUT BELOW GIVEN FRQ\n"
- "2) BOOST OR CUT ABOVE GIVEN FRQ\n"
- "3) BOOST OR CUT A BAND CENTERED ON GIVEN FRQ\n\n"
- "BWIDTH is the filter bandwidth in Hz for Mode 3 only\n"
- "BOOST/CUT is the boost or cut, in dB\n"
- "FREQ is the filter frequency in Hz\n"
- "TAIL decay tail duration\n"
- "PRESCALE scales the INPUT to the filter.\n");
- } else if (!strcmp(str,"lohi")) { /* LOHI */
- fprintf(stdout,
- "FIXED LOW PASS OR HIGH PASS FILTER.\n\n"
- "USAGE:\nfilter lohi mode infile outfile attenuation pass-band stop-band [-ttail] [-sprescale]\n\n"
- "MODES ARE\n"
- "1) Pass-band and stop-band as freq in Hz.\n"
- "2) Pass-band and stop-band as (possibly fractional) midi notes.\n\n"
- "ATTENUATION Gain reduction of filter, in dB. Range(0 to %.0lf)\n"
- " Greater attenuation, sharper filter, but longer to calculate.\n"
- "PASS-BAND last pitch to be passed by the filter.\n"
- "STOP-BAND first pitch to be stopped by the filter.\n"
- " If stop-band is above pass-band, this is a lopass filter.\n"
- " If stop-band is below pass-band, this is a hipass filter.\n"
- "TAIL decay tail duration\n"
- "-s Prescale input: Avoid overflows: Range(%.3lf to %.1lf)\n",
- MIN_DB_ON_16_BIT,FLT_MINEQPRESCALE,FLT_MAXEQPRESCALE);
- } else if (!strcmp(str,"variable")) { /* FSTATVAR */
- fprintf(stdout,
- "LOPASS, HIGH-PASS, BANDPASS, OR NOTCH FILTER WITH VARIABLE FRQ\n\n"
- "USAGE: filter variable mode infile outfile acuity gain frq [-ttail]\n\n"
- "MODES ARE..\n"
- "1) NOTCH (Band Reject)\n\n"
- "2) BAND-PASS\n"
- "3) LOW-PASS\n"
- "4) HIGH-PASS\n"
- "ACUITY acuity of filter: Range(%lf to %.1lf).\n"
- " Smaller vals give tighter filter.\n"
- "GAIN overall gain on output: Range(%lf to %.1lf)\n"
- " Rule of thumb:\n"
- " if acuity = (1/3)to-power-n: gain = (2/3)-to-power-n\n"
- "FRQ frq of filter: Range(%.1lf to srate/2)\n\n"
- "ACUITY and FRQ can vary over time.\n"
- "TAIL decay tail duration\n",MIN_ACUITY,MAX_ACUITY,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ);
- } else if (!strcmp(str,"bank")) { /* FLTBANKN */
- fprintf(stdout,
- "BANK OF FILTERS, WITH TIME-VARIABLE Q\n\n"
- "USAGE: filter bank 1-3 infile outfile Q gain lof hif [-ttail] [-sscat] [-d]\n"
- "OR: filter bank 4-6 infile outfile Q gain lof hif param [-ttail] [-sscat] [-d]\n\n"
- "MODES...\n"
- "1) HARMONIC SERIES over lofrq.\n"
- "2) ALTERNATE HARMONICS over lofrq.\n"
- "3) SUBHARMONIC SERIES below hifrq.\n"
- "4) HARMONIC SERIES WITH LINEAR OFFSET: param = offset in Hz.\n"
- "5) EQUAL INTERVALS BETWEEN lo & hifrq: param = no. of filters.\n"
- "6) EQUAL INTERVALS BETWEEN lo & hifrq: param = interval semitone-size.\n\n"
- "Q Q (tightness) of filters (Range %lf <= Q < %.1lf)\n"
- "GAIN overall gain (Range %lf to %.1lf).\n"
- "LOF lofrq limit of filters (Range: %.0lf to srate/3).\n"
- "HIF hifrq limit of filters (Range: lofrq+ to srate/3).\n"
- "TAIL decay tail duration\n"
- "SCAT Random scatter of filter frqs (Range 0 to 1: Default 0).\n"
- "-d Double filtering.\n\n"
- "Q may vary over time.\n",MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ);
- } else if (!strcmp(str,"bankfrqs")) { /* FLTBANKC */
- fprintf(stdout,
- "GENERATE A LIST OF FREQUENCIES FOR USE AS A FILTERBANK\n"
- "(ADD AMPLITUDES TO THE TEXTFILE FOR USE WITH 'USERBANK')\n\n"
- "USAGE: filter bankfrqs 1-3 anysndfile outtextfile lof hif\n"
- "OR: filter bankfrqs 4-6 anysndfile outtextfile lof hif param\n\n"
- "MODES...\n"
- "1) HARMONIC SERIES over lofrq.\n"
- "2) ALTERNATE HARMONICS over lofrq.\n"
- "3) SUBHARMONIC SERIES below hifrq.\n"
- "4) HARMONIC SERIES WITH LINEAR OFFSET: param = offset in Hz.\n"
- "5) EQUAL INTERVALS BETWEEN lo & hifrq: param = no. of filters.\n"
- "6) EQUAL INTERVALS BETWEEN lo & hifrq: param = interval semitone-size.\n\n"
- "LOF lofrq limit of filters (Range: %.0lf to srate/3).\n"
- "HIF hifrq limit of filters (Range: lofrq+ to srate/3).\n"
- // "SCAT Random scatter of filter frqs (Range 0 to 1: Default 0).\n\n" /* RWD Apr 2011 this param not supported here */
- "NB sampling rate of input soundfile determines frq range\n",FLT_MINFRQ);
- } else if (!strcmp(str,"userbank")) { /* FLTBANKU */
- fprintf(stdout,
- "USER-DEFINED FILTERBANK,WITH TIME-VARIABLE Q\n\n"
- "USAGE: filter userbank mode infile outfile datafile Q gain [-ttail] [-d]\n\n"
- "MODES are\n"
- "1) Filter-pitches as frq in Hz.\n"
- "2) Filter-pitches as MIDI values.\n\n"
- "DATAFILE: has Pitch & Amp of filters (paired, one pair on each line).\n"
- " Ranges: Pitch (%.0lfHz to sr/3) Amp (%lf to %.1lf)\n"
- " Amplitude may also be expressed in decibels.\n"
- " Comment-lines (starting with ';') may be used.\n\n"
- "Q: Q (tightness) of filter: Range(%lf to %.1lf)\n"
- "GAIN overall gain, Range(%lf to %.1lf).\n"
- "TAIL decay tail duration\n"
- "-d double filtering.\n\n"
- "Q may vary over time.",FLT_MINFRQ,FLT_MINGAIN,FLT_MAXGAIN,MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN);
- } else if (!strcmp(str,"varibank")) { /* FLTBANKV */
- fprintf(stdout,
- "USER-DEFINED TIME_VARYING FILTERBANK,WITH TIME-VARIABLE Q\n\n"
- "USAGE:\nfilter varibank mode infile outfile data Q gain [-ttail] [-hhcnt] [-rrolloff] [-d]\n\n"
- "MODES ARE...\n"
- "1) Enter filter-pitches as frq, in Hz.\n"
- "2) Enter filter-pitches as MIDI values.\n\n"
- "DATAFILE: has lines of data for filter bands at successive times.\n"
- " Each line contains the following items\n"
- " Time: Pitch1 Amp1 [Pitch2 Amp2 etc....].\n"
- " Pitch and Amp values must be paired:\n"
- " any number of pairs can be used in a line,\n"
- " BUT each line must have SAME number of pairs on it.\n"
- " (To eliminate a band in any line(s), set its amplitude to 0.0).\n"
- " Time values (in secs) must be in ascending order (and >=0.0)\n"
- " Pitch vals may be EITHER frq, OR MIDI, depending on MODE.\n"
- " Amp values may be numeric, or dB values (e.g. -4.1dB).\n"
- " Comment-lines may be used: start these with ';'.\n\n"
- "Q Q (tightness) of filter : Range(%lf to %.1lf).\n"
- "GAIN: overall gain: Range: (%lf to %.1lf)\n"
- "TAIL decay tail duration\n"
- "HCNT No of harmonics of each pitch to use: Default 1.\n"
- " High harmonics of high pitches may be beyond nyquist.\n"
- " (No-of-pitches times no-of-harmonics determines program speed).\n"
- "ROLLOFF Level drop (in dB) from one harmonic to next. Range(0 to %.1lf)\n"
- "-d double filtering.\n\n"
- "Q may also vary over time.\n",MINQ,MAXQ,FLT_MINGAIN, FLT_MAXGAIN,MIN_DB_ON_16_BIT);
- } else if (!strcmp(str,"varibank2")) { /* FLTBANKV */
- fprintf(stdout,
- "USER-DEFINED TIME_VARYING FILTERBANK,WITH TIME-VARIABLE Q AND PARTIALS\n"
- "USAGE:\nfilter varibank2 mode infil outfil data Q gain [-ttail] [-d]\n"
- "MODES ARE...\n"
- "1) Enter filter-pitches as frq, in Hz.\n"
- "2) Enter filter-pitches as MIDI values.\n\n"
- "DATAFILE: has lines of data for filter bands at successive times.\n"
- " as varibank filter....\n"
- " Followed by a line with a '#' sign at the start.\n"
- " Followed by 2nd set of lines, similar to the pitchdata lines\n"
- " but now the data is a time followed by any number of pairs of\n"
- " partial number (possibly fractional) + amplitude of partial.\n"
- " Times for pitch AND for partials data MUST START AT ZERO.\n"
- "Q Q (tightness) of filter : Range(%lf to %.1lf).\n"
- "GAIN: overall gain: Range: (%lf to %.1lf)\n"
- "TAIL decay tail duration\n"
- "-d double filtering.\n\n"
- "Q may also vary over time.\n",MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN);
- } else if (!strcmp(str,"iterated")) { /* FLTITER */
- fprintf(stdout,
- "ITERATE SOUND, WITH CUMULATIVE FILTERING BY A FILTERBANK.\n\n"
- "USAGE: filter iterated mode infile outfile datafile Q gain delay dur \n"
- " [-sprescale] [-rrand] [-ppshift] [-aashift] [-d] [-i] [-e] [-n]\n\n"
- "MODES ARE...\n"
- "1) Enter filter-pitches as frq, in Hz.\n"
- "2) Enter filter-pitches as MIDI values.\n\n"
- "DATAFILE has Pitch & Amp of filters (paired, one pair on each line).\n"
- " Pitch, as Hz or MIDI, Range(%.0lfHz to srate/3)\n"
- " Amp, Range(%lf to %.1lf), can also be entered as dB vals\n\n"
- "Q Q (tightness) of filter: Range(%lf to %.1lf)\n"
- "GAIN overrall gain in filtering process (%lf < gain < %.1lf)\n"
- "DELAY (average) delay between iterations (secs).\n"
- " Range(>0 to %.0lf)\n"
- "DUR (min) duration of output file (>infile duration).\n"
- "PRESCALE gain on the INPUT to the filtering process.\n"
- " Range (0.0 - 1.0) Default 1.0\n"
- " If set to 0.0, Program automatically divides input level by\n"
- " the max no. of sound overlays occuring in the iteration process.\n"
- "RAND delaytime-randomisation: Range 0 (none) to 1 (max).\n"
- "PSHIFT max pitchshift of any segment in (fractions of) semitones (>=0).\n"
- "ASHIFT max amplitude reduction of any segment: Range (0.0 - 1.0)\n"
- "-d double filtering.\n"
- "-i Turn off Interpolation during pitch shift: (fast but dirty).\n"
- "-e Exponential decay added: each seg gets quieter before next enters.\n"
- "-n turns OFF normalisation: segs may grow or fall in level quickly.\n",
- FLT_MINFRQ,FLT_MINGAIN,FLT_MAXGAIN,MINQ, MAXQ, FLT_MINGAIN,FLT_MAXGAIN,FLT_MAXDELAY);
- } else if (!strcmp(str,"sweeping")) { /* FLTSWEEP */
- fprintf(stdout,
- "FILTER WHOSE FOCUS-FREQUENCY SWEEPS OVER A RANGE OF FREQUENCIES\n\n"
- "USAGE:\n"
- "filter sweeping mode infile outfile acuity gain lofrq hifrq sweepfrq [-ttail] [-pphase]\n\n"
- "MODES ARE...\n"
- "1) NOTCH (Band-reject). 3) LOW-PASS\n"
- "2) BAND-PASS 4) HIGH-PASS \n\n"
- "ACUITY Acuity of filter: Range(%lf to %.1lf)\n"
- " Smaller vals give tighter filter.\n"
- "GAIN overall gain on output: Range(%lf to %.1lf)\n"
- " Rule of thumb:\n"
- " if acuity = (1/3)to-power-n: gain = (2/3)-to-power-n\n"
- "LOFRQ lowest frq to sweep to: Range(%.1lf to srate/2)\n"
- "HIFRQ highest frq to sweep to: Range(%.1lf to srate/2)\n"
- "SWEEPFRQ frq of the sweep itself: Range(0.0 to %.1lf)\n"
- " e.g. to sweep once over range, set sweepfrq to infiledur/2 (default)\n"
- " and set phase to 0 (upsweep) or .5(downsweep)\n"
- "TAIL decay tail duration\n"
- "PHASE start of sweep: Range(0-1)\n"
- " vals are: 0 = (lofrq) rising to .5 = (hifrq) falling to 1 = (lofrq).\n"
- " Default value is .25 (midfrq,rising)\n\n"
- "ACUITY, LOFRQ, HIFRQ and SWEEPFRQ may all vary over time.\n"
- "This filter is most effective in BAND-PASS or LOW-PASS mode, at low ACUITY.\n",
- MIN_ACUITY,MAX_ACUITY,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ,FLT_MINFRQ,FLT_MAXSWEEP);
- } else if (!strcmp(str,"phasing")) { /* ALLPASS */
- fprintf(stdout,
- "PHASESHIFT SOUND, OR PRODUCE 'PHASING' EFFECT\n\n"
- "USAGE: filter phasing mode infile outfile gain delay [-ttail] [-sprescale] [-l]\n\n"
- "MODES ARE..\n"
- "1) ALLPASS FILTER (PHASE-SHIFTED)\n"
- "2) PHASING EFFECT\n\n"
- "GAIN Range (-1.0 to 1.0)\n"
- " In MODE 2, phasing effect increases as gain increases from -1\n"
- " BUT a gain of 1.0 will produce complete phase cancellation\n"
- " and the output signal will be zero.\n"
- "DELAY >0.0 MS\n"
- "TAIL decay tail duration\n"
- "PRESCALE gain on the INPUT to the filtering process.\n"
- " Range (0.0 - 1.0) Default 1.0\n"
- "-l linear interpolation of changing delay vals (default: logarithmic)\n\n"
- "DELAY may vary over time.\n");
- } else if (!strcmp(str,"vfilters")) { /* MAKE VFILTER FIXED-PITCH DATA FILES */
- fprintf(stdout,
- "MAKE FIXED-PITCH DATA-FILES FOR VARIBANK FILTER\n\n"
- "USAGE: filter vfilters inpitchfile outfile\n\n"
- "INPITCHFILE Textfile, contains a list of MIDI or FRQ pitch values\n"
- " with one or more values on each line.\n"
- "Each line is converted to a data file for a fixed pitch(es) filter,\n"
- "of the 'varibank' type.\n"
- "Producing outfile0.txt, outfile1.txt etc.\n");
- } else
- fprintf(stdout,"Unknown option '%s'\n",str);
- return(USAGE_ONLY);
- }
- /******************************** USAGE3 ********************************/
- int usage3(char *str1,char *str2)
- {
- sprintf(errstr,"Insufficient parameters on command line.\n");
- return(USAGE_ONLY);
- }
- /******************************** INNER_LOOP (redundant) ********************************/
- int inner_loop
- (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
- {
- return(FINISHED);
- }
- /**************************** CHECK_SEQ_AND_RANGE_OF_FILTER_DATA2 *******************************/
- int check_seq_and_range_of_filter_data2(double *fbrk,double *hbrk,dataptr dz)
- {
- double lasttime = -1.0;
- double maxpartial = dz->infile->srate/(2.0 * FLT_MINFRQ);
- double minpartial = 1.0;
- int n, m, lineno = 0;
- double frqmax = dz->infile->srate/2.0;
- double midimax = unchecked_hztomidi(frqmax);
- double midimin = unchecked_hztomidi(FLT_MINFRQ);
- int wordcnt_in_line = dz->iparam[FLT_ENTRYCNT];
- for(n=0;n<dz->iparam[FLT_WORDCNT];n++) {
- m = n%wordcnt_in_line;
- if(m==0) {
- lineno++; /* original line-no : ignoring comments */
- if(fbrk[n] <= lasttime) {
- sprintf(errstr,"Time is out of sequence in pitch data line %d\n",lineno);
- return(DATA_ERROR);
- }
- lasttime = fbrk[n];
- } else if(ODD(m)) {
- if(dz->mode==FLT_MIDI) {
- if(fbrk[n] < midimin || fbrk[n] > midimax) {
- sprintf(errstr,"midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
- fbrk[n],midimin,midimax,lineno);
- return(DATA_ERROR);
- }
- fbrk[n] = miditohz(fbrk[n]);
- } else {
- if(fbrk[n] < FLT_MINFRQ || fbrk[n] > frqmax) {
- sprintf(errstr,"frq_or_midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
- fbrk[n],FLT_MINFRQ,frqmax,lineno);
- return(DATA_ERROR);
- }
- }
- } else
- fbrk[n] = max(fbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
- }
- wordcnt_in_line = dz->iparam[HRM_ENTRYCNT];
- lasttime = -1.0;
- lineno = 0;
- for(n=0;n<dz->iparam[HRM_WORDCNT];n++) {
- m = n%wordcnt_in_line;
- if(m==0) {
- lineno++;
- if(hbrk[n] <= lasttime) {
- sprintf(errstr,"Time is out of sequence in partials data line %d\n",lineno);
- return(DATA_ERROR);
- }
- lasttime = hbrk[n];
- } else if(ODD(m)) {
- if(hbrk[n]<minpartial|| hbrk[n]>maxpartial) {
- sprintf(errstr,"partial value [%.3lf] out of range (%lf - %.1f) on line %d\n",hbrk[n],minpartial,maxpartial,lineno);
- return(DATA_ERROR);
- }
- } else
- hbrk[n] = max(hbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
- }
- return(FINISHED);
- }
- /**************************** READ_DATA_FROM_T_AND_P_VARY_INFILE *******************************/
- int read_data_from_t_and_p_vary_infile(char *filename,dataptr dz)
- {
- int exit_status;
- char *temp, *p, *thisword;
- int maxlinelen, frqcnt = 0, hcnt;
- int total_wordcnt = 0, number_of_rows = 0, total_number_of_rows = 0,columns_in_this_row,columns_in_row = 0;
- int harmdata = 0, ishash = 0, thisarray;
- double val;
- if((dz->fp = fopen(filename,"r"))==NULL) {
- sprintf(errstr,"Cannot open datafile %s\n",filename);
- return(DATA_ERROR);
- }
- if((exit_status = getmaxlinelen2(&maxlinelen,dz->fp))<0)
- return(exit_status);
- if((fseek(dz->fp,0,0))<0) {
- sprintf(errstr,"Seek failed in get_data_from_t_and_p_vary_infile()\n");
- return(SYSTEM_ERROR);
- }
- if((temp = (char *)malloc((maxlinelen+2) * sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for temporary line storage.\n");
- return(MEMORY_ERROR);
- }
- while(fgets(temp,maxlinelen,dz->fp)!=NULL) {
- columns_in_this_row = 0;
- if(is_an_empty_line_or_a_comment(temp))
- continue;
- p = temp;
- while(get_word_from_string(&p,&thisword)) {
- if(!strncmp(thisword,"#",1)) {
- if(harmdata) {
- sprintf(errstr,"HASH SIGN AT WRONG PLACE IN DATA in LINE %d.\n",total_number_of_rows+1);
- return(DATA_ERROR);
- }
- dz->iparam[FLT_WORDCNT] = total_wordcnt;
- dz->iparam[FLT_ENTRYCNT] = columns_in_row;
- total_wordcnt = 0;
- number_of_rows = 0;
- frqcnt = columns_in_row - 1;
- harmdata = 1;
- ishash = 1;
- break;
- }
- if((exit_status = get_level(thisword,&val))<0) { /* reads vals */
- free(temp);
- return(exit_status);
- }
- if(harmdata)
- thisarray = FLT_HBRK;
- else
- thisarray = FLT_FBRK;
- if(total_wordcnt==0) {
- if ((dz->parray[thisarray] = (double *)malloc(sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktables.\n");
- return(MEMORY_ERROR);
- }
- dz->parray[thisarray][total_wordcnt] = val;
- } else {
- if ((dz->parray[thisarray] = (double *)realloc(dz->parray[thisarray],(total_wordcnt+1) * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktables.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->parray[thisarray][total_wordcnt] = val;
- columns_in_this_row++;
- total_wordcnt++;
- }
- if(ishash) {
- ishash = 0;
- continue;
- }
- if(number_of_rows==0) {
- if((columns_in_row = columns_in_this_row)<3) {
- sprintf(errstr,"Insufficient data in row 1 of file %s.\n",filename);
- free(temp);
- return(DATA_ERROR);
- } else if (ODD(columns_in_row - 1)) {
- sprintf(errstr,"Value and Amp data not paired correctly (or no Time) in row %d of file %s.\n",total_number_of_rows+1,filename);
- free(temp);
- return(DATA_ERROR);
- }
- } else if(columns_in_this_row!=columns_in_row) {
- free(temp);
- if(columns_in_this_row < columns_in_row)
- sprintf(errstr,"Not enough entries in row %d of file %s\n",total_number_of_rows+1,filename);
- else
- sprintf(errstr,"Too many entries in row %d of file %s\n",total_number_of_rows+1,filename);
- return(DATA_ERROR);
- }
- number_of_rows++;
- total_number_of_rows++;
- }
- dz->iparam[HRM_WORDCNT] = total_wordcnt;
- free(temp);
- if(columns_in_row<3) {
- sprintf(errstr,"Insufficient data in each row, to define filters.\n");
- return(DATA_ERROR);
- }
- dz->iparam[HRM_ENTRYCNT] = columns_in_row;
- hcnt = columns_in_row - 1;
- dz->iparam[FLT_CNT] = frqcnt/2;
- dz->iparam[FLT_HARMCNT] = hcnt/2;
- dz->iparam[FLT_CNT] *= dz->iparam[FLT_HARMCNT];
- if(fclose(dz->fp)<0) {
- fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
- fflush(stdout);
- }
- if(dz->parray[FLT_FBRK][0] !=0.0) {
- sprintf(errstr,"FIRST TIME VALUE FOR PITCHES MUST BE ZERO\n");
- return(DATA_ERROR);
- }
- if(dz->parray[FLT_HBRK][0] !=0.0) {
- sprintf(errstr,"FIRST TIME VALUE FOR HARMONICS MUST BE ZERO\n");
- return(DATA_ERROR);
- }
- return check_seq_and_range_of_filter_data2(dz->parray[FLT_FBRK],dz->parray[FLT_HBRK],dz);
- }
- /**************************** GETMAXLINELEN2 *******************************/
- int getmaxlinelen2(int *maxcnt,FILE *fp)
- {
- int thiscnt = 0;
- int gothash = 0;
- int gotdata1 = 0, gotdata2 = 0;
- char c;
- *maxcnt = 0;
- while((c= (char)fgetc(fp))!=EOF) {
- if(!gothash) {
- if(c=='#') {
- if(!gotdata1) {
- sprintf(errstr,"FAILED TO GET FIRST SET OF DATA (PITCH INFORMATION) BEFORE HASH SIGN\n");
- return(DATA_ERROR);
- }
- while((c= (char)fgetc(fp))!=EOF) {
- if(c == '\n' || c == ENDOFSTR) {
- gothash = 1;
- thiscnt = 0;
- break;
- }
- }
- if(!gothash)
- break;
- } else {
- if(c=='\n' || c == ENDOFSTR) {
- *maxcnt = max(*maxcnt,thiscnt);
- thiscnt = 0;
- gotdata1 = 1;
- } else {
- thiscnt++;
- }
- }
- } else {
- if(c=='\n' || c == ENDOFSTR) {
- *maxcnt = max(*maxcnt,thiscnt);
- thiscnt = 0;
- gotdata2 = 1;
- } else {
- thiscnt++;
- }
- }
- }
- if(!gotdata2) {
- sprintf(errstr,"FAILED TO GET SECOND SET OF DATA (PARTIALS INFORMATION) AFTER HASH SIGN\n");
- return(DATA_ERROR);
- }
- *maxcnt = (int)max(*maxcnt,thiscnt);
- *maxcnt += 4; /* NEWLINE, ENDOFSTR and safety!! */
- return(FINISHED);
- }
|