hilite.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593
  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. /* floatsam version TW */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <globcon.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <arrays.h>
  31. #include <flags.h>
  32. #include <highlight.h>
  33. #include <cdpmain.h>
  34. #include <formants.h>
  35. #include <speccon.h>
  36. #include <sfsys.h>
  37. #include <osbind.h>
  38. #include <highlight.h>
  39. //TW UPDATE
  40. #include <vowels.h>
  41. #if defined unix || defined __GNUC__
  42. #define round(x) lround((x))
  43. #endif
  44. static int do_filtering(double frq_limit,double hifrq_limit,dataptr dz);
  45. static int below_limitfrq_and_zeroed(int vc,double loskirt,dataptr dz);
  46. static int below_limitfrq_and_filtered(int vc,double limitfrq,double loskirt,double loskirt_bwidth,dataptr dz);
  47. static int above_limitfrq_and_zeroed(int vc,double hiskirt,dataptr dz);
  48. static int filter_above_limitfrq(int vc,double limitfrq,double hiskirt,double hiskirt_bwidth,dataptr dz);
  49. static int filtered_in_lower_skirt(int vc,double skirttop,double loskirt,double loskirt_bwidth,dataptr dz);
  50. static int filtered_in_upper_skirt(int vc,double skirt_bottom,double hiskirt,double hiskirt_bwidth,dataptr dz);
  51. static int do_greq_filter(dataptr dz);
  52. static int invert_greq_filter_envelope(dataptr dz);
  53. static int process_specsplit_channel(int cc,bandptr bb,dataptr dz);
  54. static int do_on(double bandhilimit,double bandlolimit,dataptr dz);
  55. static int do_below(double bandmid,dataptr dz);
  56. static int do_above(double bandmid,dataptr dz);
  57. static int do_boost(double bandhilimit,double bandlolimit,dataptr dz);
  58. static int do_above_boost(double bandhilimit,double bandlolimit,int *in_start_portion, dataptr dz);
  59. static int do_below_boost(double bandhilimit,double bandlolimit,int *in_start_portion,dataptr dz);
  60. static int do_once_below(double bandlolimit,int *in_start_portion,dataptr dz);
  61. static int do_once_above(double bandhilimit,int *in_start_portion,dataptr dz);
  62. static int initiate_new_arpeg_note(int cc,int vc,dataptr dz);
  63. static int initiate_new_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz);
  64. static int temporarily_sustain_arpeg_note(int cc,double thisamp,dataptr dz);
  65. static int temporarily_sustain_arpeg_note_with_fixed_pitch(int cc,int vc,double thisamp,dataptr dz);
  66. static int get_non_linear_decimation(double *nonlin_dec,int cc,dataptr dz);
  67. static int get_decimation(double *dec,int cc,dataptr dz);
  68. static int sustain_arpeg_note(int cc,int vc,dataptr dz);
  69. static int sustain_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz);
  70. static int nonlin_sustain_arpeg_note(int cc,int vc, dataptr dz);
  71. static int nonlin_sustain_arpeg_note_with_fixed_pitch(int cc, int vc, dataptr dz);
  72. static int set_bit_to_zero(int bflagno,int mask,dataptr dz);
  73. static int set_bit_to_one(int bflagno,int mask,dataptr dz);
  74. static int outside_skirts(int vc,double loskirt,double hiskirt,dataptr dz);
  75. static int reset_timechanging_arpe_variables(double *frqrange,double *lofrq, double *hifrq,dataptr dz);
  76. static int locate_current_wavetable_position(dataptr dz);
  77. //TW UPDATE
  78. static int do_vowel_filter(double *vamp,double formant1,double formant2,double formant3,double f2atten,double f3atten,
  79. double *sensitivity,int senslen,dataptr dz);
  80. static int get_formant_frqs
  81. (int vowel,double *formant1, double *formant2, double *formant3, double *f2atten, double *f3atten);
  82. static int define_sensitivity_curve(double **sensitivity,int *senslen);
  83. static int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen);
  84. /**************************** SPECFILT ***************************/
  85. int specfilt(dataptr dz)
  86. {
  87. int exit_status;
  88. int vc;
  89. double frq_limit, hifrq_limit = 0.0, pre_amptotal, post_amptotal;
  90. if(dz->brksize[FILT_QQ])
  91. dz->param[FILT_QQ] = exp(dz->param[FILT_QQ]);
  92. if(dz->brksize[FILT_FRQ1])
  93. frq_limit = exp(dz->param[FILT_FRQ1]);
  94. else
  95. frq_limit = dz->param[FILT_FRQ1];
  96. switch(dz->mode) {
  97. case(F_BND):
  98. case(F_BND_NORM):
  99. case(F_NOTCH):
  100. case(F_NOTCH_NORM):
  101. case(F_BAND_GAIN):
  102. case(F_NOTCH_GAIN):
  103. if(dz->brksize[FILT_FRQ2])
  104. hifrq_limit = exp(dz->param[FILT_FRQ2]);
  105. else
  106. hifrq_limit = dz->param[FILT_FRQ2];
  107. if(frq_limit > hifrq_limit)
  108. swap(&frq_limit,&hifrq_limit);
  109. break;
  110. }
  111. if((exit_status = get_totalamp(&pre_amptotal,dz->flbufptr[0],dz->wanted))<0)
  112. return(exit_status);
  113. if((exit_status = do_filtering(frq_limit,hifrq_limit,dz))<0)
  114. return(exit_status);
  115. if((exit_status = get_totalamp(&post_amptotal,dz->flbufptr[0],dz->wanted))<0)
  116. return(exit_status);
  117. switch(dz->mode) {
  118. case(F_HI_NORM):
  119. case(F_LO_NORM):
  120. case(F_BND_NORM):
  121. case(F_NOTCH_NORM): /* normalised output */
  122. if((exit_status = normalise(pre_amptotal,post_amptotal,dz))<0)
  123. return(exit_status);
  124. break;
  125. case(F_HI_GAIN):
  126. case(F_LO_GAIN):
  127. case(F_BAND_GAIN):
  128. case(F_NOTCH_GAIN): /* post-gain */
  129. for(vc = 0; vc < dz->wanted; vc += 2)
  130. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->param[FILT_PG]);
  131. break;
  132. }
  133. return(FINISHED);
  134. }
  135. /**************************** DO_FILTERING ***************************/
  136. int do_filtering(double frq_limit,double hifrq_limit,dataptr dz)
  137. {
  138. int exit_status;
  139. int vc;
  140. double loskirt, loskirt_bwidth, hiskirt, hiskirt_bwidth;
  141. switch(dz->mode) {
  142. case(F_HI):
  143. case(F_HI_NORM):
  144. case(F_HI_GAIN):
  145. loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
  146. loskirt_bwidth = frq_limit - loskirt;
  147. for(vc = 0; vc < dz->wanted; vc += 2) {
  148. if((exit_status = below_limitfrq_and_zeroed(vc,loskirt,dz))<0)
  149. return(exit_status);
  150. if(exit_status==TRUE)
  151. continue;
  152. if((exit_status = below_limitfrq_and_filtered(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
  153. return(exit_status);
  154. }
  155. break;
  156. case(F_LO):
  157. case(F_LO_NORM):
  158. case(F_LO_GAIN):
  159. hiskirt = min(dz->nyquist,(frq_limit + dz->param[FILT_QQ]));
  160. hiskirt_bwidth = hiskirt - frq_limit;
  161. for(vc = 0; vc < dz->wanted; vc += 2) {
  162. if((exit_status = above_limitfrq_and_zeroed(vc,hiskirt,dz))<0)
  163. return(exit_status);
  164. if(exit_status==TRUE)
  165. continue;
  166. if((exit_status = filter_above_limitfrq(vc,frq_limit,hiskirt,hiskirt_bwidth,dz))<0)
  167. return(exit_status);
  168. }
  169. break;
  170. case(F_BND):
  171. case(F_BND_NORM):
  172. case(F_BAND_GAIN):
  173. loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
  174. loskirt_bwidth = frq_limit - loskirt;
  175. hiskirt = min(dz->nyquist,(hifrq_limit + dz->param[FILT_QQ]));
  176. hiskirt_bwidth = hiskirt - hifrq_limit;
  177. for(vc = 0; vc < dz->wanted; vc += 2) {
  178. if((exit_status = below_limitfrq_and_zeroed(vc,loskirt,dz))<0)
  179. return(exit_status);
  180. if(exit_status==TRUE)
  181. continue;
  182. if((exit_status = below_limitfrq_and_filtered(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
  183. return(exit_status);
  184. if(exit_status == TRUE)
  185. continue;
  186. if((exit_status = above_limitfrq_and_zeroed(vc,hiskirt,dz))<0)
  187. return(exit_status);
  188. if(exit_status == TRUE)
  189. continue;
  190. if((exit_status = filter_above_limitfrq(vc,hifrq_limit,hiskirt,hiskirt_bwidth,dz))<0)
  191. return(exit_status);
  192. }
  193. break;
  194. case(F_NOTCH):
  195. case(F_NOTCH_NORM):
  196. case(F_NOTCH_GAIN):
  197. loskirt = max(0.0,(frq_limit - dz->param[FILT_QQ]));
  198. loskirt_bwidth = frq_limit - loskirt;
  199. hiskirt = min(dz->nyquist,(hifrq_limit + dz->param[FILT_QQ]));
  200. hiskirt_bwidth = hiskirt - hifrq_limit;
  201. for(vc = 0; vc < dz->wanted; vc += 2) {
  202. if(outside_skirts(vc,loskirt,hiskirt,dz))
  203. continue;
  204. if((exit_status = filtered_in_lower_skirt(vc,frq_limit,loskirt,loskirt_bwidth,dz))<0)
  205. return(exit_status);
  206. if(exit_status==TRUE)
  207. continue;
  208. if((exit_status = filtered_in_upper_skirt(vc,hifrq_limit,hiskirt,hiskirt_bwidth,dz))<0)
  209. return(exit_status);
  210. if(exit_status==TRUE)
  211. continue;
  212. dz->flbufptr[0][AMPP] = 0.0F;
  213. }
  214. break;
  215. default:
  216. sprintf(errstr,"unknown mode in do_filtering()\n");
  217. return(PROGRAM_ERROR);
  218. }
  219. return(FINISHED);
  220. }
  221. /**************************** BELOW_LIMITFRQ_AND_ZEROED ***************************/
  222. int below_limitfrq_and_zeroed(int vc,double loskirt,dataptr dz)
  223. {
  224. if(dz->flbufptr[0][FREQ] < loskirt) {
  225. dz->flbufptr[0][AMPP] = 0.0F;
  226. return(TRUE);
  227. }
  228. return(FALSE);
  229. }
  230. /**************************** BELOW_LIMITFRQ_AND_FILTERED ***************************/
  231. int below_limitfrq_and_filtered(int vc,double limitfrq,double loskirt,double loskirt_bwidth,dataptr dz)
  232. {
  233. if(dz->flbufptr[0][FREQ] < limitfrq) {
  234. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * ((dz->flbufptr[0][FREQ] - loskirt)/loskirt_bwidth));
  235. return(TRUE);
  236. }
  237. return(FALSE);
  238. }
  239. /**************************** FILTER_ABOVE_LIMITFRQ ***************************/
  240. int filter_above_limitfrq(int vc,double limitfrq,double hiskirt,double hiskirt_bwidth,dataptr dz)
  241. {
  242. if(dz->flbufptr[0][FREQ] > limitfrq) {
  243. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * ((hiskirt - dz->flbufptr[0][FREQ])/hiskirt_bwidth));
  244. return(TRUE);
  245. }
  246. return(FALSE);
  247. }
  248. /**************************** ABOVE_LIMITFRQ_AND_ZEROED ***************************/
  249. int above_limitfrq_and_zeroed(int vc,double hiskirt,dataptr dz)
  250. {
  251. if(dz->flbufptr[0][FREQ] > hiskirt) {
  252. dz->flbufptr[0][AMPP] = 0.0F;
  253. return(TRUE);
  254. }
  255. return(FALSE);
  256. }
  257. /**************************** FILTER_IN_LOWER_SKIRT ***************************/
  258. int filtered_in_lower_skirt(int vc,double skirttop,double loskirt,double loskirt_bwidth,dataptr dz)
  259. {
  260. if(dz->flbufptr[0][FREQ] < skirttop) {
  261. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * (1.0 - ((dz->flbufptr[0][FREQ] - loskirt)/loskirt_bwidth)));
  262. return(TRUE);
  263. }
  264. return(FALSE);
  265. }
  266. /**************************** FILTER_IN_UPPER_SKIRT ***************************/
  267. int filtered_in_upper_skirt(int vc,double skirt_bottom,double hiskirt,double hiskirt_bwidth,dataptr dz)
  268. {
  269. if(dz->flbufptr[0][FREQ] > skirt_bottom) {
  270. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * (1.0 - ((hiskirt - dz->flbufptr[0][FREQ])/hiskirt_bwidth)));
  271. return(TRUE);
  272. }
  273. return(FALSE);
  274. }
  275. /*********************** SPECGREQ **********************/
  276. int specgreq(dataptr dz)
  277. {
  278. int exit_status;
  279. if((exit_status = construct_filter_envelope((int)dz->itemcnt,dz->flbufptr[0],dz))<0)
  280. return(exit_status);
  281. if(dz->vflag[GREQ_NOTCH]) {
  282. if((exit_status = invert_greq_filter_envelope(dz))<0)
  283. return(exit_status);
  284. }
  285. if((exit_status = do_greq_filter(dz))<0)
  286. return(exit_status);
  287. return(FINISHED);
  288. }
  289. /****************************** DO_GREQ_FILTER ***************************/
  290. int do_greq_filter(dataptr dz)
  291. {
  292. int cc, vc;
  293. for(cc=0, vc=0; cc < dz->clength; cc++, vc += 2)
  294. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->fsampbuf[cc]);
  295. return(FINISHED);
  296. }
  297. /****************************** INVERT_GREQ_FILTER_ENVELOPE ***************************/
  298. int invert_greq_filter_envelope(dataptr dz)
  299. {
  300. int cc;
  301. for(cc=0; cc<dz->clength; cc++)
  302. dz->fsampbuf[cc] = (float)(1.0 - dz->fsampbuf[cc]);
  303. return(FINISHED);
  304. }
  305. /******************************** SPECSPLIT ******************************/
  306. int specsplit(dataptr dz)
  307. {
  308. int exit_status;
  309. int cc, bno = 0, bottom, top, done = 0, k;
  310. bandptr bb;
  311. double bandbot, bandtop;
  312. rectify_window(dz->flbufptr[0],dz);
  313. if((exit_status = get_amp_and_frq(dz->flbufptr[0],dz))<0)
  314. return(exit_status);
  315. cc = 0; /* channel counter */
  316. while(bno<dz->itemcnt) { /* For all bands */
  317. bb = dz->band[bno];
  318. bandbot = bb->bfrqlo;
  319. bandtop = bb->bfrqhi;
  320. while(dz->freq[cc]<bandbot) { /* while chan-frq<bandbot: do nothing */
  321. if(++cc>=dz->clength) {
  322. done = 1;
  323. break; /* if all channels<bandbot, we.ve finished pass */
  324. }
  325. }
  326. if(done)
  327. break;
  328. bottom = cc; /* set bottom channel for inner loop */
  329. while(dz->freq[cc]<bandtop) {
  330. if(++cc>=dz->clength) {
  331. done = 1; /* find channels up to top of band */
  332. break;
  333. }
  334. }
  335. top = min(cc,(dz->clength)-1); /* set top channel for inner loop */
  336. if((bb->bdoflag & DO_TRANSPOSITION) && bb->btrans>1.0) {
  337. for( k = top; k>= bottom; k--) {
  338. if((exit_status = process_specsplit_channel(k,bb,dz))<0)
  339. return(exit_status);
  340. }
  341. } else {
  342. for( k = bottom; k <= top; k++) {
  343. if((exit_status = process_specsplit_channel(k,bb,dz))<0)
  344. return(exit_status);
  345. }
  346. }
  347. if(done)
  348. break;
  349. bno++;
  350. }
  351. if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0)
  352. return(exit_status);
  353. return(FINISHED);
  354. }
  355. /************************ PROCESS_SPECSPLIT_CHANNEL *****************************/
  356. int process_specsplit_channel(int cc,bandptr bb,dataptr dz)
  357. {
  358. int exit_status;
  359. double thismult;
  360. double newamp = dz->amp[cc]; /* DEFAULT */
  361. double newfrq = dz->freq[cc]; /* DEFAULT */
  362. int newchan;
  363. if(bb->bdoflag & DO_AMPLITUDE_CHANGE) {
  364. if(bb->bdoflag & DO_RAMPED_AMPLITUDE) {
  365. thismult = (dz->freq[cc] - bb->bfrqlo)/(bb->bfrqdif);
  366. thismult *= bb->bampdif;
  367. thismult += bb->bamp;
  368. newamp = dz->amp[cc] * thismult;
  369. } else
  370. newamp = dz->amp[cc] * bb->bamp;
  371. }
  372. if(bb->bdoflag & DO_TRANSPOSITION) {
  373. if(bb->badditive) {
  374. if((newfrq = dz->freq[cc] + bb->btrans)<dz->nyquist) {
  375. if((exit_status = get_channel_corresponding_to_frq(&newchan,newfrq,dz))<0)
  376. return(exit_status);
  377. if(newchan!=cc) {
  378. dz->freq[newchan] = (float)newfrq;
  379. dz->amp[newchan] = (float)newamp;
  380. }
  381. }
  382. } else {
  383. if((newfrq = dz->freq[cc] * bb->btrans)<dz->nyquist) {
  384. if((exit_status = get_channel_corresponding_to_frq(&newchan,newfrq,dz))<0)
  385. return(exit_status);
  386. if(newchan!=cc) {
  387. dz->freq[newchan] = (float)newfrq;
  388. dz->amp[newchan] = (float)newamp;
  389. }
  390. }
  391. }
  392. if(!(bb->bdoflag & DO_ADD_TO_SPECTRUM)) {
  393. newamp = /* set interpolated value on old amp */
  394. (dz->amp[max(cc-1,0)] + dz->amp[min(cc+1,(dz->clength-1))])/2.0;
  395. }
  396. }
  397. dz->freq[cc] = (float)newfrq;
  398. dz->amp[cc] = (float)newamp;
  399. return(FINISHED);
  400. }
  401. /********************************** SPECARPE **********************************/
  402. int specarpe(int *in_start_portion,dataptr dz)
  403. {
  404. int exit_status;
  405. double lofrq, hifrq, frqrang;
  406. double bandmid, bandhilimit, bandlolimit;
  407. int tabindex;
  408. if((exit_status = reset_timechanging_arpe_variables(&frqrang,&lofrq,&hifrq,dz))<0)
  409. return(exit_status);
  410. if((exit_status = locate_current_wavetable_position(dz))<0)
  411. return(exit_status);
  412. tabindex = round(dz->param[ARPE_WAVETABPOS]);
  413. /* LOCATE CURRENT FREQUENCY BAND */
  414. bandmid = (dz->parray[ARPE_TAB][tabindex] * frqrang) + lofrq;
  415. bandhilimit = min(bandmid + dz->param[ARPE_HBAND],dz->nyquist);
  416. bandlolimit = max(bandmid - dz->param[ARPE_HBAND],0.0);
  417. if((exit_status = get_amp_and_frq(dz->flbufptr[0],dz))<0) /* SEPARATE THE AMP AND FREQ DATA */
  418. return(exit_status);
  419. switch(dz->mode) { /* ELIMINATE OR MODIFY FREQUENCIES, AS NECESSARY */
  420. case(ON): exit_status = do_on(bandhilimit,bandlolimit,dz); break;
  421. case(BELOW): exit_status = do_below(bandmid,dz); break;
  422. case(ABOVE): exit_status = do_above(bandmid,dz); break;
  423. case(BOOST): exit_status = do_boost(bandhilimit,bandlolimit,dz); break;
  424. case(ABOVE_BOOST): exit_status = do_above_boost(bandhilimit,bandlolimit,in_start_portion,dz); break;
  425. case(BELOW_BOOST): exit_status = do_below_boost(bandhilimit,bandlolimit,in_start_portion,dz); break;
  426. case(ONCE_ABOVE): exit_status = do_once_above(bandhilimit,in_start_portion,dz); break;
  427. case(ONCE_BELOW): exit_status = do_once_below(bandlolimit,in_start_portion,dz); break;
  428. default:
  429. sprintf(errstr,"unknown mode in specarpe()\n");
  430. return(PROGRAM_ERROR);
  431. }
  432. if(exit_status<0)
  433. return(exit_status);
  434. if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0) /* WRITE MODIFIED AMP & FREQ BUFF TO SAMP BUFF */
  435. return(exit_status);
  436. return(FINISHED);
  437. }
  438. /*************************** DO_ON ****************************/
  439. int do_on(double bandhilimit,double bandlolimit,dataptr dz)
  440. {
  441. int exit_status;
  442. int cc, vc = 0;
  443. double dec, nonlin_dec = 0.0, thisamp;
  444. switch(dz->iparam[ARPE_SUSFLAG]) {
  445. case(AP_NORMAL):
  446. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  447. if(dz->iparray[ARPE_KEEP][cc]) {
  448. if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
  449. return(exit_status);
  450. } else {
  451. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  452. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  453. return(exit_status);
  454. } else
  455. dz->amp[cc] = 0.0f;
  456. }
  457. }
  458. break;
  459. case(AP_SUSTAIN_PITCH):
  460. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  461. if(dz->iparray[ARPE_KEEP][cc]) {
  462. if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  463. return(exit_status);
  464. } else {
  465. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  466. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  467. return(exit_status);
  468. } else
  469. dz->amp[cc] = 0.0f;
  470. }
  471. }
  472. break;
  473. case(AP_LIMIT_SUSTAIN):
  474. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  475. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  476. if((exit_status = get_decimation(&dec,cc,dz))<0)
  477. return(exit_status);
  478. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
  479. if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
  480. return(exit_status);
  481. } else {
  482. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  483. return(exit_status);
  484. }
  485. } else {
  486. if(dz->iparray[ARPE_KEEP][cc]) {
  487. if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
  488. return(exit_status);
  489. } else
  490. dz->amp[cc] = 0.0f;
  491. }
  492. }
  493. break;
  494. case(AP_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
  495. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  496. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  497. if((exit_status = get_decimation(&dec,cc,dz))<0)
  498. return(exit_status);
  499. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
  500. if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
  501. return(exit_status);
  502. } else {
  503. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  504. return(exit_status);
  505. }
  506. } else {
  507. if(dz->iparray[ARPE_KEEP][cc]) {
  508. if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  509. return(exit_status);
  510. } else
  511. dz->amp[cc] = 0.0f;
  512. }
  513. }
  514. break;
  515. case(AP_NONLIN):
  516. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  517. if(dz->iparray[ARPE_KEEP][cc]) {
  518. if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
  519. return(exit_status);
  520. } else {
  521. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  522. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  523. return(exit_status);
  524. } else
  525. dz->amp[cc] = 0.0f;
  526. }
  527. }
  528. break;
  529. case(AP_NONLIN_AND_SUSTAIN_PITCH):
  530. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  531. if(dz->iparray[ARPE_KEEP][cc]) {
  532. if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  533. return(exit_status);
  534. } else {
  535. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  536. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  537. return(exit_status);
  538. } else
  539. dz->amp[cc] = 0.0f;
  540. }
  541. }
  542. break;
  543. case(AP_NONLIN_AND_LIMIT_SUSTAIN):
  544. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  545. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  546. if(dz->iparray[ARPE_KEEP][cc]) {
  547. if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
  548. return(exit_status);
  549. }
  550. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
  551. if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
  552. return(exit_status);
  553. } else {
  554. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  555. return(exit_status);
  556. }
  557. } else {
  558. if(dz->iparray[ARPE_KEEP][cc]) {
  559. if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
  560. return(exit_status);
  561. } else
  562. dz->amp[cc] = 0.0f;
  563. }
  564. }
  565. break;
  566. case(AP_NONLIN_AND_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
  567. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  568. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  569. if(dz->iparray[ARPE_KEEP][cc]) {
  570. if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
  571. return(exit_status);
  572. }
  573. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
  574. if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
  575. return(exit_status);
  576. } else {
  577. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  578. return(exit_status);
  579. }
  580. } else {
  581. if(dz->iparray[ARPE_KEEP][cc]) {
  582. if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  583. return(exit_status);
  584. } else
  585. dz->amp[cc] = 0.0f;
  586. }
  587. }
  588. break;
  589. }
  590. return(FINISHED);
  591. }
  592. /******************************* DO_BELOW **************************/
  593. int do_below(double bandmid,dataptr dz)
  594. {
  595. int cc;
  596. for(cc=0;cc<dz->clength;cc++) {
  597. if(dz->freq[cc]>bandmid)
  598. dz->amp[cc] = 0.0f;
  599. //TW JULY 2006
  600. else
  601. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
  602. }
  603. return(FINISHED);
  604. }
  605. /******************************** DO_ABOVE ***********************/
  606. int do_above(double bandmid,dataptr dz)
  607. {
  608. int cc;
  609. for(cc=0;cc<dz->clength;cc++) {
  610. if(dz->freq[cc]<bandmid)
  611. dz->amp[cc] = 0.0f;
  612. //TW JULY 2006
  613. else
  614. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
  615. }
  616. return(FINISHED);
  617. }
  618. /**************************** DO_BOOST ****************************/
  619. int do_boost(double bandhilimit,double bandlolimit,dataptr dz)
  620. {
  621. int exit_status;
  622. int cc, vc;
  623. double dec, nonlin_dec = 0.0,thisamp;
  624. switch(dz->iparam[ARPE_SUSFLAG]) {
  625. case(AP_NORMAL):
  626. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  627. if(dz->iparray[ARPE_KEEP][cc]) {
  628. if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
  629. return(exit_status);
  630. } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  631. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  632. return(exit_status);
  633. }
  634. }
  635. break;
  636. case(AP_SUSTAIN_PITCH):
  637. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  638. if(dz->iparray[ARPE_KEEP][cc]) {
  639. if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  640. return(exit_status);
  641. } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  642. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  643. return(exit_status);
  644. }
  645. }
  646. break;
  647. case(AP_LIMIT_SUSTAIN):
  648. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  649. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  650. if((exit_status = get_decimation(&dec,cc,dz))<0)
  651. return(exit_status);
  652. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
  653. if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
  654. return(exit_status);
  655. } else {
  656. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  657. return(exit_status);
  658. }
  659. } else {
  660. if(dz->iparray[ARPE_KEEP][cc]) {
  661. if((exit_status = sustain_arpeg_note(cc,vc,dz))<0)
  662. return(exit_status);
  663. }
  664. }
  665. }
  666. break;
  667. case(AP_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
  668. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  669. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  670. if((exit_status = get_decimation(&dec,cc,dz))<0)
  671. return(exit_status);
  672. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * dec) > dz->amp[cc])) {
  673. if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
  674. return(exit_status);
  675. } else {
  676. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  677. return(exit_status);
  678. }
  679. } else {
  680. if(dz->iparray[ARPE_KEEP][cc]) {
  681. if((exit_status = sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  682. return(exit_status);
  683. }
  684. }
  685. }
  686. break;
  687. case(AP_NONLIN):
  688. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  689. if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
  690. return(exit_status);
  691. if(dz->iparray[ARPE_KEEP][cc]) {
  692. dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * nonlin_dec);
  693. dz->iparray[ARPE_KEEP][cc]--;
  694. } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  695. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  696. return(exit_status);
  697. }
  698. }
  699. break;
  700. case(AP_NONLIN_AND_SUSTAIN_PITCH):
  701. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  702. if(dz->iparray[ARPE_KEEP][cc]) {
  703. if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  704. return(exit_status);
  705. } else if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  706. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  707. return(exit_status);
  708. }
  709. }
  710. break;
  711. case(AP_NONLIN_AND_LIMIT_SUSTAIN):
  712. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  713. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  714. if(dz->iparray[ARPE_KEEP][cc]) {
  715. if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
  716. return(exit_status);
  717. }
  718. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
  719. if((exit_status = temporarily_sustain_arpeg_note(cc,thisamp,dz))<0)
  720. return(exit_status);
  721. } else {
  722. if((exit_status = initiate_new_arpeg_note(cc,vc,dz))<0)
  723. return(exit_status);
  724. }
  725. } else {
  726. if(dz->iparray[ARPE_KEEP][cc]) {
  727. if((exit_status = nonlin_sustain_arpeg_note(cc,vc,dz))<0)
  728. return(exit_status);
  729. }
  730. }
  731. }
  732. break;
  733. case(AP_NONLIN_AND_SUSTAIN_PITCH_AND_LIMIT_SUSTAIN):
  734. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  735. if(dz->freq[cc]>=bandlolimit && dz->freq[cc]<=bandhilimit) {
  736. if(dz->iparray[ARPE_KEEP][cc]) {
  737. if((exit_status = get_non_linear_decimation(&nonlin_dec,cc,dz))<0)
  738. return(exit_status);
  739. }
  740. if(dz->iparray[ARPE_KEEP][cc] && ((thisamp = dz->windowbuf[0][AMPP] * nonlin_dec) > dz->amp[cc])) {
  741. if((exit_status = temporarily_sustain_arpeg_note_with_fixed_pitch(cc,vc,thisamp,dz))<0)
  742. return(exit_status);
  743. } else {
  744. if((exit_status = initiate_new_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  745. return(exit_status);
  746. }
  747. } else {
  748. if(dz->iparray[ARPE_KEEP][cc]) {
  749. if((exit_status = nonlin_sustain_arpeg_note_with_fixed_pitch(cc,vc,dz))<0)
  750. return(exit_status);
  751. }
  752. }
  753. }
  754. break;
  755. }
  756. return(FINISHED);
  757. }
  758. /************************* DO_ABOVE_BOOST ****************************/
  759. int do_above_boost(double bandhilimit,double bandlolimit,int *in_start_portion, dataptr dz)
  760. {
  761. int cc;
  762. if(*in_start_portion) {
  763. if((dz->iparam[ARPE_WTYPE]==SIN || dz->iparam[ARPE_WTYPE]==SAW)) {
  764. if(dz->param[ARPE_WAVETABPOS]>=ARPE_TABSIZE/2)
  765. *in_start_portion = FALSE;
  766. } else {
  767. if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
  768. *in_start_portion = FALSE;
  769. }
  770. }
  771. if(*in_start_portion) {
  772. for(cc=0;cc<dz->clength;cc++) {
  773. if(dz->freq[cc]>bandlolimit)
  774. dz->amp[cc] = 0.0f;
  775. //TW JULY 2006
  776. else
  777. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL] * dz->iparam[ARPE_SUST]);
  778. }
  779. } else
  780. return do_boost(bandhilimit,bandlolimit,dz);
  781. return(FINISHED);
  782. }
  783. /**************************** DO_BELOW_BOOST ************************/
  784. int do_below_boost(double bandhilimit,double bandlolimit,int *in_start_portion,dataptr dz)
  785. {
  786. int cc;
  787. if(*in_start_portion) {
  788. if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
  789. *in_start_portion = FALSE;
  790. }
  791. if(*in_start_portion) {
  792. for(cc=0;cc<dz->clength;cc++) {
  793. if(dz->freq[cc]<bandhilimit)
  794. dz->amp[cc] = 0.0f;
  795. //TW JULY 2006
  796. else
  797. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL] * dz->iparam[ARPE_SUST]);
  798. }
  799. } else
  800. return do_boost(bandhilimit,bandlolimit,dz);
  801. return(FINISHED);
  802. }
  803. /************************** DO_ONCE_BELOW ***************************/
  804. int do_once_below(double bandlolimit,int *in_start_portion,dataptr dz)
  805. {
  806. int cc;
  807. if(*in_start_portion) {
  808. if((dz->iparam[ARPE_WTYPE]==SIN || dz->iparam[ARPE_WTYPE]==SAW)) {
  809. if(dz->param[ARPE_WAVETABPOS] >= ARPE_TABSIZE/2)
  810. *in_start_portion = FALSE;
  811. } else {
  812. if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
  813. *in_start_portion = FALSE;
  814. }
  815. }
  816. if(*in_start_portion) {
  817. for(cc=0;cc<dz->clength;cc++) {
  818. if(dz->freq[cc]>bandlolimit)
  819. dz->amp[cc] = 0.0f;
  820. //TW JULY 2006
  821. else
  822. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
  823. }
  824. }
  825. return(FINISHED);
  826. }
  827. /***************************** DO_ONCE_ABOVE **************************/
  828. int do_once_above(double bandhilimit,int *in_start_portion,dataptr dz)
  829. {
  830. int cc;
  831. if(*in_start_portion) {
  832. if(dz->param[ARPE_WAVETABPOS] < dz->param[ARPE_LAST_TABPOS])
  833. *in_start_portion = FALSE;
  834. }
  835. if(*in_start_portion) {
  836. for(cc=0;cc<dz->clength;cc++) {
  837. if(dz->freq[cc]<bandhilimit)
  838. dz->amp[cc] = 0.0f;
  839. //TW JULY 2006
  840. else
  841. dz->amp[cc] = (float)(dz->amp[cc] * dz->param[ARPE_AMPL]);
  842. }
  843. }
  844. return(FINISHED);
  845. }
  846. /******************** INITIATE_NEW_ARPEG_NOTE ********************/
  847. int initiate_new_arpeg_note(int cc,int vc,dataptr dz)
  848. {
  849. dz->iparray[ARPE_KEEP][cc] = dz->iparam[ARPE_SUST];
  850. dz->amp[cc] *= (float)(dz->param[ARPE_AMPL] * dz->iparray[ARPE_KEEP][cc]);
  851. dz->windowbuf[0][AMPP] = dz->amp[cc];
  852. (dz->iparray[ARPE_KEEP][cc])--;
  853. return(FINISHED);
  854. }
  855. /******************** INITIATE_NEW_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
  856. int initiate_new_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz)
  857. {
  858. dz->iparray[ARPE_KEEP][cc] = dz->iparam[ARPE_SUST];
  859. dz->amp[cc] *= (float)(dz->param[ARPE_AMPL] * dz->iparray[ARPE_KEEP][cc]);
  860. dz->windowbuf[0][AMPP] = dz->amp[cc];
  861. dz->windowbuf[0][FREQ] = dz->freq[cc];
  862. dz->iparray[ARPE_KEEP][cc]--;
  863. return(FINISHED);
  864. }
  865. /******************** TEMPORARILY_SUSTAIN_ARPEG_NOTE ********************/
  866. int temporarily_sustain_arpeg_note(int cc,double thisamp,dataptr dz)
  867. {
  868. dz->amp[cc] = (float)thisamp;
  869. dz->iparray[ARPE_KEEP][cc]--;
  870. return(FINISHED);
  871. }
  872. /******************** TEMPORARILY_SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
  873. int temporarily_sustain_arpeg_note_with_fixed_pitch(int cc,int vc,double thisamp,dataptr dz)
  874. {
  875. dz->amp[cc] = (float)thisamp;
  876. dz->freq[cc] = dz->windowbuf[0][FREQ];
  877. dz->iparray[ARPE_KEEP][cc]--;
  878. return(FINISHED);
  879. }
  880. /******************** GET_NON_LINEAR_DECIMATION ********************/
  881. int get_non_linear_decimation(double *nonlin_dec,int cc,dataptr dz)
  882. {
  883. *nonlin_dec = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  884. *nonlin_dec = pow(*nonlin_dec,dz->param[ARPE_NONLIN]);
  885. return(FINISHED);
  886. }
  887. /******************** GET_DECIMATION ********************/
  888. int get_decimation(double *dec,int cc,dataptr dz)
  889. {
  890. *dec = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  891. return(FINISHED);
  892. }
  893. /******************** SUSTAIN_ARPEG_NOTE ********************/
  894. int sustain_arpeg_note(int cc,int vc,dataptr dz)
  895. {
  896. double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  897. dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
  898. dz->iparray[ARPE_KEEP][cc]--;
  899. return(FINISHED);
  900. }
  901. /******************** SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
  902. int sustain_arpeg_note_with_fixed_pitch(int cc,int vc,dataptr dz)
  903. {
  904. double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  905. dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
  906. dz->freq[cc] = dz->windowbuf[0][FREQ];
  907. dz->iparray[ARPE_KEEP][cc]--;
  908. return(FINISHED);
  909. }
  910. /******************** NONLIN_SUSTAIN_ARPEG_NOTE ********************/
  911. int nonlin_sustain_arpeg_note(int cc,int vc, dataptr dz)
  912. {
  913. double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  914. z = pow(z,dz->param[ARPE_NONLIN]);
  915. dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
  916. dz->iparray[ARPE_KEEP][cc]--;
  917. return(FINISHED);
  918. }
  919. /******************** NONLIN_SUSTAIN_ARPEG_NOTE_WITH_FIXED_PITCH ********************/
  920. int nonlin_sustain_arpeg_note_with_fixed_pitch(int cc, int vc, dataptr dz)
  921. {
  922. double z = (double)dz->iparray[ARPE_KEEP][cc]/(double)dz->iparam[ARPE_SUST];
  923. z = pow(z,dz->param[ARPE_NONLIN]);
  924. dz->amp[cc] = (float)(dz->windowbuf[0][AMPP] * z);
  925. dz->freq[cc] = dz->windowbuf[0][FREQ];
  926. dz->iparray[ARPE_KEEP][cc]--;
  927. return(FINISHED);
  928. }
  929. /****************************** SPECPLUCK ****************************/
  930. int specpluck(dataptr dz)
  931. {
  932. int exit_status;
  933. int mask = 1;
  934. int cc, vc, bflagno, is_set;
  935. if(dz->total_windows==1) { /* Set up BITFLAGS for current state of chans */
  936. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2){
  937. if((exit_status = choose_bflagno_and_reset_mask_if_ness
  938. (&bflagno,cc,&mask,dz->iparam[PLUK_LONGPOW2],dz->iparam[PLUK_DIVMASK]))<0)
  939. return(exit_status);
  940. if(!flteq((double)dz->flbufptr[0][AMPP],0.0))
  941. dz->lparray[PLUK_BFLG][bflagno] |= mask;
  942. mask <<= 1;
  943. }
  944. } else { /* Check change of state of channels */
  945. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2){
  946. if((exit_status = choose_bflagno_and_reset_mask_if_ness
  947. (&bflagno,cc,&mask,dz->iparam[PLUK_LONGPOW2],dz->iparam[PLUK_DIVMASK]))<0)
  948. return(exit_status);
  949. is_set = dz->lparray[PLUK_BFLG][bflagno] & mask;
  950. if(!flteq((double)dz->flbufptr[0][vc],0.0)) { /* If chan amp NOT zero */
  951. if(!is_set) { /* if bit previously 0 (for zero amp) */
  952. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * dz->param[PLUK_GAIN]);
  953. exit_status = set_bit_to_one(bflagno,mask,dz); /* Give boost to chan amp */
  954. }
  955. } else { /* channel amp IS zero */
  956. if(is_set) /* if bit previously 1 for nonzero amp */
  957. exit_status = set_bit_to_zero(bflagno,mask,dz);
  958. }
  959. mask <<= 1; /* move bitmask upwards */
  960. }
  961. }
  962. return(FINISHED);
  963. }
  964. /****************************** SET_BIT_TO_ZERO ****************************/
  965. int set_bit_to_zero(int bflagno,int mask,dataptr dz)
  966. {
  967. mask = ~mask; /* bit-invert mask */
  968. dz->lparray[PLUK_BFLG][bflagno] &= mask; /* Set bit to 0 */
  969. return(FINISHED);
  970. }
  971. /****************************** SET_BIT_TO_ONE ****************************/
  972. int set_bit_to_one(int bflagno,int mask,dataptr dz)
  973. {
  974. dz->lparray[PLUK_BFLG][bflagno] |= mask;
  975. return(FINISHED);
  976. }
  977. /********************************** SPECTRACE **********************************/
  978. int spectrace(dataptr dz)
  979. {
  980. int exit_status;
  981. int invtrindex, cc, vc;
  982. int chans_outside_fltband_to_keep = 0, chans_in_filtband;
  983. double hifrq_limit = 0.0, lofrq_limit = 0.0;
  984. chvptr quietest, loudest;
  985. if((dz->mode == TRC_ALL || dz->vflag[TRACE_RETAIN]) && dz->iparam[TRAC_INDX] >= dz->clength)
  986. return(FINISHED);
  987. if(dz->mode != TRC_ALL) {
  988. hifrq_limit = dz->param[TRAC_HIFRQ];
  989. lofrq_limit = dz->param[TRAC_LOFRQ];
  990. if(hifrq_limit < lofrq_limit)
  991. swap(&hifrq_limit,&lofrq_limit);
  992. if(dz->vflag[TRACE_RETAIN] ) {
  993. chans_in_filtband = dz->clength;
  994. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  995. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
  996. chans_in_filtband--;
  997. }
  998. if((chans_outside_fltband_to_keep = dz->iparam[TRAC_INDX] - chans_in_filtband) <= 0) {
  999. chans_outside_fltband_to_keep = 0;
  1000. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  1001. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
  1002. dz->flbufptr[0][AMPP] = 0.0f;
  1003. }
  1004. }
  1005. } else {
  1006. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  1007. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit)
  1008. dz->flbufptr[0][AMPP] = 0.0f;
  1009. }
  1010. }
  1011. }
  1012. if(chans_outside_fltband_to_keep>0) {
  1013. if((exit_status = initialise_ring_vals(chans_outside_fltband_to_keep,-BIGAMP,dz))<0)
  1014. return(exit_status);
  1015. for(vc = 0; vc < dz->wanted; vc += 2) {
  1016. if(dz->flbufptr[0][FREQ] < lofrq_limit || dz->flbufptr[0][FREQ] > hifrq_limit) {
  1017. if((exit_status = if_one_of_loudest_chans_store_in_ring(vc,dz))<0)
  1018. return(exit_status);
  1019. dz->flbufptr[0][AMPP] = 0.0F;
  1020. }
  1021. }
  1022. /* RESTORE TRUE AMPLITUDE (STORED IN RING) IN LOUDEST OUTSIDER CHANNELS ONLY */
  1023. loudest = dz->ringhead;
  1024. do {
  1025. dz->flbufptr[0][loudest->loc] = loudest->val;
  1026. } while((loudest = loudest->next)!=dz->ringhead);
  1027. } else {
  1028. if(dz->iparam[TRAC_INDX]>(dz->clength/2)) { /* IF MORE CHANS TO KEEP THAN TO REJECT */
  1029. invtrindex = dz->clength - dz->iparam[TRAC_INDX]; /* COUNT CHANS TO REJECT */
  1030. if((exit_status = initialise_ring_vals(invtrindex,BIGAMP,dz))<0)/* MAXIMISE ALL QUIETEST STORES IN RING */
  1031. return(exit_status);
  1032. for(vc = 0; vc < dz->wanted; vc += 2) { /* STORE INDICES OF QUIETEST CHANS */
  1033. if((exit_status = if_one_of_quietest_chans_store_in_ring(vc,dz))<0)
  1034. return(exit_status);
  1035. }
  1036. quietest = dz->ringhead;
  1037. do { /* ZERO ALL QUIETEST CHANS */
  1038. dz->flbufptr[0][quietest->loc] = 0.0F;
  1039. } while((quietest = quietest->next)!=dz->ringhead);
  1040. } else { /* IF MORE CHANS TO REJECT THAN TO KEEP */
  1041. if((exit_status = initialise_ring_vals(dz->iparam[TRAC_INDX],-BIGAMP,dz))<0)
  1042. return(exit_status); /* MINIMISE ALL LOUDEST STORES IN RING */
  1043. for(vc = 0; vc < dz->wanted; vc += 2) {
  1044. if((exit_status = if_one_of_loudest_chans_store_in_ring(vc,dz))<0)
  1045. return(exit_status); /* STORE INDICES OF LOUDEST CHANS */
  1046. dz->flbufptr[0][AMPP] = 0.0F; /* INITIALISE EVERY CHANNEL TO ZERO AMP */
  1047. }
  1048. loudest = dz->ringhead;
  1049. do { /* RESTORE AMPLITUDE IN LOUDEST CHANS ONLY */
  1050. dz->flbufptr[0][loudest->loc] = loudest->val;
  1051. } while((loudest = loudest->next)!=dz->ringhead);
  1052. }
  1053. }
  1054. return(FINISHED);
  1055. }
  1056. /**************************** OUTSIDE_SKIRTS ***************************/
  1057. int outside_skirts(int vc,double loskirt,double hiskirt,dataptr dz)
  1058. {
  1059. if(dz->flbufptr[0][FREQ] < loskirt || dz->flbufptr[0][FREQ] > hiskirt)
  1060. return(TRUE);
  1061. return(FALSE);
  1062. }
  1063. /***************************** RESET_TIMECHANGING_ARPE_VARIABLES **************************/
  1064. int reset_timechanging_arpe_variables(double *frqrange,double *lofrq, double *hifrq,dataptr dz)
  1065. {
  1066. double this_arpfrq;
  1067. if(dz->brksize[ARPE_ARPFRQ]) { /* RESET ARPFREQ, if ness */
  1068. this_arpfrq = (dz->param[ARPE_LASTARPFRQ] + dz->param[ARPE_ARPFRQ])/2.0;
  1069. dz->param[ARPE_LASTARPFRQ] = dz->param[ARPE_ARPFRQ];
  1070. dz->param[ARPE_ARPFRQ] = this_arpfrq;
  1071. }
  1072. /* RESET arp amplification, if ness */
  1073. //TW JULY 2006
  1074. if(dz->mode < BELOW) {
  1075. if(dz->brksize[ARPE_AMPL] || dz->brksize[ARPE_SUST])
  1076. dz->param[ARPE_AMPL] /= (double)dz->iparam[ARPE_SUST];
  1077. }
  1078. *lofrq = dz->param[ARPE_LOFRQ]; /* RESET arp hi and lo limits */
  1079. *hifrq = dz->param[ARPE_HIFRQ];
  1080. if((dz->brksize[ARPE_LOFRQ] || dz->brksize[ARPE_HIFRQ])
  1081. && (*hifrq < *lofrq))
  1082. swap(hifrq,lofrq);
  1083. *frqrange = *hifrq - *lofrq;
  1084. return(FINISHED);
  1085. }
  1086. /******************** LOCATE_CURRENT_WAVETABLE_POSITION ********************/
  1087. int locate_current_wavetable_position(dataptr dz)
  1088. {
  1089. double tabincr;
  1090. tabincr = dz->frametime * dz->param[ARPE_ARPFRQ] * ARPE_TABSIZE;
  1091. dz->param[ARPE_LAST_TABPOS] = dz->param[ARPE_WAVETABPOS];
  1092. dz->param[ARPE_WAVETABPOS] = fmod(dz->param[ARPE_WAVETABPOS] + tabincr,(double)ARPE_TABSIZE);
  1093. return(FINISHED);
  1094. }
  1095. //TW UPDATE: NEW FUNCTIONS (adjusted for float)
  1096. /************************************ VOWEL_FILTER ************************************/
  1097. #define NOISEBASE (0.2)
  1098. int vowel_filter(dataptr dz)
  1099. {
  1100. int *vowels = dz->iparray[0];
  1101. double *times = dz->parray[0];
  1102. double startformant1, startformant2, startformant3, endformant1, endformant2, endformant3;
  1103. double formant1, formant2, formant3;
  1104. double form1step, form2step, form3step;
  1105. double starttime, endtime, time, timefrac, timestep, *sensitivity;
  1106. double f3startatten, f3endatten, f3attenstep, f3atten;
  1107. double f2startatten, f2endatten, f2attenstep, f2atten;
  1108. int exit_status, senslen;
  1109. int n = 0, t = 0;
  1110. double *amp;
  1111. int total_windows_got, windows_in_buf;
  1112. if((amp = (double *)malloc(dz->clength * sizeof(double)))==NULL) {
  1113. sprintf(errstr,"Insufficient memory to store vowel envelope\n");
  1114. return(MEMORY_ERROR);
  1115. }
  1116. if((exit_status = define_sensitivity_curve(&sensitivity,&senslen))<0)
  1117. return(exit_status);
  1118. dz->flbufptr[0] = dz->bigfbuf;
  1119. if((exit_status = get_formant_frqs
  1120. (vowels[t],&startformant1,&startformant2,&startformant3,&f2startatten,&f3startatten))<0)
  1121. return(exit_status);
  1122. starttime = times[t++];
  1123. if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
  1124. return(exit_status);
  1125. endtime = times[t++];
  1126. form1step = endformant1 - startformant1;
  1127. form2step = endformant2 - startformant2;
  1128. form3step = endformant3 - startformant3;
  1129. f2attenstep = f2endatten - f2startatten;
  1130. f3attenstep = f3endatten - f3startatten;
  1131. timestep = endtime-starttime;
  1132. formant1 = startformant1; /* works if only one vowel is entered (for time zero) */
  1133. formant2 = startformant2;
  1134. formant3 = startformant3;
  1135. f2atten = f2startatten;
  1136. f3atten = f3startatten;
  1137. total_windows_got = 0;
  1138. while(n < dz->wlength) {
  1139. if(n >= total_windows_got) {
  1140. if((exit_status = read_samps(dz->bigfbuf, dz)) < 0) {
  1141. sprintf(errstr,"Problem reading source analysis data.\n");
  1142. return(SYSTEM_ERROR);
  1143. }
  1144. dz->flbufptr[0] = dz->bigfbuf;
  1145. windows_in_buf = dz->ssampsread/dz->wanted;
  1146. total_windows_got += windows_in_buf;
  1147. }
  1148. if(dz->itemcnt) {
  1149. time = n * dz->frametime;
  1150. while(time >= endtime) { /* advance along vowels */
  1151. startformant1 = endformant1;
  1152. startformant2 = endformant2;
  1153. startformant3 = endformant3;
  1154. f2startatten = f2endatten;
  1155. f3startatten = f3endatten;
  1156. starttime = endtime;
  1157. if(t < dz->itemcnt) {
  1158. if((exit_status = get_formant_frqs(vowels[t],&endformant1,&endformant2,&endformant3,&f2endatten,&f3endatten))<0)
  1159. return(exit_status);
  1160. endtime = times[t++];
  1161. } else
  1162. break;
  1163. form1step = endformant1 - startformant1;
  1164. form2step = endformant2 - startformant2;
  1165. form3step = endformant3 - startformant3;
  1166. f2attenstep = f2endatten - f2startatten;
  1167. f3attenstep = f3endatten - f3startatten;
  1168. timestep = endtime-starttime;
  1169. }
  1170. if(!flteq(starttime,endtime)) { /* interpolate between vowels : or retain last vowel */
  1171. timefrac = (time - starttime)/timestep;
  1172. formant1 = startformant1 + (form1step * timefrac);
  1173. formant2 = startformant2 + (form2step * timefrac);
  1174. formant3 = startformant3 + (form3step * timefrac);
  1175. f2atten = f2startatten + (f2attenstep * timefrac);
  1176. f3atten = f3startatten + (f3attenstep * timefrac);
  1177. }
  1178. }
  1179. if((exit_status = do_vowel_filter
  1180. (amp,formant1,formant2,formant3,f2atten,f3atten,sensitivity,senslen,dz)) <0)
  1181. return(exit_status);
  1182. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[1]) {
  1183. if((exit_status = write_samps(dz->bigfbuf,dz->buflen,dz))<0)
  1184. return(exit_status);
  1185. dz->flbufptr[0] = dz->bigfbuf;
  1186. }
  1187. n++;
  1188. }
  1189. if(dz->flbufptr[0] != dz->bigfbuf) {
  1190. if((exit_status = write_samps(dz->bigfbuf,dz->flbufptr[0] - dz->bigfbuf,dz))<0)
  1191. return(exit_status);
  1192. }
  1193. return(FINISHED);
  1194. }
  1195. /************************************ DO_VOWEL_FILTER ************************************
  1196. *
  1197. * "sensitivity" compensates for frq sensitivity of ear at low end, and attenuates
  1198. * formant bands above c3500.
  1199. */
  1200. int do_vowel_filter(double *vamp,double formant1,double formant2,double formant3,double f2atten,double f3atten,
  1201. double *sensitivity,int senslen,dataptr dz)
  1202. {
  1203. double hfwidth1, hfwidth2, hfwidth3 = 0.0, lolim1, lolim2, lolim3 = 0.0, hilim1, hilim2, hilim3 = 0.0;
  1204. // double thisfrq, amp, amp2, amp3 = 0.0, totamp = 0.0;
  1205. double thisfrq, amp, amp2 = 0.0, amp3 = 0.0;
  1206. int exit_status, cc, vc;
  1207. int overlapped_formants12 = 0, overlapped_formants23 = 0, overlapped_formants13 = 0;
  1208. int is_overlap12, is_overlap23, is_overlap13;
  1209. double toplim, pre_totamp, post_totamp, maxamp, maxvamp, ampscale;
  1210. int is_third_formant = 0;
  1211. double signal_base = 1.0 - dz->param[PV_PKRANG];
  1212. if(formant3 > 0.0)
  1213. is_third_formant = 1;
  1214. hfwidth1 = formant1 * dz->param[PV_HWIDTH]; /* set limits of formant bands */
  1215. lolim1 = formant1 - hfwidth1;
  1216. hilim1 = formant1 + hfwidth1;
  1217. hfwidth2 = formant2 * dz->param[PV_HWIDTH];
  1218. lolim2 = formant2 - hfwidth2;
  1219. hilim2 = formant2 + hfwidth2;
  1220. if(is_third_formant) {
  1221. hfwidth3 = formant3 * dz->param[PV_HWIDTH];
  1222. lolim3 = formant3 - hfwidth3;
  1223. hilim3 = formant3 + hfwidth3;
  1224. }
  1225. if(hilim1 > lolim2) /* deal with overlapping formants */
  1226. overlapped_formants12 = 1;
  1227. if(is_third_formant) {
  1228. if(hilim2 > lolim3)
  1229. overlapped_formants23 = 1;
  1230. if(hilim1 > lolim3)
  1231. overlapped_formants13 = 1;
  1232. }
  1233. if(is_third_formant)
  1234. toplim = hilim3;
  1235. else
  1236. toplim = hilim2;
  1237. maxamp = 0.0;
  1238. pre_totamp = 0.0;
  1239. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  1240. pre_totamp += dz->flbufptr[0][AMPP];
  1241. maxamp = max(dz->flbufptr[0][AMPP],maxamp);
  1242. }
  1243. maxvamp = 0.0;
  1244. /* find the formant envelope amplitude at frequency of every window */
  1245. if(!is_third_formant)
  1246. hilim3 = hilim2;
  1247. for(cc = 0, vc = 0;cc <dz->clength; cc++, vc += 2) {
  1248. thisfrq = dz->flbufptr[0][FREQ];
  1249. amp = 0.0;
  1250. is_overlap12 = 0;
  1251. is_overlap23 = 0;
  1252. is_overlap13 = 0;
  1253. if(thisfrq < lolim1 || thisfrq > hilim3)
  1254. ;
  1255. else if((thisfrq > lolim1) && (thisfrq < hilim1)) {
  1256. if(overlapped_formants12 && (thisfrq > lolim2)) {
  1257. is_overlap12 = 1;
  1258. if(thisfrq >= formant2)
  1259. amp2 = (hilim2 - thisfrq)/hfwidth2;
  1260. else
  1261. amp2 = (thisfrq - lolim2)/hfwidth2;
  1262. amp2 *= f2atten;
  1263. }
  1264. if(is_third_formant) {
  1265. if(overlapped_formants13 && (thisfrq > lolim3)) {
  1266. is_overlap13 = 1;
  1267. if(thisfrq >= formant3)
  1268. amp3 = (hilim3 - thisfrq)/hfwidth3;
  1269. else
  1270. amp3 = (thisfrq - lolim3)/hfwidth3;
  1271. amp3 *= f3atten;
  1272. }
  1273. }
  1274. if(thisfrq >= formant1)
  1275. amp = (hilim1 - thisfrq)/hfwidth1;
  1276. else
  1277. amp = (thisfrq - lolim1)/hfwidth1;
  1278. if(is_overlap12)
  1279. amp = max(amp,amp2);
  1280. if(is_third_formant && is_overlap13)
  1281. amp = max(amp,amp3);
  1282. } else if((thisfrq > lolim2) && (thisfrq < hilim2)) {
  1283. if(is_third_formant && overlapped_formants23 && (thisfrq > lolim3)) {
  1284. is_overlap23 = 1;
  1285. if(thisfrq >= formant3)
  1286. amp3 = (hilim3 - thisfrq)/hfwidth3;
  1287. else
  1288. amp3 = (thisfrq - lolim3)/hfwidth3;
  1289. amp3 *= f3atten;
  1290. }
  1291. if(thisfrq >= formant2)
  1292. amp = (hilim2 - thisfrq)/hfwidth2;
  1293. else
  1294. amp = (thisfrq - lolim2)/hfwidth2;
  1295. amp *= f2atten;
  1296. if(is_third_formant && is_overlap23)
  1297. amp = max(amp,amp3);
  1298. } else if(is_third_formant && (thisfrq > lolim3)) {
  1299. if(thisfrq >= formant3)
  1300. amp = (hilim3 - thisfrq)/hfwidth3;
  1301. else
  1302. amp = (thisfrq - lolim3)/hfwidth3;
  1303. amp *= f3atten;
  1304. }
  1305. amp = pow(amp,dz->param[PV_CURVIT]);
  1306. amp *= dz->param[PV_PKRANG];
  1307. amp += signal_base;
  1308. if((exit_status = adjust_for_sensitivity(&amp,(double)thisfrq,sensitivity,senslen))<0)
  1309. return(exit_status);
  1310. vamp[cc] = amp;
  1311. maxvamp = max(maxvamp,vamp[cc]);
  1312. }
  1313. /* set scaling factor to allow for max level of input window */
  1314. if(flteq(maxvamp,0.0))
  1315. ampscale = 0.0;
  1316. else
  1317. ampscale = (maxamp/maxvamp);
  1318. post_totamp = 0.0;
  1319. for(cc = 0,vc = 0;cc <dz->clength; cc++,vc += 2) {
  1320. vamp[cc] *= ampscale;
  1321. /* force window to formant level ONLY if existing val > a given proportion of formant level */
  1322. if((double)dz->flbufptr[0][AMPP] > vamp[cc] * dz->param[VF_THRESH])
  1323. dz->flbufptr[0][AMPP] = (float)vamp[cc];
  1324. post_totamp += dz->flbufptr[0][AMPP];
  1325. }
  1326. /* normalise to overall level of original window */
  1327. if((exit_status = normalise(pre_totamp,post_totamp,dz))<0)
  1328. return(exit_status);
  1329. return(FINISHED);
  1330. }
  1331. /************************************ DEFINE_SENSITIVITY_CURVE ************************************
  1332. *
  1333. * approximate compensation for aural sensitivity
  1334. */
  1335. #define LOFRQ_BOOST (2.511) /* 8dB */
  1336. #define HIFRQ_LOSS (0.4) /* -8dB */
  1337. #define LOFRQ_FOOT (250.0)
  1338. #define MIDFRQSHELF_BOT (2000.0)
  1339. #define MIDFRQSHELF_TOP (3000.0)
  1340. #define HIFRQ_FOOT (4000.0)
  1341. #define TOP_OF_SPECTRUM (96000.0) /* double maximum nyquist (i.e. >nyquist: for safety margin) */
  1342. int define_sensitivity_curve(double **sensitivity,int *senslen)
  1343. {
  1344. int arraysize = BIGARRAY;
  1345. double *p;
  1346. int n = 0;
  1347. if((*sensitivity = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  1348. sprintf(errstr,"INSUFFICIENT MEMORY for time data.\n");
  1349. return(MEMORY_ERROR);
  1350. }
  1351. p = *sensitivity;
  1352. *p++ = 0.0; *p++ = 1.0; n+= 2; /* everything must be in 0-1 range */
  1353. *p++ = LOFRQ_FOOT; *p++ = 1.0; n+= 2; /* for pow() calculations to work, later */
  1354. *p++ = MIDFRQSHELF_BOT; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
  1355. *p++ = MIDFRQSHELF_TOP; *p++ = 1.0/LOFRQ_BOOST; n+= 2;
  1356. *p++ = HIFRQ_FOOT; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
  1357. *p++ = TOP_OF_SPECTRUM; *p++ = HIFRQ_LOSS/LOFRQ_BOOST; n+= 2;
  1358. if((*sensitivity = (double *)realloc((char *)(*sensitivity),n * sizeof(double)))==NULL) {
  1359. sprintf(errstr,"INSUFFICIENT MEMORY for sensitivity curve.\n");
  1360. return(MEMORY_ERROR);
  1361. }
  1362. *senslen = n;
  1363. return(FINISHED);
  1364. }
  1365. /************************************ GET_FORMANT_FRQS ************************************/
  1366. int get_formant_frqs
  1367. (int vowel,double *formant1, double *formant2, double *formant3, double *f2atten, double *f3atten)
  1368. {
  1369. switch(vowel) {
  1370. case(VOWEL_EE): *formant1= EE_FORMANT1; *formant2= EE_FORMANT2; *formant3= EE_FORMANT3;
  1371. /* heed */ *f2atten = EE_F2ATTEN; *f3atten = EE_F3ATTEN;
  1372. break;
  1373. case(VOWEL_I): *formant1= I_FORMANT1; *formant2= I_FORMANT2; *formant3= I_FORMANT3;
  1374. /* hid */ *f2atten = I_F2ATTEN; *f3atten = I_F3ATTEN;
  1375. break;
  1376. case(VOWEL_AI): *formant1= AI_FORMANT1; *formant2= AI_FORMANT2; *formant3= AI_FORMANT3;
  1377. /* maid */ *f2atten = AI_F2ATTEN; *f3atten = AI_F3ATTEN;
  1378. break;
  1379. case(VOWEL_AII): *formant1= AII_FORMANT1; *formant2= AII_FORMANT2; *formant3= AII_FORMANT3;
  1380. /* scottish educAted */ *f2atten = AII_F2ATTEN; *f3atten = AII_F3ATTEN;
  1381. break;
  1382. case(VOWEL_E): *formant1= E_FORMANT1; *formant2= E_FORMANT2; *formant3= E_FORMANT3;
  1383. /* head */ *f2atten = E_F2ATTEN; *f3atten = E_F3ATTEN;
  1384. break;
  1385. case(VOWEL_A): *formant1= A_FORMANT1; *formant2= A_FORMANT2; *formant3= A_FORMANT3;
  1386. /* had */ *f2atten = A_F2ATTEN; *f3atten = A_F3ATTEN;
  1387. break;
  1388. case(VOWEL_AR): *formant1= AR_FORMANT1; *formant2= AR_FORMANT2; *formant3= AR_FORMANT3;
  1389. /* hard */ *f2atten = AR_F2ATTEN; *f3atten = AR_F3ATTEN;
  1390. break;
  1391. case(VOWEL_O): *formant1= O_FORMANT1; *formant2= O_FORMANT2; *formant3= O_FORMANT3;
  1392. /* hod */ *f2atten = O_F2ATTEN; *f3atten = O_F3ATTEN;
  1393. break;
  1394. case(VOWEL_OR): *formant1= OR_FORMANT1; *formant2= OR_FORMANT2; *formant3= OR_FORMANT3;
  1395. /* hoard */ *f2atten = OR_F2ATTEN; *f3atten = OR_F3ATTEN;
  1396. break;
  1397. case(VOWEL_OA): *formant1= OA_FORMANT1; *formant2= OA_FORMANT2; *formant3= OA_FORMANT3;
  1398. /* load (North of England) */ *f2atten = OA_F2ATTEN; *f3atten = OA_F3ATTEN;
  1399. break;
  1400. case(VOWEL_U): *formant1= U_FORMANT1; *formant2= U_FORMANT2; *formant3= U_FORMANT3;
  1401. /* hood, mud (North of England) */ *f2atten = U_F2ATTEN; *f3atten = U_F3ATTEN;
  1402. break;
  1403. case(VOWEL_UU): *formant1= UU_FORMANT1; *formant2= UU_FORMANT2; *formant3= UU_FORMANT3;
  1404. /* Scottish edUcated */ *f2atten = UU_F2ATTEN; *f3atten = UU_F3ATTEN;
  1405. break;
  1406. case(VOWEL_UI): *formant1= UI_FORMANT1; *formant2= UI_FORMANT2; *formant3= UI_FORMANT3;
  1407. /* Scottish 'could' */ *f2atten = UI_F2ATTEN; *f3atten = UI_F3ATTEN;
  1408. break;
  1409. case(VOWEL_OO): *formant1= OO_FORMANT1; *formant2= OO_FORMANT2; *formant3= OO_FORMANT3;
  1410. /* mood */ *f2atten = OO_F2ATTEN; *f3atten = OO_F3ATTEN;
  1411. break;
  1412. case(VOWEL_XX): *formant1= XX_FORMANT1; *formant2= XX_FORMANT2; *formant3= XX_FORMANT3;
  1413. /* mud (South of England) */ *f2atten = XX_F2ATTEN; *f3atten = XX_F3ATTEN;
  1414. break;
  1415. case(VOWEL_X): *formant1= X_FORMANT1; *formant2= X_FORMANT2; *formant3 = X_FORMANT3;
  1416. /* the, herd */ *f2atten = X_F2ATTEN; *f3atten = X_F3ATTEN;
  1417. break;
  1418. case(VOWEL_N): *formant1= N_FORMANT1; *formant2= N_FORMANT2; *formant3 = N_FORMANT3;
  1419. /* 'n' */ *f2atten = N_F2ATTEN; *f3atten = N_F3ATTEN;
  1420. break;
  1421. case(VOWEL_M): *formant1= M_FORMANT1; *formant2= M_FORMANT2; *formant3 = M_FORMANT3;
  1422. /* 'm' */ *f2atten = M_F2ATTEN; *f3atten = M_F3ATTEN;
  1423. break;
  1424. case(VOWEL_R): *formant1= R_FORMANT1; *formant2= R_FORMANT2; *formant3 = R_FORMANT3;
  1425. /* dRaws */ *f2atten = R_F2ATTEN; *f3atten = R_F3ATTEN;
  1426. break;
  1427. case(VOWEL_TH): *formant1= TH_FORMANT1; *formant2= TH_FORMANT2; *formant3 = TH_FORMANT3;
  1428. /* 'THe' */ *f2atten = TH_F2ATTEN; *f3atten = TH_F3ATTEN;
  1429. break;
  1430. default:
  1431. sprintf(errstr,"Unknown vowel\n");
  1432. return(PROGRAM_ERROR);
  1433. }
  1434. return(FINISHED);
  1435. }
  1436. /************************************ ADJUST_FOR_SENSITIVITY ************************************/
  1437. int adjust_for_sensitivity(double *amp,double frq,double *sensitivity,int senslen)
  1438. {
  1439. int n = 0;
  1440. double multiplier, losensfrq, hisensfrq, losens, hisens, frqfrac, sensstep;
  1441. while(frq > sensitivity[n]) {
  1442. n += 2;
  1443. if(n > senslen) {
  1444. sprintf(errstr,"Failed to find sensitivity value (1)\n");
  1445. return(PROGRAM_ERROR);
  1446. }
  1447. }
  1448. hisensfrq = sensitivity[n];
  1449. n -= 2;
  1450. if(n < 0) {
  1451. *amp *= sensitivity[1];
  1452. return(FINISHED);
  1453. }
  1454. losensfrq = sensitivity[n];
  1455. frqfrac = (frq - losensfrq)/(hisensfrq - losensfrq);
  1456. n++;
  1457. losens = sensitivity[n];
  1458. n += 2;
  1459. if(n >= senslen) {
  1460. sprintf(errstr,"Failed to find sensitivity value (3)\n");
  1461. return(PROGRAM_ERROR);
  1462. }
  1463. hisens = sensitivity[n];
  1464. sensstep = hisens - losens;
  1465. multiplier = losens + (sensstep * frqfrac);
  1466. *amp *= multiplier;
  1467. return(FINISHED);
  1468. }