ap_formants.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  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 <cdpmain.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <fmnts.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <globcon.h>
  31. #include <logic.h>
  32. #include <filetype.h>
  33. #include <mixxcon.h>
  34. #include <speccon.h>
  35. #include <flags.h>
  36. #include <arrays.h>
  37. #include <formants.h>
  38. #include <sfsys.h>
  39. #include <osbind.h>
  40. #include <string.h>
  41. #include <math.h>
  42. #include <srates.h>
  43. /********************************************************************************************/
  44. /********************************** FORMERLY IN pconsistency.c ******************************/
  45. /********************************************************************************************/
  46. static int check_compatibility_of_params_for_form(dataptr dz);
  47. /********************************************************************************************/
  48. /********************************** FORMERLY IN procspec.c **********************************/
  49. /********************************************************************************************/
  50. static int zero_formant(dataptr dz);
  51. /********************************************************************************************/
  52. /********************************** FORMERLY IN preprocess.c ********************************/
  53. /********************************************************************************************/
  54. #define MSECOND (1.059463)
  55. #define SECOND (1.122462)
  56. #define MTHIRD (1.1892)
  57. #define THIRD (1.259921)
  58. #define FOURTH (1.33484)
  59. #define TRITONE (1.414214)
  60. #define FIFTH (1.4983)
  61. #define MSIXTH (1.5874)
  62. #define SIXTH (1.6818)
  63. #define MSEVENTH (1.781797)
  64. #define SEVENTH (1.88775)
  65. static int formants_preprocess(dataptr dz);
  66. static int setup_internal_arrays_and_params_for_fmntsee(dataptr dz);
  67. //TW REMOVED: redundant
  68. //static int get_max_formantval(dataptr dz);
  69. static int setup_internal_params_and_arrays_for_formsee(dataptr dz);
  70. static int get_formant_sample_points(int *fcnt,dataptr dz);
  71. /***************************************************************************************/
  72. /****************************** FORMERLY IN aplinit.c **********************************/
  73. /***************************************************************************************/
  74. /***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/
  75. int establish_bufptrs_and_extra_buffers(dataptr dz)
  76. {
  77. int exit_status;
  78. int is_spec = FALSE;
  79. dz->extra_bufcnt = -1; /* ENSURE EVERY CASE HAS A PAIR OF ENTRIES !! */
  80. dz->bptrcnt = 0;
  81. dz->bufcnt = 0;
  82. switch(dz->process) {
  83. case(FORMANTS): dz->extra_bufcnt = 0; dz->bptrcnt = 4; is_spec = TRUE; break;
  84. case(FORM): dz->extra_bufcnt = 0; dz->bptrcnt = 4; is_spec = TRUE; break;
  85. case(VOCODE): dz->extra_bufcnt = 0; dz->bptrcnt = 4; is_spec = TRUE; break;
  86. case(FMNTSEE): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
  87. case(FORMSEE): dz->extra_bufcnt = 1; dz->bptrcnt = 1; is_spec = TRUE; break;
  88. default:
  89. sprintf(errstr,"Unknown program type [%d] in establish_bufptrs_and_extra_buffers()\n",dz->process);
  90. return(PROGRAM_ERROR);
  91. }
  92. if(dz->extra_bufcnt < 0) {
  93. sprintf(errstr,"bufcnts have not been set: establish_bufptrs_and_extra_buffers()\n");
  94. return(PROGRAM_ERROR);
  95. }
  96. if(is_spec)
  97. return establish_spec_bufptrs_and_extra_buffers(dz);
  98. else if((dz->process==HOUSE_SPEC && dz->mode==HOUSE_CONVERT) || dz->process==INFO_DIFF) {
  99. if((exit_status = establish_spec_bufptrs_and_extra_buffers(dz))<0)
  100. return(exit_status);
  101. }
  102. return establish_groucho_bufptrs_and_extra_buffers(dz);
  103. }
  104. /***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
  105. int setup_internal_arrays_and_array_pointers(dataptr dz)
  106. {
  107. int n;
  108. dz->ptr_cnt = -1; //base constructor...process
  109. dz->array_cnt = -1;
  110. dz->iarray_cnt = -1;
  111. dz->larray_cnt = -1;
  112. switch(dz->process) {
  113. case(FORMANTS): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  114. case(FORM): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  115. case(VOCODE): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  116. case(FMNTSEE): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  117. case(FORMSEE): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
  118. }
  119. /*** WARNING ***
  120. ANY APPLICATION DEALING WITH A NUMLIST INPUT: MUST establish AT LEAST 1 double array: i.e. dz->array_cnt = at least 1
  121. **** WARNING ***/
  122. if(dz->array_cnt < 0 || dz->iarray_cnt < 0 || dz->larray_cnt < 0 || dz->ptr_cnt < 0 || dz->fptr_cnt < 0) {
  123. sprintf(errstr,"array_cnt not set in setup_internal_arrays_and_array_pointers()\n");
  124. return(PROGRAM_ERROR);
  125. }
  126. if(dz->array_cnt > 0) {
  127. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  128. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  129. return(MEMORY_ERROR);
  130. }
  131. for(n=0;n<dz->array_cnt;n++)
  132. dz->parray[n] = NULL;
  133. }
  134. if(dz->iarray_cnt > 0) {
  135. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  136. sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
  137. return(MEMORY_ERROR);
  138. }
  139. for(n=0;n<dz->iarray_cnt;n++)
  140. dz->iparray[n] = NULL;
  141. }
  142. if(dz->larray_cnt > 0) {
  143. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  144. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  145. return(MEMORY_ERROR);
  146. }
  147. for(n=0;n<dz->larray_cnt;n++)
  148. dz->lparray[n] = NULL;
  149. }
  150. if(dz->ptr_cnt > 0) {
  151. if((dz->ptr = (double **)malloc(dz->ptr_cnt * sizeof(double *)))==NULL) {
  152. sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
  153. return(MEMORY_ERROR);
  154. }
  155. for(n=0;n<dz->ptr_cnt;n++)
  156. dz->ptr[n] = NULL;
  157. }
  158. if(dz->fptr_cnt > 0) {
  159. if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
  160. sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
  161. return(MEMORY_ERROR);
  162. }
  163. for(n=0;n<dz->fptr_cnt;n++)
  164. dz->fptr[n] = NULL;
  165. }
  166. return(FINISHED);
  167. }
  168. /****************************** ASSIGN_PROCESS_LOGIC *********************************/
  169. int assign_process_logic(dataptr dz)
  170. {
  171. switch(dz->process) {
  172. case(FORMANTS): setup_process_logic(ANALFILE_ONLY, ANAL_TO_FORMANTS, FORMANTS_OUT, dz); break;
  173. case(FORM): setup_process_logic(ANAL_AND_FORMANTS, BIG_ANALFILE, ANALFILE_OUT, dz); break;
  174. case(VOCODE): setup_process_logic(TWO_ANALFILES, MIN_ANALFILE, ANALFILE_OUT, dz); break;
  175. case(FMNTSEE): setup_process_logic(FORMANTFILE_ONLY, PSEUDOSNDFILE, SNDFILE_OUT, dz); break;
  176. case(FORMSEE): setup_process_logic(ANALFILE_ONLY, PSEUDOSNDFILE, SNDFILE_OUT, dz); break;
  177. default:
  178. sprintf(errstr,"Unknown process: assign_process_logic()\n");
  179. return(PROGRAM_ERROR);
  180. break;
  181. }
  182. if(dz->has_otherfile) {
  183. switch(dz->input_data_type) {
  184. case(ALL_FILES):
  185. case(TWO_SNDFILES):
  186. case(SNDFILE_AND_ENVFILE):
  187. case(SNDFILE_AND_BRKFILE):
  188. case(SNDFILE_AND_UNRANGED_BRKFILE):
  189. case(SNDFILE_AND_DB_BRKFILE):
  190. break;
  191. case(MANY_SNDFILES):
  192. if(dz->process==INFO_TIMELIST)
  193. break;
  194. /* fall thro */
  195. default:
  196. sprintf(errstr,"Most processes accepting files with different properties\n"
  197. "can only take 2 sound infiles.\n");
  198. return(PROGRAM_ERROR);
  199. }
  200. }
  201. return(FINISHED);
  202. }
  203. /***************************** SET_LEGAL_INFILE_STRUCTURE **************************
  204. *
  205. * Allows 2nd infile to have different props to first infile.
  206. */
  207. void set_legal_infile_structure(dataptr dz)
  208. {
  209. switch(dz->process) {
  210. default:
  211. dz->has_otherfile = FALSE;
  212. break;
  213. }
  214. }
  215. /***************************************************************************************/
  216. /****************************** FORMERLY IN internal.c *********************************/
  217. /***************************************************************************************/
  218. /****************************** SET_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
  219. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  220. {
  221. int exit_status = FINISHED;
  222. mode = 0;
  223. switch(process) {
  224. case(FORMANTS): exit_status = set_internalparam_data("i",ap); break;
  225. case(FORM): return(FINISHED);
  226. case(VOCODE): return(FINISHED);
  227. case(FMNTSEE): exit_status = set_internalparam_data("d",ap); break;
  228. case(FORMSEE): exit_status = set_internalparam_data("di",ap); break;
  229. default:
  230. sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n");
  231. return(PROGRAM_ERROR);
  232. }
  233. return(exit_status);
  234. }
  235. /********************************************************************************************/
  236. /********************************** FORMERLY IN specialin.c *********************************/
  237. /********************************************************************************************/
  238. /********************** READ_SPECIAL_DATA ************************/
  239. int read_special_data(char *str,dataptr dz)
  240. {
  241. aplptr ap = dz->application;
  242. switch(ap->special_data) {
  243. default:
  244. sprintf(errstr,"Unknown special_data type: read_special_data()\n");
  245. return(PROGRAM_ERROR);
  246. }
  247. return(FINISHED);
  248. }
  249. /********************************************************************************************/
  250. /********************************** FORMERLY IN preprocess.c ********************************/
  251. /********************************************************************************************/
  252. /****************************** PARAM_PREPROCESS *********************************/
  253. int param_preprocess(dataptr dz)
  254. {
  255. switch(dz->process) {
  256. case(FORMANTS): return formants_preprocess(dz);
  257. case(VOCODE): return initialise_specenv2(dz);
  258. case(FMNTSEE): return setup_internal_arrays_and_params_for_fmntsee(dz);
  259. case(FORMSEE): return setup_internal_params_and_arrays_for_formsee(dz);
  260. case(FORM):
  261. break;
  262. default:
  263. sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
  264. return(PROGRAM_ERROR);
  265. }
  266. return(FINISHED);
  267. }
  268. /************************** FORMANTS_PREPROCESS ******************************/
  269. int formants_preprocess(dataptr dz)
  270. {
  271. int exit_status;
  272. if((exit_status = write_formant_descriptor(&dz->flbufptr[1],dz->flbufptr[2],dz))<0)
  273. return(exit_status);
  274. dz->iparam[FMNT_SAMPS_TO_WRITE] = dz->descriptor_samps;
  275. return(FINISHED);
  276. }
  277. /******************** PRINT_FORMANT_PARAMS_TO_SCREEN **********************/
  278. void print_formant_params_to_screen(dataptr dz)
  279. {
  280. /* CORRECTIONS: June 1999 */
  281. int n;
  282. float *bf = dz->bigfbuf;
  283. char temp[200];
  284. fprintf(stdout,"INFO: Number of formant bands %d\n",dz->infile->specenvcnt);
  285. fprintf(stdout,"INFO: Formant envelope frequency band centres (hz)\n");
  286. sprintf(errstr,"INFO: ");
  287. for(n=0;n<dz->infile->specenvcnt;n++) {
  288. sprintf(temp," frq[%d] = %.1f",n,exp(*bf++));
  289. strcat(errstr,temp);
  290. if((n % 3)==2) {
  291. fprintf(stdout,"%s\n",errstr);
  292. sprintf(errstr,"INFO: ");
  293. } else {
  294. strcat(errstr,"\t");
  295. }
  296. }
  297. if((n % 3) > 0)
  298. fprintf(stdout,"%s\n",errstr);
  299. fprintf(stdout,"INFO: Formant band tops (HZ)\n");
  300. sprintf(errstr,"INFO: ");
  301. for(n=0;n<dz->infile->specenvcnt;n++) {
  302. sprintf(temp," top[%d] = %.1f",n,*bf++);
  303. strcat(errstr,temp);
  304. if((n % 3)==2) {
  305. fprintf(stdout,"%s\n",errstr);
  306. sprintf(errstr,"INFO: ");
  307. } else {
  308. strcat(errstr,"\t");
  309. }
  310. }
  311. if((n % 3) > 0)
  312. fprintf(stdout,"%s\n",errstr);
  313. fflush(stdout);
  314. }
  315. /************ SETUP_INTERNAL_ARRAYS_AND_PARAMS_FOR_FMNTSEE *************/
  316. int setup_internal_arrays_and_params_for_fmntsee(dataptr dz)
  317. {
  318. dz->wlength = dz->insams[0]/dz->wanted; /* sample frames to process */
  319. if((dz->sndbuf = (float *)malloc((size_t)(((dz->infile->specenvcnt + SPACER)*sizeof(float)) * FMNT_BUFMULT)))==NULL) {
  320. sprintf(errstr,"INSUFFICIENT MEMORY for pseudosound buffer.\n");
  321. return(MEMORY_ERROR);
  322. }
  323. return(FINISHED);
  324. }
  325. /***************************** GET_MAX_FORMANTVAL *************************/
  326. //TW UPDATE: get_max_formantval REMOVED , REDUNDANT
  327. /************ SETUP_INTERNAL_PARAMS_AND_ARRAYS_FOR_FORMSEE *************/
  328. int setup_internal_params_and_arrays_for_formsee(dataptr dz)
  329. {
  330. int exit_status;
  331. dz->wlength = dz->insams[0]/dz->wanted; /* sample frames to process */
  332. if((exit_status = get_formant_sample_points(&(dz->iparam[FSEE_FCNT]),dz))<0)
  333. return(exit_status);
  334. dz->param[FSEE_FMAX] = 0.0;
  335. if((dz->sndbuf = (float *)malloc(dz->clength * FMNT_BUFMULT * sizeof(float)))==NULL) {
  336. sprintf(errstr,"INSUFFICIENT MEMORY for formant pseudo-sound array.\n");
  337. return(MEMORY_ERROR);
  338. }
  339. return(FINISHED);
  340. }
  341. /*********************** GET_FORMANT_SAMPLE_POINTS **********************/
  342. int get_formant_sample_points(int *fcnt,dataptr dz)
  343. {
  344. double thisfrq = dz->chwidth, frqhere, triple_band = 0.0;
  345. int n = 0;
  346. switch(dz->vflag[FSEE_DISPLAY]) {
  347. case(PICHWISE_FORMANTS):
  348. while(thisfrq < dz->nyquist) {
  349. n++;
  350. if((frqhere=thisfrq*MSECOND)< dz->nyquist) n++; else break;
  351. if((frqhere=thisfrq*SECOND) < dz->nyquist) n++; else break;
  352. if((frqhere=thisfrq*MTHIRD) < dz->nyquist) n++; else break;
  353. if((frqhere=thisfrq*THIRD) < dz->nyquist) n++; else break;
  354. if((frqhere=thisfrq*FOURTH) < dz->nyquist) n++; else break;
  355. if((frqhere=thisfrq*TRITONE)< dz->nyquist) n++; else break;
  356. if((frqhere=thisfrq*FIFTH) < dz->nyquist) n++; else break;
  357. if((frqhere=thisfrq*MSIXTH) < dz->nyquist) n++; else break;
  358. if((frqhere=thisfrq*SIXTH) < dz->nyquist) n++; else break;
  359. if((frqhere=thisfrq*MSEVENTH)<dz->nyquist) n++; else break;
  360. if((frqhere=thisfrq*SEVENTH)< dz->nyquist) n++; else break;
  361. thisfrq *= 2.0;
  362. }
  363. *fcnt = n;
  364. break;
  365. case(FREQWISE_FORMANTS):
  366. triple_band = dz->chwidth * 3.0;
  367. while(thisfrq < dz->nyquist) {
  368. n++;
  369. thisfrq += triple_band;
  370. }
  371. *fcnt = n;
  372. break;
  373. }
  374. if((dz->windowbuf[0] = (float *)realloc((char *)dz->windowbuf[0],(*fcnt) * sizeof(float)))==NULL) {
  375. sprintf(errstr,"INSUFFICIENT MEMORY for formant sample points buffer.\n");
  376. return(MEMORY_ERROR);
  377. }
  378. n = 0;
  379. thisfrq = dz->chwidth;
  380. switch(dz->vflag[FSEE_DISPLAY]) {
  381. case(PICHWISE_FORMANTS):
  382. for(;;) {
  383. dz->windowbuf[0][n++]=(float)thisfrq; if(n >= *fcnt) break;
  384. dz->windowbuf[0][n++]=(float)(thisfrq * MSECOND); if(n >= *fcnt) break;
  385. dz->windowbuf[0][n++]=(float)(thisfrq * SECOND); if(n >= *fcnt) break;
  386. dz->windowbuf[0][n++]=(float)(thisfrq * MTHIRD); if(n >= *fcnt) break;
  387. dz->windowbuf[0][n++]=(float)(thisfrq * THIRD); if(n >= *fcnt) break;
  388. dz->windowbuf[0][n++]=(float)(thisfrq * FOURTH); if(n >= *fcnt) break;
  389. dz->windowbuf[0][n++]=(float)(thisfrq * TRITONE); if(n >= *fcnt) break;
  390. dz->windowbuf[0][n++]=(float)(thisfrq * FIFTH); if(n >= *fcnt) break;
  391. dz->windowbuf[0][n++]=(float)(thisfrq * MSIXTH); if(n >= *fcnt) break;
  392. dz->windowbuf[0][n++]=(float)(thisfrq * SIXTH); if(n >= *fcnt) break;
  393. dz->windowbuf[0][n++]=(float)(thisfrq * MSEVENTH); if(n >= *fcnt) break;
  394. dz->windowbuf[0][n++]=(float)(thisfrq * SEVENTH); if(n >= *fcnt) break;
  395. thisfrq *= 2.0;
  396. }
  397. break;
  398. case(FREQWISE_FORMANTS):
  399. while(thisfrq < dz->nyquist) {
  400. dz->windowbuf[0][n++] = (float)thisfrq;
  401. thisfrq += triple_band;
  402. }
  403. break;
  404. }
  405. if(*fcnt > dz->clength || *fcnt==0) {
  406. sprintf(errstr,"Invalid formant_cnt: get_formant_sample_points()\n");
  407. return(PROGRAM_ERROR);
  408. }
  409. return(FINISHED);
  410. }
  411. /********************************************************************************************/
  412. /********************************** FORMERLY IN procspec.c **********************************/
  413. /********************************************************************************************/
  414. /**************************** SPEC_PROCESS_FILE ****************************/
  415. int spec_process_file(dataptr dz)
  416. {
  417. dz->total_windows = 0;
  418. display_virtual_time(0L,dz);
  419. switch(dz->process) {
  420. case(FORMANTS): return specformants(dz);
  421. case(FORM): return specform(dz);
  422. case(VOCODE): return outer_twofileinput_loop(dz);
  423. case(FMNTSEE): return specfmntsee(dz);
  424. case(FORMSEE): return outer_formsee_loop(dz);
  425. default:
  426. sprintf(errstr,"Unknown process in procspec()\n");
  427. return(PROGRAM_ERROR);
  428. }
  429. return(FINISHED); /* NOTREACHED */
  430. }
  431. /**************************** INNER_LOOP ****************************/
  432. int inner_loop
  433. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  434. {
  435. int exit_status;
  436. int local_zero_set = FALSE;
  437. int wc;
  438. for(wc=0; wc<windows_in_buf; wc++) {
  439. if(dz->total_windows==0) {
  440. if((exit_status = skip_or_special_operation_on_window_zero(dz))<0)
  441. return(exit_status);
  442. if(exit_status==TRUE) {
  443. dz->flbufptr[0] += dz->wanted;
  444. dz->total_windows++;
  445. dz->time = (float)(dz->time + dz->frametime);
  446. continue;
  447. }
  448. }
  449. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  450. return(exit_status);
  451. switch(dz->process) {
  452. case(FORMSEE): exit_status = specformsee(dz); break;
  453. default:
  454. sprintf(errstr,"unknown process in inner_loop()\n");
  455. return(PROGRAM_ERROR);
  456. }
  457. if(exit_status<0)
  458. return(exit_status);
  459. dz->flbufptr[0] += dz->wanted;
  460. dz->total_windows++;
  461. dz->time = (float)(dz->time + dz->frametime);
  462. }
  463. //TW UPDATE
  464. // if(!dz->zeroset && local_zero_set==TRUE) {
  465. if(!dz->zeroset && (local_zero_set==TRUE)) {
  466. fprintf(stdout,"WARNING: Zero-amp spectral window(s) encountered: orig window(s) substituted.\n");
  467. fflush(stdout);
  468. dz->zeroset = TRUE;
  469. }
  470. return(FINISHED);
  471. }
  472. /***************** SKIP_OR_SPECIAL_OPERATION_ON_WINDOW_ZERO ************/
  473. int skip_or_special_operation_on_window_zero(dataptr dz)
  474. {
  475. int exit_status = FINISHED;
  476. switch(dz->process) {
  477. case(FORMANTS): case(FORMSEE): case(FMNTSEE): case(VOCODE):
  478. switch(dz->process) {
  479. case(FORMSEE):
  480. case(FMNTSEE):
  481. memset((char *)dz->flbufptr[0],0,(size_t)dz->wanted * sizeof(float));
  482. break;
  483. case(FORMANTS):
  484. if((exit_status = zero_formant(dz))<0)
  485. return(exit_status);
  486. if((dz->iparam[FMNT_SAMPS_TO_WRITE] += dz->infile->specenvcnt) >= dz->buflen2) {
  487. if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen2,dz))<0)
  488. return(exit_status);
  489. dz->iparam[FMNT_SAMPS_TO_WRITE] = 0;
  490. dz->flbufptr[1] = dz->flbufptr[2];
  491. } else
  492. dz->flbufptr[1] += dz->infile->specenvcnt;
  493. break;
  494. }
  495. return(TRUE);
  496. }
  497. return(FALSE);
  498. }
  499. /**************************** OUTER_TWOFILEINPUT_LOOP ***************************/
  500. int outer_twofileinput_loop(dataptr dz)
  501. {
  502. int exit_status;
  503. int windows_to_process, windows_in_buf, samps_read, samps_to_write, wc, got;
  504. int file_to_keep = 0, finished = 0, stop_at_end_of_shortest_file = 0;
  505. int stop_at_end_of_process = 0;
  506. dz->time = 0.0f;
  507. switch(dz->process) {
  508. case(VOCODE):
  509. windows_to_process = min(dz->insams[0],dz->insams[1])/dz->wanted;
  510. stop_at_end_of_shortest_file = 1;
  511. break;
  512. default:
  513. sprintf(errstr,"unknown case in outer_twofileinput_loop()\n");
  514. return(PROGRAM_ERROR);
  515. }
  516. while(!finished) {
  517. if((exit_status = read_both_files(&windows_in_buf,&got,dz))<0)
  518. return(exit_status);
  519. samps_to_write = got;
  520. for(wc=0; wc<windows_in_buf; wc++) {
  521. if(dz->total_windows==0) {
  522. if((exit_status = skip_or_special_operation_on_window_zero(dz))<0)
  523. return(exit_status);
  524. if(exit_status==TRUE) {
  525. if((exit_status = advance_one_2fileinput_window(dz))<0)
  526. return(exit_status);
  527. continue;
  528. }
  529. }
  530. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  531. return(exit_status);
  532. switch(dz->process) {
  533. case(VOCODE):
  534. if((exit_status = specvocode(dz))<0)
  535. return(exit_status);
  536. break;
  537. default:
  538. sprintf(errstr,"unknown process in outer_twofileinput_loop()\n");
  539. return(PROGRAM_ERROR);
  540. }
  541. if((exit_status = advance_one_2fileinput_window(dz))<0)
  542. return(exit_status);
  543. if(dz->total_windows >= windows_to_process) {
  544. if((exit_status = keep_excess_samps_from_correct_file(&samps_to_write,file_to_keep,got,wc,dz))<0)
  545. return(exit_status);
  546. finished = 1;
  547. break;
  548. }
  549. }
  550. if(samps_to_write > 0) {
  551. if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0)
  552. return(exit_status);
  553. }
  554. }
  555. if(!stop_at_end_of_process && !stop_at_end_of_shortest_file) {
  556. if((exit_status = read_either_file(&samps_read,file_to_keep,dz))<0)
  557. return(exit_status);
  558. while(samps_read > 0) {
  559. if((exit_status = write_samps(dz->bigfbuf,samps_read,dz))<0)
  560. return(exit_status);
  561. if((exit_status = read_either_file(&samps_read,file_to_keep,dz))<0)
  562. return(exit_status);
  563. }
  564. }
  565. return(FINISHED);
  566. }
  567. /****************************** ZERO_FORMANT ***************************/
  568. int zero_formant(dataptr dz)
  569. {
  570. int n;
  571. for(n=0;n<dz->infile->specenvcnt;n++)
  572. dz->flbufptr[1][n] = 0.0f;
  573. return(FINISHED);
  574. }
  575. /********************************************************************************************/
  576. /********************************** FORMERLY IN pconsistency.c ******************************/
  577. /********************************************************************************************/
  578. /****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
  579. int check_param_validity_and_consistency(dataptr dz)
  580. {
  581. int exit_status, chans, stype;
  582. int srate;
  583. char filename[200];
  584. handle_pitch_zeros(dz);
  585. switch(dz->process) {
  586. case(FORMANTS):
  587. chans = dz->infile->channels;
  588. //TW 2003: specenvcnt is number of pieces of data in a single formant
  589. //TW 2004: it would be more logical for channels to be equal to specenvcnt
  590. //TW However, this breaks some other things ...notably
  591. //TW the gobo, which will only accept Formant,Pitch (and Envelope) files, for recombination
  592. //TW if they share the same number of channels (i.e. 1)
  593. //TW Rewriting the gobo program is one's worst nightmare!!!
  594. dz->infile->channels = 1;
  595. if((exit_status = create_sized_outfile(dz->wordstor[0],dz))<0)
  596. return(exit_status);
  597. dz->infile->channels = chans;
  598. break;
  599. case(FORM):
  600. return check_compatibility_of_params_for_form(dz);
  601. case(FMNTSEE):
  602. chans = dz->infile->channels;
  603. srate = dz->infile->srate;
  604. stype = dz->infile->stype;
  605. dz->infile->channels = 1;
  606. dz->infile->srate = dz->infile->origrate;
  607. dz->infile->stype = SAMP_SHORT;
  608. if((exit_status = create_sized_outfile(dz->wordstor[0],dz))<0)
  609. return(exit_status);
  610. dz->infile->channels = chans;
  611. dz->infile->srate = srate;
  612. dz->infile->stype = stype;
  613. break;
  614. case(FORMSEE):
  615. chans = dz->infile->channels;
  616. srate = dz->infile->srate;
  617. stype = dz->infile->stype;
  618. dz->infile->channels = 1;
  619. dz->infile->srate = dz->infile->origrate;
  620. dz->infile->stype = SAMP_SHORT;
  621. //TW process uses tempfile before normalising output
  622. strcpy(filename,dz->outfilename);
  623. get_other_filename(filename,'1');
  624. if((exit_status = create_sized_outfile(filename,dz))<0)
  625. return(exit_status);
  626. dz->infile->channels = chans;
  627. dz->infile->srate = srate;
  628. dz->infile->stype = stype;
  629. break;
  630. }
  631. return(FINISHED);
  632. }
  633. /************ CHECK_COMPATIBILITY_OF_PARAMS_FOR_FORM *************/
  634. int check_compatibility_of_params_for_form(dataptr dz)
  635. {
  636. if(dz->param[FORM_FTOP] <= dz->param[FORM_FBOT]) {
  637. sprintf(errstr,"Frequency limits incompatible\n");
  638. return(USER_ERROR);
  639. }
  640. return(FINISHED);
  641. }
  642. /********************************************************************************************/
  643. /********************************** FORMERLY IN buffers.c ***********************************/
  644. /********************************************************************************************/
  645. /**************************** ALLOCATE_LARGE_BUFFERS ******************************/
  646. int allocate_large_buffers(dataptr dz)
  647. {
  648. switch(dz->process) {
  649. case(FMNTSEE): case(FORMSEE):
  650. return allocate_single_buffer(dz);
  651. case(VOCODE):
  652. return allocate_double_buffer(dz);
  653. case(FORMANTS): case(FORM):
  654. return allocate_analdata_plus_formantdata_buffer(dz);
  655. default:
  656. sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
  657. return(PROGRAM_ERROR);
  658. }
  659. return(FINISHED);
  660. }
  661. /********************************************************************************************/
  662. /********************************** FORMERLY IN cmdline.c ***********************************/
  663. /********************************************************************************************/
  664. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  665. {
  666. if (!strcmp(prog_identifier_from_cmdline,"get")) dz->process = FORMANTS;
  667. else if(!strcmp(prog_identifier_from_cmdline,"put")) dz->process = FORM;
  668. else if(!strcmp(prog_identifier_from_cmdline,"vocode")) dz->process = VOCODE;
  669. else if(!strcmp(prog_identifier_from_cmdline,"see")) dz->process = FMNTSEE;
  670. else if(!strcmp(prog_identifier_from_cmdline,"getsee")) dz->process = FORMSEE;
  671. else {
  672. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  673. return(USAGE_ONLY);
  674. }
  675. //TW UPDATE
  676. return(FINISHED);
  677. }
  678. /********************************************************************************************/
  679. /********************************** FORMERLY IN usage.c *************************************/
  680. /********************************************************************************************/
  681. /******************************** USAGE1 ********************************/
  682. int usage1(void)
  683. {
  684. sprintf(errstr,
  685. "\nEXTRACTION AND USE OF FORMANTS FROM SPECTRAL FILES\n\n"
  686. "USAGE: formants NAME (mode) infile (infile2) outfile parameters: \n"
  687. "\n"
  688. "where NAME can be any one of\n"
  689. "\n"
  690. "get put vocode see getsee\n\n"
  691. "Type 'formants get' for more info on formants get..ETC.\n");
  692. return(USAGE_ONLY);
  693. }
  694. /******************************** USAGE2 ********************************/
  695. int usage2(char *str)
  696. {
  697. if(!strcmp(str,"get")) {
  698. fprintf(stdout,
  699. "formants get infile outfile -fN|-pN\n\n"
  700. "EXTRACT EVOLVING FORMANT ENVELOPE FROM AN ANALYSIS FILE.\n\n"
  701. "OUTFILE is a formant file, which can be used in other formant applications.\n\n"
  702. "-f extract formant envelope linear frqwise,\n"
  703. " using 1 point for every N equally-spaced frequency-channels.\n"
  704. "-p extract formant envelope linear pitchwise,\n"
  705. " using N equally-spaced pitch-bands per octave.\n");
  706. } else if(!strcmp(str,"put")) {
  707. fprintf(stdout,
  708. "formants put 1 infile fmntfile outfile [-i] [-llof] [-hhif] [-ggain]\n"
  709. "formants put 2 infile fmntfile outfile [-llof] [-hhif] [-ggain]\n\n"
  710. "IMPOSE SPECTRAL ENVELOPE IN A FORMANTFILE ON SPECTRUM IN A PVOC ANALYSIS FILE.\n\n"
  711. "MODES.\n"
  712. "(1) New formant envelope REPLACES sound's own formant envelope.\n"
  713. "(2) New formant envelope IMPOSED ON TOP OF sound's own formant envelope.\n\n"
  714. "INFILE and OUTFILE are PVOC analysis files. FMNTFILE is a formant data file.\n"
  715. "-l LOF = low frq, below which spectrum is set to zero.\n"
  716. "-h HIF = high frq, above which spectrum is set to zero.\n"
  717. "-g GAIN = adjustment to spectrum loudness (normally < 1.0).\n"
  718. "-i quicksearch for formants (less accurate).\n");
  719. } else if(!strcmp(str,"vocode")) {
  720. fprintf(stdout,
  721. "formants vocode infile infile2 outfile -fN|-pN [-llof] [-hhif] [-ggain]\n\n"
  722. "IMPOSE SPECTRAL ENVELOPE OF 2nd SOUND, ON 1st SOUND.\n\n"
  723. "-f extract formant envelope linear frqwise,\n"
  724. " using 1 point for every N equally-spaced frequency-channels.\n"
  725. "-p extract formant envelope linear pitchwise,\n"
  726. " using N equally-spaced pitch-bands per octave.\n"
  727. "-l LOF = low frq, below which data is filtered out.\n"
  728. "-h HIF = high frq, above which data is filtered out.\n"
  729. "-g GAIN adjustment to signal (normally < 1.0).\n");
  730. } else if(!strcmp(str,"see")) {
  731. fprintf(stdout,
  732. "formants see infile outsndfile [-v]\n\n"
  733. "CONVERT FORMANT DATA IN A BINARY FORMANTDATA FILE TO 'SNDFILE' FOR VIEWING.\n\n"
  734. "-v display data about formant-band parameters.\n\n"
  735. "The resulting logarithmically scaled display indicates formant shapes,\n"
  736. "but NOT the absolute amplitude values.\n");
  737. } else if(!strcmp(str,"getsee")) {
  738. fprintf(stdout,
  739. "formants getsee infile outsndfile -fN|-pN [-s]\n\n"
  740. "EXTRACT FORMANTS FROM ANALFILE AND WRITE AS 'SNDFILE' FOR VIEWING.\n\n"
  741. "-f extract formant envelope linear frqwise,\n"
  742. " using 1 point for every N equally-spaced frequency-channels.\n"
  743. "-p extract formant envelope linear pitchwise,\n"
  744. " using N equally-spaced pitch-bands per octave.\n"
  745. "-s semitone bands for display (Default: equal hz bands).\n\n"
  746. "The resulting logarithmically scaled display indicates formant shapes,\n"
  747. "but NOT the absolute amplitude values.\n"
  748. "\n"
  749. //TW temporary cmdline restriction
  750. "(Do not use filenames which end in '1').\n");
  751. } else
  752. fprintf(stdout,"Unknown option '%s'\n",str);
  753. return(USAGE_ONLY);
  754. }
  755. /******************************** USAGE3 ********************************/
  756. int usage3(char *str1,char *str2)
  757. {
  758. sprintf(errstr,"Insufficient parameters on command line.\n");
  759. return(USAGE_ONLY);
  760. }