pvoc.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  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 <globcon.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <logic.h>
  30. #include <cdpmain.h>
  31. #include <pvoc.h>
  32. #include <string.h>
  33. #include <sfsys.h>
  34. #include <pvoc.h>
  35. // NEW 2014 -->
  36. static int outfloats(float *nextOut, float *maxsampl,float *minsample,float *local_maxsample,int *num_overflows,int todo, int finished, dataptr dz);
  37. // <-- NEW 2014
  38. static int pvoc_float_array(int nnn,float **ptr);
  39. static int sndwrite_header(int N2,int *Nchans,float *arate,float R,int D,int origsize,int *isr,int M,dataptr dz);
  40. static void hamming(float *win,int winLen,int even);
  41. static int pvoc_time_display(int nI,int srate,int *samptime,dataptr dz);
  42. static int write_samps_pvoc(float *bbuf,int samps_to_write,dataptr dz);
  43. /****************************** HAMMING ******************************/
  44. void hamming(float *win,int winLen,int even)
  45. {
  46. float Pi,ftmp;
  47. int i;
  48. /***********************************************************
  49. Pi = (float)((double)4.*atan((double)1.));
  50. ***********************************************************/
  51. Pi = (float)PI;
  52. ftmp = Pi/winLen;
  53. if (even) {
  54. for (i=0; i<winLen; i++)
  55. *(win+i) = (float)((double).54 + (double).46*cos((double)(ftmp*((float)i+.5))));
  56. *(win+winLen) = 0.0f;}
  57. else{ *(win) = 1.0f;
  58. for (i=1; i<=winLen; i++)
  59. *(win+i) =(float)((double).54 + (double).46*cos((double)(ftmp*(float)i)));
  60. }
  61. return;
  62. }
  63. /****************************** FLOAT_ARRAY ******************************/
  64. int pvoc_float_array(int nnn,float **ptr)
  65. { /* set up a floating point array length nnn. */
  66. *ptr = (float *) calloc(nnn,sizeof(float));
  67. if(*ptr==NULL){
  68. sprintf(errstr,"pvoc: insufficient memory\n");
  69. return(MEMORY_ERROR);
  70. }
  71. return(FINISHED);
  72. }
  73. /****************************** PVOC_PROCESS ******************************/
  74. int pvoc_process(dataptr dz)
  75. {
  76. int exit_status;
  77. int finished = 0;
  78. int num_overflows = 0;
  79. int samptime = SAMP_TIME_STEP;
  80. double rratio;
  81. float *input, /* pointer to start of input buffer */
  82. *output, /* pointer to start of output buffer */
  83. *anal, /* pointer to start of analysis buffer */
  84. *syn, /* pointer to start of synthesis buffer */
  85. *banal, /* pointer to anal[1] (for FFT calls) */
  86. *bsyn, /* pointer to syn[1] (for FFT calls) */
  87. *nextIn, /* pointer to next empty word in input */
  88. *nextOut, /* pointer to next empty word in output */
  89. *analWindow, /* pointer to center of analysis window */
  90. *synWindow, /* pointer to center of synthesis window */
  91. *maxAmp, /* pointer to start of max amp buffer */
  92. *avgAmp, /* pointer to start of avg amp buffer */
  93. *avgFrq, /* pointer to start of avg frq buffer */
  94. *env, /* pointer to start of spectral envelope */
  95. *i0, /* pointer to amplitude channels */
  96. *i1, /* pointer to frequency channels */
  97. *oi, /* pointer to old phase channels */
  98. *oldInPhase, /* pointer to start of input phase buffer */
  99. *oldOutPhase, /* pointer to start of output phase buffer */
  100. maxsample = 0.0, minsample = 0.0, biggest;
  101. int M = 0, /* length of analWindow impulse response */
  102. D = 0, /* decimatin factor */
  103. I = 0, /* interpolation factor (default will be I=D)*/
  104. /* RWD */
  105. /*F = 0,*/ /* fundamental frequency (determines dz->iparam[PVOC_CHANS]) */
  106. analWinLen, /* half-length of analysis window */
  107. synWinLen; /* half-length of synthesis window */
  108. int sampsize, /* sample size for output file */
  109. outCount, /* number of samples written to output */
  110. ibuflen, /* length of input buffer */
  111. obuflen, /* length of output buffer */
  112. nI = 0, /* current input (analysis) sample */
  113. nO, /* current output (synthesis) sample */
  114. nMaxOut; /* last output (synthesis) sample */
  115. int origsize = 0, /* sample type of file analysed */
  116. isr, /* sampling rate */
  117. Nchans, /* no of chans */
  118. endsamp = VERY_BIG_INT;
  119. float real, /* real part of analysis data */
  120. imag, /* imaginary part of analysis data */
  121. mag, /* magnitude of analysis data */
  122. phase, /* phase of analysis data */
  123. angleDif, /* angle difference */
  124. RoverTwoPi, /* R/D divided by 2*Pi */
  125. TwoPioverR, /* 2*Pi divided by R/I */
  126. sum, /* scale factor for renormalizing windows */
  127. // ftot = 0.0f, /* scale factor for calculating statistics */
  128. rIn, /* decimated sampling rate */
  129. rOut, /* pre-interpolated sampling rate */
  130. R, /* input sampling rate */
  131. // NEW 2014 -->
  132. local_maxsample = 0.0;
  133. // <-- NEW 2014
  134. int i,j,k, /* index variables */
  135. Dd, /* number of new inputs to read (Dd <= D) */
  136. Ii, /* number of new outputs to write (Ii <= I) */
  137. N2, /* dz->iparam[PVOC_CHANS]/2 */
  138. NO, /* synthesis NO = dz->iparam[PVOC_CHANS] / P */
  139. NO2, /* NO/2 */
  140. IO, /* synthesis IO = I / P */
  141. IOi, /* synthesis IOi = Ii / P */
  142. Mf = 0, /* flag for even M */
  143. #ifdef SINGLE_SAMP
  144. rv, /* return value from fgetfloat */
  145. #endif
  146. flag = 0; /* end-of-input flag */
  147. float arate = 1.0 /* TW: arbitrary initialisation */; /* sample rate for header on stdout if -A */
  148. /*RWD */
  149. float F = 0.0f;
  150. if(sndgetprop(dz->ifd[0],"sample type", (char *) &sampsize, sizeof(int)) < 0){
  151. sprintf(errstr,"pvoc: failure to get sample type\n");
  152. return(MEMORY_ERROR);
  153. }
  154. if (dz->process==PVOC_SYNTH) {
  155. isr = dz->infile->origrate;
  156. sampsize = dz->infile->origstype;
  157. arate = dz->infile->arate;
  158. Nchans = dz->infile->channels;
  159. dz->iparam[PVOC_CHANS] = Nchans - 2;
  160. M = dz->infile->Mlen;
  161. D = dz->infile->Dfac;
  162. R = ((float) D * arate);
  163. } else {
  164. isr = dz->infile->srate;
  165. R = (float)isr;
  166. Nchans = dz->infile->channels;
  167. /*RWD OCT 05 need this to preserved hires infile formats */
  168. origsize = dz->infile->stype;
  169. }
  170. if(flteq(R,0.0)) {
  171. sprintf(errstr,"Problem: zero sampling rate\n");
  172. return(DATA_ERROR);
  173. }
  174. sampsize = ((dz->iparam[PVOC_ANAL_ONLY]) ? SAMP_FLOAT:dz->infile->stype);
  175. N2 = dz->iparam[PVOC_CHANS] / 2;
  176. F = /*(int)*/(float)(R /(float)dz->iparam[PVOC_CHANS]); /*RWD*/
  177. if(dz->process!=PVOC_SYNTH) {
  178. switch(dz->iparam[PVOC_WIN_OVERLAP]){
  179. case 0: M = 4*dz->iparam[PVOC_CHANS]; break;
  180. case 1: M = 2*dz->iparam[PVOC_CHANS]; break;
  181. case 2: M = dz->iparam[PVOC_CHANS]; break;
  182. case 3: M = N2; break;
  183. default:
  184. sprintf(errstr,"pvoc: Invalid window overlap factor.\n");
  185. return(PROGRAM_ERROR);
  186. }
  187. }
  188. if(!sloom) {
  189. if(dz->iparam[PVOC_ANAL_ONLY] && (dz->process==PVOC_SYNTH)) {
  190. sprintf(errstr,"both -A and -S specified: Impossible!\n");
  191. return(PROGRAM_ERROR);
  192. }
  193. }
  194. Mf = 1 - M%2;
  195. if (M < 7) {
  196. fprintf(stdout,"WARNING: analWindow impulse response is too small\n");
  197. fflush(stdout);
  198. }
  199. ibuflen = 4 * M;
  200. obuflen = 4 * M;
  201. if(dz->process!=PVOC_SYNTH) {
  202. if((D = (int)(M/PVOC_CONSTANT_A)) == 0){
  203. fprintf(stdout,"WARNING: Decimation too low: adjusted.\n");
  204. fflush(stdout);
  205. D = 1;
  206. }
  207. }
  208. switch(dz->process) {
  209. case(PVOC_ANAL):
  210. case(PVOC_EXTRACT):
  211. arate = (float)(R/D); /* Needed to write to outheader */
  212. dz->wanted = dz->iparam[PVOC_CHANS] + 2;
  213. /* fall thro */
  214. case(PVOC_SYNTH):
  215. dz->frametime = (float)(1.0/arate);
  216. break;
  217. }
  218. if(sloom) {
  219. if(dz->process==PVOC_SYNTH) {
  220. dz->tempsize = (dz->insams[0]/dz->infile->channels) * dz->infile->Dfac;
  221. /*length of output in samps: needed for time-display in TK mode */
  222. } else {
  223. dz->tempsize = dz->insams[0];
  224. }
  225. }
  226. I = D;
  227. NO = dz->iparam[PVOC_CHANS]; /* synthesis transform will be NO points */
  228. NO2 = NO/2;
  229. IO = I;
  230. if((exit_status = sndwrite_header(N2,&Nchans,&arate,R,D,origsize,&isr,M,dz))<0)
  231. return(exit_status);
  232. //TW
  233. // if(!sloom) {
  234. if(!sloom && !sloombatch) {
  235. fprintf(stdout,"analysis/synthesis beginning\n");
  236. fflush(stdout);
  237. }
  238. /* set up analysis window: The window is assumed to be symmetric
  239. with M total points. After the initial memory allocation,
  240. analWindow always points to the midpoint of the window
  241. (or one half sample to the right, if M is even); analWinLen
  242. is half the true window length (rounded down). Any low pass
  243. window will work; a Hamming window is generally fine,
  244. but a Kaiser is also available. If the window duration is
  245. longer than the transform (M > N), then the window is
  246. multiplied by a sin(x)/x function to meet the condition:
  247. analWindow[Ni] = 0 for i != 0. In either case, the
  248. window is renormalized so that the phase vocoder amplitude
  249. estimates are properly scaled. The maximum allowable
  250. window duration is ibuflen/2. */
  251. if((exit_status = pvoc_float_array(M+Mf,&analWindow))<0)
  252. return(exit_status);
  253. analWindow += (analWinLen = M/2);
  254. hamming(analWindow,analWinLen,Mf);
  255. for (i = 1; i <= analWinLen; i++)
  256. *(analWindow - i) = *(analWindow + i - Mf);
  257. if (M > dz->iparam[PVOC_CHANS]) {
  258. if (Mf)
  259. *analWindow *=(float)
  260. ((double)dz->iparam[PVOC_CHANS]*sin((double)PI*.5/dz->iparam[PVOC_CHANS])/(double)(PI*.5));
  261. for (i = 1; i <= analWinLen; i++)
  262. *(analWindow + i) *=(float)
  263. ((double)dz->iparam[PVOC_CHANS] * sin((double) (PI*(i+.5*Mf)/dz->iparam[PVOC_CHANS])) / (PI*(i+.5*Mf))); /* D.Timis */
  264. for (i = 1; i <= analWinLen; i++)
  265. *(analWindow - i) = *(analWindow + i - Mf);
  266. }
  267. sum = 0.0f;
  268. for (i = -analWinLen; i <= analWinLen; i++)
  269. sum += *(analWindow + i);
  270. sum = (float)(2.0/sum); /*factor of 2 comes in later in trig identity*/
  271. for (i = -analWinLen; i <= analWinLen; i++)
  272. *(analWindow + i) *= sum;
  273. /* set up synthesis window: For the minimal mean-square-error
  274. formulation (valid for N >= M), the synthesis window
  275. is identical to the analysis window (except for a
  276. scale factor), and both are even in length. If N < M,
  277. then an interpolating synthesis window is used. */
  278. if((exit_status = pvoc_float_array(M+Mf,&synWindow))<0)
  279. return(exit_status);
  280. synWindow += (synWinLen = M/2);
  281. if (M <= dz->iparam[PVOC_CHANS]){
  282. hamming(synWindow,synWinLen,Mf);
  283. for (i = 1; i <= synWinLen; i++)
  284. *(synWindow - i) = *(synWindow + i - Mf);
  285. for (i = -synWinLen; i <= synWinLen; i++)
  286. *(synWindow + i) *= sum;
  287. sum = 0.0f;
  288. for (i = -synWinLen; i <= synWinLen; i+=I)
  289. sum += *(synWindow + i) * *(synWindow + i);
  290. sum = (float)(1.0/ sum);
  291. for (i = -synWinLen; i <= synWinLen; i++)
  292. *(synWindow + i) *= sum;
  293. } else {
  294. hamming(synWindow,synWinLen,Mf);
  295. for (i = 1; i <= synWinLen; i++)
  296. *(synWindow - i) = *(synWindow + i - Mf);
  297. if (Mf)
  298. *synWindow *= (float)((double)IO * sin((double) (PI*.5/IO)) / (double)(PI*.5));
  299. for (i = 1; i <= synWinLen; i++)
  300. *(synWindow + i) *=(float)
  301. ((double)IO * sin((double) (PI*(i+.5*Mf)/IO)) /(double) (PI*(i+.5*Mf)));
  302. for (i = 1; i <= synWinLen; i++)
  303. *(synWindow - i) = *(synWindow + i - Mf);
  304. sum = (float)(1.0/sum);
  305. for (i = -synWinLen; i <= synWinLen; i++)
  306. *(synWindow + i) *= sum;
  307. }
  308. /* set up input buffer: nextIn always points to the next empty
  309. word in the input buffer (i.e., the sample following
  310. sample number (n + analWinLen)). If the buffer is full,
  311. then nextIn jumps back to the beginning, and the old
  312. values are written over. */
  313. if((exit_status = pvoc_float_array(ibuflen,&input))<0)
  314. return(exit_status);
  315. nextIn = input;
  316. /* set up output buffer: nextOut always points to the next word
  317. to be shifted out. The shift is simulated by writing the
  318. value to the standard output and then setting that word
  319. of the buffer to zero. When nextOut reaches the end of
  320. the buffer, it jumps back to the beginning. */
  321. if((exit_status = pvoc_float_array(obuflen,&output))<0)
  322. return(exit_status);
  323. nextOut = output;
  324. /* set up analysis buffer for (N/2 + 1) channels: The input is real,
  325. so the other channels are redundant. oldInPhase is used
  326. in the conversion to remember the previous phase when
  327. calculating phase difference between successive samples. */
  328. if((exit_status = pvoc_float_array(dz->iparam[PVOC_CHANS]+2,&anal))<0)
  329. return(exit_status);
  330. banal = anal + 1;
  331. if((exit_status = pvoc_float_array(N2+1,&oldInPhase))<0)
  332. return(exit_status);
  333. if((exit_status = pvoc_float_array(N2+1,&maxAmp))<0)
  334. return(exit_status);
  335. if((exit_status = pvoc_float_array(N2+1,&avgAmp))<0)
  336. return(exit_status);
  337. if((exit_status = pvoc_float_array(N2+1,&avgFrq))<0)
  338. return(exit_status);
  339. if((exit_status = pvoc_float_array(N2+1,&env))<0)
  340. return(exit_status);
  341. /* set up synthesis buffer for (dz->iparam[PVOC_CHANS]/2 + 1) channels: (This is included
  342. only for clarity.) oldOutPhase is used in the re-
  343. conversion to accumulate angle differences (actually angle
  344. difference per second). */
  345. if((exit_status = pvoc_float_array(NO+2,&syn))<0)
  346. return(exit_status);
  347. bsyn = syn + 1;
  348. if((exit_status = pvoc_float_array(NO2+1,&oldOutPhase))<0)
  349. return(exit_status);
  350. /* initialization: input time starts negative so that the rightmost
  351. edge of the analysis filter just catches the first non-zero
  352. input samples; output time is always T times input time. */
  353. outCount = 0;
  354. rIn = (float)(R/(float)D);
  355. rOut = (float)(R/(float)I);
  356. RoverTwoPi = (float)(rIn/TWOPI);
  357. TwoPioverR = (float)(TWOPI/rOut);
  358. nI = -(analWinLen / D) * D; /* input time (in samples) */
  359. nO = nI; /* output time (in samples) */
  360. Dd = analWinLen + nI + 1; /* number of new inputs to read */
  361. Ii = 0; /* number of new outputs to write */
  362. IOi = 0;
  363. flag = 1;
  364. /* main loop: If endsamp is not specified it is assumed to be very large
  365. and then readjusted when fgetfloat detects the end of input. */
  366. display_virtual_time(0L,dz);
  367. while(nI < (endsamp + analWinLen)){
  368. if (dz->process==PVOC_SYNTH){
  369. #ifdef SINGLE_SAMP
  370. for (i = 0; i < dz->iparam[PVOC_CHANS]+2; i++){ /* synthesis only */
  371. if ((rv = fgetfloat((anal+i),dz->ifd[0])) <= 0){
  372. goto epilog;
  373. }
  374. }
  375. #else
  376. // NEW 2014 -->
  377. memset((char *)anal,0,(dz->iparam[PVOC_CHANS]+2) * sizeof(float)); /* Ensure buffer is wiped, esp for empty buffers at process end */
  378. // <-- NEW 2014
  379. if((i = fgetfbufEx(anal, dz->iparam[PVOC_CHANS]+2, dz->ifd[0], 0)) < 0) {
  380. sfperror("pvoc: read error: ");
  381. return(SYSTEM_ERROR);
  382. }
  383. // NEW 2014 -->
  384. if(i < dz->iparam[PVOC_CHANS]+2) {
  385. finished = 1; // Finished reading input
  386. if(local_maxsample == 0.0) // Finished writing output
  387. goto epilog;
  388. }
  389. // <-- NEW 2014
  390. #endif
  391. } else { /* prepare for analysis: read next Dd input values */
  392. #ifdef SINGLE_SAMP
  393. for (i = 0; i < Dd; i++){
  394. if (fgetfloat(nextIn++,dz->ifd[0]) <= 0)
  395. Dd = i; /* EOF ? */
  396. if (nextIn >= (input + ibuflen))
  397. nextIn -= ibuflen;
  398. }
  399. #else
  400. {
  401. static float *sbuf = 0;
  402. static int sblen = 0;
  403. int got, tocp;
  404. float *sp;
  405. if(sblen < Dd) {
  406. if(sbuf != 0)
  407. free(sbuf);
  408. if((sbuf = (float *)malloc(Dd*sizeof(float))) == 0) {
  409. sprintf(errstr, "pvoc: can't allocate short buffer\n");
  410. return(MEMORY_ERROR);
  411. }
  412. sblen = Dd;
  413. }
  414. if((got = fgetfbufEx(sbuf, Dd, dz->ifd[0],0)) < 0) {
  415. sfperror("pvoc: read error");
  416. return(SYSTEM_ERROR);
  417. }
  418. if(got < Dd)
  419. Dd = got;
  420. sp = sbuf;
  421. tocp = min(got, input+ibuflen-nextIn);
  422. got -= tocp;
  423. while(tocp-- > 0)
  424. *nextIn++ = *sp++;
  425. if(got > 0) {
  426. nextIn -= ibuflen;
  427. while(got-- > 0)
  428. *nextIn++ = *sp++;
  429. }
  430. if (nextIn >= (input + ibuflen))
  431. nextIn -= ibuflen;
  432. }
  433. #endif
  434. if (nI > 0)
  435. for (i = Dd; i < D; i++){ /* zero fill at EOF */
  436. *(nextIn++) = 0.0f;
  437. if (nextIn >= (input + ibuflen))
  438. nextIn -= ibuflen;
  439. }
  440. /* analysis: The analysis subroutine computes the complex output at
  441. time n of (dz->iparam[PVOC_CHANS]/2 + 1) of the phase vocoder channels. It operates
  442. on input samples (n - analWinLen) thru (n + analWinLen) and
  443. expects to find these in input[(n +- analWinLen) mod ibuflen].
  444. It expects analWindow to point to the center of a
  445. symmetric window of length (2 * analWinLen +1). It is the
  446. responsibility of the main program to ensure that these values
  447. are correct! The results are returned in anal as succesive
  448. pairs of real and imaginary values for the lowest (dz->iparam[PVOC_CHANS]/2 + 1)
  449. channels. The subroutines fft and reals together implement
  450. one efficient FFT call for a real input sequence. */
  451. for (i = 0; i < dz->iparam[PVOC_CHANS]+2; i++)
  452. *(anal + i) = 0.0f; /*initialize*/
  453. j = (nI - analWinLen - 1 + ibuflen) % ibuflen; /*input pntr*/
  454. k = nI - analWinLen - 1; /*time shift*/
  455. while (k < 0)
  456. k += dz->iparam[PVOC_CHANS];
  457. k = k % dz->iparam[PVOC_CHANS];
  458. for (i = -analWinLen; i <= analWinLen; i++) {
  459. if (++j >= ibuflen)
  460. j -= ibuflen;
  461. if (++k >= dz->iparam[PVOC_CHANS])
  462. k -= dz->iparam[PVOC_CHANS];
  463. *(anal + k) += *(analWindow + i) * *(input + j);
  464. }
  465. if((exit_status = fft_(anal,banal,1,N2,1,-2))<0)
  466. return(exit_status);
  467. if((exit_status = reals_(anal,banal,N2,-2))<0)
  468. return(exit_status);
  469. /* conversion: The real and imaginary values in anal are converted to
  470. magnitude and angle-difference-per-second (assuming an
  471. intermediate sampling rate of rIn) and are returned in
  472. anal. */
  473. for(i=0,i0=anal,i1=anal+1,oi=oldInPhase; i <= N2; i++,i0+=2,i1+=2,oi++){
  474. real = *i0;
  475. imag = *i1;
  476. *i0 =(float) sqrt((double)(real * real + imag * imag));
  477. /* phase unwrapping */
  478. if (*i0 == 0.)
  479. angleDif = 0.0f;
  480. else {
  481. rratio = atan((double)imag/(double)real);
  482. if(real<0.0) {
  483. if(imag<0.0)
  484. rratio -= PI;
  485. else
  486. rratio += PI;
  487. }
  488. angleDif = (phase = (float)rratio) - *oi;
  489. *oi = phase;
  490. }
  491. if (angleDif > PI)
  492. angleDif = (float)(angleDif - TWOPI);
  493. if (angleDif < -PI)
  494. angleDif = (float)(angleDif + TWOPI);
  495. /* add in filter center freq.*/
  496. *i1 = angleDif * RoverTwoPi + ((float) i * F);
  497. }
  498. }
  499. /* if analysis only, write out interleaved instantaneous amplitudes
  500. and frequencies; otherwise perform resynthesis */
  501. if (dz->iparam[PVOC_ENVOUT_ONLY]) {
  502. #ifdef SINGLE_SAMP
  503. for (i=0; i <= N2; i++)
  504. fputfloat((env+i),dz->ofd);
  505. #else
  506. write_samps_pvoc(env, N2+1, dz);
  507. #endif
  508. } else if (dz->iparam[PVOC_MAGOUT_ONLY]) {
  509. #ifdef SINGLE_SAMP
  510. for (i=0; i <= N2; i++)
  511. fputfloat((anal + 2*i),dz->ofd);
  512. #else
  513. float *fp = anal;
  514. for (i=0; i <= N2; i++) {
  515. fputfloat(fp,dz->ofd);
  516. fp += 2;
  517. }
  518. #endif
  519. } else if (dz->iparam[PVOC_ANAL_ONLY]) {
  520. #ifdef SINGLE_SAMP
  521. for (i=0; i < dz->iparam[PVOC_CHANS]+2; i++)
  522. fputfloat((anal+i),dz->ofd);
  523. #else
  524. write_samps_pvoc(anal, dz->iparam[PVOC_CHANS]+2, dz);
  525. #endif
  526. } else { /* synthesis */
  527. if (dz->iparam[PVOC_PARTIAL_RESYNTH]){ /* zero out non-selected channels */
  528. for (i = 0; i < dz->iparam[PVOC_AF_PAIR_LO]; i++)
  529. *(anal+2*i) = 0.0f;
  530. for (i = dz->iparam[PVOC_AF_PAIR_HI]+1; i <= N2; i++)
  531. *(anal+2*i) = 0.0f;
  532. if (dz->iparam[PVOC_SELECTED_CHAN] == 1) {
  533. for (i = dz->iparam[PVOC_AF_PAIR_LO]; i <= dz->iparam[PVOC_AF_PAIR_HI]; i++) {
  534. if (i%2 == 0)
  535. *(anal+2*i) = 0.0f;
  536. }
  537. }
  538. if (dz->iparam[PVOC_SELECTED_CHAN] == 2) {
  539. for (i = dz->iparam[PVOC_AF_PAIR_LO]; i <= dz->iparam[PVOC_AF_PAIR_HI]; i++) {
  540. if (i%2 != 0)
  541. *(anal+2*i) = 0.0f;
  542. }
  543. }
  544. }
  545. /* reconversion: The magnitude and angle-difference-per-second in syn
  546. (assuming an intermediate sampling rate of rOut) are
  547. converted to real and imaginary values and are returned in syn.
  548. This automatically incorporates the proper phase scaling for
  549. time modifications. */
  550. if (NO <= dz->iparam[PVOC_CHANS]){
  551. for (i = 0; i < NO+2; i++)
  552. *(syn+i) = *(anal+i);
  553. }
  554. else {
  555. for (i = 0; i <= dz->iparam[PVOC_CHANS]+1; i++)
  556. *(syn+i) = *(anal+i);
  557. for (i = dz->iparam[PVOC_CHANS]+2; i < NO+2; i++)
  558. *(syn+i) = 0.0f;
  559. }
  560. for(i=0, i0=syn, i1=syn+1; i<= NO2; i++,i0+=2,i1+=2){
  561. mag = *i0;
  562. *(oldOutPhase + i) += *i1 - ((float) i * F);
  563. phase = *(oldOutPhase + i) * TwoPioverR;
  564. *i0 = (float)((double)mag * cos((double)phase));
  565. *i1 = (float)((double)mag * sin((double)phase));
  566. }
  567. /* synthesis: The synthesis subroutine uses the Weighted Overlap-Add
  568. technique to reconstruct the time-domain signal. The (dz->iparam[PVOC_CHANS]/2 + 1)
  569. phase vocoder channel outputs at time n are inverse Fourier
  570. transformed, windowed, and added into the output array. The
  571. subroutine thinks of output as a shift register in which
  572. locations are referenced modulo obuflen. Therefore, the main
  573. program must take care to zero each location which it "shifts"
  574. out (to standard output). The subroutines reals and fft
  575. together perform an efficient inverse FFT. */
  576. if((exit_status = reals_(syn,bsyn,NO2,2))<0)
  577. return(exit_status);
  578. if((exit_status = fft_(syn,bsyn,1,NO2,1,2))<0)
  579. return(exit_status);
  580. j = nO - synWinLen - 1;
  581. while (j < 0)
  582. j += obuflen;
  583. j = j % obuflen;
  584. k = nO - synWinLen - 1;
  585. while (k < 0)
  586. k += NO;
  587. k = k % NO;
  588. for (i = -synWinLen; i <= synWinLen; i++) { /*overlap-add*/
  589. if (++j >= obuflen)
  590. j -= obuflen;
  591. if (++k >= NO)
  592. k -= NO;
  593. *(output + j) += *(syn + k) * *(synWindow + i);
  594. }
  595. #ifdef SINGLE_SAMP
  596. for (i = 0; i < IOi; i++){ /* shift out next IOi values */
  597. fputfloat(nextOut,dz->ofd);
  598. *(nextOut++) = 0.;
  599. if (nextOut >= (output + obuflen))
  600. nextOut -= obuflen;
  601. outCount++;
  602. }
  603. #else
  604. for (i = 0; i < IOi;){ /* shift out next IOi values */
  605. int j;
  606. int todo = min(IOi-i, output+obuflen-nextOut);
  607. // NEW 2014 -->
  608. if((exit_status = outfloats(nextOut,&maxsample,&minsample,&local_maxsample,&num_overflows,todo,finished,dz))<0)
  609. return(exit_status);
  610. // <-- NEW 2014
  611. i += todo;
  612. outCount += todo;
  613. for(j = 0; j < todo; j++)
  614. *nextOut++ = 0.0f;
  615. if (nextOut >= (output + obuflen))
  616. nextOut -= obuflen;
  617. }
  618. #endif
  619. }
  620. if(flag /* flag means do this operation only once */
  621. && (nI > 0) && (Dd < D)){ /* EOF detected */
  622. flag = 0;
  623. endsamp = nI + analWinLen - (D - Dd);
  624. }
  625. nI += D; /* increment time */
  626. nO += IO;
  627. /* Dd = D except when the end of the sample stream intervenes */
  628. Dd = min(D, max(0, D+endsamp-nI-analWinLen));
  629. if (nO > (synWinLen + I))
  630. Ii = I;
  631. else if (nO > synWinLen)
  632. Ii = nO - synWinLen;
  633. else {
  634. Ii = 0;
  635. for (i=nO+synWinLen; i<obuflen; i++) {
  636. if (i > 0)
  637. *(output+i) = 0.0f;
  638. }
  639. }
  640. IOi = Ii;
  641. if(nI > samptime && (exit_status = pvoc_time_display(nI,isr,&samptime,dz))<0)
  642. return(exit_status);
  643. } /* End of main while loop */
  644. if(!dz->iparam[PVOC_ANAL_ONLY]) {
  645. nMaxOut = endsamp;
  646. while (outCount <= nMaxOut){
  647. #ifdef SINGLE_SAMP
  648. outCount++;
  649. fputfloat(nextOut++,dz->ofd);
  650. if (nextOut >= (output + obuflen))
  651. nextOut -= obuflen;
  652. #else
  653. int todo = min(nMaxOut-outCount, output+obuflen-nextOut);
  654. if(todo == 0)
  655. break;
  656. // NEW 2014 -->
  657. if((exit_status = outfloats(nextOut,&maxsample,&minsample,&local_maxsample,&num_overflows,todo,finished,dz))<0)
  658. return(exit_status);
  659. // <-- NEW 2014
  660. outCount += todo;
  661. nextOut += todo;
  662. if (nextOut >= (output + obuflen))
  663. nextOut -= obuflen;
  664. #endif
  665. }
  666. if((exit_status = pvoc_time_display((int)endsamp,isr,&samptime,dz))<0)
  667. return(exit_status);
  668. }
  669. epilog:
  670. #ifndef NOOVERCHK
  671. if(num_overflows > 0) {
  672. biggest = maxsample;
  673. if(-minsample > maxsample)
  674. biggest = -minsample;
  675. fprintf(stdout, "WARNING: %d samples overflowed, and were clipped\n",num_overflows);
  676. fprintf(stdout, "WARNING: maximum sample was %f : minimum sample was %f\n",maxsample,minsample);
  677. fprintf(stdout, "WARNING: You should reduce source level to avoid clipping: use gain of <= %lf\n",1.0/biggest);
  678. fflush(stdout);
  679. }
  680. #endif
  681. return(FINISHED);
  682. }
  683. /*MCA
  684. * Convert floats -> shorts explicitly, since we are compiled with
  685. * hardware FP(probably), and the sound filing system is not!
  686. * (even without this, it should be more efficient!)
  687. */
  688. // NEW 2014 -->
  689. int outfloats(float *nextOut,float *maxsample,float *minsample,float *local_maxsample,int *num_overflows,int todo,int finished,dataptr dz)
  690. {
  691. static float *sbuf = 0;
  692. static int sblen = 0;
  693. float *sp;
  694. int cnt;
  695. float val;
  696. float local_minsample = 0.0;
  697. *local_maxsample = 0.0;
  698. if(sblen < todo) {
  699. if(sbuf != 0)
  700. free(sbuf);
  701. if((sbuf = (float *)malloc(todo*sizeof(float))) == 0) {
  702. sprintf(errstr, "pvoc: can't allocate output buffer\n");
  703. return(MEMORY_ERROR);
  704. }
  705. sblen = todo;
  706. }
  707. sp = sbuf;
  708. #ifdef NOOVERCHK
  709. for(cnt = 0; cnt < todo; cnt++)
  710. *sp++ = *nextOut++;
  711. #else
  712. for(cnt = 0; cnt < todo; cnt++) {
  713. val = *nextOut++;
  714. if(val >= 1.0 || val <= -1.0) {
  715. (*num_overflows)++;
  716. if(val > 0.0f) {
  717. if(val > *maxsample)
  718. *maxsample = val;
  719. val = 1.0f;
  720. }
  721. if(val < 0.0f) {
  722. if(val < *minsample)
  723. *minsample = val;
  724. val = -1.0f;
  725. }
  726. }
  727. *sp = val;
  728. if(*sp > *local_maxsample)
  729. *local_maxsample = val;
  730. if(*sp < local_minsample)
  731. local_minsample = val;
  732. sp++;
  733. }
  734. #endif
  735. *local_maxsample = max(-local_minsample,*local_maxsample);
  736. if(finished && (*local_maxsample == 0.0)) // Input read finished && Output buffer empty
  737. todo = 0;
  738. if(todo > 0) {
  739. if(write_samps_pvoc(sbuf, todo, dz) < 0) {
  740. sfperror("pvoc: write error");
  741. return(SYSTEM_ERROR);
  742. }
  743. }
  744. return(FINISHED);
  745. // <-- NEW 2014
  746. }
  747. /************************************ SNDWRITE_HEADER ************************************/
  748. int sndwrite_header(int N2,int *Nchans,float *arate,float R,int D,int origsize,int *isr,int M,dataptr dz)
  749. {
  750. if (dz->iparam[PVOC_ANAL_ONLY]){
  751. if (dz->iparam[PVOC_ENVOUT_ONLY] || dz->iparam[PVOC_MAGOUT_ONLY]){
  752. *Nchans = N2 + 1;
  753. if(sndputprop(dz->ofd,"blocksize",(char *)Nchans,sizeof(int)) < 0 )
  754. fprintf(stdout,"WARNING: pvoc failed to write bloksize data\n");
  755. *arate = (float)((float)(*Nchans)*R/(float)D);
  756. } else {
  757. *Nchans = dz->iparam[PVOC_CHANS] + 2;
  758. dz->outfile->channels = *Nchans;
  759. *arate = (float)(R/(float)D);
  760. }
  761. dz->outfile->srate = (int)(*arate);
  762. dz->outfile->arate = *arate;
  763. dz->outfile->origstype = origsize;
  764. dz->outfile->origrate = *isr;
  765. dz->outfile->Mlen = M;
  766. dz->outfile->Dfac = D;
  767. } else { /* Synthesis */
  768. *isr = (int)R;
  769. dz->outfile->srate = *isr;
  770. *Nchans = 1;
  771. dz->outfile->channels = *Nchans;
  772. }
  773. fflush(stdout);
  774. return(FINISHED);
  775. }
  776. /****************************** PVOC_PREPROCESS ******************************/
  777. int pvoc_preprocess(dataptr dz)
  778. {
  779. int ampfrqpair_cnt;
  780. dz->iparam[PVOC_ENVOUT_ONLY] = FALSE;
  781. dz->iparam[PVOC_MAGOUT_ONLY] = FALSE;
  782. dz->iparam[PVOC_ANAL_ONLY] = FALSE;
  783. switch(dz->process) {
  784. case(PVOC_ANAL):
  785. dz->iparam[PVOC_CHANS] = dz->iparam[PVOC_CHANS_INPUT];
  786. dz->iparam[PVOC_WIN_OVERLAP] = dz->iparam[PVOC_WINOVLP_INPUT]-1;
  787. switch(dz->mode) {
  788. case(STANDARD_ANAL): dz->iparam[PVOC_ANAL_ONLY] = TRUE; break;
  789. case(ENVEL_ONLY): dz->iparam[PVOC_ANAL_ONLY] = TRUE; dz->iparam[PVOC_ENVOUT_ONLY] = TRUE; break;
  790. case(MAG_ONLY): dz->iparam[PVOC_ANAL_ONLY] = TRUE; dz->iparam[PVOC_MAGOUT_ONLY] = TRUE; break;
  791. default:
  792. sprintf(errstr,"Unknown mode in pvoc_preprocess()\n");
  793. return(PROGRAM_ERROR);
  794. }
  795. break;
  796. case(PVOC_SYNTH):
  797. dz->iparam[PVOC_CHANS] = dz->infile->channels - 2;
  798. /*RWD need this! */
  799. dz->iparam[PVOC_PARTIAL_RESYNTH] = FALSE;
  800. break;
  801. case(PVOC_EXTRACT):
  802. dz->iparam[PVOC_CHANS] = dz->iparam[PVOC_CHANS_INPUT];
  803. ampfrqpair_cnt = dz->iparam[PVOC_CHANS]/2;
  804. dz->iparam[PVOC_WIN_OVERLAP] = dz->iparam[PVOC_WINOVLP_INPUT]-1;
  805. if(dz->iparam[PVOC_CHANSLCT_INPUT]) {
  806. dz->iparam[PVOC_SELECTED_CHAN] = dz->iparam[PVOC_CHANSLCT_INPUT];
  807. dz->iparam[PVOC_PARTIAL_RESYNTH] = TRUE;
  808. }
  809. dz->iparam[PVOC_AF_PAIR_LO] = 0;
  810. if(dz->iparam[PVOC_LOCHAN_INPUT] > 0) {
  811. dz->iparam[PVOC_AF_PAIR_LO] = min(dz->iparam[PVOC_LOCHAN_INPUT],ampfrqpair_cnt);
  812. dz->iparam[PVOC_PARTIAL_RESYNTH] = TRUE;
  813. }
  814. dz->iparam[PVOC_AF_PAIR_HI] = ampfrqpair_cnt;
  815. if(dz->iparam[PVOC_HICHAN_INPUT] > 0) {
  816. dz->iparam[PVOC_AF_PAIR_HI] = min(dz->iparam[PVOC_HICHAN_INPUT],ampfrqpair_cnt);
  817. dz->iparam[PVOC_PARTIAL_RESYNTH] = TRUE;
  818. }
  819. if((dz->iparam[PVOC_CHANSLCT_INPUT] == 0) && (dz->iparam[PVOC_LOCHAN_INPUT] == 0)
  820. && (dz->iparam[PVOC_HICHAN_INPUT] == 0)) {
  821. sprintf(errstr,"As no channels have been selected, output sound would be the same as the input.\n");
  822. return(DATA_ERROR);
  823. }
  824. break;
  825. default:
  826. sprintf(errstr,"Unknown process in pvoc_preprocess()\n");
  827. return(PROGRAM_ERROR);
  828. }
  829. /* Force PVOC_CHANS to be even */
  830. dz->iparam[PVOC_CHANS] = dz->iparam[PVOC_CHANS] + (dz->iparam[PVOC_CHANS]%2);
  831. return(FINISHED);
  832. }
  833. /*********************************** PVOC_TIME_DISPLAY ***********************************/
  834. int pvoc_time_display(int nI,int srate,int *samptime,dataptr dz)
  835. {
  836. int true_chans, true_srate;
  837. int true_outfiletype;
  838. switch(dz->process) {
  839. case(PVOC_ANAL):
  840. true_outfiletype = dz->outfiletype;
  841. dz->outfiletype = SNDFILE_OUT;
  842. display_virtual_time(nI,dz);
  843. dz->outfiletype = true_outfiletype;
  844. break;
  845. case(PVOC_SYNTH):
  846. true_chans = dz->infile->channels;
  847. true_srate = dz->infile->srate;
  848. dz->infile->channels = 1;
  849. dz->infile->srate = srate;
  850. display_virtual_time(nI,dz);
  851. dz->infile->channels = true_chans;
  852. dz->infile->srate = true_srate;
  853. break;
  854. case(PVOC_EXTRACT):
  855. display_virtual_time(nI,dz);
  856. break;
  857. default:
  858. sprintf(errstr,"Unknown process in pvoc_time_display()\n");
  859. return(PROGRAM_ERROR);
  860. }
  861. *samptime += SAMP_TIME_STEP;
  862. return(FINISHED);
  863. }
  864. /******************************* WRITE_SAMPS_PVOC ********************************/
  865. int write_samps_pvoc(float *bbuf,int samps_to_write,dataptr dz)
  866. {
  867. int samps_written;
  868. int i,j;
  869. int granularity = 22100;
  870. int this_granularity = 0;
  871. float val;
  872. if(dz->needpeaks){
  873. for(i=0;i < samps_to_write; i += dz->outchans){
  874. for(j = 0;j < dz->outchans;j++){
  875. val = (float)fabs(bbuf[i+j]);
  876. /* this way, posiiton of first peak value is stored */
  877. if(val > dz->outpeaks[j].value){
  878. dz->outpeaks[j].value = val;
  879. dz->outpeaks[j].position = dz->outpeakpos[j];
  880. }
  881. }
  882. /* count framepos */
  883. for(j=0;j < dz->outchans;j++)
  884. dz->outpeakpos[j]++;
  885. }
  886. }
  887. if((samps_written = fputfbufEx(bbuf,samps_to_write,dz->ofd))<=0) {
  888. sprintf(errstr,"Can't write to output soundfile: %s\n",sferrstr());
  889. return(SYSTEM_ERROR);
  890. }
  891. dz->total_samps_written += samps_written;
  892. this_granularity += samps_to_write;
  893. if(this_granularity > granularity){
  894. display_virtual_time(dz->total_samps_written,dz);
  895. this_granularity -= granularity;
  896. }
  897. return(FINISHED);
  898. }