46 int ComputeTempoOSC (
STempo *,
int,
int,
int,
int *, lo_address *,
int,
int);
47 int ComputeTempoOSCRL(
STempoRL *,
int,
int,
int,
int *, lo_address *,
int);
57 static const MyType WeighGauss[SizeGauss]={0.10, 0.15, 0.20, 0.25, 0.30};
58 static MyType SpeedGauss[SizeGauss]={1.00, 1.00, 1.00, 1.00, 1.00};
63 void pqsort(MyType *,
int);
71 void pqsort(MyType *v,
int size)
75 #pragma omp single nowait 76 { pqsort_inner(v, 0, size-1, size/omp_get_num_threads()); }
81 void pqsort_inner(MyType *,
int,
int,
int);
91 void pqsort_inner(MyType *v,
int left,
int right,
int cutoff)
94 MyType tmp, pivot=v[(left + right) / 2];
98 while (v[i] < pivot) i++;
99 while (v[j] > pivot) j--;
101 if (i <= j) { tmp = v[i]; v[i] = v[j]; v[j] = tmp; i++; j--; }
104 if (((right-left)<cutoff)) {
105 if (left < j) { pqsort_inner(v, left, j, cutoff); }
106 if (i < right) { pqsort_inner(v, i, right, cutoff); }
109 #pragma omp task untied mergeable 110 { pqsort_inner(v, left, j, cutoff); }
111 #pragma omp task untied mergeable 112 { pqsort_inner(v, i, right, cutoff); }
114 #pragma omp task untied 115 { pqsort_inner(v, left, j, cutoff); }
116 #pragma omp task untied 117 { pqsort_inner(v, i, right, cutoff); }
122 int cmpfunc(
const void *,
const void *);
132 if (*(MyType *)a < *(MyType *)b)
134 else if (*(MyType *)a == *(MyType *)b)
153 MyType a=.0, b=.0, lerr=.0, slopes[NUMAPPAIRS], err[NUMAPMAX];
154 int i, j, N, M, idx=0;
156 if (L > NUMAPMAX) { N=NUMAPMAX; }
else { N=L; }
162 #pragma omp parallel for private(j, idx) 165 idx=i*N-((i+2)*(i+1)/2);
166 for (j=i+1; j<N; j++)
167 slopes[idx+j] = (MyType)(y[j]-y[i]) / (MyType)(x[j]-x[i]);
170 for (i = 0; i < N; i++)
171 for (j = i+1; j < N; j++)
173 slopes[idx] = (MyType)(y[j]-y[i]) / (MyType)(x[j]-x[i]);
182 qsort (slopes, M,
sizeof(MyType),
cmpfunc);
186 { a = (slopes[M/2-1] + slopes[M/2]) / 2; }
188 { a = slopes[(M-1)/2]; }
189 if ((a < 0.8) || (a > 1.2)) { *outlier = 1;
return a; }
192 #pragma omp parallel for reduction(+: b) 195 b = b + (y[i] - a*x[i]);
203 #pragma omp parallel for reduction(+: b) 206 for (i = 0; i < N; i++)
208 err[i] = fabsf(y[i] - (a*x[i] + b));
210 err[i] = fabs (y[i] - (a*x[i] + b));
214 lerr = err[(L-1)%NUMAPMAX];
218 qsort (err, N,
sizeof(MyType),
cmpfunc);
221 { *outlier = (lerr > err[N/2-1]); }
223 { *outlier = (lerr > err[(N-1)/2]); }
244 int ComputeTempoOSC(
STempo *TEMPO,
int current,
int pos_min,
int count_min,
int *states_corr, lo_address *DirOSC,
int NCli,
int NStates)
247 MyType nextScoreTime, Speed;
249 if ((count_min > TEMPO->PrevState) && (states_corr[count_min]==1) && (count_min < (NStates-1)))
252 Speed=((pos_min - TEMPO->MidiFrame) * TrainJumpTime) / ((current - TEMPO->RealFrame) * RunJumpTime);
254 TEMPO->SynthTime = ((current - TEMPO->RealFrame) * TrainJumpTime) * TEMPO->SynthSpeed + TEMPO->SynthTime;
256 nextScoreTime = DelayTimeMidi * Speed + pos_min * TrainJumpTime;
258 TEMPO->SynthSpeed = (nextScoreTime - TEMPO->SynthTime) / DelayTimeMidi;
262 for (i=0; i<SizeGauss-1; i++)
264 Speed += SpeedGauss[i]*WeighGauss[i];
265 SpeedGauss[i]= SpeedGauss[i+1];
267 Speed += SpeedGauss[SizeGauss-1]*WeighGauss[SizeGauss-1];
269 if (TEMPO->SynthSpeed < 0)
270 { TEMPO->SynthSpeed = 0.25; }
271 else if (TEMPO->SynthSpeed > (1.2*Speed))
272 { TEMPO->SynthSpeed = (1.2*Speed); }
273 else if (TEMPO->SynthSpeed < (0.8*Speed))
274 { TEMPO->SynthSpeed = (0.8*Speed); }
275 SpeedGauss[SizeGauss-1]=TEMPO->SynthSpeed;
277 TEMPO->MidiFrame=pos_min;
278 TEMPO->RealFrame=current;
279 TEMPO->PrevState=count_min;
281 TEMPO->SoloSpeed = Speed;
282 TEMPO->NextFrame = current + round((TEMPO->SynthTime - pos_min*TrainJumpTime)/(TEMPO->SoloSpeed - TEMPO->SynthSpeed) / TrainJumpTime);
284 printf(
"Vmatch: frame %d pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
286 for (i=0; i<NCli; i++) CHECKERR(SendTempo(DirOSC[i], TEMPO->SynthSpeed*100));
288 else if (TEMPO->NextFrame == current) {
290 TEMPO->SynthSpeed = TEMPO->SoloSpeed;
292 printf(
"Vtempo: matching with the soloist. Frame %d, pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
294 for (i=0; i<NCli; i++) CHECKERR(SendTempo(DirOSC[i], TEMPO->SynthSpeed*100));
313 int ComputeTempoOSCRL(
STempoRL *TEMPO,
int current,
int pos_min,
int count_min,
int *states_corr, lo_address *DirOSC,
int NCli)
316 MyType SoloTime, TimeDiff, SpeedDiff, a;
320 TEMPO->SynthTime = TEMPO->SynthTime + TEMPO->SynthSpeed*(MyType)RunJumpTime;
323 if ((count_min > TEMPO->PrevState) && (states_corr[count_min]==1))
326 TEMPO->AudioTimeAP[TEMPO->numap % NUMAPMAX] = current;
327 TEMPO->ScoreTimeAP[TEMPO->numap % NUMAPMAX] = pos_min;
329 TEMPO->PrevState = count_min;
332 SoloTime = (MyType)pos_min * (MyType)TrainJumpTime;
334 TimeDiff = fabsf(TEMPO->SynthTime - SoloTime);
336 TimeDiff = fabs (TEMPO->SynthTime - SoloTime);
340 if ((TEMPO->matched) && (TimeDiff>0.050))
342 a =
TheilSenRegression(TEMPO->AudioTimeAP, TEMPO->ScoreTimeAP, TEMPO->numap, &outlier);
346 TEMPO->SoloSpeed = a;
349 TEMPO->SynthSpeed = TEMPO->SoloSpeed * (SoloTime + DelayTimeMidi - TEMPO->SynthTime) / DelayTimeMidi;
350 if (TEMPO->SynthSpeed < (MyType)0.1)
351 TEMPO->SynthSpeed = (MyType)0.1;
352 else if (TEMPO->SynthSpeed > (MyType)3.0)
353 TEMPO->SynthSpeed = (MyType)3.0;
356 for (i=0; i<NCli; i++) CHECKERR(SendTempo(DirOSC[i], TEMPO->SynthSpeed*100));
360 SpeedDiff = fabsf(TEMPO->SoloSpeed - TEMPO->SynthSpeed);
361 TEMPO->NextFrame = current + (int)roundf(TimeDiff / SpeedDiff / (MyType)RunJumpTime);
363 SpeedDiff = fabs(TEMPO->SoloSpeed - TEMPO->SynthSpeed);
364 TEMPO->NextFrame = current + (int)round (TimeDiff / SpeedDiff / (MyType)RunJumpTime);
368 printf(
"Vmatch: frame %d pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
374 if (TEMPO->NextFrame == current)
377 TEMPO->SynthSpeed = TEMPO->SoloSpeed;
379 for (i=0; i<NCli; i++) CHECKERR(SendTempo(DirOSC[i], TEMPO->SynthSpeed*100));
381 printf(
"Vtempo: matching with the soloist. Frame %d, pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
401 void ComputeTempo(
STempo *TEMPO,
int current,
int pos_min,
int count_min,
int *states_corr,
int NStates)
404 MyType nextScoreTime, Speed;
406 if ((count_min > TEMPO->PrevState) && (states_corr[count_min]==1) && (count_min < (NStates-1)))
409 Speed=((pos_min - TEMPO->MidiFrame) * TrainJumpTime) / ((current - TEMPO->RealFrame) * RunJumpTime);
411 TEMPO->SynthTime = ((current - TEMPO->RealFrame) * TrainJumpTime) * TEMPO->SynthSpeed + TEMPO->SynthTime;
413 nextScoreTime = DelayTimeMidi * Speed + pos_min * TrainJumpTime;
415 TEMPO->SynthSpeed = (nextScoreTime - TEMPO->SynthTime) / DelayTimeMidi;
419 for (i=0; i<SizeGauss-1; i++)
421 Speed += SpeedGauss[i]*WeighGauss[i];
422 SpeedGauss[i]= SpeedGauss[i+1];
424 Speed += SpeedGauss[SizeGauss-1]*WeighGauss[SizeGauss-1];
426 if (TEMPO->SynthSpeed < 0)
427 { TEMPO->SynthSpeed = 0.25; }
428 else if (TEMPO->SynthSpeed > (1.2*Speed))
429 { TEMPO->SynthSpeed = (1.2*Speed); }
430 else if (TEMPO->SynthSpeed < (0.8*Speed))
431 { TEMPO->SynthSpeed = (0.8*Speed); }
432 SpeedGauss[SizeGauss-1]=TEMPO->SynthSpeed;
434 TEMPO->MidiFrame=pos_min;
435 TEMPO->RealFrame=current;
436 TEMPO->PrevState=count_min;
438 TEMPO->SoloSpeed = Speed;
439 TEMPO->NextFrame = current + round((TEMPO->SynthTime - pos_min*TrainJumpTime)/(TEMPO->SoloSpeed - TEMPO->SynthSpeed) / TrainJumpTime);
441 printf(
"Vmatch: frame %d pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
444 else if (TEMPO->NextFrame == current)
447 TEMPO->SynthSpeed = TEMPO->SoloSpeed;
449 printf(
"Vtempo: matching with the soloist. Frame %d, pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
468 MyType SoloTime, TimeDiff, SpeedDiff, a;
472 TEMPO->SynthTime = TEMPO->SynthTime + TEMPO->SynthSpeed*(MyType)RunJumpTime;
475 if ((count_min > TEMPO->PrevState) && (states_corr[count_min]==1))
478 TEMPO->AudioTimeAP[TEMPO->numap % NUMAPMAX] = current;
479 TEMPO->ScoreTimeAP[TEMPO->numap % NUMAPMAX] = pos_min;
481 TEMPO->PrevState = count_min;
484 SoloTime = (MyType)pos_min * (MyType)TrainJumpTime;
486 TimeDiff = fabsf(TEMPO->SynthTime - SoloTime);
488 TimeDiff = fabs (TEMPO->SynthTime - SoloTime);
492 if ((TEMPO->matched) && (TimeDiff>0.050))
494 a =
TheilSenRegression(TEMPO->AudioTimeAP, TEMPO->ScoreTimeAP, TEMPO->numap, &outlier);
498 TEMPO->SoloSpeed = a;
501 TEMPO->SynthSpeed = TEMPO->SoloSpeed * (SoloTime + DelayTimeMidi - TEMPO->SynthTime) / DelayTimeMidi;
502 if (TEMPO->SynthSpeed < (MyType)0.1)
503 TEMPO->SynthSpeed = (MyType)0.1;
504 else if (TEMPO->SynthSpeed > (MyType)3.0)
505 TEMPO->SynthSpeed = (MyType)3.0;
509 SpeedDiff = fabsf(TEMPO->SoloSpeed - TEMPO->SynthSpeed);
510 TEMPO->NextFrame = current + (int)roundf(TimeDiff / SpeedDiff / (MyType)RunJumpTime);
512 SpeedDiff = fabs(TEMPO->SoloSpeed - TEMPO->SynthSpeed);
513 TEMPO->NextFrame = current + (int)round (TimeDiff / SpeedDiff / (MyType)RunJumpTime);
517 printf(
"Vmatch: frame %d pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
523 if (TEMPO->NextFrame == current)
526 TEMPO->SynthSpeed = TEMPO->SoloSpeed;
529 printf(
"Vtempo: matching with the soloist. Frame %d, pos_min %d SynthSpeed %1.5f\n", current, pos_min, TEMPO->SynthSpeed);
Struct for Compute tempos.
File with functions used by ReMAS, both CPU and GPU, for management communications.
int cmpfunc(const void *, const void *)
cmpfunc compares two values.
void ComputeTempo(STempo *, int, int, int, int *, int)
ComputeTempo calculates the tempo for current frame using gaussian filter.
General header file with constants, defines, structs, etc. using by ReMAS, both CPU and GPU...
void ComputeTempoRL(STempoRL *, int, int, int, int *)
ComputeTempoRL calculates tempo and controls synthesizer speed using linear regression.
Struct for Compute tempos.
MyType TheilSenRegression(int *, int *, int, bool *)
TheilSenRegression computes Theil-Sen linear regression.