strange.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  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 <pnames.h>
  26. #include <globcon.h>
  27. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <flags.h>
  30. #include <strange.h>
  31. #include <cdpmain.h>
  32. #include <formants.h>
  33. #include <speccon.h>
  34. #include <sfsys.h>
  35. #include <osbind.h>
  36. #include <string.h>
  37. #include <strange.h>
  38. //#ifdef unix
  39. #define round(x) lround((x))
  40. //#endif
  41. #define RATIO_LIMIT (20.0) /* Max ratio actual chanamp allowed to exceed
  42. formant derived amp for frq */
  43. #define SMOOTHER (0.5)
  44. #define VERY_SMALL (0.0000000000000001)
  45. static int zero_sampbuf(dataptr dz);
  46. static int establish_frq_params(double *scalefact,dataptr dz);
  47. static int write_partials_moving_down(double scalefact,dataptr dz);
  48. static int write_partials_moving_up(double scalefact,dataptr dz);
  49. static int cut_or_rolloff_high_frq(dataptr dz);
  50. static int selfglis_down_within_spectral_envelope(int vc,double transpos,dataptr dz);
  51. static int glis_down_within_spectral_envelope(double fundamental,double *thisfrq,double scalefact,int *n,dataptr dz);
  52. static int selfglis_up_within_spectral_envelope(int vc,double transpos,dataptr dz);
  53. static int glis_up_within_spectral_envelope(double fundamental,double *thisfrq,double scalefact,int *n,dataptr dz);
  54. static int do_waver(int *wc,int *w_to_buf,int *samps_read,int wcnt,int upwcnt,int dnwcnt,dataptr dz);
  55. static int spectrally_stretch_window(double thisstr,dataptr dz);
  56. static int advance_along_windows(int *wc,int *w_to_buf,int *samps_read,dataptr dz);
  57. static int warp_pitch(int *avcnt,dataptr dz);
  58. static int warp_time(int avcnt,dataptr dz);
  59. static int get_pitch_averages(int *avcnt,dataptr dz);
  60. static int setup_and_do_pitchwarp(int start,int avg_no,int *lastpos,double *lastmidi,dataptr dz);
  61. static int do_pitch_wiggle(double *thismidi,double ttime, dataptr dz);
  62. static int warp_pitches(int thispos,int diff,int *lastpos,double thismidi,double *lastmidi,dataptr dz);
  63. static int setup_and_do_timewarp(float **thisbuf,float **nextbuf,int n,int *lastoutpos,
  64. int *lastinpos,int *last_total_wndws,dataptr dz);
  65. static int adjust_input_buffers(float **thisbuf,float **nextbuf,int thisindex,
  66. int *last_total_wndws,int do_next,dataptr dz);
  67. static int transpos_initial_windows(float **thisbuf,float **nextbuf,int cnt,int *last_total_wndws,dataptr dz);
  68. static int do_time_wiggle(double *ttime,dataptr dz);
  69. static int do_timewarp(float **thisbuf,float **nextbuf,int thisinpos,int outdiff,
  70. int *lastinpos,int *last_total_wndws,dataptr dz);
  71. static int find_currentbuf_index(int *currentbuf_index,int *last_total_wndws,float **thisbuf,dataptr dz);
  72. static int find_currentbuf_nextindex(int *currentbuf_nextindex,int last_total_wndws,dataptr dz);
  73. static int setup_thisbuf_and_nextbuf(int last_total_wndws,float **thisbuf,float **nextbuf,dataptr dz);
  74. static int interp_between_vals_in_two_bufs(float *thisbuf,float *nextbuf,double interpval,dataptr dz);
  75. static int interp_between_pitch_vals(double *thismidi,float *pitch,int thisindex,double interpval,dataptr dz);
  76. static int interp_between_pitch_vals2(double *thismidi,double *pitch,int thisindex,double interpval,dataptr dz);
  77. static int transpose_outbuf(double transp,dataptr dz);
  78. static int put_transposed_data_in_appropriate_chans(double transp,dataptr dz);
  79. static int put_thisdata_in_appropriate_chan(int cc,int vc, dataptr dz);
  80. static int do_specshift(int windows_in_buf,dataptr dz);
  81. static int do_the_specshift(dataptr dz);
  82. static int logread_shift(double timenow,int btktable_no,dataptr dz);
  83. static int read_value_from_brktable_using_log_interpolation(double thistime,int paramno,dataptr dz);
  84. static int reassign_frqs_to_appropriate_chans(dataptr dz);
  85. static int do_chan_shifting(int cc,int vc,dataptr dz);
  86. static int assign_new_frqs_to_appropriate_channels(dataptr dz);
  87. /**************************** SPECSHIFT ****************************/
  88. int specshift(dataptr dz)
  89. {
  90. int exit_status;
  91. int samps_read, windows_in_buf;
  92. dz->time = 0.0f;
  93. if(dz->bptrcnt <= 0) {
  94. sprintf(errstr,"flbufptr[0] not established by outer_shift_loop()\n");
  95. return(PROGRAM_ERROR);
  96. }
  97. while((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) > 0) {
  98. dz->flbufptr[0] = dz->bigfbuf;
  99. windows_in_buf = samps_read/dz->wanted;
  100. if((exit_status = do_specshift(windows_in_buf,dz))<0)
  101. return(exit_status);
  102. if((exit_status = write_exact_samps(dz->bigfbuf,samps_read,dz))<0)
  103. return(exit_status);
  104. }
  105. if(samps_read<0) {
  106. sprintf(errstr,"Sound read error.\n");
  107. return(SYSTEM_ERROR);
  108. }
  109. return(FINISHED);
  110. }
  111. /**************************** DO_SPECSHIFT ****************************/
  112. int do_specshift(int windows_in_buf,dataptr dz)
  113. {
  114. int exit_status;
  115. int wc;
  116. for(wc=0; wc<windows_in_buf; wc++) {
  117. if(dz->vflag[SHIFT_LOG]) {
  118. if(dz->brksize[SHIFT_SHIF]) {
  119. if((exit_status = logread_shift(dz->time,SHIFT_SHIF,dz))<0)
  120. return(exit_status);
  121. }
  122. if(dz->brksize[SHIFT_FRQ1]) {
  123. if((exit_status =
  124. read_value_from_brktable_using_log_interpolation((double)dz->time,SHIFT_FRQ1,dz))<0)
  125. return(exit_status);
  126. }
  127. if(dz->brksize[SHIFT_FRQ2]) {
  128. if((exit_status =
  129. read_value_from_brktable_using_log_interpolation((double)dz->time,SHIFT_FRQ2,dz))<0)
  130. return(exit_status);
  131. }
  132. } else {
  133. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  134. return(exit_status);
  135. }
  136. if((exit_status = do_the_specshift(dz))<0)
  137. return(exit_status);
  138. dz->flbufptr[0] += dz->wanted;
  139. dz->time = (float)(dz->time + dz->frametime);
  140. }
  141. return(FINISHED);
  142. }
  143. /**************************** DO_THE_SPECSHIFT ***************************
  144. *
  145. * linear frequency shift of spectrum.
  146. */
  147. int do_the_specshift(dataptr dz)
  148. {
  149. int cc, vc;
  150. switch(dz->mode) {
  151. case(SHIFT_ALL):
  152. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2)
  153. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + dz->param[SHIFT_SHIF]);
  154. break;
  155. case(SHIFT_ABOVE):
  156. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  157. if(dz->flbufptr[0][FREQ] > dz->param[SHIFT_FRQ1])
  158. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + dz->param[SHIFT_SHIF]);
  159. }
  160. break;
  161. case(SHIFT_BELOW):
  162. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  163. if(dz->flbufptr[0][FREQ] < dz->param[SHIFT_FRQ1])
  164. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + dz->param[SHIFT_SHIF]);
  165. }
  166. break;
  167. case(SHIFT_BETWEEN):
  168. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  169. if(dz->flbufptr[0][FREQ] > dz->param[SHIFT_FRQ1] && dz->flbufptr[0][FREQ] < dz->param[SHIFT_FRQ2])
  170. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + dz->param[SHIFT_SHIF]);
  171. }
  172. break;
  173. case(SHIFT_OUTSIDE):
  174. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  175. if(dz->flbufptr[0][FREQ] < dz->param[SHIFT_FRQ1] || dz->flbufptr[0][FREQ] > dz->param[SHIFT_FRQ2])
  176. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + dz->param[SHIFT_SHIF]);
  177. }
  178. break;
  179. default:
  180. sprintf(errstr,"Unkonwn mode in do_specshift()\n");
  181. return(PROGRAM_ERROR);
  182. }
  183. return reassign_frqs_to_appropriate_chans(dz);
  184. }
  185. /*************************** REASSIGN_FRQS_TO_APPROPRIATE_CHANS ***************************/
  186. int reassign_frqs_to_appropriate_chans(dataptr dz)
  187. {
  188. int exit_status;
  189. int cc, vc;
  190. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  191. dz->iparray[SHIFT_OVER][cc] = 0;
  192. dz->iparray[SHIFT_DONE][cc] = 0;
  193. }
  194. if(dz->param[SHIFT_SHIF] > 0.0) {
  195. for(cc=0,vc=0;cc< dz->clength; cc++, vc+=2) {
  196. if(dz->flbufptr[0][FREQ] > (float)dz->parray[SHIFT_CHTOP][cc])
  197. dz->iparray[SHIFT_OVER][cc] = 1;
  198. } /* Work down from top, shifting up */
  199. for(cc=dz->clength-1,vc=(dz->clength-1)*2;cc>=0; cc--, vc-=2) {
  200. if(dz->iparray[SHIFT_OVER][cc]) {
  201. if((exit_status = do_chan_shifting(cc,vc,dz))<0)
  202. return(exit_status);
  203. }
  204. }
  205. } /* Work up from bottom shifting down */
  206. if(dz->param[SHIFT_SHIF] < 0.0) {
  207. for(cc=1,vc=2;cc< dz->clength; cc++, vc+=2) {
  208. if(dz->flbufptr[0][FREQ] <= (float)dz->parray[SHIFT_CHTOP][cc-1]) {
  209. if((exit_status = do_chan_shifting(cc,vc,dz))<0)
  210. return(exit_status);
  211. }
  212. }
  213. }
  214. return(FINISHED);
  215. }
  216. /*************************** DO_CHAN_SHIFTING ***************************/
  217. int do_chan_shifting(int cc,int vc,dataptr dz)
  218. {
  219. int k = (int)((dz->flbufptr[0][FREQ] + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  220. int newvc = k * 2;
  221. if(k >=0 && k < dz->clength) {
  222. if(!dz->iparray[SHIFT_DONE][k]
  223. || (dz->iparray[SHIFT_DONE][k] && (dz->flbufptr[0][AMPP] > dz->flbufptr[0][newvc]))) {
  224. dz->flbufptr[0][newvc++] = dz->flbufptr[0][AMPP];
  225. dz->flbufptr[0][newvc] = dz->flbufptr[0][FREQ];
  226. dz->iparray[SHIFT_DONE][k] = 1;
  227. }
  228. }
  229. dz->flbufptr[0][AMPP] = 0.0f;
  230. dz->flbufptr[0][FREQ] = (float)dz->parray[SHIFT_CHMID][cc];
  231. return(FINISHED);
  232. }
  233. /*********************** SPECGLIS ***************************/
  234. int specglis(dataptr dz)
  235. {
  236. int exit_status;
  237. double pre_totalamp, post_totalamp;
  238. double scalefact;
  239. if(dz->brksize[GLIS_RATE])
  240. dz->param[GLIS_RATE] *= dz->param[GLIS_CONVERTOR];
  241. rectify_window(dz->flbufptr[0],dz);
  242. if((exit_status = extract_specenv(0,0,dz))<0)
  243. return(exit_status);
  244. if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
  245. return(exit_status);
  246. if(dz->mode != SELFGLIS) {
  247. if((exit_status = zero_sampbuf(dz))<0)
  248. return(exit_status);
  249. }
  250. if((exit_status = establish_frq_params(&scalefact,dz))<0)
  251. return(exit_status);
  252. if(dz->param[GLIS_RATE] <= 0.0) {
  253. if((exit_status = write_partials_moving_down(scalefact,dz))<0)
  254. return(exit_status);
  255. } else {
  256. if((exit_status = write_partials_moving_up(scalefact,dz))<0)
  257. return(exit_status);
  258. }
  259. if(dz->vflag[GLIS_FTOP]) {
  260. if((exit_status = cut_or_rolloff_high_frq(dz))<0)
  261. return(exit_status);
  262. }
  263. if((exit_status = get_totalamp(&post_totalamp,dz->flbufptr[0],dz->wanted))<0)
  264. return(exit_status);
  265. return normalise(pre_totalamp,post_totalamp,dz);
  266. }
  267. /*********************** ZERO_SAMPBUF **********************/
  268. int zero_sampbuf(dataptr dz)
  269. {
  270. int vc;
  271. for(vc = 0; vc < dz->wanted; vc += 2)
  272. dz->flbufptr[0][AMPP] = 0.0f;
  273. return(FINISHED);
  274. }
  275. /*********************** ESTABLISH_FRQ_PARAMS **********************/
  276. int establish_frq_params(double *scalefact,dataptr dz)
  277. {
  278. double thispitch;
  279. dz->param[GLIS_BASEFRQ] *= pow(2.0,dz->param[GLIS_RATE]);
  280. if(dz->param[GLIS_RATE] >= 0.0) { /* GOING UP */
  281. while(dz->param[GLIS_BASEFRQ] > GLIS_REFERENCE_FRQ * 2.0)
  282. dz->param[GLIS_BASEFRQ] /= 2.0;
  283. thispitch = log(dz->param[GLIS_BASEFRQ]);
  284. *scalefact = thispitch - dz->param[GLIS_REFPITCH];
  285. } else { /* GOING DOWN */
  286. while(dz->param[GLIS_BASEFRQ] < GLIS_REFERENCE_FRQ/2.0)
  287. dz->param[GLIS_BASEFRQ] *= 2.0;
  288. thispitch = log(dz->param[GLIS_BASEFRQ]);
  289. *scalefact = thispitch - dz->param[GLIS_HALF_REFPITCH];
  290. }
  291. return(FINISHED);
  292. }
  293. /********************* WRITE_PARTIALS_MOVING_DOWN *********************
  294. *
  295. * (0) Assume we start at fundamental.
  296. * (1) Calculate partials from where we are.
  297. * (2) Fade out odd partials.
  298. * (3) Move up by equal frq steps, or by multiples of current fundamental.
  299. */
  300. int write_partials_moving_down(double scalefact,dataptr dz)
  301. {
  302. int exit_status;
  303. int n, cc, vc; /* 0 */
  304. double fundamental, thisfrq, transpos;
  305. switch(dz->mode) {
  306. case(SELFGLIS):
  307. rectify_window(dz->flbufptr[0],dz);
  308. transpos = dz->param[GLIS_BASEFRQ]/GLIS_REFERENCE_FRQ;
  309. for(cc=0,vc=0;cc < dz->clength;cc++,vc+=2) {
  310. dz->amp[cc] = 0.0f;
  311. dz->freq[cc] = dz->flbufptr[0][FREQ];
  312. }
  313. for(vc=0;vc < dz->wanted; vc+=2) {
  314. if((exit_status = selfglis_down_within_spectral_envelope(vc,transpos,dz))<0)
  315. return(exit_status);
  316. }
  317. if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0)
  318. return(exit_status);
  319. break;
  320. case(INHARMONIC):
  321. case(SHEPARD):
  322. fundamental = dz->param[GLIS_BASEFRQ]; /* 1 */
  323. thisfrq = dz->param[GLIS_BASEFRQ];
  324. n = 1;
  325. while(thisfrq < dz->nyquist) {
  326. if((exit_status = glis_down_within_spectral_envelope(fundamental,&thisfrq,scalefact,&n,dz))<0)
  327. return(exit_status);
  328. }
  329. break;
  330. default:
  331. sprintf(errstr,"Unknown mode in write_partials_moving_down()\n");
  332. return(PROGRAM_ERROR);
  333. }
  334. return(FINISHED);
  335. }
  336. /************************ WRITE_PARTIALS_MOVING_UP ***********************
  337. *
  338. * (0) Assume we start at 2nd harmonic.
  339. * (1) Calculate partials from a fundamental an 8va below ref pitch.
  340. * (2) Fade in lowest component, and odd partials.
  341. * (3) Move up by equal frq steps, or by multiples of current fundamental.
  342. */
  343. int write_partials_moving_up(double scalefact,dataptr dz)
  344. {
  345. int exit_status;
  346. int n = 2, cc, vc; /* 0 */
  347. double fundamental = dz->param[GLIS_BASEFRQ]/2.0; /* 1 */
  348. double thisfrq = dz->param[GLIS_BASEFRQ];
  349. double transpos;
  350. switch(dz->mode) {
  351. case(SELFGLIS) :
  352. transpos = dz->param[GLIS_BASEFRQ]/ GLIS_REFERENCE_FRQ;
  353. for(cc=0,vc=0;cc < dz->clength;cc++,vc+=2) {
  354. dz->amp[cc] = 0.0f;
  355. dz->freq[cc] = dz->flbufptr[0][FREQ];
  356. }
  357. for(vc=0;vc < dz->wanted;vc+=2) {
  358. if((exit_status = selfglis_up_within_spectral_envelope(vc,transpos,dz))<0)
  359. return(exit_status);
  360. }
  361. if((exit_status = put_amp_and_frq(dz->flbufptr[0],dz))<0)
  362. return(exit_status);
  363. break;
  364. case(SHEPARD):
  365. case(INHARMONIC):
  366. while(thisfrq < dz->nyquist) {
  367. if((exit_status = glis_up_within_spectral_envelope(fundamental,&thisfrq,scalefact,&n,dz))<0)
  368. return(exit_status);
  369. }
  370. break;
  371. default:
  372. sprintf(errstr,"Unknown mode in write_partials_moving_up()\n");
  373. return(PROGRAM_ERROR);
  374. }
  375. return(FINISHED);
  376. }
  377. /****************************** CUT_OR_ROLLOFF_HIGH_FRQ *****************************/
  378. int cut_or_rolloff_high_frq(dataptr dz)
  379. {
  380. int vc;
  381. for(vc = 0; vc < dz->wanted;vc += 2) {
  382. if(dz->flbufptr[0][FREQ] > dz->param[GLIS_HIFRQ]) {
  383. if(dz->flbufptr[0][FREQ] >= dz->param[GLIS_FRQTOP_TOP])
  384. dz->flbufptr[0][AMPP] = 0.0f;
  385. else
  386. dz->flbufptr[0][AMPP] =
  387. (float)(dz->flbufptr[0][AMPP] * (dz->param[GLIS_FRQTOP_TOP] - dz->flbufptr[0][FREQ])/dz->param[GLIS_ROLL_OFF]);
  388. }
  389. }
  390. return(FINISHED);
  391. }
  392. /******************* SELFGLIS_DOWN_WITHIN_SPECTRAL_ENVELOPE ********************/
  393. int selfglis_down_within_spectral_envelope(int vc,double transpos,dataptr dz)
  394. {
  395. int exit_status;
  396. double ampratio, amphere, thisfrq, thisamp, frqhi, amphi;
  397. int n;
  398. if((exit_status = getspecenvamp(&amphere,dz->flbufptr[0][FREQ],0,dz))<0)
  399. return(exit_status);
  400. if(amphere <= VERY_SMALL)
  401. ampratio = 0.0;
  402. else {
  403. if((ampratio = fabs(dz->flbufptr[0][AMPP]/amphere)) > RATIO_LIMIT)
  404. ampratio = RATIO_LIMIT;
  405. }
  406. if((thisfrq = fabs(dz->flbufptr[0][FREQ]) * transpos) < dz->nyquist) {
  407. if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
  408. return(exit_status);
  409. thisamp *= ampratio;
  410. thisamp *= pow(max(0.0,(transpos * 2.0) - 1.0),SMOOTHER);
  411. if((exit_status = get_channel_corresponding_to_frq(&n,thisfrq,dz))<0)
  412. return(exit_status);
  413. if(n >=0 && n < dz->clength && thisamp > dz->amp[n]) {
  414. dz->amp[n++] = (float)thisamp;
  415. dz->freq[n] = (float)thisfrq;
  416. }
  417. }
  418. if((frqhi = thisfrq * 2.0) < dz->nyquist) {
  419. if((exit_status = getspecenvamp(&amphi,frqhi,0,dz))<0)
  420. return(exit_status);
  421. amphi *= ampratio;
  422. amphi *= pow(max(0.0,2.0 - (transpos * 2.0)),SMOOTHER);
  423. if((exit_status = get_channel_corresponding_to_frq(&n,thisfrq,dz))<0)
  424. return(exit_status);
  425. if(n >=0 && n < dz->clength && amphi > dz->amp[n]) {
  426. dz->amp[n++] = (float)amphi;
  427. dz->freq[n] = (float)frqhi;
  428. }
  429. }
  430. return(FINISHED);
  431. }
  432. /******************* GLIS_DOWN_WITHIN_SPECTRAL_ENVELOPE ********************/
  433. int glis_down_within_spectral_envelope(double fundamental,double *thisfrq,double scalefact,int *n,dataptr dz)
  434. {
  435. int exit_status;
  436. int cc, vc;
  437. double thisamp;
  438. if((exit_status = get_channel_corresponding_to_frq(&cc,*thisfrq,dz))<0)
  439. return(exit_status);
  440. vc = cc * 2;
  441. dz->flbufptr[0][FREQ] = (float)(*thisfrq);
  442. if((exit_status = getspecenvamp(&thisamp,*thisfrq,0,dz))<0)
  443. return(exit_status);
  444. dz->flbufptr[0][AMPP] = (float)thisamp;
  445. if(ODD(*n))
  446. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * scalefact); /* 2 */
  447. (*n)++;
  448. switch(dz->mode) {
  449. case(INHARMONIC): *thisfrq += dz->param[GLIS_SHIFT]; break;
  450. case(SHEPARD): *thisfrq = fundamental * (double)(*n); break;
  451. } /* 3 */
  452. return(FINISHED);
  453. }
  454. /******************* SELFGLIS_UP_WITHIN_SPECTRAL_ENVELOPE ********************/
  455. int selfglis_up_within_spectral_envelope(int vc,double transpos,dataptr dz)
  456. {
  457. int exit_status;
  458. double amphere, ampratio;
  459. double thisfrq, thisamp, frqlo, amplo;
  460. int n;
  461. if((exit_status = getspecenvamp(&amphere,dz->flbufptr[0][FREQ],0,dz))<0)
  462. return(exit_status);
  463. if(amphere <= VERY_SMALL)
  464. ampratio = 0.0;
  465. else {
  466. if((ampratio = fabs(dz->flbufptr[0][AMPP]/amphere)) > RATIO_LIMIT)
  467. ampratio = RATIO_LIMIT;
  468. }
  469. if((thisfrq = fabs(dz->flbufptr[0][FREQ]) * transpos) < dz->nyquist) {
  470. if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
  471. return(exit_status);
  472. thisamp *= ampratio;
  473. thisamp *= pow(2.0 - transpos,SMOOTHER);
  474. if((exit_status = get_channel_corresponding_to_frq(&n,thisfrq,dz))<0)
  475. return(exit_status);
  476. if(n >=0 && n < dz->clength && thisamp > dz->amp[n]) {
  477. dz->amp[n] = (float)thisamp;
  478. dz->freq[n] = (float)thisfrq;
  479. }
  480. }
  481. if((frqlo = thisfrq/2.0) < dz->nyquist) {
  482. if((exit_status = getspecenvamp(&amplo,frqlo,0,dz))<0)
  483. return(exit_status);
  484. amplo *= ampratio;
  485. amplo *= pow(transpos - 1.0,SMOOTHER);
  486. exit_status = get_channel_corresponding_to_frq(&n,thisfrq,dz);
  487. if(n < dz->clength && amplo > dz->amp[n]) {
  488. dz->amp[n] = (float)amplo;
  489. dz->freq[n] = (float)frqlo;
  490. }
  491. }
  492. return(FINISHED);
  493. }
  494. /******************* GLIS_UP_WITHIN_SPECTRAL_ENVELOPE ********************/
  495. int glis_up_within_spectral_envelope(double fundamental,double *thisfrq,double scalefact,int *n,dataptr dz)
  496. {
  497. int exit_status;
  498. int cc, vc;
  499. double thisamp;
  500. if((exit_status = get_channel_corresponding_to_frq(&cc,*thisfrq,dz))<0)
  501. return(exit_status);
  502. vc = cc * 2;
  503. dz->flbufptr[0][FREQ] = (float)(*thisfrq);
  504. if((exit_status = getspecenvamp(&thisamp,*thisfrq,0,dz))<0)
  505. return(exit_status);
  506. dz->flbufptr[0][AMPP] = (float)thisamp;
  507. if(ODD(*n) || *n==2)
  508. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * scalefact); /* 2 */
  509. (*n)++;
  510. switch(dz->mode) {
  511. case(INHARMONIC):*thisfrq += dz->param[GLIS_HALF_SHIFT]; break;
  512. case(SHEPARD): *thisfrq = fundamental * (double)(*n); break;
  513. } /* 3 */
  514. return(FINISHED);
  515. }
  516. /*************************** SPECINVERT *********************/
  517. int specinvert(dataptr dz)
  518. {
  519. int exit_status;
  520. double zort, pre_totalamp;
  521. int cc, vc;
  522. switch(dz->mode) {
  523. case(INV_NORMAL):
  524. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  525. dz->flbufptr[0][AMPP] = dz->amp[cc] - dz->flbufptr[0][AMPP];
  526. break;
  527. case(INV_KEEPAMP):
  528. if((exit_status = get_totalamp(&pre_totalamp,dz->flbufptr[0],dz->wanted))<0)
  529. return(exit_status);
  530. if(pre_totalamp > MINAMP) {
  531. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  532. zort = dz->parray[INV_AMPRATIO][cc] - (dz->flbufptr[0][vc]/pre_totalamp);
  533. dz->flbufptr[0][vc] = (float)(zort * pre_totalamp);
  534. }
  535. }
  536. break;
  537. }
  538. return(FINISHED);
  539. }
  540. /******************************* SPECWAVER ********************************/
  541. int specwaver(dataptr dz)
  542. {
  543. int exit_status = FINISHED;
  544. double duration = dz->wlength * dz->frametime;
  545. int wcnt, upwcnt, dnwcnt, wc, samps_read, w_to_buf;
  546. if(duration <= 0.0) {
  547. sprintf(errstr,"Zero length analysis file: cannot proceed.\n");
  548. return(DATA_ERROR);
  549. }
  550. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->big_fsize,dz->ifd[0],0)) > 0) {
  551. dz->flbufptr[0] = dz->bigfbuf;
  552. w_to_buf = samps_read/dz->wanted;
  553. wc = 0;
  554. }
  555. else {
  556. if(samps_read<0) {
  557. sprintf(errstr,"Sound read error.\n");
  558. return(SYSTEM_ERROR);
  559. }
  560. sprintf(errstr,"No windows found. specwaver()\n");
  561. return(PROGRAM_ERROR);
  562. }
  563. while(dz->time < duration) {
  564. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  565. return(exit_status);
  566. wcnt = round(1.0/(dz->param[WAVER_VIB] * dz->frametime));
  567. dnwcnt = upwcnt = wcnt/2;
  568. if(ODD(wcnt))
  569. upwcnt++;
  570. if((exit_status = do_waver(&wc,&w_to_buf,&samps_read,wcnt,upwcnt,dnwcnt,dz))!=CONTINUE)
  571. break;
  572. }
  573. return(exit_status);
  574. }
  575. /******************************** DO_WAVER *******************************/
  576. int do_waver(int *wc,int *w_to_buf,int *samps_read,int wcnt,int upwcnt,int dnwcnt,dataptr dz)
  577. {
  578. int exit_status;
  579. int n;
  580. double strstep = dz->param[WAVER_STR]/(double)upwcnt;
  581. double thisstr = dz->param[WAVER_STR];
  582. for(n=0;n<upwcnt;n++) {
  583. if((exit_status = spectrally_stretch_window(thisstr,dz))<0)
  584. return(exit_status);
  585. if((exit_status = advance_along_windows(wc,w_to_buf,samps_read,dz))!=CONTINUE)
  586. return(exit_status);
  587. thisstr += strstep;
  588. }
  589. if(ODD(wcnt))
  590. thisstr -= strstep;
  591. for(n=0;n<dnwcnt;n++) {
  592. if((exit_status = spectrally_stretch_window(thisstr,dz))<0)
  593. return(exit_status);
  594. if((exit_status = advance_along_windows(wc,w_to_buf,samps_read,dz))!=CONTINUE)
  595. return(exit_status);
  596. thisstr -= strstep;
  597. }
  598. return(CONTINUE);
  599. }
  600. /*********************** SPECTRALLY_STRETCH_WINDOW *****************************/
  601. int spectrally_stretch_window(double thisstr,dataptr dz)
  602. {
  603. int dd;
  604. int cc, vc;
  605. double herestr, thislocation, strdiff = thisstr - 1.0;
  606. for(dd=0,cc=dz->iparam[WAVER_BOTCHAN],vc=dz->iparam[WAVER_BOTCHAN]*2; cc < dz->clength; dd++,cc++,vc+=2) {
  607. thislocation = (double)dd/(double)dz->iparam[WAVER_STRCHANS];
  608. if(dz->mode==WAVER_SPECIFIED)
  609. thislocation = pow(thislocation,dz->param[WAVER_EXP]);
  610. herestr = (thislocation * strdiff) + 1.0;
  611. dz->amp[cc] = dz->flbufptr[0][AMPP];
  612. dz->freq[cc] = (float)fabs(dz->flbufptr[0][FREQ] * herestr);
  613. }
  614. return assign_new_frqs_to_appropriate_channels(dz);
  615. }
  616. /***************************** ADVANCE_ALONG_WINDOWS *************************/
  617. int advance_along_windows(int *wc,int *w_to_buf,int *samps_read,dataptr dz)
  618. {
  619. int exit_status;
  620. dz->flbufptr[0] += dz->wanted;
  621. if(++(*wc) >= *w_to_buf) {
  622. if(*samps_read > 0) {
  623. if((exit_status = write_exact_samps(dz->bigfbuf,*samps_read,dz))<0)
  624. return(exit_status);
  625. }
  626. if((*samps_read = fgetfbufEx(dz->bigfbuf, dz->big_fsize,dz->ifd[0],0)) > 0) {
  627. dz->flbufptr[0] = dz->bigfbuf;
  628. *w_to_buf = *samps_read/dz->wanted;
  629. *wc = 0;
  630. } else {
  631. //TW CORRECTED indirection error : Dec 2002
  632. if(*samps_read<0) {
  633. sprintf(errstr,"Sound read error.\n");
  634. return(SYSTEM_ERROR);
  635. }
  636. return(FINISHED);
  637. }
  638. }
  639. dz->time = (float)(dz->time + dz->frametime);
  640. return(CONTINUE);
  641. }
  642. /****************************** SPECWARP ***************************/
  643. int specwarp(dataptr dz)
  644. {
  645. int exit_status;
  646. int avcnt;
  647. if(sloom) {
  648. fprintf(stdout,"INFO: Warping pitch.\n");
  649. fflush(stdout);
  650. }
  651. if((exit_status = warp_pitch(&avcnt,dz))<0)
  652. return(exit_status);
  653. if(sloom) {
  654. fprintf(stdout,"INFO: Warping time.\n");
  655. fflush(stdout);
  656. }
  657. return warp_time(avcnt,dz);
  658. }
  659. /************************** WARP_PITCH ************************/
  660. int warp_pitch(int *avcnt,dataptr dz)
  661. {
  662. int exit_status;
  663. int n = 0, lastpos = 0, thispos, diff, q, start;
  664. double lastmidi;
  665. double ttime, thismidi;
  666. initrand48();
  667. if((exit_status = get_pitch_averages(avcnt,dz))<0)
  668. return(exit_status);
  669. if((exit_status = get_statechanges(*avcnt,WARP_SRNG,WARP_AVP,WARP_CHANGE,WARP_MININT,-WARP_MININT,IS_PITCH,dz))<0)
  670. return(exit_status);
  671. while(dz->parray[WARP_AVP][n] < MIDIMIN) {
  672. if(++n >= *avcnt) {
  673. sprintf(errstr,"No valid pitch-average data found: warp_pitch()\n");
  674. return(PROGRAM_ERROR);
  675. }
  676. }
  677. dz->iparray[WARP_CHANGE][n] = 1;
  678. start = n;
  679. for(;n < *avcnt;n++) {
  680. if(dz->iparray[WARP_CHANGE][n]) {
  681. if((exit_status = setup_and_do_pitchwarp(start,n,&lastpos,&lastmidi,dz))<0)
  682. return(exit_status);
  683. }
  684. }
  685. thispos = (dz->wlength - 1);
  686. if((diff = thispos - lastpos) > 0) {
  687. q = (*avcnt) - 1;
  688. while(dz->parray[WARP_AVP][q]<MIDIMIN) {
  689. if(--q<=lastpos)
  690. return(FINISHED);
  691. }
  692. thismidi = dz->parray[WARP_AVP][q];
  693. ttime = (q * BLOKCNT) * dz->frametime;
  694. if((exit_status = do_pitch_wiggle(&thismidi,ttime,dz))<0)
  695. return(exit_status);
  696. if((exit_status = warp_pitches(thispos,diff,&lastpos,thismidi,&lastmidi,dz))<0)
  697. return(exit_status);
  698. }
  699. return(FINISHED);
  700. }
  701. /************************** WARP_TIME ************************/
  702. int warp_time(int avcnt,dataptr dz)
  703. {
  704. int exit_status = CONTINUE;
  705. int lastoutpos = 0, lastinpos = 0, indiff, remain;
  706. int n, ip, samps_read;
  707. int last_total_wndws = 0;
  708. float *nextbuf = dz->flbufptr[0] + dz->wanted, *thisbuf = dz->flbufptr[0];
  709. if(sloom)
  710. dz->total_samps_read = 0;
  711. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) <= 0) {
  712. if(samps_read<0) {
  713. sprintf(errstr,"Sound read error.\n");
  714. return(SYSTEM_ERROR);
  715. } else {
  716. sprintf(errstr,"Cannot read data from input analysis file.\n");
  717. return(DATA_ERROR);
  718. }
  719. }
  720. if(sloom)
  721. dz->total_samps_read += samps_read;
  722. dz->iparam[WARP_WREAD] = samps_read/dz->wanted;
  723. if((dz->flbufptr[6] = dz->bigfbuf + samps_read)!=dz->flbufptr[2]) {
  724. dz->iparam[WARP_PART_INBUF] = 1;
  725. dz->iparam[WARP_ATEND] = 1;
  726. }
  727. for(n=0;n<avcnt;n++) {
  728. if(dz->iparray[WARP_CHANGE][n]) {
  729. if((exit_status = setup_and_do_timewarp(&thisbuf,&nextbuf,n,&lastoutpos,&lastinpos,&last_total_wndws,dz))<0)
  730. return(exit_status);
  731. }
  732. if(exit_status!=CONTINUE)
  733. break;
  734. }
  735. if((indiff = (dz->wlength - 1) - lastinpos) > 0) {
  736. ip = lastinpos + 1;
  737. while(lastinpos < dz->wlength) {
  738. if((exit_status = adjust_input_buffers(&thisbuf,&nextbuf,ip,&last_total_wndws,0,dz))<0)
  739. return(exit_status);
  740. if(dz->flbufptr[1]!=thisbuf)
  741. memmove((char *)dz->flbufptr[1],(char *)thisbuf,(size_t)(dz->wanted * sizeof(float)));
  742. if((dz->flbufptr[1] += dz->wanted) >= dz->flbufptr[3]) {
  743. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->big_fsize,dz))<0)
  744. return(exit_status);
  745. dz->flbufptr[1] = dz->flbufptr[2];
  746. }
  747. lastinpos++; /* MAY 1997 ??? */
  748. ip = lastinpos; /* MAY 1997 ??? */
  749. }
  750. }
  751. if((remain = (dz->flbufptr[1] - dz->flbufptr[2]))>0) {
  752. if((exit_status = write_samps(dz->flbufptr[2],remain,dz))<0)
  753. return(exit_status);
  754. }
  755. return(FINISHED);
  756. }
  757. /************************** GET_PITCH_AVERAGES ************************/
  758. int get_pitch_averages(int *avcnt,dataptr dz)
  759. {
  760. int k = 0, OK = 1, n = 0, m, cnt;
  761. while(OK) {
  762. dz->parray[WARP_AVP][k] = 0.0;
  763. m = 0;
  764. cnt = 0;
  765. while(m < BLOKCNT) {
  766. if(dz->pitches[n]<MIDIMIN) {
  767. m++;
  768. if(++n >= dz->wlength) {
  769. OK = 0;
  770. break;
  771. }
  772. continue;
  773. }
  774. dz->parray[WARP_AVP][k] += dz->pitches[n];
  775. cnt++;
  776. m++;
  777. if(++n >= dz->wlength) {
  778. OK = 0;
  779. break;
  780. }
  781. }
  782. if(cnt==0)
  783. dz->parray[WARP_AVP][k] = -1.0;
  784. else
  785. dz->parray[WARP_AVP][k] /= (double)cnt;
  786. k++;
  787. }
  788. if((dz->parray[WARP_AVP] = (double *)realloc((char *)dz->parray[WARP_AVP],k * sizeof(double)))==NULL) {
  789. sprintf(errstr,"INSUFFICIENT MEMORY for warp averages array.\n");
  790. return(MEMORY_ERROR);
  791. }
  792. *avcnt = k;
  793. return(FINISHED);
  794. }
  795. /************************** SETUP_AND_DO_PITCHWARP ************************/
  796. int setup_and_do_pitchwarp(int start,int avg_no,int *lastpos,double *lastmidi,dataptr dz)
  797. {
  798. int exit_status;
  799. int here, q, z, diff;
  800. double thismidi, ttime;
  801. here = min((dz->wlength - 1),avg_no * BLOKCNT); /* just being ultra careful !! */
  802. for(q = here; q < here+BLOKCNT; q++) {
  803. if(q>=dz->wlength)
  804. break;
  805. if(dz->pitches[q] >= MIDIMIN)
  806. break;
  807. }
  808. if(q >= here+BLOKCNT || q>=dz->wlength) { /* No valid pitchdata here !! */
  809. for(z=here; z<q; z++)
  810. dz->parray[WARP_P2][z] = -1.0;
  811. dz->iparray[WARP_CHANGE][avg_no] = 0;
  812. return(FINISHED);
  813. } else /* [WARP_CHANGE] remembers position of approp wndw to work on */
  814. dz->iparray[WARP_CHANGE][avg_no] = q;
  815. here = q;
  816. ttime = dz->frametime * (double)here;
  817. thismidi = dz->pitches[here];
  818. if((exit_status = do_pitch_wiggle(&thismidi,ttime,dz))<0)
  819. return(exit_status);
  820. if(avg_no==start) {
  821. dz->parray[WARP_P2][q] = thismidi;
  822. *lastpos = q;
  823. *lastmidi = thismidi;
  824. return(FINISHED);
  825. }
  826. diff = q - *lastpos;
  827. return warp_pitches(q,diff,lastpos,thismidi,lastmidi,dz);
  828. }
  829. /***************** DO_PITCH_WIGGLE *******************/
  830. int do_pitch_wiggle(double *thismidi,double ttime, dataptr dz)
  831. {
  832. int exit_status;
  833. double wiggle, this_prange;
  834. if(dz->brksize[WARP_PRNG]) {
  835. if((exit_status = read_value_from_brktable(ttime,WARP_PRNG,dz))<0)
  836. return(exit_status);
  837. }
  838. wiggle = (drand48() * 2.0) -1.0; /* random +- */
  839. this_prange = wiggle * dz->param[WARP_PRNG];
  840. *thismidi += this_prange;
  841. return(FINISHED);
  842. }
  843. /***************** WARP_PITCHES *******************/
  844. int warp_pitches(int thispos,int diff,int *lastpos,double thismidi,double *lastmidi,dataptr dz)
  845. {
  846. int n, m;
  847. double mididiff = thismidi - *lastmidi;
  848. double midistep = mididiff/(double)diff;
  849. for(m=1, n=(*lastpos)+1; m <= diff; m++, n++) {
  850. if(n < dz->wlength && dz->pitches[n]<MIDIMIN) {
  851. dz->parray[WARP_P2][n] = -1.0;
  852. continue;
  853. }
  854. thismidi = *lastmidi + (midistep * (double)m);
  855. dz->parray[WARP_P2][n] = thismidi;
  856. }
  857. *lastmidi = thismidi;
  858. *lastpos = thispos;
  859. return(FINISHED);
  860. }
  861. /************************** SETUP_AND_DO_TIMEWARP ************************/
  862. int setup_and_do_timewarp
  863. (float **thisbuf,float **nextbuf,int n,int *lastoutpos,int *lastinpos,int *last_total_wndws,dataptr dz)
  864. {
  865. int exit_status;
  866. int thisoutpos, outdiff;
  867. int thisinpos = dz->iparray[WARP_CHANGE][n];
  868. double ttime = dz->frametime * (double)thisinpos;
  869. if(n==0) {
  870. if((exit_status = transpos_initial_windows(thisbuf,nextbuf,thisinpos,last_total_wndws,dz))!=CONTINUE)
  871. return(exit_status);
  872. *lastinpos = thisinpos;
  873. *lastoutpos = thisinpos;
  874. } else {
  875. if((exit_status = do_time_wiggle(&ttime,dz))<0)
  876. return(exit_status);
  877. thisoutpos = round(ttime/dz->frametime);
  878. thisoutpos = max(0L,thisoutpos);
  879. if((outdiff = thisoutpos - *lastoutpos)>0) {/* number of windows to scan in output data */
  880. if((exit_status = do_timewarp(thisbuf,nextbuf,thisinpos,outdiff,lastinpos,last_total_wndws,dz))!=CONTINUE)
  881. return(exit_status);
  882. }
  883. *lastinpos = thisinpos; /* ??? */
  884. *lastoutpos = thisoutpos; /* ??? */
  885. }
  886. return(CONTINUE);
  887. }
  888. /***************** ADJUST_INPUT_BUFFERS *******************/
  889. int adjust_input_buffers(float **thisbuf,float **nextbuf,int thisindex,int *last_total_wndws,int do_next,dataptr dz)
  890. {
  891. int exit_status;
  892. int currentbuf_index, currentbuf_nextindex;
  893. currentbuf_index = thisindex - *last_total_wndws;
  894. if(currentbuf_index >= dz->iparam[WARP_WREAD]) {
  895. if((exit_status = find_currentbuf_index(&currentbuf_index,last_total_wndws,thisbuf,dz))!=CONTINUE)
  896. return(exit_status);
  897. }
  898. if(do_next) {
  899. currentbuf_nextindex = currentbuf_index + 1;
  900. if(currentbuf_nextindex >= dz->iparam[WARP_WREAD]) {
  901. if(dz->flbufptr[3]!=*thisbuf)
  902. memmove((char *)dz->flbufptr[3],(char *)(*thisbuf),(size_t)(dz->wanted * sizeof(float)));
  903. *thisbuf = dz->flbufptr[3];
  904. if((exit_status = find_currentbuf_nextindex(&currentbuf_nextindex,*last_total_wndws,dz))<0)
  905. return(exit_status);
  906. *nextbuf = dz->bigfbuf + (currentbuf_nextindex * dz->wanted);
  907. }
  908. }
  909. return(FINISHED);
  910. }
  911. /***************** TRANSPOS_INITIAL_WINDOWS ******************/
  912. int transpos_initial_windows(float **thisbuf,float **nextbuf,int cnt,int *last_total_wndws,dataptr dz)
  913. {
  914. int exit_status;
  915. int cc, vc;
  916. int n = 0, samps_to_write, samps_read;
  917. double transp;
  918. while(n <= cnt) {
  919. rectify_window(dz->flbufptr[0],dz);
  920. if(dz->pitches[n] > MIDIMIN) {
  921. transp = SEMITONES_AS_RATIO(dz->parray[WARP_P2][n] - dz->pitches[n]);
  922. for(cc=0,vc=0;cc<dz->clength;cc++,vc+=2) {
  923. dz->flbufptr[1][AMPP] = dz->flbufptr[0][AMPP];
  924. dz->flbufptr[1][FREQ] = (float)(dz->flbufptr[0][FREQ] * transp);
  925. }
  926. if((exit_status = put_transposed_data_in_appropriate_chans(transp,dz))<0)
  927. return(exit_status);
  928. } else {
  929. for(vc=0;vc<dz->wanted;vc+=2)
  930. dz->flbufptr[1][vc] = dz->flbufptr[0][vc]; /* Copy unpitched windows */
  931. }
  932. dz->flbufptr[1] += dz->wanted;
  933. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[6]) {
  934. if(dz->iparam[WARP_PART_INBUF]) {
  935. if((samps_to_write = dz->flbufptr[1] - dz->flbufptr[2])>0)
  936. return write_samps(dz->flbufptr[2],samps_to_write,dz);
  937. return FINISHED;
  938. } else {
  939. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->big_fsize,dz))<0)
  940. return(exit_status);
  941. }
  942. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) <= 0) {
  943. if(samps_read<0) {
  944. sprintf(errstr,"Sound read error.\n");
  945. return(SYSTEM_ERROR);
  946. }
  947. return(FINISHED);
  948. }
  949. if(sloom)
  950. dz->total_samps_read += samps_read;
  951. *last_total_wndws += dz->iparam[WARP_WREAD];
  952. dz->iparam[WARP_WREAD] = samps_read/dz->wanted;
  953. if(samps_read < dz->big_fsize) {
  954. dz->iparam[WARP_PART_INBUF] = 1;
  955. dz->flbufptr[6] = dz->bigfbuf + samps_read;
  956. }
  957. dz->flbufptr[1] = dz->flbufptr[2];
  958. dz->flbufptr[0] = dz->bigfbuf;
  959. }
  960. n++;
  961. }
  962. if((exit_status = setup_thisbuf_and_nextbuf(*last_total_wndws,thisbuf,nextbuf,dz))<0)
  963. return(exit_status);
  964. return(CONTINUE);
  965. }
  966. /************************** DO_TIME_WIGGLE ************************/
  967. int do_time_wiggle(double *ttime,dataptr dz)
  968. {
  969. int exit_status;
  970. double this_trange;
  971. double wiggle = (drand48() * 2.0) -1.0;
  972. if(dz->brksize[WARP_TRNG]) { /* RWD need curly */
  973. if((exit_status = read_value_from_brktable(*ttime,WARP_TRNG,dz))<0)
  974. return(exit_status);
  975. }
  976. this_trange = dz->param[WARP_TRNG] * wiggle;
  977. *ttime += this_trange;
  978. return(FINISHED);
  979. }
  980. /************************** DO_TIMEWARP ************************/
  981. int do_timewarp
  982. (float **thisbuf,float **nextbuf,int thisinpos,int outdiff,int *lastinpos,int *last_total_wndws,dataptr dz)
  983. {
  984. int exit_status;
  985. int indiff = thisinpos - *lastinpos; /* number of windows to scan in input data */
  986. double step = (double)indiff/(double)outdiff; /* fractional step in input data */
  987. int move;
  988. int n, ip, lastip = *lastinpos;
  989. double thisfrac, thisindex = (double)(*lastinpos) + step; /* fractional position in input data */
  990. double oldmidi, newmidi, transp;
  991. for(n=1; n <= outdiff; n++, thisindex+=step) {
  992. ip = (int)thisindex; /* TRUNCATE */
  993. thisfrac = thisindex - (double)ip;
  994. move = ip - lastip;
  995. lastip = ip;
  996. if(move) {
  997. if((exit_status = adjust_input_buffers(thisbuf,nextbuf,ip,last_total_wndws,1,dz))!=CONTINUE)
  998. return(exit_status);
  999. }
  1000. if((exit_status = interp_between_vals_in_two_bufs(*thisbuf,*nextbuf,thisfrac,dz))<0)
  1001. return(exit_status);
  1002. if((exit_status = interp_between_pitch_vals(&oldmidi,dz->pitches,ip,thisfrac,dz))<0)
  1003. return(exit_status);
  1004. if((exit_status = interp_between_pitch_vals2(&newmidi,dz->parray[WARP_P2],ip,thisfrac,dz))<0)
  1005. return(exit_status);
  1006. transp = SEMITONES_AS_RATIO(newmidi - oldmidi);
  1007. if((exit_status = transpose_outbuf(transp,dz))<0)
  1008. return(exit_status);
  1009. if((dz->flbufptr[1] += dz->wanted) >= dz->flbufptr[3]) {
  1010. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->big_fsize,dz))<0)
  1011. return(exit_status);
  1012. dz->flbufptr[1] = dz->flbufptr[2];
  1013. }
  1014. }
  1015. return(CONTINUE);
  1016. }
  1017. /***************** FIND_CURRENTBUF_INDEX *******************/
  1018. int find_currentbuf_index(int *currentbuf_index,int *last_total_wndws,float **thisbuf,dataptr dz)
  1019. {
  1020. int samps_read = 0;
  1021. int finalbuf_index;
  1022. if(dz->iparam[WARP_ATEND]) {
  1023. *currentbuf_index = max((dz->wlength - 2) - (*last_total_wndws),0);
  1024. return(CONTINUE);
  1025. }
  1026. while(*currentbuf_index >= dz->iparam[WARP_WREAD]) {
  1027. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0)) <= 0) {
  1028. if(samps_read<0) {
  1029. sprintf(errstr,"Sound read error.\n");
  1030. return(SYSTEM_ERROR);
  1031. }
  1032. return(FINISHED);
  1033. }
  1034. if(sloom)
  1035. dz->total_samps_read += samps_read;
  1036. if(samps_read <= dz->big_fsize)
  1037. dz->iparam[WARP_ATEND] = 1;
  1038. *currentbuf_index -= dz->iparam[WARP_WREAD];
  1039. *last_total_wndws += dz->iparam[WARP_WREAD];
  1040. if(dz->iparam[WARP_ATEND]) {
  1041. finalbuf_index = max((dz->wlength - 2) - (*last_total_wndws),0);
  1042. *currentbuf_index = min(*currentbuf_index,finalbuf_index);
  1043. }
  1044. }
  1045. dz->iparam[WARP_WREAD] = samps_read/dz->wanted;
  1046. if(dz->iparam[WARP_ATEND])
  1047. dz->flbufptr[6] = dz->bigfbuf + samps_read;
  1048. *thisbuf = dz->bigfbuf + (*currentbuf_index * dz->wanted);
  1049. return(CONTINUE);
  1050. }
  1051. /***************** FIND_CURRENTBUF_NEXTINDEX *******************/
  1052. int find_currentbuf_nextindex(int *currentbuf_nextindex,int last_total_wndws,dataptr dz)
  1053. {
  1054. int samps_read;
  1055. int lastindex = (dz->wlength - 1) - last_total_wndws;
  1056. *currentbuf_nextindex = lastindex;
  1057. if(dz->iparam[WARP_ATEND])
  1058. return(FINISHED);
  1059. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->big_fsize,dz->ifd[0],0)) <= 0) {
  1060. if(samps_read<0) {
  1061. sprintf(errstr,"Sound read error.\n");
  1062. return(SYSTEM_ERROR);
  1063. }
  1064. dz->iparam[WARP_ATEND] = 1;
  1065. return(FINISHED);
  1066. }
  1067. if(sloom)
  1068. dz->total_samps_read += samps_read;
  1069. dz->iparam[WARP_WREAD] = samps_read/dz->wanted;
  1070. if(samps_read < dz->big_fsize) {
  1071. dz->iparam[WARP_ATEND] = 1;
  1072. dz->flbufptr[6] = dz->bigfbuf + samps_read;
  1073. }
  1074. *currentbuf_nextindex = 0L;
  1075. return(FINISHED);
  1076. }
  1077. /***************** SETUP_THISBUF_AND_NEXTBUF *******************/
  1078. int setup_thisbuf_and_nextbuf(int last_total_wndws,float **thisbuf,float **nextbuf,dataptr dz)
  1079. {
  1080. int exit_status;
  1081. int currentbuf_nextindex;
  1082. if(dz->flbufptr[0] + dz->wanted >= dz->flbufptr[2]) {
  1083. memmove((char *)dz->flbufptr[3],(char *)dz->flbufptr[0],(size_t)dz->wanted * sizeof(float));
  1084. *thisbuf = dz->flbufptr[3];
  1085. if((exit_status = find_currentbuf_nextindex(&currentbuf_nextindex,last_total_wndws,dz))<0)
  1086. return(exit_status);
  1087. *nextbuf = dz->bigfbuf + (currentbuf_nextindex * dz->wanted);
  1088. }
  1089. return(FINISHED);
  1090. }
  1091. /***************** INTERP_BETWEEN_VALS_IN_TWO_BUFS *******************/
  1092. int interp_between_vals_in_two_bufs(float *thisbuf,float *nextbuf,double interpval,dataptr dz)
  1093. {
  1094. int vc;
  1095. double thismidi, nextmidi, mididiff, ampdiff;
  1096. rectify_window(thisbuf,dz);
  1097. if(interpval<FLTERR) {
  1098. rectify_window(thisbuf,dz);
  1099. if(dz->flbufptr[1]!=thisbuf)
  1100. memmove((char *)dz->flbufptr[1],(char *)thisbuf,(size_t)(dz->wanted * sizeof(float)));
  1101. return(FINISHED);
  1102. }
  1103. if(interpval > (1.0 - FLTERR)) {
  1104. rectify_window(nextbuf,dz);
  1105. if(dz->flbufptr[1]!=nextbuf)
  1106. memmove((char *)dz->flbufptr[1],(char *)nextbuf,(size_t)(dz->wanted * sizeof(float)));
  1107. return(FINISHED);
  1108. }
  1109. rectify_window(thisbuf,dz);
  1110. rectify_window(nextbuf,dz);
  1111. for(vc = 0; vc<dz->wanted; vc+=2) {
  1112. thismidi = log(max(SPEC_MINFRQ,(double)thisbuf[FREQ])); /* quick calc using logs, without hztimidi() */
  1113. nextmidi = log(max(SPEC_MINFRQ,(double)nextbuf[FREQ])); /* works because logs to different bases are simply */
  1114. mididiff = nextmidi - thismidi; /* scaled versions of one another. See Feynmann book. */
  1115. ampdiff = nextbuf[AMPP] - thisbuf[AMPP];
  1116. dz->flbufptr[1][FREQ] = (float)exp(thismidi + (mididiff * interpval)); /* exp() = antilog of log() */
  1117. dz->flbufptr[1][AMPP] = (float)(thisbuf[AMPP] + (ampdiff * interpval));
  1118. }
  1119. return(FINISHED);
  1120. }
  1121. /***************** INTERP_BETWEEN_PITCH_VALS *******************/
  1122. int interp_between_pitch_vals(double *thismidi,float *pitch,int thisindex,double interpval,dataptr dz)
  1123. {
  1124. double mididiff;
  1125. if(thisindex<0) {
  1126. sprintf(errstr,"Pitch_interpolation val < 0 in interp_between_pitch_vals()\n");
  1127. return(PROGRAM_ERROR);
  1128. }
  1129. if(thisindex >= (dz->wlength - 2)) {
  1130. *thismidi = (double)pitch[(dz->wlength - 1)];
  1131. return(FINISHED);
  1132. }
  1133. if(interpval < FLTERR) {
  1134. *thismidi = (double)pitch[thisindex];
  1135. return(FINISHED);
  1136. }
  1137. if(interpval > (1.0 - FLTERR)) {
  1138. *thismidi = (double)pitch[thisindex+1];
  1139. return(FINISHED);
  1140. }
  1141. mididiff = pitch[thisindex+1] - pitch[thisindex];
  1142. *thismidi = pitch[thisindex] + (mididiff * interpval);
  1143. return(FINISHED);
  1144. }
  1145. /***************** INTERP_BETWEEN_PITCH_VALS2 *******************/
  1146. int interp_between_pitch_vals2(double *thismidi,double *pitch,int thisindex,double interpval,dataptr dz)
  1147. {
  1148. double mididiff;
  1149. if(thisindex<0) {
  1150. sprintf(errstr,"Interpolation val < 0 in interp_between_pitch_vals2()\n");
  1151. return(PROGRAM_ERROR);
  1152. }
  1153. if(thisindex >= (dz->wlength - 2)) {
  1154. *thismidi = pitch[(dz->wlength - 1)];
  1155. return(FINISHED);
  1156. }
  1157. if(interpval < FLTERR) {
  1158. *thismidi = pitch[thisindex];
  1159. return(FINISHED);
  1160. }
  1161. if(interpval > (1.0 - FLTERR)) {
  1162. *thismidi = pitch[thisindex+1];
  1163. return(FINISHED);
  1164. }
  1165. mididiff = pitch[thisindex+1] - pitch[thisindex];
  1166. *thismidi = pitch[thisindex] + (mididiff * interpval);
  1167. return(FINISHED);
  1168. }
  1169. /***************** TRANSPOSE_OUTBUF *******************/
  1170. int transpose_outbuf(double transp,dataptr dz)
  1171. {
  1172. int vc;
  1173. for(vc=0;vc<dz->wanted;vc+=2)
  1174. dz->flbufptr[1][FREQ] = (float)(dz->flbufptr[1][FREQ] * transp);
  1175. return put_transposed_data_in_appropriate_chans(transp,dz);
  1176. }
  1177. /***************** PUT_TRANSPOSED_DATA_IN_APPROPRIATE_CHANS *******************/
  1178. int put_transposed_data_in_appropriate_chans(double transp,dataptr dz)
  1179. {
  1180. int exit_status;
  1181. int cc,vc;
  1182. if((exit_status = rectify_frqs(dz->flbufptr[1],dz))<0)
  1183. return(exit_status);
  1184. if(transp < 1.0) { /* If transposition is downwards, go up the channels */
  1185. for(cc=0,vc=0; cc < dz->clength; cc++,vc+=2) {
  1186. if((exit_status = put_thisdata_in_appropriate_chan(cc,vc,dz))<0)
  1187. return(exit_status);
  1188. }
  1189. } else { /* If transposition is upwards, go down the channels */
  1190. for(cc=dz->clength-1,vc = dz->wanted-2; cc >=0 ;cc--,vc-=2) {
  1191. if((exit_status = put_thisdata_in_appropriate_chan(cc,vc,dz))<0)
  1192. return(exit_status);
  1193. }
  1194. }
  1195. return(FINISHED);
  1196. }
  1197. /***************** PUT_THISDATA_IN_APPROPRIATE_CHAN *******************/
  1198. int put_thisdata_in_appropriate_chan(int cc,int vc, dataptr dz)
  1199. {
  1200. int exit_status;
  1201. int truecc, truevc, trutop;
  1202. if(dz->flbufptr[1][FREQ] > dz->nyquist) { /* zero out frqs above nyquist */
  1203. dz->flbufptr[1][AMPP] = 0.0f;
  1204. dz->flbufptr[1][FREQ] = (float)dz->nyquist;
  1205. return(FINISHED);
  1206. } /* if new frq outside acceptable frq limits for channel */
  1207. if(dz->flbufptr[1][FREQ] < dz->flbufptr[WCHBOT][cc] || dz->flbufptr[1][FREQ] > dz->flbufptr[WCHTOP][cc]) {
  1208. if((exit_status = get_channel_corresponding_to_frq(&truecc,(double)dz->flbufptr[1][FREQ],dz))<0)
  1209. return(exit_status);
  1210. trutop = min(dz->clength-1,truecc + CHANSPAN);
  1211. truecc = max(truecc - CHANSPAN,0); /* find bottom and top chans that could receive this frq */
  1212. truevc = truecc * 2;
  1213. while(dz->flbufptr[1][FREQ] > dz->flbufptr[1][truevc+1]) {
  1214. truevc += 2; /* find position of new freq amongst freq ordering of existing data */
  1215. if(truevc >= trutop)
  1216. break;
  1217. }
  1218. truevc -= 2;
  1219. do {
  1220. if(dz->flbufptr[1][AMPP] > dz->flbufptr[1][truevc]) { /* If transpd data stronger than existing data */
  1221. dz->flbufptr[1][truevc] = dz->flbufptr[1][AMPP];/* replace existing data by transposed data */
  1222. dz->flbufptr[1][truevc+1] = dz->flbufptr[1][FREQ];
  1223. break;
  1224. }
  1225. truevc += 2;
  1226. } while(truevc < trutop);
  1227. dz->flbufptr[1][AMPP] = 0.0f; /* Zero out channel from which data has been moved */
  1228. if(cc>0 && cc < dz->clength-1) /* Interp frq of that chan, betwn preexisting chans */
  1229. dz->flbufptr[1][FREQ] = (float)((dz->flbufptr[1][FREQ+2] + dz->flbufptr[1][FREQ-2])/2.0);
  1230. else {
  1231. if(cc==0) dz->flbufptr[1][FREQ] = 0.0f;
  1232. else dz->flbufptr[1][FREQ] = (float)dz->nyquist;
  1233. } /* This chan may later be filld by other moved data */
  1234. }
  1235. return(FINISHED);
  1236. }
  1237. /**************************** LOGREAD_SHIFT *****************************/
  1238. int logread_shift(double timenow,int btktable_no,dataptr dz)
  1239. {
  1240. double *endpair, *p;
  1241. double hival, loval, hiind, loind, lopshift, interval, newpshift;
  1242. if(!dz->brkinit[btktable_no]) {
  1243. dz->firstval[btktable_no] = *(dz->brk[btktable_no]+1);
  1244. endpair = dz->brk[btktable_no]
  1245. + ((dz->brksize[btktable_no]-1)*2);
  1246. dz->lastind[btktable_no] = *endpair;
  1247. dz->lastval[btktable_no] = *(endpair+1);
  1248. dz->brkinit[btktable_no] = 1;
  1249. }
  1250. p = dz->brkptr[btktable_no];
  1251. if(timenow <= *(dz->brk[btktable_no])) {
  1252. dz->param[btktable_no] = dz->firstval[btktable_no];
  1253. return(FINISHED);
  1254. } else if(timenow >= dz->lastind[btktable_no]) {
  1255. dz->param[btktable_no] = dz->lastval[btktable_no];
  1256. return(FINISHED);
  1257. }
  1258. if(timenow > *(p)) {
  1259. while(*(p)<timenow)
  1260. p += 2;
  1261. } else {
  1262. while(*(p)>=timenow)
  1263. p -= 2;
  1264. p += 2;
  1265. }
  1266. hival = *(p+1);
  1267. hiind = *p;
  1268. loval = *(p-1);
  1269. loind = *(p-2);
  1270. if(flteq(loval,hival))
  1271. dz->param[btktable_no] = loval;
  1272. else if(loval < 0.0 && hival < 0.0) {
  1273. lopshift = log(-loval);
  1274. interval = log(-hival/-loval);
  1275. interval *= (timenow - loind)/(hiind - loind);
  1276. newpshift = lopshift + interval;
  1277. dz->param[btktable_no] = -exp(newpshift);
  1278. } else if (loval > 0.0 && hival > 0.0){
  1279. lopshift = log(loval);
  1280. interval = log(hival/loval);
  1281. interval *= (timenow - loind)/(hiind - loind);
  1282. newpshift = lopshift + interval;
  1283. dz->param[btktable_no] = exp(newpshift);
  1284. } else {
  1285. /* if shift changes from +ve (or 0) to -ve (or 0) or v.v., do linear shift */
  1286. interval = hival - loval;
  1287. interval *= (timenow - loind)/(hiind - loind);
  1288. dz->param[btktable_no] = loval + interval;
  1289. }
  1290. dz->brkptr[btktable_no] = p;
  1291. return(FINISHED);
  1292. }
  1293. /**************************** READ_VALUE_FROM_BRKTABLE_USING_LOG_INTERPOLATION *****************************
  1294. *
  1295. * Slightly weird function that fudges problem of log(0) and log(-ve).
  1296. */
  1297. int read_value_from_brktable_using_log_interpolation(double thistime,int paramno,dataptr dz)
  1298. {
  1299. double *endpair, *p;
  1300. double hival, loval, hiind, loind, lopitch, interval, newpitch;
  1301. if(!dz->brkinit[paramno]) {
  1302. dz->brkptr[paramno] = dz->brk[paramno];
  1303. dz->firstval[paramno] = *(dz->brk[paramno]+1);
  1304. endpair = dz->brk[paramno] + ((dz->brksize[paramno]-1)*2);
  1305. dz->lastind[paramno] = *endpair;
  1306. dz->lastval[paramno] = *(endpair+1);
  1307. dz->brkinit[paramno] = 1;
  1308. }
  1309. p = dz->brkptr[paramno];
  1310. if(thistime <= *(dz->brk[paramno])) {
  1311. dz->param[paramno] = dz->firstval[paramno];
  1312. return(FINISHED);
  1313. } else if(thistime >= dz->lastind[paramno]) {
  1314. dz->param[paramno] = dz->lastval[paramno];
  1315. return(FINISHED);
  1316. }
  1317. if(thistime > *(p)) {
  1318. while(*(p)<thistime)
  1319. p += 2;
  1320. } else {
  1321. while(*(p)>=thistime)
  1322. p -= 2;
  1323. p += 2;
  1324. }
  1325. hival = *(p+1);
  1326. hiind = *p;
  1327. loval = *(p-1);
  1328. loind = *(p-2);
  1329. if(flteq(loval,hival))
  1330. dz->param[paramno] = loval;
  1331. else if(loval < 0.0 && hival < 0.0) {
  1332. lopitch = log(-loval);
  1333. interval = log(-hival/-loval);
  1334. interval *= (thistime - loind)/(hiind - loind);
  1335. newpitch = lopitch + interval;
  1336. dz->param[paramno] = -exp(newpitch);
  1337. } else if (loval > 0.0 && hival > 0.0){
  1338. lopitch = log(loval);
  1339. interval = log(hival/loval);
  1340. interval *= (thistime - loind)/(hiind - loind);
  1341. newpitch = lopitch + interval;
  1342. dz->param[paramno] = exp(newpitch);
  1343. } else {
  1344. /* if val changes from +ve (or 0) to -ve (or 0) or v.v., do linear shift */
  1345. interval = hival - loval;
  1346. interval *= (thistime - loind)/(hiind - loind);
  1347. dz->param[paramno] = loval + interval;
  1348. }
  1349. dz->brkptr[paramno] = p;
  1350. return(FINISHED);
  1351. }
  1352. /**************************** ASSIGN_NEW_FRQS_TO_APPROPRIATE_CHANNELS ****************************
  1353. *
  1354. * (0) Find the lowest channel for which we have generated a new freq value.
  1355. * (0a) If no frqs lie below nyquist, zero all chan amps above botchan!!
  1356. * (1) Set initial amplitude for each transformed channel to zero.
  1357. * (2) Look through the set of stretched channels for any frequency
  1358. * values which lie below the top frq boundary of the current channel,
  1359. * (3) IF they are also above the bottom freq boundary of this channel,
  1360. * (i.e. they should be in THIS channel), if their amplitude
  1361. * is greater than any amp already assigned to this channel,
  1362. * substitute this frq/amp pair as the true value for this channel.
  1363. * (4) If we run out of values among the transformed freq values,
  1364. * break, and set OK=0 to break from outer loop too.
  1365. * (5) If we've broken from inner loop, break from outer loop too.
  1366. * (6) If we've broken from inner loop, zero amplitude of any channels
  1367. * which have not been assigned a new frequency.
  1368. */
  1369. int assign_new_frqs_to_appropriate_channels(dataptr dz)
  1370. {
  1371. int dd = dz->iparam[WAVER_BOTCHAN]; /* 0 */
  1372. int OK = 1, cc = 0, vc;
  1373. while(dz->freq[dd] >= (float)(dz->parray[WAVER_CHFBOT][cc+1])) {
  1374. if(++cc >= dz->clength) { /* 0a */
  1375. for(vc = dz->iparam[WAVER_BOTCHAN] * 2; vc < dz->wanted; vc += 2)
  1376. dz->flbufptr[0][AMPP] = 0.0F;
  1377. return(FINISHED);
  1378. }
  1379. }
  1380. for(vc=cc*2; cc<dz->clength; cc++,vc+=2) {
  1381. dz->flbufptr[0][AMPP] = 0.0F; /* 1 */
  1382. while(dz->freq[dd] < (float)(dz->parray[WAVER_CHFBOT][cc+1])) { /* 2 */
  1383. if((dz->freq[dd] >= dz->parray[WAVER_CHFBOT][cc]) && (dz->amp[dd] > dz->flbufptr[0][AMPP])) {
  1384. dz->flbufptr[0][AMPP] = dz->amp[dd]; /* 3 */
  1385. dz->flbufptr[0][FREQ] = dz->freq[dd];
  1386. }
  1387. if(++dd>=dz->clength) { /* 4 */
  1388. OK = 0;
  1389. break;
  1390. }
  1391. }
  1392. if(!OK) /* 5 */
  1393. break;
  1394. }
  1395. if(!OK) {
  1396. while(vc<dz->wanted) { /* 6 */
  1397. dz->flbufptr[0][AMPP] = 0.0F;
  1398. vc += 2;
  1399. }
  1400. }
  1401. return(FINISHED);
  1402. }