1 /*
2 	SuperCollider real time audio synthesis system
3  Copyright (c) 2002 James McCartney. All rights reserved.
4 	http://www.audiosynth.com
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program 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 General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19  */
20 
21 //Spectral Modeling Synthesis plugin
22 
23 //no use of chain since must create multiple internal FFTs
24 //cross synthesis could come later if can abstract out components of analysis into multiple UGens; too dangerous for now, test all in one place
25 //must accept defaults hard coded, ie 1024 fft size, 256 hop
26 //SMS.ar(maxpeaks=80, currentpeaks, tolerance=4, noisefloor= 0.2, freqmult=1.0, noiseprop=0.5)
27 
28 //need to try debugger
29 //http://lists.create.ucsb.edu/pipermail/sc-dev/2003-October/005103.html
30 //Shark profiler?
31 
32 //DEVELOPMENT NOTES:
33 //SOLVED- AHA! both deterministic synthesis routines simultaneous and sharing phase variable!
34 //TRIED, not any better: sine detection windowing from Kaiser Bessel/Blackman Harris window as most refined (see Harris windows paper)
35 //test scale factor on FFT + IFFT via Green's code: SCALE FACTOR is 1 for fft->ifft chain
36 //any scale factor for sinusoidal resynthesis? factor of N larger at FFT output (N/2 outside dc/nyquist); windowing reduces further (by -6 dB or so? windows necessarily remove power from signals)!
37 //cos function put through it, or just white noise
38 //for spectral interpolation would like zero padding!
39 
40 
41 //initial delay = framesize - hopsize
42 //newframedelay = hopsize
43 //amortise delay = hopsize
44 //total delay to output is framesize+hopsize
45 
46 
47 
48 #include "NCAnalysis.h"
49 #include <stdio.h>
50 
51 //#include "FFT_UGens.h"
52 //
53 //#include "SC_PlugIn.h"
54 //#include "SC_Constants.h"
55 //
56 //#include <string.h>
57 //#include <math.h>
58 
59 //
60 
61 //extern "C"
62 //{
63 //	//void load(InterfaceTable *inTable);
64 //
65 //	//Requires C linking
66 //	#include "fftlib.h"
67 //}
68 
69 //
70 //InterfaceTable *ft;
71 
72 
73 //blackman92fft[]= {-2.990080, -0.000001, 36.167683, 0.000001, -125.002235, 0.000002, 183.679993, -0.000001, -125.002228, 0.000000, 36.167679, 0.000000, -2.990080 }
74 //these are results of cosine(10*w)*window and show real coefficients only (all imag are 0 due to even input)
75 float g_blackman92fft[7]= {-2.990080, 36.167683, -125.002235, 183.679993, -125.002228, 36.167679, -2.990080 };
76 
77 float g_blackman92window[1024]; //created in loadSMS()
78 //BOTH of these assume 1024 window, no zero padding
79 
80 //will calculate output as A/2 * exp(i phase) * coeff over real and imag bin components centred on frequency (freq1+freq2)*0.5 at blackman[3]
81 
82 
83 
84 
85 
86 //SndBuf is too full a construct with fields I don't need. Just need an indication of whether rectangular or polar; but then, will know this anyway!
ToPolarApx2(float * buf,int windowsize=1024)87 SCPolarBuf* ToPolarApx2(float* buf, int windowsize=1024)
88 {
89 	//assumes it already is complex format
90 	//if (buf->coord == coord_Complex) {
91 		SCComplexBuf* p = (SCComplexBuf*)buf;
92 		int numbins = (windowsize - 2) >> 1;
93 		for (int i=0; i<numbins; ++i) {
94 			p->bin[i].ToPolarApxInPlace();
95 		}
96 		//buf->coord = coord_Polar;
97 	//}
98 	return (SCPolarBuf*)buf; //->data;
99 }
100 
ToComplexApx2(float * buf,int windowsize=1024)101 SCComplexBuf* ToComplexApx2(float *buf, int windowsize=1024)
102 {
103 	//if (buf->coord == coord_Polar) {
104 		SCPolarBuf* p = (SCPolarBuf*)buf; //->data;
105 		int numbins = (windowsize - 2) >> 1;
106 		for (int i=0; i<numbins; ++i) {
107 			p->bin[i].ToComplexApxInPlace();
108 		}
109 		//buf->coord = coord_Complex;
110 	//}
111 	return (SCComplexBuf*)buf;
112 }
113 
114 //
115 //void init_SCComplex(InterfaceTable *inTable);
116 
117 //
118 ////too much hassle, not compatible with runtime requirements (problem with new and delete, would want to make a global object and allocate on load)
119 ////wrapper for platform specific fft implementation details, doesn't use existing buffer, internal UGen use only?
120 ////class FFTAssist {
121 //
122 //FFTAssist(int n);
123 //~FFTAssist();
124 //
125 //fft(float *);
126 //ifft(float *);
127 //};
128 
129 
130 //const int g_maxpeaks = 80;
131 
132 //not used currently
133 //const int g_maxsleep=3;
134 
135 //phases not interpolated, just linear increment of running phase over guide's life
136 struct Guide {
137 	float phase1, phase2; //two phase variables required- in general, one for each resynthesis required!
138 	float amp1, amp2, freq1, freq2;
139 	//not using for now
140 	//int status; //alive 0 sleeping 1+ for number of steps asleep
141 
142 };
143 
144 //no phase stored now
145 struct Peak {
146 	float mag, freq, phase;
147 };
148 
149 
150 
151 //overlap add for output requires storage of sample data for last x frames and resynthesis
152 
153 
154 //no zero padding to start with but option for later?
155 //will support FFT size of 1024 with hop size of 256
156 
157 
158 //static float g_GreenCosTable[257]; //cosTable for 1024 point FFT for Green FFT
159 //static float g_HannTable[1024]; //fixed von Hann window for now
160 static float g_fade[512]; //fixed size for now
161 
162 //for sine based resynthesis
163 const int g_costablesize=1024; //large so truncation error not too bad (see Moore book)
164 float g_costable[g_costablesize+1]; //extra value for wraparound linear interpolation calculations
165 
166 
167 struct SMS : Unit {
168 
169 	//final list of peaks is size at most numpeaks(n) + numpeaks(n+1). reasonably around max of the two.
170 	//as long as have birth and death resolved for each peak in the two lists, can synthesise up to curent frame. So output latency is one FFT frame
171 
172 	int m_sr;
173 	int m_blocksize;
174 
175 	float * buf; //for passing sines+noise data to a graphics object
176 	float * m_inputbuffer;
177 	int m_inputpos;
178 
179 	//will be using Green transform which is in place and requires auxilliary cos table data
180 	//make cos table data when plugin loaded
181 	//will be using a variant of ToComplexApx functions, since don't want to store buf->coord and will know what state each buffer is in
182 	//////////FFT data
183 	//int m_fftsize; //no zero padding
184 	int m_windowsize;		//1024
185 	int m_hopsize;			//256
186 	int m_shuntsize;		//768
187 	int m_overlapfactor;	//4
188 	int m_nover2;			//512
189 	int m_nover4;			//256
190 	int m_log2n;			//10
191 
192 	//SC FFT variables
193 	//float* m_transformbuf;
194 	scfft* m_scfftinput;
195 	scfft* m_scfftresynth;
196 	scfft* m_scifft;
197 	float* m_q;
198 
199 	scfft* m_scifftresynth1;
200 	float * resynth1;
201 
202 	int m_useifft;
203 	float m_ampmult;
204 
205 	//ready for transform
206 	float * m_inplace;
207 
208 	//store last magnitude spectrum calculated
209 	float * m_magspectrum;
210 
211 	//512 samples in each for crossfade in and out via triangular envelopes
212 	float * m_outputold; //fades out
213 	float * m_outputnew; //fades in
214 
215 	//independent buffers for sines and noise signal
216 	float * m_outputoldnoise; //fades out
217 	float * m_outputnewnoise; //fades in
218 	int m_outputpos;
219 
220 	//1024 samples worth
221 	float * m_straightresynthesis;
222 	//512 samples worth
223 	float * m_deterministicresynthesis;
224 	int m_straightpos, m_deterministicpos;
225 	//synthesised noise can be added onto
226 
227 	//frequency multiplication
228 	float m_freqmult, m_freqadd;
229 	Guide * m_tracks2; //adjusted tracks for formant preservation, only calculated as necessary
230 	int m_formantpreserve; //whether using alternative formant preserving track data or not
231 	////////
232 
233 
234 	//or for each partial to be rendered persistent data for rendering need phasek, angfreqk (omegak), alphak, betak as per (37)
235 	Guide * m_tracks; //space for double maxpeaks if all birth and die at once!
236 	int m_numtracks;
237 
238 	int m_maxpeaks;
239 
240 	//use buffer swapping of pointer as needed
241 	Peak * m_prevpeaks;
242 	Peak * m_newpeaks;
243 	int m_numprevpeaks;
244 	int m_numnewpeaks;
245 
246 	//keep track of how many samples resynthesised in current run
247 	//int m_resynthesisposition;
248 
249 
250 	//not sure how many steps to take yet
251 	//float * m_noiseEnvelope;
252 	//easiest if just have hop of half N, overlapfactor of 2
253 	//number depends on overlapfactor
254 	//for overlapfactor4, just synthesise half of N in output
255 	//so only ever two active at once
256 	//float ** m_outputframe;
257 	//int outputframecounter;
258 
259 };
260 
261 
262 
263 
264 
265 extern "C"
266 {
267 	//required interface functions
268 	void SMS_next(SMS *unit, int wrongNumSamples);
269 	void SMS_Ctor(SMS *unit);
270 	void SMS_Dtor(SMS *unit);
271 }
272 
273 
274 
275 
276 //void calculatefeatures(SMS *unit, int ibufnum);
277 
278 //calculate by summing
279 //void oscillatorbankresynthesis(SMS *unit, int numsamples);
280 //void peakmatch(SMS *unit);
281 //void newframe(SMS* unit, int ibufnum);
282 void peakmatching(SMS * unit);
283 void peakdetection(SMS * unit, float * magspectrum, SCPolarBuf *p);
284 void newinputframe(SMS * unit, float * inputbuffer);
285 //void synthesisedeterministic(SMS * unit, float * output, int number,int& pos, int total, float mult, int which);
286 void synthesisedeterministic(SMS * unit, float * output, int number,int& pos, int total, Guide * tracks);
287 void synthesisestochastic(SMS * unit);
288 void formantpreserve(SMS * unit, float freqmult);
289 void ifftsines(SMS * unit, float * output, int number,int& pos, int total, Guide * tracks);
290 void graphicsbuffer(SMS * unit, Guide * tracks);
291 
SMS_Ctor(SMS * unit)292 void SMS_Ctor(SMS* unit) {
293 
294 	int j; //i,j;
295 
296 
297 	//CHECK SAMPLING RATE AND BUFFER SIZE
298 	unit->m_blocksize = unit->mWorld->mFullRate.mBufLength;
299 
300 	if(unit->m_blocksize!=64) {
301 		printf("SMS complains: block size not 64, you have %d\n", unit->m_blocksize);
302 		SETCALC(*ClearUnitOutputs);
303 		unit->mDone = true;
304 		return;
305 	}
306 
307 	unit->m_sr = unit->mWorld->mSampleRate;
308 
309 	if(unit->m_sr!=44100) {
310 	printf("SMS complains: sample rate not 44100, you have %d\n", unit->m_sr);
311 	SETCALC(*ClearUnitOutputs);
312 	unit->mDone = true;
313 	return;
314 	}
315 
316 
317 	unit->m_windowsize=1024;
318 	unit->m_hopsize=256;
319 	unit->m_shuntsize=768;
320 	unit->m_overlapfactor=4;
321 	unit->m_nover2=512;
322 	unit->m_nover4=256;
323 	unit->m_log2n = 10; //LOG2CEIL(unit->m_windowsize);
324 
325 	//no choices allowed on FFt size for the moment
326 	//assumption for now is that FFT size and hop rate match the temporal window size and hop rate
327 	//unit->m_windowsize=(int)(ZIN0(1)); //defaults for now, may have to set as options later
328 	//unit->m_hopsize=(int)(ZIN0(2));
329 	//unit->m_nover2=unit->m_windowsize/2;
330 
331 
332 
333 	//unit->tcache=  (float*)RTAlloc(unit->mWorld, unit->m_hopsize * sizeof(float));
334 
335 	//printf("another check: windowsize %d hopsize %d \n", unit->m_windowsize, unit->m_hopsize);
336 
337 	unit->m_inputbuffer = (float*)RTAlloc(unit->mWorld, unit->m_windowsize * sizeof(float));
338 	unit->m_inputpos = 0;
339 	unit->m_inplace = (float*)RTAlloc(unit->mWorld, unit->m_windowsize * sizeof(float));
340 
341 	//ignoring dc and nyquist I assume? No, need them to carry through for differencing
342 	unit->m_magspectrum =  (float*)RTAlloc(unit->mWorld, (unit->m_nover2+1) * sizeof(float));
343 
344 	unit->m_outputold = (float*)RTAlloc(unit->mWorld, (unit->m_nover2) * sizeof(float));
345 	unit->m_outputnew= (float*)RTAlloc(unit->mWorld, (unit->m_nover2) * sizeof(float));
346 	unit->m_outputpos=0;
347 
348 	unit->m_outputoldnoise = (float*)RTAlloc(unit->mWorld, (unit->m_nover2) * sizeof(float));
349 	unit->m_outputnewnoise= (float*)RTAlloc(unit->mWorld, (unit->m_nover2) * sizeof(float));
350 
351     for(int i=0; i<unit->m_nover2; ++i) {
352         unit->m_outputold[i] = 0.f;
353         unit->m_outputnew[i] = 0.f;
354         unit->m_outputoldnoise[i] = 0.f;
355         unit->m_outputnewnoise[i] = 0.f;
356     }
357 
358 
359 	//1024 samples worth
360 	unit->m_straightresynthesis=(float*)RTAlloc(unit->mWorld, unit->m_windowsize * sizeof(float));
361 	//double hopsize samples worth
362 	unit->m_deterministicresynthesis=(float*)RTAlloc(unit->mWorld, (unit->m_nover2) * sizeof(float));
363 
364 	//two forwards and one inverse FFT
365 
366 	//rffts(resynthesis, unit->m_log2n, 1, g_GreenCosTable);
367 	//inputbuffer is unit->m_inplace
368 	//rffts(inputbuffer, unit->m_log2n, 1, g_GreenCosTable);
369 	//riffts(q, unit->m_log2n, 1, g_GreenCosTable);
370 
371 	//unit->m_transformbuf = (float*)RTAlloc(unit->mWorld, scfft_trbufsize(unit->m_windowsize));
372 
373     SCWorld_Allocator alloc(ft, unit->mWorld);
374 
375     unit->m_scfftinput = scfft_create(unit->m_windowsize, unit->m_windowsize, kHannWindow, unit->m_inplace, unit->m_inplace, kForward, alloc);
376 
377     unit->m_scfftresynth = scfft_create(unit->m_windowsize, unit->m_windowsize, kHannWindow, unit->m_straightresynthesis, unit->m_straightresynthesis, kForward, alloc);
378 
379     unit->m_scifft = scfft_create(unit->m_windowsize, unit->m_windowsize, kRectWindow, unit->m_straightresynthesis, unit->m_inplace, kBackward, alloc);
380 
381 //	unit->m_scfftinput = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
382 //	unit->m_scfftresynth = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
383 //	unit->m_scifft = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
384 //
385 //	//scfft, input size, window size, window type, in, out, transfer, forwards flag
386 //	scfft_create(unit->m_scfftinput, unit->m_windowsize, unit->m_windowsize, WINDOW_HANN, unit->m_inplace, unit->m_inplace, unit->m_transformbuf, true);
387 //	//should be WINDOW_RECT or WINDOW_HANN? WINDOW_HANN because comparing FFT of resynthesis to original magnitude spectrum, so both must have same windowing, see Fig 1 in CMJ 14(4): p.14
388 //	//scfft_create(unit->m_scfftresynth, unit->m_windowsize, unit->m_windowsize, WINDOW_RECT, unit->m_straightresynthesis, unit->m_straightresynthesis, unit->m_transformbuf, true);
389 //	scfft_create(unit->m_scfftresynth, unit->m_windowsize, unit->m_windowsize, WINDOW_HANN, unit->m_straightresynthesis, unit->m_straightresynthesis, unit->m_transformbuf, true);
390 //	//scfft_create(unit->m_scifft, unit->m_windowsize, unit->m_windowsize, WINDOW_RECT, unit->m_q, unit->m_q, unit->m_transformbuf, false);
391 //	scfft_create(unit->m_scifft, unit->m_windowsize, unit->m_windowsize, WINDOW_RECT, unit->m_straightresynthesis, unit->m_inplace, unit->m_transformbuf, false);
392 
393     unit->resynth1= (float*)RTAlloc(unit->mWorld, (unit->m_windowsize) * sizeof(float));
394     unit->m_scifftresynth1= scfft_create(unit->m_windowsize, unit->m_windowsize, kRectWindow, unit->resynth1, unit->resynth1, kBackward, alloc);
395 
396 
397 //	scfft_create(unit->m_scifftresynth1, unit->m_windowsize, unit->m_windowsize, WINDOW_RECT, unit->resynth1, unit->resynth1, unit->m_transformbuf, false);
398 
399 	float * ifftsum= unit->resynth1;
400 	for (j=0; j<unit->m_windowsize; ++j)
401 		ifftsum[j]=0.0;
402 
403 	unit->m_useifft = (int)ZIN0(8);
404 
405 	unit->m_straightpos=0;
406 	unit->m_deterministicpos=0;
407 
408 	float * resynth= unit->m_straightresynthesis;
409 
410 	//zero these buffers
411 	for (j=0; j<unit->m_windowsize; ++j)
412 	resynth[j]=0.0;
413 
414 	resynth= unit->m_deterministicresynthesis;
415 
416 	//2 times hopsize
417 	for (j=0; j<unit->m_nover2; ++j)
418 	resynth[j]=0.0;
419 
420 	//for (j=0; j<numSamples; ++j) {
421 //		inputbuffer[pos++] = 0.0; //in[j]; //post increment returns previous?
422 //	}
423 
424 
425 	unit->m_ampmult= 2.0*ZIN0(9)/((float)unit->m_windowsize); //compensatio for half components (should be except at dc/nyquist)
426 
427 	unit->m_maxpeaks=(int)ZIN0(1);
428 	//int m_maxlistsize; //double m_maxpeaks
429 
430     //no LocalBuf support for graphics buffer since communicating back to language
431 
432 	float fbufnum = ZIN0(10);
433 	//if (bufnum >= world->mNumSndBufs) bufnum = 0;
434 	World * world = unit->mWorld;
435 
436 	//printf("fbufnum %f int %d \n",fbufnum, (int)fbufnum);
437 
438 	if(fbufnum>=0.f){
439 
440 		int bufnum= (int)fbufnum;
441 
442 	if(0<=bufnum<= world->mNumSndBufs) {
443 		SndBuf * buf;
444 
445 		buf = world->mSndBufs + bufnum;
446 		//unit->mBufNum=bufnum;
447 		//printf("%d \n",bufnum);
448 		//unit->mBufSize = buf->samples;
449 		unit->buf= buf->data; //(float*)RTAlloc(unit->mWorld, unit->mBufSize * sizeof(float));
450 							  //
451 							  //		} else {
452 							  //			if(world->mVerbosity > -1){ Print("SLUGens buffer number error: invalid buffer number: %i.\n", bufnum); }
453 							  //			SETCALC(*ClearUnitOutputs);
454 							  //			unit->mDone = true;
455 							  //			return NULL;
456 							  //		}
457 
458 		//must be enough room for current peak count integer, up to max number of sine peaks*2, and a mag spectrum for the noise
459 		if(buf->samples<(unit->m_maxpeaks*10 + unit->m_nover2+1+1)) {
460 			Print("buffer not large enough %i.\n", buf->samples);
461 		SETCALC(*ClearUnitOutputs);
462 		unit->mDone = true;
463 		//return NULL;
464 		}
465 
466 buf->data[0]= 0; //start with no trails to paint
467 
468 	} else {
469 		unit->buf=NULL;
470 	}
471 
472 } else
473 {
474 		unit->buf=NULL;
475 }
476 
477 
478 
479 
480 
481 
482 	unit->m_tracks= (Guide*)RTAlloc(unit->mWorld, 2*unit->m_maxpeaks * sizeof(Guide));
483 
484 	//use buffer swapping of pointer as needed
485 	unit->m_prevpeaks = (Peak*)RTAlloc(unit->mWorld, unit->m_maxpeaks * sizeof(Peak));
486 	unit->m_newpeaks=(Peak*)RTAlloc(unit->mWorld, unit->m_maxpeaks * sizeof(Peak));
487 
488 	//no need to initialise these arrays since filled as needed
489 
490 	unit->m_numprevpeaks =0;
491 	unit->m_numnewpeaks =0;
492 	unit->m_numtracks=0;
493 	//unit->m_resynthesisposition=0;
494 
495 	//formant preservation test
496 	unit->m_freqmult=1.0;
497 	unit->m_freqadd=0.0;
498 	unit->m_formantpreserve=0;
499 	unit->m_tracks2= (Guide*)RTAlloc(unit->mWorld, 2*unit->m_maxpeaks * sizeof(Guide));
500 
501 
502 	//SETCALC(*ClearUnitOutputs);
503 	unit->mCalcFunc = (UnitCalcFunc)&SMS_next;
504 
505 	//printf("Made it to here at least! %d\n", unit->m_sr);
506 
507 }
508 
509 
510 
SMS_Dtor(SMS * unit)511 void SMS_Dtor(SMS *unit)
512 {
513 
514 
515     RTFree(unit->mWorld, unit->m_tracks2);
516 
517 	RTFree(unit->mWorld, unit->m_tracks);
518 	RTFree(unit->mWorld, unit->m_prevpeaks);
519 	RTFree(unit->mWorld, unit->m_newpeaks);
520 
521 	//RTFree(unit->mWorld, unit->tcache);
522 	RTFree(unit->mWorld, unit->m_inputbuffer);
523 	RTFree(unit->mWorld, unit->m_inplace);
524 	RTFree(unit->mWorld, unit->m_magspectrum);
525 
526 	RTFree(unit->mWorld, unit->m_outputold);
527 	RTFree(unit->mWorld, unit->m_outputnew);
528 	RTFree(unit->mWorld, unit->m_outputoldnoise);
529 	RTFree(unit->mWorld, unit->m_outputnewnoise);
530 
531 	RTFree(unit->mWorld, unit->m_straightresynthesis);
532 	RTFree(unit->mWorld, unit->m_deterministicresynthesis);
533 
534 	//RTFree(unit->mWorld, unit->m_transformbuf);
535 
536 	RTFree(unit->mWorld, unit->resynth1);
537 
538     SCWorld_Allocator alloc(ft, unit->mWorld);
539 
540     if(unit->m_scfftinput) {
541 
542         scfft_destroy(unit->m_scfftinput, alloc);
543         scfft_destroy(unit->m_scfftresynth, alloc);
544         scfft_destroy(unit->m_scifft, alloc);
545 
546 	}
547 
548     if(unit->m_scifftresynth1){
549         scfft_destroy(unit->m_scifftresynth1, alloc);
550         //scfft_destroy(unit->m_scifftresynth1);
551         //RTFree(unit->mWorld, unit->m_scifftresynth1);
552 
553 	}
554 
555 //	if(unit->m_scfftinput){
556 //		scfft_destroy(unit->m_scfftinput);
557 //		RTFree(unit->mWorld, unit->m_scfftinput);
558 //	}
559 //
560 //	if(unit->m_scfftresynth){
561 //		scfft_destroy(unit->m_scfftresynth);
562 //		RTFree(unit->mWorld, unit->m_scfftresynth);
563 //	}
564 //
565 //	if(unit->m_scifft){
566 //		scfft_destroy(unit->m_scifft);
567 //		RTFree(unit->mWorld, unit->m_scifft);
568 //	}
569 
570 	//
571 
572 
573 
574 }
575 
576 
577 
578 //HARD CODE 4*overlap? OR use 2*overlap?
579 
580 //each next:
581 //collect block of samples for new fft
582 //calculate block of samples for straight resynthesis (need 4*hopsize worth for 4*overlap)
583 //calculate block of samples for deterministic transformation (only need 2*hopsize worth)
584 
585 //on fft
586 //FFT(input sample frame)
587 //peak detection
588 //FFT of previous straight resynthesis
589 //magnitude difference, noise modelling, noise transformation, IFFT (size M of window can be less than N)
590 //now ready to begin outputting previous frame as transformed frame (apply window beforehand so just need to add blocks of samples)
591 
592 //sum up overlap signals
593 
594 
595 
596 //int numSamples = unit->mWorld->mFullRate.mBufLength;
SMS_next(SMS * unit,int numSamples)597 void SMS_next(SMS *unit, int numSamples)
598 {
599 	int i,j;
600 
601 	float* in = IN(0);
602 	float* out = OUT(0);
603 	float* out2 = OUT(1);
604 
605 	float * inputbuffer= unit->m_inputbuffer;
606 	int pos = unit->m_inputpos;
607 
608 	//fill up input buffer with next numSamples
609 	for (j=0; j<numSamples; ++j) {
610 		inputbuffer[pos++] = in[j]; //post increment returns previous?
611 	}
612 
613 
614 	//ASSUMPTIONS RIFE HERE FOR WHAT BLOCKSIZE IS
615 	//printf("before str %d det %d \n",unit->m_straightpos, unit->m_deterministicpos);
616 
617 
618 	if(unit->m_useifft) {
619 		//experimental inverse FFT resynthesis
620 		ifftsines(unit, unit->m_straightresynthesis, numSamples*unit->m_overlapfactor, unit->m_straightpos, unit->m_windowsize, unit->m_tracks);
621 		ifftsines(unit, unit->m_deterministicresynthesis, numSamples*2, unit->m_deterministicpos, unit->m_hopsize*2, unit->m_tracks2);
622 
623 	} else
624 	{
625 		//calculate blocksize*overlapfactor into straight resynthesis buffer
626 		//would be more efficient if separate function
627 		//NOT THIS ONE synthesisedeterministic(unit, unit->m_straightresynthesis, numSamples*unit->m_overlapfactor, unit->m_straightpos, unit->m_windowsize, 1.0,0);
628 
629 		synthesisedeterministic(unit, unit->m_straightresynthesis, numSamples*unit->m_overlapfactor, unit->m_straightpos, unit->m_windowsize, unit->m_tracks);
630 
631 		//POTENTIAL ERROR HERE SINCE freqmult can change during resynthesis of set of tracks
632 		//precalculates twice as much as needed so ready to do crossfade for next time without preserving multiple guide lists?
633 		//assumes overlap is 4 or 2????
634 		//calculate blocksize*2 into deterministic transformation buffer
635 		//which flag set to 1 here to differentiate which phase variable to use in Guides
636 		//ZIN0(5)
637 		//no need to separate as flag 0 or 1 anymore since independent guides list
638 
639 		//CURRENT
640 		synthesisedeterministic(unit, unit->m_deterministicresynthesis, numSamples*2, unit->m_deterministicpos, unit->m_hopsize*2,  unit->m_tracks2);
641 
642 		//OLD
643 		//synthesisedeterministic(unit, unit->m_deterministicresynthesis, numSamples*2, unit->m_deterministicpos, unit->m_hopsize*2, unit->m_freqmult, 1);
644 	}
645 
646 
647 	//printf("after str %d det %d \n",unit->m_straightpos, unit->m_deterministicpos);
648 
649 	//resynthpos
650 
651 	//resynthesisposition += numSamples;
652 	//unit->m_resynthesisposition=resynthesisposition;
653 
654 	if (pos>=unit->m_windowsize) {
655 
656 		//prepare new output buffers
657 		//buffer swap
658 		float * temp= unit->m_outputold; //has finished fade out
659 		unit->m_outputold = unit->m_outputnew; //will now start to fade out
660 		unit->m_outputnew = temp;	//will now be overwritten with new data
661 
662 		//for noise output too!
663 		temp= unit->m_outputoldnoise; //has finished fade out
664 		unit->m_outputoldnoise = unit->m_outputnewnoise; //will now start to fade out
665 		unit->m_outputnewnoise = temp;	//will now be overwritten with new data
666 
667 		float * outputnew= unit-> m_outputnew;
668 		float * deterministic= unit->m_deterministicresynthesis;
669 		int nover2 = unit->m_nover2;
670 
671 		for (i=0; i<nover2; ++i) {
672 		outputnew[i]= deterministic[i];
673 		}
674 
675 		unit->m_outputpos=0;
676 
677 		//printf("now synthesise stochastic\n");
678 
679 		//deal with last frame update first
680 		synthesisestochastic(unit);
681 		//APPLY WINDOWING HERE TO AVOID DOING ELSEWHERE
682 
683 		//printf("post stochastic\n");
684 
685 		//update inputbuffer (shunt procedure)
686 		float * inplace= unit->m_inplace;
687 		memcpy(inplace, inputbuffer, unit->m_windowsize * sizeof(float));
688 		//shunt operation should work, after testing
689 		memcpy(inputbuffer, inputbuffer+(unit->m_hopsize), unit->m_shuntsize * sizeof(float));
690 		pos= unit->m_shuntsize; //ready to continue next time
691 
692 
693 		//printf("shunt done, now new input frame\n");
694 
695 		unit->m_ampmult= 2.0*ZIN0(9)/(float)unit->m_windowsize;
696 		//must update before starting new cycle since determines amp coefficients in peak detection
697 		unit->m_useifft = (int)ZIN0(8);
698 		//fft, phase vocode, peak pick and peak match
699 		newinputframe(unit, inplace);
700 
701 		//printf("after input frame\n");
702 
703 		//ready for new resynthesis round
704 		//unit->m_resynthesisposition=0;
705 		unit->m_straightpos=0;
706 		unit->m_deterministicpos=0;
707 
708 		//get new freq mult at this point?
709 		//create guide copies with adjusted amplitudes
710 		unit->m_freqmult= ZIN0(5);
711 		unit->m_freqadd= ZIN0(6);
712 		unit->m_formantpreserve= ZIN0(7);
713 		//adjust guide amplitudes based on matching frequencies to original magspectrum
714 		//if(unit->m_formantpreserve)
715 
716 
717 		//IF always running, probably don't need two phase variables any more?
718 		//always run this, for freqmult
719 		formantpreserve(unit, unit->m_freqmult);
720 
721 		//HERE! create formantpreserve function
722 		//then potentially rejig synthesisedeterminstic into two versions, avoiding ifs and freqmult step
723 
724 
725 		float * resynth= unit->m_straightresynthesis;
726 
727 		//zero these buffers
728 		for (j=0; j<unit->m_windowsize; ++j)
729 		resynth[j]=0.0;
730 
731 		resynth= unit->m_deterministicresynthesis;
732 
733 		//2 times hopsize
734 		for (j=0; j<unit->m_nover2; ++j)
735 		resynth[j]=0.0;
736 
737 
738 	}
739 
740 	unit->m_inputpos=pos; //store for next time
741 
742 	int outputpos= unit->m_outputpos;
743 
744 	float * fadeout= unit->m_outputold+unit->m_hopsize;
745 	float * fadein= unit->m_outputnew;
746 
747 	float * fadeout2= unit->m_outputoldnoise+unit->m_hopsize;
748 	float * fadein2= unit->m_outputnewnoise;
749 
750 	//float rhop= 1.0f/unit->m_hopsize;
751 	float temp;
752 	//crossfade of previous frame data and newer frame
753 	for (j=0; j<numSamples; ++j) {
754 
755 		//float prop= outputpos*rhop;
756 		//crossfade already precalculated
757 		temp = fadeout[outputpos]+fadein[outputpos]; //*(1.0-prop) + fadein[outputpos]*prop;
758 		out[j]=temp;
759 		temp = fadeout2[outputpos]+fadein2[outputpos];
760 		out2[j]=temp;
761 		++outputpos;
762 	}
763 
764     //safety (especially for first time round when waiting to collect full input window)
765     if(outputpos>=unit->m_nover4)
766         outputpos = 0;
767 
768 	unit->m_outputpos = outputpos;
769 
770 }
771 
772 
773 
774 //can get magspectrum of noise and sine peak data
graphicsbuffer(SMS * unit,Guide * tracks,SCPolarBuf * p)775 void graphicsbuffer(SMS * unit, Guide * tracks, SCPolarBuf * p) {
776 
777 	int i;
778 
779 	float * buf = unit->buf;
780 
781 	int numtracks = unit->m_numtracks;
782 
783 	int pos= 0; //numtracks;
784 
785 	buf[0]= (float)numtracks;
786 
787 	//printf("numtracks %d ",numtracks);
788 
789 	for (i=0; i<numtracks; ++i) {
790 
791 		pos= i*5+1; //numtracks;
792 
793 		Guide *  pointer= &tracks[i];
794 
795 		buf[pos]= pointer->freq1;
796 		buf[pos+1]= pointer->freq2;
797 		buf[pos+2]= pointer->amp1;
798 		buf[pos+3]= pointer->amp2;
799 		buf[pos+4]= pointer->phase1;
800 	}
801 
802 	pos= numtracks*5+1;
803 
804 	int nover2= unit->m_nover2;
805 
806 	for (i=0; i<(nover2-1); ++i) {
807 
808 		//will be copy or actual one?
809 		SCPolar& polar = p->bin[i];
810 
811 		buf[pos+i] = polar.mag;
812 	}
813 
814 }
815 
816 
817 
818 
819 //float phase1, phase2; //two phase variables required- in general, one for each resynthesis required!
820 //float amp1, amp2, freq1, freq2;
formantpreserve(SMS * unit,float freqmult)821 void formantpreserve(SMS * unit, float freqmult) {
822 
823 	//copy between
824 	//m_tracks2
825 	//m_tracks
826 
827 	Guide * tracks = unit->m_tracks;
828 	Guide * tracks2 = unit->m_tracks2;
829 	int numtracks = unit->m_numtracks;
830 
831 	float freqshift = 2*pi* unit->m_freqadd/unit->m_sr;  //2pi* f/R
832 
833 	int i;
834 
835 	Guide * pointer;
836 	Guide * pointer2;
837 
838 	if(unit->m_formantpreserve) {
839 
840 		float * magspectrum= unit->m_magspectrum;
841 		float angmultr= unit->m_nover2/pi;
842 		float ampmult= unit->m_ampmult; //(1.0/unit->m_windowsize); //NOT NEEDED: remember blackman window function already has scale factor of N implcit unit->m_useifft? 1.0 : (1.0/unit->m_windowsize);
843 
844 		int test= (unit->m_nover2-1); //top bin value
845 
846 		int low; //, high;
847 		float freqbin; //, frac;
848 
849 		for (i=0; i<numtracks; ++i) {
850 
851 			pointer= &tracks[i];
852 			pointer2= &tracks2[i];
853 
854 			pointer2->phase1= pointer->phase1;
855 			//pointer2->phase2= pointer->phase2;
856 			pointer2->freq1= pointer->freq1 * freqmult + freqshift;
857 			pointer2->freq2= pointer->freq2 * freqmult + freqshift;
858 
859 			//bin number to freq (i-1)*angmult float angmult= pi/nover2;
860 
861 			freqbin= pointer2->freq1 * angmultr;
862 
863 			//don't do linear interpolation, rough calc only
864 			low= (int)freqbin;
865 
866 			if(low>=test) low= low%test;
867 			if(low<0) low= (-low)%test;
868 
869 //			frac= freqbin-low;
870 //			high= low+1;
871 
872 			//must check for birth and deaths and preserve those
873 			pointer2->amp1=(pointer->amp1<0.000001)? (pointer->amp1): (magspectrum[low]*ampmult);
874 
875 			freqbin= pointer2->freq2 * angmultr;
876 			low= (int)freqbin;
877 
878 			if(low>=test) low= low%test;
879 			if(low<0) low= (-low)%test;
880 
881 			pointer2->amp2=(pointer->amp2<0.000001)? (pointer->amp2): (magspectrum[low]*ampmult);
882 
883 		}
884 
885 	}
886 	else
887 	{
888 
889 		for (i=0; i<numtracks; ++i) {
890 
891 			pointer= &tracks[i];
892 			pointer2= &tracks2[i];
893 
894 			pointer2->phase1= pointer->phase1;
895 			//pointer2->phase2= pointer->phase2;
896 			pointer2->amp1= pointer->amp1;
897 			pointer2->amp2= pointer->amp2;
898 
899 			//printf("amp1 %f amp2 %f \n",pointer->amp1, pointer->amp2);
900 
901 
902 			pointer2->freq1= pointer->freq1 * freqmult + freqshift;
903 			pointer2->freq2= pointer->freq2 * freqmult + freqshift;
904 
905 		}
906 
907 	}
908 
909 
910 }
911 
912 
913 //, int number,int& pos, int total,
ifftsines(SMS * unit,float * output,int number,int & pos,int total,Guide * tracks)914 void ifftsines(SMS * unit, float * output, int number,int& pos, int total, Guide * tracks) {
915 
916 	if(pos<total) {
917 
918 	pos=total;
919 
920 	int i,j;
921 
922 	float * ifftsum= unit->resynth1;
923 	for (j=0; j<unit->m_windowsize; ++j)
924 		ifftsum[j]=0.0;
925 
926 	int numtracks = unit->m_numtracks;
927 
928 	Guide * pointer;
929 
930 	//printf("numtracks %d \n", numtracks);
931 
932 	float phase;
933 
934 	float angmultr= unit->m_nover2/pi;
935 
936 	SCComplex what(1.0,0.0);
937 
938 	int highestbinallowed= unit->m_nover2-4;
939 
940 	for (i=0; i<numtracks; ++i) {
941 
942 		pointer = &(tracks[i]);
943 
944 	//	float amp1= pointer->amp1;
945 		//float amp2=pointer->amp2;
946 		//((i*40.0)/22050.0)*pi;
947 		//float freq1= pointer->freq1;
948 		//float freq2= pointer->freq2;
949 
950 		//take averages
951 		float amp= ((pointer->amp1 + pointer->amp2)*0.5); //*0.5; //additional half recommended by Laroche
952 		float freq= (pointer->freq1 + pointer->freq2)*0.5;
953 		int freqbin= ((angmultr*freq)+0.5);
954 
955 		//need sc_fold if outside of 0 to Nyquist bins?
956 		phase= pointer->phase1;
957 		what= SCPolar(1.0,phase).ToComplexApx();
958 
959 		//safety; don't synthesise if off the scale
960 		if((freqbin>=4) && (freqbin<highestbinallowed)) {
961 		//ignore phase for now, later would work in via e(i*phase) term to spread over real and imag parts
962 		//if (freqbin>=4) {
963 
964 			for (j=0; j<7; ++j)
965 			{
966 				int now = 2*(freqbin-3+j);
967 				float val = amp*g_blackman92fft[j];
968 				//ifftsum[now] += val;
969 
970 				ifftsum[now] += what.real*(val);
971 				ifftsum[now+1]+= what.imag*(val);
972 			}
973 
974 		//}
975 		//must take account of negative frequencies entering positive region- times by i
976 //		else {
977 //				//need clauses to cope with neg frequencies etc; just skip it for now
978 //			for (j=0; j<7; ++j)
979 //			{
980 //				int now = 2*(freqbin-3+j);
981 //				float val = amp*g_blackman92fft[j];
982 //				//ifftsum[now] += val;
983 //
984 //				ifftsum[now] += what.real*(val);
985 //				ifftsum[now+1]+= what.imag*(val);
986 //			}
987 //
988 //		}
989 		}
990 		//if(which)
991 		//else
992 		//phase= pointer->phase2;
993 	}
994 
995 	//do IFFT
996 	scfft_doifft(unit->m_scifftresynth1);
997 
998 	//divide out window as well   /g_blackman92window
999 	//total = unit->m_windowsize or half window size in one case
1000 	for (j=0; j<total; ++j)
1001 		output[j]= 	ifftsum[j]*g_blackman92window[j];
1002 
1003 	}
1004 
1005 }
1006 
1007 
1008 //void synthesisedeterministic(SMS * unit, float * output, int number,int& pos, int total, float mult, int which=0)
synthesisedeterministic(SMS * unit,float * output,int number,int & pos,int total,Guide * tracks)1009 void synthesisedeterministic(SMS * unit, float * output, int number,int& pos, int total, Guide * tracks) {
1010 
1011 	int i,j;
1012 
1013 	//Guide * tracks = unit->m_tracks;
1014 	int numtracks = unit->m_numtracks;
1015 
1016 	//int resynthesisposition = unit->m_resynthesisposition;
1017 
1018 	//float T = unit->m_hopsize;
1019 	//float rT= 1.0/T;
1020 
1021 	Guide * pointer;
1022 
1023 	//printf("numtracks %d \n", numtracks);
1024 
1025 	//test avoids pile-up, particulaly at start
1026 	//printf("problem pos %d \n",pos);
1027 	if(pos<total) {
1028 
1029 	int top= pos+number;
1030 	float rtotal= 1.0/total;
1031 	float constantsize= rtwopi*g_costablesize;
1032 
1033 	float phase;
1034 
1035 	for (i=0; i<numtracks; ++i) {
1036 
1037 		pointer = &(tracks[i]);
1038 
1039 		float amp1=pointer->amp1;
1040 		float amp2=pointer->amp2;
1041 		//((i*40.0)/22050.0)*pi;
1042 		float freq1= pointer->freq1;
1043 		float freq2= pointer->freq2;
1044 
1045 		//if(which)
1046 		phase= pointer->phase1;
1047 		//else
1048 		//phase= pointer->phase2;
1049 
1050 		for (j=pos; j<top; ++j) {
1051 
1052 			float tpos= (float)j*rtotal;
1053 
1054 			//linear interpolation of amplitude
1055 			float amp= amp1 + (tpos*(amp2- amp1));
1056 			//amp= amp*0.00390625; //compensation for approx 256.0 increase in size of magnitude values for Hanning window observing a sine peak on bin?
1057 
1058 			//printf("amp %f temp3 %f amp2 %f number %f \n",amp,temp3, tracks[i].amp2, ((float)t/T));
1059 
1060 			float freq= freq1 + (tpos*(freq2- freq1));
1061 
1062 			//SPEED UP could remove this line if had precalculated frequency multiplication effects, ie separate guides array with freq1 and freq2 already adjusted
1063 			//update by instantaneous phase
1064 			phase +=  freq; //WAS freq*mult; //*rT; //per sample? with frequency multiplier in here! rT
1065 
1066 			float phasetemp= phase*constantsize; //rtwopi*g_costablesize;
1067 
1068 			//if(i==10)
1069 			//printf("freq check f1 %f f2 %f instantaneous freq %f phase %f \n",freq1, freq2, freq, phase);
1070 
1071 			//linear interpolation into costable
1072 			//could use fmod if add very big multiple of pi so modulo works properly; ie, no negative phases allowed BUT fmod is really inefficient!
1073 			//float wrapval= sc_wrap(phasetemp,0.0f,1024.0f); //modulo or fold won't work correctly- i.e., we need -1 = 1023
1074 
1075 			//phase now always positive so take modulo 1024.0?
1076 			//int prev= ((int)phasetemp)%1024;	//cheaper on CPU?
1077 
1078 			//int prev= (int)wrapval; //truncation alone is sufficient for larger wavetable
1079 			//float interp= cos(freq1*j); //TEST
1080 			//float interp= g_costable[((int)phasetemp)%1024];
1081 			//can use efficient trick for any power of two when doing modulo
1082 			float interp= g_costable[((int)phasetemp) & 0x03FF];
1083 
1084 
1085 
1086 
1087 			//float prop=  wrapval-prev; //linear interpolation parameter
1088 			//float interp= ((1.0-prop)*(g_costable[prev])) + (prop*(g_costable[prev+1]));
1089 
1090 			//if(number==128)
1091 			//printf("pos %d amp %f phase %f interp %f \n",j,amp, phase, interp);
1092 
1093 			output[j] += amp*interp; //g_costable[((int)(phasetemp))%g_costablesize];
1094 
1095 			//if(i==10)
1096 			//printf("output j %d value %f amp %f interp %f \n",j, output[j], amp, interp);
1097 
1098 		}
1099 
1100 
1101 		//if(which)
1102 		pointer->phase1= phase;
1103 		//else
1104 		//pointer->phase2= phase;
1105 
1106 	}
1107 
1108 	//for(j=0;j<128;++j)
1109 	//	printf("test %f \n",output[j]);
1110 
1111 
1112 	pos= pos+number; //reference so should update
1113 	//resynthesisposition += numSamples;
1114 	//unit->m_resynthesisposition=resynthesisposition;
1115 	}
1116 
1117 
1118 }
1119 
1120 
newinputframe(SMS * unit,float * inputbuffer)1121 void newinputframe(SMS * unit, float * inputbuffer) {
1122 
1123 int i;
1124 
1125 //windowing
1126 //int n= unit->m_windowsize;
1127 
1128 //for (i=0; i<n; ++i)
1129 //	inputbuffer[i] *= g_HannTable[i];
1130 //
1131 //
1132 ////FFT in place via Green FFT , 10 is log2(1024)
1133 ////real forward fft carried out in place
1134 //rffts(inputbuffer, unit->m_log2n, 1, g_GreenCosTable);
1135 
1136 //will act on inputbuffer since same as m_inplace
1137 scfft_dofft(unit->m_scfftinput);
1138 
1139 
1140 //phase vocoder
1141 
1142 //input buffer now in standard format but need magnitudes and phases viewpoint- actually, don't need phases, but efficient McCartney procedure to get magnitude goes via angle, which pretty much solves phase anyway!
1143 SCPolarBuf *p = ToPolarApx2(inputbuffer); //assumes inputbuffer in SCComplex format, which it is!
1144 
1145 //save magnitude spectrum
1146 //copy magnitude spectrum for differencing calculation
1147 
1148 //this will overwrite previous; must have done differencing from previous frame by now?
1149 float * magspectrum= unit->m_magspectrum;
1150 
1151 int nover2 = unit->m_nover2;
1152 
1153 for (i=0; i<(nover2-1); ++i) {
1154 magspectrum[i]= p->bin[i].mag;
1155 }
1156 
1157 //store dc and nyquist for later
1158 magspectrum[nover2-1] = p->dc;
1159 magspectrum[nover2] = p->nyq;
1160 
1161 //peak detection for new fft frame
1162 peakdetection(unit, magspectrum, p);
1163 
1164 //peak matching
1165 peakmatching(unit);
1166 
1167 }
1168 
1169 
1170 
1171 //peak detection searching through magspectrum, could limit up to 10000 Hz
peakdetection(SMS * unit,float * magspectrum,SCPolarBuf * p)1172 void peakdetection(SMS * unit, float * magspectrum, SCPolarBuf *p) {
1173 
1174 	int i; //,j;
1175 
1176 int nover2 = unit->m_nover2;
1177 
1178 Peak * prevpeaks= unit->m_prevpeaks;
1179 Peak * newpeaks= unit->m_newpeaks;
1180 int numprevpeaks= unit->m_numprevpeaks;
1181 int numnewpeaks= unit->m_numnewpeaks;
1182 
1183 //printf("prev pointer %p new pointer %p \n",prevpeaks, newpeaks);
1184 
1185 //ditch old
1186 numprevpeaks= numnewpeaks;
1187 numnewpeaks=0;
1188 
1189 //swap pointers ready to write new peaks
1190 Peak * temp= prevpeaks;
1191 prevpeaks=newpeaks;
1192 newpeaks=temp;
1193 
1194 //printf("prev pointer %p new pointer %p temp %p \n",prevpeaks, newpeaks, temp);
1195 
1196 float prevmag, mag, nextmag; //phase,
1197 
1198 //bin 1 can't be pick since no interpolation possible! dc should be ignored
1199 //test each if peak candidate; if so, add to list and add to peaks total
1200 
1201 prevmag= magspectrum[0]; //this is at analysis frequency, not dc
1202 mag= magspectrum[1];
1203 
1204 int numpeaksrequested= (int)ZIN0(2); //(int)(ZIN0(4)+0.0001);
1205 int maxpeaks= unit->m_maxpeaks;
1206 
1207 maxpeaks = sc_min(maxpeaks,numpeaksrequested);
1208 
1209 //angular frequency is pi*(i/nover2)
1210 
1211 float angmult= pi/nover2; //MIGHT NEED TO VARY BASED ON RESYNTHESIS SPEED? NAH
1212 //if IFFT resynthesis, get 1/N from the IFFT call; otherwise, time domain resynthesis requires scalefactor to be built in
1213 float ampmult= unit->m_ampmult; //(1.0/unit->m_windowsize); //unit->m_useifft? 1.0 : (1.0/unit->m_windowsize); //*(1.0/unit->m_maxpeaks);
1214 
1215 	//defined here since needed in backdating phase for track births (and potentially for track deaths too)
1216 //T = number of samples per interpolaion frame, so equals hopsize
1217 //float T = unit->m_hopsize;
1218 
1219 float ampcheck= ZIN0(4); //0.001
1220 
1221     float temp1, position, refinement;
1222 
1223 //could restrict not to go above nover4!
1224 for (i=2; i<(nover2-1); ++i) {
1225 
1226 	//phase= p->bin[i].phase;
1227 	nextmag= magspectrum[i];
1228 
1229 	if ((prevmag<mag) && (nextmag<mag) && (mag>ampcheck) && (numnewpeaks<maxpeaks)) {
1230 		//found a peak
1231 
1232 		//should I be preserving phase?
1233 
1234         //quadratic interpolation formula
1235 
1236         //temp1 should be greater than zero since mag is a local peak
1237         temp1= prevmag+nextmag-(2*mag);
1238 
1239         if(temp1>0.00001) {
1240             position=(prevmag-nextmag)/(2*temp1);
1241             refinement = (0.5*temp1*(position*position)) + (0.5*(nextmag-prevmag)*position) + mag;
1242         } {
1243 
1244             position= 0.f;
1245             refinement = mag;
1246 
1247 
1248         }
1249 
1250 		//parabolic interpolation to refine peak location used here
1251 		newpeaks[numnewpeaks].mag = refinement * ampmult; //was mag*ampmult must divide by fftsize before resynthesis!
1252 		newpeaks[numnewpeaks].freq =(i-1+position)*angmult; //was (i-1)*angmult *freqmult; //if should be angular frequency per sample, divide by T
1253 		newpeaks[numnewpeaks].phase =p->bin[i-1].phase;
1254 
1255         //old
1256 //        newpeaks[numnewpeaks].mag = mag * ampmult; //was mag*ampmult must divide by fftsize before resynthesis!
1257 //		newpeaks[numnewpeaks].freq =(i-1)*angmult; //was (i-1)*angmult *freqmult; //if should be angular frequency per sample, divide by T
1258 //		newpeaks[numnewpeaks].phase =p->bin[i-1].phase;
1259 //
1260 
1261 		++numnewpeaks;
1262 	}
1263 
1264 	prevmag=mag;
1265 	mag=nextmag;
1266 
1267 }
1268 
1269 unit->m_prevpeaks = prevpeaks;
1270 unit->m_newpeaks = newpeaks;
1271 unit->m_numprevpeaks = numprevpeaks;
1272 unit->m_numnewpeaks = numnewpeaks;
1273 
1274 }
1275 
1276 
1277 
1278 
1279 //TO TIDY AND MAKE SURE IT WORKS
1280 //non-recursive procedure from TPV for now, no sleeping
peakmatching(SMS * unit)1281 void peakmatching(SMS * unit) {
1282 
1283 int i,j;
1284 
1285 int nover2 = unit->m_nover2;
1286 float angmult= pi/nover2;
1287 
1288 Peak * prevpeaks= unit->m_prevpeaks;
1289 Peak * newpeaks= unit->m_newpeaks;
1290 int numprevpeaks= unit->m_numprevpeaks;
1291 int numnewpeaks= unit->m_numnewpeaks;
1292 
1293 //now peak matching algorithm
1294 //int leftsort=0;
1295 int rightsort=0;
1296 bool flag= true;
1297 //float rightfreq= newpeaks[0].freq;
1298 
1299 Guide * tracks = unit->m_tracks;
1300 int numtracks = 0; //unit->m_numtracks;
1301 
1302 //increase tolerance
1303 float tolerance= ZIN0(3)*angmult;
1304 
1305 float testfreq;
1306 
1307 //	SEEMS OK
1308 //	printf("numprevpeaks %d numnewpeaks %d \n",numprevpeaks, numnewpeaks);
1309 //	//print all and look for junk data
1310 	//for (i=0; i<numnewpeaks; ++i)
1311 	//printf("new i %d amp %f freq %f \n",i,newpeaks[i].mag,newpeaks[i].freq);
1312 //
1313 //	for (i=0; i<numprevpeaks; ++i)
1314 //	printf("prev i %d amp %f freq %f phase %f \n",i,prevpeaks[i].mag,prevpeaks[i].freq,prevpeaks[i].phase);
1315 //
1316 //
1317 
1318 //RGen& rgen = *unit->mParent->mRGen;
1319 
1320 //ASSUMES BOTH PEAKS LISTS ARE IN ORDER OF INCREASING FREQUENCY
1321 
1322 //while right less than left-tolerance then birth on right
1323 
1324 //if right within tolerance, find closest; if less than, match, else must check next on left whether better match. If not, match, else, check previous on right. If within tolerance, match, else death on right.
1325 
1326 //step through prevpeaks
1327 for (i=0; i<numprevpeaks; ++i) {
1328 
1329 	float freqnow= prevpeaks[i].freq;
1330 
1331 	flag=true;
1332 	while(flag) {
1333 
1334 		if(rightsort>=numnewpeaks) {flag=false;} else {
1335 			testfreq= newpeaks[rightsort].freq;
1336 
1337 			if((testfreq+tolerance)<freqnow) {
1338 				//birth on right
1339 				tracks[numtracks].freq1=newpeaks[rightsort].freq;
1340 				tracks[numtracks].freq2=newpeaks[rightsort].freq; //match to itself
1341 				tracks[numtracks].amp1=0.0;
1342 				tracks[numtracks].amp2=newpeaks[rightsort].mag;
1343 				tracks[numtracks].phase1=newpeaks[rightsort].phase;//rgen.frand()*twopi;
1344 				tracks[numtracks].phase2=tracks[numtracks].phase1;
1345 				++numtracks;
1346 				++rightsort;
1347 
1348 			} else {
1349 
1350 				flag=false;
1351 
1352 			}
1353 
1354 		}
1355 
1356 	}
1357 
1358 	flag=false; //whether match process fails
1359 	if(rightsort>=numnewpeaks) {flag=true;} else {
1360 			//printf("testfreq %f freqnow %f tolerance %f \n ", testfreq, freqnow, tolerance);
1361 
1362 		//assumption that testfreq already valid;
1363 		if (testfreq>(freqnow+tolerance)) {flag=true;} else {
1364 
1365 			//now have a candidate. search for closest amongst remaining; as soon as no closer, break
1366 			//printf("candidate! \n ");
1367 
1368 			float bestsofar= fabs(freqnow- testfreq);
1369 			int bestindex= rightsort;
1370 
1371 			for (j=(rightsort+1); j<numnewpeaks; ++j) {
1372 				float newcandidate= newpeaks[j].freq;
1373 				float newproximity= fabs(newcandidate-freqnow);
1374 
1375 				//must keep getting closer, else no use
1376 				if(newproximity<bestsofar) {bestindex= j; bestsofar= newproximity;}
1377 				else break; //nothing better
1378 			}
1379 
1380 			//now have closest estimate. If less than freqnow have match
1381 			float closest= newpeaks[bestindex].freq;
1382 			bool havematch=false;
1383 
1384 			//printf("closest! %f bestindex %d rightsort %d \n ", closest, bestindex, rightsort);
1385 
1386 			if(closest<freqnow || (i==(numprevpeaks-1))) havematch=true;
1387 			else { //test next i as available in this case
1388 
1389 				float competitor = prevpeaks[i+1].freq;
1390 
1391 				if (fabs(competitor-closest)<bestsofar) {
1392 
1393 					//if no alternative
1394 					if (bestindex==rightsort) flag= true; //failure to match anything
1395 					else {bestindex= rightsort-1;
1396 						havematch=true;
1397 					}
1398 
1399 				} else
1400 				havematch=true;
1401 
1402 			}
1403 
1404 			if(havematch) {
1405 
1406 				//int newrightsort= bestindex;
1407 				//if() newrightsort=
1408 
1409 				//TIDY UP ANY CANIDATES MISSED OUT BY THIS PROCESS
1410 
1411 				for (j=rightsort; j<=(bestindex-1);++j) {
1412 					//BIRTHS ON RIGHT
1413 
1414 					tracks[numtracks].freq1=newpeaks[j].freq;
1415 					tracks[numtracks].freq2=newpeaks[j].freq; //match to itself
1416 					tracks[numtracks].amp1=0.0;
1417 					tracks[numtracks].amp2=newpeaks[j].mag;
1418 					tracks[numtracks].phase1=newpeaks[j].phase; //rgen.frand()*twopi;
1419 					tracks[numtracks].phase2=tracks[numtracks].phase1;
1420 					++numtracks;
1421 					++rightsort;
1422 				}
1423 
1424 				//printf("match! \n ");
1425 
1426 				//MATCH!
1427 				tracks[numtracks].freq1=prevpeaks[i].freq;
1428 				tracks[numtracks].freq2=newpeaks[rightsort].freq;
1429 				//find currently existing Guide corresponding to this frequency and its phase
1430 				tracks[numtracks].amp1=prevpeaks[i].mag;
1431 				tracks[numtracks].amp2=newpeaks[rightsort].mag;
1432 				tracks[numtracks].phase1=prevpeaks[i].phase; //rgen.frand()*twopi;
1433 				tracks[numtracks].phase2=tracks[numtracks].phase1;
1434 				//yes, OK
1435 				//printf("amp check i %d amp1 %f amp2 %f source1 %f source2 %f\n",i,tracks[numtracks].amp1, tracks[numtracks].amp2, prevpeaks[i].mag, newpeaks[rightsort].mag);
1436 				++numtracks;
1437 				++rightsort;
1438 
1439 				//rightsort=bestindex+1;
1440 
1441 			}
1442 
1443 			//if was flag==true, then none missed out, still on rightsort
1444 
1445 		}
1446 
1447 	}
1448 
1449 
1450 	//match failed, death on left
1451 	if (flag==true) {
1452 
1453 		//DEATH ON LEFT
1454 
1455 		//death on left
1456 		tracks[numtracks].freq1=prevpeaks[i].freq;
1457 		tracks[numtracks].freq2=prevpeaks[i].freq; //match to itself
1458 		//find phase of corresponding Guide
1459 		tracks[numtracks].amp1=prevpeaks[i].mag;
1460 		tracks[numtracks].amp2=0.0;
1461 		tracks[numtracks].phase1=prevpeaks[i].phase; //rgen.frand()*twopi;
1462 		tracks[numtracks].phase2=tracks[numtracks].phase1;
1463 		++numtracks;
1464 
1465 		//ADDCODE
1466 		//++leftsort;
1467 	}
1468 
1469 }
1470 
1471 //rightsort should equal numnewpeaks!
1472 
1473 //now iterate through PartialTracks, preparing them for synthesis
1474 unit->m_numtracks = numtracks;
1475 
1476 //printf("numtracks problem? %d \n",numtracks);
1477 
1478 }
1479 
1480 
1481 
1482 
1483 
1484 
1485 //IFFT
synthesisestochastic(SMS * unit)1486 void synthesisestochastic(SMS * unit) {
1487 
1488 int i;
1489 
1490 float * resynthesis= unit->m_straightresynthesis;
1491 
1492 //printf("in synthesis function \n");
1493 
1494 //FFT of m_straightresynthesis
1495 //float * inplace= unit->m_inplace;
1496 //does it need to be copied? NO
1497 //memcpy(inplace, unit->m_straightresynthesis, unit->m_windowsize*sizeof(float));
1498 
1499 ///MISSING HANN WINDOWING BEFOREHAND?
1500 
1501 //FFT in place via Green FFT , 10 is log2(1024)
1502 //real forward fft carried out in place
1503 //rffts(resynthesis, unit->m_log2n, 1, g_GreenCosTable);
1504 scfft_dofft(unit->m_scfftresynth);
1505 
1506 //printf("past fft \n");
1507 
1508 //phase vocoder
1509 
1510 //input buffer now in standard format but need magnitudes and phases viewpoint- actually, don't need phases, but efficient McCartney procedure to get magnitude goes via angle, which pretty much solves phase anyway!
1511 SCPolarBuf *p = ToPolarApx2(resynthesis); //assumes inputbuffer in SCComplex format, which it is!
1512 
1513 //difference to last magnitudespectrum
1514 //RENAME magspectrum as straight name
1515 
1516 //this will overwrite previous; must have done differencing from previous frame by now?
1517 float * magspectrum= unit->m_magspectrum;
1518 
1519 //model with line segment approximation: LATER, not needed for now...
1520 
1521 //in place disturbance of p for now
1522 
1523 int nover2 = unit->m_nover2;
1524 
1525 //leave dc and nyquist as they were since abandoned for sinusoidal modelling
1526 
1527 //USE FABS for differences as per p21 Serra and Smith?
1528 
1529 //just preserved since no peaks here
1530 p->dc= fabs(magspectrum[nover2-1]- p->dc);
1531 p->nyq= fabs(magspectrum[nover2] - p->nyq);
1532 
1533 RGen& rgen = *unit->mParent->mRGen;
1534 
1535 //printf("mag diff loop \n");
1536 
1537 
1538 for (i=0; i<(nover2-1); ++i) {
1539 
1540 //will be copy or actual one?
1541 SCPolar& polar = p->bin[i];
1542 
1543 polar.phase = rgen.frand2()*pi; //rgen.frand()*twopi- pi;  //random number from -pi to pi
1544 //polar.mag = magspectrum[nover2] - polar.mag; //surely terrible mistake?
1545 float newmag =magspectrum[i] - polar.mag;
1546 polar.mag =  newmag>=0.0? newmag: -newmag; //make sure positive!
1547 }
1548 
1549 
1550 //must write to buffer at this point if going to do so, while have noise magnitude spectrum
1551 if(unit->buf)
1552 graphicsbuffer(unit, unit->m_tracks, p);
1553 
1554 
1555 //returns SCComplexBuf*
1556  float* q = (float *) ToComplexApx2((float *)p); //assumes inputbuffer in SCPolar format, which it is!
1557 
1558 
1559 //printf("Pre inverse FFT \n");
1560 
1561 unit->m_q = q;
1562 //resynthesise via IFFT of line segment magnitudes and random phase
1563 //riffts(q, unit->m_log2n, 1, g_GreenCosTable);
1564 scfft_doifft(unit->m_scifft);
1565 
1566 float * ifftoutput= unit->m_inplace;
1567 
1568 //printf("Post inverse FFT \n");
1569 
1570 
1571 //in place so resynthesis buffer now contains noise
1572 //add to already calculated deterministic resynthesis output
1573 
1574 float * outputbuffer= unit->m_outputnewnoise;
1575 float * outputbuffer2= unit->m_outputnew;
1576 
1577 //need to make proper interpolation or independent attributes later (premultiply whole buffer by another multiplier)
1578 //float sineamp= ZIN0(6);
1579 //float noiseamp= ZIN0(7);
1580 
1581 //only need to use first half
1582 for (i=0; i<nover2; ++i) {
1583 outputbuffer[i] = ifftoutput[i]; //(outputbuffer[i]*sineamp) + (q[i]*noiseamp);
1584 }
1585 
1586 //impose fade in and fade out envelope
1587 for (i=0; i<nover2; ++i) {
1588 outputbuffer[i] *= g_fade[i];
1589 outputbuffer2[i] *= g_fade[i];
1590 }
1591 
1592 }
1593 
1594 
1595 
1596 
1597 
1598 
1599 
1600 
1601 //void peakmatch(SMS *unit) {
1602 //}
1603 
1604 
loadSMS(InterfaceTable * inTable)1605 void loadSMS(InterfaceTable *inTable)
1606 {
1607 	int i;
1608 	double w;
1609 
1610 	ft= inTable;
1611 
1612 	//init_SCComplex(inTable);
1613 
1614 //	//Create g_GreenCosTable for Green FFT
1615 //	int size = 1024; //1 << log2n;
1616 //	int size2 = 257; //size / 4 + 1;
1617 //	//float *win = (float*)malloc(size2 * sizeof(float));
1618 //	double winc = twopi / size;
1619 //	for (i=0; i<size2; ++i) {
1620 //		w = i * winc;
1621 //		g_GreenCosTable[i] = cos(w);
1622 //	}
1623 //
1624 //	//create von Hann window
1625 //
1626 //	//int size = 1 << log2n;
1627 //	winc = twopi / size;
1628 //	for (i=0; i<size; ++i) {
1629 //		w = i * winc;
1630 //		g_HannTable[i] = 0.5 - 0.5 * cos(w);
1631 //	}
1632 
1633 //less useful than Hann in this situation since have a threshold on peak detection anyway! so not seeking to find low amplitude components in the presence of higher amplitude components
1634 //	//Blackman Harris window, low sidelobes but wider main lobe than Hann
1635 //	for (i=0; i<size; ++i) {
1636 //		w = i * winc;
1637 //		g_HannTable[i] = 0.40217-(0.49703*cos(w))+(0.09392*cos(w*2))-(0.00183*cos(w*3));
1638 //		//g_HannTable[i] = 0.402 - 0.498*cos(winc) + 0.098*cos(2*winc)+ 0.001*cos(3*winc);
1639 //	}
1640 //
1641 //
1642 
1643 	//prepare cosine table for resynthesis
1644 	for (i=0; i<=g_costablesize; ++i) {
1645 
1646 	float temp= twopi*((float)i/g_costablesize);
1647 	g_costable[i]= cos(temp); //or sin
1648 
1649 	//printf("cos check %d %f",i,g_costable[i]);
1650 	}
1651 
1652 	for (i=0; i<256; ++i) {
1653 
1654 	float prop= (float)i/256.0;
1655 	g_fade[i]= prop;
1656 	g_fade[i+256]= 1.0-prop;
1657 	}
1658 
1659 	int windowsize=1024;
1660 	//g_blackman92window
1661 	double winc = twopi / windowsize;
1662 	for (i=0; i<windowsize; ++i) {
1663 			w = i * winc;
1664 			//92dB 4-term
1665 		//reciprocal now since otherwise have to divide by window later, can multiply this way round
1666 			g_blackman92window[i] = 1.0/(0.35875-(0.48829*cos(w))+(0.14128*cos(w*2))-(0.01168*cos(w*3)));
1667 			//printf("i %d value %f \n", i,g_blackman92window[i]);	//doesn't go totally to zero, but dangerously low skirts
1668 	}
1669 
1670 
1671 	//printf("SMS LOADED CHECK  test1 %d %d   test2 %d %d  \n",1025 & 0x03FF, 1025%1024, 2050 & 0x03FF, 2050%1024);
1672 
1673 	// & 0x07FF
1674 
1675 
1676 	//DefineDtorUnit(SMS);
1677 	//
1678 	DefineDtorCantAliasUnit(SMS);
1679 
1680 	//printf("SMS LOADED CHECK  test1 %d %d   test2 %d %d  \n",1025 & 0x0400, 1025%1024, 2050 & 0x0400, 2050);
1681 
1682 	//testing amplitude multiplier and phase result for input sine at multiple of
1683 //
1684 //	//int windowsize=1024;
1685 //	int fullsize= windowsize; //*8;
1686 //	float * transformbuf = new float[scfft_trbufsize(fullsize)];
1687 //	float * inplace = new float[fullsize];
1688 //	scfft *scfftwindow = new scfft;
1689 //
1690 //	//scfft, input size, window size, window type, in, out, transfer, forwards flag
1691 //	scfft_create(scfftwindow, fullsize, fullsize, WINDOW_RECT, inplace, inplace, transformbuf, true);
1692 //
1693 //	//make window
1694 //	for (i=0; i<fullsize; ++i)
1695 //	inplace[i]=sin(twopi* (1.0/fullsize) * i);  //no phase offset yet
1696 //
1697 //	scfft_dofft(scfftwindow);
1698 //
1699 //	for (i=0; i<512; ++i) {
1700 //		printf("i %d value %f \n", i,sqrt((inplace[2*i]*inplace[2*i]) + (inplace[2*i+1]*inplace[2*i+1])) );
1701 //	}
1702 //
1703 ////	for (i=0; i<windowsize; ++i) {
1704 ////		printf("i %d value %f \n", i,inplace[i]);
1705 ////	}
1706 ////
1707 //
1708 //
1709 //
1710 
1711 	//
1712 //
1713 //	//testing IFFT resynthesis ; take FFT of zero-padded window shape
1714 //
1715 //	int windowsize=1024;
1716 //	int fullsize= windowsize; //*8;
1717 //	float * transformbuf = new float[scfft_trbufsize(fullsize)];
1718 //	float * inplace = new float[fullsize];
1719 //	scfft *scfftwindow = new scfft;
1720 //
1721 //	//scfft, input size, window size, window type, in, out, transfer, forwards flag
1722 //	scfft_create(scfftwindow, fullsize, fullsize, WINDOW_RECT, inplace, inplace, transformbuf, true);
1723 //
1724 //	//make window
1725 //	for (i=0; i<fullsize; ++i)
1726 //	inplace[i]=0.0;
1727 //
1728 //	//Blackman-Harris?
1729 //	double winc = twopi / windowsize;
1730 //	for (i=0; i<windowsize; ++i) {
1731 //		w = i * winc;
1732 //
1733 //		//92dB 4-term
1734 //		//inplace[i] = 0.35875-(0.48829*cos(w))+(0.14128*cos(w*2))-(0.01168*cos(w*3));
1735 //
1736 //		//boost up to a multiple of analysis fundamental
1737 //		inplace[i] = sin(w*10)*(0.35875-(0.48829*cos(w))+(0.14128*cos(w*2))-(0.01168*cos(w*3)));
1738 //
1739 //
1740 //		//http://www.diracdelta.co.uk/science/source/b/l/blackman-harris%20window/source.html
1741 //		//72dB
1742 //		//inplace[i] = 0.40217-(0.49703*cos(w))+(0.09392*cos(w*2))-(0.00183*cos(w*3));
1743 //	}
1744 //
1745 //	scfft_dofft(scfftwindow);
1746 //
1747 //	for (i=0; i<windowsize; ++i) {
1748 //		printf("i %d value %f \n", i,inplace[i]);
1749 //	}
1750 
1751 
1752 //	for (i=0; i<windowsize; ++i) {
1753 //		printf("i %d value %f \n", i,inplace[i]);
1754 //	}
1755 
1756 		//18 bins either side of bin 22
1757 	//for (i=4; i<40; ++i) {
1758 	//	printf("i %d value %f \n", i,inplace[i]);
1759 	//}
1760 
1761 
1762 	//testing scale factors for FFT library, particularly with resynthesis via IFFT
1763 	//
1764 //	float inputbuffer[1024];
1765 //	float outputbuffer[1024];
1766 //
1767 //	for (i=0; i<1024; ++i) {
1768 //
1769 //	float temp= 14.0*twopi*((float)i/1024.0);
1770 //	inputbuffer[i]= cos(temp)*g_HannTable[i]; //or sin
1771 //
1772 //	//printf("cos check %d %f",i,g_costable[i]);
1773 //	outputbuffer[i]= inputbuffer[i];
1774 //	}
1775 //
1776 //
1777 //	rffts(outputbuffer, 10, 1, g_GreenCosTable);
1778 //
1779 //	//check scale factor of sinusoidal resynthesis from magnitudes
1780 //	for (i=2; i<512; ++i) {
1781 //		printf("i %d magnitude %f\n",i,pow((outputbuffer[2*i]*outputbuffer[2*i]) + (outputbuffer[2*i+1]*outputbuffer[2*i+1]),0.5));
1782 //	}
1783 //
1784 //
1785 //	riffts(outputbuffer, 10, 1, g_GreenCosTable);
1786 //
1787 //	for (i=0; i<1024; ++i) {
1788 //		printf("i %d input %f output %f difference %f ratio %f\n",i,inputbuffer[i], outputbuffer[i], inputbuffer[i]-outputbuffer[i], outputbuffer[i]/inputbuffer[i]);
1789 //	}
1790 //
1791 
1792 }
1793