1 #include "sms.h"
2 #include "real.h"
3 #include "utils.h"
4 #include "dBTable.h"
5 #include <stdlib.h>
6 #include <math.h>
7 #include <set>
8 using namespace std;
9
10 namespace _sbsms_ {
11
SMS(SMS * lo,int N,int band,int bandMax,int h,int res,int N0,int N1,int N2,int channels,audio * peak2)12 SMS :: SMS(SMS *lo, int N, int band, int bandMax, int h, int res, int N0, int N1, int N2, int channels, audio *peak2)
13 {
14 this->lo = lo;
15 if(lo) lo->hi = this;
16 hi = NULL;
17 this->band = band;
18 this->h = h;
19 this->h1 = (double)(h<<band);
20 this->res = res;
21 this->resMask = res - 1;
22 this->channels = channels;
23 this->N = N;
24 this->Nover2 = N/2;
25 float pad2 = (float)N/(float)N2;
26 float pad1 = (float)N/(float)N1;
27 float pad0 = (float)N/(float)N0;
28 M = (float)(1<<band);
29 peakThresh = 1e-8f;
30
31 float maxDF2 = square(0.005f * (float)h) / M;
32 maxDF = sqrt(maxDF2);
33 maxCost2 = 0.5f * maxDF2;
34 dMCoeff2 = 0.002f * maxDF2;
35
36 float maxDF2SplitMerge = square(0.001f * (float)h) / M;
37 maxDFSplitMerge = sqrt(maxDF2SplitMerge);
38 maxCost2SplitMerge = 1.0f * maxDF2SplitMerge;
39 dMCoeff2SplitMerge = 0.006f * maxDF2SplitMerge;
40
41 maxDFMatch = .06f / M;
42 float maxDF2Match = square(maxDFMatch);
43 dMCoeff2Match = 0.0075f * maxDF2Match;
44 maxCost2Match = 0.8f * maxDF2Match;
45
46 maxDFStereo = .04f / (float)M;
47 float maxDF2Stereo = square(maxDFStereo);
48 dMCoeff2Stereo = 0.005f * maxDF2Stereo;
49 maxCost2Stereo = 1.0f*maxDF2Stereo;
50
51 peakWidth0 = lrintf(pad0*(float)N*0.0055f) + 1;
52 peakWidth1 = lrintf(pad1*(float)N*0.0055f) + 1;
53 peakWidth2 = lrintf(pad2*(float)N*0.0055f) + 1;
54 minTrackSize = max(384/(h<<band),N2/h/2);
55 minCutSep2 = max((int)lrintf(0.008f * (float)N),peakWidth1);
56 minCutSep1 = max((int)lrintf(0.011f * (float)N),peakWidth0);
57 if(band==bandMax) kLo = 1;
58 else kLo = max(1L,lrintf(floor(0.5f*(float)N/(float)lo->N*(float)lo->kHi-maxDFMatch*M/TWOPI*(float)N)));
59 if(band==0) kHi = Nover2;
60 else kHi = max(1L,lrintf(0.4785f * N)-peakWidth0*2);
61 kStart = max(1,kLo-peakWidth0);
62 kEnd = min(Nover2-1,kHi+peakWidth0*2);
63 float kNorm = TWOPI / (float)(M * N);
64 maxFHi = (float)kHi * kNorm + maxDF;
65 minFLo = (float)kLo * kNorm - maxDF;
66 if(lo) maxFMatchM = (float)lo->kHi * TWOPI / (float)(lo->N * M * 2) + maxDFMatch;
67 else maxFMatchM = 0.0f;
68 minFMatchL = (float)kLo * kNorm - maxDFMatch;
69 if(lo) maxFMid = (float)lo->kHi * TWOPI / (float)(lo->N * M * 2) + maxDF;
70 else maxFMid = 0.0f;
71 if(lo) lo->minFMid = (float)kLo * kNorm - lo->maxDF;
72 if(lo && lo->lo) {
73 minK = max(1L,(lrintf(0.25f * (float)N / (float)lo->lo->N * (float)lo->lo->kHi + peakWidth0)));
74 } else {
75 minK = 1;
76 }
77 maxK = min(kEnd,kHi + peakWidth0);
78 localFavorRatio = 1.1f;
79 mNorm = MScale * MScale * 16.061113032124002f * pad2 / square((float)N);
80 for(int c=0; c<channels; c++) {
81 bAssignDone[c] = false;
82 addtime[c] = 0;
83 assigntime[c] = 0;
84 trial2time[c] = 0;
85 trial1time[c] = 0;
86 synthtime[c] = 0;
87 for(int k=1; k<256; k++) {
88 trackIndex[c].push(k);
89 }
90 trial2Buf[c] = (float*)malloc(h*res*sizeof(float));
91 trial2RingBuf[c] = new ArrayRingBuffer<float>(0);
92 dmag1[c] = (float*)malloc(N*sizeof(float));
93 mag11[c] = (float*)malloc((Nover2+1)*sizeof(float));
94 x10[c] = (audio*)malloc(N*sizeof(audio));
95 x11[c] = (audio*)malloc(N*sizeof(audio));
96 trial1Buf[c] = (float*)malloc(h*res*sizeof(float));
97 trial1RingBuf[c] = new ArrayRingBuffer<float>(0);
98 dmag0[c] = (float*)malloc(N*sizeof(float));
99 mag01[c] = (float*)malloc((Nover2+1)*sizeof(float));
100 x00[c] = (audio*)malloc(N*sizeof(audio));
101 x01[c] = (audio*)malloc(N*sizeof(audio));
102 mag2[c] = (float*)malloc((Nover2+1)*sizeof(float));
103 dec2[c] = (float*)malloc(N*sizeof(float));
104 x2[c] = (audio*)malloc(N*sizeof(audio));
105 #ifdef MULTITHREADED
106 pthread_mutex_init(&renderMutex[c],NULL);
107 pthread_mutex_init(&trackMutex[c],NULL);
108 pthread_mutex_init(&sliceMutex[c],NULL);
109 pthread_mutex_init(&trial2Mutex[c],NULL);
110 pthread_mutex_init(&trial1Mutex[c],NULL);
111 pthread_mutex_init(&magMutex[c],NULL);
112 #endif
113 }
114 h2cum = 0.0;
115 adjust2time = 0;
116 adjust1time = 0;
117 trial2GrainBuf = new GrainBuf(N,h,N1,hannpoisson);
118 trial1GrainBuf = new GrainBuf(N,h,N0,hannpoisson);
119 peak20 = (float*)calloc(2*N,sizeof(float));
120 peak2N = peak20 + N;
121 for(int k=-Nover2;k<=Nover2;k++) {
122 peak2N[k] = norm2(peak2[(k+N)%N]);
123 }
124 }
125
~SMS()126 SMS :: ~SMS()
127 {
128 for(int c=0;c<channels;c++) {
129 while(!mag1Queue[c].empty()) {
130 delete mag1Queue[c].front();
131 mag1Queue[c].pop();
132 }
133 while(!mag0Queue[c].empty()) {
134 delete mag0Queue[c].front();
135 mag0Queue[c].pop();
136 }
137 set<Track*> tracks;
138 for(list<Track*>::iterator i=assignTracks[c].begin();
139 i != assignTracks[c].end();
140 ++i ) {
141 tracks.insert(*i);
142 }
143 for(list<Track*>::iterator i=renderTracks[c].begin();
144 i != renderTracks[c].end();
145 ++i ) {
146 tracks.insert(*i);
147 }
148 for(set<Track*>::iterator i=tracks.begin();
149 i != tracks.end();
150 ++i ) {
151 delete *i;
152 }
153 set<Slice*> slices;
154 while(!adjust2SliceQueue[c].empty()) {
155 slices.insert(adjust2SliceQueue[c].front());
156 adjust2SliceQueue[c].pop();
157 }
158 while(!adjust1SliceQueue[c].empty()) {
159 slices.insert(adjust1SliceQueue[c].front());
160 adjust1SliceQueue[c].pop();
161 }
162 for(long k=sliceBuffer[c].readPos; k<sliceBuffer[c].writePos; k++) {
163 slices.insert(sliceBuffer[c].read(k));
164 }
165 for(set<Slice*>::iterator i = slices.begin();
166 i != slices.end();
167 ++i) {
168 Slice *s = *i;
169 TrackPoint *tp = s->bottom;
170 delete s;
171 while(tp) {
172 TrackPoint *tpn = tp->pn;
173 if(!tp->owner) tp->destroy();
174 tp = tpn;
175 }
176 }
177 free(trial2Buf[c]);
178 delete trial2RingBuf[c];
179 free(trial1Buf[c]);
180 delete trial1RingBuf[c];
181 free(dmag1[c]);
182 free(mag11[c]);
183 free(x10[c]);
184 free(x11[c]);
185 free(dmag0[c]);
186 free(mag01[c]);
187 free(x00[c]);
188 free(x01[c]);
189 free(mag2[c]);
190 free(x2[c]);
191 free(dec2[c]);
192 }
193 free(peak20);
194 delete trial2GrainBuf;
195 delete trial1GrainBuf;
196 }
197
trial2Start(int c)198 void SMS :: trial2Start(int c)
199 {
200 if(band >= minTrial2Band) {
201 memset(trial2Buf[c],0,h*res*sizeof(float));
202 }
203 }
204
trial2End(int c)205 void SMS :: trial2End(int c)
206 {
207 if(band < minTrial2Band) return;
208 #ifdef MULTITHREADED
209 pthread_mutex_lock(&trial2Mutex[c]);
210 #endif
211 trial2RingBuf[c]->write(trial2Buf[c],h*res);
212 #ifdef MULTITHREADED
213 pthread_mutex_unlock(&trial2Mutex[c]);
214 #endif
215 }
216
trial2(int c)217 void SMS :: trial2(int c)
218 {
219 #ifdef MULTITHREADED
220 pthread_mutex_lock(&trackMutex[c]);
221 #endif
222 for(list<Track*>::iterator tt = renderTracks[c].begin();
223 tt != renderTracks[c].end();
224 ++tt) {
225 Track *t = (*tt);
226 if(trial2time[c] >= t->start) {
227 if(trial2time[c] > t->last) continue;
228 t->updateM(trial2time[c],synthModeTrial2);
229 if(hi && hi->band >= minTrial2Band) {
230 float f = 0.5f*M;
231 t->updateFPH(trial2time[c],synthModeTrial2,h<<1,f,f);
232 t->synth(hi->trial2Buf[c],trial2time[c],h<<1,synthModeTrial2,c);
233 }
234 if(lo && lo->band >= minTrial2Band) {
235 float f = 2.0f*M;
236 t->updateFPH(trial2time[c],synthModeTrial2,h>>1,f,f);
237 t->synth(lo->trial2Buf[c]+(trial2time[c]&(res*lo->res-1))*(h>>1),trial2time[c],h>>1,synthModeTrial2,c);
238 }
239 if(band >= minTrial2Band) {
240 float f = M;
241 t->updateFPH(trial2time[c],synthModeTrial2,h,f,f);
242 }
243 } else {
244 break;
245 }
246 }
247 #ifdef MULTITHREADED
248 pthread_mutex_unlock(&trackMutex[c]);
249 #endif
250 trial2time[c]++;
251 }
252
trial1Start(int c)253 void SMS :: trial1Start(int c)
254 {
255 if(band >= minTrial1Band) {
256 memset(trial1Buf[c],0,h*res*sizeof(float));
257 }
258 }
259
trial1End(int c)260 void SMS :: trial1End(int c)
261 {
262 if(band < minTrial1Band) return;
263 #ifdef MULTITHREADED
264 pthread_mutex_lock(&trial1Mutex[c]);
265 #endif
266 trial1RingBuf[c]->write(trial1Buf[c],h*res);
267 #ifdef MULTITHREADED
268 pthread_mutex_unlock(&trial1Mutex[c]);
269 #endif
270 }
271
trial1(int c)272 void SMS :: trial1(int c)
273 {
274 #ifdef MULTITHREADED
275 pthread_mutex_lock(&trackMutex[c]);
276 #endif
277 for(list<Track*>::iterator tt = renderTracks[c].begin();
278 tt != renderTracks[c].end();
279 ++tt) {
280 Track *t = (*tt);
281 if(trial1time[c] >= t->start) {
282 if(trial1time[c] > t->last) continue;
283 t->updateM(trial1time[c],synthModeTrial1);
284 if(hi && hi->band >= minTrial1Band) {
285 float f = 0.5f*M;
286 t->updateFPH(trial1time[c],synthModeTrial1,h<<1,f,f);
287 t->synth(hi->trial1Buf[c],trial1time[c],h<<1,synthModeTrial1,c);
288 }
289 if(lo && lo->band >= minTrial1Band) {
290 float f = 2.0f*M;
291 t->updateFPH(trial1time[c],synthModeTrial1,h>>1,f,f);
292 t->synth(lo->trial1Buf[c]+(trial1time[c]&(res*lo->res-1))*(h>>1),trial1time[c],h>>1,synthModeTrial1,c);
293 }
294 if(band >= minTrial1Band) {
295 float f = M;
296 t->updateFPH(trial1time[c],synthModeTrial1,h,f,f);
297 t->synth(trial1Buf[c]+(trial1time[c]&resMask)*h,trial1time[c],h,synthModeTrial1,c);
298 }
299 } else {
300 break;
301 }
302 }
303 #ifdef MULTITHREADED
304 pthread_mutex_unlock(&trackMutex[c]);
305 #endif
306 trial1time[c]++;
307 }
308
adjust2()309 void SMS :: adjust2()
310 {
311 Slice* slice[2];
312 for(int c=0; c<channels; c++) {
313 #ifdef MULTITHREADED
314 pthread_mutex_lock(&sliceMutex[c]);
315 #endif
316 slice[c] = adjust2SliceQueue[c].front(); adjust2SliceQueue[c].pop();
317 #ifdef MULTITHREADED
318 pthread_mutex_unlock(&sliceMutex[c]);
319 #endif
320 }
321 if(band >= minTrial2Band) {
322 #ifdef MULTITHREADED
323 for(int c=0; c<channels; c++) {
324 pthread_mutex_lock(&trial2Mutex[c]);
325 }
326 #endif
327 adjustInit(trial2RingBuf,trial2GrainBuf);
328 #ifdef MULTITHREADED
329 for(int c=channels-1; c>=0; c--) {
330 pthread_mutex_unlock(&trial2Mutex[c]);
331 }
332 #endif
333 adjust(trial2GrainBuf,mag1Queue,minCutSep1,mag11,dmag1,x11,adjust2time,slice);
334 }
335 if(channels == 2) {
336 for(int c=0; c<2; c++) {
337 for(TrackPoint *pc = slice[c]->bottom;
338 pc;
339 pc = pc->pn) {
340 pc->bOwned = false;
341 pc->cont = NULL;
342 }
343 }
344 for(int c=0; c<2; c++) {
345 int c2 = (c==0?1:0);
346 TrackPoint *begin = slice[c2]->bottom;
347 for(TrackPoint *pc = slice[c]->bottom;
348 pc;
349 pc = pc->pn) {
350 float F;
351 pc->cont = nearestForward(&begin,pc,&F,maxCost2Stereo,maxDFStereo,dMCoeff2Stereo);
352 }
353 }
354 for(TrackPoint *p0 = slice[0]->bottom;
355 p0;
356 p0 = p0->pn) {
357 TrackPoint *p1 = p0->cont;
358 if(p1 && p1->cont == p0) {
359 p0->dupStereo = p1;
360 p1->dupStereo = p0;
361 }
362 }
363 }
364 adjust2time++;
365 }
366
adjust1(float stretch,float pitch0,float pitch1)367 void SMS :: adjust1(float stretch, float pitch0, float pitch1)
368 {
369 Slice* slice[2];
370 for(int c=0; c<channels; c++) {
371 #ifdef MULTITHREADED
372 pthread_mutex_lock(&sliceMutex[c]);
373 #endif
374 slice[c] = adjust1SliceQueue[c].front(); adjust1SliceQueue[c].pop();
375 #ifdef MULTITHREADED
376 pthread_mutex_unlock(&sliceMutex[c]);
377 #endif
378 }
379 if(band >= minTrial1Band) {
380 #ifdef MULTITHREADED
381 for(int c=0; c<channels; c++) {
382 pthread_mutex_lock(&trial1Mutex[c]);
383 }
384 #endif
385 adjustInit(trial1RingBuf,trial1GrainBuf);
386 #ifdef MULTITHREADED
387 for(int c=channels-1; c>=0; c--) {
388 pthread_mutex_unlock(&trial1Mutex[c]);
389 }
390 #endif
391 adjust(trial1GrainBuf,mag0Queue,minCutSep1,mag01,dmag0,x01,adjust1time,slice);
392 }
393 for(int c=0; c<channels; c++) {
394 delete slice[c];
395 }
396 double h2 = stretch * h1;
397 h2cum += h2;
398 int h2i = lrint(h2cum);
399 h2cum -= h2i;
400 for(int c=0; c<channels; c++) {
401 #ifdef MULTITHREADED
402 pthread_mutex_lock(&renderMutex[c]);
403 #endif
404 nRender[c].push(h2i);
405 #ifdef MULTITHREADED
406 pthread_mutex_unlock(&renderMutex[c]);
407 #endif
408 }
409 list<TrackPoint*> dupStereoPostponed;
410 for(int c=0; c<channels; c++) {
411 #ifdef MULTITHREADED
412 pthread_mutex_lock(&trackMutex[c]);
413 #endif
414 for(list<Track*>::iterator tt = renderTracks[c].begin();
415 tt != renderTracks[c].end();
416 ++tt) {
417 Track *t = (*tt);
418 if(adjust1time >= t->start) {
419 if(adjust1time <= t->last) {
420 TrackPoint *tp = t->updateFPH(adjust1time,synthModeOutput,h2i,pitch0,pitch1);
421 if(tp) dupStereoPostponed.push_back(tp);
422 }
423 } else {
424 break;
425 }
426 }
427 #ifdef MULTITHREADED
428 pthread_mutex_unlock(&trackMutex[c]);
429 #endif
430 }
431 for(list<TrackPoint*>::iterator tpi = dupStereoPostponed.begin();
432 tpi != dupStereoPostponed.end();
433 tpi++) {
434 TrackPoint *tp = (*tpi);
435 tp->phSynth = canon2PI(tp->dupStereo->phSynth + tp->ph - tp->dupStereo->ph);
436 }
437 adjust1time++;
438 }
439
findCut(float * dmag,int k0,int maxK)440 int SMS :: findCut(float *dmag, int k0, int maxK)
441 {
442 int k;
443 for(k = max(1,k0); k <= maxK; k++) {
444 float dd0 = dmag[k+1] - dmag[k];
445 if(dd0 > 0.0f) {
446 float d02 = square(dmag[k+1] + dmag[k]);
447 if(dd0 * square(dmag[k] + dmag[k-1]) > (dmag[k] - dmag[k-1]) * d02
448 &&
449 dd0 * square(dmag[k+2] + dmag[k+1]) > (dmag[k+2] - dmag[k+1]) * d02) {
450 break;
451 }
452 }
453 }
454 return k;
455 }
456
adjustInit(ArrayRingBuffer<float> ** trialRingBuf,GrainBuf * trialGrainBuf)457 void SMS :: adjustInit(ArrayRingBuffer<float> **trialRingBuf,
458 GrainBuf *trialGrainBuf)
459 {
460 long n = trialRingBuf[0]->nReadable();
461 for(int c=1; c<channels; c++) {
462 n = min(n,trialRingBuf[c]->nReadable());
463 }
464 long ndone = 0;
465 while(n) {
466 audio abuf[512];
467 long ntodo = min(512L,n);
468 for(int c=0; c<channels; c++) {
469 float *fbuf = trialRingBuf[c]->getReadBuf();
470 for(int k=0; k<ntodo; k++) {
471 abuf[k][c] = fbuf[ndone+k];
472 }
473 }
474 for(int c=channels; c<2; c++) {
475 for(int k=0; k<ntodo; k++) {
476 abuf[k][c] = 0.0f;
477 }
478 }
479 trialGrainBuf->write(abuf,ntodo);
480 ndone += ntodo;
481 n -= ntodo;
482 }
483 for(int c=0; c<channels; c++) {
484 trialRingBuf[c]->advance(ndone);
485 }
486 }
487
adjust(GrainBuf * trialGrainBuf,queue<float * > * magQueue,int minCutSep,float ** _mag1,float ** _dmag1,audio ** x1,const TimeType & time,Slice ** slices)488 void SMS :: adjust(GrainBuf *trialGrainBuf,
489 queue<float*> *magQueue,
490 int minCutSep,
491 float **_mag1,
492 float **_dmag1,
493 audio **x1,
494 const TimeType &time,
495 Slice **slices)
496 {
497 grain *g = trialGrainBuf->read(trialGrainBuf->readPos);
498 g->analyze();
499 for(int c=0; c<channels; c++) {
500 Slice *slice = slices[c];
501 TrackPoint *p = slice->bottom;
502 if(c == 0) {
503 c2even(g->x, x1[0], N);
504 } else {
505 c2odd(g->x, x1[1], N);
506 }
507 float *mag1 = _mag1[c];
508 calcmags(mag1, x1[c]);
509 #ifdef MULTITHREADED
510 pthread_mutex_lock(&magMutex[c]);
511 #endif
512 float *mag0 = magQueue[c].front(); magQueue[c].pop();
513 #ifdef MULTITHREADED
514 pthread_mutex_unlock(&magMutex[c]);
515 #endif
516 if(p) {
517 float *dmag = _dmag1[c];
518 list<int> cuts;
519 int k3 = min(Nover2,maxK+2);
520 dmag[0] = mag1[0];
521 for(int k=max(1,minK-2); k<k3; k++) {
522 dmag[k] = mag1[k] - mag1[k-1];
523 }
524 int k = minK;
525 while(true) {
526 k = findCut(dmag,k+1,maxK);
527 if(k >= maxK) {
528 break;
529 } else {
530 cuts.push_back(k);
531 }
532 }
533 bool bDone = false;
534 while(!bDone) {
535 bDone = true;
536 for(list<int>::iterator i = cuts.begin();
537 i != cuts.end();
538 ++i) {
539 int k0 = *i;
540 list<int>::iterator ibad = cuts.end();
541 list<int>::iterator i2 = i;
542 ++i2;
543 float maxY = 0.0f;
544 for(;
545 i2 != cuts.end();
546 ++i2) {
547 int k2 = *i2;
548 if(k2 - k0 >= minCutSep) break;
549 float y = mag0[k2] * mag1[k2];
550 if(y >= maxY) {
551 maxY = y;
552 ibad = i2;
553 }
554 k0 = k2;
555 }
556 if(ibad != cuts.end()) {
557 if(mag0[*i] * mag1[*i] > maxY) {
558 ibad = i;
559 }
560 cuts.erase(ibad);
561 bDone = false;
562 break;
563 }
564 }
565 }
566 cuts.push_front(minK);
567 cuts.push_back(maxK);
568 list<int>::iterator i = cuts.begin();
569 while(p) {
570 int k0 = *i;
571 ++i;
572 if(i == cuts.end()) break;
573 int k2 = *i;
574 if(p->x > k2) continue;
575 float m0 = 0.0f;
576 float m1 = 0.0f;
577 for(int k=k0;k<=k2;k++) {
578 m0 += mag0[k];
579 m1 += mag1[k];
580 }
581 float s = (m1>m0?sqrt(m0/m1):1.0f);
582 while(p && p->x <= k2) {
583 p->m *= s;
584 p = p->pn;
585 }
586 }
587 }
588 free(mag0);
589 }
590 trialGrainBuf->advance(1);
591 }
592
render(int c,list<SBSMSRenderer * > & renderers)593 void SMS :: render(int c, list<SBSMSRenderer*> &renderers)
594 {
595 #ifdef MULTITHREADED
596 pthread_mutex_lock(&renderMutex[c]);
597 #endif
598 int n = nRender[c].front(); nRender[c].pop();
599 #ifdef MULTITHREADED
600 pthread_mutex_unlock(&renderMutex[c]);
601 #endif
602 TimeType time = synthtime[c];
603 for(list<SBSMSRenderer*>::iterator i = renderers.begin(); i != renderers.end(); ++i) {
604 SBSMSRenderer *renderer = *i;
605 renderer->startTime(c,time,n);
606 }
607 #ifdef MULTITHREADED
608 pthread_mutex_lock(&trackMutex[c]);
609 #endif
610 for(list<Track*>::iterator tt = renderTracks[c].begin();
611 tt != renderTracks[c].end();) {
612 Track *t = (*tt);
613 if(t->bEnded && time > t->last) {
614 list<Track*>::iterator eraseMe = tt;
615 ++tt;
616 renderTracks[c].erase(eraseMe);
617 delete t;
618 } else if(time >= t->start) {
619 if(time <= t->last) {
620 t->updateM(time,synthModeOutput);
621 for(list<SBSMSRenderer*>::iterator i = renderers.begin(); i != renderers.end(); ++i) {
622 SBSMSRenderer *renderer = *i;
623 renderer->render(c,t);
624 }
625 t->step(time);
626 }
627 ++tt;
628 } else {
629 break;
630 }
631 }
632 #ifdef MULTITHREADED
633 pthread_mutex_unlock(&trackMutex[c]);
634 #endif
635 for(list<SBSMSRenderer*>::iterator i = renderers.begin(); i != renderers.end(); ++i) {
636 SBSMSRenderer *renderer = *i;
637 renderer->endTime(c);
638 }
639 synthtime[c]++;
640 }
641
nearestForward(TrackPoint ** begin,TrackPoint * tp0,float * minCost2,float maxCost2,float maxDF,float dMCoeff2,float dNCoeff2)642 TrackPoint *SMS :: nearestForward(TrackPoint **begin, TrackPoint *tp0, float *minCost2, float maxCost2, float maxDF, float dMCoeff2, float dNCoeff2)
643 {
644 *minCost2 = TrackPointNoCont;
645 float minF = tp0->f - maxDF;
646 float maxF = tp0->f + maxDF;
647 float maxDF2 = square(maxDF);
648 while((*begin) && (*begin)->f < minF) {
649 (*begin) = (*begin)->pn;
650 }
651 TrackPoint *mintp1 = NULL;
652 for(TrackPoint *tp1 = (*begin);
653 tp1;
654 tp1 = tp1->pn) {
655 if(tp1->bOwned) continue;
656 float df2 = square(tp1->f - tp0->f);
657 if(df2 > maxDF2) break;
658 float dM2 = dBApprox(tp1->m2,tp0->m2);
659 float cost2 = (df2+dMCoeff2*dM2);
660 if(cost2 > maxCost2) continue;
661 if(cost2 < (*minCost2)) {
662 (*minCost2) = cost2;
663 mintp1 = tp1;
664 }
665 }
666 return mintp1;
667 }
668
nearestReverse(TrackPoint ** begin,TrackPoint * tp0,float * minCost2,float maxCost2,float maxDF,float dMCoeff2,float dNCoeff2)669 TrackPoint *SMS :: nearestReverse(TrackPoint **begin, TrackPoint *tp0, float *minCost2, float maxCost2, float maxDF, float dMCoeff2, float dNCoeff2)
670 {
671 *minCost2 = TrackPointNoCont;
672 float minF = tp0->f - maxDF;
673 float maxF = tp0->f + maxDF;
674 float maxDF2 = square(maxDF);
675 while((*begin) && (*begin)->f > maxF) {
676 (*begin) = (*begin)->pp;
677 }
678 TrackPoint *mintp1 = NULL;
679 for(TrackPoint *tp1 = (*begin);
680 tp1;
681 tp1 = tp1->pp) {
682 if(tp1->bOwned) continue;
683 float df2 = square(tp1->f - tp0->f);
684 if(df2 > maxDF2) break;
685 float dM2 = dBApprox(tp1->m2,tp0->m2);
686 float cost2 = (df2+dMCoeff2*dM2);
687 if(cost2 > maxCost2) continue;
688 if(cost2 < (*minCost2)) {
689 (*minCost2) = cost2;
690 mintp1 = tp1;
691 }
692 }
693 return mintp1;
694 }
695
nearestForward2(TrackPoint ** begin,TrackPoint * tp0,float * minCost2,float maxCost2,float maxDF,float dMCoeff2,float dNCoeff2)696 TrackPoint *SMS :: nearestForward2(TrackPoint **begin, TrackPoint *tp0, float *minCost2, float maxCost2, float maxDF, float dMCoeff2, float dNCoeff2)
697 {
698 *minCost2 = TrackPointNoCont;
699 float minF = tp0->f - maxDF;
700 float maxF = tp0->f + maxDF;
701 float maxDF2 = square(maxDF);
702 while((*begin) && (*begin)->f < minF) {
703 (*begin) = (*begin)->pn;
704 }
705 TrackPoint *mintp1 = NULL;
706 for(TrackPoint *tp1 = (*begin);
707 tp1;
708 tp1 = tp1->pn) {
709 if(!tp1->owner) continue;
710 float df2 = square(tp1->f - tp0->f);
711 if(df2 > maxDF2) break;
712 float dM2 = dBApprox(0.25f*tp1->m2,tp0->m2);
713 float cost2 = (df2+dMCoeff2*dM2);
714 if(cost2 > maxCost2) continue;
715 if(cost2 < (*minCost2)) {
716 (*minCost2) = cost2;
717 mintp1 = tp1;
718 }
719 }
720 return mintp1;
721 }
722
nearestReverse2(TrackPoint ** begin,TrackPoint * tp0,float * minCost2,float maxCost2,float maxDF,float dMCoeff2,float dNCoeff2)723 TrackPoint *SMS :: nearestReverse2(TrackPoint **begin, TrackPoint *tp0, float *minCost2, float maxCost2, float maxDF, float dMCoeff2, float dNCoeff2)
724 {
725 *minCost2 = TrackPointNoCont;
726 float minF = tp0->f - maxDF;
727 float maxF = tp0->f + maxDF;
728 float maxDF2 = square(maxDF);
729 while((*begin) && (*begin)->f > maxF) {
730 (*begin) = (*begin)->pp;
731 }
732 TrackPoint *mintp1 = NULL;
733 for(TrackPoint *tp1 = (*begin);
734 tp1;
735 tp1 = tp1->pp) {
736 if(!tp1->owner) continue;
737 float df2 = square(tp1->f - tp0->f);
738 if(df2 > maxDF2) break;
739 float dM2 = dBApprox(tp1->m2,tp0->m2);
740 float cost2 = (df2+dMCoeff2*dM2);
741 if(cost2 > maxCost2) continue;
742 if(cost2 < (*minCost2)) {
743 (*minCost2) = cost2;
744 mintp1 = tp1;
745 }
746 }
747 return mintp1;
748 }
749
connect(TrackPoint * tp0,TrackPoint * tp1,int ilo,int c)750 void SMS :: connect(TrackPoint *tp0, TrackPoint *tp1, int ilo, int c)
751 {
752 TimeType time = assigntime[c];
753 if(tp0->slice->band == tp1->slice->band) {
754 #ifdef MULTITHREADED
755 pthread_mutex_lock(&trackMutex[c]);
756 #endif
757 tp0->owner->push_back(tp1);
758 #ifdef MULTITHREADED
759 pthread_mutex_unlock(&trackMutex[c]);
760 #endif
761 } else if(tp0->slice->band < tp1->slice->band) {
762 Track *precursor = tp0->owner;
763 if(ilo == 1) {
764 #ifdef MULTITHREADED
765 pthread_mutex_lock(&trackMutex[c]);
766 #endif
767 precursor->push_back(tp1);
768 precursor->endTrack(true);
769 TimeType time = precursor->end/res;
770 #ifdef MULTITHREADED
771 pthread_mutex_unlock(&trackMutex[c]);
772 #endif
773 #ifdef MULTITHREADED
774 pthread_mutex_lock(&lo->trackMutex[c]);
775 #endif
776 lo->createTrack(c,tp1,time,true);
777 #ifdef MULTITHREADED
778 pthread_mutex_unlock(&lo->trackMutex[c]);
779 #endif
780 } else {
781 #ifdef MULTITHREADED
782 pthread_mutex_lock(&trackMutex[c]);
783 #endif
784 TimeType time = precursor->end/res;
785 precursor->endTrack(true);
786 TrackPoint *last = precursor->back();
787 #ifdef MULTITHREADED
788 pthread_mutex_unlock(&trackMutex[c]);
789 #endif
790 #ifdef MULTITHREADED
791 pthread_mutex_lock(&lo->trackMutex[c]);
792 #endif
793 Track *t = lo->createTrack(c,last,time,true);
794 t->push_back(tp1);
795 #ifdef MULTITHREADED
796 pthread_mutex_unlock(&lo->trackMutex[c]);
797 #endif
798 last->owner = precursor;
799 }
800 } else {
801 Track *precursor = tp0->owner;
802 #ifdef MULTITHREADED
803 pthread_mutex_lock(&trackMutex[c]);
804 #endif
805 precursor->push_back(tp1);
806 precursor->endTrack(true);
807 TimeType time = precursor->end*hi->res;
808 #ifdef MULTITHREADED
809 pthread_mutex_unlock(&trackMutex[c]);
810 #endif
811 #ifdef MULTITHREADED
812 pthread_mutex_lock(&hi->trackMutex[c]);
813 #endif
814 hi->createTrack(c,tp1,time,true);
815 #ifdef MULTITHREADED
816 pthread_mutex_unlock(&hi->trackMutex[c]);
817 #endif
818 }
819 tp0->bConnected = true;
820 tp1->bConnected = true;
821 tp0->bOwned = true;
822 tp1->bOwned = true;
823 if(tp0->dupcont) {
824 TrackPoint *dup = tp0->dupcont;
825 if(!dup->owner) {
826 dup->bOwned = true;
827 dup->bDelete = true;
828 }
829 }
830 TrackPoint *dup2 = tp0->dup[2];
831 if(dup2 && dup2 != tp1 && !dup2->owner) {
832 dup2->bOwned = true;
833 dup2->bDelete = true;
834 }
835 for(int d=0;d<3;d++) {
836 TrackPoint *dup = tp1->dup[d];
837 if(dup && !dup->owner && (d<2 || dup->slice->band < tp1->slice->band)) {
838 dup->bOwned = true;
839 dup->bDelete = true;
840 }
841 }
842 }
843
mark(long offset,int c)844 void SMS :: mark(long offset, int c)
845 {
846 mark(offset,0,c);
847 if(offset&resMask) {
848 mark(offset,1,c);
849 }
850 }
851
mark(long offset,long offsetlo,int c)852 void SMS :: mark(long offset, long offsetlo, int c)
853 {
854 if(!lo) return;
855 #ifdef MULTITHREADED
856 pthread_mutex_lock(&lo->sliceMutex[c]);
857 #endif
858 Slice *sliceL1 = lo->sliceBuffer[c].read(lo->sliceBuffer[c].readPos+offset/res+offsetlo);
859 #ifdef MULTITHREADED
860 pthread_mutex_unlock(&lo->sliceMutex[c]);
861 #endif
862 #ifdef MULTITHREADED
863 pthread_mutex_lock(&sliceMutex[c]);
864 #endif
865 Slice *sliceM1 = sliceBuffer[c].read(sliceBuffer[c].readPos+offset);
866 #ifdef MULTITHREADED
867 pthread_mutex_unlock(&sliceMutex[c]);
868 #endif
869 bool b0 = !(offset&resMask);
870 bool bDone = false;
871 bool bLastDitch = false;
872 while(!bDone) {
873 int nToCont = 0;
874 int nCont = 0;
875 TrackPoint *rbegin = NULL;
876 TrackPoint *begin = sliceL1->bottom;
877 for(TrackPoint *tp = sliceM1->bottom;
878 tp;
879 tp = tp->pn) {
880 if(tp->bMarked) continue;
881 if(tp->f > maxFMatchM) {
882 break;
883 } else {
884 rbegin = tp;
885 }
886 float F;
887 tp->cont = nearestForward(&begin,tp,&F,maxCost2Match,maxDFMatch,dMCoeff2Match);
888 if(tp->cont) nToCont++;
889 }
890 if(sliceL1) {
891 for(TrackPoint *tp = sliceL1->top;
892 tp;
893 tp = tp->pp) {
894 if(tp->f < minFLo) break;
895 float F;
896 tp->cont = nearestReverse(&rbegin,tp,&F,maxCost2Match,maxDFMatch,dMCoeff2Match);
897 }
898 }
899 for(TrackPoint *tp0 = sliceM1->bottom;
900 tp0;
901 tp0 = tp0->pn) {
902 if(tp0->bMarked) continue;
903 if(tp0->f > maxFMatchM) {
904 break;
905 }
906 TrackPoint *tp1 = tp0->cont;
907 if(tp1) {
908 if(bLastDitch || tp1->cont == tp0) {
909 nCont++;
910 bool bAlreadyMarked = false;
911 if(b0) {
912 if(tp1->dup[1] || tp0->dup[1]) {
913 bAlreadyMarked = true;
914 }
915 } else {
916 if(tp1->dup[2-2*offsetlo] || tp0->dup[2*offsetlo]) {
917 bAlreadyMarked = true;
918 }
919 }
920 if(!bAlreadyMarked) {
921 if(b0) {
922 tp1->dup[1] = tp0;
923 tp0->dup[1] = tp1;
924 } else {
925 tp1->dup[2-2*offsetlo] = tp0;
926 tp0->dup[2*offsetlo] = tp1;
927 }
928 }
929 tp0->bMarked = true;
930 }
931 }
932 }
933 bDone = (nToCont == nCont);
934 bLastDitch = (!bDone && nCont==0);
935 }
936 }
937
assignStart(long offset,int c)938 void SMS :: assignStart(long offset, int c)
939 {
940 bAssignDone[c] = false;
941 #ifdef MULTITHREADED
942 pthread_mutex_lock(&sliceMutex[c]);
943 #endif
944 sliceM0[c] = sliceBuffer[c].read(sliceBuffer[c].readPos+offset);
945 sliceM1[c] = sliceBuffer[c].read(sliceBuffer[c].readPos+offset+1);
946 if(res == 2) {
947 sliceM2[c] = sliceBuffer[c].read(sliceBuffer[c].readPos+offset+2);
948 } else {
949 sliceM2[c] = NULL;
950 }
951 #ifdef MULTITHREADED
952 pthread_mutex_unlock(&sliceMutex[c]);
953 #endif
954 for(TrackPoint *tp = sliceM0[c]->bottom;
955 tp;
956 tp = tp->pn) {
957 if(!tp->owner->bEnded) {
958 tp->owner->bEnd = true;
959 tp->bConnected = false;
960 tp->bOwned = false;
961 } else {
962 tp->bConnected = true;
963 tp->bOwned = true;
964 }
965 }
966 #ifdef MULTITHREADED
967 if(hi) pthread_mutex_lock(&hi->sliceMutex[c]);
968 #endif
969 sliceH0[c] = hi?hi->sliceBuffer[c].read(hi->sliceBuffer[c].readPos+(offset+1)*hi->res):NULL;
970 sliceH0[c] = NULL;
971 sliceH1[c] = hi?hi->sliceBuffer[c].read(hi->sliceBuffer[c].readPos+(offset+1)*hi->res):NULL;
972 #ifdef MULTITHREADED
973 if(hi) pthread_mutex_unlock(&hi->sliceMutex[c]);
974 #endif
975 #ifdef MULTITHREADED
976 if(lo) pthread_mutex_lock(&lo->sliceMutex[c]);
977 #endif
978 sliceL0[c] = lo?lo->sliceBuffer[c].read(lo->sliceBuffer[c].readPos+offset/res+1):NULL;
979 sliceL0[c] = NULL;
980 sliceL1[c] = lo?lo->sliceBuffer[c].read(lo->sliceBuffer[c].readPos+offset/res+1):NULL;
981 #ifdef MULTITHREADED
982 if(lo) pthread_mutex_unlock(&lo->sliceMutex[c]);
983 #endif
984 }
985
assignInit(long offset,int c)986 void SMS :: assignInit(long offset, int c)
987 {
988 for(TrackPoint *tp = sliceM1[c]->bottom;
989 tp;
990 tp = tp->pn) {
991 tp->cont = NULL;
992 tp->contF = TrackPointNoCont;
993 }
994 if(sliceM2[c]) {
995 for(TrackPoint *tp = sliceM2[c]->bottom;
996 tp;
997 tp = tp->pn) {
998 tp->cont = NULL;
999 tp->contF = TrackPointNoCont;
1000 }
1001 }
1002 }
1003
assignFind(long offset,int c)1004 void SMS :: assignFind(long offset, int c)
1005 {
1006 if(bAssignDone[c]) return;
1007 Slice *sliceM0 = this->sliceM0[c];
1008 Slice *sliceM1 = this->sliceM1[c];
1009 Slice *sliceM2 = this->sliceM2[c];
1010 Slice *sliceL1 = this->sliceL1[c];
1011 Slice *sliceH1 = this->sliceH1[c];
1012 TrackPoint *begin;
1013 begin = sliceM0->bottom;
1014 for(TrackPoint *tp = sliceM1->bottom;
1015 tp;
1016 tp = tp->pn) {
1017 if(tp->bOwned) continue;
1018 float F;
1019 tp->bConnect = false;
1020 TrackPoint *minM = nearestForward(&begin,tp,&F,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1021 if(minM && F < tp->contF) {
1022 tp->cont = minM;
1023 tp->contF = F;
1024 }
1025 }
1026 if(sliceL1) {
1027 TrackPoint *rbegin = sliceM0->top;
1028 for(TrackPoint *tp = sliceL1->top;
1029 tp;
1030 tp = tp->pp) {
1031 if(tp->bOwned) continue;
1032 if(tp->f < minFLo) break;
1033 float F;
1034 TrackPoint *minL = nearestReverse(&rbegin,tp,&F,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1035 if(minL) {
1036 F *= localFavorRatio;
1037 if(F < tp->contF) {
1038 tp->cont = minL;
1039 tp->contF = F;
1040 }
1041 }
1042 }
1043 }
1044 begin = sliceM0->bottom;
1045 if(sliceH1) {
1046 for(TrackPoint *tp = sliceH1->bottom;
1047 tp;
1048 tp = tp->pn) {
1049 if(tp->bOwned) continue;
1050 if(tp->f > maxFHi) break;
1051 float F;
1052 TrackPoint *minH = nearestForward(&begin,tp,&F,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1053 if(minH) {
1054 F *= localFavorRatio;
1055 if(F < tp->contF) {
1056 tp->cont = minH;
1057 tp->contF = F;
1058 }
1059 }
1060 }
1061 }
1062 if(sliceM2 && !(offset&resMask)) {
1063 begin = sliceM1->bottom;
1064 for(TrackPoint *tp = sliceM2->bottom;
1065 tp;
1066 tp = tp->pn) {
1067 if(tp->bOwned) continue;
1068 float F;
1069 tp->bConnect = false;
1070 TrackPoint *minM = nearestForward(&begin,tp,&F,maxCost2,maxDF,dMCoeff2);
1071 if(minM) {
1072 tp->cont = minM;
1073 tp->contF = F;
1074 }
1075 }
1076 if(sliceL1) {
1077 for(TrackPoint *tp = sliceM2->bottom;
1078 tp;
1079 tp = tp->pn) {
1080 if(tp->bOwned) continue;
1081 if(tp->f > maxFMid) break;
1082 float F;
1083 TrackPoint *rbegin = sliceL1->top;
1084 TrackPoint *minL = nearestReverse(&rbegin,tp,&F,maxCost2,maxDF,dMCoeff2);
1085 if(minL) {
1086 F *= localFavorRatio;
1087 if(F < tp->contF) {
1088 tp->cont = minL;
1089 tp->contF = F;
1090 }
1091 }
1092 }
1093 }
1094 }
1095 }
1096
assignConnect(long offset,int c,bool bLastDitch)1097 bool SMS :: assignConnect(long offset, int c, bool bLastDitch)
1098 {
1099 if(bAssignDone[c]) return false;
1100 Slice *sliceM0 = this->sliceM0[c];
1101 Slice *sliceM1 = this->sliceM1[c];
1102 Slice *sliceL1 = this->sliceL1[c];
1103 Slice *sliceH1 = this->sliceH1[c];
1104 int nToCont = 0;
1105 int nCont = 0;
1106 bool b0 = !(offset&resMask);
1107 int ilo;
1108 if(res == 2 && b0) {
1109 ilo = 0;
1110 } else {
1111 ilo = 1;
1112 }
1113 TrackPoint *beginM1 = sliceM1->bottom;
1114 TrackPoint *beginH1;
1115 if(sliceH1) beginH1 = sliceH1->bottom;
1116 for(TrackPoint *tp = sliceM0->bottom;
1117 tp;
1118 tp = tp->pn) {
1119 if(tp->bOwned) continue;
1120 float FM1 = TrackPointNoCont;
1121 float FL1 = TrackPointNoCont;
1122 float FH1 = TrackPointNoCont;
1123 TrackPoint *minM1 = nearestForward(&beginM1,tp,&FM1,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1124 TrackPoint *minL1 = NULL;
1125 if(sliceL1 && tp->f < maxFMid) {
1126 TrackPoint *rbeginL1 = sliceL1->top;
1127 minL1 = nearestReverse(&rbeginL1,tp,&FL1,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1128 FL1 *= localFavorRatio;
1129 }
1130 TrackPoint *minH1 = NULL;
1131 if(sliceH1 && tp->f > minFMid) {
1132 minH1 = nearestForward(&beginH1,tp,&FH1,maxCost2,maxDF,dMCoeff2,dNCoeff2);
1133 FH1 *= localFavorRatio;
1134 }
1135 if(minM1 &&
1136 ((FM1<=FH1 && FM1<=FL1)
1137 ||(minL1 && FL1<=FH1 && FL1<=FM1 && minL1->dup[ilo] == minM1)
1138 ||(minH1 && FH1<=FL1 && FH1<=FM1 && minH1->dup[1] == minM1))) {
1139 if(ilo == 1 && minL1 && minL1->dup[1] == minM1) {
1140 tp->dupcont = minL1;
1141 } else if(minH1 && minH1->dup[1] == minM1) {
1142 tp->dupcont = minH1;
1143 } else {
1144 tp->dupcont = NULL;
1145 }
1146 tp->contF = FM1;
1147 tp->cont = minM1;
1148 nToCont++;
1149 } else if(minL1 && FL1<=FM1 && FL1<=FH1) {
1150 if(minM1 && minL1->dup[ilo] == minM1) {
1151 tp->dupcont = minM1;
1152 } else {
1153 tp->dupcont = NULL;
1154 }
1155 tp->contF = FL1;
1156 tp->cont = minL1;
1157 nToCont++;
1158 } else if(minH1 && FH1<=FM1 && FH1<=FL1) {
1159 if(minM1 && minH1->dup[1] == minM1) {
1160 tp->dupcont = minM1;
1161 } else {
1162 tp->dupcont = NULL;
1163 }
1164 tp->contF = FH1;
1165 tp->cont = minH1;
1166 nToCont++;
1167 } else {
1168 tp->cont = NULL;
1169 }
1170 }
1171 for(TrackPoint *tp0 = sliceM0->bottom;
1172 tp0;
1173 tp0 = tp0->pn) {
1174 if(tp0->bOwned) continue;
1175 tp0->bConnect = false;
1176 TrackPoint *tp1 = tp0->cont;
1177 TimeType time = assigntime[c];
1178 if(tp1 && !tp1->bOwned &&
1179 (bLastDitch ||
1180 (tp1->cont == tp0) ||
1181 ((tp1->cont && tp0->contF <= tp1->cont->contF) &&
1182 ((tp1->cont->dup[0] == tp0) ||
1183 (tp1->cont->dup[1] == tp0))))) {
1184 tp1->cont = tp0;
1185 tp0->bConnect = true;
1186 tp1->bConnect = true;
1187 }
1188 }
1189 for(TrackPoint *tp0 = sliceM0->bottom;
1190 tp0;
1191 tp0 = tp0->pn) {
1192 if(tp0->bOwned) continue;
1193 TrackPoint *tp1 = tp0->cont;
1194 if(tp0->bConnect && tp1 && !tp1->bOwned && tp1->bConnect && tp1->cont == tp0) {
1195 TrackPoint *dupcont = tp0->dupcont;
1196 if(dupcont && dupcont->bConnect) {
1197 if(!tp1->bConnected && !dupcont->bConnected) {
1198 if(!tp0->bConnected && (dupcont->cont == NULL || tp0->contF <= dupcont->cont->contF)) {
1199 nCont++;
1200 connect(tp0,tp1,ilo,c);
1201 tp0->owner->bEnd = false;
1202 dupcont->bConnect = false;
1203 } else if(dupcont->cont && !dupcont->cont->bConnected) {
1204 nCont++;
1205 connect(dupcont->cont,dupcont,ilo,c);
1206 dupcont->cont->owner->bEnd = false;
1207 tp1->bConnect = false;
1208 }
1209 }
1210 } else if(!tp0->bConnected && !tp1->bConnected) {
1211 nCont++;
1212 connect(tp0,tp1,ilo,c);
1213 tp0->owner->bEnd = false;
1214 }
1215 }
1216 }
1217 bAssignDone[c] = (nToCont == nCont || bLastDitch);
1218 return !(bAssignDone[c] || nCont == 0);
1219 }
1220
start(long offset,int c)1221 void SMS :: start(long offset, int c)
1222 {
1223 started[c].clear();
1224 ended[c].clear();
1225 #ifdef MULTITHREADED
1226 pthread_mutex_lock(&trackMutex[c]);
1227 #endif
1228 for(list<Track*>::iterator tt = assignTracks[c].begin();
1229 tt != assignTracks[c].end(); ) {
1230 Track *t = (*tt);
1231 bool bKeep;
1232 if(t->bEnded) {
1233 bKeep = ((!t->bRender) && (t->bStitch || t->size() >= minTrackSize));
1234 if(assigntime[c] > t->last) {
1235 returnTrackIndex(c,t);
1236 list<Track*>::iterator eraseMe = tt;
1237 ++tt;
1238 assignTracks[c].erase(eraseMe);
1239 } else {
1240 ++tt;
1241 }
1242 } else if(t->bEnd) {
1243 bKeep = (t->bStitch || t->size() >= minTrackSize);
1244 if(bKeep) {
1245 bKeep = !t->bRender;
1246 t->endTrack(false);
1247 ended[c].push_back(t->back());
1248 ++tt;
1249 } else {
1250 list<Track*>::iterator eraseMe = tt;
1251 ++tt;
1252 assignTracks[c].erase(eraseMe);
1253 returnTrackIndex(c,t);
1254 t->absorb();
1255 delete t;
1256 continue;
1257 }
1258 } else {
1259 bKeep = ((!t->bRender) && (t->bStitch || t->size() >= minTrackSize));
1260 ++tt;
1261 }
1262 if(bKeep) {
1263 list<Track*>::reverse_iterator tt0 = renderTracks[c].rbegin();
1264 while(tt0 != renderTracks[c].rend()) {
1265 Track *t0 = *tt0;
1266 if(t->start >= t0->start) {
1267 break;
1268 }
1269 tt0++;
1270 }
1271 renderTracks[c].insert(tt0.base(),t);
1272 t->bRender = true;
1273 }
1274 }
1275 #ifdef MULTITHREADED
1276 pthread_mutex_unlock(&trackMutex[c]);
1277 #endif
1278 #ifdef MULTITHREADED
1279 pthread_mutex_lock(&sliceMutex[c]);
1280 #endif
1281 Slice *sliceM0 = sliceBuffer[c].read(sliceBuffer[c].readPos+offset);
1282 adjust2SliceQueue[c].push(sliceM0);
1283 adjust1SliceQueue[c].push(sliceM0);
1284 #ifdef MULTITHREADED
1285 pthread_mutex_unlock(&sliceMutex[c]);
1286 #endif
1287 for(TrackPoint *tp = sliceM0->bottom;
1288 tp;) {
1289 TrackPoint *tpn = tp->pn;
1290 if(tp->bOwned) {
1291 if(tp->bDelete) {
1292 tp->destroy();
1293 }
1294 } else {
1295 Track *t = createTrack(c,tp,assigntime[c],false);
1296 started[c].push_back(tp);
1297 for(int d=0;d<2;d++) {
1298 TrackPoint *dup = tp->dup[d];
1299 if(dup && !dup->owner) {
1300 dup->destroy();
1301 }
1302 }
1303 }
1304 tp = tpn;
1305 }
1306 assigntime[c]++;
1307 }
1308
splitMerge(int c)1309 void SMS :: splitMerge(int c)
1310 {
1311 TimeType time = assigntime[c] - 1;
1312 #ifdef MULTITHREADED
1313 pthread_mutex_lock(&trackMutex[c]);
1314 #endif
1315 Slice *sliceM0 = this->sliceM0[c];
1316 Slice *sliceL0 = this->sliceL0[c];
1317 Slice *sliceH0 = this->sliceH0[c];
1318 Slice *sliceM1 = this->sliceM1[c];
1319 Slice *sliceL1 = this->sliceL1[c];
1320 Slice *sliceH1 = this->sliceH1[c];
1321 TrackPoint *rbeginL0 = sliceL0?sliceL0->top:NULL;
1322 TrackPoint *beginM0 = sliceM0->bottom;
1323 TrackPoint *beginH0 = sliceH0?sliceH0->bottom:NULL;
1324 for(list<TrackPoint*>::iterator i = started[c].begin();
1325 i != started[c].end();
1326 ++i) {
1327 TrackPoint *tp = *i;
1328 float F, FL, FH;
1329 tp->cont = nearestForward2(&beginM0,tp,&F,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1330 TrackPoint *minL = nearestReverse2(&rbeginL0,tp,&FL,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1331 if(minL) {
1332 FL *= localFavorRatio;
1333 if(FL < F) {
1334 tp->cont = minL;
1335 F = FL;
1336 }
1337 }
1338 TrackPoint *minH = nearestForward2(&beginH0,tp,&FH,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1339 if(minH) {
1340 FH *= localFavorRatio;
1341 if(FH < F) {
1342 tp->cont = minH;
1343 }
1344 }
1345 if(tp->cont) {
1346 tp->owner->point.insert(tp->owner->point.begin(),tp->cont);
1347 tp->owner->first--;
1348 tp->owner->bStitch = true;
1349 tp->bSplit = true;
1350 tp->cont->bSplit = true;
1351 tp->owner->bSplit = true;
1352 tp->cont->refCount++;
1353 tp->cont->owner->bStitch = true;
1354 }
1355 }
1356
1357 TrackPoint *rbeginL1 = sliceL1?sliceL1->top:NULL;
1358 TrackPoint *beginM1 = sliceM1->bottom;
1359 TrackPoint *beginH1 = sliceH1?sliceH1->bottom:NULL;
1360 for(list<TrackPoint*>::iterator i = ended[c].begin();
1361 i != ended[c].end();
1362 ++i) {
1363 TrackPoint *tp = *i;
1364 float F, FL, FH;
1365 tp->cont = nearestForward2(&beginM1,tp,&F,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1366 TrackPoint *minL = nearestReverse2(&rbeginL1,tp,&FL,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1367 if(minL) {
1368 FL *= localFavorRatio;
1369 if(FL < F) {
1370 tp->cont = minL;
1371 F = FL;
1372 }
1373 }
1374 TrackPoint *minH = nearestForward2(&beginH1,tp,&FH,maxCost2SplitMerge,maxDFSplitMerge,dMCoeff2SplitMerge);
1375 if(minH) {
1376 FH *= localFavorRatio;
1377 if(FH < F) {
1378 tp->cont = minH;
1379 }
1380 }
1381 if(tp->cont) {
1382 tp->owner->point.insert(tp->owner->point.end(),tp->cont);
1383 tp->owner->last++;
1384 tp->owner->bStitch = true;
1385 tp->bMerge = true;
1386 tp->cont->bMerge = true;
1387 tp->owner->bMerge = true;
1388 tp->cont->refCount++;
1389 tp->cont->owner->bStitch = true;
1390 }
1391 }
1392 #ifdef MULTITHREADED
1393 pthread_mutex_unlock(&trackMutex[c]);
1394 #endif
1395 }
1396
advance(int c)1397 void SMS :: advance(int c)
1398 {
1399 #ifdef MULTITHREADED
1400 pthread_mutex_lock(&sliceMutex[c]);
1401 #endif
1402 sliceBuffer[c].advance(1);
1403 #ifdef MULTITHREADED
1404 pthread_mutex_unlock(&sliceMutex[c]);
1405 #endif
1406 }
1407
add(grain * g0,grain * g1,grain * g2,int c)1408 void SMS :: add(grain *g0, grain *g1, grain *g2, int c)
1409 {
1410 if(c == 0) {
1411 if(band >= minTrial1Band) {
1412 c2even(g0->x, x00[0], N);
1413 }
1414 if(band >= minTrial2Band) {
1415 c2even(g1->x, x10[0], N);
1416 }
1417 c2even(g2->x, x2[0], N);
1418 } else {
1419 if(band >= minTrial1Band) {
1420 c2odd(g0->x, x00[1], N);
1421 }
1422 if(band >= minTrial2Band) {
1423 c2odd(g1->x, x10[1], N);
1424 }
1425 c2odd(g2->x, x2[1], N);
1426 }
1427
1428 float *mag0;
1429 if(band >= minTrial1Band) {
1430 mag0 = (float*)malloc((Nover2+1)*sizeof(float));
1431 calcmags(mag0, x00[c]);
1432 }
1433 float *mag1;
1434 if(band >= minTrial2Band) {
1435 mag1 = (float*)malloc((Nover2+1)*sizeof(float));
1436 calcmags(mag1, x10[c]);
1437 }
1438 float mag2sum[1024];
1439 memset(mag2sum,0,1024*sizeof(float));
1440
1441 float *mag2 = this->mag2[c];
1442 calcmags(mag2sum, g2->x);
1443 calcmags(mag2sum, x2[c]);
1444 calcmags(mag2, x2[c]);
1445 #ifdef MULTITHREADED
1446 pthread_mutex_lock(&magMutex[c]);
1447 #endif
1448 if(band >= minTrial1Band) mag0Queue[c].push(mag0);
1449 if(band >= minTrial2Band) mag1Queue[c].push(mag1);
1450 #ifdef MULTITHREADED
1451 pthread_mutex_unlock(&magMutex[c]);
1452 #endif
1453 float magmax = mag2[0];
1454 for(int k=1;k<=kEnd;k++) {
1455 if(magmax < mag2[k]) magmax = mag2[k];
1456 }
1457 float peakmin = magmax * peakThresh;
1458
1459 float xt2 = 1.0f;
1460 bool bTroughN1 = false;
1461 bool bTroughN2 = false;
1462 float x0 = 1.0f;
1463 float y0 = mag2[1];
1464 float x1 = 0.0f;
1465 float y1 = 0.0f;
1466 bool bX0 = !lo;
1467 bool bX1 = false;
1468 TrackPoint *prev = NULL;
1469
1470 Slice *slice = new Slice(band,addtime[c]);
1471
1472 for(int k=1; k<=kEnd; k++) {
1473 if(mag2[k] > peakmin && mag2[k] > mag2[k-1] && mag2[k] >= mag2[k+1]) {
1474 if(k < kLo) {
1475 x0 = findExtremum(mag2,mag2,k,&y0);
1476 bX0 = true;
1477 } else if(k > kHi) {
1478 if(!bX1) {
1479 x1 = findExtremum(mag2,mag2,k,&y1);
1480 if(prev) {
1481 prev->x01 = x1;
1482 prev->y01 = y1;
1483 }
1484 bX1 = true;
1485 }
1486 } else {
1487 TrackPoint *p = new TrackPoint(slice,peak2N,x2[c],mag2,mag2,k,N,band);
1488
1489 if(prev) {
1490 prev->pn = p;
1491 p->pp = prev;
1492 } else {
1493 slice->bottom = p;
1494 }
1495 slice->top = p;
1496 prev = p;
1497 p->xtn2 = (float)maxK;
1498 bTroughN1 = true;
1499 bTroughN2 = true;
1500 p->xtp2 = xt2;
1501 p->x01 = x0;
1502 p->y01 = y0;
1503 }
1504 } else if(mag2[k] <= mag2[k-1] && mag2[k] <= mag2[k+1]) {
1505 xt2 = findExtremum(mag2,mag2,k,NULL);
1506 xt2 = max(1.0f,xt2);
1507 xt2 = min((float)kEnd,xt2);
1508 if(bTroughN2) {
1509 prev->xtn2 = xt2;
1510 bTroughN2 = false;
1511 }
1512 }
1513 }
1514 if(bTroughN2) {
1515 prev->xtn2 = (float)kEnd;
1516 }
1517 if(!bX1 && !hi) {
1518 x1 = (float)kEnd;
1519 y1 = mag2[kEnd];
1520 bX1 = true;
1521 }
1522 float *dec2 = this->dec2[c];
1523 memset(dec2,0,(Nover2+1)*sizeof(float));
1524 if(bX0 && prev) {
1525 int k1 = lrintf(x0);
1526 int ko1 = k1 > x0 ? -1 : 1;
1527 float kf1 = k1 > x0 ? k1 - x0 : x0 - k1;
1528 int k3 = min(kEnd,k1+peakWidth2);
1529 for(int k=lrintf(slice->bottom->xtp2);k<=k3;k++) {
1530 float m = interp2(k-k1,ko1,kf1);
1531 dec2[k] += m * y0;
1532 }
1533 }
1534 if(bX1 && prev) {
1535 int k1 = lrintf(x1);
1536 int ko1 = k1 > x1 ? -1 : 1;
1537 float kf1 = k1 > x1 ? k1 - x1 : x1 - k1;
1538 int k3 = lrintf(slice->top->xtn2);
1539 for(int k=max(0,k1-peakWidth2);k<=k3;k++) {
1540 float m = interp2(k-k1,ko1,kf1);
1541 dec2[k] += m * y1;
1542 }
1543 }
1544 for(TrackPoint *p = slice->bottom;
1545 p;
1546 p = p->pn) {
1547 int k1 = lrintf(p->x);
1548 int ko1 = k1 > p->x ? -1 : 1;
1549 float kf1 = k1 > p->x ? k1 - p->x : p->x - k1;
1550 int k0 = lrintf(p->xtp2);
1551 float kf0 = (k0 > p->xtp2 ? k0 - p->xtp2 : p->xtp2 - k0);
1552 int k2 = lrintf(p->xtn2);
1553 float kf2 = (k2 > p->xtn2 ? k2 - p->xtn2 : p->xtn2 - k2);
1554 float m2 = 0.0f;
1555 if(k0 < p->xtp2) {
1556 m2 += (mag2[k0] + mag2[k0+1]) * 0.5f * (1.0f - kf0) + 0.5f * mag2[k0+1];
1557 int i = k0 - k1;
1558 float m = interp2(i,ko1,kf1) * p->y;
1559 m = min(m,mag2[k0]) * 0.5f * (1.0f + kf0);
1560 m2 += m;
1561 dec2[k0] += m;
1562 m = interp2(i+1,ko1,kf1) * p->y;
1563 m = min(m,mag2[k0+1]) * 0.5f * kf0;
1564 m2 += m;
1565 dec2[k0+1] += m;
1566 m = interp2(i-1,ko1,kf1) * p->y;
1567 m = min(m,mag2[k0-1]);
1568 m2 += m;
1569 dec2[k0-1] += m;
1570 } else {
1571 m2 += (mag2[k0] + mag2[k0-1]) * 0.5f * kf0 + 0.5f * mag2[k0] + mag2[k0+1];
1572 int i = k0 - k1;
1573 float m = interp2(i,ko1,kf1) * p->y;
1574 m = min(m,mag2[k0]) * 0.5f * (1.0f - kf0);
1575 m2 += m;
1576 dec2[k0] += m;
1577 m = interp2(i-1,ko1,kf1) * p->y;
1578 m = min(m,mag2[k0-1]) * 0.5f * (2.0f - kf0);
1579 m2 += m;
1580 dec2[k0-1] += m;
1581 }
1582 if(k2 < p->xtn2) {
1583 m2 += mag2[k2-1] + 0.5f * mag2[k2] + 0.5f * kf2 * (mag2[k2] + mag2[k2+1]);
1584 int i = k2 - k1;
1585 float m = interp2(i,ko1,kf1) * p->y;
1586 m = min(m,mag2[k2]) * 0.5f * (1.0f - kf2);
1587 m2 += m;
1588 dec2[k2] += m;
1589 m = interp2(i+1,ko1,kf1) * p->y;
1590 m = min(m,mag2[k2+1]) * 0.5f * (2.0f - kf2);
1591 m2 += m;
1592 dec2[k2+1] += m;
1593 } else {
1594 m2 += (mag2[k2-1] + mag2[k2]) * (1.0f - kf2) * 0.5f + 0.5f * mag2[k2-1];
1595 int i = k2 - k1;
1596 float m = interp2(i,ko1,kf1) * p->y;
1597 m = min(m,mag2[k2]) * 0.5f * (1.0f + kf2);
1598 m2 += m;
1599 dec2[k2] += m;
1600 m = interp2(i-1,ko1,kf1) * p->y;
1601 m = min(m,mag2[k2-1]) * 0.5f * kf2;
1602 m2 += m;
1603 dec2[k2-1] += m;
1604 m = interp2(i+1,ko1,kf1) * p->y;
1605 m = min(m,mag2[k2+1]);
1606 m2 += m;
1607 dec2[k2+1] += m;
1608 }
1609 for(int k=k0+2;k<k2-1;k++) {
1610 m2 += mag2[k];
1611 }
1612 if(k0 + 1 == k2 - 1) {
1613 m2 -= mag2[k0+1];
1614 }
1615 for(int k=max(0,k1-peakWidth2);k<k0-1;k++) {
1616 float m = interp2(k-k1,ko1,kf1) * p->y;
1617 m = min(m,mag2[k]);
1618 m2 += m;
1619 dec2[k] += m;
1620 }
1621 int k3 = min(kEnd,k1+peakWidth2);
1622 for(int k=k2+2;k<=k3;k++) {
1623 float m = interp2(k-k1,ko1,kf1) * p->y;
1624 m = min(m,mag2[k]);
1625 m2 += m;
1626 dec2[k] += m;
1627 }
1628 p->m2 = m2;
1629 }
1630 float m2max = 0.0f;
1631 for(TrackPoint *p = slice->bottom;
1632 p;
1633 p = p->pn) {
1634 int k1 = lrintf(p->x);
1635 int ko1 = k1 > p->x ? -1 : 1;
1636 float kf1 = k1 > p->x ? k1 - p->x : p->x - k1;
1637 int k0 = lrintf(p->xtp2);
1638 float kf0 = (k0 > p->xtp2 ? k0 - p->xtp2 : p->xtp2 - k0);
1639 int k2 = lrintf(p->xtn2);
1640 float kf2 = (k2 > p->xtn2 ? k2 - p->xtn2 : p->xtn2 - k2);
1641 float mdec = 0.0f;
1642 if(k0 < p->xtp2) {
1643 mdec += (dec2[k0] + dec2[k0+1]) * 0.5f * (1.0f - kf0) + 0.5f * dec2[k0+1];
1644 } else {
1645 mdec += (dec2[k0] + dec2[k0-1]) * 0.5f * kf0 + 0.5f * dec2[k0] + dec2[k0+1];
1646 }
1647 if(k2 < p->xtn2) {
1648 mdec += dec2[k2-1] + 0.5f * dec2[k2] + 0.5f * kf2 * (dec2[k2] + dec2[k2+1]);
1649 } else {
1650 mdec += (dec2[k2-1] + dec2[k2]) * (1.0f - kf2) * 0.5f + 0.5f * dec2[k2-1];
1651 }
1652 for(int k=k0+2;k<k2-1;k++) {
1653 mdec += dec2[k];
1654 }
1655 if(k0 + 1 == k2 - 1) {
1656 mdec -= dec2[k0+1];
1657 }
1658
1659 p->m2 -= mdec;
1660 p->m2 *= mNorm;
1661 if(p->m2 > m2max) {
1662 m2max = p->m2;
1663 }
1664 }
1665 float m2min = m2max * peakThresh;
1666 for(TrackPoint *p = slice->bottom;
1667 p; ) {
1668 TrackPoint *pn = p->pn;
1669 if(p->m2 < m2min) {
1670 if(p->m2 < 0) { p->m2 = 0; }
1671 p->absorb();
1672 delete p;
1673 }
1674 p = pn;
1675 }
1676
1677 #ifdef MULTITHREADED
1678 pthread_mutex_lock(&sliceMutex[c]);
1679 #endif
1680 sliceBuffer[c].write(slice);
1681 #ifdef MULTITHREADED
1682 pthread_mutex_unlock(&sliceMutex[c]);
1683 #endif
1684 addtime[c]++;
1685 }
1686
prepad1(audio * buf,long n)1687 void SMS :: prepad1(audio *buf, long n)
1688 {
1689 if(band >= minTrial2Band) {
1690 trial2GrainBuf->write(buf,n);
1691 }
1692 }
1693
prepad0(audio * buf,long n)1694 void SMS :: prepad0(audio *buf, long n)
1695 {
1696 if(band >= minTrial1Band) {
1697 trial1GrainBuf->write(buf,n);
1698 }
1699 }
1700
getTrial2Latency()1701 int SMS :: getTrial2Latency()
1702 {
1703 return minTrackSize;
1704 }
1705
createTrack(int c,TrackPoint * tp,const TimeType & time,bool bStitch)1706 Track *SMS :: createTrack(int c, TrackPoint *tp, const TimeType &time, bool bStitch)
1707 {
1708 TrackIndexType index;
1709 if(trackIndex[c].empty()) {
1710 index = trackIndexNone;
1711 } else {
1712 index = trackIndex[c].front();
1713 trackIndex[c].pop();
1714 }
1715 Track *t = new Track(h1,index,tp,time,bStitch);
1716 assignTracks[c].push_back(t);
1717 return t;
1718 }
1719
returnTrackIndex(int c,Track * t)1720 void SMS :: returnTrackIndex(int c, Track *t)
1721 {
1722 if(t->index != trackIndexNone) {
1723 trackIndex[c].push(t->index);
1724 t->index = trackIndexNone;
1725 }
1726 }
1727
interp2(int k,int ko,float kf)1728 float SMS :: interp2(int k, int ko, float kf) {
1729 return (1.0f-kf)*peak2N[k] + kf*peak2N[k+ko];
1730 }
1731
findExtremum(float * mag,float * mag2,int k,float * y)1732 float SMS :: findExtremum(float *mag, float *mag2, int k, float *y)
1733 {
1734 float y0 = mag[k-1];
1735 float y1 = mag[k];
1736 float y2 = mag[k+1];
1737 float d = (y0 + y2 - y1 - y1);
1738 float x = (d==0.0f?k:k + 0.5f * (y0 - y2) / d);
1739 if(y) {
1740 int ki = lrintf(x);
1741 float kf = ki<x?x-ki:ki-x;
1742 int ki1 = ki<k?ki+1:ki-1;
1743 *y = ((1.0f-kf)*mag2[ki] + kf*mag2[ki1]);
1744 }
1745 return x;
1746 }
1747
calcmags(float * mag,audio * x)1748 void SMS :: calcmags(float *mag, audio *x) {
1749 for(int k=0;k<=Nover2;k++) {
1750 mag[k] = norm2(x[k]);
1751 }
1752 }
1753
SynthRenderer(int channels,int h)1754 SynthRenderer :: SynthRenderer(int channels, int h)
1755 {
1756 this->channels = channels;
1757 for(int c=0; c<channels; c++) {
1758 sines[c] = new ArrayRingBuffer<float>(0);
1759 synthBufLength[c] = h << 4;
1760 synthBuf[c] = (float*)malloc(synthBufLength[c]*sizeof(float));
1761 }
1762 #ifdef MULTITHREADED
1763 pthread_mutex_init(&bufferMutex,NULL);
1764 #endif
1765 }
1766
~SynthRenderer()1767 SynthRenderer :: ~SynthRenderer()
1768 {
1769 for(int c=0; c<channels; c++) {
1770 delete sines[c];
1771 free(synthBuf[c]);
1772 }
1773 }
1774
startTime(int c,const TimeType & time,int n)1775 void SynthRenderer :: startTime(int c, const TimeType &time, int n)
1776 {
1777 if(n > synthBufLength[c]) {
1778 free(synthBuf[c]);
1779 synthBufLength[c] = n << 1;
1780 synthBuf[c] = (float*)malloc(synthBufLength[c]*sizeof(float));
1781 }
1782 this->n[c] = n;
1783 this->time[c] = time;
1784 memset(synthBuf[c],0,n*sizeof(float));
1785 }
1786
render(int c,SBSMSTrack * t)1787 void SynthRenderer :: render(int c, SBSMSTrack *t)
1788 {
1789 ((Track*)t)->synth(synthBuf[c],time[c],n[c],synthModeOutput,c);
1790 }
1791
endTime(int c)1792 void SynthRenderer :: endTime(int c)
1793 {
1794 #ifdef MULTITHREADED
1795 pthread_mutex_lock(&bufferMutex);
1796 #endif
1797 int n = this->n[c];
1798 sines[c]->grow(n);
1799 long j = sines[c]->writePos;
1800 float *dest = sines[c]->buf;
1801 float *src = synthBuf[c];
1802 for(int k=0; k<n; k++) {
1803 dest[j++] += src[k];
1804 }
1805 sines[c]->writePos += n;
1806 #ifdef MULTITHREADED
1807 pthread_mutex_unlock(&bufferMutex);
1808 #endif
1809 }
1810
read(audio * out,long n)1811 long SynthRenderer :: read(audio *out, long n)
1812 {
1813 #ifdef MULTITHREADED
1814 pthread_mutex_lock(&bufferMutex);
1815 #endif
1816 n = min(n,sines[0]->nReadable());
1817 for(int c=1; c<channels; c++) {
1818 n = min(n,sines[c]->nReadable());
1819 }
1820 for(int c=0; c<channels; c++) {
1821 float *buf = sines[c]->getReadBuf();
1822 for(int k=0; k<n; k++) {
1823 out[k][c] = buf[k];
1824 }
1825 sines[c]->advance(n);
1826 }
1827 #ifdef MULTITHREADED
1828 pthread_mutex_unlock(&bufferMutex);
1829 #endif
1830 return n;
1831 }
1832
1833 }
1834