focus.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  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 <flags.h>
  29. #include <arrays.h>
  30. #include <focus.h>
  31. #include <cdpmain.h>
  32. #include <formants.h>
  33. #include <speccon.h>
  34. #include <sfsys.h>
  35. #include <float.h>
  36. #include <string.h>
  37. #include <focus.h>
  38. static int rwd_accumulate(int index,float *flbufptr, float *windowbuf);
  39. static int do_fold(int vc,double lofrq_limit,double hifrq_limit,dataptr dz);
  40. static int fold_in(int vc,double thisfrq,dataptr dz);
  41. static int do_stable_peaks_filter(int *peakscore,int *descnt,double lofrq_limit,double hifrq_limit,dataptr dz);
  42. static int extract_formant_peaks(int *pkcnt_here,double lofrq_limit,double hifrq_limit,int *least,dataptr dz);
  43. static int establish_bottom_and_top_of_filter_bands(int pkcnt_here,dataptr dz);
  44. static int do_focu_filter(float *thisbuf,dataptr dz);
  45. static int design_filter(int *peakscore,int *descnt,dataptr dz);
  46. static int increment_pointer_in_output_buffer(dataptr dz);
  47. static int insert_new_peak_in_peaklist(int position_in_formant,int *least,dataptr dz);
  48. static int sort_focu_peaks_by_frq(int pkcnt_here,dataptr dz);
  49. static int write_last_focu_buffers(dataptr dz);
  50. static int read_first_buffer(int *windows_in_buf,dataptr dz);
  51. static int sfwind(int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz);
  52. static int get_buffer_containing_frzpos(int frztime,int *frzpos,int *windows_in_buf,
  53. int *wndws_read_pre_thisbuf,dataptr dz);
  54. static int get_freeze_template(dataptr dz);
  55. static int get_startwindow_position(int *startwpos,int this_segtime,int *wndws_read_pre_thisbuf,
  56. int *windows_in_buf,int buffer_saved,dataptr dz);
  57. static int freeze_data(dataptr dz);
  58. static int save_buffer(dataptr dz);
  59. static int sfrewind(int *windows_in_buf,int window_sought,int *wndws_read_pre_thisbuf,dataptr dz);
  60. static int restore_buffer(dataptr dz);
  61. static int do_specstep(int wc,dataptr dz);
  62. /* NEW CODE */
  63. static int read_buffer(int *windows_in_buf,dataptr dz);
  64. /* NEW CODE */
  65. /********************************** SPECACCU **********************************/
  66. int specaccu(dataptr dz)
  67. {
  68. int exit_status;
  69. int vc, cc;
  70. if(dz->param[ACCU_GLIS] > 0.0) {
  71. if(dz->param[ACCU_DECAY] < 1.0) {
  72. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  73. dz->windowbuf[0][AMPP] = (float)(dz->windowbuf[0][AMPP] * dz->param[ACCU_DINDEX]);
  74. dz->windowbuf[0][FREQ] = (float)(dz->windowbuf[0][FREQ] * dz->param[ACCU_GINDEX]);
  75. if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
  76. return(exit_status);
  77. }
  78. } else {
  79. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  80. dz->windowbuf[0][FREQ] = (float)(dz->windowbuf[0][FREQ] * dz->param[ACCU_GINDEX]);
  81. if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
  82. return(exit_status);
  83. }
  84. }
  85. } else if(dz->param[ACCU_DECAY] < 1.0) {
  86. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  87. dz->windowbuf[0][AMPP] = (float)(dz->windowbuf[0][AMPP] * dz->param[ACCU_DINDEX]);
  88. if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
  89. return(exit_status);
  90. }
  91. } else {
  92. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  93. if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
  94. return(exit_status);
  95. }
  96. }
  97. return(FINISHED);
  98. }
  99. /********************************** RWD_ACCUMULATE **********************************/
  100. int rwd_accumulate(int index,float *flbufptr, float *windowbuf)
  101. {
  102. int frq = index+1;
  103. if(flbufptr[index] > windowbuf[index]) { /* if current amp > amp in accumulator */
  104. windowbuf[index] = flbufptr[index];
  105. windowbuf[frq] = flbufptr[frq]; /* replace amp in accumulator with current amp */
  106. } else {
  107. flbufptr[index] = windowbuf[index]; /* else replace current amp with amp in accumulator */
  108. flbufptr[frq] = windowbuf[frq];
  109. }
  110. return(FINISHED);
  111. }
  112. /**************************** SPECEXAG ****************************/
  113. int specexag(int *zero_set,dataptr dz)
  114. {
  115. int cc, vc;
  116. double post_totalamp = 0.0, pre_totalamp = 0.0;
  117. double maxamp = 0.0, normaliser;
  118. for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2) {
  119. pre_totalamp += dz->flbufptr[0][vc];
  120. if(dz->flbufptr[0][vc] > maxamp)
  121. maxamp = dz->flbufptr[0][vc];
  122. }
  123. if(maxamp<=0.0) {
  124. *zero_set = TRUE;
  125. return(FINISHED);
  126. }
  127. normaliser = 1.0/maxamp;
  128. for(cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2) {
  129. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * normaliser);
  130. dz->flbufptr[0][vc] = (float)(pow(dz->flbufptr[0][vc],dz->param[EXAG_EXAG]));
  131. post_totalamp += dz->flbufptr[0][vc];
  132. }
  133. return normalise(pre_totalamp,post_totalamp,dz);
  134. }
  135. /**************************** SPECFOLD ***************************/
  136. int specfold(dataptr dz)
  137. {
  138. int exit_status;
  139. int vc;
  140. double hifrq_limit = dz->param[FOLD_HIFRQ];
  141. double lofrq_limit = dz->param[FOLD_LOFRQ];
  142. if(hifrq_limit < lofrq_limit)
  143. swap(&lofrq_limit,&hifrq_limit);
  144. if(dz->brksize[FOLD_HIFRQ]) {
  145. dz->iparam[FOLD_HICHAN] = (int)((hifrq_limit + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  146. dz->param[FOLD_HICHANTOP] = ((double)dz->iparam[FOLD_HICHAN] * dz->chwidth) + dz->halfchwidth;
  147. if(dz->iparam[FOLD_HICHAN] != 0)
  148. dz->iparam[FOLD_HICHAN] <<= 1;
  149. }
  150. if(dz->brksize[FOLD_LOFRQ]) {
  151. dz->iparam[FOLD_LOCHAN] = (int)((lofrq_limit + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  152. if(dz->iparam[FOLD_LOCHAN] > 0)
  153. dz->param[FOLD_LOCHANBOT] = ((double)(dz->iparam[FOLD_LOCHAN]-1) * dz->chwidth) + dz->halfchwidth;
  154. else
  155. dz->param[FOLD_LOCHANBOT] = 0.0;
  156. if(dz->iparam[FOLD_LOCHAN] != 0)
  157. dz->iparam[FOLD_LOCHAN]<<= 1;
  158. }
  159. for(vc = 0; vc < dz->wanted; vc += 2) {
  160. if((exit_status = do_fold(vc,lofrq_limit,hifrq_limit,dz))<0)
  161. return(exit_status);
  162. }
  163. return(FINISHED);
  164. }
  165. /******************************* DO_FOLD **************************/
  166. int do_fold(int vc,double lofrq_limit,double hifrq_limit,dataptr dz)
  167. {
  168. int exit_status;
  169. double thisfrq = fabs((double)dz->flbufptr[0][FREQ]);
  170. if(thisfrq < 1.0) {
  171. dz->flbufptr[0][AMPP] = 0.0f;
  172. return(FINISHED);
  173. }
  174. if(thisfrq < lofrq_limit) {
  175. while(thisfrq < lofrq_limit)
  176. thisfrq *= 2.0;
  177. if(thisfrq < hifrq_limit) {
  178. if((exit_status = fold_in(vc,thisfrq,dz))<0)
  179. return(exit_status);
  180. }
  181. dz->flbufptr[0][AMPP] = 0.0f;
  182. } else {
  183. if(thisfrq > hifrq_limit) {
  184. while(thisfrq > hifrq_limit)
  185. thisfrq /= 2.0;
  186. if(thisfrq > lofrq_limit) {
  187. if((exit_status = fold_in(vc,thisfrq,dz))<0)
  188. return(exit_status);
  189. }
  190. dz->flbufptr[0][AMPP] = 0.0f;
  191. }
  192. }
  193. return(FINISHED);
  194. }
  195. /******************************** FOLD_IN ************************/
  196. int fold_in(int vc,double thisfrq,dataptr dz)
  197. {
  198. #define THISCHANSCAN (4)
  199. int truecc, truevc;
  200. int minscan, maxscan, n;
  201. truecc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
  202. truevc = truecc * 2;
  203. switch(dz->vflag[FOLD_WITH_BODY]) {
  204. case(FALSE):
  205. if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][truevc]) {
  206. dz->flbufptr[0][truevc++] = dz->flbufptr[0][AMPP];
  207. dz->flbufptr[0][truevc] = dz->flbufptr[0][FREQ];
  208. }
  209. break;
  210. case(TRUE):
  211. if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][truevc]) {
  212. dz->flbufptr[0][truevc++] = dz->flbufptr[0][AMPP];
  213. dz->flbufptr[0][truevc] = dz->flbufptr[0][FREQ];
  214. return(FINISHED);
  215. }
  216. minscan = max(dz->iparam[FOLD_LOCHAN]-2,truevc - (THISCHANSCAN * 2));
  217. maxscan = min(dz->iparam[FOLD_HICHAN]+2,truevc + (THISCHANSCAN * 2));
  218. for(n=truevc-2;n>minscan;n-=2) {
  219. if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][n]) {
  220. dz->flbufptr[0][n++] = dz->flbufptr[0][AMPP];
  221. dz->flbufptr[0][n] = dz->flbufptr[0][FREQ];
  222. return(FINISHED);
  223. }
  224. }
  225. for(n=truevc+2;n<maxscan;n+=2) {
  226. if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][n]) {
  227. dz->flbufptr[0][n++] = dz->flbufptr[0][AMPP];
  228. dz->flbufptr[0][n] = dz->flbufptr[0][FREQ];
  229. return(FINISHED);
  230. }
  231. }
  232. break;
  233. default:
  234. sprintf(errstr,"Unknown case in fold_in()\n");
  235. return(PROGRAM_ERROR);
  236. }
  237. return(FINISHED);
  238. }
  239. /**************************** OUTER_FOCU_LOOP ****************************/
  240. int outer_focu_loop(dataptr dz)
  241. {
  242. int exit_status;
  243. int samps_read, got, windows_in_buf;
  244. int peakscore = 0, pitchcnt = 0;
  245. int in_start_portion = TRUE, least = 0, descnt = 0;
  246. if(dz->vflag[FOCUS_STABLE])
  247. dz->flbufptr[1] = dz->flbufptr[2];
  248. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) {
  249. got = samps_read;
  250. dz->flbufptr[0] = dz->bigfbuf;
  251. windows_in_buf = got/dz->wanted;
  252. if((exit_status = inner_loop(&peakscore,&descnt,&in_start_portion,&least,&pitchcnt,windows_in_buf,dz))<0)
  253. return(exit_status);
  254. if(!dz->vflag[FOCUS_STABLE] && (samps_read > 0)) {
  255. if((exit_status = write_exact_samps(dz->bigfbuf,samps_read,dz))<0)
  256. return(exit_status);
  257. }
  258. }
  259. if(samps_read < 0) {
  260. sprintf(errstr,"Sound read error.\n");
  261. return(SYSTEM_ERROR);
  262. }
  263. if(dz->vflag[FOCUS_STABLE])
  264. return write_last_focu_buffers(dz);
  265. return(FINISHED);
  266. }
  267. /**************************** SPECFOCUS ***************************/
  268. int specfocus(int *peakscore,int *descnt,int *least,dataptr dz)
  269. {
  270. int exit_status;
  271. double lofrq_limit, hifrq_limit, d;
  272. int pkcnt_here;
  273. lofrq_limit = dz->param[FOCU_LOFRQ];
  274. hifrq_limit = dz->param[FOCU_HIFRQ];
  275. if(dz->brksize[FOCU_LOFRQ] || dz->brksize[FOCU_HIFRQ]) {
  276. if(flteq(lofrq_limit,hifrq_limit)) {
  277. sprintf(errstr,"Frequency limits define a zero-width band at time %lf.\n",dz->time);
  278. return(USER_ERROR);
  279. }
  280. if(lofrq_limit > hifrq_limit)
  281. swap(&lofrq_limit,&hifrq_limit);
  282. }
  283. if(dz->brksize[FOCU_BW]) {
  284. d = dz->param[FOCU_BW]/2.0; /* d is halfbandwidth. */
  285. dz->scalefact = PI/d; /* Convert an 8va offset from filter centre-frq */
  286. /* to a fraction of the bandwidth * PI */
  287. dz->param[FOCU_BRATIO_UP] = pow(2.0,d); /* upward transp ratio to top of filtband */
  288. dz->param[FOCU_BRATIO_DN] = 1.0/dz->param[FOCU_BRATIO_UP];
  289. } /* Downward transp ratio to bot of fband */
  290. rectify_window(dz->flbufptr[0],dz);
  291. if((exit_status = extract_specenv(0,0,dz))<0)
  292. return(exit_status);
  293. if(dz->vflag[FOCUS_STABLE])
  294. return do_stable_peaks_filter(peakscore,descnt,lofrq_limit,hifrq_limit,dz);
  295. if((exit_status = extract_formant_peaks(&pkcnt_here,lofrq_limit,hifrq_limit,least,dz))<0)
  296. return(exit_status);
  297. if((exit_status = establish_bottom_and_top_of_filter_bands(pkcnt_here,dz))<0)
  298. return(exit_status);
  299. if((exit_status = construct_filter_envelope(pkcnt_here,dz->flbufptr[0],dz))<0)
  300. return(exit_status);
  301. return do_focu_filter(dz->flbufptr[0],dz);
  302. }
  303. /****************************** DO_STABLE_PEAKS_FILTER ***************************/
  304. int do_stable_peaks_filter(int *peakscore,int *descnt,double lofrq_limit,double hifrq_limit,dataptr dz)
  305. {
  306. int exit_status, thispkcnt;
  307. // int *fppk = dz->stable->fpk[dz->iparam[FOCU_SL1]], n;
  308. int n;
  309. /* shufl bak stord specenvs: */
  310. /* put latest specenvarray here */
  311. memmove((char *)dz->stable->spec[0],
  312. //TW CODE ERROR
  313. // (char *)dz->stable->spec[1],dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(int));
  314. (char *)dz->stable->spec[1],dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(float));
  315. memmove((char *)dz->stable->spec[dz->iparam[FOCU_SL1]],
  316. //TW CODE ERROR
  317. // (char *)dz->specenvamp,dz->infile->specenvcnt * sizeof(int));
  318. (char *)dz->specenvamp,dz->infile->specenvcnt * sizeof(float));
  319. memmove((char *)dz->stable->fpk[0], (char *)dz->stable->fpk[1],
  320. dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(int));
  321. memmove((char *)dz->stable->total_pkcnt,(char *)(dz->stable->total_pkcnt+1),dz->iparam[FOCU_SL1] * sizeof(int));
  322. /* shufl bak stord fpks & shufl bak stored fpk_totals */
  323. if((exit_status = extract_formant_peaks2(FOCU_SL1,&thispkcnt,lofrq_limit,hifrq_limit,dz))<0)
  324. return(exit_status); /* put into into last fpk[z] store */
  325. dz->stable->total_pkcnt[dz->iparam[FOCU_SL1]] = thispkcnt; /* put into into last fpk[z] store */
  326. if(dz->total_windows >= dz->iparam[FOCU_SL1]) { /* before this we can't design a filter */
  327. if((exit_status = design_filter(peakscore,descnt,dz))<0)
  328. return(exit_status);
  329. if(dz->total_windows==dz->iparam[FOCU_SL1]) { /* If 1st time to do filtering */
  330. memmove((char *)(dz->flbufptr[1]),(char *)dz->stable->sbuf[0],(size_t)dz->wanted * sizeof(float)); /* copy zero-amp-1st-buff */
  331. if((exit_status = increment_pointer_in_output_buffer(dz))<0)
  332. return(exit_status);
  333. for(n = 1; n <= dz->stable->offset; n++) { /* filter all windows <= offset, using 1st filter */
  334. if((exit_status = do_focu_filter(dz->stable->sbuf[n],dz))<0)
  335. return(exit_status); /* and output them */
  336. memmove((char *)(dz->flbufptr[1]),(char *)dz->stable->sbuf[n],(size_t)dz->wanted * sizeof(float));
  337. if((exit_status = increment_pointer_in_output_buffer(dz))<0)
  338. return(exit_status);
  339. }
  340. } else { /* all later times to do filtering */
  341. /* filter buffer at offset and output it */
  342. if((exit_status = do_focu_filter(dz->stable->sbuf[dz->stable->offset],dz))<0)
  343. return(exit_status);
  344. memmove((char *)dz->flbufptr[1],(char *)dz->stable->sbuf[dz->stable->offset],(size_t)dz->wanted * sizeof(float));
  345. if((exit_status = increment_pointer_in_output_buffer(dz))<0)
  346. return(exit_status);
  347. }
  348. }
  349. memmove((char *)dz->stable->sbuf[0],(char *)dz->stable->sbuf[1],
  350. (size_t)(dz->wanted * sizeof(float) * dz->iparam[FOCU_SL1])); /* shuffle back stored bufs */
  351. memmove((char *)dz->stable->sbuf[dz->iparam[FOCU_SL1]],(char *)dz->flbufptr[0],(size_t)dz->wanted * sizeof(float));
  352. return(FINISHED); /* copy new buf to store */
  353. }
  354. /****************************** EXTRACT_FORMANT_PEAKS ***************************/
  355. int extract_formant_peaks(int *pkcnt_here,double lofrq_limit,double hifrq_limit,int *least,dataptr dz)
  356. {
  357. int exit_status;
  358. int n = 0;
  359. int falling = 0, last_channel_was_in_range = 1;
  360. *pkcnt_here = 0;
  361. for(n=0;n<dz->itemcnt;n++)
  362. dz->filtpeak[n] = 0.0;
  363. n = 1;
  364. while(n<dz->infile->specenvcnt) {
  365. if(dz->specenvfrq[n] < lofrq_limit) {
  366. last_channel_was_in_range = 0;
  367. n++;
  368. continue;
  369. }
  370. if(dz->specenvamp[n] > dz->specenvamp[n-1])
  371. falling = 0;
  372. else {
  373. if(!falling) {
  374. if(last_channel_was_in_range) {
  375. if((exit_status = insert_new_peak_in_peaklist(n-1,least,dz))<0)
  376. return(exit_status);
  377. }
  378. (*pkcnt_here)++;
  379. falling = 1;
  380. }
  381. }
  382. last_channel_was_in_range = 1;
  383. if(dz->specenvfrq[n] > hifrq_limit)
  384. break;
  385. n++;
  386. }
  387. *pkcnt_here = min(*pkcnt_here,dz->itemcnt);
  388. return sort_focu_peaks_by_frq(*pkcnt_here,dz);
  389. }
  390. /******************************** ESTABLISH_BOTTOM_AND_TOP_OF_FILTER_BANDS ************************/
  391. int establish_bottom_and_top_of_filter_bands(int pkcnt_here,dataptr dz)
  392. {
  393. int n;
  394. for(n=0;n<pkcnt_here;n++) {
  395. dz->fbandbot[n] = dz->specenvfrq[dz->peakno[n]] * dz->param[FOCU_BRATIO_DN];
  396. dz->fbandtop[n] = min(dz->specenvfrq[dz->peakno[n]] * dz->param[FOCU_BRATIO_UP],dz->nyquist);
  397. }
  398. return(FINISHED);
  399. }
  400. /****************************** DO_FOCU_FILTER ***************************/
  401. int do_focu_filter(float *thisbuf,dataptr dz)
  402. {
  403. int cc, vc;
  404. for(cc=0, vc=0; cc < dz->clength; cc++, vc += 2)
  405. thisbuf[AMPP] = (float)(thisbuf[AMPP] * dz->fsampbuf[cc]);
  406. return(FINISHED);
  407. }
  408. /****************************** DESIGN_FILTER ******************************/
  409. int design_filter(int *peakscore,int *descnt,dataptr dz)
  410. {
  411. int exit_status;
  412. int this_pkcnt;
  413. int n = 0;
  414. int pkcnt_here;
  415. if(dz->total_windows<=dz->iparam[FOCU_SL1])
  416. memset((char *)dz->stable->design_score,0,dz->infile->specenvcnt * sizeof(int));
  417. if((exit_status = score_peaks(peakscore,FOCU_SL1,FOCU_STABL,dz))<0)
  418. return(exit_status);
  419. if(*peakscore==0) {
  420. memset(dz->fsampbuf,0,(size_t)dz->wanted * sizeof(float)); /* zero filter */
  421. return(FINISHED);
  422. }
  423. if((exit_status = collect_scores(&this_pkcnt,descnt,dz))<0)
  424. return(exit_status); /* Find how many times each peak occurs across the stabilise buffers */
  425. if((exit_status = sort_design(this_pkcnt,dz))<0) /* Sort these on the basis of the most commonly occuring */
  426. return(exit_status);
  427. if(this_pkcnt<=dz->itemcnt || (dz->stable->des[dz->itemcnt-1]->score > dz->stable->des[dz->itemcnt]->score)) {
  428. pkcnt_here = min(this_pkcnt,dz->itemcnt);
  429. for(n=0;n<pkcnt_here;n++) /* If most common pkcnt (or less) peaks more common than ALL others */
  430. dz->peakno[n] = dz->stable->des[n]->chan;/* these are the peaks to keep */
  431. } else { /* Else choose amongst equivalent peaks, in terms of amplitude */
  432. if((exit_status = sort_equivalent_scores(this_pkcnt,dz))<0)
  433. return(exit_status);
  434. pkcnt_here = dz->itemcnt;
  435. }
  436. if((exit_status = sort_focu_peaks_by_frq(pkcnt_here,dz))<0)
  437. return(exit_status);
  438. if((exit_status = establish_bottom_and_top_of_filter_bands(pkcnt_here,dz))<0)
  439. return(exit_status);
  440. if((exit_status = construct_filter_envelope(pkcnt_here,dz->stable->sbuf[dz->stable->offset],dz))<0)
  441. return(exit_status);
  442. if(dz->total_windows>dz->iparam[FOCU_SL1]) { /* Logically this should be '>=dz->iparam[FOCU_SL1]' : but */
  443. if((exit_status = unscore_peaks(peakscore,dz))<0)
  444. return(exit_status); /* don't have to subtract window 0, as there are NO PEAKS there */
  445. }
  446. return(FINISHED);
  447. }
  448. /****************************** INCREMENT_POINTER_IN_OUTPUT_BUFFER ***************************/
  449. int increment_pointer_in_output_buffer(dataptr dz)
  450. {
  451. int exit_status;
  452. if((dz->flbufptr[1] += dz->wanted) >= dz->flbufptr[3]) {
  453. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen,dz))<0)
  454. return(exit_status);
  455. dz->flbufptr[1] = dz->flbufptr[2];
  456. }
  457. return(FINISHED);
  458. }
  459. /****************************** INSERT_NEW_PEAK_IN_PEAKLIST ***************************/
  460. int insert_new_peak_in_peaklist(int position_in_formant,int *least,dataptr dz)
  461. {
  462. int n;
  463. double smallest = DBL_MAX;
  464. if(dz->specenvamp[position_in_formant] > dz->filtpeak[*least]) {
  465. dz->filtpeak[*least] = dz->specenvamp[position_in_formant];
  466. dz->peakno[*least] = position_in_formant;
  467. }
  468. for(n=0;n<dz->itemcnt;n++) {
  469. if(dz->filtpeak[n] < smallest) {
  470. *least = n;
  471. smallest = dz->filtpeak[n];
  472. }
  473. }
  474. return(FINISHED);
  475. }
  476. /****************************** SORT_FOCU_PEAKS_BY_FRQ ***************************/
  477. int sort_focu_peaks_by_frq(int pkcnt_here,dataptr dz)
  478. {
  479. int n, m, k;
  480. for(n=0;n<pkcnt_here-1;n++) {
  481. for(m=n+1;m<pkcnt_here;m++) {
  482. if(dz->specenvfrq[dz->peakno[n]] > dz->specenvfrq[dz->peakno[m]]) {
  483. k = dz->peakno[m];
  484. dz->peakno[m] = dz->peakno[n];
  485. dz->peakno[n] = k;
  486. }
  487. }
  488. }
  489. return(FINISHED);
  490. }
  491. /****************************** WRITE_LAST_FOCU_BUFFERS ******************************/
  492. int write_last_focu_buffers(dataptr dz)
  493. {
  494. int exit_status;
  495. int n;
  496. for(n = dz->stable->offset+1; n < dz->iparam[FOCU_STABL]; n++) {
  497. if((exit_status = do_focu_filter(dz->stable->sbuf[n],dz))<0)
  498. return(exit_status);
  499. memmove((char *)dz->flbufptr[1],(char *)dz->stable->sbuf[n],(size_t)dz->wanted * sizeof(float));
  500. if((exit_status = increment_pointer_in_output_buffer(dz))<0)
  501. return(exit_status);
  502. }
  503. if(dz->flbufptr[1]!=dz->flbufptr[2]) {
  504. if((exit_status = write_exact_samps(dz->flbufptr[2],(dz->flbufptr[1] - dz->flbufptr[2]),dz))<0)
  505. return(exit_status);
  506. }
  507. return(FINISHED);
  508. }
  509. /****************** SPECFREEZE ********************
  510. *
  511. * (1) if no freezing needed.
  512. * (2) write any complete buffers before next timepoint.
  513. * (3) advance to buffer containing freeze-window if ness.
  514. * (4) advance within current buffer, to freeze-window.
  515. * (5) get number of windows to process.
  516. * (6) set endwindow relative to current buffer.
  517. * (7) advance within current buffer, to start-window.
  518. * (8) process windows from here to end-window.
  519. * (9) if current buffer overrun: proceed to next buffer.
  520. * (10) readjust window counters to be relative to nextbuffer start.
  521. * (11) write data and go to next buffer.
  522. * (12) flush buffer.
  523. */
  524. int specfreeze(dataptr dz)
  525. {
  526. int exit_status;
  527. int n = 0, buffer_saved;
  528. int wc, wndws_read_pre_thisbuf = 0, frzpos;
  529. int startwpos = 0, endwpos = 0, windiff;
  530. int windows_in_buf;
  531. if((exit_status = read_first_buffer(&windows_in_buf,dz))<0)
  532. return(exit_status);
  533. while(n<dz->itemcnt-1) {
  534. if(dz->lparray[FRZ_FRZTIME][n] < 0L) { /* 1 */
  535. while(dz->lparray[FRZ_SEGTIME][n+1] > wndws_read_pre_thisbuf + windows_in_buf) {
  536. if((exit_status = sfwind(&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
  537. return(exit_status); /* 2 */
  538. if(exit_status == FINISHED) {
  539. sprintf(errstr,"Window search miscalculation 1, specfreeze()\n");
  540. return(PROGRAM_ERROR);
  541. }
  542. }
  543. endwpos = dz->lparray[FRZ_SEGTIME][n+1] - wndws_read_pre_thisbuf;
  544. } else {
  545. buffer_saved = 0;
  546. frzpos = dz->lparray[FRZ_FRZTIME][n] - wndws_read_pre_thisbuf;
  547. if(frzpos > windows_in_buf) { /* 3 */
  548. if((exit_status = get_buffer_containing_frzpos
  549. (dz->lparray[FRZ_FRZTIME][n],&frzpos,&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
  550. return(exit_status);
  551. buffer_saved = 1;
  552. }
  553. dz->flbufptr[0] = dz->bigfbuf + (frzpos * dz->wanted); /* 4 */
  554. if((exit_status = get_freeze_template(dz))<0)
  555. return(exit_status);
  556. windiff = dz->lparray[FRZ_SEGTIME][n+1] - dz->lparray[FRZ_SEGTIME][n];/* 5 */
  557. if((exit_status = get_startwindow_position
  558. (&startwpos,dz->lparray[FRZ_SEGTIME][n],&wndws_read_pre_thisbuf,&windows_in_buf,buffer_saved,dz))<0)
  559. return(exit_status);
  560. endwpos = startwpos + windiff; /* 6 */
  561. wc = startwpos; /* 7 */
  562. dz->flbufptr[0] = dz->bigfbuf + (startwpos * dz->wanted); /* 8 */
  563. exit_status = CONTINUE;
  564. while(wc<endwpos) {
  565. if(exit_status == FINISHED) {
  566. sprintf(errstr,"Window search miscalculation 2, specfreeze()\n");
  567. return(PROGRAM_ERROR);
  568. }
  569. if((exit_status = freeze_data(dz))<0)
  570. return(exit_status);
  571. dz->flbufptr[0] += dz->wanted;
  572. if(++wc >= windows_in_buf) { /* 9 */
  573. wc = 0; /* 10 */
  574. endwpos -= windows_in_buf; /* 11 */
  575. if((exit_status = sfwind(&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
  576. return(exit_status);
  577. }
  578. }
  579. }
  580. n++;
  581. }
  582. if((endwpos > 0) && (windows_in_buf > 0)) { /* 12 */
  583. if((exit_status = write_exact_samps(dz->bigfbuf,windows_in_buf * dz->wanted,dz))<0)
  584. return(exit_status);
  585. }
  586. return(FINISHED);
  587. }
  588. /*************************** READ_FIRST_BUFFER ******************************/
  589. int read_first_buffer(int *windows_in_buf,dataptr dz)
  590. {
  591. int samps_read, got;
  592. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
  593. sprintf(errstr,"Cannot read data from input file: read_first_buffer()\n");
  594. return(SYSTEM_ERROR);
  595. }
  596. got = samps_read;
  597. *windows_in_buf = got/dz->wanted;
  598. return(FINISHED);
  599. }
  600. /*************************** SFWIND *******************************/
  601. int sfwind(int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz)
  602. {
  603. int exit_status;
  604. int got, samps_read;
  605. *wndws_read_pre_thisbuf += *windows_in_buf;
  606. if(*windows_in_buf > 0) {
  607. if((exit_status = write_exact_samps(dz->bigfbuf,*windows_in_buf * dz->wanted,dz))<0)
  608. return(exit_status);
  609. }
  610. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
  611. sprintf(errstr,"Failed to read sound data: sfwind()\n");
  612. return(SYSTEM_ERROR);
  613. }
  614. got = samps_read;
  615. *windows_in_buf = got/dz->wanted;
  616. dz->flbufptr[0] = dz->bigfbuf;
  617. if(samps_read==0)
  618. return(FINISHED);
  619. return(CONTINUE);
  620. }
  621. /*************************** GET_BUFFER_CONTAINING_FRZPOS *******************************/
  622. int get_buffer_containing_frzpos(int frztime,int *frzpos,int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz)
  623. {
  624. int exit_status;
  625. int samps_read, got;
  626. int buffer_saved = 0;
  627. while(*frzpos > *windows_in_buf) {
  628. if(!buffer_saved) {
  629. if((exit_status = save_buffer(dz))<0)
  630. return(exit_status);
  631. }
  632. buffer_saved = 1;
  633. *wndws_read_pre_thisbuf += *windows_in_buf;
  634. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) <= 0) {
  635. if(samps_read<0) {
  636. sprintf(errstr,"Sound read error.\n");
  637. return(SYSTEM_ERROR);
  638. } else {
  639. sprintf(errstr,"Buffer accnting probl: Can't read input data: get_buffer_containing_frzpos()\n");
  640. return(PROGRAM_ERROR);
  641. }
  642. }
  643. got = samps_read;
  644. *windows_in_buf = got/dz->wanted;
  645. *frzpos = frztime - *wndws_read_pre_thisbuf;
  646. }
  647. return(FINISHED);
  648. }
  649. /*************************** GET_FREEZE_TEMPLATE *******************************/
  650. int get_freeze_template(dataptr dz)
  651. {
  652. int cc, vc;
  653. switch(dz->mode) {
  654. case(FRZ_AMP):
  655. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  656. dz->windowbuf[0][AMPP] = dz->flbufptr[0][AMPP];
  657. break;
  658. case(FRZ_FRQ):
  659. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
  660. dz->windowbuf[0][FREQ] = dz->flbufptr[0][FREQ];
  661. break;
  662. case(FRZ_AMP_AND_FRQ):
  663. for(vc = 0; vc < dz->wanted; vc++)
  664. dz->windowbuf[0][vc] = dz->flbufptr[0][vc];
  665. break;
  666. default:
  667. sprintf(errstr,"unknown mode in get_freeze_template()\n");
  668. return(PROGRAM_ERROR);
  669. }
  670. return(FINISHED);
  671. }
  672. /*************************** GET_STARTWINDOW_POSITION ******************************
  673. *
  674. * If startwindow is not in this buffer: rewind.
  675. */
  676. int get_startwindow_position
  677. (int *startwpos,int this_segtime,int *wndws_read_pre_thisbuf,int *windows_in_buf,int buffer_saved,dataptr dz)
  678. {
  679. int exit_status;
  680. if((*startwpos = this_segtime - *wndws_read_pre_thisbuf)<0) {
  681. if((exit_status = sfrewind(windows_in_buf,this_segtime,wndws_read_pre_thisbuf,dz))<0)
  682. return(exit_status);
  683. if(buffer_saved) {
  684. if((exit_status = restore_buffer(dz))<0)
  685. return(exit_status);
  686. }
  687. *startwpos = this_segtime - *wndws_read_pre_thisbuf;
  688. }
  689. return(FINISHED);
  690. }
  691. /*************************** FREEZE_DATA ******************************/
  692. int freeze_data(dataptr dz)
  693. {
  694. int cc, vc;
  695. switch(dz->mode) {
  696. case(FRZ_AMP):
  697. for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2)
  698. dz->flbufptr[0][AMPP] = dz->windowbuf[0][AMPP];
  699. break;
  700. case(FRZ_FRQ):
  701. for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2)
  702. dz->flbufptr[0][FREQ] = dz->windowbuf[0][FREQ];
  703. break;
  704. case(FRZ_AMP_AND_FRQ):
  705. for(vc = 0; vc < dz->wanted; vc++)
  706. dz->flbufptr[0][vc] = dz->windowbuf[0][vc];
  707. break;
  708. default:
  709. sprintf(errstr,"unknown mode in freeze_data()\n");
  710. return(PROGRAM_ERROR);
  711. }
  712. return(CONTINUE);
  713. }
  714. /*************************** SAVE_BUFFER *******************************/
  715. int save_buffer(dataptr dz)
  716. {
  717. memmove((char *)(dz->flbufptr[2]),(char *)dz->bigfbuf,(size_t)dz->buflen * sizeof(float));
  718. return(FINISHED);
  719. }
  720. /***************************** SFREWIND ********************************/
  721. int sfrewind(int *windows_in_buf,int window_sought,int *wndws_read_pre_thisbuf,dataptr dz)
  722. {
  723. int samps_read, got;
  724. int big_wsize = dz->buflen/dz->wanted;
  725. int zzz = (window_sought/big_wsize) * big_wsize; /* TRUNCATE to a multiple of bigbufsize (in windows) */
  726. if((sndseekEx(dz->ifd[0],zzz * dz->wanted, 0))<0) {
  727. sprintf(errstr,"Window seek failed. sfrewind()\n");
  728. return(SYSTEM_ERROR);
  729. }
  730. *wndws_read_pre_thisbuf = zzz;
  731. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) <= 0) {
  732. if(samps_read<0) {
  733. sprintf(errstr,"Sound read error.\n");
  734. return(SYSTEM_ERROR);
  735. } else {
  736. sprintf(errstr,"Window reverse search miscalculation.sfrewind()\n");
  737. return(PROGRAM_ERROR);
  738. }
  739. }
  740. got = samps_read;
  741. *windows_in_buf = got/dz->wanted;
  742. return(FINISHED);
  743. }
  744. /*************************** RESTORE_BUFFER *******************************/
  745. int restore_buffer(dataptr dz)
  746. {
  747. memmove((char *)dz->bigfbuf,(char *)(dz->flbufptr[2]),(size_t)dz->buflen * sizeof(float));
  748. return(FINISHED);
  749. }
  750. /**************************** SPECSTEP ****************************/
  751. int specstep(dataptr dz)
  752. {
  753. int exit_status;
  754. int samps_read, got, windows_in_buf, wc;
  755. while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) {
  756. got = samps_read;
  757. dz->flbufptr[0] = dz->bigfbuf;
  758. windows_in_buf = got/dz->wanted;
  759. for(wc=0; wc<windows_in_buf; wc++) {
  760. if((exit_status = do_specstep(wc,dz))<0)
  761. return(exit_status);
  762. dz->total_windows++;
  763. dz->flbufptr[0] += dz->wanted;
  764. }
  765. if(dz->total_windows % dz->iparam[STEP_STEP]!=0) /* at bigbufend, if not at start of step */
  766. memmove((char *)(dz->windowbuf[0]),(char *)(dz->flbufptr[1]),(size_t)dz->wanted * sizeof(float));
  767. /* copy the unchanging window into saving buffer */
  768. if((exit_status = write_exact_samps(dz->bigfbuf,samps_read,dz))<0)
  769. return(exit_status);
  770. }
  771. return(FINISHED);
  772. }
  773. /**************************** DO_SPECSTEP ***************************/
  774. int do_specstep(int wc,dataptr dz)
  775. {
  776. if(wc==0) { /* if at start of a bigfbuf */
  777. if(dz->total_windows % dz->iparam[STEP_STEP]!=0) /* and not at start of a step */
  778. memmove((char *)(dz->flbufptr[0]),(char *)(dz->windowbuf[0]),(size_t)dz->wanted * sizeof(float));
  779. /* get the saved unchanging window into 1st buf of bigfbuf */
  780. dz->flbufptr[1] = dz->flbufptr[0];/* point to this window, as unchanging window */
  781. } else if(dz->total_windows % dz->iparam[STEP_STEP]==0) /* if at start of a step */
  782. dz->flbufptr[1] = dz->flbufptr[0];/* point to this window, as unchanging window */
  783. else /* if not at start of a step */
  784. memmove((char *)(dz->flbufptr[0]),(char *)(dz->flbufptr[1]),(size_t)dz->wanted * sizeof(float));
  785. /* copy the unchanging window into current window */
  786. return(FINISHED);
  787. }
  788. /* NEW CODE */
  789. /****************** SPECFREEZE2 ********************
  790. *
  791. * (1) if no freezing needed.
  792. * (2) write any complete buffers before next timepoint.
  793. * (3) advance to buffer containing freeze-window if ness.
  794. * (4) advance within current buffer, to freeze-window.
  795. * (5) get number of windows to process.
  796. * (6) set endwindow relative to current buffer.
  797. * (7) advance within current buffer, to start-window.
  798. * (8) process windows from here to end-window.
  799. * (9) if current buffer overrun: proceed to next buffer.
  800. * (10) readjust window counters to be relative to nextbuffer start.
  801. * (11) write data and go to next buffer.
  802. * (12) flush buffer.
  803. */
  804. int specfreeze2(dataptr dz)
  805. {
  806. int exit_status;
  807. int n = 0, m;
  808. int windows_in_buf, inwindowcnt = 0, outbufwincnt = 0, inbufwincnt = 0;
  809. int bufwinlen = dz->buflen/dz->wanted;
  810. if((exit_status = read_first_buffer(&windows_in_buf,dz))<0)
  811. return(exit_status);
  812. dz->flbufptr[0] = dz->bigfbuf;
  813. dz->flbufptr[1] = dz->flbufptr[2];
  814. while(n<dz->itemcnt) {
  815. while(inwindowcnt < dz->lparray[FRZ_FRZTIME][n]) { /* 1 */
  816. memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
  817. if(++inwindowcnt >= dz->wlength) {
  818. dz->finished = TRUE;
  819. break;
  820. } else if(++inbufwincnt >= windows_in_buf) {
  821. if((exit_status = read_buffer(&windows_in_buf,dz))<0)
  822. return(exit_status);
  823. dz->flbufptr[0] = dz->bigfbuf;
  824. inbufwincnt = 0;
  825. } else
  826. dz->flbufptr[0] += dz->wanted;
  827. if(++outbufwincnt >= bufwinlen) {
  828. if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
  829. return(exit_status);
  830. dz->flbufptr[1] = dz->flbufptr[2];
  831. outbufwincnt = 0;
  832. } else
  833. dz->flbufptr[1] += dz->wanted;
  834. }
  835. if(dz->finished)
  836. break;
  837. for(m=0;m<dz->lparray[FRZ_SEGTIME][n];m++) {
  838. memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
  839. if(++outbufwincnt >= bufwinlen) {
  840. if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
  841. return(exit_status);
  842. dz->flbufptr[1] = dz->flbufptr[2];
  843. outbufwincnt = 0;
  844. } else
  845. dz->flbufptr[1] += dz->wanted;
  846. }
  847. n++;
  848. }
  849. while(inwindowcnt < dz->wlength) {
  850. memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
  851. if(++outbufwincnt >= bufwinlen) {
  852. if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
  853. return(exit_status);
  854. dz->flbufptr[1] = dz->flbufptr[2];
  855. outbufwincnt = 0;
  856. } else
  857. dz->flbufptr[1] += dz->wanted;
  858. inwindowcnt++;
  859. if(++inbufwincnt >= windows_in_buf) {
  860. if((exit_status = read_buffer(&windows_in_buf,dz))<0)
  861. return(exit_status);
  862. dz->flbufptr[0] = dz->bigfbuf;
  863. inbufwincnt = 0;
  864. } else
  865. dz->flbufptr[0] += dz->wanted;
  866. }
  867. if(dz->flbufptr[1] != dz->flbufptr[2]) {
  868. if((exit_status = write_samps(dz->flbufptr[2],(dz->flbufptr[1] - dz->flbufptr[2]),dz))<0)
  869. return(exit_status);
  870. }
  871. return(FINISHED);
  872. }
  873. /*************************** READ_BUFFER ******************************/
  874. int read_buffer(int *windows_in_buf,dataptr dz)
  875. {
  876. int samps_read, got;
  877. if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
  878. sprintf(errstr,"Can't read samples from input soundfile.\n");
  879. return(SYSTEM_ERROR);
  880. }
  881. got = samps_read;
  882. *windows_in_buf = got/dz->wanted;
  883. return(FINISHED);
  884. }
  885. /* END OF NEW CODE */