formants.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  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. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <flags.h>
  30. #include <fmnts.h>
  31. #include <cdpmain.h>
  32. #include <formants.h>
  33. #include <speccon.h>
  34. #include <sfsys.h>
  35. #include <string.h>
  36. #include <fmnts.h>
  37. static int inner_form_loop(int windows_in_buf,dataptr dz);
  38. static int do_specform(dataptr dz);
  39. static int form_filter(dataptr dz);
  40. static int form_gain(dataptr dz);
  41. static int vocode_channel(int vc,dataptr dz);
  42. static int eliminate_out_of_range_data(dataptr dz);
  43. static int vocogain(dataptr dz);
  44. static int reset_file_to_start_and_pointers_to_after_descriptor_blocks(int *windows_in_buf,dataptr dz);
  45. static int renormalise_formsee(dataptr dz);
  46. //static int setformval(int *thissamp,float inval,double normaliser,double adjuster);
  47. static int setformval(float *thissamp,float inval,double normaliser,double adjuster);
  48. static int do_specformants(dataptr dz);
  49. static int extract_formant_and_place_in_output_buffer(int formantlen,dataptr dz);
  50. static int get_max_formantval(dataptr dz);
  51. static int initialise_the_formant_data(int *windows_in_buf,dataptr dz);
  52. /****************************** SPECFORMANTS ***************************/
  53. int specformants(dataptr dz)
  54. {
  55. int exit_status;
  56. int wc, windows_in_buf;
  57. int OK = 1;
  58. if(sloom)
  59. dz->total_samps_read = 0L;
  60. dz->time = 0.0f;
  61. while(OK) {
  62. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
  63. return exit_status;
  64. if(dz->ssampsread <= 0)
  65. break;
  66. dz->flbufptr[0] = dz->bigfbuf;
  67. windows_in_buf = dz->ssampsread/dz->wanted;
  68. for(wc=0; wc<windows_in_buf; wc++) {
  69. if(dz->total_windows==0) {
  70. if((exit_status = skip_or_special_operation_on_window_zero(dz))<0)
  71. return(exit_status);
  72. if(exit_status==TRUE) {
  73. dz->flbufptr[0] += dz->wanted;
  74. dz->total_windows++;
  75. dz->time = (float)(dz->time + dz->frametime);
  76. continue;
  77. }
  78. }
  79. if((exit_status = do_specformants(dz))<0)
  80. return(exit_status);
  81. dz->flbufptr[0] += dz->wanted; /* move along bigfbuf */
  82. dz->total_windows++;
  83. dz->time = (float)(dz->time + dz->frametime);
  84. }
  85. }
  86. if(dz->iparam[FMNT_SAMPS_TO_WRITE] > 0) {
  87. if((exit_status = write_samps(dz->flbufptr[2],dz->iparam[FMNT_SAMPS_TO_WRITE],dz))<0)
  88. return(exit_status);
  89. }
  90. return(FINISHED);
  91. }
  92. /**************************** DO_SPECFORMANTS ***************************
  93. *
  94. * Extract formants from an analfile.
  95. */
  96. int do_specformants(dataptr dz)
  97. {
  98. int exit_status;
  99. rectify_window(dz->flbufptr[0],dz);
  100. if((exit_status = extract_specenv(0,0,dz))<0)
  101. return(exit_status);
  102. memmove((char *)dz->flbufptr[1],(char *)dz->specenvamp,(dz->infile->specenvcnt * sizeof(float)));
  103. if((dz->iparam[FMNT_SAMPS_TO_WRITE] += dz->infile->specenvcnt) >= dz->buflen2) {
  104. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen2,dz))<0)
  105. return(exit_status);
  106. dz->iparam[FMNT_SAMPS_TO_WRITE] = 0L;
  107. dz->flbufptr[1] = dz->flbufptr[2];
  108. } else
  109. dz->flbufptr[1] += dz->infile->specenvcnt; /* move along dz->flbufptr[2] */
  110. return(FINISHED);
  111. }
  112. /****************************** SPECFORM ***************************/
  113. int specform(dataptr dz)
  114. {
  115. int exit_status, current_status;
  116. int windows_in_buf;
  117. if(sloom)
  118. dz->total_samps_read = 0L;
  119. dz->time = 0.0f;
  120. if((exit_status = setup_formant_params(dz->ifd[1],dz))<0)
  121. return(exit_status);
  122. // if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) ALREADY READ IN setup_formant_params()
  123. // return(exit_status);
  124. while(dz->ssampsread > 0) {
  125. dz->flbufptr[0] = dz->bigfbuf;
  126. windows_in_buf = dz->ssampsread/dz->wanted;
  127. if((exit_status = inner_form_loop(windows_in_buf,dz))<0) {
  128. dz->specenvamp2 = (float *)0;
  129. return(exit_status);
  130. }
  131. current_status = exit_status;
  132. if(dz->flbufptr[0] - dz->bigfbuf > 0) {
  133. if((exit_status = write_samps(dz->bigfbuf,(dz->flbufptr[0] - dz->bigfbuf),dz))<0) {
  134. dz->specenvamp2 = NULL;
  135. return(exit_status);
  136. }
  137. }
  138. if(current_status!=CONTINUE)
  139. break;
  140. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
  141. return(exit_status);
  142. }
  143. dz->specenvamp2 = NULL;
  144. return(FINISHED);
  145. }
  146. /****************************** INNER_FORM_LOOP ***************************/
  147. int inner_form_loop(int windows_in_buf,dataptr dz)
  148. {
  149. int exit_status;
  150. int wc;
  151. double pre_amptotal, post_amptotal;
  152. for(wc=0; wc<windows_in_buf; wc++) {
  153. if(dz->total_windows==0) {
  154. if((exit_status = move_along_formant_buffer(dz))!=CONTINUE)
  155. return(exit_status);
  156. dz->flbufptr[0] += dz->wanted;
  157. dz->total_windows++;
  158. dz->time = (float)(dz->time + dz->frametime);
  159. continue; /* SKIP FIRST (ZERO-AMP) WINDOW */
  160. }
  161. if(dz->mode==FORM_REPLACE) {
  162. rectify_window(dz->flbufptr[0],dz);
  163. if((exit_status = extract_specenv(0,0,dz))<0)
  164. return(exit_status);
  165. }
  166. dz->specenvamp2 = dz->flbufptr[1];
  167. pre_amptotal = post_amptotal = 0.0;
  168. if((exit_status = get_totalamp(&pre_amptotal,dz->flbufptr[0],dz->wanted))<0)
  169. return(exit_status);
  170. if((exit_status = do_specform(dz))<0)
  171. return(exit_status);
  172. if((exit_status = form_filter(dz))<0)
  173. return(exit_status);
  174. if((exit_status = get_totalamp(&post_amptotal,dz->flbufptr[0],dz->wanted))<0)
  175. return(exit_status);
  176. if((exit_status = normalise(pre_amptotal,post_amptotal,dz))<0)
  177. return(exit_status);
  178. if(!flteq(dz->param[FORM_GAIN],1.0)) {
  179. if((exit_status = form_gain(dz))<0)
  180. return(exit_status);
  181. /* NB This check must be BEFORE move_along_formant_buffer() */
  182. }
  183. dz->flbufptr[0] += dz->wanted;
  184. if(++dz->total_windows >= dz->wlength)
  185. return(FINISHED);
  186. if((exit_status = move_along_formant_buffer(dz))!=CONTINUE)
  187. return(exit_status);
  188. dz->time = (float)(dz->time + dz->frametime);
  189. }
  190. return(CONTINUE);
  191. }
  192. /**************************** DO_SPECFORM ***************************
  193. *
  194. * Impose formants onto an analfile.
  195. */
  196. int do_specform(dataptr dz)
  197. {
  198. int exit_status;
  199. int vc;
  200. double thisspecamp0, thisspecamp1, thisvalue;
  201. rectify_window(dz->flbufptr[0],dz);
  202. switch(dz->mode) {
  203. case(FORM_REPLACE):
  204. for(vc = 0; vc < dz->wanted ; vc += 2) {
  205. if((exit_status = getspecenvamp(&thisspecamp0,(double)dz->flbufptr[0][FREQ],0,dz))<0)
  206. return(exit_status);
  207. if((exit_status = getspecenvamp(&thisspecamp1,(double)dz->flbufptr[0][FREQ],1,dz))<0)
  208. return(exit_status);
  209. if(thisspecamp0 < VERY_TINY_VAL)
  210. dz->flbufptr[0][AMPP] = 0.0f;
  211. else {
  212. if((thisvalue = dz->flbufptr[0][AMPP] * thisspecamp1/thisspecamp0)< VERY_TINY_VAL)
  213. dz->flbufptr[0][AMPP] = 0.0f;
  214. else
  215. dz->flbufptr[0][AMPP] = (float)thisvalue;
  216. }
  217. }
  218. break;
  219. case(FORM_IMPOSE):
  220. for(vc = 0; vc < dz->wanted ; vc += 2) {
  221. if((exit_status = getspecenvamp(&thisspecamp1,(double)dz->flbufptr[0][FREQ],1,dz))<0)
  222. return(exit_status);
  223. if((thisvalue = dz->flbufptr[0][AMPP] * thisspecamp1)< VERY_TINY_VAL)
  224. dz->flbufptr[0][AMPP] = 0.0f;
  225. else
  226. dz->flbufptr[0][AMPP] = (float)thisvalue;
  227. }
  228. break;
  229. default:
  230. sprintf(errstr,"Unknown case in do_specform()\n");
  231. return(PROGRAM_ERROR);
  232. }
  233. return(FINISHED);
  234. }
  235. /****************************** FORM_FILTER ***************************/
  236. int form_filter(dataptr dz)
  237. {
  238. int vc;
  239. for(vc = 0; vc < dz->wanted ; vc += 2) {
  240. if(dz->flbufptr[0][FREQ] < dz->param[FORM_FBOT]
  241. || dz->flbufptr[0][FREQ] > dz->param[FORM_FTOP])
  242. dz->flbufptr[0][AMPP] = 0.0f;
  243. }
  244. return(FINISHED);
  245. }
  246. /****************************** FORM_GAIN ***************************/
  247. int form_gain(dataptr dz)
  248. {
  249. int vc;
  250. for(vc=0;vc<dz->wanted;vc+=2)
  251. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->param[FORM_GAIN]);
  252. return(FINISHED);
  253. }
  254. /************************** SPECVOCODE ***********************/
  255. int specvocode(dataptr dz)
  256. {
  257. int exit_status;
  258. int vc;
  259. double pre_amptotal, post_amptotal;
  260. rectify_window(dz->flbufptr[0],dz);
  261. if((exit_status = extract_specenv(0,0,dz))<0)
  262. return(exit_status);
  263. rectify_window(dz->flbufptr[1],dz);
  264. if((exit_status = extract_specenv(1,1,dz))<0)
  265. return(exit_status);
  266. if((exit_status = get_totalamp(&pre_amptotal,dz->flbufptr[0],dz->wanted))<0)
  267. return(exit_status);
  268. for(vc = 0; vc < dz->wanted; vc += 2) {
  269. if((exit_status = vocode_channel(vc,dz))<0)
  270. return(exit_status);
  271. }
  272. if((exit_status = eliminate_out_of_range_data(dz))<0)
  273. return(exit_status);
  274. if((exit_status = get_totalamp(&post_amptotal,dz->flbufptr[0],dz->wanted))<0)
  275. return(exit_status);
  276. if((exit_status = normalise(pre_amptotal,post_amptotal,dz))<0)
  277. return(exit_status);
  278. return vocogain(dz);
  279. }
  280. /************************** VOCODE_CHANNEL ***********************/
  281. int vocode_channel(int vc,dataptr dz)
  282. {
  283. int exit_status;
  284. double thisvalue;
  285. double thisspecamp1, thisspecamp2;
  286. if((exit_status = getspecenvamp(&thisspecamp1,(double)dz->flbufptr[0][FREQ],0,dz))<0)
  287. return(exit_status);
  288. if((exit_status = getspecenvamp(&thisspecamp2,(double)dz->flbufptr[1][FREQ],1,dz))<0)
  289. return(exit_status);
  290. if(thisspecamp1 <= 0.0)
  291. dz->flbufptr[0][AMPP] = 0.0f;
  292. else {
  293. if((thisvalue = dz->flbufptr[0][AMPP] * thisspecamp2/thisspecamp1) < VERY_TINY_VAL)
  294. dz->flbufptr[0][AMPP] = 0.0f;
  295. else
  296. dz->flbufptr[0][AMPP] = (float)thisvalue;
  297. }
  298. return(FINISHED);
  299. }
  300. /************************** ELIMINATE_OUT_OF_RANGE_DATA ***********************/
  301. int eliminate_out_of_range_data(dataptr dz)
  302. {
  303. int vc;
  304. for(vc = 0;vc < dz->wanted; vc+=2) {
  305. if(dz->flbufptr[0][FREQ] < dz->param[VOCO_LOF] || dz->flbufptr[0][FREQ] > dz->param[VOCO_HIF])
  306. dz->flbufptr[0][AMPP] = 0.0f;
  307. }
  308. return(FINISHED);
  309. }
  310. /************************** VOCOGAIN ***********************/
  311. int vocogain(dataptr dz)
  312. {
  313. int vc;
  314. if(!flteq(dz->param[VOCO_GAIN],1.0)) {
  315. for(vc=0;vc<dz->wanted;vc+=2)
  316. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * dz->param[VOCO_GAIN]);
  317. }
  318. return(FINISHED);
  319. }
  320. /**************************** SPECFMNTSEE ***************************/
  321. int specfmntsee(dataptr dz)
  322. {
  323. int exit_status;
  324. double thisval;
  325. int windows_in_buf, wc;
  326. int cc;
  327. double normaliser;
  328. // double adjuster = (double)MAXSAMP/log(10000.0);
  329. double adjuster = F_MAXSAMP/log(10000.0);
  330. int outcnt = 0, outbufcnt = 0;
  331. if(sloom)
  332. dz->total_samps_read = 0L;
  333. if((exit_status = initialise_the_formant_data(&windows_in_buf,dz))<0)
  334. return(exit_status);
  335. normaliser = 9999.0/dz->param[FMNTSEE_MAX];
  336. dz->time = 0.0f;
  337. do {
  338. for(wc=0; wc<windows_in_buf; wc++) {
  339. if(dz->total_windows==0) {
  340. if((exit_status = skip_or_special_operation_on_window_zero(dz))<0)
  341. return(exit_status);
  342. if(exit_status==TRUE) {
  343. dz->flbufptr[0] += dz->wanted;
  344. dz->total_windows++;
  345. dz->time = (float)(dz->time + dz->frametime);
  346. continue;
  347. }
  348. }
  349. for(cc = 0; cc < dz->wanted; cc++) {
  350. thisval = log((dz->flbufptr[0][cc] * normaliser) + 1.0);
  351. thisval *= adjuster;
  352. // dz->sndbuf[outcnt] = (short)round(thisval);
  353. dz->sndbuf[outcnt] = (float)thisval;
  354. if(++outcnt >= (dz->infile->specenvcnt + SPACER) * FMNT_BUFMULT) {
  355. sprintf(errstr,"buffer accounting error in specfmntsee()\n");
  356. return(PROGRAM_ERROR);
  357. }
  358. }
  359. for(cc = 0; cc < SPACER; cc++)
  360. // dz->sndbuf[outcnt++] = (short)0;
  361. dz->sndbuf[outcnt++] = 0.0f;
  362. if(++outbufcnt >= FMNT_BUFMULT) {
  363. if(outcnt != (dz->infile->specenvcnt + SPACER) * FMNT_BUFMULT) {
  364. sprintf(errstr,"bufcount error in specfmntsee()\n");
  365. return(PROGRAM_ERROR);
  366. }
  367. if(outcnt > 0) {
  368. if((exit_status = write_samps(dz->sndbuf,outcnt,dz))<0)
  369. return(exit_status);
  370. }
  371. outcnt = 0;
  372. outbufcnt = 0;
  373. }
  374. dz->flbufptr[0] += dz->wanted; /* move along bigfbuf */
  375. dz->time = (float)(dz->time + dz->frametime);
  376. }
  377. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
  378. sprintf(errstr,"Sound read error.\n");
  379. return(SYSTEM_ERROR);
  380. }
  381. dz->flbufptr[0] = dz->bigfbuf;
  382. windows_in_buf = dz->ssampsread/dz->wanted;
  383. } while(windows_in_buf > 0);
  384. if(outcnt) {
  385. if((exit_status = write_samps(dz->sndbuf,outcnt,dz))<0)
  386. return(exit_status);
  387. }
  388. return(FINISHED);
  389. }
  390. /*********************** RESET_FILE_TO_START_AND_POINTERS_TO_AFTER_DESCRIPTOR_BLOCKS **********************/
  391. int reset_file_to_start_and_pointers_to_after_descriptor_blocks(int *windows_in_buf,dataptr dz)
  392. {
  393. int exit_status;
  394. if(sndseekEx(dz->ifd[0],0L,0)<0) { /* RESET FILE POINTER TO START OF DATA */
  395. sprintf(errstr,"seek failed in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  396. return(SYSTEM_ERROR);
  397. }
  398. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
  399. sprintf(errstr,"Read problem after rewind in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  400. return(SYSTEM_ERROR);
  401. }
  402. *windows_in_buf = dz->ssampsread/dz->wanted;
  403. if((*windows_in_buf -= DESCRIPTOR_DATA_BLOKS) < 0) {
  404. sprintf(errstr,"Buffers too SMALL in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  405. return(PROGRAM_ERROR);
  406. }
  407. dz->flbufptr[0] = dz->bigfbuf + (DESCRIPTOR_DATA_BLOKS * dz->wanted);
  408. return(FINISHED);
  409. }
  410. /**************************** OUTER_FORMSEE_LOOP ****************************/
  411. int outer_formsee_loop(dataptr dz)
  412. {
  413. int exit_status;
  414. int windows_in_buf, peakscore = 0, pitchcnt = 0;
  415. int in_start_portion = TRUE, least = 0, descnt = 0;
  416. if(sloom)
  417. dz->total_samps_read = 0L;
  418. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
  419. return(exit_status);
  420. while(dz->ssampsread > 0) {
  421. dz->flbufptr[0] = dz->bigfbuf;
  422. windows_in_buf = dz->ssampsread/dz->wanted;
  423. if((exit_status = inner_loop(&peakscore,&descnt,&in_start_portion,&least,&pitchcnt,windows_in_buf,dz))<0)
  424. return(exit_status);
  425. if((exit_status = write_samps(dz->bigfbuf,dz->ssampsread,dz))<0)
  426. return(exit_status);
  427. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
  428. return(exit_status);
  429. }
  430. if(dz->ssampsread < 0) {
  431. sprintf(errstr,"Sound read error.\n");
  432. return(SYSTEM_ERROR);
  433. }
  434. return renormalise_formsee(dz);
  435. }
  436. /******************************* RENORMALISE_FORMSEE ****************************
  437. *
  438. * Multiply by 9999/formantmax -> range 0 TO 9999.
  439. * Add 1 -> range 1 TO 10000.
  440. * Take log : -> range 0 TO log(10000).(log display)
  441. * Times MAXSAMPP/log(10000) : -> range 0 TO MAXSAMPP (log log display)
  442. */
  443. int renormalise_formsee(dataptr dz)
  444. {
  445. int exit_status;
  446. int cc, vc;
  447. int wc, outcnt, outbufcnt /* , total_samps_read */;
  448. int ssampsread, total_samps_todo = dz->total_samps_written;
  449. int windows_in_buf;
  450. int windows_remaining = dz->wlength;
  451. float thissamp;
  452. double normaliser;
  453. double adjuster = F_MAXSAMP/log(10000.0);
  454. int chans, stype;
  455. int srate;
  456. if(dz->param[FSEE_FMAX] < VERY_TINY_VAL) {
  457. sprintf(errstr,"No siginificant data found in srcfile\n");
  458. return(DATA_ERROR);
  459. }
  460. //TW NEW MECHANISM writes renormalised vals from original file created (tempfile) into true outfile
  461. // true outfile gets the name the user originally input
  462. if(sndcloseEx(dz->ifd[0]) < 0) {
  463. sprintf(errstr, "WARNING: Can't close input soundfile\n");
  464. return(SYSTEM_ERROR);
  465. }
  466. if(sndcloseEx(dz->ofd) < 0) {
  467. sprintf(errstr, "WARNING: Can't close output soundfile\n");
  468. return(SYSTEM_ERROR);
  469. }
  470. if((dz->ifd[0] = sndopenEx(dz->outfilename,0,CDP_OPEN_RDWR)) < 0) { /* RWD Nov 2003 was RDONLY */
  471. sprintf(errstr,"Failure to reopen file %s for renormalisation.\n",dz->outfilename);
  472. return(SYSTEM_ERROR);
  473. }
  474. /* RWD Jumy 2010 no lopmger need this - now built into sndopenEx in sfsys */
  475. //sndseekEx(dz->ifd[0],0,0);
  476. chans = dz->infile->channels;
  477. srate = dz->infile->srate;
  478. stype = dz->infile->stype;
  479. dz->infile->channels = 1;
  480. dz->infile->srate = dz->infile->origrate;
  481. dz->infile->stype = SAMP_SHORT;
  482. if((exit_status = create_sized_outfile(dz->wordstor[0],dz))<0) {
  483. sprintf(errstr,"Failure to create file %s for renormalisation.\n",dz->wordstor[0]);
  484. return(exit_status);
  485. }
  486. dz->infile->channels = chans;
  487. dz->infile->srate = srate;
  488. dz->infile->stype = stype;
  489. if((exit_status = reset_peak_finder(dz))<0)
  490. return(exit_status);
  491. normaliser = 9999.0/dz->param[FSEE_FMAX];
  492. total_samps_todo = dz->total_samps_written;
  493. outbufcnt = 0L;
  494. outcnt = 0L;
  495. // total_samps_read = 0L;
  496. dz->total_samps_written = 0L;
  497. dz->total_windows = 0L;
  498. dz->total_samps_read = 0L;
  499. while(total_samps_todo > 0) {
  500. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
  501. sprintf(errstr,"Sound read error.\n");
  502. close_and_delete_tempfile(dz->outfilename,dz);
  503. return(SYSTEM_ERROR);
  504. }
  505. dz->flbufptr[0] = dz->bigfbuf;
  506. // total_samps_read += dz->ssampsread;
  507. ssampsread = dz->ssampsread;
  508. if(total_samps_todo - ssampsread<0) {
  509. ssampsread = total_samps_todo;
  510. total_samps_todo = 0;
  511. } else
  512. total_samps_todo -= ssampsread;
  513. windows_in_buf = ssampsread/dz->wanted;
  514. if(windows_remaining - windows_in_buf < 0) {
  515. windows_in_buf = windows_remaining;
  516. windows_remaining = 0;
  517. } else
  518. windows_remaining -= windows_in_buf;
  519. for(wc=0;wc<windows_in_buf;wc++) {
  520. if(dz->total_windows==0) {
  521. for(cc=0;cc<dz->clength;cc++)
  522. dz->sndbuf[outcnt++] = 0.0f;
  523. } else {
  524. for(cc=0,vc=0;cc<dz->iparam[FSEE_FCNT];cc++,vc += 2) { /* 1 */
  525. if((exit_status = setformval(&thissamp,dz->flbufptr[0][AMPP],normaliser,adjuster))<0)
  526. return(exit_status);
  527. dz->sndbuf[outcnt++] = thissamp;
  528. }
  529. for(;cc<dz->clength;cc++)
  530. dz->sndbuf[outcnt++] = 0.0f;
  531. }
  532. if(++outbufcnt >= FMNT_BUFMULT) {
  533. if(outcnt!=dz->clength * FMNT_BUFMULT) {
  534. sprintf(errstr,"Buffercnt error in renormalise_formsee()\n");
  535. close_and_delete_tempfile(dz->outfilename,dz);
  536. return(PROGRAM_ERROR);
  537. }
  538. if(outcnt > 0) {
  539. if((exit_status = write_samps(dz->sndbuf,outcnt,dz))<0) {
  540. close_and_delete_tempfile(dz->outfilename,dz);
  541. return(exit_status);
  542. }
  543. }
  544. outcnt = 0;
  545. outbufcnt = 0;
  546. }
  547. dz->flbufptr[0] += dz->wanted;
  548. dz->total_windows++;
  549. }
  550. if(windows_remaining <=0)
  551. break;
  552. }
  553. if(outcnt) {
  554. if((exit_status = write_samps(dz->sndbuf,outcnt,dz))<0) {
  555. close_and_delete_tempfile(dz->outfilename,dz);
  556. return(exit_status);
  557. }
  558. }
  559. close_and_delete_tempfile(dz->outfilename,dz);
  560. return(FINISHED);
  561. }
  562. /****************************** SETFORMVAL ***************************/
  563. //int setformval(int *thissamp,float inval,double normaliser,double adjuster)
  564. int setformval(float *thissamp,float inval,double normaliser,double adjuster)
  565. {
  566. double thisval = log((inval * normaliser) + 1.0);
  567. // thisval *= adjuster;
  568. // *thissamp = round(thisval);
  569. *thissamp = (float)(thisval * adjuster);
  570. return(FINISHED);
  571. }
  572. /**************************** SPECFORMSEE ***************************/
  573. int specformsee(dataptr dz)
  574. {
  575. int exit_status;
  576. rectify_window(dz->flbufptr[0],dz);
  577. if((exit_status = extract_specenv(0,0,dz))<0)
  578. return(exit_status);
  579. return extract_formant_and_place_in_output_buffer(dz->iparam[FSEE_FCNT],dz);
  580. }
  581. /*********************** EXTRACT_FORMANT_AND_PLACE_IN_OUTPUT_BUFFER **********************/
  582. int extract_formant_and_place_in_output_buffer(int formantlen,dataptr dz)
  583. {
  584. int exit_status;
  585. int cc, vc;
  586. double thisamp;
  587. for(cc=0,vc=0;cc<formantlen;cc++,vc+=2) {
  588. if((exit_status = getspecenvamp(&thisamp,dz->windowbuf[0][cc],0,dz))<0)
  589. return(exit_status);
  590. dz->flbufptr[0][AMPP] = (float)thisamp;
  591. if(dz->flbufptr[0][AMPP] > dz->param[FSEE_FMAX])
  592. dz->param[FSEE_FMAX] = dz->flbufptr[0][AMPP];
  593. }
  594. for(;cc<dz->clength;cc++,vc+=2)
  595. dz->flbufptr[0][AMPP] = 0.0f;
  596. return(FINISHED);
  597. }
  598. /***************************** GET_MAX_FORMANTVAL *************************/
  599. int get_max_formantval(dataptr dz)
  600. {
  601. int exit_status;
  602. int total_floats_in_file = (dz->wlength + DESCRIPTOR_DATA_BLOKS) * dz->infile->specenvcnt;
  603. int floats_read = min(total_floats_in_file,dz->big_fsize);
  604. float *sbufend = dz->bigfbuf + floats_read;
  605. float *sbuf = dz->flbufptr[0];
  606. /* which has already skipped the float descriptor blocks */
  607. dz->param[FMNTSEE_MAX] = 0.0;
  608. do {
  609. while(sbuf < sbufend) {
  610. if(*sbuf > dz->param[FMNTSEE_MAX])
  611. dz->param[FMNTSEE_MAX] = *sbuf;
  612. sbuf++;
  613. }
  614. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0) {
  615. sprintf(errstr,"Sound read error.\n");
  616. return(SYSTEM_ERROR);
  617. }
  618. sbuf = dz->bigfbuf;
  619. sbufend = dz->bigfbuf + dz->ssampsread;
  620. } while(dz->ssampsread > 0);
  621. return(FINISHED);
  622. }
  623. /***************************** INITIALISE_THE_FORMANT_DATA *************************/
  624. int initialise_the_formant_data(int *windows_in_buf,dataptr dz)
  625. {
  626. int exit_status;
  627. int fsamps_to_read = dz->descriptor_samps/DESCRIPTOR_DATA_BLOKS;
  628. if((exit_status = read_samps(dz->bigfbuf,dz)) < 0)
  629. return(exit_status);
  630. if(dz->ssampsread < dz->descriptor_samps) {
  631. sprintf(errstr,"No significant data in formantfile.\n");
  632. return(DATA_ERROR);
  633. }
  634. dz->flbufptr[0] = dz->bigfbuf;
  635. memmove((char *)dz->specenvpch,(char *)dz->flbufptr[0],(size_t)(fsamps_to_read * sizeof(float)));
  636. dz->flbufptr[0] += dz->infile->specenvcnt;
  637. memmove((char *)dz->specenvtop,(char *)dz->flbufptr[0],(size_t)(fsamps_to_read * sizeof(float)));
  638. dz->flbufptr[0] += dz->infile->specenvcnt;
  639. dz->flbufptr[0] = dz->bigfbuf + (DESCRIPTOR_DATA_BLOKS * dz->wanted);
  640. *windows_in_buf = dz->ssampsread/dz->wanted;
  641. if((*windows_in_buf -= DESCRIPTOR_DATA_BLOKS) <= 0) {
  642. sprintf(errstr,"Buffers too SMALL for formant data.\n");
  643. return(PROGRAM_ERROR);
  644. }
  645. if(dz->vflag[FMNT_VIEW])
  646. print_formant_params_to_screen(dz);
  647. if((exit_status = get_max_formantval(dz))<0)
  648. return(exit_status);
  649. return reset_file_to_start_and_pointers_to_after_descriptor_blocks(windows_in_buf,dz);
  650. }