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