combine.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. /*
  2. * Copyright (c) 1983-2023 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. //TW UPDATE
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <arrays.h>
  31. #include <flags.h>
  32. #include <combine.h>
  33. #include <cdpmain.h>
  34. #include <formants.h>
  35. #include <speccon.h>
  36. #include <sfsys.h>
  37. #include <osbind.h>
  38. #include <string.h>
  39. #include <combine.h>
  40. static int setup_channel_mifdrqs(dataptr dz);
  41. static int check_formant_buffer(dataptr dz);
  42. static int preset_channels(dataptr dz);
  43. static int write_pitched_window(double fundamental,double *amptotal,dataptr dz);
  44. //TW UPDATES + AVOID WARNING
  45. static int write_unpitched_window(double *amptotal,dataptr dz);
  46. static int write_silent_window(dataptr dz);
  47. static int normalise_in_file(double normaliser,dataptr dz);
  48. static int do_specmax(dataptr dz);
  49. static int if_loud_enough_to_go_in_list_put_in_list(float *ampstore,int *locstore,float val,int location,dataptr dz);
  50. static int generate_mean_values(int *loc1, int *loc2,dataptr dz);
  51. static int pichwise_mean_of_frqs(double *outfrq,double frq1,double frq2);
  52. //TW UPDATE
  53. static int read_envel_from_envfile(float **env,float **envend,int *envlen,int fileno,dataptr dz);
  54. /****************************** SPECMAKE ****************************
  55. *
  56. * Construct an analfile, from pitchfile and formantdata only.
  57. */
  58. int specmake(dataptr dz)
  59. {
  60. #define MAXANALAMP (1.0)
  61. int exit_status;
  62. double normaliser, amptotal, thisfrq, maxamptotal = 0.0;
  63. //TW UPDATE
  64. float *env = NULL, *envend;
  65. int envlen;
  66. if(dz->process==MAKE2) {
  67. if((exit_status = read_envel_from_envfile(&env,&envend,&envlen,2,dz))<0)
  68. return(exit_status);
  69. dz->wlength = min(dz->wlength,envlen);
  70. }
  71. dz->wanted = dz->infile->origchans; /* to reconstruct an analfile !! */
  72. if((exit_status = setup_formant_params(dz->ifd[1],dz))<0)
  73. return(exit_status);
  74. dz->flbufptr[1] = dz->flbufptr[2] + dz->descriptor_samps;
  75. if((exit_status = setup_channel_mifdrqs(dz))<0)
  76. return(exit_status);
  77. if((exit_status = check_formant_buffer(dz))<0)
  78. return(exit_status);
  79. dz->flbufptr[0] = dz->bigfbuf;
  80. while(dz->total_windows < dz->wlength){
  81. amptotal = 0.0;
  82. if((exit_status = preset_channels(dz))<0)
  83. return(exit_status);
  84. if((thisfrq = dz->pitches[dz->total_windows])>0.0) {
  85. if((exit_status = write_pitched_window(thisfrq,&amptotal,dz))<0)
  86. return(exit_status);
  87. //TW UPDATE
  88. } else if(flteq(thisfrq,NOT_SOUND)) {
  89. amptotal = 0.0;
  90. if((exit_status = write_silent_window(dz))<0)
  91. return(exit_status);
  92. } else {
  93. //TW AVOID WARNING
  94. if((exit_status = write_unpitched_window(&amptotal,dz))<0)
  95. return(exit_status);
  96. if(dz->process==MAKE2)
  97. normalise(env[dz->total_windows],amptotal,dz);
  98. }
  99. if(amptotal > maxamptotal)
  100. maxamptotal = amptotal;
  101. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[2]) {
  102. if((exit_status = write_exact_samps(dz->bigfbuf,dz->buflen,dz))<0)
  103. return(exit_status);
  104. dz->flbufptr[0] = dz->bigfbuf;
  105. }
  106. if((exit_status = move_along_formant_buffer(dz))<0)
  107. return(exit_status);
  108. if(exit_status!=CONTINUE)
  109. break;
  110. dz->total_windows++;
  111. }
  112. if(dz->flbufptr[0] != dz->bigfbuf) {
  113. if((exit_status = write_samps(dz->bigfbuf,(dz->flbufptr[0] - dz->bigfbuf),dz))<0)
  114. return(exit_status);
  115. }
  116. //TW UPDATE
  117. if(dz->process!=MAKE2) {
  118. if(maxamptotal > MAXANALAMP)
  119. normaliser = MAXANALAMP/maxamptotal;
  120. else
  121. normaliser = 1.0;
  122. if((exit_status = normalise_in_file(normaliser,dz))<0)
  123. return(exit_status);
  124. }
  125. dz->specenvamp = NULL; /* prevent SUPERFREE from attempting to free this pointer */
  126. return(FINISHED);
  127. }
  128. /*************************** SETUP_CHANNEL_MIFDRQS ********************/
  129. int setup_channel_mifdrqs(dataptr dz)
  130. {
  131. int cc;
  132. double thisfrq = 0.0;
  133. for(cc=0;cc<dz->clength;cc++) {
  134. dz->freq[cc] = (float)thisfrq; /* Set up midfrqs of PVOC channels */
  135. thisfrq += dz->chwidth;
  136. }
  137. return(FINISHED);
  138. }
  139. /*************************** CHECK_FORMANT_BUFFER ********************/
  140. int check_formant_buffer(dataptr dz)
  141. {
  142. if(dz->flbufptr[1] >= dz->flbufptr[3]) {
  143. if(fgetfbufEx(dz->flbufptr[2],dz->buflen2,dz->ifd[1],0)<0) {
  144. sprintf(errstr,"data miscount in check_formant_buffer()\n");
  145. return(SYSTEM_ERROR);
  146. }
  147. dz->flbufptr[1] = dz->flbufptr[2];
  148. }
  149. return(FINISHED);
  150. }
  151. /*************************** PRESET_CHANNELS ********************/
  152. int preset_channels(dataptr dz)
  153. {
  154. int vc, cc;
  155. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc+=2) {
  156. dz->flbufptr[0][AMPP] = 0.0f;
  157. dz->flbufptr[0][FREQ] = dz->freq[cc];
  158. }
  159. return(FINISHED);
  160. }
  161. /*************************** WRITE_PITCHED_WINDOW ********************/
  162. int write_pitched_window(double fundamental,double *amptotal,dataptr dz)
  163. {
  164. int exit_status;
  165. double thisamp, thisfrq = fundamental;
  166. int n = 1, vc, cc;
  167. dz->specenvamp = dz->flbufptr[1];
  168. while(thisfrq < dz->nyquist) {
  169. if((exit_status = get_channel_corresponding_to_frq(&cc,thisfrq,dz))<0)
  170. return(exit_status);
  171. vc = cc * 2;
  172. if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
  173. return(exit_status);
  174. if(thisamp > dz->flbufptr[0][vc]) {
  175. *amptotal -= dz->flbufptr[0][vc];
  176. dz->flbufptr[0][AMPP] = (float)thisamp;
  177. dz->flbufptr[0][FREQ] = (float)thisfrq;
  178. *amptotal += thisamp;
  179. }
  180. n++;
  181. thisfrq = fundamental * (double)n;
  182. }
  183. return(FINISHED);
  184. }
  185. /********************************** NORMALISE_IN_FILE ***********************************/
  186. int normalise_in_file(double normaliser,dataptr dz)
  187. {
  188. int exit_status;
  189. int vc;
  190. // int bufcnt = 0;
  191. int total_samps_to_write = dz->total_samps_written;
  192. int samps_to_write;
  193. float *bufend;
  194. //TW NEW MECHANISM writes renormalised vals from original file created (tempfile) into true outfile
  195. // true outfile gets the name the user originally input
  196. //seek eliminated
  197. if(sndcloseEx(dz->ifd[0]) < 0) {
  198. sprintf(errstr, "WARNING: Can't close input soundfile\n");
  199. return(SYSTEM_ERROR);
  200. }
  201. dz->ifd[0] = -1;
  202. if(sndcloseEx(dz->ofd) < 0) {
  203. sprintf(errstr, "WARNING: Can't close output soundfile\n");
  204. return(SYSTEM_ERROR);
  205. }
  206. dz->ofd = -1;
  207. if((dz->ifd[0] = sndopenEx(dz->outfilename,0,CDP_OPEN_RDWR)) < 0) { /*RWD Nov 2003, was RDONLY */
  208. sprintf(errstr,"Failure to reopen file %s for renormalisation.\n",dz->outfilename);
  209. return(SYSTEM_ERROR);
  210. }
  211. sndseekEx(dz->ifd[0],0,0);
  212. if((exit_status = create_sized_outfile(dz->wordstor[0],dz))<0) {
  213. sprintf(errstr,"Failure to create file %s for renormalisation.\n",dz->wordstor[0]);
  214. return(exit_status);
  215. }
  216. if((exit_status = reset_peak_finder(dz)) < 0)
  217. return exit_status;
  218. dz->total_samps_written = 0;
  219. fprintf(stdout,"INFO: Normalising.\n");
  220. fflush(stdout);
  221. while(total_samps_to_write>0) {
  222. if(fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)<0) {
  223. sprintf(errstr,"Sound read error.\n");
  224. close_and_delete_tempfile(dz->outfilename,dz);
  225. return(SYSTEM_ERROR);
  226. }
  227. dz->flbufptr[0] = dz->bigfbuf;
  228. samps_to_write = min(dz->buflen,total_samps_to_write);
  229. bufend = dz->flbufptr[0] + samps_to_write;
  230. while(dz->flbufptr[0] < bufend) {
  231. for(vc = 0;vc < dz->wanted; vc+=2)
  232. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * normaliser);
  233. dz->flbufptr[0] += dz->wanted;
  234. }
  235. if(samps_to_write>=dz->buflen) {
  236. if((exit_status = write_exact_samps(dz->bigfbuf,samps_to_write,dz))<0) {
  237. close_and_delete_tempfile(dz->outfilename,dz);
  238. return(exit_status);
  239. }
  240. } else if(samps_to_write > 0) {
  241. if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0) {
  242. close_and_delete_tempfile(dz->outfilename,dz);
  243. return(exit_status);
  244. }
  245. }
  246. total_samps_to_write -= samps_to_write;
  247. // bufcnt++;
  248. }
  249. close_and_delete_tempfile(dz->outfilename,dz);
  250. return(FINISHED);
  251. }
  252. /*************************** SPECSUM ***********************/
  253. int specsum(dataptr dz)
  254. {
  255. int vc;
  256. switch(dz->vflag[SUM_IS_CROSS]) {
  257. case(TRUE):
  258. for(vc = 0; vc < dz->wanted; vc += 2)
  259. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + (dz->param[SUM_CROSS] * dz->flbufptr[1][vc]));
  260. break;
  261. case(FALSE):
  262. for(vc = 0; vc < dz->wanted; vc += 2)
  263. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + dz->flbufptr[1][vc]);
  264. break;
  265. default:
  266. sprintf(errstr,"unknown case in specsum()\n");
  267. return(PROGRAM_ERROR);
  268. }
  269. return(FINISHED);
  270. }
  271. /*************************** SPECDIFF ***********************/
  272. int specdiff(dataptr dz)
  273. {
  274. int vc;
  275. switch(dz->vflag[DIFF_SUBZERO]) {
  276. case(FALSE):
  277. switch(dz->vflag[DIFF_IS_CROSS]) {
  278. case(FALSE):
  279. for(vc = 0; vc < dz->wanted; vc += 2)
  280. dz->flbufptr[0][vc] = (float)max(0.0,dz->flbufptr[0][vc] - dz->flbufptr[1][vc]);
  281. break;
  282. case(TRUE):
  283. for(vc = 0; vc < dz->wanted; vc += 2)
  284. dz->flbufptr[0][vc] = (float)max(0.0,dz->flbufptr[0][vc] - (dz->flbufptr[1][vc] * dz->param[DIFF_CROSS]));
  285. break;
  286. }
  287. break;
  288. case(TRUE):
  289. switch(dz->vflag[DIFF_IS_CROSS]) {
  290. case(FALSE):
  291. for(vc = 0; vc < dz->wanted; vc += 2)
  292. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] - dz->flbufptr[1][vc]);
  293. break;
  294. case(TRUE):
  295. for(vc = 0; vc < dz->wanted; vc += 2)
  296. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] - (dz->flbufptr[1][vc] * dz->param[DIFF_CROSS]));
  297. break;
  298. }
  299. break;
  300. }
  301. return(FINISHED);
  302. }
  303. /**************************** SPECLEAF ****************************/
  304. int specleaf(dataptr dz)
  305. {
  306. int exit_status;
  307. int n;
  308. int samps_read, minsams = dz->insams[0];
  309. for(n=1;n<dz->infilecnt;n++)
  310. minsams = min(minsams,dz->insams[n]);
  311. dz->wlength = minsams/dz->wanted;
  312. while(dz->total_windows < dz->wlength) {
  313. for(n = 0;n < dz->infilecnt;n++) {
  314. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[n],0))<=0) {
  315. if(samps_read<0) {
  316. sprintf(errstr,"Sound read error.\n");
  317. return(SYSTEM_ERROR);
  318. } else {
  319. sprintf(errstr,"Accounting problem: specleaf()\n");
  320. return(PROGRAM_ERROR);
  321. }
  322. }
  323. if((exit_status = write_samps(dz->bigfbuf,dz->buflen,dz))<0)
  324. return(exit_status);
  325. if((dz->total_windows += dz->iparam[LEAF_SIZE]) >= dz->wlength)
  326. break;
  327. }
  328. }
  329. return(FINISHED);
  330. }
  331. /***************************** SPECMAX ***********************
  332. *
  333. * NB file0 is always the largest.
  334. */
  335. int specmax(dataptr dz)
  336. {
  337. int exit_status;
  338. int n, m, windows_in_buf, windows_read, samps_read, samps_to_write;
  339. int windows_to_process = dz->wlength;
  340. while(windows_to_process) {
  341. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0))<=0) {
  342. if(samps_read<0) {
  343. sprintf(errstr,"Sound read error.\n");
  344. return(SYSTEM_ERROR);
  345. } else {
  346. sprintf(errstr,"Buffer accounting problem: specmax()\n");
  347. return(PROGRAM_ERROR);
  348. }
  349. }
  350. windows_read = samps_read/dz->wanted;
  351. samps_to_write = samps_read;
  352. for(n=1;n<dz->infilecnt;n++) {
  353. if((samps_read = fgetfbufEx(dz->flbufptr[2],dz->buflen,dz->ifd[n],0))>0) {
  354. windows_in_buf = samps_read/dz->wanted;
  355. dz->flbufptr[0] = dz->bigfbuf;
  356. dz->flbufptr[1] = dz->flbufptr[2];
  357. for(m=0;m<windows_in_buf;m++) {
  358. if((exit_status = do_specmax(dz))<0)
  359. return(exit_status);
  360. dz->flbufptr[0] += dz->wanted;
  361. dz->flbufptr[1] += dz->wanted;
  362. }
  363. }
  364. }
  365. if(samps_to_write > 0) {
  366. if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0)
  367. return(exit_status);
  368. }
  369. windows_to_process -= windows_read;
  370. }
  371. return(FINISHED);
  372. }
  373. /****************** DO_SPECMAX *********************/
  374. int do_specmax(dataptr dz)
  375. {
  376. int vc;
  377. for(vc=0;vc<dz->wanted;vc+=2) {
  378. if(dz->flbufptr[1][AMPP] > dz->flbufptr[0][AMPP]) {
  379. dz->flbufptr[0][AMPP] = dz->flbufptr[1][AMPP];
  380. dz->flbufptr[0][FREQ] = dz->flbufptr[1][FREQ];
  381. }
  382. }
  383. return(FINISHED);
  384. }
  385. /****************** SPECMEAN *********************/
  386. int specmean(dataptr dz)
  387. {
  388. int exit_status;
  389. int vc, cc;
  390. int *loc1 = dz->iparray[MEAN_LOC1];
  391. int *loc2 = dz->iparray[MEAN_LOC2];
  392. /* SUBZERO ALL LOUDEST-VALS TO BE USED IN THIS PASS */
  393. rectify_window(dz->flbufptr[0],dz);
  394. rectify_window(dz->flbufptr[1],dz);
  395. for(cc = 0; cc < dz->clength; cc++) {
  396. dz->windowbuf[1][cc] = -1.0f;
  397. dz->windowbuf[2][cc] = -1.0f;
  398. }
  399. if(dz->vflag[MEAN_ZEROED]) { /* zero out-of-range channels */
  400. for(vc = 0; vc < dz->iparam[MEAN_BOT];vc += 2)
  401. dz->flbufptr[0][AMPP] = 0.0f;
  402. for(vc = dz->iparam[MEAN_TOP]; vc < dz->wanted; vc += 2)
  403. dz->flbufptr[0][AMPP] = 0.0f;
  404. return(FINISHED);
  405. }
  406. for(vc = dz->iparam[MEAN_BOT]; vc < dz->iparam[MEAN_TOP]; vc += 2) {
  407. if((exit_status = if_loud_enough_to_go_in_list_put_in_list(dz->windowbuf[1],loc1,dz->flbufptr[0][vc],vc,dz))<0)
  408. return(exit_status);
  409. if((exit_status = if_loud_enough_to_go_in_list_put_in_list(dz->windowbuf[2],loc2,dz->flbufptr[1][vc],vc,dz))<0)
  410. return(exit_status);
  411. dz->windowbuf[0][AMPP] = 0.0f; /* initialise each output to zero amp */
  412. dz->windowbuf[0][FREQ] = dz->flbufptr[0][FREQ];
  413. }
  414. return generate_mean_values(loc1,loc2,dz); /* SWITCH AMPLITUDES */
  415. }
  416. /****************************** IF_LOUD_ENOUGH_TO_GO_IN_LIST_PUT_IN_LIST ******************************/
  417. int if_loud_enough_to_go_in_list_put_in_list(float *ampstore,int *locstore,float val,int location,dataptr dz)
  418. {
  419. int n = 0;
  420. if(val < 0.0) /* eliminate any subzero amplitudes */
  421. return(FINISHED);
  422. while(ampstore[n] >= val) { /* Move along until stored vals are less than input val */
  423. if(++n >= dz->clength)
  424. return(FINISHED);
  425. }
  426. if(n < dz->clength-1) { /* If ness, shuffle existing vals */
  427. memmove((char *)(ampstore + n),(char *)(ampstore + n + 1),(dz->clength - n - 1) * sizeof(float));
  428. memmove((char *)(locstore + n),(char *)(locstore + n + 1),(dz->clength - n - 1) * sizeof(int));
  429. }
  430. ampstore[n] = val; /* Store new value */
  431. locstore[n] = location; /* store its location in original buffer */
  432. return(FINISHED);
  433. }
  434. /*************************** GENERATE_MEAN_VALUES ****************************/
  435. int generate_mean_values(int *loc1, int *loc2,dataptr dz)
  436. {
  437. int exit_status;
  438. double newfrq, newamp;
  439. int j, n, a, b;
  440. n = 0;
  441. while(n < dz->clength && dz->windowbuf[1][n] >= 0.0 && dz->windowbuf[2][n] >= 0.0) {
  442. a = loc1[n];
  443. b = loc2[n];
  444. switch(dz->mode) {
  445. case(MEAN_AMP_AND_PICH):
  446. newamp = (dz->flbufptr[0][a] + dz->flbufptr[1][b])/2.0;
  447. a++;
  448. b++;
  449. if((exit_status = pichwise_mean_of_frqs
  450. (&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
  451. return(exit_status);
  452. break;
  453. case(MEAN_AMP_AND_FRQ):
  454. newamp = (dz->flbufptr[0][a] + dz->flbufptr[1][b])/2.0;
  455. a++;
  456. b++;
  457. newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
  458. break;
  459. case(AMP1_MEAN_PICH):
  460. newamp = dz->flbufptr[0][a];
  461. a++;
  462. b++;
  463. if((exit_status = pichwise_mean_of_frqs
  464. (&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
  465. return(exit_status);
  466. break;
  467. case(AMP1_MEAN_FRQ):
  468. newamp = dz->flbufptr[0][a];
  469. a++;
  470. b++;
  471. newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
  472. break;
  473. case(AMP2_MEAN_PICH):
  474. newamp = dz->flbufptr[1][b];
  475. a++;
  476. b++;
  477. if((exit_status = pichwise_mean_of_frqs
  478. (&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
  479. return(exit_status);
  480. break;
  481. case(AMP2_MEAN_FRQ):
  482. newamp = dz->flbufptr[1][b];
  483. a++;
  484. b++;
  485. newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
  486. break;
  487. case(MAXAMP_MEAN_PICH):
  488. newamp = max(dz->flbufptr[0][a],dz->flbufptr[1][b]);
  489. a++;
  490. b++;
  491. if((exit_status = pichwise_mean_of_frqs
  492. (&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
  493. return(exit_status);
  494. break;
  495. case(MAXAMP_MEAN_FRQ):
  496. newamp = max(dz->flbufptr[0][a],dz->flbufptr[1][b]);
  497. a++;
  498. b++;
  499. newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
  500. break;
  501. default:
  502. sprintf(errstr,"unknown program mode in generate_mean_values()\n");
  503. return(PROGRAM_ERROR);
  504. }
  505. j = (int)((newfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */ /*FIND APPROP CHAN */
  506. if(j < dz->infile->channels) {
  507. j *= 2;
  508. if(newamp > dz->windowbuf[0][j]) {
  509. dz->windowbuf[0][j++] = (float)newamp;
  510. dz->windowbuf[0][j] = (float)newfrq;
  511. }
  512. }
  513. n++;
  514. }
  515. for(j = dz->iparam[MEAN_BOT]; j < dz->iparam[MEAN_TOP]; j++)
  516. dz->flbufptr[0][j] = dz->windowbuf[0][j];
  517. return(FINISHED);
  518. }
  519. /****************************** PICHWISE_MEAN_OF_FRQS ******************************/
  520. int pichwise_mean_of_frqs(double *outfrq,double frq1,double frq2)
  521. {
  522. double half_of_interval_in_octaves;
  523. if(frq1 == 0.0) {
  524. *outfrq = frq2;
  525. return(FINISHED);
  526. }
  527. if(frq2 == 0.0) {
  528. *outfrq = frq1;
  529. return(FINISHED);
  530. }
  531. half_of_interval_in_octaves = (LOG2(frq2/frq1))/2.0;
  532. *outfrq = pow(2.0,half_of_interval_in_octaves) * frq1;
  533. return(FINISHED);
  534. }
  535. /************************* SPECCROSS ***************************/
  536. int speccross(dataptr dz)
  537. {
  538. int vc;
  539. double valdiff;
  540. switch(dz->vflag[CROSS_INTP]) {
  541. case(CROS_FULL):
  542. for(vc = 0; vc < dz->wanted; vc += 2)
  543. dz->flbufptr[0][vc] = dz->flbufptr[1][vc];
  544. break;
  545. case(CROS_INTERP):
  546. for(vc = 0; vc < dz->wanted; vc += 2) {
  547. valdiff = dz->flbufptr[1][vc] - dz->flbufptr[0][vc];
  548. valdiff *= dz->param[CROS_INTP];
  549. dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + valdiff);
  550. }
  551. break;
  552. default:
  553. sprintf(errstr,"Unknown flag value in speccross()\n");
  554. return(PROGRAM_ERROR);
  555. }
  556. return(FINISHED);
  557. }
  558. //TW NEW UPDATE CODE BELOW
  559. /*************************** WRITE_UNPITCHED_WINDOW ********************/
  560. #define NOISEBASEX (0.5)
  561. //TW AVOID WARNING
  562. int write_unpitched_window(double *amptotal,dataptr dz)
  563. {
  564. int exit_status;
  565. double thisamp, basefrq = 0.0, thisfrq;
  566. double rand_offset;
  567. double noisrange = 1.0 - NOISEBASEX;
  568. int n = 1, vc, cc;
  569. int ccnt = dz->wanted/2;
  570. n = 1;
  571. while(n <= ccnt) {
  572. rand_offset = (drand48() - (.5)) * dz->chwidth;
  573. thisfrq = basefrq + rand_offset;
  574. if(thisfrq < 0.0 || thisfrq > dz->nyquist)
  575. continue;
  576. if((exit_status = get_channel_corresponding_to_frq(&cc,thisfrq,dz))<0)
  577. return(exit_status);
  578. vc = cc * 2;
  579. if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
  580. return(exit_status);
  581. if(thisamp > dz->flbufptr[0][vc]) {
  582. *amptotal -= dz->flbufptr[0][vc];
  583. dz->flbufptr[0][AMPP] = (float)(thisamp * (drand48() * noisrange));
  584. dz->flbufptr[0][FREQ] = (float)thisfrq;
  585. *amptotal += thisamp;
  586. }
  587. basefrq += dz->chwidth;
  588. n++;
  589. }
  590. return(FINISHED);
  591. }
  592. /*************************** WRITE_SILENT_WINDOW ********************/
  593. int write_silent_window(dataptr dz)
  594. {
  595. int vc, cc;
  596. double thisfrq = 0.0;
  597. for(cc=0, vc =0; cc < dz->clength; cc++, vc += 2) {
  598. dz->flbufptr[0][AMPP] = (float)0.0;
  599. dz->flbufptr[0][FREQ] = (float)thisfrq;
  600. thisfrq += dz->chwidth;
  601. }
  602. return(FINISHED);
  603. }
  604. /*************************** READ_ENVEL_FROM_ENVFILE **************************/
  605. int read_envel_from_envfile(float **env,float **envend,int *envlen,int fileno,dataptr dz)
  606. {
  607. int samps_to_read, secs_to_read;
  608. *envlen = dz->insams[fileno];
  609. if(((secs_to_read = dz->insams[fileno]/F_SECSIZE)*F_SECSIZE)!=dz->insams[fileno])
  610. secs_to_read++;
  611. samps_to_read = secs_to_read * F_SECSIZE;
  612. if((*env = (float *)malloc((size_t)(samps_to_read * sizeof(float))))==NULL) {
  613. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  614. return(MEMORY_ERROR);
  615. }
  616. if(fgetfbufEx(*env,samps_to_read,dz->ifd[fileno],0) < 0) {
  617. sprintf(errstr,"fgetfbufEx() Anomaly in read_envel_from_envfile()\n");
  618. return(SYSTEM_ERROR);
  619. }
  620. if((*env = (float *)realloc(*env,(size_t)(dz->insams[fileno] * sizeof(float))))==NULL) {
  621. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope array.\n");
  622. return(MEMORY_ERROR);
  623. }
  624. *envend = *env + *envlen;
  625. return(FINISHED);
  626. }