|
@@ -2498,10 +2498,10 @@ cmRC_t cmPvSynDoIt( cmPvSyn* p, const cmSample_t* v )
|
2498
|
2498
|
return cmOkRC;
|
2499
|
2499
|
}
|
2500
|
2500
|
|
2501
|
|
-
|
2502
|
2501
|
const cmSample_t* cmPvSynExecOut(cmPvSyn* p )
|
2503
|
2502
|
{ return cmOlaExecOut(&p->ola); }
|
2504
|
2503
|
|
|
2504
|
+
|
2505
|
2505
|
//------------------------------------------------------------------------------------------------------------
|
2506
|
2506
|
cmMidiSynth* cmMidiSynthAlloc( cmCtx* ctx, cmMidiSynth* ap, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate )
|
2507
|
2507
|
{
|
|
@@ -5947,9 +5947,9 @@ cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* x, unsigned bandN )
|
5947
|
5947
|
cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
|
5948
|
5948
|
{
|
5949
|
5949
|
cmSpecDist_t* p = cmObjAlloc( cmSpecDist_t, ctx, ap );
|
5950
|
|
-
|
|
5950
|
+
|
5951
|
5951
|
//p->iSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
|
5952
|
|
- //p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
|
|
5952
|
+ //p->oSpecVa = cmVectArrayAlloc(ctx,kRealVaFl);
|
5953
|
5953
|
p->statVa = cmVectArrayAlloc(ctx,kDoubleVaFl);
|
5954
|
5954
|
|
5955
|
5955
|
if( procSmpCnt != 0 )
|
|
@@ -6459,6 +6459,203 @@ const cmSample_t* cmSpecDistOut( cmSpecDist_t* p )
|
6459
|
6459
|
return cmPvSynExecOut(p->pvs);
|
6460
|
6460
|
}
|
6461
|
6461
|
|
|
6462
|
+
|
|
6463
|
+//------------------------------------------------------------------------------------------------------------
|
|
6464
|
+cmSpecDist2_t* cmSpecDist2Alloc( cmCtx* ctx,cmSpecDist2_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
|
|
6465
|
+{
|
|
6466
|
+ cmSpecDist2_t* p = cmObjAlloc( cmSpecDist2_t, ctx, ap );
|
|
6467
|
+
|
|
6468
|
+ if( procSmpCnt != 0 )
|
|
6469
|
+ {
|
|
6470
|
+ if( cmSpecDist2Init( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC )
|
|
6471
|
+ cmSpecDist2Free(&p);
|
|
6472
|
+ }
|
|
6473
|
+
|
|
6474
|
+ return p;
|
|
6475
|
+
|
|
6476
|
+}
|
|
6477
|
+
|
|
6478
|
+cmRC_t cmSpecDist2Free( cmSpecDist2_t** pp )
|
|
6479
|
+{
|
|
6480
|
+ if( pp == NULL || *pp == NULL )
|
|
6481
|
+ return cmOkRC;
|
|
6482
|
+
|
|
6483
|
+ cmSpecDist2_t* p = *pp;
|
|
6484
|
+
|
|
6485
|
+ cmSpecDist2Final(p);
|
|
6486
|
+ cmObjFree(pp);
|
|
6487
|
+ return cmOkRC;
|
|
6488
|
+
|
|
6489
|
+}
|
|
6490
|
+
|
|
6491
|
+cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
|
|
6492
|
+{
|
|
6493
|
+ cmRC_t rc;
|
|
6494
|
+ if((rc = cmSpecDist2Final(p)) != cmOkRC )
|
|
6495
|
+ return rc;
|
|
6496
|
+
|
|
6497
|
+ unsigned flags = 0;
|
|
6498
|
+
|
|
6499
|
+
|
|
6500
|
+ p->srate = srate;
|
|
6501
|
+ p->wndSmpCnt = wndSmpCnt;
|
|
6502
|
+ p->hopSmpCnt = (unsigned)floor(wndSmpCnt/hopFcmt);
|
|
6503
|
+ p->procSmpCnt = procSmpCnt;
|
|
6504
|
+
|
|
6505
|
+ p->ceiling = 30;
|
|
6506
|
+ p->expo = 2.0;
|
|
6507
|
+
|
|
6508
|
+ p->thresh = 60;
|
|
6509
|
+ p->uprSlope = 0.0;
|
|
6510
|
+ p->lwrSlope = 2.0;
|
|
6511
|
+
|
|
6512
|
+ p->mix = 0.0;
|
|
6513
|
+
|
|
6514
|
+ p->pva = cmPvAnlAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, flags );
|
|
6515
|
+ p->pvs = cmPvSynAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, olaWndTypeId );
|
|
6516
|
+
|
|
6517
|
+
|
|
6518
|
+ return rc;
|
|
6519
|
+}
|
|
6520
|
+
|
|
6521
|
+cmRC_t cmSpecDist2Final(cmSpecDist2_t* p )
|
|
6522
|
+{
|
|
6523
|
+ cmRC_t rc = cmOkRC;
|
|
6524
|
+
|
|
6525
|
+
|
|
6526
|
+ cmPvAnlFree(&p->pva);
|
|
6527
|
+ cmPvSynFree(&p->pvs);
|
|
6528
|
+ return rc;
|
|
6529
|
+}
|
|
6530
|
+
|
|
6531
|
+void _cmSpecDist2Bump( cmSpecDist2_t* p, cmReal_t* x, unsigned binCnt, double thresh, double expo)
|
|
6532
|
+{
|
|
6533
|
+ unsigned i = 0;
|
|
6534
|
+ double minDb = -100.0;
|
|
6535
|
+
|
|
6536
|
+ thresh = -fabs(thresh);
|
|
6537
|
+
|
|
6538
|
+ for(i=0; i<binCnt; ++i)
|
|
6539
|
+ {
|
|
6540
|
+ double y;
|
|
6541
|
+
|
|
6542
|
+ if( x[i] < minDb )
|
|
6543
|
+ x[i] = minDb;
|
|
6544
|
+
|
|
6545
|
+ if( x[i] > thresh )
|
|
6546
|
+ y = 1;
|
|
6547
|
+ else
|
|
6548
|
+ {
|
|
6549
|
+ y = (minDb - x[i])/(minDb - thresh);
|
|
6550
|
+ y += y - pow(y,expo);
|
|
6551
|
+ }
|
|
6552
|
+
|
|
6553
|
+ x[i] = minDb + (-minDb) * y;
|
|
6554
|
+
|
|
6555
|
+ }
|
|
6556
|
+}
|
|
6557
|
+
|
|
6558
|
+void _cmSpecDist2BasicMode(cmSpecDist2_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh, double upr, double lwr )
|
|
6559
|
+{
|
|
6560
|
+
|
|
6561
|
+ unsigned i=0;
|
|
6562
|
+
|
|
6563
|
+ if( lwr < 0.3 )
|
|
6564
|
+ lwr = 0.3;
|
|
6565
|
+
|
|
6566
|
+ for(i=0; i<binCnt; ++i)
|
|
6567
|
+ {
|
|
6568
|
+ cmReal_t a = fabs(X1m[i]);
|
|
6569
|
+ cmReal_t d = a - thresh;
|
|
6570
|
+
|
|
6571
|
+ X1m[i] = -thresh;
|
|
6572
|
+
|
|
6573
|
+ if( d > 0 )
|
|
6574
|
+ X1m[i] -= (lwr*d);
|
|
6575
|
+ else
|
|
6576
|
+ X1m[i] -= (upr*d);
|
|
6577
|
+ }
|
|
6578
|
+
|
|
6579
|
+}
|
|
6580
|
+
|
|
6581
|
+cmRC_t cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn )
|
|
6582
|
+{
|
|
6583
|
+
|
|
6584
|
+ assert( sn == p->procSmpCnt );
|
|
6585
|
+
|
|
6586
|
+ unsigned binN = p->pva->binCnt;
|
|
6587
|
+
|
|
6588
|
+ // cmPvAnlExec() returns true when it calc's a new spectral output frame
|
|
6589
|
+ if( cmPvAnlExec( p->pva, sp, sn ) )
|
|
6590
|
+ {
|
|
6591
|
+ cmReal_t X0m[binN];
|
|
6592
|
+ cmReal_t X1m[binN];
|
|
6593
|
+
|
|
6594
|
+ // take the mean of the the input magntitude spectrum
|
|
6595
|
+ cmReal_t u0 = cmVOR_Mean(p->pva->magV,binN);
|
|
6596
|
+
|
|
6597
|
+ // convert magnitude to db (range=-1000.0 to 0.0)
|
|
6598
|
+ cmVOR_AmplToDbVV(X0m, binN, p->pva->magV, -1000.0 );
|
|
6599
|
+ cmVOR_Copy(X1m,binN,X0m);
|
|
6600
|
+
|
|
6601
|
+ // bump transform X0m
|
|
6602
|
+ _cmSpecDist2Bump(p,X0m, binN, p->ceiling, p->expo);
|
|
6603
|
+
|
|
6604
|
+ // xfade bump output with raw input: X1m = (X0m*mix) + (X1m*(1.0-mix))
|
|
6605
|
+ cmVOR_MultVS(X0m,binN,p->mix);
|
|
6606
|
+ cmVOR_MultVS(X1m,binN,1.0 - p->mix );
|
|
6607
|
+ cmVOR_AddVV(X1m,binN,X0m);
|
|
6608
|
+
|
|
6609
|
+ // basic transform
|
|
6610
|
+ _cmSpecDist2BasicMode(p,X1m,binN,p->thresh,p->uprSlope,p->lwrSlope);
|
|
6611
|
+
|
|
6612
|
+ // convert db back to magnitude
|
|
6613
|
+ cmVOR_DbToAmplVV(X1m, binN, X1m );
|
|
6614
|
+
|
|
6615
|
+
|
|
6616
|
+ // convert the mean input magnitude to db
|
|
6617
|
+ cmReal_t idb = 20*log10(u0);
|
|
6618
|
+
|
|
6619
|
+ // get the mean output magnitude spectra
|
|
6620
|
+ cmReal_t u1 = cmVOR_Mean(X1m,binN);
|
|
6621
|
+
|
|
6622
|
+ if( idb > -150.0 )
|
|
6623
|
+ {
|
|
6624
|
+ // set the output gain such that the mean output magnitude
|
|
6625
|
+ // will match the mean input magnitude
|
|
6626
|
+ p->ogain = u0/u1;
|
|
6627
|
+ }
|
|
6628
|
+ else
|
|
6629
|
+ {
|
|
6630
|
+ cmReal_t a0 = 0.9;
|
|
6631
|
+ p->ogain *= a0;
|
|
6632
|
+ }
|
|
6633
|
+
|
|
6634
|
+ // apply the output gain
|
|
6635
|
+ cmVOR_MultVS(X1m,binN,cmMin(4.0,p->ogain));
|
|
6636
|
+
|
|
6637
|
+
|
|
6638
|
+ // convert back to time domain
|
|
6639
|
+ cmPvSynExec(p->pvs, X1m, p->pva->phsV );
|
|
6640
|
+
|
|
6641
|
+ p->fi += 1;
|
|
6642
|
+ }
|
|
6643
|
+
|
|
6644
|
+ return cmOkRC;
|
|
6645
|
+}
|
|
6646
|
+
|
|
6647
|
+
|
|
6648
|
+const cmSample_t* cmSpecDist2Out( cmSpecDist2_t* p )
|
|
6649
|
+{
|
|
6650
|
+ return cmPvSynExecOut(p->pvs);
|
|
6651
|
+}
|
|
6652
|
+
|
|
6653
|
+void cmSpecDist2Report( cmSpecDist2_t* p )
|
|
6654
|
+{
|
|
6655
|
+ printf("ceil:%f expo:%f mix:%f thresh:%f upr:%f lwr:%f\n", p->ceiling,p->expo,p->mix,p->thresh,p->lwrSlope,p->uprSlope);
|
|
6656
|
+}
|
|
6657
|
+
|
|
6658
|
+
|
6462
|
6659
|
//------------------------------------------------------------------------------------------------------------
|
6463
|
6660
|
|
6464
|
6661
|
cmRC_t _cmBinMtxFileWriteHdr( cmBinMtxFile_t* p )
|