morph.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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 <pnames.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <morph.h>
  30. #include <cdpmain.h>
  31. #include <formants.h>
  32. #include <speccon.h>
  33. #include <sfsys.h>
  34. #include <string.h>
  35. #include <morph.h>
  36. //RWD set different name here : IN now used in Windows (MSVC)
  37. #define BEFORE (0)
  38. #define _IN_ (1)
  39. #define AFTER (2)
  40. #define NO_NORMALISE (0)
  41. #define NORMALISE_FILE1 (1)
  42. #define NORMALISE_FILE2 (2)
  43. //#ifdef unix
  44. #define round(x) lround((x))
  45. //#endif
  46. static int read_two_individual_input_windows(dataptr dz);
  47. static int establish_glide_ratios(dataptr dz);
  48. static int establish_temporary_file_for_offsetting(dataptr dz);
  49. static int determine_process_startwindow(dataptr dz);
  50. static int determine_process_endwindow(dataptr dz);
  51. static int read_bothfiles_for_bridge(int *windows_in_buf,dataptr dz);
  52. static int do_specbridge(dataptr dz);
  53. static int create_temporary_file_frontpadded_with_silence(dataptr dz);
  54. static int do_interpolation(int where,dataptr dz);
  55. static int set_tempfile_properties(dataptr dz);
  56. static int set_normalisation_type(int *normalisation_type,int where,double *normaliser, dataptr dz);
  57. static int read_specific_file_to_specific_buf(int fileno,int *windows_to_buf,
  58. float **fbufptr,float *floatbuf,dataptr dz);
  59. static int do_specmorph(double alen, double flen, dataptr dz);
  60. static void remove_temp_file(dataptr dz);
  61. static int warped_cosin(double *interpratio,double exponent,dataptr dz);
  62. static int time_warp(double *interpratio,double exponent);
  63. static int cosin_lookup(double *interpratio,dataptr dz);
  64. /*********************** SPECGLIDE ***************************/
  65. int specglide(dataptr dz)
  66. {
  67. int exit_status;
  68. int wc;
  69. int cc, vc;
  70. double interp_fact;
  71. if((exit_status = read_two_individual_input_windows(dz))<0)
  72. return(exit_status);
  73. if((exit_status = establish_glide_ratios(dz))<0)
  74. return(exit_status);
  75. dz->flbufptr[0] = dz->bigfbuf;
  76. dz->flbufptr[1] = dz->bigfbuf + dz->big_fsize; /* bufend */
  77. for(wc = 0; wc < dz->wlength; wc++) {
  78. interp_fact = (double)wc/(double)(dz->wlength-1);
  79. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  80. if(dz->iparray[GLIDE_ZERO][cc]) {
  81. dz->flbufptr[0][AMPP] = dz->windowbuf[1][AMPP];
  82. dz->flbufptr[0][FREQ] = dz->windowbuf[1][FREQ];
  83. } else {
  84. dz->flbufptr[0][AMPP] = (float)(dz->windowbuf[0][AMPP] + (interp_fact * dz->windowbuf[1][AMPP]));
  85. dz->flbufptr[0][FREQ] = (float)(dz->windowbuf[0][FREQ] * pow(2.0,(dz->parray[GLIDE_INF][cc] * interp_fact)));
  86. }
  87. }
  88. if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[1]) { /* move along bigfbuf */
  89. if((exit_status = write_exact_samps(dz->bigfbuf,dz->big_fsize,dz))<0)
  90. return(exit_status);
  91. dz->flbufptr[0] = dz->bigfbuf;
  92. }
  93. }
  94. if(dz->flbufptr[0] != dz->bigfbuf) {
  95. if((exit_status = write_samps(dz->bigfbuf,dz->flbufptr[0] - dz->bigfbuf,dz))<0)
  96. return(exit_status);
  97. }
  98. return(FINISHED);
  99. }
  100. /****************************** READ_TWO_INDIVIDUAL_INPUT_WINDOWS ***************************/
  101. int read_two_individual_input_windows(dataptr dz)
  102. {
  103. int samps_read;
  104. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->wanted,dz->ifd[0],0)) < dz->wanted) {
  105. if(samps_read < 0) {
  106. sprintf(errstr,"Sound read error.\n");
  107. return(SYSTEM_ERROR);
  108. } else {
  109. sprintf(errstr,"Failed to read a window from 1st input file.\n");
  110. return(DATA_ERROR);
  111. }
  112. }
  113. memmove((char *)dz->windowbuf[0],(char *)dz->bigfbuf,(size_t)(dz->wanted * sizeof(float)));
  114. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->wanted,dz->ifd[1],0)) < dz->wanted) {
  115. if(samps_read < 0) {
  116. sprintf(errstr,"Sound read error.\n");
  117. return(SYSTEM_ERROR);
  118. } else {
  119. sprintf(errstr,"Failed to read a window from 2nd input file.\n");
  120. return(DATA_ERROR);
  121. }
  122. }
  123. memmove((char *)dz->windowbuf[1],(char *)dz->bigfbuf,(size_t)(dz->wanted * sizeof(float)));
  124. return(FINISHED);
  125. }
  126. /****************************** ESTABLISH_GLIDE_RATIOS ***************************/
  127. int establish_glide_ratios(dataptr dz)
  128. {
  129. int cc, vc;
  130. for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
  131. dz->iparray[GLIDE_ZERO][cc] = 0;
  132. if(flteq((double)dz->windowbuf[0][FREQ],0.0) || flteq((double)dz->windowbuf[1][FREQ],0.0)) {
  133. dz->iparray[GLIDE_ZERO][cc] = 1; /* mark any zeros in frq */
  134. dz->windowbuf[1][AMPP] = 0.0f;
  135. dz->windowbuf[1][FREQ] = (float)((double)cc * dz->chwidth);
  136. } else {
  137. dz->windowbuf[1][AMPP] = (float)(dz->windowbuf[1][AMPP] - dz->windowbuf[0][AMPP]);
  138. if(dz->windowbuf[0][FREQ] < 0.0)
  139. dz->windowbuf[0][FREQ] = -dz->windowbuf[0][FREQ]; /*invert any -ve frqs */
  140. if(dz->windowbuf[1][FREQ]<0.0)
  141. dz->windowbuf[1][FREQ] = -dz->windowbuf[1][FREQ];
  142. dz->parray[GLIDE_INF][cc] = log(dz->windowbuf[1][FREQ]/dz->windowbuf[0][FREQ])/LOG10_OF_2;
  143. }
  144. }
  145. return(FINISHED);
  146. }
  147. /**************************** SPECBRIDGE ***************************
  148. *
  149. * COMMENT FOR RWD: I know this is irrational!!
  150. *
  151. * MOVING POINTERS
  152. * flbufptr[0] flbufptr[1] flbufptr[5]
  153. * | | |
  154. * | V | V | V
  155. * |______________________________|______________________________|______________________________
  156. * | input buffer for file0 | input buffer for file1 | output buffer |
  157. * |_____________ifd[0]___________|_(ifd[1] becoming) otherfile__|______________________________|
  158. *
  159. * /\ /\ /\ /\
  160. * bigfbuf flbufptr[2] flbufptr[3] flbufptr[4]
  161. * FIXED POINTERS
  162. *
  163. * I've tidied it up in 'distort' package, so fixed pointers are called windowbuf[]
  164. * and moving pointers are called flbufptr[]
  165. */
  166. int specbridge(dataptr dz)
  167. {
  168. int exit_status;
  169. int windows_in_buf, startwindow, endwindow, remain, wc;
  170. dz->flbufptr[0] = dz->bigfbuf; /* moving pointer */
  171. dz->flbufptr[1] = dz->flbufptr[2]; /* moving pointer */
  172. dz->flbufptr[5] = dz->flbufptr[3]; /* moving pointer */
  173. //TW we only needed dz->outfilesize for truncating the final outfile: which no longer happens
  174. if((exit_status = establish_temporary_file_for_offsetting(dz))<0)
  175. return(exit_status);
  176. startwindow = determine_process_startwindow(dz);
  177. endwindow = determine_process_endwindow(dz);
  178. dz->total_windows = 0;
  179. if(startwindow >= endwindow) {
  180. sprintf(errstr,"error in window arithmetic: specbridge()\n");
  181. return(PROGRAM_ERROR);
  182. }
  183. while(dz->total_windows < endwindow) {
  184. if((exit_status = read_bothfiles_for_bridge(&windows_in_buf,dz))<0)
  185. return(exit_status);
  186. if(windows_in_buf <=0)
  187. break;
  188. for(wc=0; wc<windows_in_buf; wc++) {
  189. if(dz->total_windows >= startwindow) {
  190. if((exit_status = do_specbridge(dz))<0)
  191. return(exit_status);
  192. }
  193. if((exit_status = advance_one_2fileinput_window(dz))<0)
  194. return(exit_status);
  195. if(dz->total_windows >= endwindow)
  196. break;
  197. }
  198. }
  199. if((remain = dz->flbufptr[5] - dz->flbufptr[3]) > 0) {
  200. if((exit_status = write_samps(dz->flbufptr[3],remain,dz))<0)
  201. return(exit_status);
  202. }
  203. remove_temp_file(dz);
  204. return(FINISHED);
  205. }
  206. /*************************** ESTABLISH_TEMPORARY_FILE_FOR_OFFSETTING ***********************/
  207. int establish_temporary_file_for_offsetting(dataptr dz)
  208. {
  209. int exit_status;
  210. dz->flbufptr[5] = dz->flbufptr[3];
  211. if((dz->insams = (int *)realloc((char *)(dz->insams),(dz->infilecnt+1) * sizeof(int)))==NULL) {
  212. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge insams array.\n");
  213. return(MEMORY_ERROR);
  214. }
  215. if(dz->param[BRG_OFFSET] > 0.0) {
  216. if((exit_status = create_temporary_file_frontpadded_with_silence(dz))<0)
  217. return(exit_status);
  218. } else { /* point to original file */
  219. dz->other_file = dz->ifd[1];
  220. dz->insams[2] = dz->insams[1];
  221. }
  222. return(FINISHED);
  223. }
  224. /*************************** DETERMINE_PROCESS_STARTWINDOW ***********************/
  225. int determine_process_startwindow(dataptr dz)
  226. {
  227. int startwindow;
  228. switch(dz->mode) {
  229. case(BRG_NO_NORMALISE):
  230. case(BRG_NORM_TO_FILE1):
  231. case(BRG_NORM_FROM_1_TO_2):
  232. if(dz->param[BRG_SF2] > 0.0 || dz->param[BRG_SA2] > 0.0)
  233. startwindow = round(dz->param[BRG_OFFSET]/dz->frametime); /* start_of_sound from infile2 */
  234. else
  235. startwindow = 0;
  236. break;
  237. case(BRG_NORM_TO_MIN):
  238. case(BRG_NORM_FROM_2_TO_1):
  239. case(BRG_NORM_TO_FILE2):
  240. startwindow = round(dz->param[BRG_OFFSET]/dz->frametime); /* start_of_sound from infile2 */
  241. break;
  242. default:
  243. sprintf(errstr,"Unknown case in determine_process_startwindow()\n");
  244. return(PROGRAM_ERROR);
  245. }
  246. return(startwindow);
  247. }
  248. /*************************** DETERMINE_PROCESS_ENDWINDOW ***********************/
  249. int determine_process_endwindow(dataptr dz)
  250. {
  251. #define STOP_AT_END_OF_INFILE1 (0)
  252. #define STOP_AT_END_OF_INFILE2 (1)
  253. #define STOP_AT_END_OF_SHORTEST_FILE (2)
  254. int process_end;
  255. int endwindow = 0;
  256. switch(dz->mode) {
  257. case(BRG_NO_NORMALISE):
  258. if(dz->param[BRG_EF2] <= 0.0 && dz->param[BRG_EA2] <= 0.0)
  259. process_end = STOP_AT_END_OF_INFILE1;
  260. else if(dz->param[BRG_EF2] >= 1.0 && dz->param[BRG_EA2] >= 1.0)
  261. process_end = STOP_AT_END_OF_INFILE2;
  262. else
  263. process_end = STOP_AT_END_OF_SHORTEST_FILE;
  264. break;
  265. case(BRG_NORM_TO_MIN):
  266. process_end = STOP_AT_END_OF_SHORTEST_FILE;
  267. break;
  268. case(BRG_NORM_TO_FILE1):
  269. case(BRG_NORM_FROM_2_TO_1):
  270. if(dz->param[BRG_EF2] > 0.0 || dz->param[BRG_EA2] > 0.0)
  271. process_end = STOP_AT_END_OF_SHORTEST_FILE;
  272. else
  273. process_end = STOP_AT_END_OF_INFILE1;
  274. break;
  275. case(BRG_NORM_TO_FILE2):
  276. case(BRG_NORM_FROM_1_TO_2):
  277. if(dz->param[BRG_EF2] < 1.0 || dz->param[BRG_EA2] < 1.0)
  278. process_end = STOP_AT_END_OF_SHORTEST_FILE;
  279. else
  280. process_end = STOP_AT_END_OF_INFILE2;
  281. break;
  282. default:
  283. sprintf(errstr,"Unknown case in determine_process_endwindow()\n");
  284. return(PROGRAM_ERROR);
  285. }
  286. switch(process_end) {
  287. case(STOP_AT_END_OF_INFILE1):
  288. endwindow = dz->insams[0]/dz->wanted;
  289. break;
  290. case(STOP_AT_END_OF_INFILE2):
  291. endwindow = dz->insams[2]/dz->wanted;
  292. break;
  293. case(STOP_AT_END_OF_SHORTEST_FILE):
  294. endwindow = min(dz->insams[2]/dz->wanted,dz->insams[0]/dz->wanted);
  295. break;
  296. }
  297. return(endwindow);
  298. }
  299. /***************************** READ_BOTHFILES_FOR_BRIDGE ***********************/
  300. int read_bothfiles_for_bridge(int *windows_in_buf,dataptr dz)
  301. {
  302. int samps_read;
  303. int samps_read1, samps_read2;
  304. if((samps_read1 = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[0],0))<0
  305. || (samps_read2 = fgetfbufEx(dz->flbufptr[2],dz->big_fsize,dz->other_file,0))<0) {
  306. sprintf(errstr,"Sound read error.\n");
  307. return(SYSTEM_ERROR);
  308. }
  309. samps_read = max(samps_read1,samps_read2);
  310. *windows_in_buf = samps_read/dz->wanted;
  311. dz->flbufptr[0] = dz->bigfbuf;
  312. dz->flbufptr[1] = dz->flbufptr[2];
  313. return(FINISHED);
  314. }
  315. /***************************** DO_SPECBRIDGE *********************************/
  316. int do_specbridge(dataptr dz)
  317. {
  318. int exit_status;
  319. int where;
  320. if(dz->total_windows < dz->iparam[BRG_SWIN]) where = BEFORE;
  321. else if(dz->total_windows < dz->iparam[BRG_INTPEND]) where = _IN_;
  322. else where = AFTER;
  323. switch(where) {
  324. case(BEFORE): /*** BEFORE START OF INTERPOLATION ***/
  325. switch(dz->iparam[BRG_STARTIS]) {
  326. case(1):
  327. memmove((char *)dz->flbufptr[5],(char *)dz->flbufptr[0],(size_t)(dz->wanted * sizeof(float)));
  328. break; /* KEEP FILE1 DATA */
  329. case(2):
  330. memmove((char *)dz->flbufptr[5],(char *)dz->flbufptr[1],(size_t)(dz->wanted * sizeof(float)));
  331. break; /* KEEP FILE2 DATA */
  332. case(3):
  333. if((exit_status = do_interpolation(BEFORE,dz))<0)
  334. return(exit_status);
  335. break; /* INTERP DATA */
  336. case(0):
  337. sprintf(errstr,"BRG_STARTIS = 0: Should be impossible!!! do_specbridge()\n");
  338. return(PROGRAM_ERROR);
  339. }
  340. break;
  341. case(_IN_): /******** INTERPOLATION PROPER ********/
  342. dz->param[BRG_SF2] += dz->param[BRG_FSTEP];
  343. dz->param[BRG_SA2] += dz->param[BRG_ASTEP];
  344. if((exit_status = do_interpolation(_IN_,dz))<0)
  345. return(exit_status);
  346. break;
  347. case(AFTER): /*** TAIL ***/
  348. switch(dz->iparam[BRG_TAILIS]) {
  349. case(1):
  350. memmove((char *)dz->flbufptr[5],(char *)dz->flbufptr[0],(size_t)(dz->wanted * sizeof(float)));
  351. break; /* KEEP FILE1 DATA */
  352. case(2):
  353. memmove((char *)dz->flbufptr[5],(char *)dz->flbufptr[1],(size_t)(dz->wanted * sizeof(float)));
  354. break; /* KEEP FILE2 DATA */
  355. case(3):
  356. if((exit_status = do_interpolation(AFTER,dz))<0)
  357. return(exit_status);
  358. break; /* KEEP INTERPOLATED DATA */
  359. case(0):
  360. sprintf(errstr,"tailis = 0: Should be impossible!!! do_specbridge()\n");
  361. return(PROGRAM_ERROR);
  362. }
  363. break;
  364. }
  365. if((dz->flbufptr[5] += dz->wanted) >= dz->flbufptr[4]) {
  366. if((exit_status = write_exact_samps(dz->flbufptr[3],dz->big_fsize,dz))<0)
  367. return(exit_status);
  368. dz->flbufptr[5] = dz->flbufptr[3];
  369. }
  370. return(FINISHED);
  371. }
  372. /*************************** CREATE_TEMPORARY_FILE_FRONTPADDED_WITH_SILENCE ***********************/
  373. int create_temporary_file_frontpadded_with_silence(dataptr dz)
  374. {
  375. int exit_status;
  376. int offset_windows,bufwindows, samps_read, windows_read, remain;
  377. // if((dz->other_file = sndcreat("temp",-1,SAMP_FLOAT)) < 0) {
  378. // sprintf(errstr,"Can't create intermediate soundfile 'temp.wav'\n");
  379. // return(GOAL_FAILED);
  380. // }
  381. if((dz->other_file = sndcreat_formatted("temp",-1,SAMP_FLOAT,
  382. dz->infile->channels,dz->infile->srate,CDP_CREATE_NORMAL)) < 0) {
  383. sprintf(errstr,"Can't create intermediate soundfile 'temp.wav'\n");
  384. return(GOAL_FAILED);
  385. }
  386. if((exit_status = set_tempfile_properties(dz))<0)
  387. return(exit_status);
  388. offset_windows = round(dz->param[BRG_OFFSET]/dz->frametime);
  389. bufwindows = dz->big_fsize/dz->wanted;
  390. while(offset_windows >= bufwindows) {
  391. memset((char *)dz->flbufptr[3],0,(size_t)(dz->big_fsize * sizeof(float)));
  392. if((exit_status =
  393. write_samps_to_elsewhere(dz->other_file,dz->flbufptr[3],dz->big_fsize,dz))<0)
  394. return(exit_status);
  395. offset_windows -= bufwindows;
  396. }
  397. if(offset_windows) {
  398. memset((char *)dz->flbufptr[3],0,(size_t)(offset_windows * dz->wanted * sizeof(float)));
  399. dz->flbufptr[5] = dz->flbufptr[3] + offset_windows * dz->wanted;
  400. }
  401. do {
  402. if((samps_read = fgetfbufEx(dz->bigfbuf,dz->big_fsize,dz->ifd[1],0)) < 0) {
  403. sprintf(errstr,"soundfile read failed.\n");
  404. return(SYSTEM_ERROR);
  405. }
  406. dz->flbufptr[0] = dz->bigfbuf;
  407. if(samps_read > 0) {
  408. windows_read = samps_read/dz->wanted;
  409. while(windows_read) {
  410. if(dz->flbufptr[0] >= dz->flbufptr[2]) {
  411. sprintf(errstr,"Error in buffer arithmetic: create_temporary_file_frontpadded_with_silence()\n");
  412. return(PROGRAM_ERROR);
  413. }
  414. memmove((char *)dz->flbufptr[5],(char *)dz->flbufptr[0],(size_t)(dz->wanted * sizeof(float)));
  415. if((dz->flbufptr[5] += dz->wanted) >= dz->flbufptr[4]) {
  416. if((exit_status =
  417. write_samps_to_elsewhere(dz->other_file,dz->flbufptr[3],dz->big_fsize,dz))<0)
  418. return(exit_status);
  419. dz->flbufptr[5] = dz->flbufptr[3];
  420. }
  421. dz->flbufptr[0] += dz->wanted;
  422. windows_read--;
  423. }
  424. }
  425. }while(samps_read > 0);
  426. if((remain = dz->flbufptr[5] - dz->flbufptr[3]) > 0) {
  427. if((exit_status = write_samps_to_elsewhere(dz->other_file,dz->flbufptr[3],remain,dz))<0)
  428. return(exit_status);
  429. }
  430. dz->insams[2] = dz->total_samps_written;
  431. dz->total_samps_written = 0;
  432. dz->flbufptr[0] = dz->bigfbuf;
  433. dz->flbufptr[5] = dz->flbufptr[3];
  434. if((sndseekEx(dz->other_file,0L,0))<0) {
  435. sprintf(errstr,"seek to 0 failed, in create_temporary_file_frontpadded_with_silence()\n");
  436. return(SYSTEM_ERROR);
  437. }
  438. return(FINISHED);
  439. }
  440. /********************* DO_INTERPOLATION **************************/
  441. int do_interpolation(int where,dataptr dz)
  442. {
  443. int exit_status;
  444. int n = 0, normalisation_type = NO_NORMALISE;
  445. double normaliser = 0.0;
  446. if(dz->mode!= BRG_NO_NORMALISE) { /* RWD need these! */
  447. if((exit_status = set_normalisation_type(&normalisation_type,where,&normaliser,dz))<0)
  448. return(exit_status);
  449. }//RWD
  450. switch(normalisation_type) {
  451. case(NO_NORMALISE):
  452. while(n < dz->wanted) {
  453. dz->flbufptr[5][n] = (float)((dz->flbufptr[1][n]*dz->param[BRG_SA2]) + (dz->flbufptr[0][n]*(1.0 - dz->param[BRG_SA2])));
  454. n++;
  455. }
  456. break;
  457. case(NORMALISE_FILE1):
  458. while(n < dz->wanted) {
  459. dz->flbufptr[5][n] = (float)((dz->flbufptr[1][n]*dz->param[BRG_SA2]) + (dz->flbufptr[0][n]*(1.0 - dz->param[BRG_SA2])*normaliser));
  460. n++;
  461. dz->flbufptr[5][n] = (float)((dz->flbufptr[1][n]*dz->param[BRG_SF2]) + (dz->flbufptr[0][n]*(1.0 - dz->param[BRG_SF2])));
  462. n++;
  463. }
  464. break;
  465. case(NORMALISE_FILE2):
  466. while(n < dz->wanted) {
  467. dz->flbufptr[5][n] = (float)((dz->flbufptr[1][n]*dz->param[BRG_SA2]*normaliser) + (dz->flbufptr[0][n]*(1.0 - dz->param[BRG_SA2])));
  468. n++;
  469. dz->flbufptr[5][n] = (float)((dz->flbufptr[1][n]*dz->param[BRG_SF2]) + (dz->flbufptr[0][n]*(1.0 - dz->param[BRG_SF2])));
  470. n++;
  471. }
  472. break;
  473. default:
  474. sprintf(errstr,"unknown case in do_interpolation()\n");
  475. return(PROGRAM_ERROR);
  476. }
  477. return(FINISHED);
  478. }
  479. /***************************** SET_TEMPFILE_PROPERTIES ******************************/
  480. int set_tempfile_properties(dataptr dz)
  481. {
  482. if(sndputprop(dz->other_file,"original sampsize", (char *)&(dz->infile->origstype), sizeof(int)) < 0){
  483. sprintf(errstr,"Failure to write original sample size. set_tempfile_properties()\n");
  484. return(PROGRAM_ERROR);
  485. }
  486. if(sndputprop(dz->other_file,"original sample rate", (char *)&(dz->infile->origrate), sizeof(int)) < 0){
  487. sprintf(errstr,"Failure to write original sample rate. set_tempfile_properties()\n");
  488. return(PROGRAM_ERROR);
  489. }
  490. if(sndputprop(dz->other_file,"arate",(char *)&(dz->infile->arate),sizeof(float)) < 0){
  491. sprintf(errstr,"Failed to write analysis sample rate. set_tempfile_properties()\n");
  492. return(PROGRAM_ERROR);
  493. }
  494. if(sndputprop(dz->other_file,"analwinlen",(char *)&(dz->infile->Mlen),sizeof(int)) < 0){
  495. sprintf(errstr,"Failure to write analysis window length. set_tempfile_properties()\n");
  496. return(PROGRAM_ERROR);
  497. }
  498. if(sndputprop(dz->other_file,"decfactor",(char *)&(dz->infile->Dfac),sizeof(int)) < 0){
  499. sprintf(errstr,"Failure to write decimation factor. set_tempfile_properties()\n");
  500. return(PROGRAM_ERROR);
  501. }
  502. if(sndputprop(dz->other_file,"sample rate", (char *)&(dz->infile->srate), sizeof(int)) < 0){
  503. sprintf(errstr,"Failure to write sample rate. set_tempfile_properties()\n");
  504. return(PROGRAM_ERROR);
  505. }
  506. if(sndputprop(dz->other_file,"channels", (char *)&(dz->infile->channels), sizeof(int)) < 0){
  507. sprintf(errstr,"Failure to write channel data. set_tempfile_properties()\n");
  508. return(PROGRAM_ERROR);
  509. }
  510. //TW can't change sample type after file opened
  511. // if(sndputprop(dz->other_file,"sample type", (char *)&(dz->infile->stype), sizeof(int)) < 0){
  512. // sprintf(errstr,"Failure to write sample size. set_tempfile_properties()\n");
  513. // return(PROGRAM_ERROR);
  514. // }
  515. return(FINISHED);
  516. }
  517. /********************* SET_NORMALISATION_TYPE **************************/
  518. int set_normalisation_type(int *normalisation_type,int where,double *normaliser, dataptr dz)
  519. {
  520. int vc;
  521. double z1, z2;
  522. double sum1 = 0.0;
  523. double sum2 = 0.0;
  524. for(vc = 0;vc < dz->wanted; vc+=2) {
  525. sum1 += dz->flbufptr[0][AMPP];
  526. sum2 += dz->flbufptr[1][AMPP];
  527. }
  528. if(sum1 < 0.0 || sum2 < 0.0) {
  529. sprintf(errstr,"Amplitude anomaly in data: cannot proceed.\n");
  530. return(DATA_ERROR);
  531. }
  532. switch(dz->mode) {
  533. case(BRG_NORM_TO_MIN):
  534. if(sum1>sum2) {
  535. *normalisation_type = NORMALISE_FILE1;
  536. if(flteq(sum1,0.0))
  537. *normaliser = 0.0;
  538. else
  539. *normaliser = sum2/sum1;
  540. } else {
  541. *normalisation_type = NORMALISE_FILE2;
  542. if(flteq(sum2,0.0))
  543. *normaliser = 0.0;
  544. else
  545. *normaliser = sum1/sum2;
  546. }
  547. break;
  548. case(BRG_NORM_TO_FILE1):
  549. *normalisation_type = NORMALISE_FILE2;
  550. if(flteq(sum2,0.0))
  551. *normaliser = 0.0;
  552. else
  553. *normaliser = sum1/sum2;
  554. break;
  555. case(BRG_NORM_TO_FILE2):
  556. *normalisation_type = NORMALISE_FILE1;
  557. if(flteq(sum1,0.0))
  558. *normaliser = 0.0;
  559. else
  560. *normaliser = sum2/sum1;
  561. break;
  562. case(BRG_NORM_FROM_1_TO_2):
  563. switch(where) {
  564. case(BEFORE):
  565. *normalisation_type = NORMALISE_FILE2;
  566. if(flteq(sum2,0.0))
  567. *normaliser = 0.0;
  568. else
  569. *normaliser = sum1/sum2;
  570. break;
  571. case(_IN_):
  572. if(flteq(sum2,0.0))
  573. *normaliser = 0.0;
  574. else if(flteq(sum1,0.0))
  575. *normaliser = 0.0;
  576. else {
  577. z1 = sum1/sum2;
  578. z2 = sum2/sum1;
  579. *normaliser = z1 * pow(z2,dz->param[BRG_TFAC]);
  580. }
  581. if(dz->param[BRG_TFAC]<=1.0)
  582. *normalisation_type = NORMALISE_FILE2;
  583. else
  584. *normalisation_type = NORMALISE_FILE1;
  585. dz->param[BRG_TFAC] += dz->param[BRG_TSTEP];
  586. break;
  587. case(AFTER):
  588. *normalisation_type = NORMALISE_FILE1;
  589. if(flteq(sum1,0.0))
  590. *normaliser = 0.0;
  591. else
  592. *normaliser = sum2/sum1;
  593. break;
  594. default:
  595. sprintf(errstr,"Unknown case (A) in set_normalisation_type()\n");
  596. return(PROGRAM_ERROR);
  597. }
  598. break;
  599. case(BRG_NORM_FROM_2_TO_1):
  600. switch(where) {
  601. case(BEFORE):
  602. *normalisation_type = NORMALISE_FILE1;
  603. if(flteq(sum1,0.0))
  604. *normaliser = 0.0;
  605. else
  606. *normaliser = sum2/sum1;
  607. break;
  608. case(_IN_):
  609. if(flteq(sum1,0.0))
  610. *normaliser = 0.0;
  611. else if(flteq(sum2,0.0))
  612. *normaliser = 0.0;
  613. else {
  614. z1 = sum2/sum1;
  615. z2 = sum1/sum2;
  616. *normaliser = z1 * pow(z2,dz->param[BRG_TFAC]);
  617. }
  618. if(dz->param[BRG_TFAC]<=1.0)
  619. *normalisation_type = NORMALISE_FILE1;
  620. else
  621. *normalisation_type = NORMALISE_FILE2;
  622. dz->param[BRG_TFAC] += dz->param[BRG_TSTEP];
  623. break;
  624. case(AFTER):
  625. *normalisation_type = NORMALISE_FILE2;
  626. if(flteq(sum2,0.0))
  627. *normaliser = 0.0;
  628. else
  629. *normaliser = sum1/sum2;
  630. break;
  631. default:
  632. sprintf(errstr,"Unknown case (B) in set_normalisation_type()\n");
  633. return(PROGRAM_ERROR);
  634. }
  635. break;
  636. default:
  637. sprintf(errstr,"Unknown case (C) in set_normalisation_type()\n");
  638. return(PROGRAM_ERROR);
  639. }
  640. return(FINISHED);
  641. }
  642. /***************************** SPECMORPH ***********************/
  643. int specmorph(dataptr dz)
  644. {
  645. #define FILE0 (0)
  646. #define FILE1 (1)
  647. int exit_status;
  648. int windows_to_buf0 = 0, windows_to_buf1 = 0,
  649. bufwsize = dz->big_fsize/dz->wanted;
  650. int start_of_morph = min(dz->iparam[MPH_ASTTW],dz->iparam[MPH_FSTTW]);
  651. int end_of_morph = max(dz->iparam[MPH_AENDW],dz->iparam[MPH_FENDW]);
  652. double flen = (double)(dz->iparam[MPH_FENDW] - dz->iparam[MPH_FSTTW]);
  653. double alen = (double)(dz->iparam[MPH_AENDW] - dz->iparam[MPH_ASTTW]);
  654. int window_position_in_current_buf_for_file0 = 0,
  655. window_position_in_outfile = 0,
  656. window_position_in_current_buf_for_file1 = -dz->iparam[MPH_STAGW];
  657. int total_windows_processed_from_file0 = 0,
  658. total_windows_processed_from_file1 = 0;
  659. int finished_file0 = 0,
  660. finished_file1 = 0;
  661. int total_windows_in_file1 = dz->insams[1]/dz->wanted;
  662. do {
  663. if(!finished_file0) {
  664. if(total_windows_processed_from_file0 >= end_of_morph)
  665. finished_file0 = 1;
  666. else {
  667. if(window_position_in_current_buf_for_file0 == windows_to_buf0) {
  668. if((exit_status = read_specific_file_to_specific_buf
  669. (FILE0,&windows_to_buf0,&dz->flbufptr[0],dz->bigfbuf,dz))<0)
  670. return(exit_status);
  671. window_position_in_current_buf_for_file0 = 0;
  672. }
  673. }
  674. }
  675. if(window_position_in_current_buf_for_file1>=0) {
  676. if(window_position_in_current_buf_for_file1 >= windows_to_buf1) {
  677. if((exit_status = read_specific_file_to_specific_buf
  678. (FILE1,&windows_to_buf1,&dz->flbufptr[1],dz->flbufptr[2],dz))<0)
  679. return(exit_status);
  680. window_position_in_current_buf_for_file1 = 0;
  681. }
  682. if(total_windows_processed_from_file0 >= start_of_morph) {
  683. if(!finished_file0) {
  684. if((exit_status = do_specmorph(alen,flen,dz))<0)
  685. return(exit_status);
  686. } else
  687. memmove((char *)dz->flbufptr[0],(char *)dz->flbufptr[1],(size_t)(dz->wanted * sizeof(float)));
  688. }
  689. dz->flbufptr[1] += dz->wanted;
  690. if(++total_windows_processed_from_file1 >= total_windows_in_file1)
  691. finished_file1 = 1;
  692. }
  693. dz->flbufptr[0] += dz->wanted;
  694. if(++window_position_in_outfile >= bufwsize) {
  695. if((exit_status = write_exact_samps(dz->bigfbuf,dz->big_fsize,dz))<0)
  696. return(exit_status);
  697. window_position_in_outfile = 0;
  698. dz->flbufptr[0] = dz->bigfbuf;
  699. }
  700. if(!finished_file0) {
  701. total_windows_processed_from_file0++;
  702. window_position_in_current_buf_for_file0++;
  703. }
  704. window_position_in_current_buf_for_file1++;
  705. dz->total_windows++;
  706. } while(!finished_file1);
  707. if((window_position_in_outfile > 0) && (window_position_in_current_buf_for_file0 > 0)) {
  708. if((exit_status = write_samps(dz->bigfbuf,window_position_in_current_buf_for_file0 * dz->wanted,dz))<0)
  709. return(exit_status);
  710. }
  711. return(FINISHED);
  712. }
  713. /***************************** READ_SPECIFIC_FILE_TO_SPECIFIC_BUF ***********************/
  714. int read_specific_file_to_specific_buf(int fileno,int *windows_to_buf,float **fbufptr,float *floatbuf,dataptr dz)
  715. {
  716. int samps_read;
  717. if((samps_read = fgetfbufEx(floatbuf,dz->big_fsize,dz->ifd[fileno],0))<=0) {
  718. if(samps_read<0) {
  719. sprintf(errstr,"Sound read error.\n");
  720. return(SYSTEM_ERROR);
  721. } else {
  722. sprintf(errstr,"Error in buffer arithmetic in read_specific_file_to_specific_buf()\n");
  723. return(PROGRAM_ERROR);
  724. }
  725. }
  726. *windows_to_buf = samps_read/dz->wanted;
  727. *fbufptr = floatbuf;
  728. return(FINISHED);
  729. }
  730. /*************************************** DO_SPECMORPH ******************************************/
  731. int do_specmorph(double alen, double flen, dataptr dz)
  732. {
  733. int exit_status;
  734. int vc;
  735. double amp_interpratio, frq_interpratio, diff, incr;
  736. if(dz->total_windows > dz->iparam[MPH_ASTTW]) {
  737. if(dz->total_windows < dz->iparam[MPH_AENDW]) {
  738. amp_interpratio = (double)(dz->total_windows - dz->iparam[MPH_ASTTW])/(double)alen;
  739. switch(dz->mode) {
  740. case(MPH_LINE):
  741. amp_interpratio = pow(amp_interpratio,dz->param[MPH_AEXP]);
  742. break;
  743. case(MPH_COSIN):
  744. if((exit_status = warped_cosin(&amp_interpratio,dz->param[MPH_AEXP],dz))<0)
  745. return(exit_status);
  746. break;
  747. default:
  748. sprintf(errstr,"Unknown case in do_specmorph()\n");
  749. return(PROGRAM_ERROR);
  750. }
  751. for(vc=0;vc < dz->wanted; vc+=2) {
  752. diff = dz->flbufptr[1][AMPP] - dz->flbufptr[0][AMPP];
  753. incr = diff * amp_interpratio;
  754. dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] + incr);
  755. }
  756. }
  757. else {
  758. for(vc=0;vc < dz->wanted; vc+=2)
  759. dz->flbufptr[0][AMPP] = dz->flbufptr[1][AMPP];
  760. }
  761. }
  762. if(dz->total_windows > dz->iparam[MPH_FSTTW]) {
  763. if(dz->total_windows < dz->iparam[MPH_FENDW]) {
  764. frq_interpratio = (double)(dz->total_windows - dz->iparam[MPH_FSTTW])/flen;
  765. switch(dz->mode) {
  766. case(MPH_LINE):
  767. frq_interpratio = pow(frq_interpratio,dz->param[MPH_FEXP]);
  768. break;
  769. case(MPH_COSIN):
  770. if((exit_status = warped_cosin(&frq_interpratio,dz->param[MPH_FEXP],dz))<0)
  771. return(exit_status);
  772. break;
  773. default:
  774. sprintf(errstr,"Unknown case in do_specmorph()\n");
  775. return(PROGRAM_ERROR);
  776. }
  777. for(vc=0;vc < dz->wanted; vc+=2) {
  778. diff = dz->flbufptr[1][FREQ] - dz->flbufptr[0][FREQ];
  779. incr = diff * frq_interpratio;
  780. dz->flbufptr[0][FREQ] = (float)(dz->flbufptr[0][FREQ] + incr);
  781. }
  782. } else {
  783. for(vc=0;vc < dz->wanted; vc+=2)
  784. dz->flbufptr[0][FREQ] = dz->flbufptr[1][FREQ];
  785. }
  786. }
  787. return(FINISHED);
  788. }
  789. /*************************** DETERMINE_PROCESS_STARTWINDOW ***********************/
  790. void remove_temp_file(dataptr dz)
  791. {
  792. if(dz->param[BRG_OFFSET] && dz->other_file >= 0) {
  793. if(sndunlink(dz->other_file) < 0) {
  794. fprintf(stdout, "WARNING: Can't set temporary sndfile 'temp' for deletion\n");
  795. }
  796. if(sndcloseEx(dz->other_file) < 0) {
  797. fprintf(stdout,"WARNING: Can't close temporary sndfile 'temp'\n");
  798. }
  799. }
  800. dz->other_file = -1;
  801. }
  802. /****************************** WARPED_COSIN ******************************/
  803. int warped_cosin(double *interpratio,double exponent,dataptr dz)
  804. {
  805. int exit_status;
  806. if(*interpratio < .5) {
  807. if((exit_status = time_warp(interpratio,exponent))<0)
  808. return(exit_status);
  809. } else if(*interpratio > .5) {
  810. *interpratio = 1.0 - *interpratio;
  811. if((exit_status = time_warp(interpratio,exponent))<0)
  812. return(exit_status);
  813. *interpratio = 1.0 - *interpratio;
  814. }
  815. if((exit_status = cosin_lookup(interpratio,dz))<0)
  816. return(exit_status);
  817. return(FINISHED);
  818. }
  819. /****************************** TIME_WARP ******************************/
  820. int time_warp(double *interpratio,double exponent)
  821. {
  822. *interpratio = min(*interpratio * 2.0,1.0);
  823. *interpratio = pow(*interpratio,exponent);
  824. *interpratio /= 2.0;
  825. return(FINISHED);
  826. }
  827. /****************************** COSIN_LOOKUP ******************************/
  828. int cosin_lookup(double *interpratio,dataptr dz)
  829. {
  830. double dtabindex = *interpratio * (double)MPH_COSTABSIZE;
  831. int tabindex = (int)floor(dtabindex); /* TRUNCATE */
  832. double frac = dtabindex - (double)tabindex;
  833. double thisval = dz->parray[0][tabindex++]; /* table has wraparound pnt */
  834. double nextval = dz->parray[0][tabindex];
  835. double diff = nextval - thisval;
  836. double step = diff * frac;
  837. *interpratio = thisval + step;
  838. return(FINISHED);
  839. }