Переглянути джерело

cmProc.2.h/c : Added cmFbCtl.

Added _cmFrqTrkFillMap() to change width of suppression filter w/ frequency.
Shifted cmFrqTrkExec() to  follow non-linear xform in cmSpecDistExec().
master
Kevin Larke 10 роки тому
джерело
коміт
555ed24266
2 змінених файлів з 240 додано та 21 видалено
  1. 204
    20
      cmProc2.c
  2. 36
    1
      cmProc2.h

+ 204
- 20
cmProc2.c Переглянути файл

@@ -5023,11 +5023,43 @@ void _cmFrqTrkScoreChs( cmFrqTrk* p )
5023 5023
     }
5024 5024
 }
5025 5025
 
5026
+// Generate a filter that is wider for higher frequencies than lower frequencies.
5027
+unsigned _cmFrqTrkFillMap( cmFrqTrk* p, cmReal_t* map, unsigned maxN, cmReal_t hz )
5028
+{
5029
+  assert( maxN % 2 == 1 );
5030
+
5031
+  unsigned i;
5032
+  cmReal_t maxHz = p->a.srate/2;
5033
+  unsigned mapN  = cmMin(maxN,ceil(hz/maxHz * maxN));
5034
+
5035
+  if( mapN % 2 == 0 )
5036
+    mapN += 1;
5037
+
5038
+  mapN = cmMin(maxN,mapN);
5039
+
5040
+  unsigned   N = floor(mapN/2);
5041
+
5042
+  double COEFF = 0.3;
5043
+
5044
+  for(i=0; i<N; ++i)
5045
+  {
5046
+    map[i] = pow(((double)i+1)/(N+1),COEFF);
5047
+    map[mapN-(i+1)] = map[i];
5048
+  }
5049
+
5050
+  map[N] = 1.0;
5051
+  return mapN;
5052
+}
5053
+
5026 5054
 void _cmFrqTrkApplyAtten( cmFrqTrk* p, cmReal_t* aV, cmReal_t gain, cmReal_t hz )
5027 5055
 {
5028 5056
   int       cbi = cmMin(p->a.binCnt,cmMax(0,round(hz/p->binHz)));
5029
-  cmReal_t  map[] = { .25, .5, 1, .5, .25 };
5030
-  int       mapN = sizeof(map)/sizeof(map[0]);
5057
+  //cmReal_t  map[] = { .25, .5, 1, .5, .25 };
5058
+  //int       mapN = sizeof(map)/sizeof(map[0]);
5059
+
5060
+  unsigned  maxN = 30;  // must be odd
5061
+  cmReal_t  map[ maxN ];
5062
+  int       mapN = _cmFrqTrkFillMap(p, map, maxN, hz );
5031 5063
   int       j;
5032 5064
 
5033 5065
   int ai = cbi - mapN/2;
@@ -5062,6 +5094,9 @@ void _cmFrqTrkUpdateFilter( cmFrqTrk* p )
5062 5094
         case kAtkFrqTrkId:
5063 5095
           if( c->attenPhsIdx < p->attenPhsMax )
5064 5096
           {
5097
+
5098
+            c->attenGain = cmMin(1.0,p->a.attenGain * c->attenPhsIdx / p->attenPhsMax);
5099
+
5065 5100
             _cmFrqTrkApplyAtten(p, p->aV, c->attenGain, c->hz);
5066 5101
           }
5067 5102
 
@@ -5238,23 +5273,33 @@ void _cmFrqTrkNewChs( cmFrqTrk* p, const cmReal_t* dbV, const cmReal_t* hzV, uns
5238 5273
 
5239 5274
 }
5240 5275
 
5276
+void _cmFrqTrkApplyFrqBias( cmFrqTrk* p, cmReal_t* xV )
5277
+{
5278
+  // 1+2*([0:.01:1].^4)
5279
+  unsigned i;
5280
+  for(i=0; i<p->bN; ++i)
5281
+    xV[i] =  cmMax(0.0, (20*log10( cmMax(xV[i]/1.5,0.00001)) + 100.0)/100.0);
5282
+
5283
+}
5284
+
5241 5285
 
5242 5286
 cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hertzV )
5243 5287
 {
5244 5288
   cmRC_t   rc = cmOkRC;
5245 5289
   cmReal_t hzV[ p->bN ];
5246 5290
 
5247
-  cmReal_t powV[ p->bN ];
5248
-  //cmReal_t whV[ p->bN];
5249
-  cmVOR_MultVVV(powV,p->bN,magV,magV);
5250
-  cmWhFiltExec(p->wf,powV,p->dbV,p->bN);
5291
+  //cmReal_t powV[ p->bN ];
5292
+  //cmReal_t yV[ p->bN];
5293
+
5294
+  //cmVOR_MultVVV(powV,p->bN,magV,magV);
5295
+  //cmWhFiltExec(p->wf,powV,p->dbV,p->bN);
5251 5296
 
5252 5297
   // convert magV to Decibels
5253 5298
   //cmVOR_AmplToDbVV(p->dbV,p->bN, magV, -200.0);
5254 5299
 
5255 5300
   
5256 5301
   // copy p->dbV to dbM[hi,:] 
5257
-  cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, p->dbV, 1 );
5302
+  //cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, p->dbV, 1 );
5258 5303
   //cmVOR_CopyN(p->dbM + p->hi, p->bN, p->hN, whV, 1 );
5259 5304
 
5260 5305
   if( 1 )
@@ -5262,6 +5307,7 @@ cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, co
5262 5307
     cmReal_t powV[ p->bN ];
5263 5308
     cmVOR_MultVVV(powV,p->bN,magV,magV);
5264 5309
     cmWhFiltExec(p->wf,powV,p->dbV,p->bN);
5310
+    _cmFrqTrkApplyFrqBias(p,p->dbV);
5265 5311
   }
5266 5312
   else
5267 5313
   {
@@ -5302,6 +5348,7 @@ cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, co
5302 5348
     // 
5303 5349
     _cmFrqTrkUpdateFilter(p);
5304 5350
 
5351
+    /*
5305 5352
     // write the log file
5306 5353
     _cmFrqTrkWriteLog(p);
5307 5354
 
@@ -5315,6 +5362,7 @@ cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, co
5315 5362
 
5316 5363
     // write the the level file
5317 5364
     _cmFrqTrkWriteLevel(p,p->dbV,hzV,p->bN);
5365
+    */
5318 5366
   }
5319 5367
 
5320 5368
   p->fN += 1;
@@ -5337,12 +5385,107 @@ void  cmFrqTrkPrint( cmFrqTrk* p )
5337 5385
 
5338 5386
 }
5339 5387
 
5388
+//------------------------------------------------------------------------------------------------------------
5389
+cmFbCtl_t*  cmFbCtlAlloc( cmCtx* c, cmFbCtl_t* ap, const cmFbCtlArgs_t* a )
5390
+{
5391
+  cmFbCtl_t* p = cmObjAlloc( cmFbCtl_t, c, ap );
5392
+
5393
+  p->sva = cmVectArrayAlloc(c,kRealVaFl);
5394
+  p->uva = cmVectArrayAlloc(c,kRealVaFl);
5395
+
5396
+  if( a != NULL )
5397
+  {
5398
+    if( cmFbCtlInit( p, a ) != cmOkRC )
5399
+      cmFbCtlFree(&p);
5400
+  }
5401
+
5402
+  return p;
5403
+
5404
+}
5405
+
5406
+cmRC_t    cmFbCtlFree( cmFbCtl_t** pp )
5407
+{
5408
+  if( pp == NULL || *pp == NULL )
5409
+    return cmOkRC;
5410
+
5411
+  cmFbCtl_t* p = *pp;
5412
+  
5413
+  cmVectArrayWrite(p->sva, "/home/kevin/temp/frqtrk/fb_ctl_s.va");
5414
+  cmVectArrayWrite(p->uva, "/home/kevin/temp/frqtrk/fb_ctl_u.va");
5415
+
5416
+  cmMemFree(p->bM);
5417
+  cmMemFree(p->rmsV);
5418
+  cmVectArrayFree(&p->sva);
5419
+  cmVectArrayFree(&p->uva);
5420
+  cmObjFree(pp);
5421
+  return cmOkRC;
5422
+
5423
+}
5424
+
5425
+cmRC_t    cmFbCtlInit( cmFbCtl_t* p, const cmFbCtlArgs_t* a )
5426
+{
5427
+  cmRC_t rc;
5428
+  if((rc = cmFbCtlFinal(p)) != cmOkRC )
5429
+    return rc;
5430
+
5431
+  double binHz = a->srate / ((a->binCnt-1)*2);
5432
+
5433
+  p->a      = *a;
5434
+  p->frmCnt = (a->bufMs * a->srate / 1000.0) /a->hopSmpCnt;
5435
+  p->binCnt = cmMin(p->a.binCnt, a->maxHz/binHz);
5436
+  p->bM     = cmMemResizeZ(cmReal_t, p->bM,   p->binCnt*p->frmCnt);
5437
+  p->rmsV   = cmMemResizeZ(cmReal_t, p->rmsV, p->frmCnt);
5438
+  p->sV     = cmMemResizeZ(cmReal_t, p->sV,   p->binCnt);
5439
+  p->uV     = cmMemResizeZ(cmReal_t, p->uV,   p->binCnt);
5440
+
5441
+  printf("cmFbCtl: frmCnt:%i binCnt:%i \n",p->frmCnt,p->binCnt);
5442
+  return rc;
5443
+}
5444
+
5445
+cmRC_t    cmFbCtlFinal(cmFbCtl_t* p )
5446
+{ return cmOkRC; }
5447
+
5448
+cmRC_t    cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* x0V )
5449
+{
5450
+  unsigned i;
5451
+  cmRC_t rc = cmOkRC;
5452
+
5453
+  cmReal_t xV[ p->binCnt ];
5454
+  cmVOR_AmplToDbVV(xV, p->binCnt, x0V, -1000.0 );
5455
+
5456
+  cmVOR_Shift( p->rmsV, p->frmCnt, -1, 0 );
5457
+  p->rmsV[0] = cmVOR_Mean(xV,p->binCnt);
5458
+
5459
+  cmVOR_CopyN(p->bM + p->bfi, p->binCnt, p->frmCnt, xV, 1 );
5460
+
5461
+  p->bfi  = (p->bfi + 1) % p->frmCnt;
5462
+  p->bfN  = cmMin(p->bfN+1,p->frmCnt);
5463
+  
5464
+  for(i=0; i<p->binCnt; ++i)
5465
+  {
5466
+    const cmReal_t* v = p->bM + i * p->frmCnt;
5467
+    cmReal_t u = cmVOR_Mean(v, p->bfN );
5468
+    cmReal_t s = sqrt(cmVOR_Variance(v, p->bfN,&u));
5469
+
5470
+    
5471
+
5472
+    p->sV[i] = (0.0002 - s);
5473
+    p->uV[i] = u;
5474
+  }
5475
+ 
5476
+
5477
+  cmVectArrayAppendR(p->sva,p->sV,p->binCnt);
5478
+  cmVectArrayAppendR(p->uva,p->uV,p->binCnt);
5479
+
5480
+  return rc;
5481
+}
5340 5482
 
5341 5483
 //------------------------------------------------------------------------------------------------------------
5342 5484
 cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId  )
5343 5485
 {
5344 5486
   cmSpecDist_t* p = cmObjAlloc( cmSpecDist_t, ctx, ap );
5345 5487
 
5488
+  p->oSpecVa   = cmVectArrayAlloc(ctx,kRealVaFl);
5346 5489
 
5347 5490
   if( procSmpCnt != 0 )
5348 5491
   {
@@ -5362,6 +5505,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp )
5362 5505
   cmSpecDist_t* p = *pp;
5363 5506
   
5364 5507
   cmSpecDistFinal(p);
5508
+  cmVectArrayFree(&p->oSpecVa);
5365 5509
   cmMemPtrFree(&p->hzV);
5366 5510
   cmObjFree(pp);
5367 5511
   return cmOkRC;
@@ -5402,13 +5546,13 @@ cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsig
5402 5546
   fta.minTrkSec     = 0.25;
5403 5547
   fta.maxTrkDeadSec = 0.25;
5404 5548
   fta.pkThreshDb    = 0.1; //-110.0;
5405
-  fta.pkAtkThreshDb = 0.5; //-60.0;
5406
-  fta.pkMaxHz       = 10000;
5549
+  fta.pkAtkThreshDb = 0.4; //-60.0;
5550
+  fta.pkMaxHz       = 20000;
5407 5551
   fta.whFiltCoeff   = 0.33;
5408 5552
 
5409 5553
   fta.attenThresh = 900.0;
5410
-  fta.attenGain   = 0.9; 
5411
-  fta.attenAtkSec = 0.1;  
5554
+  fta.attenGain   = 1.0; 
5555
+  fta.attenAtkSec = 0.25;  
5412 5556
 
5413 5557
   fta.logFn         = "/home/kevin/temp/frqtrk/trk_log.va";
5414 5558
   fta.levelFn       = "/home/kevin/temp/frqtrk/level.va";
@@ -5418,6 +5562,14 @@ cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsig
5418 5562
   p->ft  = cmFrqTrkAlloc( p->obj.ctx, NULL, &fta );
5419 5563
   cmFrqTrkPrint(p->ft);
5420 5564
 
5565
+  cmFbCtlArgs_t fba;
5566
+  fba.srate = srate;
5567
+  fba.binCnt = p->pva->binCnt;
5568
+  fba.hopSmpCnt = p->hopSmpCnt;
5569
+  fba.bufMs = 500;
5570
+  fba.maxHz = 5000;
5571
+
5572
+  p->fbc  = cmFbCtlAlloc( p->obj.ctx, NULL, &fba );
5421 5573
 
5422 5574
   p->spcBwHz   = cmMin(srate/2,10000);
5423 5575
   p->spcSmArg  = 0.05;
@@ -5438,16 +5590,19 @@ cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsig
5438 5590
 
5439 5591
   //p->bypOut = cmMemResizeZ(cmSample_t, p->bypOut, procSmpCnt );
5440 5592
 
5441
-
5442 5593
   return rc;
5443 5594
 }
5444 5595
 
5445 5596
 cmRC_t cmSpecDistFinal(cmSpecDist_t* p )
5446 5597
 {
5447 5598
   cmRC_t rc = cmOkRC;
5599
+
5600
+  cmVectArrayWrite(p->oSpecVa, "/home/kevin/temp/frqtrk/oSpec.va");
5601
+
5448 5602
   cmPvAnlFree(&p->pva);
5449 5603
   cmPvSynFree(&p->pvs);
5450 5604
   cmFrqTrkFree(&p->ft);
5605
+  cmFbCtlFree(&p->fbc);
5451 5606
   return rc;
5452 5607
 }
5453 5608
 
@@ -5493,7 +5648,6 @@ void _cmSpecDistBasicMode(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRea
5493 5648
       X1m[i] -= (p->lwrSlope*d);
5494 5649
     else
5495 5650
       X1m[i] -= (p->uprSlope*d);
5496
-
5497 5651
   }
5498 5652
 
5499 5653
 }
@@ -5604,9 +5758,6 @@ void _cmSpecDistAmpEnvMode( cmSpecDist_t* p, cmReal_t* X1m )
5604 5758
   cmReal_t mx = cmVOR_Max(X1m,p->pva->binCnt,1);
5605 5759
   p->aeSmMax  = (mx * smCoeff) + (p->aeSmMax * (1.0-smCoeff));
5606 5760
 
5607
-
5608
-
5609
-
5610 5761
   cmReal_t a = cmVOR_Mean(X1m,p->pva->binCnt);
5611 5762
   
5612 5763
   p->ae = (a * smCoeff) + (p->ae * (1.0-smCoeff));
@@ -5636,13 +5787,16 @@ cmRC_t  cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
5636 5787
   {
5637 5788
     cmReal_t X1m[p->pva->binCnt]; 
5638 5789
 
5639
-    cmFrqTrkExec(p->ft, p->pva->magV, p->pva->phsV, NULL );
5790
+    cmReal_t u0 = cmVOR_Mean(p->pva->magV,p->pva->binCnt);
5791
+
5792
+    //cmFrqTrkExec(p->ft, p->pva->magV, p->pva->phsV, NULL );
5640 5793
 
5641 5794
     // apply the freq track suppression filter
5642
-    cmVOR_MultVVV(X1m, p->pva->binCnt,p->pva->magV,p->ft->aV );
5795
+    //cmVOR_MultVVV(X1m, p->pva->binCnt,p->pva->magV, p->ft->aV );
5796
+
5797
+    cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 );
5798
+    //cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -1000.0 );
5643 5799
 
5644
-    //cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 );
5645
-   cmVOR_AmplToDbVV(X1m, p->pva->binCnt, X1m, -1000.0 );
5646 5800
 
5647 5801
     switch( p->mode )
5648 5802
     {
@@ -5683,9 +5837,39 @@ cmRC_t  cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
5683 5837
       default:
5684 5838
         break;
5685 5839
     }
5840
+
5841
+    //cmVectArrayAppendR(p->oSpecVa,X1m,p->pva->binCnt);
5686 5842
     
5687 5843
     cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m );
5688 5844
 
5845
+
5846
+    // run and apply the tracker/supressor
5847
+    cmFrqTrkExec(p->ft, X1m, p->pva->phsV, NULL );
5848
+    cmVOR_MultVV(X1m, p->pva->binCnt,p->ft->aV );
5849
+
5850
+
5851
+    cmReal_t idb = 20*log10(u0);
5852
+    cmReal_t u1 = cmVOR_Mean(X1m,p->pva->binCnt);
5853
+
5854
+    if( idb > -150.0 )
5855
+    {
5856
+      p->ogain = u0/u1;
5857
+    }
5858
+    else
5859
+    {
5860
+      cmReal_t a0 = 0.9;
5861
+      p->ogain *= a0;
5862
+    }
5863
+
5864
+    //cmReal_t v[] = { u0, u1, idb, 20*log10(u1), p->ogain };
5865
+    //unsigned vn = sizeof(v)/sizeof(v[0]);
5866
+    //cmVectArrayAppendR(p->oSpecVa,v,vn);
5867
+
5868
+    cmVOR_MultVS(X1m,p->pva->binCnt,cmMin(4.0,p->ogain));
5869
+
5870
+
5871
+    //cmFbCtlExec(p->fbc,X1m);
5872
+
5689 5873
     cmPvSynExec(p->pvs, X1m, p->pva->phsV );
5690 5874
   
5691 5875
   }

+ 36
- 1
cmProc2.h Переглянути файл

@@ -1018,7 +1018,38 @@ extern "C" {
1018 1018
   cmRC_t    cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV );
1019 1019
   void      cmFrqTrkPrint( cmFrqTrk* p );
1020 1020
 
1021
+  //------------------------------------------------------------------------------------------------------------
1021 1022
 
1023
+  typedef struct
1024
+  {
1025
+    double   srate;
1026
+    unsigned binCnt;
1027
+    unsigned hopSmpCnt;
1028
+    unsigned bufMs;
1029
+    cmReal_t maxHz;
1030
+  } cmFbCtlArgs_t;
1031
+
1032
+  typedef struct
1033
+  {
1034
+    cmObj          obj;
1035
+    cmFbCtlArgs_t  a;
1036
+    unsigned       binCnt;
1037
+    unsigned       frmCnt;
1038
+    cmReal_t*      bM;           // bM[ frmCnt, binCnt ];
1039
+    unsigned       bfi;          // current buffer frame (column) index
1040
+    unsigned       bfN;          // currrent count of frames in the buffer
1041
+    cmReal_t*      rmsV;         // rmsV[ frmCnt ];   
1042
+    cmReal_t*      sV;           // sV[ binCnt ]
1043
+    cmReal_t*      uV;
1044
+    cmVectArray_t* sva;
1045
+    cmVectArray_t* uva;
1046
+  } cmFbCtl_t;
1047
+
1048
+  cmFbCtl_t* cmFbCtlAlloc( cmCtx* c, cmFbCtl_t* p, const cmFbCtlArgs_t* a );
1049
+  cmRC_t     cmFbCtlFree( cmFbCtl_t** pp );
1050
+  cmRC_t     cmFbCtlInit( cmFbCtl_t* p, const cmFbCtlArgs_t* a );
1051
+  cmRC_t     cmFbCtlFinal(cmFbCtl_t* p );
1052
+  cmRC_t     cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* xV );
1022 1053
 
1023 1054
   //------------------------------------------------------------------------------------------------------------
1024 1055
 
@@ -1045,7 +1076,8 @@ extern "C" {
1045 1076
     cmPvSyn*  pvs;
1046 1077
 
1047 1078
     cmFrqTrk* ft;
1048
-    
1079
+    cmFbCtl_t*  fbc;
1080
+
1049 1081
     unsigned mode;
1050 1082
     double   thresh;
1051 1083
 
@@ -1074,6 +1106,9 @@ extern "C" {
1074 1106
     cmReal_t  aeMax;
1075 1107
     cmReal_t  aeUnit;
1076 1108
 
1109
+    cmVectArray_t* oSpecVa;
1110
+    cmReal_t ogain;
1111
+
1077 1112
   } cmSpecDist_t;
1078 1113
 
1079 1114
   cmSpecDist_t*     cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId  ); 

Завантаження…
Відмінити
Зберегти