fltpcon.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <globcon.h>
  26. #include <processno.h>
  27. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <filters.h>
  30. #include <sfsys.h>
  31. #include <osbind.h>
  32. /*RWD*/
  33. #include <math.h>
  34. #include <string.h>
  35. //#ifdef unix
  36. #define round(x) lround((x))
  37. //#endif
  38. static int force_start_and_end_val(int paramno,dataptr dz);
  39. static void initialise_filter_table_read(int param,dataptr dz);
  40. static int setup_internal_eq_params(dataptr dz);
  41. static int setup_internal_fstatvar_params(dataptr dz);
  42. static int setup_internal_fltsweep_params(dataptr dz);
  43. static int setup_internal_allpass_params_and_delaybufs(dataptr dz);
  44. static int setup_internal_fltbankn_params(dataptr dz);
  45. static void setup_internal_iterfilt_params(dataptr dz);
  46. static int allocate_tvarying_filter_arrays(int timeslot_cnt,int harmonics_cnt,dataptr dz);
  47. static int put_tvarying_filter_data_in_arrays(double *fbrk,dataptr dz);
  48. static int initialise_fltbankv_internal_params(dataptr dz);
  49. static int error_name(int paramno,char *paramname,dataptr dz);
  50. static int setup_stereo_variables(int a,int b,int c,int d,int chans,dataptr dz);
  51. static int setup_eqfilter_coeffs(dataptr dz);
  52. static int convert_delay_times_to_samples_and_get_maxdelay(dataptr dz);
  53. static int count_filters(dataptr dz);
  54. static void convert_phase_from_input_range_to_actual_range(dataptr dz);
  55. static void convert_sfrq(dataptr dz);
  56. static void set_doflag(dataptr dz);
  57. /* ANDY MOORER ROUTINES: for 2nd-order presence and shelving filters */
  58. /* rationalised slightly */
  59. #define PII (3.141592653589793238462643)
  60. #define ROOT2OF2 (0.7071067811965475244) /* = sqrt(2)/2 */
  61. #define SPN 1.65436e-24 /* Smallest possible number on DEC VAX-780: but it will work here */
  62. static void presence(double cf,double boost,double bw,double *a0,double *a1,double *a2,double *b1,double *b2);
  63. static void shelve(double cf,double boost,double *a0,double *a1,double *a2,double *b1,double *b2,int mode);
  64. static double bw2angle(double a,double bw);
  65. static void normalise_b0_to_one(double b0,double *a0,double *a1,double *a2,double *b1,double *b2);
  66. static void bilinear_transform(double a,double t0,double t1,double t2,double asq,double *x0,double *x1,double *x2);
  67. static void set_the_tvars(double gamma,double *t0,double *t1,double *t2);
  68. static void establish_a_asq_A_F_F2_tmp(double cf,double boost,
  69. double *a,double *asq,double *A,double *F,double *f2,double *temp);
  70. static int test_pitch_and_spectrum_varying_filterdata(double *fbrk,double *hbrk,dataptr dz);
  71. static int allocate_tvarying2_filter_arrays(dataptr dz);
  72. /************************************* FILTER_PCONSISTENCY *********************************/
  73. int filter_pconsistency(dataptr dz)
  74. {
  75. int exit_status;
  76. initrand48();
  77. switch(dz->process) { /* preset internal counters, or defaulted variables */
  78. case(FLTBANKN):
  79. case(FSTATVAR):
  80. case(FLTBANKU):
  81. case(FLTBANKV):
  82. case(FLTBANKV2):
  83. case(FLTSWEEP):
  84. dz->iparam[FLT_SAMS] = 0;
  85. dz->iparam[FLT_OVFLW] = 0;
  86. dz->iparam[FLT_BLOKSIZE] = BSIZE;
  87. dz->iparam[FLT_BLOKCNT] = 0;
  88. dz->param[FLT_INV_SR] = 1.0/(double)dz->infile->srate;
  89. if(dz->brksize[FLT_Q]) {
  90. if((exit_status = force_start_and_end_val(FLT_Q,dz))<0)
  91. return(exit_status);
  92. initialise_filter_table_read(FLT_Q,dz);
  93. }
  94. break;
  95. case(FLTBANKC):
  96. dz->param[FLT_RANDFACT] = 0.0;
  97. dz->param[FLT_INV_SR] = 1.0/(double)dz->infile->srate;
  98. break;
  99. case(EQ):
  100. dz->iparam[FLT_OVFLW] = 0;
  101. dz->param[FLT_INV_SR] = 1.0/(double)dz->infile->srate;
  102. break;
  103. case(LPHP):
  104. if(dz->mode==FLT_MIDI) {
  105. miditohz(dz->param[FLT_PASSFRQ]);
  106. miditohz(dz->param[FLT_STOPFRQ]);
  107. }
  108. dz->iparam[FLT_OVFLW] = 0;
  109. break;
  110. case(FLTITER):
  111. dz->iparam[FLT_OVFLW] = 0;
  112. dz->param[FLT_INV_SR] = 1.0/(double)dz->infile->srate;
  113. dz->iparam[FLT_SAMS] = 0;
  114. break;
  115. case(ALLPASS):
  116. dz->iparam[FLT_BLOKSIZE] = 1; /* delay (& strength) incremented on (stereo-pair)sample-by-sample basis */
  117. dz->iparam[FLT_OVFLW] = 0;
  118. dz->iparam[FLT_SAMS] = 0;
  119. break;
  120. }
  121. switch(dz->process) {
  122. case(EQ): return setup_internal_eq_params(dz);
  123. case(FSTATVAR): return setup_internal_fstatvar_params(dz);
  124. case(FLTSWEEP): return setup_internal_fltsweep_params(dz);
  125. case(ALLPASS): return setup_internal_allpass_params_and_delaybufs(dz);
  126. case(FLTBANKN):
  127. case(FLTBANKC): return setup_internal_fltbankn_params(dz);
  128. case(FLTITER):
  129. setup_internal_iterfilt_params(dz);
  130. break;
  131. case(FLTBANKV):
  132. dz->param[FLT_ROLLOFF] = dbtogain(dz->param[FLT_ROLLOFF]);
  133. if((exit_status = allocate_tvarying_filter_arrays(dz->iparam[FLT_TIMESLOTS],dz->iparam[FLT_HARMCNT],dz))<0)
  134. return(exit_status);
  135. if((exit_status = put_tvarying_filter_data_in_arrays(dz->parray[FLT_FBRK],dz))<0)
  136. return(exit_status);
  137. if((exit_status = initialise_fltbankv_internal_params(dz))<0)
  138. return(exit_status);
  139. break;
  140. case(FLTBANKV2):
  141. if((exit_status = allocate_tvarying2_filter_arrays(dz))<0)
  142. return(exit_status);
  143. if((exit_status = test_pitch_and_spectrum_varying_filterdata(dz->parray[FLT_FBRK],dz->parray[FLT_HBRK],dz))<0)
  144. return(exit_status);
  145. if((exit_status = allocate_filter_frq_amp_arrays(dz->iparam[FLT_CNT],dz))<0)
  146. return(exit_status);
  147. if((exit_status = newfval2(dz->parray[FLT_FBRK],dz->parray[FLT_HBRK],dz))<0)
  148. return(exit_status);
  149. break;
  150. }
  151. return(FINISHED);
  152. }
  153. /*************************************** FORCE_START_AND_END_VAL **************************************/
  154. int force_start_and_end_val(int paramno,dataptr dz)
  155. {
  156. int exit_status;
  157. double lasttime, filedur, firsttime, *p;
  158. int k, n;
  159. char paramname[10];
  160. if((exit_status = error_name(paramno,paramname,dz))<0)
  161. return(exit_status);
  162. firsttime = *(dz->brk[paramno]);
  163. if(firsttime < 0.0) {
  164. sprintf(errstr,"First time in %s file is -ve: Can't proceed\n",paramname);
  165. return(DATA_ERROR);
  166. }
  167. if(flteq(firsttime,0.0))
  168. *(dz->brk[paramno]) = 0.0;
  169. else { /* FORCE VALUE AT TIME 0 */
  170. dz->brksize[paramno]++;
  171. if((dz->brk[paramno] = (double *)realloc(dz->brk[paramno],dz->brksize[paramno] * 2 * sizeof(double)))==NULL) {
  172. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter array.\n");
  173. return(MEMORY_ERROR);
  174. }
  175. k = dz->brksize[paramno] * 2;
  176. for(n=k-1;n>=2;n--)
  177. dz->brk[paramno][n] = dz->brk[paramno][n-2];
  178. dz->brk[paramno][0] = 0.0;
  179. dz->brk[paramno][1] = dz->brk[paramno][3];
  180. }
  181. lasttime = *(dz->brk[paramno] + ((dz->brksize[paramno]-1) * 2));
  182. filedur = (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
  183. if(lasttime >= filedur + FLT_TAIL)
  184. return(FINISHED); /* FORCE Q VALUE AT (BEYOND) END OF FILE */
  185. dz->brksize[paramno]++;
  186. if((dz->brk[paramno] = (double *)realloc(dz->brk[paramno],dz->brksize[paramno] * 2 * sizeof(double)))==NULL) {
  187. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate filter array.\n");
  188. return(MEMORY_ERROR);
  189. }
  190. p = (dz->brk[paramno] + ((dz->brksize[paramno]-1) * 2));
  191. *p++ = filedur + FLT_TAIL + 1.0;
  192. *p = *(p-2);
  193. return(FINISHED);
  194. }
  195. /************************************* INITIALISE_FILTER_TABLE_READ *********************************/
  196. void initialise_filter_table_read(int param,dataptr dz)
  197. {
  198. dz->lastind[param] = (double)round((*dz->brk[param]) * dz->infile->srate);
  199. dz->lastval[param] = *(dz->brk[param]+1);
  200. dz->brkptr[param] = dz->brk[param] + 2;
  201. }
  202. /**************************** SETUP_INTERNAL_EQ_PARAMS **********************/
  203. int setup_internal_eq_params(dataptr dz)
  204. {
  205. int exit_status;
  206. dz->param[FLT_ONEFRQ] *= dz->param[FLT_INV_SR];
  207. dz->param[FLT_BW] *= dz->param[FLT_INV_SR];
  208. if((exit_status = setup_stereo_variables(FLT_XX1,FLT_XX2,FLT_YY1,FLT_YY2,dz->infile->channels,dz))<0)
  209. return(exit_status);
  210. return setup_eqfilter_coeffs(dz);
  211. }
  212. /************************************* SETUP_INTERNAL_FSTATVAR_PARAMS *********************************/
  213. int setup_internal_fstatvar_params(dataptr dz)
  214. {
  215. int exit_status;
  216. if(dz->brksize[FLT_Q]==0)
  217. dz->param[FLT_QFAC] = 1.0/(1.0 + dz->param[FLT_Q]);
  218. if(dz->brksize[FLT_Q]) {
  219. if((exit_status = force_start_and_end_val(FLT_Q,dz))<0)
  220. return(exit_status);
  221. initialise_filter_table_read(FLT_Q,dz);
  222. }
  223. if(dz->brksize[FLT_ONEFRQ]) {
  224. if((exit_status = force_start_and_end_val(FLT_ONEFRQ,dz))<0)
  225. return(exit_status);
  226. initialise_filter_table_read(FLT_ONEFRQ,dz);
  227. }
  228. return setup_stereo_variables(FLT_DLS,FLT_DBS,FLT_DHS,FLT_DNS,dz->infile->channels,dz);
  229. }
  230. /************************************* SETUP_INTERNAL_FLTSWEEP_PARAMS *********************************/
  231. int setup_internal_fltsweep_params(dataptr dz)
  232. {
  233. int exit_status;
  234. convert_phase_from_input_range_to_actual_range(dz);
  235. dz->iparam[FLT_LOSAMS] = 0;
  236. dz->iparam[FLT_HISAMS] = 0;
  237. dz->iparam[FLT_SWSAMS] = 0;
  238. dz->param[FLT_CYCPOS] = dz->param[FLT_SWPPHASE];
  239. if(dz->brksize[FLT_Q]==0)
  240. dz->param[FLT_QFAC] = 1.0/(1.0 + dz->param[FLT_Q]);
  241. convert_sfrq(dz);
  242. if(dz->brksize[FLT_LOFRQ]) {
  243. if((exit_status = force_start_and_end_val(FLT_LOFRQ,dz))<0)
  244. return(exit_status);
  245. initialise_filter_table_read(FLT_LOFRQ,dz);
  246. }
  247. if(dz->brksize[FLT_HIFRQ]) {
  248. if((exit_status = force_start_and_end_val(FLT_HIFRQ,dz))<0)
  249. return(exit_status);
  250. initialise_filter_table_read(FLT_HIFRQ,dz);
  251. }
  252. if(dz->brksize[FLT_SWPFRQ]) {
  253. if((exit_status = force_start_and_end_val(FLT_SWPFRQ,dz))<0)
  254. return(exit_status);
  255. initialise_filter_table_read(FLT_SWPFRQ,dz);
  256. }
  257. return setup_stereo_variables(FLT_DLS,FLT_DBS,FLT_DHS,FLT_DNS,dz->infile->channels,dz);
  258. }
  259. /******************** CONVERT_PHASE_FROM_INPUT_RANGE_TO_ACTUAL_RANGE *******************/
  260. void convert_phase_from_input_range_to_actual_range(dataptr dz)
  261. {
  262. dz->param[FLT_SWPPHASE] += .5;
  263. if(dz->param[FLT_SWPPHASE] >= 1.0)
  264. dz->param[FLT_SWPPHASE] -= 1.0;
  265. dz->param[FLT_SWPPHASE] *= TWOPI;
  266. }
  267. /**************************** CONVERT_SFRQ ***************************
  268. *
  269. * (1) frq is in cycles/sec.
  270. * (2) Divide by SR gives what fraction of a cycle we get through in one sample.
  271. * (3) Multiply by FLT_BLOKSIZE, gives what fraction of a cycle we get through in one sample-blok.
  272. * (4) Multiply by TWOPI gives what part of a TWOPI-cycle do we get through in one sample-blok.
  273. */
  274. void convert_sfrq(dataptr dz)
  275. {
  276. double *p, *end;
  277. if(dz->brksize[FLT_SWPFRQ]) {
  278. p = dz->brk[FLT_SWPFRQ] + 1;
  279. end = dz->brk[FLT_SWPFRQ] + (dz->brksize[FLT_SWPFRQ]*2);
  280. while(p<end) {
  281. if(flteq(*p,0.0))
  282. *p = FLT_MINSWEEP; /* prevent divides by zero */
  283. *p *= dz->param[FLT_INV_SR] * dz->iparam[FLT_BLOKSIZE] * TWOPI; /* 1,2,3,4 */
  284. p += 2;
  285. }
  286. } else {
  287. if(flteq(dz->param[FLT_SWPFRQ],0.0))
  288. dz->param[FLT_SWPFRQ] = FLT_MINSWEEP; /* prevent divides by zero */
  289. dz->param[FLT_SWPFRQ] *= dz->param[FLT_INV_SR] * dz->iparam[FLT_BLOKSIZE] * TWOPI;
  290. }
  291. }
  292. /**************************** SETUP_INTERNAL_ALLPASS_PARAMS_AND_DELAYBUFS **********************/
  293. int setup_internal_allpass_params_and_delaybufs(dataptr dz)
  294. {
  295. #define DELAY_SAFETY (64)
  296. int exit_status;
  297. int delbufsize;
  298. dz->iparam[FLT_MAXDELSAMPS] = convert_delay_times_to_samples_and_get_maxdelay(dz);
  299. if(dz->brksize[FLT_DELAY])
  300. dz->iparam[FLT_MAXDELSAMPS] += DELAY_SAFETY;
  301. delbufsize = dz->iparam[FLT_MAXDELSAMPS] * dz->infile->channels * sizeof(double);
  302. /*RWD 9:2001 need calloc */
  303. if((dz->parray[FLT_DELBUF1] = (double *)calloc((size_t)delbufsize,sizeof(char)))==NULL) {
  304. sprintf(errstr,"INSUFFICIENT MEMORY for 1st delay buffer.\n");
  305. return(MEMORY_ERROR);
  306. }
  307. if((dz->parray[FLT_DELBUF2] = (double *)calloc((size_t)delbufsize,sizeof(char)))==NULL) {
  308. sprintf(errstr,"INSUFFICIENT MEMORY for 2nd delay buffer.\n");
  309. return(MEMORY_ERROR);
  310. }
  311. dz->iparam[FLT_DELBUFPOS] = 0;
  312. if(dz->brksize[FLT_DELAY]) {
  313. if((exit_status = force_start_and_end_val(FLT_DELAY,dz))<0)
  314. return(exit_status);
  315. initialise_filter_table_read(FLT_DELAY,dz);
  316. }
  317. return(FINISHED);
  318. }
  319. /************************************* SETUP_INTERNAL_FLTBANKN_PARAMS *********************************/
  320. int setup_internal_fltbankn_params(dataptr dz)
  321. {
  322. int exit_status;
  323. double temp;
  324. switch(dz->mode) {
  325. case(FLT_EQUALINT): dz->param[FLT_INTSIZE] = pow(SEMITONE_INTERVAL,dz->param[FLT_INTSIZE]); break;
  326. case(FLT_HARMONIC): dz->param[FLT_OFFSET] = 0.0; break;
  327. }
  328. if(dz->param[FLT_LOFRQ] > dz->param[FLT_HIFRQ]) { /* correct inverted frq range */
  329. temp = dz->param[FLT_LOFRQ];
  330. dz->param[FLT_LOFRQ] = dz->param[FLT_HIFRQ];
  331. dz->param[FLT_HIFRQ] = temp;
  332. }
  333. if((exit_status = count_filters(dz))<0)
  334. return(exit_status);
  335. return allocate_filter_frq_amp_arrays(dz->iparam[FLT_CNT],dz);
  336. }
  337. /************************************* SETUP_INTERNAL_ITERFILT_PARAMS *********************************/
  338. void setup_internal_iterfilt_params(dataptr dz)
  339. {
  340. int srate = dz->infile->srate;
  341. int chans = dz->infile->channels;
  342. dz->iparam[FLT_OUTDUR] = max(round(dz->param[FLT_OUTDUR] * (double)(srate * chans)),dz->insams[0]);
  343. dz->iparam[FLT_MSAMPDEL] = round(dz->param[FLT_DELAY] * (double)srate);
  344. dz->iparam[FLT_SMPDEL] = dz->iparam[FLT_MSAMPDEL] * chans;
  345. dz->iparam[FLT_INMSAMPSIZE] = dz->insams[0]/chans;
  346. if(flteq(dz->param[FLT_PRESCALE],0.0)) { /* set default prescaling of input */
  347. dz->iparam[FLT_MAXOVERLAY] = round(((double)dz->iparam[FLT_INMSAMPSIZE]/(double)dz->iparam[FLT_MSAMPDEL])+1.0);
  348. if(dz->param[FLT_RANDDEL] > 0.0)
  349. dz->iparam[FLT_MAXOVERLAY]++;
  350. dz->param[FLT_PRESCALE] = 1.0/(double)dz->iparam[FLT_MAXOVERLAY];
  351. }
  352. dz->param[FLT_PSHIFT] /= SEMITONES_PER_OCTAVE; /* convert semitones to fractions of 8vas */
  353. set_doflag(dz);
  354. }
  355. /************************** SET_DOFLAG ********************************/
  356. void set_doflag(dataptr dz)
  357. {
  358. if(dz->param[FLT_PSHIFT]>0.0) {
  359. if(dz->vflag[FLT_PINTERP_OFF]) {
  360. if(dz->infile->channels>1)
  361. dz->iparam[FLT_DOFLAG] = ST_SHIFT;
  362. else
  363. dz->iparam[FLT_DOFLAG] = MN_SHIFT;
  364. } else {
  365. if(dz->infile->channels>1)
  366. dz->iparam[FLT_DOFLAG] = ST_FLT_INTP_SHIFT;
  367. else
  368. dz->iparam[FLT_DOFLAG] = MN_FLT_INTP_SHIFT;
  369. }
  370. } else {
  371. if(dz->infile->channels>1)
  372. dz->iparam[FLT_DOFLAG] = ITER_STEREO;
  373. else
  374. dz->iparam[FLT_DOFLAG] = ITER_MONO;
  375. }
  376. if(flteq(dz->param[FLT_AMPSHIFT],0.0))
  377. dz->iparam[FLT_DOFLAG] += FIXED_AMP;
  378. /* ??? */
  379. if(dz->iparam[FLT_MSAMPDEL] >= dz->iparam[FLT_INMSAMPSIZE])
  380. dz->vflag[FLT_EXPDEC] = 0;
  381. /* ??? */
  382. }
  383. /**************************** ALLOCATE_TVARYING_FILTER_ARRAYS *******************************/
  384. int allocate_tvarying_filter_arrays(int timeslot_cnt,int harmonics_cnt,dataptr dz)
  385. {
  386. dz->iparam[FLT_CNT] *= harmonics_cnt;
  387. if((dz->lparray[FLT_SAMPTIME] = (int *)calloc(timeslot_cnt * sizeof(int),sizeof(char)))==NULL
  388. || (dz->parray[FLT_INFRQ] = (double *)calloc(dz->iparam[FLT_CNT] * timeslot_cnt * sizeof(double),sizeof(char)))==NULL
  389. || (dz->parray[FLT_INAMP] = (double *)calloc(dz->iparam[FLT_CNT] * timeslot_cnt * sizeof(double),sizeof(char)))==NULL
  390. || (dz->parray[FLT_FINCR] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
  391. || (dz->parray[FLT_AINCR] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
  392. || (dz->parray[FLT_LASTFVAL] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL
  393. || (dz->parray[FLT_LASTAVAL] = (double *)calloc(dz->iparam[FLT_CNT] * sizeof(double),sizeof(char)))==NULL) {
  394. sprintf(errstr,"INSUFFICIENT MEMORY for filter coefficients.\n");
  395. return(MEMORY_ERROR);
  396. }
  397. return(FINISHED);
  398. }
  399. /**************************** ALLOCATE_TVARYING2_FILTER_ARRAYS *******************************/
  400. int allocate_tvarying2_filter_arrays(dataptr dz)
  401. {
  402. if((dz->parray[FLT_INFRQ] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
  403. || (dz->parray[FLT_INAMP] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
  404. || (dz->parray[FLT_FINCR] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
  405. || (dz->parray[FLT_AINCR] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
  406. || (dz->parray[FLT_LASTFVAL] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL
  407. || (dz->parray[FLT_LASTAVAL] = (double *)malloc(dz->iparam[FLT_CNT] * sizeof(double)))==NULL) {
  408. sprintf(errstr,"INSUFFICIENT MEMORY for filter coefficients.\n");
  409. return(MEMORY_ERROR);
  410. }
  411. return(FINISHED);
  412. }
  413. /**************************** PUT_TVARYING_FILTER_DATA_IN_ARRAYS *******************************/
  414. int put_tvarying_filter_data_in_arrays(double *fbrk,dataptr dz)
  415. {
  416. int timescnt = 0, freqcnt = 0, ampcnt = 0, n, m;
  417. double atten;
  418. int total_frq_cnt = dz->iparam[FLT_CNT] * dz->iparam[FLT_TIMESLOTS];
  419. int entrycnt = dz->iparam[FLT_ENTRYCNT];
  420. int wordcnt = dz->iparam[FLT_WORDCNT];
  421. int j;
  422. int srate = dz->infile->srate;
  423. if(dz->parray[FLT_INFRQ]==NULL) {
  424. sprintf(errstr,"FLT_INFRQ array not established: put_tvarying_filter_data_in_arrays()\n");
  425. return(PROGRAM_ERROR);
  426. }
  427. if(dz->parray[FLT_INAMP]==NULL) {
  428. sprintf(errstr,"FLT_INAMP array not established: put_tvarying_filter_data_in_arrays()\n");
  429. return(PROGRAM_ERROR);
  430. }
  431. if(dz->lparray[FLT_SAMPTIME]==NULL) {
  432. sprintf(errstr,"FLT_SAMPTIME array not established: put_tvarying_filter_data_in_arrays()\n");
  433. return(PROGRAM_ERROR);
  434. }
  435. for(n=0;n<wordcnt;n++) {
  436. m = n%entrycnt;
  437. if(m==0) {
  438. if(timescnt >= dz->iparam[FLT_TIMESLOTS]) {
  439. sprintf(errstr,"Error 0 in filter counting: put_tvarying_filter_data_in_arrays()\n");
  440. return(PROGRAM_ERROR);
  441. }
  442. dz->lparray[FLT_SAMPTIME][timescnt++] = round(fbrk[n] * dz->infile->srate);
  443. } else if(ODD(m)) {
  444. for(j=1;j<=dz->iparam[FLT_HARMCNT];j++) {
  445. if(freqcnt >= total_frq_cnt) {
  446. sprintf(errstr,"Error 1 in filter counting: put_tvarying_filter_data_in_arrays()\n");
  447. return(PROGRAM_ERROR);
  448. }
  449. if((dz->parray[FLT_INFRQ][freqcnt] = fbrk[n] * (double)j) > FLT_MAXFRQ) {
  450. sprintf(errstr,"Filter Harmonic %d of %.1lfHz = %.1lfHz beyond filter limit %.1lf.\n",
  451. j,fbrk[n],dz->parray[FLT_INFRQ][freqcnt],FLT_MAXFRQ);
  452. return(DATA_ERROR);
  453. }
  454. freqcnt++;
  455. }
  456. } else {
  457. atten = 1.0;
  458. for(j=1;j<=dz->iparam[FLT_HARMCNT];j++) {
  459. if(ampcnt >= total_frq_cnt) {
  460. sprintf(errstr,"Error 2 in filter counting: put_tvarying_filter_data_in_arrays()\n");
  461. return(PROGRAM_ERROR);
  462. }
  463. dz->parray[FLT_INAMP][ampcnt] = fbrk[n] * atten;
  464. ampcnt++;
  465. atten *= dz->param[FLT_ROLLOFF];
  466. }
  467. }
  468. }
  469. if(freqcnt != total_frq_cnt || ampcnt != freqcnt || timescnt != dz->iparam[FLT_TIMESLOTS]) {
  470. sprintf(errstr,"Filter data accounting problem: read_time_varying_filter_data()\n");
  471. return(PROGRAM_ERROR);
  472. }
  473. return(FINISHED);
  474. }
  475. /**************************** INITALISE_FLTBANKV_INTERNAL_PARAMS **********************/
  476. int initialise_fltbankv_internal_params(dataptr dz)
  477. {
  478. int exit_status;
  479. int n;
  480. if((exit_status = allocate_filter_frq_amp_arrays(dz->iparam[FLT_CNT],dz))<0)
  481. return(exit_status);
  482. for(n = 0;n<dz->iparam[FLT_CNT];n++) {
  483. dz->parray[FLT_FRQ][n] = dz->parray[FLT_INFRQ][n];
  484. dz->parray[FLT_AMP][n] = dz->parray[FLT_INAMP][n];
  485. dz->parray[FLT_LASTFVAL][n] = dz->parray[FLT_FRQ][n];
  486. dz->parray[FLT_LASTAVAL][n] = dz->parray[FLT_AMP][n];
  487. }
  488. dz->iparam[FLT_FRQ_INDEX] = dz->iparam[FLT_CNT];
  489. dz->iparam[FLT_TIMES_CNT] = 1;
  490. return(FINISHED);
  491. }
  492. /*************************************** ERROR_NAME **************************************/
  493. int error_name(int paramno,char *paramname,dataptr dz)
  494. {
  495. switch(dz->process) {
  496. case(FLTSWEEP):
  497. switch(paramno) {
  498. case(FLT_LOFRQ): strcpy(paramname,"lofrq"); break;
  499. case(FLT_HIFRQ): strcpy(paramname,"hifrq"); break;
  500. case(FLT_SWPFRQ): strcpy(paramname,"sweepfrq"); break;
  501. case(FLT_Q): strcpy(paramname,"Q"); break;
  502. default:
  503. sprintf(errstr,"Invalid case in error_name()\n");
  504. return(PROGRAM_ERROR);
  505. }
  506. break;
  507. case(FLTBANKN):
  508. case(FLTBANKU):
  509. case(FLTBANKV):
  510. case(FLTBANKV2):
  511. switch(paramno) {
  512. case(FLT_Q): strcpy(paramname,"Q"); break;
  513. default:
  514. sprintf(errstr,"Invalid case in error_name()\n");
  515. return(PROGRAM_ERROR);
  516. }
  517. break;
  518. case(FLTITER):
  519. case(ALLPASS):
  520. switch(paramno) {
  521. case(FLT_DELAY): strcpy(paramname,"delay"); break;
  522. default:
  523. sprintf(errstr,"Invalid case in error_name()\n");
  524. return(PROGRAM_ERROR);
  525. }
  526. break;
  527. case(FSTATVAR):
  528. switch(paramno) {
  529. case(FLT_Q): strcpy(paramname,"Q"); break;
  530. case(FLT_ONEFRQ): strcpy(paramname,"frq"); break;
  531. default:
  532. sprintf(errstr,"Invalid case in error_name()\n");
  533. return(PROGRAM_ERROR);
  534. }
  535. break;
  536. default:
  537. sprintf(errstr,"Invalid case in error_name()\n");
  538. return(PROGRAM_ERROR);
  539. }
  540. return(FINISHED);
  541. }
  542. /*************************** SETUP_STEREO_VARIABLES ************************/
  543. int setup_stereo_variables(int a,int b,int c,int d,int chans,dataptr dz)
  544. {
  545. int n;
  546. if((dz->parray[a] = (double *)calloc(chans * sizeof(double),sizeof(char)))==NULL
  547. || (dz->parray[b] = (double *)calloc(chans * sizeof(double),sizeof(char)))==NULL
  548. || (dz->parray[c] = (double *)calloc(chans * sizeof(double),sizeof(char)))==NULL
  549. || (dz->parray[d] = (double *)calloc(chans * sizeof(double),sizeof(char)))==NULL) {
  550. sprintf(errstr,"INSUFFICIENT MEMORY for stereo coefficients.\n");
  551. return(MEMORY_ERROR);
  552. }
  553. for(n=0;n<chans;n++) {
  554. dz->parray[a][n] = 0.0;
  555. dz->parray[b][n] = 0.0;
  556. dz->parray[c][n] = 0.0;
  557. dz->parray[d][n] = 0.0;
  558. }
  559. return(FINISHED);
  560. }
  561. /******************************* SETUP_EQFILTER_COEFFS ******************************/
  562. int setup_eqfilter_coeffs(dataptr dz)
  563. {
  564. switch(dz->mode) {
  565. case(FLT_LOSHELF):
  566. case(FLT_HISHELF):
  567. shelve(dz->param[FLT_ONEFRQ],dz->param[FLT_BOOST],
  568. &(dz->param[FLT_A0]),&(dz->param[FLT_A1]),&(dz->param[FLT_A2]),
  569. &(dz->param[FLT_B1]),&(dz->param[FLT_B2]),dz->mode);
  570. break;
  571. case(FLT_PEAKING):
  572. presence(dz->param[FLT_ONEFRQ],dz->param[FLT_BOOST],dz->param[FLT_BW],
  573. &(dz->param[FLT_A0]),&(dz->param[FLT_A1]),&(dz->param[FLT_A2]),
  574. &(dz->param[FLT_B1]),&(dz->param[FLT_B2]));
  575. break;
  576. default:
  577. sprintf(errstr,"Unknown mode: setup_eqfilter_coeffs()\n");
  578. return(PROGRAM_ERROR);
  579. }
  580. return(FINISHED);
  581. }
  582. /* ANDY MOORER routines, rationalised slightly */
  583. /* Design programs for 2nd-order presence and shelving filters */
  584. #define PII (3.141592653589793238462643)
  585. #define ROOT2OF2 (0.7071067811965475244) /* = sqrt(2)/2 */
  586. #define SPN 1.65436e-24 /* Smallest possible number on DEC VAX-780: but it will work here */
  587. /* ----------------------------------------------------------------------------
  588. PRESENCE - Design straightforward 2nd-order presence filter.
  589. Must be given (normalised) centre frequency, bandwidth and boost/cut in dB.
  590. Returns filter of form:
  591. -1 -2
  592. A0 + A1 Z + A2 Z
  593. T(z) = ---------------------
  594. -1 -2
  595. 1 + B1 Z + B2 Z
  596. --------------------------------------------------------------------------- */
  597. void presence(double cf,double boost,double bw,double *a0,double *a1,double *a2,double *b1,double *b2)
  598. {
  599. double a, A, F, xfmbw, C, tmp, alphan, alphad, b0, recipb0, asq, F2, a2plus1, ma2plus1;
  600. establish_a_asq_A_F_F2_tmp(cf,boost,&a,&asq,&A,&F,&F2,&tmp);
  601. xfmbw = bw2angle(a, bw);
  602. C = 1.0 / tan(2 * PII * xfmbw); /* Co-tangent of angle */
  603. if(fabs(tmp) <= SPN)
  604. alphad = C;
  605. else {
  606. alphad = (C * C * (F2 - 1))/tmp;
  607. alphad = sqrt(alphad);
  608. }
  609. alphan = A * alphad;
  610. a2plus1 = 1 + asq;
  611. ma2plus1 = 1 - asq;
  612. *a0 = a2plus1 + alphan * ma2plus1;
  613. *a1 = 4 * a;
  614. *a2 = a2plus1 - alphan * ma2plus1;
  615. b0 = a2plus1 + alphad * ma2plus1;
  616. *b2 = a2plus1 - alphad * ma2plus1;
  617. recipb0 = 1.0/b0;
  618. *a0 *= recipb0;
  619. *a1 *= recipb0;
  620. *a2 *= recipb0;
  621. *b1 = *a1; /* is this correct ?? */
  622. *b2 *= recipb0;
  623. }
  624. /* -------------------------------------------------------------------------
  625. SHELVE - Design straightforward 2nd-order shelving filter.
  626. Must be given (normalised) centre frequency, bandwidth and boost/cut in dB.
  627. This is a LOW shelving filter, in that the response at z = -1 will be 1.0.
  628. Returns filter of form:
  629. -1 -2
  630. A0 + A1 Z + A2 Z
  631. T(z) = --------------------- ANDY MOORER
  632. -1 -2
  633. 1 + B1 Z + B2 Z
  634. --------------------------------------------------------------------------- */
  635. void shelve(double cf,double boost,double *a0,double *a1,double *a2,double *b1,double *b2,int mode)
  636. {
  637. double a, A, F, tmp, b0, asq, F2, gamman, gammad, ta0, ta1, ta2, tb0, tb1, tb2;
  638. establish_a_asq_A_F_F2_tmp(cf,boost,&a,&asq,&A,&F,&F2,&tmp);
  639. if(fabs(tmp) <= SPN)
  640. gammad = 1.0;
  641. /* NB: CHANGED FROM THE ORIGINAL *
  642. else
  643. gammad = pow((F2 - 1.0)/tmp,0.25);
  644. AS THIS GAVE A -VE RESULT: SOME KIND OF AIRTHMETIC ERROR INSIDE pow */
  645. else {
  646. gammad = (F2 - 1.0)/tmp;
  647. gammad = pow(gammad,0.25); /* Fourth root */
  648. }
  649. gamman = sqrt(A) * gammad;
  650. /* Once for the numerator */
  651. set_the_tvars(gamman,&ta0,&ta1,&ta2);
  652. if(mode==FLT_HISHELF)
  653. ta1 = -ta1;
  654. /* And again for the denominator */
  655. set_the_tvars(gammad,&tb0,&tb1,&tb2);
  656. if(mode==FLT_HISHELF)
  657. tb1 = -tb1;
  658. /* Now bilinear transform to proper centre frequency */
  659. bilinear_transform(a,ta0,ta1,ta2,asq,a0,a1,a2);
  660. bilinear_transform(a,tb0,tb1,tb2,asq,&b0,b1,b2);
  661. /* Normalise b0 to 1.0 for realisability */
  662. normalise_b0_to_one(b0,a0,a1,a2,b1,b2);
  663. }
  664. /* -------------------------------------------------------------------------
  665. BW2ANGLE - Given bilinear transform parameter and
  666. desired bandwidth (as normalised frequency), computes bandedge, e, of filter
  667. as if it were centred at the frequency .25 (or pi/2, or srate/4). The
  668. bandwidth would then 2*(.25-e). e is guaranteed to be between 0 and .25.
  669. To state it differently, given a filter centered on .25 with low bandedge
  670. e and high bandedge .5-e, the bilinear transform by a
  671. will produce a new filter with bandwidth (i.e., difference between the
  672. high bandedge frequency and low bandedge frequency) of bw ANDY MOORER
  673. ------------------------------------------------------------------------- */
  674. double bw2angle(double a,double bw)
  675. {
  676. double T, d, sn, cs, mag, delta, theta, tmp, a2, a4, asnd;
  677. T = tan(2*PII*bw);
  678. a2 = a * a;
  679. a4 = a2 * a2;
  680. d = 2 * a2 * T;
  681. sn = (1 + a4) * T;
  682. cs = (1 - a4);
  683. mag = sqrt((sn * sn) + (cs * cs));
  684. d /= mag;
  685. delta = atan2(sn, cs);
  686. asnd = asin(d);
  687. theta = 0.5 * (PII - asnd - delta); /* Bandedge for prototype */
  688. tmp = 0.5 * (asnd - delta); /* Take principal branch */
  689. if(tmp > 0 && tmp < theta)
  690. theta = tmp;
  691. return(theta /(2 * PII)); /* Return normalised frequency */
  692. }
  693. /********************************* ESTABLISH_A_ASQ_A_F *********************************/
  694. void establish_a_asq_A_F_F2_tmp(double cf,double boost,double *a,double *asq,double *A,double *F,double *F2,double *tmp)
  695. {
  696. double sqrt2 = sqrt(2.0);
  697. double cf_less_quarter = cf - 0.25;
  698. double b_over20 = boost/20.0;
  699. *a = tan(PII * cf_less_quarter); /* Warp factor */
  700. *asq = (*a) * (*a);
  701. *A = pow(10.0, b_over20); /* Cvt dB to factor */
  702. if(boost < 6.0 && boost > -6.0)
  703. *F = sqrt(*A);
  704. else if(*A > 1.0)
  705. *F = *A/sqrt2;
  706. else
  707. *F = (*A) * sqrt2;
  708. /* If |boost/cut| < 6dB, then doesn't make sense to use 3dB point.
  709. Use of root makes bandedge at half the boost/cut amount
  710. */
  711. *F2 = (*F) * (*F);
  712. *tmp = ((*A) * (*A)) - (*F2);
  713. }
  714. /********************************* SET_THE_TVARS *********************************/
  715. void set_the_tvars(double gamma,double *t0,double *t1,double *t2)
  716. {
  717. double gamma2, gam2p1, siggam2;
  718. gamma2 = gamma * gamma;
  719. gam2p1 = 1.0 + gamma2;
  720. siggam2 = 2.0 * ROOT2OF2 * gamma;
  721. *t0 = gam2p1 + siggam2;
  722. *t1 = -2.0 * (1.0 - gamma2);
  723. *t2 = gam2p1 - siggam2;
  724. }
  725. /********************************* BILINEAR_TRANSFORM *********************************/
  726. void bilinear_transform(double a,double t0,double t1,double t2,double asq,double *x0,double *x1,double *x2)
  727. {
  728. double aa1;
  729. aa1 = a * t1;
  730. *x0 = t0 + aa1 + (asq * t2);
  731. *x1 = (2 * a * (t0 + t2)) + ((1 + asq) * t1);
  732. *x2 = (asq * t0) + aa1 + t2;
  733. }
  734. /********************************* NORMALISE_B0_TO_ONE *********************************/
  735. void normalise_b0_to_one(double b0,double *a0,double *a1,double *a2,double *b1,double *b2)
  736. {
  737. double recipb0 = 1.0/b0;
  738. *a0 *= recipb0;
  739. *a1 *= recipb0;
  740. *a2 *= recipb0;
  741. *b1 *= recipb0;
  742. *b2 *= recipb0;
  743. }
  744. /******************* CONVERT_DELAY_TIMES_TO_SAMPLES_AND_GET_MAXDELAY *******************/
  745. int convert_delay_times_to_samples_and_get_maxdelay(dataptr dz)
  746. {
  747. double *p, *end;
  748. double maxdelay = 0.0;
  749. if(dz->brksize[FLT_DELAY]) {
  750. p = dz->brk[FLT_DELAY] + 1;
  751. end = dz->brk[FLT_DELAY] + (dz->brksize[FLT_DELAY] * 2);
  752. while(p < end) {
  753. if((*p = (double)round(*p * MS_TO_SECS * (double)dz->infile->srate))<1)
  754. *p = 1.0;
  755. maxdelay = max(*p,maxdelay);
  756. p+= 2;
  757. }
  758. return(round(maxdelay));
  759. }
  760. if((dz->param[FLT_DELAY] = (double)round(dz->param[FLT_DELAY] * MS_TO_SECS * (double)dz->infile->srate))<1)
  761. dz->param[FLT_DELAY] = 1.0;
  762. return(round(dz->param[FLT_DELAY]));
  763. }
  764. /************************** COUNT_FILTERS ****************************/
  765. int count_filters(dataptr dz)
  766. {
  767. int f_cnt = 0;
  768. double thisfrq;
  769. switch(dz->mode) {
  770. case(FLT_EQUALSPAN):
  771. f_cnt = dz->iparam[FLT_INCOUNT];
  772. break;
  773. case(FLT_EQUALINT):
  774. thisfrq = dz->param[FLT_LOFRQ];
  775. while(thisfrq < dz->param[FLT_HIFRQ]) {
  776. f_cnt++;
  777. thisfrq *= dz->param[FLT_INTSIZE];
  778. }
  779. break;
  780. case(FLT_HARMONIC): /* offset = 0.0 */
  781. case(FLT_LINOFFSET):
  782. thisfrq = dz->param[FLT_LOFRQ];
  783. while((thisfrq+dz->param[FLT_OFFSET]) < dz->param[FLT_HIFRQ]) {
  784. f_cnt++;
  785. thisfrq = dz->param[FLT_LOFRQ] * (double)(f_cnt+1);
  786. }
  787. break;
  788. case(FLT_ALTERNATE):
  789. thisfrq = dz->param[FLT_LOFRQ];
  790. while(thisfrq < dz->param[FLT_HIFRQ]) {
  791. f_cnt++;
  792. thisfrq = dz->param[FLT_LOFRQ] * (double)((f_cnt*2)+1);
  793. }
  794. break;
  795. case(FLT_SUBHARM):
  796. thisfrq = dz->param[FLT_HIFRQ];
  797. while(thisfrq > dz->param[FLT_LOFRQ]) {
  798. f_cnt++;
  799. thisfrq = dz->param[FLT_HIFRQ]/(double)(f_cnt+1);
  800. }
  801. break;
  802. }
  803. if(f_cnt > FLT_MAX_FILTERS || f_cnt < 0) {
  804. sprintf(errstr,"Too many filters [%d]: max %d\n",f_cnt,FLT_MAX_FILTERS);
  805. return(DATA_ERROR);
  806. }
  807. if(f_cnt < 1) {
  808. sprintf(errstr,"Too few filters in range specified.\n");
  809. return(DATA_ERROR);
  810. }
  811. dz->iparam[FLT_CNT] = (int)f_cnt;
  812. return(f_cnt);
  813. }
  814. /**************************** TEST_PITCH_AND_SPECTRUM_VARYING_FILTERDATA *******************************/
  815. int test_pitch_and_spectrum_varying_filterdata(double *fbrk,double *hbrk,dataptr dz)
  816. {
  817. int n, m, k, timepoint, htimepoint, nextrow;
  818. int entrycnt = dz->iparam[FLT_ENTRYCNT];
  819. int wordcnt = dz->iparam[FLT_WORDCNT];
  820. int hentrycnt = dz->iparam[HRM_ENTRYCNT];
  821. int hwordcnt = dz->iparam[HRM_WORDCNT];
  822. int srate = dz->infile->srate;
  823. double thistime, lotime, hitime, timefrac, valdiff;
  824. double timestep = (double)dz->iparam[FLT_BLOKSIZE]/(double)dz->infile->srate;
  825. double lasttime = fbrk[wordcnt - entrycnt];
  826. lasttime = min(lasttime,hbrk[hwordcnt - hentrycnt]);
  827. dz->iparam[FLT_BLOKCNT] = dz->iparam[FLT_BLOKSIZE] * dz->infile->channels;
  828. timepoint = 0;
  829. htimepoint = 0;
  830. fprintf(stdout,"INFO: TESTING PITCH AND HARMONICS DATA.\n");
  831. fflush(stdout);
  832. if((dz->parray[HARM_FRQ_CALC] = (double *)malloc(dz->iparam[FLT_HARMCNT] * sizeof(double)))==NULL) {
  833. sprintf(errstr,"OUT OF MEMORY TO STORE HARMONIC SHIFT DATA\n");
  834. return(MEMORY_ERROR);
  835. }
  836. if((dz->parray[HARM_AMP_CALC] = (double *)malloc(dz->iparam[FLT_HARMCNT] * sizeof(double)))==NULL) {
  837. sprintf(errstr,"OUT OF MEMORY TO STORE HARMONICS AMPLITUDE ADJUST DATA\n");
  838. return(MEMORY_ERROR);
  839. }
  840. memset((char *)dz->parray[FLT_INFRQ],0,dz->iparam[FLT_CNT] * sizeof(double));
  841. for(thistime = 0.0; thistime < lasttime;thistime += timestep) {
  842. timepoint = 0;
  843. while(thistime >= fbrk[timepoint]) { /* search times in frq array */
  844. if((timepoint += entrycnt) >= wordcnt)
  845. break;
  846. }
  847. timepoint -= entrycnt;
  848. lotime = fbrk[timepoint];
  849. nextrow = timepoint + entrycnt;
  850. for(n = timepoint+1,k = 0; n < nextrow;n+=2,k += dz->iparam[FLT_HARMCNT])
  851. dz->parray[FLT_INFRQ][k] = fbrk[n]; /* Get frqs of fundamentals into array, leaving space for harmonics */
  852. if(nextrow != wordcnt) { /* if not at end of table, do interpolation */
  853. nextrow += entrycnt;
  854. timepoint += entrycnt;
  855. hitime = fbrk[timepoint];
  856. timefrac = (thistime - lotime)/(hitime - lotime);
  857. k = 0;
  858. for(n = timepoint+1,k=0; n < nextrow;n+=2,k += dz->iparam[FLT_HARMCNT]) {
  859. valdiff = fbrk[n] - dz->parray[FLT_INFRQ][k];
  860. valdiff *= timefrac;
  861. dz->parray[FLT_INFRQ][k] = dz->parray[FLT_INFRQ][k] + valdiff;
  862. }
  863. }
  864. htimepoint = 0;
  865. while(thistime >= hbrk[htimepoint]) { /* search times in frq array */
  866. if((htimepoint += hentrycnt) >= hwordcnt)
  867. break;
  868. }
  869. htimepoint -= hentrycnt;
  870. lotime = hbrk[htimepoint];
  871. nextrow = htimepoint + hentrycnt;
  872. k = 0;
  873. for(n = htimepoint+1,k=0; n < nextrow;n+=2,k++)
  874. dz->parray[HARM_FRQ_CALC][k] = hbrk[n];
  875. if(nextrow != hwordcnt) { /* if not at end of table, do interpolation */
  876. nextrow += hentrycnt;
  877. htimepoint += hentrycnt;
  878. hitime = hbrk[htimepoint];
  879. timefrac = (thistime - lotime)/(hitime - lotime);
  880. k = 0;
  881. for(n = htimepoint+1,k=0; n < nextrow;n+=2,k++) {
  882. /* PARTIAL MULTIPLIER */
  883. valdiff = hbrk[n] - dz->parray[HARM_FRQ_CALC][k];
  884. valdiff *= timefrac;
  885. dz->parray[HARM_FRQ_CALC][k] = dz->parray[HARM_FRQ_CALC][k] + valdiff;
  886. /* PARTIAL AMP */
  887. }
  888. }
  889. for(k=0;k<dz->iparam[FLT_CNT];k+=dz->iparam[FLT_HARMCNT]) {
  890. for(m=0; m < dz->iparam[FLT_HARMCNT];m++) { /* calc vals for partials from basefrq vals */
  891. if((dz->parray[FLT_INFRQ][k+m] = dz->parray[FLT_INFRQ][k] * dz->parray[HARM_FRQ_CALC][m]) > FLT_MAXFRQ) {
  892. sprintf(errstr,"PARTIAL NO %lf TOO HIGH (Frq %lf Root %lf) AT TIME %lf\n",
  893. dz->parray[HARM_FRQ_CALC][m],dz->parray[FLT_INFRQ][k+m],dz->parray[FLT_INFRQ][k]/dz->parray[HARM_FRQ_CALC][0],thistime);
  894. return(DATA_ERROR);
  895. }
  896. }
  897. }
  898. }
  899. fprintf(stdout,"INFO: FINISHED TESTING PITCH AND HARMONICS DATA.\n");
  900. fflush(stdout);
  901. return(FINISHED);
  902. }