ap_filter.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* floatsams version*/
  22. /*RWD Apr 2011 corrected usage message. Rebuilt with fixed (?) library for extra array element */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <structures.h>
  26. #include <cdpmain.h>
  27. #include <tkglobals.h>
  28. #include <pnames.h>
  29. #include <filters.h>
  30. #include <processno.h>
  31. #include <modeno.h>
  32. #include <globcon.h>
  33. #include <logic.h>
  34. #include <filetype.h>
  35. #include <mixxcon.h>
  36. #include <arrays.h>
  37. #include <flags.h>
  38. #include <speccon.h>
  39. #include <arrays.h>
  40. #include <special.h>
  41. #include <filters1.h>
  42. #include <formants.h>
  43. #include <sfsys.h>
  44. #include <osbind.h>
  45. #include <string.h>
  46. #include <math.h>
  47. #include <srates.h>
  48. /*RWD April 2004*/
  49. #include <filtcon.h>
  50. //#ifdef unix
  51. #define round(x) lround((x))
  52. //#endif
  53. /********************************************************************************************/
  54. /********************************** FORMERLY IN buffers.c ***********************************/
  55. /********************************************************************************************/
  56. static int create_fltiter_buffer(dataptr dz);
  57. /********************************************************************************************/
  58. /********************************** FORMERLY IN specialin.c *********************************/
  59. /********************************************************************************************/
  60. static int read_filter_data(char *filename,dataptr dz);
  61. static int read_time_varying_filter_data(char *filename,dataptr dz);
  62. static int get_data_from_tvary_infile(char *filename,dataptr dz);
  63. static int getmaxlinelen(int *maxcnt,FILE *fp);
  64. static int check_filter_data(int wordcnt_in_line,dataptr dz);
  65. static int check_seq_and_range_of_filter_data(double *fbrk,int wordcnt_in_line,dataptr dz);
  66. static int check_seq_and_range_of_filter_data2(double *fbrk,double *hbrk,dataptr dz);
  67. static int getmaxlinelen2(int *maxcnt,FILE *fp);
  68. static int read_data_from_t_and_p_vary_infile(char *filename,dataptr dz);
  69. /***************************************************************************************/
  70. /****************************** FORMERLY IN aplinit.c **********************************/
  71. /***************************************************************************************/
  72. /***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/
  73. int establish_bufptrs_and_extra_buffers(dataptr dz)
  74. {
  75. // int is_spec = FALSE;
  76. dz->extra_bufcnt = -1; /* ENSURE EVERY CASE HAS A PAIR OF ENTRIES !! */
  77. dz->bptrcnt = 0;
  78. dz->bufcnt = 0;
  79. switch(dz->process) {
  80. case(EQ):
  81. case(LPHP):
  82. case(FSTATVAR):
  83. case(FLTBANKN):
  84. case(FLTBANKC):
  85. case(FLTBANKU):
  86. case(FLTBANKV):
  87. case(FLTBANKV2):
  88. case(FLTSWEEP):
  89. case(ALLPASS): dz->extra_bufcnt = 0; dz->bufcnt = 1; break;
  90. case(FLTITER): dz->extra_bufcnt = 0; dz->bufcnt = 4; break;
  91. case(MAKE_VFILT): dz->extra_bufcnt = 0; dz->bufcnt = 0; break;
  92. default:
  93. sprintf(errstr,"Unknown program type [%d] in establish_bufptrs_and_extra_buffers()\n",dz->process);
  94. return(PROGRAM_ERROR);
  95. }
  96. if(dz->extra_bufcnt < 0) {
  97. sprintf(errstr,"bufcnts have not been set: establish_bufptrs_and_extra_buffers()\n");
  98. return(PROGRAM_ERROR);
  99. }
  100. return establish_groucho_bufptrs_and_extra_buffers(dz);
  101. }
  102. /***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
  103. int setup_internal_arrays_and_array_pointers(dataptr dz)
  104. {
  105. int n;
  106. dz->ptr_cnt = -1; /* base constructor...process */
  107. dz->array_cnt = -1;
  108. dz->iarray_cnt = -1;
  109. dz->larray_cnt = -1;
  110. switch(dz->process) {
  111. case(FLTBANKC): dz->array_cnt = 2; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  112. case(ALLPASS): dz->array_cnt = 2; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  113. // case(LPHP): dz->array_cnt = 11; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  114. // TW MULTICHAN 2010
  115. case(LPHP):
  116. dz->array_cnt = 0; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;
  117. break;
  118. case(EQ): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  119. case(FSTATVAR): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  120. case(FLTSWEEP): dz->array_cnt = 4; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  121. case(FLTBANKN): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  122. case(FLTBANKU): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  123. case(FLTBANKV): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 1; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  124. case(FLTBANKV2):dz->array_cnt = 22; dz->iarray_cnt= 0; dz->larray_cnt = 1; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  125. case(FLTITER): dz->array_cnt = 19; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  126. case(MAKE_VFILT): dz->array_cnt= 1; dz->iarray_cnt= 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  127. }
  128. /*** WARNING ***
  129. ANY APPLICATION DEALING WITH A NUMLIST INPUT: MUST establish AT LEAST 1 double array: i.e. dz->array_cnt = at least 1
  130. **** WARNING ***/
  131. if(dz->array_cnt < 0 || dz->iarray_cnt < 0 || dz->larray_cnt < 0 || dz->ptr_cnt < 0 || dz->fptr_cnt < 0) {
  132. sprintf(errstr,"array_cnt not set in setup_internal_arrays_and_array_pointers()\n");
  133. return(PROGRAM_ERROR);
  134. }
  135. if(dz->array_cnt > 0) {
  136. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  137. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  138. return(MEMORY_ERROR);
  139. }
  140. for(n=0;n<dz->array_cnt;n++)
  141. dz->parray[n] = NULL;
  142. }
  143. if(dz->iarray_cnt > 0) {
  144. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  145. sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
  146. return(MEMORY_ERROR);
  147. }
  148. for(n=0;n<dz->iarray_cnt;n++)
  149. dz->iparray[n] = NULL;
  150. }
  151. if(dz->larray_cnt > 0) {
  152. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  153. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  154. return(MEMORY_ERROR);
  155. }
  156. for(n=0;n<dz->larray_cnt;n++)
  157. dz->lparray[n] = NULL;
  158. }
  159. if(dz->ptr_cnt > 0) {
  160. if((dz->ptr = (double **)malloc(dz->ptr_cnt * sizeof(double *)))==NULL) {
  161. sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
  162. return(MEMORY_ERROR);
  163. }
  164. for(n=0;n<dz->ptr_cnt;n++)
  165. dz->ptr[n] = NULL;
  166. }
  167. if(dz->fptr_cnt > 0) {
  168. if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
  169. sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
  170. return(MEMORY_ERROR);
  171. }
  172. for(n=0;n<dz->fptr_cnt;n++)
  173. dz->fptr[n] = NULL;
  174. }
  175. return(FINISHED);
  176. }
  177. /****************************** ASSIGN_PROCESS_LOGIC *********************************/
  178. int assign_process_logic(dataptr dz)
  179. {
  180. switch(dz->process) {
  181. case(EQ): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  182. case(LPHP): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  183. case(FSTATVAR): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  184. case(FLTBANKN): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  185. case(FLTBANKC): setup_process_logic(SNDFILES_ONLY, TO_TEXTFILE, TEXTFILE_OUT, dz); break;
  186. case(FLTBANKU): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  187. case(FLTBANKV2):
  188. case(FLTBANKV): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  189. case(FLTITER): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  190. case(FLTSWEEP): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  191. case(ALLPASS): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT, dz); break;
  192. case(MAKE_VFILT): setup_process_logic(WORDLIST_ONLY, TO_TEXTFILE, NO_OUTPUTFILE, dz); break;
  193. default:
  194. sprintf(errstr,"Unknown process: assign_process_logic()\n");
  195. return(PROGRAM_ERROR);
  196. break;
  197. }
  198. if(dz->has_otherfile) {
  199. switch(dz->input_data_type) {
  200. case(ALL_FILES):
  201. case(TWO_SNDFILES):
  202. case(SNDFILE_AND_ENVFILE):
  203. case(SNDFILE_AND_BRKFILE):
  204. case(SNDFILE_AND_UNRANGED_BRKFILE):
  205. case(SNDFILE_AND_DB_BRKFILE):
  206. break;
  207. case(MANY_SNDFILES):
  208. if(dz->process==INFO_TIMELIST)
  209. break;
  210. /* fall thro */
  211. default:
  212. sprintf(errstr,"Most processes accepting files with different properties\n"
  213. "can only take 2 sound infiles.\n");
  214. return(PROGRAM_ERROR);
  215. }
  216. }
  217. return(FINISHED);
  218. }
  219. /***************************** SET_LEGAL_INFILE_STRUCTURE **************************
  220. *
  221. * Allows 2nd infile to have different props to first infile.
  222. */
  223. void set_legal_infile_structure(dataptr dz)
  224. {
  225. switch(dz->process) {
  226. default:
  227. dz->has_otherfile = FALSE;
  228. break;
  229. }
  230. }
  231. /***************************************************************************************/
  232. /****************************** FORMERLY IN internal.c *********************************/
  233. /***************************************************************************************/
  234. /****************************** SET_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
  235. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  236. {
  237. int exit_status = FINISHED;
  238. switch(process) {
  239. case(EQ): exit_status = set_internalparam_data( "000dddiddd",ap); break;
  240. case(LPHP): exit_status = set_internalparam_data( "000didi",ap); break;
  241. case(FSTATVAR): exit_status = set_internalparam_data("0000diiiiididd",ap); break;
  242. case(FLTBANKN): exit_status = set_internalparam_data( "000diiiiid",ap); break;
  243. case(FLTBANKC): exit_status = set_internalparam_data( "000di",ap); break;
  244. case(FLTBANKU): exit_status = set_internalparam_data("0000diiiiid",ap); break;
  245. case(FLTBANKV): exit_status = set_internalparam_data("00iidiiiiididiiid",ap); break;
  246. case(FLTBANKV2):exit_status = set_internalparam_data("i000iidiiiiididiiidiidd",ap); break;
  247. case(FLTITER): exit_status = set_internalparam_data( "diiiiiiiiiiid",ap); break;
  248. case(FLTSWEEP): exit_status = set_internalparam_data( "000diiiiiddddddddd",ap); break;
  249. case(ALLPASS): exit_status = set_internalparam_data( "000diiiiiid",ap); break;
  250. case(MAKE_VFILT): break;
  251. default:
  252. sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n");
  253. return(PROGRAM_ERROR);
  254. }
  255. return(exit_status);
  256. }
  257. /***************************************************************************************/
  258. /******************************* FORMERLY IN sndlib.c **********************************/
  259. /***************************************************************************************/
  260. /*********************** GET_COEFFS1 *************************/
  261. void get_coeffs1(int n,dataptr dz)
  262. {
  263. dz->parray[FLT_WW][n] = 2.0 * PI * dz->parray[FLT_FRQ][n] * dz->param[FLT_INV_SR];
  264. dz->parray[FLT_COSW][n] = cos(dz->parray[FLT_WW][n]);
  265. dz->parray[FLT_SINW][n] = sin(dz->parray[FLT_WW][n]);
  266. }
  267. /*********************** GET_COEFFS2 ***************************/
  268. void get_coeffs2(int n,dataptr dz)
  269. {
  270. double g, r;
  271. r = exp( -(dz->parray[FLT_WW][n])/(2.0 * dz->param[FLT_Q]));
  272. dz->parray[FLT_A][n] = 2.0 * r * dz->parray[FLT_COSW][n];
  273. dz->parray[FLT_B][n] = -(r) * r;
  274. g = 1.0 / ((1.0 + dz->parray[FLT_B][n]) * dz->parray[FLT_SINW][n]);
  275. dz->parray[FLT_AMPL][n] = dz->parray[FLT_AMP][n]/g;
  276. if(dz->vflag[FLT_DBLFILT])
  277. dz->parray[FLT_AMPL][n] /= g;
  278. }
  279. /********************************************************************************************/
  280. /********************************** FORMERLY IN specialin.c *********************************/
  281. /********************************************************************************************/
  282. /********************** READ_SPECIAL_DATA ************************/
  283. int read_special_data(char *str,dataptr dz)
  284. {
  285. // int exit_status = FINISHED;
  286. aplptr ap = dz->application;
  287. switch(ap->special_data) {
  288. case(FILTERBANK): return read_filter_data(str,dz);
  289. case(TIMEVARYING_FILTERBANK): return read_time_varying_filter_data(str,dz);
  290. case(TIMEVARY2_FILTERBANK): return read_data_from_t_and_p_vary_infile(str,dz);
  291. default:
  292. sprintf(errstr,"Unknown special_data type: read_special_data()\n");
  293. return(PROGRAM_ERROR);
  294. }
  295. return(FINISHED); /* NOTREACHED */
  296. }
  297. /************************** READ_FILTER_DATA ********************************/
  298. int read_filter_data(char *filename,dataptr dz)
  299. {
  300. int exit_status;
  301. int n = 0, valcnt;
  302. char temp[200], *p, *thisword;
  303. double *frq, *amp;
  304. int is_frq = TRUE;
  305. if((dz->fp = fopen(filename,"r"))==NULL) {
  306. sprintf(errstr,"Cannot open datafile %s\n",filename);
  307. return(DATA_ERROR);
  308. }
  309. while(fgets(temp,200,dz->fp)!=NULL) {
  310. p = temp;
  311. if(is_an_empty_line_or_a_comment(p))
  312. continue;
  313. n++;
  314. }
  315. if(n==0) {
  316. sprintf(errstr,"No data in file %s\n",filename);
  317. return(DATA_ERROR);
  318. }
  319. dz->iparam[FLT_CNT] = n;
  320. if((exit_status = allocate_filter_frq_amp_arrays(dz->iparam[FLT_CNT],dz))<0)
  321. return(exit_status);
  322. frq = dz->parray[FLT_FRQ];
  323. amp = dz->parray[FLT_AMP];
  324. if(fseek(dz->fp,0,0)<0) {
  325. sprintf(errstr,"fseek() failed in read_filter_data()\n");
  326. return(SYSTEM_ERROR);
  327. }
  328. n = 0;
  329. while(fgets(temp,200,dz->fp)!=NULL) {
  330. p = temp;
  331. if(is_an_empty_line_or_a_comment(temp))
  332. continue;
  333. if(n >= dz->iparam[FLT_CNT]) {
  334. sprintf(errstr,"Accounting problem reading Frq & Amp: read_filter_data()\n");
  335. return(PROGRAM_ERROR);
  336. }
  337. valcnt = 0;
  338. while(get_word_from_string(&p,&thisword)) {
  339. if(valcnt>=2) {
  340. sprintf(errstr,"Too many values on line %d: file %s\n",n+1,filename);
  341. return(DATA_ERROR);
  342. }
  343. if(is_frq) {
  344. if(sscanf(thisword,"%lf",&(frq[n]))!=1) {
  345. sprintf(errstr,"Problem reading Frq data: line %d: file %s\n",n+1,filename);
  346. return(DATA_ERROR);
  347. }
  348. if(frq[n]<dz->application->min_special || frq[n]>dz->application->max_special) {
  349. sprintf(errstr,"frq (%.3lf) on line %d out of range (%.1lf to %.1lf):file %s\n",
  350. frq[n],n+1,dz->application->min_special,dz->application->max_special,filename);
  351. return(DATA_ERROR);
  352. }
  353. if(dz->mode==FLT_MIDI)
  354. frq[n] = miditohz(frq[n]);
  355. } else {
  356. if((exit_status = get_level(thisword,&(amp[n])))<0)
  357. return(exit_status);
  358. if(amp[n]<FLT_MINGAIN || amp[n]>FLT_MAXGAIN) {
  359. sprintf(errstr,"amp (%lf) out of range (%lf to %.1lf) on line %d: file %s\n",
  360. amp[n],FLT_MINGAIN,FLT_MAXGAIN,n+1,filename);
  361. return(DATA_ERROR);
  362. }
  363. }
  364. is_frq = !is_frq;
  365. valcnt++;
  366. }
  367. if(valcnt<2) {
  368. sprintf(errstr,"Not enough values on line %d: file %s\n",n+1,filename);
  369. return(DATA_ERROR);
  370. }
  371. n++;
  372. }
  373. if(fclose(dz->fp)<0) {
  374. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  375. fflush(stdout);
  376. }
  377. return(FINISHED);
  378. }
  379. /**************************** ALLOCATE_FILTER_FRQ_AMP_ARRAYS *******************************/
  380. int allocate_filter_frq_amp_arrays(int fltcnt,dataptr dz)
  381. {
  382. // int chans = dz->infile->channels;
  383. /*RWD 9:2001 must have empty arrays */
  384. if((dz->parray[FLT_AMP] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL
  385. || (dz->parray[FLT_FRQ] = (double *)calloc(fltcnt * sizeof(double),sizeof(char)))==NULL) {
  386. sprintf(errstr,"INSUFFICIENT MEMORY for filter amp and frq arrays.\n");
  387. return(MEMORY_ERROR);
  388. }
  389. return(FINISHED);
  390. }
  391. /************************** READ_TIME_VARYING_FILTER_DATA ********************************/
  392. int read_time_varying_filter_data(char *filename,dataptr dz)
  393. {
  394. int exit_status;
  395. // int cnt = 0;
  396. if((exit_status = get_data_from_tvary_infile(filename,dz))<0)
  397. return(exit_status);
  398. if((exit_status = check_filter_data(dz->iparam[FLT_ENTRYCNT],dz))<0)
  399. return(exit_status);
  400. return(FINISHED);
  401. }
  402. /**************************** GET_DATA_FROM_TVARY_INFILE *******************************/
  403. int get_data_from_tvary_infile(char *filename,dataptr dz)
  404. {
  405. int exit_status;
  406. char *temp, *p, *thisword;
  407. int maxlinelen, frqcnt;
  408. int total_wordcnt = 0;
  409. int columns_in_this_row, columns_in_row = 0, number_of_rows = 0;
  410. /* NEW CODE */
  411. int n, m, k, old_wordcnt;
  412. double filedur = (double)(dz->insams[0]/dz->infile->channels)/(double)(dz->infile->srate);
  413. double far_time = filedur + FLT_TAIL + 1.0;
  414. /* NEW CODE */
  415. double val;
  416. if((dz->fp = fopen(filename,"r"))==NULL) {
  417. sprintf(errstr,"Cannot open datafile %s\n",filename);
  418. return(DATA_ERROR);
  419. }
  420. if((exit_status = getmaxlinelen(&maxlinelen,dz->fp))<0)
  421. return(exit_status);
  422. if((fseek(dz->fp,0,0))<0) {
  423. sprintf(errstr,"Seek failed in get_data_from_tvary_infile()\n");
  424. return(SYSTEM_ERROR);
  425. }
  426. if((temp = (char *)malloc((maxlinelen+2) * sizeof(char)))==NULL) {
  427. sprintf(errstr,"INSUFFICIENT MEMORY for temporary line storage.\n");
  428. return(MEMORY_ERROR);
  429. }
  430. while(fgets(temp,maxlinelen,dz->fp)!=NULL) {
  431. columns_in_this_row = 0;
  432. if(is_an_empty_line_or_a_comment(temp))
  433. continue;
  434. p = temp;
  435. while(get_word_from_string(&p,&thisword)) {
  436. if((exit_status = get_level(thisword,&val))<0) { /* reads vals or dB vals */
  437. free(temp);
  438. return(exit_status);
  439. }
  440. if((total_wordcnt==0 && ((dz->parray[FLT_FBRK] = (double *)malloc(sizeof(double)))==NULL))
  441. || (dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt+1) * sizeof(double)))==NULL) {
  442. free(temp);
  443. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
  444. return(MEMORY_ERROR);
  445. }
  446. dz->parray[FLT_FBRK][total_wordcnt] = val;
  447. columns_in_this_row++;
  448. total_wordcnt++;
  449. }
  450. if(number_of_rows==0) {
  451. if((columns_in_row = columns_in_this_row)<3) {
  452. sprintf(errstr,"Insufficient filter data in row 1 of file %s.\n",filename);
  453. free(temp);
  454. return(DATA_ERROR);
  455. } else if (ODD(columns_in_row - 1)) {
  456. sprintf(errstr,"Frq and Amp data not paired correctly (or no Time) in row 1 of file %s.\n",filename);
  457. free(temp);
  458. return(DATA_ERROR);
  459. }
  460. } else if(columns_in_this_row!=columns_in_row) {
  461. free(temp);
  462. if(columns_in_this_row < columns_in_row)
  463. sprintf(errstr,"Not enough entries in row %d of file %s\n",number_of_rows+1,filename);
  464. else
  465. sprintf(errstr,"Too many entries in row %d of file %s\n",number_of_rows+1,filename);
  466. return(DATA_ERROR);
  467. }
  468. number_of_rows++;
  469. }
  470. dz->iparam[FLT_WORDCNT] = total_wordcnt;
  471. free(temp);
  472. if(columns_in_row<3) {
  473. sprintf(errstr,"Insufficient data in each row, to define filters.\n");
  474. return(DATA_ERROR);
  475. }
  476. dz->iparam[FLT_ENTRYCNT] = columns_in_row;
  477. frqcnt = columns_in_row - 1;
  478. if(ODD(frqcnt)) {
  479. sprintf(errstr,"amplitude and freq data not correctly paired in rows.\n");
  480. return(DATA_ERROR);
  481. }
  482. dz->iparam[FLT_CNT] = frqcnt/2;
  483. dz->iparam[FLT_TIMESLOTS] = number_of_rows;
  484. if(fclose(dz->fp)<0) {
  485. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  486. fflush(stdout);
  487. }
  488. /* NEW CODE */
  489. if(dz->parray[FLT_FBRK][0] !=0.0) {
  490. if(flteq(dz->parray[FLT_FBRK][0],0.0))
  491. dz->parray[FLT_FBRK][0] = 0.0;
  492. else {
  493. dz->iparam[FLT_TIMESLOTS]++;
  494. old_wordcnt = dz->iparam[FLT_WORDCNT];
  495. k = old_wordcnt-1;
  496. dz->iparam[FLT_WORDCNT] += dz->iparam[FLT_ENTRYCNT];
  497. m = dz->iparam[FLT_WORDCNT] - 1;
  498. if((dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],dz->iparam[FLT_WORDCNT] * sizeof(double)))==NULL) {
  499. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
  500. return(MEMORY_ERROR);
  501. }
  502. for(n=0;n<old_wordcnt;n++,m--,k--)
  503. dz->parray[FLT_FBRK][m] = dz->parray[FLT_FBRK][k];
  504. dz->parray[FLT_FBRK][0] = 0.0;
  505. total_wordcnt = dz->iparam[FLT_WORDCNT];
  506. }
  507. }
  508. if(dz->parray[FLT_FBRK][total_wordcnt - dz->iparam[FLT_ENTRYCNT]] < far_time) {
  509. dz->iparam[FLT_TIMESLOTS]++;
  510. m = dz->iparam[FLT_WORDCNT];
  511. k = m - dz->iparam[FLT_ENTRYCNT];
  512. dz->iparam[FLT_WORDCNT] += dz->iparam[FLT_ENTRYCNT];
  513. if((dz->parray[FLT_FBRK] = (double *)realloc(dz->parray[FLT_FBRK],dz->iparam[FLT_WORDCNT] * sizeof(double)))==NULL) {
  514. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
  515. return(MEMORY_ERROR);
  516. }
  517. dz->parray[FLT_FBRK][m] = far_time;
  518. m++;
  519. k++;
  520. for(n=1;n<dz->iparam[FLT_ENTRYCNT];n++,m++,k++)
  521. dz->parray[FLT_FBRK][m] = dz->parray[FLT_FBRK][k];
  522. }
  523. /* NEW CODE */
  524. return(FINISHED);
  525. }
  526. /**************************** GETMAXLINELEN *******************************/
  527. int getmaxlinelen(int *maxcnt,FILE *fp)
  528. {
  529. int thiscnt = 0;
  530. char c;
  531. *maxcnt = 0;
  532. while((c= (char)fgetc(fp))!=EOF) {
  533. if(c=='\n' || c == ENDOFSTR) {
  534. *maxcnt = max(*maxcnt,thiscnt);
  535. thiscnt = 0;
  536. } else
  537. thiscnt++;
  538. }
  539. *maxcnt = (int)max(*maxcnt,thiscnt);
  540. *maxcnt += 4; /* NEWLINE, ENDOFSTR and safety!! */
  541. return(FINISHED);
  542. }
  543. /**************************** CHECK_FILTER_DATA *******************************/
  544. int check_filter_data(int wordcnt_in_line,dataptr dz)
  545. {
  546. int exit_status;
  547. int n, lastfilt, new_total_wordcnt;
  548. double endtime;
  549. int total_wordcnt = dz->iparam[FLT_WORDCNT];
  550. if(dz->parray[FLT_FBRK][0] < 0.0) {
  551. sprintf(errstr,"Negative time value (%lf) on line 1.\n",dz->parray[FLT_FBRK][0]);
  552. return(DATA_ERROR);
  553. }
  554. if(flteq(dz->parray[FLT_FBRK][0],0.0))
  555. dz->parray[FLT_FBRK][0] = 0.0; /* FORCE A FILTER SETTING AT TIME ZERO */
  556. else {
  557. if((dz->parray[FLT_FBRK] =
  558. (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt+wordcnt_in_line) * sizeof(double)))==NULL) {
  559. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
  560. return(MEMORY_ERROR);
  561. }
  562. for(n=total_wordcnt-1; n>=0; n--)
  563. dz->parray[FLT_FBRK][n + wordcnt_in_line] = dz->parray[FLT_FBRK][n];
  564. total_wordcnt += wordcnt_in_line;
  565. dz->parray[FLT_FBRK][0] = 0.0;
  566. dz->iparam[FLT_TIMESLOTS]++;
  567. }
  568. dz->iparam[FLT_WORDCNT] = total_wordcnt;
  569. if((exit_status = check_seq_and_range_of_filter_data(dz->parray[FLT_FBRK],wordcnt_in_line,dz))<0)
  570. return(exit_status);
  571. /* FORCE A FILTER SETTING AT (BEYOND) END OF FILE */
  572. lastfilt = total_wordcnt - wordcnt_in_line;
  573. endtime = (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
  574. if(dz->parray[FLT_FBRK][lastfilt] <= endtime) {
  575. if((dz->parray[FLT_FBRK] =
  576. (double *)realloc(dz->parray[FLT_FBRK],(total_wordcnt + wordcnt_in_line) * sizeof(double)))==NULL) {
  577. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktable.\n");
  578. return(MEMORY_ERROR);
  579. }
  580. new_total_wordcnt = total_wordcnt + wordcnt_in_line;
  581. for(n=total_wordcnt;n<new_total_wordcnt;n++)
  582. dz->parray[FLT_FBRK][n] = dz->parray[FLT_FBRK][n - wordcnt_in_line];
  583. dz->parray[FLT_FBRK][total_wordcnt] = endtime + 1.0;
  584. total_wordcnt = new_total_wordcnt;
  585. dz->iparam[FLT_TIMESLOTS]++;
  586. }
  587. if(dz->iparam[FLT_TIMESLOTS]<2) {
  588. sprintf(errstr,"Error in timeslot logic: check_filter_data()\n");
  589. return(PROGRAM_ERROR);
  590. }
  591. dz->iparam[FLT_WORDCNT] = total_wordcnt;
  592. return(FINISHED);
  593. }
  594. /**************************** CHECK_SEQ_AND_RANGE_OF_FILTER_DATA *******************************/
  595. int check_seq_and_range_of_filter_data(double *fbrk,int wordcnt_in_line,dataptr dz)
  596. {
  597. double lasttime = 0.0;
  598. int n, m, lineno;
  599. for(n=1;n<dz->iparam[FLT_WORDCNT];n++) {
  600. m = n%wordcnt_in_line;
  601. lineno = (n/wordcnt_in_line)+1; /* original line-no : ignoring comments */
  602. if(m==0) {
  603. if(fbrk[n] <= lasttime) {
  604. sprintf(errstr,"Time is out of sequence on line %d\n",lineno);
  605. return(DATA_ERROR);
  606. //NEW AUGUST 2006
  607. // } else if(fbrk[n] > dz->duration) {
  608. // fbrk[n] = dz->duration + 1.0;
  609. // dz->iparam[FLT_WORDCNT] = lineno * wordcnt_in_line;
  610. }
  611. lasttime = fbrk[n];
  612. } else if(ODD(m)) {
  613. if(fbrk[n]<dz->application->min_special || fbrk[n]>dz->application->max_special) {
  614. sprintf(errstr,"frq_or_midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
  615. fbrk[n],dz->application->min_special,dz->application->max_special,lineno);
  616. return(DATA_ERROR);
  617. }
  618. if(dz->mode==FLT_MIDI)
  619. fbrk[n] = miditohz(fbrk[n]);
  620. } else
  621. fbrk[n] = max(fbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
  622. }
  623. return(FINISHED);
  624. }
  625. /********************************************************************************************/
  626. /********************************** FORMERLY IN preprocess.c ********************************/
  627. /********************************************************************************************/
  628. /****************************** PARAM_PREPROCESS *********************************/
  629. int param_preprocess(dataptr dz)
  630. {
  631. // int exit_status = FINISHED;
  632. switch(dz->process) {
  633. case(EQ): case(LPHP): case(FSTATVAR):
  634. case(FLTBANKN): case(FLTBANKU): case(FLTBANKV):
  635. case(FLTSWEEP): case(ALLPASS): case(FLTITER):
  636. case(FLTBANKC): case(FLTBANKV2):
  637. return filter_preprocess(dz);
  638. case(MAKE_VFILT): break;
  639. default:
  640. sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
  641. return(PROGRAM_ERROR);
  642. }
  643. return(FINISHED); /* NOTREACHED */
  644. }
  645. /********************************************************************************************/
  646. /********************************** FORMERLY IN procgrou.c **********************************/
  647. /********************************************************************************************/
  648. /**************************** GROUCHO_PROCESS_FILE ****************************/
  649. int groucho_process_file(dataptr dz) /* FUNCTIONS FOUND IN PROCESS.C */
  650. {
  651. // int exit_status = FINISHED;
  652. if(dz->process!= FLTBANKC)
  653. display_virtual_time(0L,dz);
  654. switch(dz->process) {
  655. case(LPHP):
  656. case(EQ): case(FSTATVAR): case(FLTSWEEP): case(ALLPASS):
  657. case(FLTBANKN): case(FLTBANKC): case(FLTBANKU): case(FLTBANKV):
  658. case(FLTBANKV2):
  659. return filter_process(dz);
  660. case(FLTITER):
  661. return iterating_filter(dz);
  662. case(MAKE_VFILT):
  663. return make_vfilt_data(dz);
  664. default:
  665. sprintf(errstr,"Unknown case in process_file()\n");
  666. return(PROGRAM_ERROR);
  667. }
  668. return(FINISHED); /* NOTREACHED */
  669. }
  670. /********************************************************************************************/
  671. /********************************** FORMERLY IN pconsistency.c ******************************/
  672. /********************************************************************************************/
  673. /****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
  674. int check_param_validity_and_consistency(dataptr dz)
  675. {
  676. // int exit_status = FINISHED;
  677. handle_pitch_zeros(dz);
  678. switch(dz->process) {
  679. case(EQ): case(LPHP): case(FSTATVAR): case(FLTBANKN):
  680. case(FLTBANKU): case(FLTBANKV): case(FLTSWEEP): case(ALLPASS):
  681. case(FLTITER): case(FLTBANKC): case(FLTBANKV2):
  682. return filter_pconsistency(dz);
  683. }
  684. return(FINISHED);
  685. }
  686. /********************************************************************************************/
  687. /********************************** FORMERLY IN buffers.c ***********************************/
  688. /********************************************************************************************/
  689. /**************************** ALLOCATE_LARGE_BUFFERS ******************************/
  690. int allocate_large_buffers(dataptr dz)
  691. {
  692. switch(dz->process) {
  693. case(EQ): case(LPHP): case(FSTATVAR):
  694. case(FLTBANKN): case(FLTBANKU): case(FLTBANKV): case(FLTBANKV2):
  695. case(FLTSWEEP): case(ALLPASS):
  696. return create_sndbufs(dz);
  697. case(FLTITER):
  698. return create_fltiter_buffer(dz);
  699. case(FLTBANKC):
  700. case(MAKE_VFILT):
  701. return(FINISHED);
  702. default:
  703. sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
  704. return(PROGRAM_ERROR);
  705. }
  706. return(FINISHED); /* NOTREACHED */
  707. }
  708. /*************************** CREATE_FLTITER_BUFFER **************************
  709. *
  710. * (1) Create extra spaces for interpolation guard points at end of infile.
  711. *
  712. * (2) Allow for any cumulative addition errors in interpolation.
  713. *
  714. * (3) Output buffer must be at least as big as the overflow buffer.
  715. * Output buffer must be big enough for the whole of any possible
  716. * data overflow (in overflow_size buff) to be copied back into it.
  717. * This is because the overflow buffer is ZEROED after such a copy
  718. * and if a 2nd copy of the overflow back into the main buffer
  719. * were necessary, we would be copying zeroes rather than true data.
  720. *
  721. * Output buffer must be bigger than the maximum possible delay.
  722. * When write_start is beyond end of buffer, we copy the overflow buffer
  723. * data back into the true buffer and reset the pointers by subtracting
  724. * buflen (length of output buffer). We must be sure that 'write_start'
  725. * will then be located WITHIN the true buffer. In the worst possible
  726. * case the write_start pointer is at the very end of the true buffer,
  727. * and is then delayed to its maximum possible extent, maxdelay_size (Z),
  728. * which will be Z samps into the overflow buffer. After the copy-back,
  729. * the 'write_start' pointer must lie WITHIN the true buffer.
  730. * Hence the true buflen must be >= maximum delay.
  731. *
  732. * true buffer overflow
  733. * |-----------------------------|------------------------------------------|
  734. * worst^ ^
  735. * possible case^ ^
  736. * ^----->-delayed by maxdelay_size to ->-----^
  737. * ^<-restored by -buffer_size into truebuf-<-^
  738. * |<-------- BUFFER_SIZE------->
  739. *
  740. */
  741. int create_fltiter_buffer(dataptr dz)
  742. {
  743. int big_buffer_size;
  744. size_t bigbufsize;
  745. double k;
  746. int chans = dz->infile->channels;
  747. int bufminimum, infilesamps;
  748. dz->iparam[FLT_INFILESPACE] = dz->insams[0];
  749. if(dz->param[FLT_PSHIFT]>0.0) {
  750. dz->iparam[FLT_INFILESPACE] += chans; /* 1 */
  751. k = pow(2.0,dz->param[FLT_PSHIFT]);
  752. dz->iparam[FLT_OVFLWSIZE] = ((round((dz->insams[0]/chans) * k) * chans) + chans);
  753. dz->iparam[FLT_OVFLWSIZE] += FLT_SAFETY; /* 2 */
  754. } else
  755. dz->iparam[FLT_OVFLWSIZE] = dz->iparam[FLT_INFILESPACE] + FLT_SAFETY;
  756. infilesamps = dz->iparam[FLT_INFILESPACE];
  757. bufminimum = dz->iparam[FLT_OVFLWSIZE];
  758. bigbufsize = (size_t)Malloc(-1);
  759. bigbufsize /= sizeof(float);
  760. bigbufsize -= (dz->iparam[FLT_INFILESPACE] * 2) + dz->iparam[FLT_OVFLWSIZE];
  761. if(bigbufsize<bufminimum)
  762. bigbufsize = bufminimum;
  763. //TW COMMENT: filters don't sfseek: so old buffer protocol can be abandoned
  764. dz->buflen = (int) bigbufsize;
  765. big_buffer_size = (dz->iparam[FLT_INFILESPACE] * 2) + dz->buflen + dz->iparam[FLT_OVFLWSIZE];
  766. if((dz->bigbuf = (float *) malloc((size_t)(big_buffer_size * sizeof(float)))) == NULL) {
  767. sprintf(errstr, "INSUFFICIENT MEMORY to create sound buffers.\n");
  768. return(MEMORY_ERROR);
  769. }
  770. dz->sampbuf[0] = dz->bigbuf;
  771. dz->sampbuf[1] = dz->sampbuf[0] + infilesamps;
  772. dz->sampbuf[FLT_OUTBUF] = dz->sampbuf[1] + infilesamps;
  773. dz->sampbuf[FLT_OVFLWBUF] = dz->sampbuf[FLT_OUTBUF] + dz->buflen;
  774. memset((char *)dz->bigbuf,0,(size_t)(big_buffer_size * sizeof(float)));
  775. return(FINISHED);
  776. }
  777. /********************************************************************************************/
  778. /********************************** FORMERLY IN cmdline.c ***********************************/
  779. /********************************************************************************************/
  780. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  781. {
  782. if (!strcmp(prog_identifier_from_cmdline,"fixed")) dz->process = EQ;
  783. else if(!strcmp(prog_identifier_from_cmdline,"lohi")) dz->process = LPHP;
  784. else if(!strcmp(prog_identifier_from_cmdline,"variable")) dz->process = FSTATVAR;
  785. else if(!strcmp(prog_identifier_from_cmdline,"bank")) dz->process = FLTBANKN;
  786. else if(!strcmp(prog_identifier_from_cmdline,"bankfrqs")) dz->process = FLTBANKC;
  787. else if(!strcmp(prog_identifier_from_cmdline,"userbank")) dz->process = FLTBANKU;
  788. else if(!strcmp(prog_identifier_from_cmdline,"varibank")) dz->process = FLTBANKV;
  789. else if(!strcmp(prog_identifier_from_cmdline,"varibank2")) dz->process = FLTBANKV2;
  790. else if(!strcmp(prog_identifier_from_cmdline,"iterated")) dz->process = FLTITER;
  791. else if(!strcmp(prog_identifier_from_cmdline,"sweeping")) dz->process = FLTSWEEP;
  792. else if(!strcmp(prog_identifier_from_cmdline,"phasing")) dz->process = ALLPASS;
  793. else if(!strcmp(prog_identifier_from_cmdline,"vfilters")) dz->process = MAKE_VFILT;
  794. else {
  795. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  796. return(USAGE_ONLY);
  797. }
  798. return FINISHED;
  799. }
  800. /********************************************************************************************/
  801. /********************************** FORMERLY IN usage.c *************************************/
  802. /********************************************************************************************/
  803. /******************************** USAGE1 ********************************/
  804. int usage1(void)
  805. {
  806. sprintf(errstr,
  807. "USAGE: filter NAME (mode) infile outfile (datafile) parameters\n"
  808. "\n"
  809. "where NAME can be any one of\n"
  810. "\n"
  811. "fixed lohi variable\n"
  812. "bank bankfrqs userbank varibank varibank2\n"
  813. "iterated sweeping phasing vfilters\n"
  814. "\n"
  815. "Type 'filter userbank' for more info on filter userbank... ETC.\n");
  816. return(USAGE_ONLY);
  817. }
  818. /******************************** USAGE2 ********************************/
  819. int usage2(char *str)
  820. {
  821. if (!strcmp(str,"fixed")) { /* EQ */
  822. fprintf(stdout,
  823. "CUT OR BOOST, ABOVE, BELOW OR AROUND A GIVEN FRQ\n\n"
  824. "USAGE: filter fixed 1-2 infile outfile boost/cut freq [-ttail] [-sprescale]\n"
  825. "OR: filter fixed 3 infile outfile bwidth boost/cut freq [-ttail] [-sprescale]\n\n"
  826. "MODES ARE...\n"
  827. "1) BOOST OR CUT BELOW GIVEN FRQ\n"
  828. "2) BOOST OR CUT ABOVE GIVEN FRQ\n"
  829. "3) BOOST OR CUT A BAND CENTERED ON GIVEN FRQ\n\n"
  830. "BWIDTH is the filter bandwidth in Hz for Mode 3 only\n"
  831. "BOOST/CUT is the boost or cut, in dB\n"
  832. "FREQ is the filter frequency in Hz\n"
  833. "TAIL decay tail duration\n"
  834. "PRESCALE scales the INPUT to the filter.\n");
  835. } else if (!strcmp(str,"lohi")) { /* LOHI */
  836. fprintf(stdout,
  837. "FIXED LOW PASS OR HIGH PASS FILTER.\n\n"
  838. "USAGE:\nfilter lohi mode infile outfile attenuation pass-band stop-band [-ttail] [-sprescale]\n\n"
  839. "MODES ARE\n"
  840. "1) Pass-band and stop-band as freq in Hz.\n"
  841. "2) Pass-band and stop-band as (possibly fractional) midi notes.\n\n"
  842. "ATTENUATION Gain reduction of filter, in dB. Range(0 to %.0lf)\n"
  843. " Greater attenuation, sharper filter, but longer to calculate.\n"
  844. "PASS-BAND last pitch to be passed by the filter.\n"
  845. "STOP-BAND first pitch to be stopped by the filter.\n"
  846. " If stop-band is above pass-band, this is a lopass filter.\n"
  847. " If stop-band is below pass-band, this is a hipass filter.\n"
  848. "TAIL decay tail duration\n"
  849. "-s Prescale input: Avoid overflows: Range(%.3lf to %.1lf)\n",
  850. MIN_DB_ON_16_BIT,FLT_MINEQPRESCALE,FLT_MAXEQPRESCALE);
  851. } else if (!strcmp(str,"variable")) { /* FSTATVAR */
  852. fprintf(stdout,
  853. "LOPASS, HIGH-PASS, BANDPASS, OR NOTCH FILTER WITH VARIABLE FRQ\n\n"
  854. "USAGE: filter variable mode infile outfile acuity gain frq [-ttail]\n\n"
  855. "MODES ARE..\n"
  856. "1) NOTCH (Band Reject)\n\n"
  857. "2) BAND-PASS\n"
  858. "3) LOW-PASS\n"
  859. "4) HIGH-PASS\n"
  860. "ACUITY acuity of filter: Range(%lf to %.1lf).\n"
  861. " Smaller vals give tighter filter.\n"
  862. "GAIN overall gain on output: Range(%lf to %.1lf)\n"
  863. " Rule of thumb:\n"
  864. " if acuity = (1/3)to-power-n: gain = (2/3)-to-power-n\n"
  865. "FRQ frq of filter: Range(%.1lf to srate/2)\n\n"
  866. "ACUITY and FRQ can vary over time.\n"
  867. "TAIL decay tail duration\n",MIN_ACUITY,MAX_ACUITY,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ);
  868. } else if (!strcmp(str,"bank")) { /* FLTBANKN */
  869. fprintf(stdout,
  870. "BANK OF FILTERS, WITH TIME-VARIABLE Q\n\n"
  871. "USAGE: filter bank 1-3 infile outfile Q gain lof hif [-ttail] [-sscat] [-d]\n"
  872. "OR: filter bank 4-6 infile outfile Q gain lof hif param [-ttail] [-sscat] [-d]\n\n"
  873. "MODES...\n"
  874. "1) HARMONIC SERIES over lofrq.\n"
  875. "2) ALTERNATE HARMONICS over lofrq.\n"
  876. "3) SUBHARMONIC SERIES below hifrq.\n"
  877. "4) HARMONIC SERIES WITH LINEAR OFFSET: param = offset in Hz.\n"
  878. "5) EQUAL INTERVALS BETWEEN lo & hifrq: param = no. of filters.\n"
  879. "6) EQUAL INTERVALS BETWEEN lo & hifrq: param = interval semitone-size.\n\n"
  880. "Q Q (tightness) of filters (Range %lf <= Q < %.1lf)\n"
  881. "GAIN overall gain (Range %lf to %.1lf).\n"
  882. "LOF lofrq limit of filters (Range: %.0lf to srate/3).\n"
  883. "HIF hifrq limit of filters (Range: lofrq+ to srate/3).\n"
  884. "TAIL decay tail duration\n"
  885. "SCAT Random scatter of filter frqs (Range 0 to 1: Default 0).\n"
  886. "-d Double filtering.\n\n"
  887. "Q may vary over time.\n",MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ);
  888. } else if (!strcmp(str,"bankfrqs")) { /* FLTBANKC */
  889. fprintf(stdout,
  890. "GENERATE A LIST OF FREQUENCIES FOR USE AS A FILTERBANK\n"
  891. "(ADD AMPLITUDES TO THE TEXTFILE FOR USE WITH 'USERBANK')\n\n"
  892. "USAGE: filter bankfrqs 1-3 anysndfile outtextfile lof hif\n"
  893. "OR: filter bankfrqs 4-6 anysndfile outtextfile lof hif param\n\n"
  894. "MODES...\n"
  895. "1) HARMONIC SERIES over lofrq.\n"
  896. "2) ALTERNATE HARMONICS over lofrq.\n"
  897. "3) SUBHARMONIC SERIES below hifrq.\n"
  898. "4) HARMONIC SERIES WITH LINEAR OFFSET: param = offset in Hz.\n"
  899. "5) EQUAL INTERVALS BETWEEN lo & hifrq: param = no. of filters.\n"
  900. "6) EQUAL INTERVALS BETWEEN lo & hifrq: param = interval semitone-size.\n\n"
  901. "LOF lofrq limit of filters (Range: %.0lf to srate/3).\n"
  902. "HIF hifrq limit of filters (Range: lofrq+ to srate/3).\n"
  903. // "SCAT Random scatter of filter frqs (Range 0 to 1: Default 0).\n\n" /* RWD Apr 2011 this param not supported here */
  904. "NB sampling rate of input soundfile determines frq range\n",FLT_MINFRQ);
  905. } else if (!strcmp(str,"userbank")) { /* FLTBANKU */
  906. fprintf(stdout,
  907. "USER-DEFINED FILTERBANK,WITH TIME-VARIABLE Q\n\n"
  908. "USAGE: filter userbank mode infile outfile datafile Q gain [-ttail] [-d]\n\n"
  909. "MODES are\n"
  910. "1) Filter-pitches as frq in Hz.\n"
  911. "2) Filter-pitches as MIDI values.\n\n"
  912. "DATAFILE: has Pitch & Amp of filters (paired, one pair on each line).\n"
  913. " Ranges: Pitch (%.0lfHz to sr/3) Amp (%lf to %.1lf)\n"
  914. " Amplitude may also be expressed in decibels.\n"
  915. " Comment-lines (starting with ';') may be used.\n\n"
  916. "Q: Q (tightness) of filter: Range(%lf to %.1lf)\n"
  917. "GAIN overall gain, Range(%lf to %.1lf).\n"
  918. "TAIL decay tail duration\n"
  919. "-d double filtering.\n\n"
  920. "Q may vary over time.",FLT_MINFRQ,FLT_MINGAIN,FLT_MAXGAIN,MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN);
  921. } else if (!strcmp(str,"varibank")) { /* FLTBANKV */
  922. fprintf(stdout,
  923. "USER-DEFINED TIME_VARYING FILTERBANK,WITH TIME-VARIABLE Q\n\n"
  924. "USAGE:\nfilter varibank mode infile outfile data Q gain [-ttail] [-hhcnt] [-rrolloff] [-d]\n\n"
  925. "MODES ARE...\n"
  926. "1) Enter filter-pitches as frq, in Hz.\n"
  927. "2) Enter filter-pitches as MIDI values.\n\n"
  928. "DATAFILE: has lines of data for filter bands at successive times.\n"
  929. " Each line contains the following items\n"
  930. " Time: Pitch1 Amp1 [Pitch2 Amp2 etc....].\n"
  931. " Pitch and Amp values must be paired:\n"
  932. " any number of pairs can be used in a line,\n"
  933. " BUT each line must have SAME number of pairs on it.\n"
  934. " (To eliminate a band in any line(s), set its amplitude to 0.0).\n"
  935. " Time values (in secs) must be in ascending order (and >=0.0)\n"
  936. " Pitch vals may be EITHER frq, OR MIDI, depending on MODE.\n"
  937. " Amp values may be numeric, or dB values (e.g. -4.1dB).\n"
  938. " Comment-lines may be used: start these with ';'.\n\n"
  939. "Q Q (tightness) of filter : Range(%lf to %.1lf).\n"
  940. "GAIN: overall gain: Range: (%lf to %.1lf)\n"
  941. "TAIL decay tail duration\n"
  942. "HCNT No of harmonics of each pitch to use: Default 1.\n"
  943. " High harmonics of high pitches may be beyond nyquist.\n"
  944. " (No-of-pitches times no-of-harmonics determines program speed).\n"
  945. "ROLLOFF Level drop (in dB) from one harmonic to next. Range(0 to %.1lf)\n"
  946. "-d double filtering.\n\n"
  947. "Q may also vary over time.\n",MINQ,MAXQ,FLT_MINGAIN, FLT_MAXGAIN,MIN_DB_ON_16_BIT);
  948. } else if (!strcmp(str,"varibank2")) { /* FLTBANKV */
  949. fprintf(stdout,
  950. "USER-DEFINED TIME_VARYING FILTERBANK,WITH TIME-VARIABLE Q AND PARTIALS\n"
  951. "USAGE:\nfilter varibank2 mode infil outfil data Q gain [-ttail] [-d]\n"
  952. "MODES ARE...\n"
  953. "1) Enter filter-pitches as frq, in Hz.\n"
  954. "2) Enter filter-pitches as MIDI values.\n\n"
  955. "DATAFILE: has lines of data for filter bands at successive times.\n"
  956. " as varibank filter....\n"
  957. " Followed by a line with a '#' sign at the start.\n"
  958. " Followed by 2nd set of lines, similar to the pitchdata lines\n"
  959. " but now the data is a time followed by any number of pairs of\n"
  960. " partial number (possibly fractional) + amplitude of partial.\n"
  961. " Times for pitch AND for partials data MUST START AT ZERO.\n"
  962. "Q Q (tightness) of filter : Range(%lf to %.1lf).\n"
  963. "GAIN: overall gain: Range: (%lf to %.1lf)\n"
  964. "TAIL decay tail duration\n"
  965. "-d double filtering.\n\n"
  966. "Q may also vary over time.\n",MINQ,MAXQ,FLT_MINGAIN,FLT_MAXGAIN);
  967. } else if (!strcmp(str,"iterated")) { /* FLTITER */
  968. fprintf(stdout,
  969. "ITERATE SOUND, WITH CUMULATIVE FILTERING BY A FILTERBANK.\n\n"
  970. "USAGE: filter iterated mode infile outfile datafile Q gain delay dur \n"
  971. " [-sprescale] [-rrand] [-ppshift] [-aashift] [-d] [-i] [-e] [-n]\n\n"
  972. "MODES ARE...\n"
  973. "1) Enter filter-pitches as frq, in Hz.\n"
  974. "2) Enter filter-pitches as MIDI values.\n\n"
  975. "DATAFILE has Pitch & Amp of filters (paired, one pair on each line).\n"
  976. " Pitch, as Hz or MIDI, Range(%.0lfHz to srate/3)\n"
  977. " Amp, Range(%lf to %.1lf), can also be entered as dB vals\n\n"
  978. "Q Q (tightness) of filter: Range(%lf to %.1lf)\n"
  979. "GAIN overrall gain in filtering process (%lf < gain < %.1lf)\n"
  980. "DELAY (average) delay between iterations (secs).\n"
  981. " Range(>0 to %.0lf)\n"
  982. "DUR (min) duration of output file (>infile duration).\n"
  983. "PRESCALE gain on the INPUT to the filtering process.\n"
  984. " Range (0.0 - 1.0) Default 1.0\n"
  985. " If set to 0.0, Program automatically divides input level by\n"
  986. " the max no. of sound overlays occuring in the iteration process.\n"
  987. "RAND delaytime-randomisation: Range 0 (none) to 1 (max).\n"
  988. "PSHIFT max pitchshift of any segment in (fractions of) semitones (>=0).\n"
  989. "ASHIFT max amplitude reduction of any segment: Range (0.0 - 1.0)\n"
  990. "-d double filtering.\n"
  991. "-i Turn off Interpolation during pitch shift: (fast but dirty).\n"
  992. "-e Exponential decay added: each seg gets quieter before next enters.\n"
  993. "-n turns OFF normalisation: segs may grow or fall in level quickly.\n",
  994. FLT_MINFRQ,FLT_MINGAIN,FLT_MAXGAIN,MINQ, MAXQ, FLT_MINGAIN,FLT_MAXGAIN,FLT_MAXDELAY);
  995. } else if (!strcmp(str,"sweeping")) { /* FLTSWEEP */
  996. fprintf(stdout,
  997. "FILTER WHOSE FOCUS-FREQUENCY SWEEPS OVER A RANGE OF FREQUENCIES\n\n"
  998. "USAGE:\n"
  999. "filter sweeping mode infile outfile acuity gain lofrq hifrq sweepfrq [-ttail] [-pphase]\n\n"
  1000. "MODES ARE...\n"
  1001. "1) NOTCH (Band-reject). 3) LOW-PASS\n"
  1002. "2) BAND-PASS 4) HIGH-PASS \n\n"
  1003. "ACUITY Acuity of filter: Range(%lf to %.1lf)\n"
  1004. " Smaller vals give tighter filter.\n"
  1005. "GAIN overall gain on output: Range(%lf to %.1lf)\n"
  1006. " Rule of thumb:\n"
  1007. " if acuity = (1/3)to-power-n: gain = (2/3)-to-power-n\n"
  1008. "LOFRQ lowest frq to sweep to: Range(%.1lf to srate/2)\n"
  1009. "HIFRQ highest frq to sweep to: Range(%.1lf to srate/2)\n"
  1010. "SWEEPFRQ frq of the sweep itself: Range(0.0 to %.1lf)\n"
  1011. " e.g. to sweep once over range, set sweepfrq to infiledur/2 (default)\n"
  1012. " and set phase to 0 (upsweep) or .5(downsweep)\n"
  1013. "TAIL decay tail duration\n"
  1014. "PHASE start of sweep: Range(0-1)\n"
  1015. " vals are: 0 = (lofrq) rising to .5 = (hifrq) falling to 1 = (lofrq).\n"
  1016. " Default value is .25 (midfrq,rising)\n\n"
  1017. "ACUITY, LOFRQ, HIFRQ and SWEEPFRQ may all vary over time.\n"
  1018. "This filter is most effective in BAND-PASS or LOW-PASS mode, at low ACUITY.\n",
  1019. MIN_ACUITY,MAX_ACUITY,FLT_MINGAIN,FLT_MAXGAIN,FLT_MINFRQ,FLT_MINFRQ,FLT_MAXSWEEP);
  1020. } else if (!strcmp(str,"phasing")) { /* ALLPASS */
  1021. fprintf(stdout,
  1022. "PHASESHIFT SOUND, OR PRODUCE 'PHASING' EFFECT\n\n"
  1023. "USAGE: filter phasing mode infile outfile gain delay [-ttail] [-sprescale] [-l]\n\n"
  1024. "MODES ARE..\n"
  1025. "1) ALLPASS FILTER (PHASE-SHIFTED)\n"
  1026. "2) PHASING EFFECT\n\n"
  1027. "GAIN Range (-1.0 to 1.0)\n"
  1028. " In MODE 2, phasing effect increases as gain increases from -1\n"
  1029. " BUT a gain of 1.0 will produce complete phase cancellation\n"
  1030. " and the output signal will be zero.\n"
  1031. "DELAY >0.0 MS\n"
  1032. "TAIL decay tail duration\n"
  1033. "PRESCALE gain on the INPUT to the filtering process.\n"
  1034. " Range (0.0 - 1.0) Default 1.0\n"
  1035. "-l linear interpolation of changing delay vals (default: logarithmic)\n\n"
  1036. "DELAY may vary over time.\n");
  1037. } else if (!strcmp(str,"vfilters")) { /* MAKE VFILTER FIXED-PITCH DATA FILES */
  1038. fprintf(stdout,
  1039. "MAKE FIXED-PITCH DATA-FILES FOR VARIBANK FILTER\n\n"
  1040. "USAGE: filter vfilters inpitchfile outfile\n\n"
  1041. "INPITCHFILE Textfile, contains a list of MIDI or FRQ pitch values\n"
  1042. " with one or more values on each line.\n"
  1043. "Each line is converted to a data file for a fixed pitch(es) filter,\n"
  1044. "of the 'varibank' type.\n"
  1045. "Producing outfile0.txt, outfile1.txt etc.\n");
  1046. } else
  1047. fprintf(stdout,"Unknown option '%s'\n",str);
  1048. return(USAGE_ONLY);
  1049. }
  1050. /******************************** USAGE3 ********************************/
  1051. int usage3(char *str1,char *str2)
  1052. {
  1053. sprintf(errstr,"Insufficient parameters on command line.\n");
  1054. return(USAGE_ONLY);
  1055. }
  1056. /******************************** INNER_LOOP (redundant) ********************************/
  1057. int inner_loop
  1058. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  1059. {
  1060. return(FINISHED);
  1061. }
  1062. /**************************** CHECK_SEQ_AND_RANGE_OF_FILTER_DATA2 *******************************/
  1063. int check_seq_and_range_of_filter_data2(double *fbrk,double *hbrk,dataptr dz)
  1064. {
  1065. double lasttime = -1.0;
  1066. double maxpartial = dz->infile->srate/(2.0 * FLT_MINFRQ);
  1067. double minpartial = 1.0;
  1068. int n, m, lineno = 0;
  1069. double frqmax = dz->infile->srate/2.0;
  1070. double midimax = unchecked_hztomidi(frqmax);
  1071. double midimin = unchecked_hztomidi(FLT_MINFRQ);
  1072. int wordcnt_in_line = dz->iparam[FLT_ENTRYCNT];
  1073. for(n=0;n<dz->iparam[FLT_WORDCNT];n++) {
  1074. m = n%wordcnt_in_line;
  1075. if(m==0) {
  1076. lineno++; /* original line-no : ignoring comments */
  1077. if(fbrk[n] <= lasttime) {
  1078. sprintf(errstr,"Time is out of sequence in pitch data line %d\n",lineno);
  1079. return(DATA_ERROR);
  1080. }
  1081. lasttime = fbrk[n];
  1082. } else if(ODD(m)) {
  1083. if(dz->mode==FLT_MIDI) {
  1084. if(fbrk[n] < midimin || fbrk[n] > midimax) {
  1085. sprintf(errstr,"midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
  1086. fbrk[n],midimin,midimax,lineno);
  1087. return(DATA_ERROR);
  1088. }
  1089. fbrk[n] = miditohz(fbrk[n]);
  1090. } else {
  1091. if(fbrk[n] < FLT_MINFRQ || fbrk[n] > frqmax) {
  1092. sprintf(errstr,"frq_or_midi value [%.3lf] out of range (%.1f - %.1f) on line %d\n",
  1093. fbrk[n],FLT_MINFRQ,frqmax,lineno);
  1094. return(DATA_ERROR);
  1095. }
  1096. }
  1097. } else
  1098. fbrk[n] = max(fbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
  1099. }
  1100. wordcnt_in_line = dz->iparam[HRM_ENTRYCNT];
  1101. lasttime = -1.0;
  1102. lineno = 0;
  1103. for(n=0;n<dz->iparam[HRM_WORDCNT];n++) {
  1104. m = n%wordcnt_in_line;
  1105. if(m==0) {
  1106. lineno++;
  1107. if(hbrk[n] <= lasttime) {
  1108. sprintf(errstr,"Time is out of sequence in partials data line %d\n",lineno);
  1109. return(DATA_ERROR);
  1110. }
  1111. lasttime = hbrk[n];
  1112. } else if(ODD(m)) {
  1113. if(hbrk[n]<minpartial|| hbrk[n]>maxpartial) {
  1114. sprintf(errstr,"partial value [%.3lf] out of range (%lf - %.1f) on line %d\n",hbrk[n],minpartial,maxpartial,lineno);
  1115. return(DATA_ERROR);
  1116. }
  1117. } else
  1118. hbrk[n] = max(hbrk[n],MINFILTAMP); /* Zero filter amp, forced to +ve, but effectively zero */
  1119. }
  1120. return(FINISHED);
  1121. }
  1122. /**************************** READ_DATA_FROM_T_AND_P_VARY_INFILE *******************************/
  1123. int read_data_from_t_and_p_vary_infile(char *filename,dataptr dz)
  1124. {
  1125. int exit_status;
  1126. char *temp, *p, *thisword;
  1127. int maxlinelen, frqcnt = 0, hcnt;
  1128. int total_wordcnt = 0, number_of_rows = 0, total_number_of_rows = 0,columns_in_this_row,columns_in_row = 0;
  1129. int harmdata = 0, ishash = 0, thisarray;
  1130. double val;
  1131. if((dz->fp = fopen(filename,"r"))==NULL) {
  1132. sprintf(errstr,"Cannot open datafile %s\n",filename);
  1133. return(DATA_ERROR);
  1134. }
  1135. if((exit_status = getmaxlinelen2(&maxlinelen,dz->fp))<0)
  1136. return(exit_status);
  1137. if((fseek(dz->fp,0,0))<0) {
  1138. sprintf(errstr,"Seek failed in get_data_from_t_and_p_vary_infile()\n");
  1139. return(SYSTEM_ERROR);
  1140. }
  1141. if((temp = (char *)malloc((maxlinelen+2) * sizeof(char)))==NULL) {
  1142. sprintf(errstr,"INSUFFICIENT MEMORY for temporary line storage.\n");
  1143. return(MEMORY_ERROR);
  1144. }
  1145. while(fgets(temp,maxlinelen,dz->fp)!=NULL) {
  1146. columns_in_this_row = 0;
  1147. if(is_an_empty_line_or_a_comment(temp))
  1148. continue;
  1149. p = temp;
  1150. while(get_word_from_string(&p,&thisword)) {
  1151. if(!strncmp(thisword,"#",1)) {
  1152. if(harmdata) {
  1153. sprintf(errstr,"HASH SIGN AT WRONG PLACE IN DATA in LINE %d.\n",total_number_of_rows+1);
  1154. return(DATA_ERROR);
  1155. }
  1156. dz->iparam[FLT_WORDCNT] = total_wordcnt;
  1157. dz->iparam[FLT_ENTRYCNT] = columns_in_row;
  1158. total_wordcnt = 0;
  1159. number_of_rows = 0;
  1160. frqcnt = columns_in_row - 1;
  1161. harmdata = 1;
  1162. ishash = 1;
  1163. break;
  1164. }
  1165. if((exit_status = get_level(thisword,&val))<0) { /* reads vals */
  1166. free(temp);
  1167. return(exit_status);
  1168. }
  1169. if(harmdata)
  1170. thisarray = FLT_HBRK;
  1171. else
  1172. thisarray = FLT_FBRK;
  1173. if(total_wordcnt==0) {
  1174. if ((dz->parray[thisarray] = (double *)malloc(sizeof(double)))==NULL) {
  1175. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktables.\n");
  1176. return(MEMORY_ERROR);
  1177. }
  1178. dz->parray[thisarray][total_wordcnt] = val;
  1179. } else {
  1180. if ((dz->parray[thisarray] = (double *)realloc(dz->parray[thisarray],(total_wordcnt+1) * sizeof(double)))==NULL) {
  1181. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter brktables.\n");
  1182. return(MEMORY_ERROR);
  1183. }
  1184. }
  1185. dz->parray[thisarray][total_wordcnt] = val;
  1186. columns_in_this_row++;
  1187. total_wordcnt++;
  1188. }
  1189. if(ishash) {
  1190. ishash = 0;
  1191. continue;
  1192. }
  1193. if(number_of_rows==0) {
  1194. if((columns_in_row = columns_in_this_row)<3) {
  1195. sprintf(errstr,"Insufficient data in row 1 of file %s.\n",filename);
  1196. free(temp);
  1197. return(DATA_ERROR);
  1198. } else if (ODD(columns_in_row - 1)) {
  1199. 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);
  1200. free(temp);
  1201. return(DATA_ERROR);
  1202. }
  1203. } else if(columns_in_this_row!=columns_in_row) {
  1204. free(temp);
  1205. if(columns_in_this_row < columns_in_row)
  1206. sprintf(errstr,"Not enough entries in row %d of file %s\n",total_number_of_rows+1,filename);
  1207. else
  1208. sprintf(errstr,"Too many entries in row %d of file %s\n",total_number_of_rows+1,filename);
  1209. return(DATA_ERROR);
  1210. }
  1211. number_of_rows++;
  1212. total_number_of_rows++;
  1213. }
  1214. dz->iparam[HRM_WORDCNT] = total_wordcnt;
  1215. free(temp);
  1216. if(columns_in_row<3) {
  1217. sprintf(errstr,"Insufficient data in each row, to define filters.\n");
  1218. return(DATA_ERROR);
  1219. }
  1220. dz->iparam[HRM_ENTRYCNT] = columns_in_row;
  1221. hcnt = columns_in_row - 1;
  1222. dz->iparam[FLT_CNT] = frqcnt/2;
  1223. dz->iparam[FLT_HARMCNT] = hcnt/2;
  1224. dz->iparam[FLT_CNT] *= dz->iparam[FLT_HARMCNT];
  1225. if(fclose(dz->fp)<0) {
  1226. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  1227. fflush(stdout);
  1228. }
  1229. if(dz->parray[FLT_FBRK][0] !=0.0) {
  1230. sprintf(errstr,"FIRST TIME VALUE FOR PITCHES MUST BE ZERO\n");
  1231. return(DATA_ERROR);
  1232. }
  1233. if(dz->parray[FLT_HBRK][0] !=0.0) {
  1234. sprintf(errstr,"FIRST TIME VALUE FOR HARMONICS MUST BE ZERO\n");
  1235. return(DATA_ERROR);
  1236. }
  1237. return check_seq_and_range_of_filter_data2(dz->parray[FLT_FBRK],dz->parray[FLT_HBRK],dz);
  1238. }
  1239. /**************************** GETMAXLINELEN2 *******************************/
  1240. int getmaxlinelen2(int *maxcnt,FILE *fp)
  1241. {
  1242. int thiscnt = 0;
  1243. int gothash = 0;
  1244. int gotdata1 = 0, gotdata2 = 0;
  1245. char c;
  1246. *maxcnt = 0;
  1247. while((c= (char)fgetc(fp))!=EOF) {
  1248. if(!gothash) {
  1249. if(c=='#') {
  1250. if(!gotdata1) {
  1251. sprintf(errstr,"FAILED TO GET FIRST SET OF DATA (PITCH INFORMATION) BEFORE HASH SIGN\n");
  1252. return(DATA_ERROR);
  1253. }
  1254. while((c= (char)fgetc(fp))!=EOF) {
  1255. if(c == '\n' || c == ENDOFSTR) {
  1256. gothash = 1;
  1257. thiscnt = 0;
  1258. break;
  1259. }
  1260. }
  1261. if(!gothash)
  1262. break;
  1263. } else {
  1264. if(c=='\n' || c == ENDOFSTR) {
  1265. *maxcnt = max(*maxcnt,thiscnt);
  1266. thiscnt = 0;
  1267. gotdata1 = 1;
  1268. } else {
  1269. thiscnt++;
  1270. }
  1271. }
  1272. } else {
  1273. if(c=='\n' || c == ENDOFSTR) {
  1274. *maxcnt = max(*maxcnt,thiscnt);
  1275. thiscnt = 0;
  1276. gotdata2 = 1;
  1277. } else {
  1278. thiscnt++;
  1279. }
  1280. }
  1281. }
  1282. if(!gotdata2) {
  1283. sprintf(errstr,"FAILED TO GET SECOND SET OF DATA (PARTIALS INFORMATION) AFTER HASH SIGN\n");
  1284. return(DATA_ERROR);
  1285. }
  1286. *maxcnt = (int)max(*maxcnt,thiscnt);
  1287. *maxcnt += 4; /* NEWLINE, ENDOFSTR and safety!! */
  1288. return(FINISHED);
  1289. }