formav.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  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. // (2) Do need an entry in standalone ....
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <structures.h>
  25. #include <filetype.h>
  26. #include <cdpmain.h>
  27. #include <logic.h>
  28. #include <sfsys.h>
  29. char errstr[2400];
  30. static int local_print_messages_and_close_sndfiles(int exit_status,int is_launched,int ofd,int *ifd,int infilecnt);
  31. static int local_read_samps(float *bbuf,int wanted,int *total_samps_read, int *ssampsread,int n,int *ifd, int totalsize);
  32. static int reset_file_to_start_and_pointers_to_after_descriptor_blocks
  33. (int *ifd,int *windows_in_buf,int n,int wanted,int specenvcnt,float *bigfbuf,float **flbufptr,
  34. int *total_samps_read,int totalsize);
  35. static int check_the_formant_data(int *windows_in_buf,float *specenvpch,float *specenvtop,float *bigfbuf,float **flbufptr,char **argv,
  36. infileptr ifp,int specenvcnt,int wanted,int *total_samps_read,int totalsize,int n,int *ifd);
  37. static int initialise_the_formant_data(int *windows_in_buf,float *specenvpch,float *specenvtop,float *bigfbuf,float **flbufptr,
  38. infileptr ifp,int specenvcnt,int wanted,int *total_samps_read,int totalsize,int n,int *ifd);
  39. static void display_sloom_time(int samps_sent,int totalsize);
  40. static int local_readhead(infileptr inputfile,int ifd,char *filename,int getmax,int needmaxinfo);
  41. static void local_splice_multiline_string(char *str,char *prefix);
  42. static int flteq(double f1,double f2);
  43. static int formant_headwrite(int ofd,infileptr ifp);
  44. #define FAILED (-1)
  45. #define SUCCEEDED (0)
  46. #define PBAR_LENGTH (256)
  47. #define CONTINUE (1)
  48. #define FINISHED (0)
  49. #define GOAL_FAILED (-1) /* program succeeds, but users goal not achieved: e.g. find pitch */
  50. #define USER_ERROR (-2) /* program fails because wrong data, no data etc given by user */
  51. #define DATA_ERROR (-3) /* Data is unsuitable, incorrect or missing */
  52. #define MEMORY_ERROR (-4) /* program fails because ran out of, or mismanaged, memory */
  53. #define SYSTEM_ERROR (-5) /* failure to write to or truncate outfile: usually means H/D is full */
  54. #define PROGRAM_ERROR (-6) /* program fails because the programming is naff */
  55. #define USAGE_ONLY (-7) /* program interrogated for usage_message only */
  56. #define TK_USAGE (-8) /* program interrogated by TK for usage_message only */
  57. #define BAD_INFILECNT (-9) /* Bad infilecnt sent from TK at program testing stage */
  58. #ifndef FALSE
  59. #define FALSE (0)
  60. #endif
  61. #ifndef TRUE
  62. #define TRUE (1)
  63. #endif
  64. #define DESCRIPTOR_DATA_BLOKS (2)
  65. #define ENDOFSTR ('\0')
  66. #define FLTERR (0.000002)
  67. /**************************************** MAIN *********************************************/
  68. // cmdline formav formfil1 formfil2 [formfil3 ....] outformfil dur
  69. int main(int argc,char *argv[])
  70. {
  71. int exit_status, n, m, k, infilecnt;
  72. int is_launched = FALSE;
  73. int *ifd = NULL, ofd = -1;
  74. int specenvcnt;
  75. int wanted, windows_in_buf,outfltcnt,outwindowcnt;
  76. infileptr ifp,ifp2;
  77. float *bigfbuf, *bigbufend, *flbufptr, *oflbufptr, *specenvpch, *specenvtop;
  78. int total_windows = 0, ssampsread, min_inwindowsize, totalsize, size, total_samps_read;
  79. double dur;
  80. if(sflinit("cdp")){
  81. sfperror("cdp: initialisation\n");
  82. return(FAILED);
  83. }
  84. if(argc < 5) {
  85. fprintf(stdout,"ERROR: Insufficient arguments on commandline.\n");
  86. fflush(stdout);
  87. return(FAILED);
  88. }
  89. if(sscanf(argv[argc-1],"%lf",&dur)!=1) {
  90. fprintf(stdout,"ERROR: Cannot read output duration from command line.\n");
  91. fflush(stdout);
  92. return(FAILED);
  93. }
  94. if (dur < 0.2) {
  95. fprintf(stdout,"ERROR: Output duration (%lf) too short (min 0.2 secs).\n",dur);
  96. fflush(stdout);
  97. return(FAILED);
  98. }
  99. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  100. fprintf(stdout,"ERROR: INSUFFICIENT MEMORY to store data on infiles (1)\n");
  101. fflush(stdout);
  102. return(FAILED);
  103. }
  104. if((ifp2 = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  105. fprintf(stdout,"ERROR: INSUFFICIENT MEMORY to store data on infiles (2)\n");
  106. fflush(stdout);
  107. return(FAILED);
  108. }
  109. if((ifd = (int *)malloc((argc-3) * sizeof(int))) == NULL) {
  110. fprintf(stdout,"ERROR: Insufficient memory.\n");
  111. fflush(stdout);
  112. return(FAILED);
  113. }
  114. for(n=1;n<argc-2;n++) {
  115. m = n-1;
  116. if((ifd[m] = sndopenEx(argv[n],0,CDP_OPEN_RDONLY)) < 0) {
  117. sprintf(errstr,"FAILED TO OPEN FILE %s\n",argv[n]);
  118. exit_status = DATA_ERROR;
  119. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,m);
  120. return(FAILED);
  121. }
  122. }
  123. infilecnt = m+1;
  124. for(n=0;n<infilecnt;n++) {
  125. if((exit_status = local_readhead(ifp,ifd[n],argv[n+1],0,0))<0) {
  126. exit_status = SYSTEM_ERROR;
  127. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  128. return(FAILED);
  129. }
  130. if(n==0) {
  131. if(ifp->filetype != FORMANTFILE) {
  132. sprintf(errstr,"First input file is not a formant file.\n");
  133. exit_status = DATA_ERROR;
  134. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  135. return(FAILED);
  136. }
  137. ifp2->filetype = ifp->filetype;
  138. ifp2->srate = ifp->srate;
  139. ifp2->stype = ifp->stype;
  140. ifp2->origstype = ifp->origstype;
  141. ifp2->origrate = ifp->origrate;
  142. ifp2->channels = ifp->channels;
  143. ifp2->origchans = ifp->origchans;
  144. ifp2->specenvcnt = ifp->specenvcnt;
  145. ifp2->Mlen = ifp->Mlen;
  146. ifp2->Dfac = ifp->Dfac;
  147. ifp2->arate = ifp->arate;
  148. ifp2->descriptor_samps = ifp->descriptor_samps;
  149. } else {
  150. if(ifp2->filetype != ifp->filetype
  151. || ifp2->srate != ifp->srate
  152. || ifp2->stype != ifp->stype
  153. || ifp2->origstype != ifp->origstype
  154. || ifp2->origrate != ifp->origrate
  155. || ifp2->channels != ifp->channels
  156. || ifp2->origchans != ifp->origchans
  157. || ifp2->specenvcnt != ifp->specenvcnt
  158. || ifp2->Mlen != ifp->Mlen
  159. || ifp2->Dfac != ifp->Dfac
  160. || ifp2->arate != ifp->arate
  161. || ifp2->descriptor_samps != ifp->descriptor_samps) {
  162. sprintf(errstr,"Input files have incompatible properties.\n");
  163. exit_status = DATA_ERROR;
  164. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  165. return(FAILED);
  166. }
  167. }
  168. }
  169. wanted = ifp->specenvcnt * 8;
  170. specenvcnt = ifp->specenvcnt;
  171. min_inwindowsize = 10000000;
  172. totalsize = 0;
  173. for(n=0;n<infilecnt;n++) {
  174. size = sndsizeEx(ifd[n]);
  175. if(n==0)
  176. min_inwindowsize = size;
  177. else if(size < min_inwindowsize)
  178. min_inwindowsize = size;
  179. totalsize += size;
  180. }
  181. if(min_inwindowsize - (specenvcnt * 2) <= 0) {
  182. sprintf(errstr,"No significant data in at least one of input files\n");
  183. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  184. return(FAILED);
  185. }
  186. outfltcnt = ((int)round(dur / ifp->frametime) * specenvcnt) + 2;
  187. if((ofd = sndcreat_formatted(argv[argc-1],outfltcnt,SAMP_FLOAT,
  188. ifp->channels,ifp->srate,CDP_CREATE_NORMAL)) < 0) {
  189. sprintf(errstr,"Cannot open output file %s\n", argv[argc-1]);
  190. exit_status = SYSTEM_ERROR;
  191. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  192. return(FAILED);
  193. }
  194. outwindowcnt = (outfltcnt/specenvcnt) - 2;
  195. is_launched = 1;
  196. if((specenvpch = (float *)malloc(specenvcnt * sizeof(float))) == NULL) {
  197. sprintf(errstr,"Insufficient memory to store formant descriptor data 1.\n");
  198. exit_status = MEMORY_ERROR;
  199. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  200. return(FAILED);
  201. }
  202. if((specenvtop = (float *)malloc(specenvcnt * sizeof(float))) == NULL) {
  203. sprintf(errstr,"Insufficient memory to store formant descriptor data 2.\n");
  204. exit_status = MEMORY_ERROR;
  205. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  206. return(FAILED);
  207. }
  208. if((oflbufptr = (float *)malloc(specenvcnt * sizeof(float))) == NULL) {
  209. sprintf(errstr,"Insufficient memory to store output formant data.\n");
  210. exit_status = MEMORY_ERROR;
  211. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  212. return(FAILED);
  213. }
  214. memset((char *)oflbufptr,0,specenvcnt * sizeof(float));
  215. if((bigfbuf = (float *)malloc(wanted * sizeof(float))) == NULL) {
  216. sprintf(errstr,"Insufficient memory to store input formant data.\n");
  217. exit_status = MEMORY_ERROR;
  218. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  219. return(FAILED);
  220. }
  221. bigbufend = bigfbuf + wanted;
  222. memset((char *)bigfbuf,0,wanted * sizeof(float));
  223. total_samps_read = 0;
  224. for(n=0;n<infilecnt;n++) {
  225. if(n==0) {
  226. if((exit_status = initialise_the_formant_data(&windows_in_buf,specenvpch,specenvtop,bigfbuf,
  227. &flbufptr,ifp,specenvcnt,wanted,&total_samps_read,totalsize,n,ifd))<0) {
  228. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  229. return(FAILED);
  230. }
  231. } else {
  232. if((exit_status = check_the_formant_data(&windows_in_buf,specenvpch,specenvtop,bigfbuf,
  233. &flbufptr,argv,ifp,specenvcnt,wanted,&total_samps_read,totalsize,n,ifd))<0) {
  234. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  235. return(FAILED);
  236. }
  237. }
  238. m = 0;
  239. while(m < windows_in_buf) {
  240. for(k = 0;k<specenvcnt;k++)
  241. oflbufptr[k] += flbufptr[k];
  242. flbufptr += specenvcnt;
  243. total_windows++;
  244. m++;
  245. }
  246. for (;;) {
  247. if((exit_status = local_read_samps(bigfbuf,wanted,&total_samps_read,&ssampsread,n,ifd,totalsize)) < 0)
  248. return(exit_status);
  249. if(ssampsread <= 0)
  250. break;
  251. windows_in_buf = ssampsread/specenvcnt;
  252. flbufptr = bigfbuf;
  253. m = 0;
  254. while(m < windows_in_buf) {
  255. for(k = 0;k<specenvcnt;k++)
  256. oflbufptr[k] += flbufptr[k];
  257. flbufptr += specenvcnt;
  258. total_windows++;
  259. m++;
  260. }
  261. }
  262. if(sndcloseEx(ifd[n]) < 0) {
  263. fprintf(stdout,"WARNING: Failed to close file %s\n",argv[n+1]);
  264. fflush(stdout);
  265. }
  266. ifd[n] = -1;
  267. }
  268. ifd = NULL;
  269. for(k = 0;k<specenvcnt;k++)
  270. oflbufptr[k] = (float) (oflbufptr[k]/(double)total_windows);
  271. if(fputfbufEx(specenvpch,specenvcnt,ofd)<=0) {
  272. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  273. return(SYSTEM_ERROR);
  274. }
  275. if(fputfbufEx(specenvtop,specenvcnt,ofd)<=0) {
  276. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  277. return(SYSTEM_ERROR);
  278. }
  279. for(n=0;n<outwindowcnt;n++) {
  280. if(fputfbufEx(oflbufptr,specenvcnt,ofd)<=0) {
  281. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  282. return(SYSTEM_ERROR);
  283. }
  284. }
  285. if(sndcloseEx(ofd) < 0) {
  286. sprintf(errstr,"ERROR: Failed to close output file %s\n",argv[argc-1]);
  287. exit_status = SYSTEM_ERROR;
  288. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  289. return(FAILED);
  290. }
  291. if((exit_status = formant_headwrite(ofd,ifp))<0) {
  292. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  293. return(FAILED);
  294. }
  295. local_print_messages_and_close_sndfiles(exit_status,is_launched,ofd,ifd,infilecnt);
  296. return(SUCCEEDED);
  297. }
  298. /***************************** INITIALISE_THE_FORMANT_DATA *************************/
  299. int initialise_the_formant_data(int *windows_in_buf,float *specenvpch,float *specenvtop,float *bigfbuf,float **flbufptr,
  300. infileptr ifp,int specenvcnt,int wanted,int *total_samps_read,int totalsize,int n,int *ifd)
  301. {
  302. int exit_status;
  303. int ssampsread;
  304. int fsamps_to_read = ifp->descriptor_samps/DESCRIPTOR_DATA_BLOKS;
  305. if((exit_status = local_read_samps(bigfbuf,wanted,total_samps_read,&ssampsread,n,ifd,totalsize)) < 0)
  306. return(exit_status);
  307. if(ssampsread < ifp->descriptor_samps) {
  308. sprintf(errstr,"No significant data in formantfile.\n");
  309. return(DATA_ERROR);
  310. }
  311. *flbufptr = bigfbuf;
  312. memcpy((char *)specenvpch,(char *)(*flbufptr),(size_t)(fsamps_to_read * sizeof(float)));
  313. *flbufptr += specenvcnt;
  314. memcpy((char *)specenvtop,(char *)(*flbufptr),(size_t)(fsamps_to_read * sizeof(float)));
  315. *flbufptr = bigfbuf + (DESCRIPTOR_DATA_BLOKS * specenvcnt);
  316. *windows_in_buf = ssampsread/specenvcnt;
  317. if((*windows_in_buf -= DESCRIPTOR_DATA_BLOKS) <= 0) {
  318. sprintf(errstr,"Buffers too SMALL for formant data.\n");
  319. return(PROGRAM_ERROR);
  320. }
  321. return reset_file_to_start_and_pointers_to_after_descriptor_blocks
  322. (ifd,windows_in_buf,n,wanted,specenvcnt,bigfbuf,flbufptr,total_samps_read,totalsize);
  323. }
  324. /***************************** CHECK_THE_FORMANT_DATA *************************/
  325. int check_the_formant_data(int *windows_in_buf,float *specenvpch,float *specenvtop,float *bigfbuf,float **flbufptr,char **argv,
  326. infileptr ifp,int specenvcnt,int wanted,int *total_samps_read,int totalsize,int n,int *ifd)
  327. {
  328. int exit_status, k;
  329. int ssampsread;
  330. int fsamps_to_read = ifp->descriptor_samps/DESCRIPTOR_DATA_BLOKS;
  331. if((exit_status = local_read_samps(bigfbuf,wanted,total_samps_read,&ssampsread,n,ifd,totalsize)) < 0)
  332. return(exit_status);
  333. if(ssampsread < ifp->descriptor_samps) {
  334. sprintf(errstr,"No significant data in formantfile.\n");
  335. return(DATA_ERROR);
  336. }
  337. *flbufptr = bigfbuf;
  338. for(k=0;k<specenvcnt;k++) {
  339. if(!flteq(specenvpch[k],(*flbufptr)[k])) {
  340. sprintf(errstr,"Formant file %s has a different format to the others\n",argv[n+1]);
  341. return(DATA_ERROR);
  342. }
  343. }
  344. *flbufptr += specenvcnt;
  345. for(k=0;k<specenvcnt;k++) {
  346. if(!flteq(specenvtop[k],(*flbufptr)[k])) {
  347. sprintf(errstr,"Formant file %s has a different format to the others\n",argv[n+1]);
  348. return(DATA_ERROR);
  349. }
  350. }
  351. *flbufptr = bigfbuf + (DESCRIPTOR_DATA_BLOKS * specenvcnt);
  352. *windows_in_buf = ssampsread/specenvcnt;
  353. if((*windows_in_buf -= DESCRIPTOR_DATA_BLOKS) <= 0) {
  354. sprintf(errstr,"Buffers too SMALL for formant data.\n");
  355. return(PROGRAM_ERROR);
  356. }
  357. return reset_file_to_start_and_pointers_to_after_descriptor_blocks
  358. (ifd,windows_in_buf,n,wanted,specenvcnt,bigfbuf,flbufptr,total_samps_read,totalsize);
  359. }
  360. /*********************** RESET_FILE_TO_START_AND_POINTERS_TO_AFTER_DESCRIPTOR_BLOCKS **********************/
  361. int reset_file_to_start_and_pointers_to_after_descriptor_blocks
  362. (int *ifd,int *windows_in_buf,int n,int wanted,int specenvcnt,float *bigfbuf,float **flbufptr,int *total_samps_read,int totalsize)
  363. {
  364. int exit_status;
  365. int ssampsread;
  366. if(sndseekEx(ifd[n],0L,0)<0) { /* RESET FILE POINTER TO START OF DATA */
  367. sprintf(errstr,"seek failed in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  368. return(SYSTEM_ERROR);
  369. }
  370. if((exit_status = local_read_samps(bigfbuf,wanted,total_samps_read,&ssampsread,n,ifd,totalsize)) < 0) {
  371. sprintf(errstr,"Read problem after rewind in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  372. return(SYSTEM_ERROR);
  373. }
  374. *total_samps_read -= ssampsread; /* allow for the backtracking invloved in reading descriptor blocks */
  375. *windows_in_buf = ssampsread/specenvcnt;
  376. if((*windows_in_buf -= DESCRIPTOR_DATA_BLOKS) < 0) {
  377. sprintf(errstr,"Buffers too SMALL in reset_file_to_start_and_pointers_to_after_descriptor_blocks()\n");
  378. return(PROGRAM_ERROR);
  379. }
  380. (*flbufptr) = bigfbuf + (DESCRIPTOR_DATA_BLOKS * specenvcnt);
  381. return(FINISHED);
  382. }
  383. /*********************** LOCAL_READ_SAMPS **********************/
  384. int local_read_samps(float *bbuf,int wanted,int *total_samps_read, int *ssampsread,int n,int *ifd,int totalsize)
  385. {
  386. if((*ssampsread = fgetfbufEx(bbuf, wanted,ifd[n],0)) < 0) {
  387. sprintf(errstr,"Can't read samples from input soundfile.\n");
  388. return(SYSTEM_ERROR);
  389. }
  390. *total_samps_read += *ssampsread;
  391. display_sloom_time(*total_samps_read,totalsize);
  392. return(FINISHED);
  393. }
  394. /*********************** DISPLAY_SLOOM_TIME **********************/
  395. void display_sloom_time(int samps_sent,int totalsize) {
  396. double float_time = min(1.0,(double)samps_sent/(double)totalsize);
  397. int display_time = round(float_time * PBAR_LENGTH);
  398. fprintf(stdout,"TIME: %d\n",display_time);
  399. fflush(stdout);
  400. }
  401. /****************************** LOCAL_PRINT_MESSAGES_AND_CLOSE_SNDFILES ******************************/
  402. int local_print_messages_and_close_sndfiles(int exit_status,int is_launched,int ofd,int *ifd,int infilecnt)
  403. {
  404. int n; /* OUTPUT ERROR MESSAGES */
  405. switch(exit_status) {
  406. case(FINISHED): break;
  407. case(PROGRAM_ERROR):
  408. fprintf(stdout,"ERROR: INTERNAL ERROR: (Bug?)\n");
  409. local_splice_multiline_string(errstr,"ERROR:");
  410. break;
  411. case(SYSTEM_ERROR):
  412. fprintf(stdout,"ERROR: SYSTEM ERROR\n");
  413. local_splice_multiline_string(errstr,"ERROR:");
  414. break;
  415. case(MEMORY_ERROR):
  416. fprintf(stdout,"ERROR: MEMORY ERROR\n");
  417. local_splice_multiline_string(errstr,"ERROR:");
  418. break;
  419. case(USER_ERROR):
  420. fprintf(stdout,"ERROR: DATA OR RANGE ERROR\n");
  421. local_splice_multiline_string(errstr,"ERROR:");
  422. break;
  423. case(DATA_ERROR):
  424. fprintf(stdout,"ERROR: INVALID DATA\n");
  425. local_splice_multiline_string(errstr,"ERROR:");
  426. break;
  427. case(GOAL_FAILED):
  428. fprintf(stdout,"ERROR: CANNOT ACHIEVE TASK:\n");
  429. local_splice_multiline_string(errstr,"ERROR:");
  430. break;
  431. case(USAGE_ONLY):
  432. fprintf(stdout,"ERROR: PROGRAM ERROR: usage messages should not be called.\n");
  433. fflush(stdout);
  434. break;
  435. case(TK_USAGE):
  436. exit_status = FINISHED;
  437. break;
  438. default:
  439. fprintf(stdout,"ERROR: INTERNAL ERROR: (Bug?)\n");
  440. fprintf(stdout,"ERROR: Unknown case in print_messages_and_close_sndfiles)\n");
  441. exit_status = PROGRAM_ERROR;
  442. break;
  443. }
  444. if(ofd >= 0 && (exit_status!=FINISHED || !is_launched) && sndunlink(ofd) < 0)
  445. fprintf(stdout, "ERROR: Can't set output soundfile for deletion.\n");
  446. // if((ofd >= 0) && dz->needpeaks){
  447. // if(sndputpeaks(dz->ofd,dz->outchans,dz->outpeaks)) {
  448. // fprintf(stdout,"WARNING: failed to write PEAK data\n");
  449. // fflush(stdout);
  450. // }
  451. // }
  452. if(ofd >= 0 && sndcloseEx(ofd) < 0) {
  453. fprintf(stdout, "WARNING: Can't close output sf-soundfile : %s\n",sferrstr());
  454. fflush(stdout);
  455. }
  456. if(ifd != NULL && infilecnt >= 0) {
  457. for(n=0;n<infilecnt;n++) {
  458. /* ALL OTHER CASES */
  459. if(ifd[n] >= 0 && sndcloseEx(ifd[n]) < 0)
  460. fprintf(stdout, "WARNING: Can't close input sf-soundfile %d.\n",n+1);
  461. }
  462. }
  463. sffinish();
  464. fprintf(stdout,"END:");
  465. fflush(stdout);
  466. if(exit_status != FINISHED) {
  467. return(FAILED);
  468. }
  469. return(SUCCEEDED);
  470. }
  471. int local_readhead(infileptr inputfile,int ifd,char *filename,int getmax,int needmaxinfo)
  472. {
  473. SFPROPS props = {0};
  474. int isenv = 0;
  475. int os;
  476. if(!snd_headread(ifd,&props)) {
  477. fprintf(stdout,"INFO: Failure to read properties, in %s\n",filename);
  478. fflush(stdout);
  479. return(DATA_ERROR);
  480. }
  481. inputfile->srate = props.srate;
  482. inputfile->channels = props.chans;
  483. switch(props.samptype) {
  484. case(SHORT16): inputfile->stype = SAMP_SHORT; break;
  485. case(FLOAT32): inputfile->stype = SAMP_FLOAT; break;
  486. case(SHORT8): inputfile->stype = SAMP_BYTE; break;
  487. default: /* remaining symbols have same int value */ break;
  488. }
  489. //TW TEMPORARY SUBSTITUTION
  490. inputfile->filetype = SNDFILE;
  491. if(sndgetprop(ifd,"is an envelope",(char *) &isenv,sizeof(int)) >= 0)
  492. inputfile->filetype = ENVFILE;
  493. else if(sndgetprop(ifd,"is a formant file",(char *) &isenv,sizeof(int)) >= 0)
  494. inputfile->filetype = FORMANTFILE;
  495. else if(sndgetprop(ifd,"is a pitch file",(char *) &isenv,sizeof(int)) >= 0)
  496. inputfile->filetype = PITCHFILE;
  497. else if(sndgetprop(ifd,"is a transpos file",(char *) &isenv,sizeof(int)) >= 0)
  498. inputfile->filetype = TRANSPOSFILE;
  499. else if(sndgetprop(ifd,"original sampsize",(char *) &os,sizeof(int)) > 0)
  500. inputfile->filetype = ANALFILE;
  501. inputfile->specenvcnt = props.specenvcnt;
  502. if(inputfile->channels != 1) {
  503. sprintf(errstr,"Channel count not equal to 1 in %s: readhead()\n"
  504. "Implies failure to write correct header in another program.\n",
  505. filename);
  506. return(PROGRAM_ERROR);
  507. }
  508. if(sndgetprop(ifd,"orig channels",(char *)&(inputfile->origchans),sizeof(int)) < 0) {
  509. fprintf(stdout,"Cannot read original channels count: %s\n",filename);
  510. fflush(stdout);
  511. return(DATA_ERROR);
  512. }
  513. if(sndgetprop(ifd,"original sampsize",(char *)&(inputfile->origstype),sizeof(int)) < 0) {
  514. fprintf(stdout,"Cannot read original sample type: %s\n",filename);
  515. fflush(stdout);
  516. return(DATA_ERROR);
  517. }
  518. if(sndgetprop(ifd,"original sample rate",(char *)&(inputfile->origrate),sizeof(int)) < 0) {
  519. fprintf(stdout,"Cannot read original sample rate: %s\n",filename);
  520. fflush(stdout);
  521. return(DATA_ERROR);
  522. }
  523. if(sndgetprop(ifd,"arate",(char *)&(inputfile->arate),sizeof(float)) < 0) {
  524. fprintf(stdout,"Cannot read analysis rate: %s\n",filename);
  525. fflush(stdout);
  526. return(DATA_ERROR);
  527. }
  528. if(sndgetprop(ifd,"analwinlen",(char *)&(inputfile->Mlen),sizeof(int)) < 0) {
  529. fprintf(stdout,"Cannot read analysis window length: %s\n",filename);
  530. fflush(stdout);
  531. return(DATA_ERROR);
  532. }
  533. if(sndgetprop(ifd,"decfactor",(char *)&(inputfile->Dfac),sizeof(int)) < 0) {
  534. fprintf(stdout,"Cannot read original decimation factor: %s\n",filename);
  535. fflush(stdout);
  536. return(DATA_ERROR);
  537. }
  538. return(FINISHED);
  539. }
  540. /****************************** LOCAL_SPLICE_MULTILINE_STRING ******************************/
  541. void local_splice_multiline_string(char *str,char *prefix)
  542. {
  543. char *p, *q, c;
  544. p = str;
  545. q = str;
  546. while(*q != ENDOFSTR) {
  547. while(*p != '\n' && *p != ENDOFSTR)
  548. p++;
  549. c = *p;
  550. *p = ENDOFSTR;
  551. fprintf(stdout,"%s %s\n",prefix,q);
  552. *p = c;
  553. if(*p == '\n')
  554. p++;
  555. while(*p == '\n') {
  556. fprintf(stdout,"%s \n",prefix);
  557. p++;
  558. }
  559. q = p;
  560. p++;
  561. }
  562. }
  563. /**************************** FLTEQ *******************************/
  564. int flteq(double f1,double f2)
  565. {
  566. double upperbnd, lowerbnd;
  567. upperbnd = f2 + FLTERR;
  568. lowerbnd = f2 - FLTERR;
  569. if((f1>upperbnd) || (f1<lowerbnd))
  570. return(FALSE);
  571. return(TRUE);
  572. }
  573. /***************************** FORMANT_HEADWRITE *******************************/
  574. int formant_headwrite(int ofd,infileptr ifp)
  575. {
  576. int property_marker = 1;
  577. if(sndputprop(ofd,"specenvcnt", (char *)&(ifp->specenvcnt), sizeof(int)) < 0){
  578. sprintf(errstr,"Failure to write specenvcnt: headwrite()\n");
  579. return(PROGRAM_ERROR);
  580. }
  581. if(sndputprop(ofd,"orig channels", (char *)&(ifp->origchans), sizeof(int)) < 0){
  582. sprintf(errstr,"Failure to write original channel data: headwrite()\n");
  583. return(PROGRAM_ERROR);
  584. }
  585. if(sndputprop(ofd,"original sampsize", (char *)&(ifp->origstype), sizeof(int)) < 0){
  586. sprintf(errstr,"Failure to write original sample size. headwrite()\n");
  587. return(PROGRAM_ERROR);
  588. }
  589. if(sndputprop(ofd,"original sample rate", (char *)&(ifp->origrate), sizeof(int)) < 0){
  590. sprintf(errstr,"Failure to write original sample rate. headwrite()\n");
  591. return(PROGRAM_ERROR);
  592. }
  593. if(sndputprop(ofd,"arate",(char *)&(ifp->arate),sizeof(float)) < 0){
  594. sprintf(errstr,"Failed to write analysis sample rate. headwrite()\n");
  595. return(PROGRAM_ERROR);
  596. }
  597. if(sndputprop(ofd,"analwinlen",(char *)&(ifp->Mlen),sizeof(int)) < 0){
  598. sprintf(errstr,"Failure to write analysis window length. headwrite()\n");
  599. return(PROGRAM_ERROR);
  600. }
  601. if(sndputprop(ofd,"decfactor",(char *)&(ifp->Dfac),sizeof(int)) < 0){
  602. sprintf(errstr,"Failure to write decimation factor. headwrite()\n");
  603. return(PROGRAM_ERROR);
  604. }
  605. if(sndputprop(ofd,"is a formant file", (char *)&property_marker, sizeof(int)) < 0){
  606. sprintf(errstr,"Failure to write formant property: headwrite()\n");
  607. return(PROGRAM_ERROR);
  608. }
  609. return(FINISHED);
  610. }