Browse Source

cmProc2.h/c : Added cmSpecDist2().

master
kevin larke 7 years ago
parent
commit
002ca3507b
2 changed files with 238 additions and 3 deletions
  1. 200
    3
      cmProc2.c
  2. 38
    0
      cmProc2.h

+ 200
- 3
cmProc2.c View File

@@ -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 )

+ 38
- 0
cmProc2.h View File

@@ -1313,6 +1313,44 @@ extern "C" {
1313 1313
 
1314 1314
   //------------------------------------------------------------------------------------------------------------
1315 1315
   //)
1316
+
1317
+  //( { label:cmSpecDist file_desc:"Spectral distortion 2 algorithm based on non-linear transform." kw:[proc]}    
1318
+
1319
+  typedef struct
1320
+  {
1321
+    cmObj    obj;
1322
+    double   srate;
1323
+    unsigned wndSmpCnt;
1324
+    unsigned hopFcmt;
1325
+    unsigned hopSmpCnt;
1326
+    unsigned procSmpCnt;
1327
+    
1328
+    cmPvAnl* pva;
1329
+    cmPvSyn* pvs;
1330
+
1331
+    double   ceiling;
1332
+    double   expo;    
1333
+    double   mix;
1334
+    double   thresh;
1335
+    double   uprSlope;
1336
+    double   lwrSlope;
1337
+
1338
+    cmReal_t ogain;
1339
+
1340
+    unsigned       fi;          // total count of frames processed by cmSpecDistExec()
1341
+
1342
+  } cmSpecDist2_t;
1343
+
1344
+  cmSpecDist2_t*    cmSpecDist2Alloc( cmCtx* ctx,cmSpecDist2_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId  ); 
1345
+  cmRC_t            cmSpecDist2Free( cmSpecDist2_t** pp );
1346
+  cmRC_t            cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId  );
1347
+  cmRC_t            cmSpecDist2Final(cmSpecDist2_t* p );
1348
+  cmRC_t            cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn );
1349
+  const cmSample_t* cmSpecDist2Out(  cmSpecDist2_t* p );
1350
+  void              cmSpecDist2Report( cmSpecDist2_t* p );
1351
+  
1352
+  //------------------------------------------------------------------------------------------------------------
1353
+  //)
1316 1354
   
1317 1355
   //( { label:cmBinMtxFile file_desc:"Write a binary matrix which can be read by readBinFile.m." kw:[proc]}
1318 1356
   

Loading…
Cancel
Save