Browse Source

cmProc4.h/c : Added the cmGoertzel tone detector object.

master
kevin 10 years ago
parent
commit
b206e2d457
2 changed files with 119 additions and 1 deletions
  1. 71
    0
      cmProc4.c
  2. 48
    1
      cmProc4.h

+ 71
- 0
cmProc4.c View File

4502
 
4502
 
4503
   return cmOkRC;
4503
   return cmOkRC;
4504
 }
4504
 }
4505
+
4506
+//=======================================================================================================================
4507
+cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt )
4508
+{
4509
+  cmGoertzel* op = cmObjAlloc(cmGoertzel,c,p);
4510
+
4511
+  if( cmGoertzelInit(op,srate,fcHzV,chCnt) != cmOkRC )
4512
+    cmGoertzelFree(&op);
4513
+
4514
+  return op;
4515
+}
4516
+
4517
+cmRC_t cmGoertzelFree( cmGoertzel** pp )
4518
+{
4519
+  cmRC_t rc = cmOkRC;
4520
+  if( pp==NULL || *pp==NULL )
4521
+    return rc;
4522
+
4523
+  cmGoertzel* p = *pp;
4524
+  if((rc = cmGoertzelFinal(p)) != cmOkRC )
4525
+    return rc;
4526
+
4527
+  cmMemFree(p->ch);
4528
+  cmObjFree(pp);
4529
+  return rc;
4530
+
4531
+}
4532
+
4533
+cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt )
4534
+{
4535
+  cmRC_t rc;
4536
+  unsigned i;
4537
+
4538
+  if((rc = cmGoertzelFinal(p)) != cmOkRC )
4539
+    return rc;
4540
+
4541
+  p->ch    = cmMemResizeZ(cmGoertzelCh,p->ch,chCnt);
4542
+  p->chCnt = chCnt;
4543
+  p->srate = srate;
4544
+
4545
+  for(i=0; i<p->chCnt; ++i)
4546
+    p->ch[i].coeff = 2*cos(2*M_PI*fcHzV[i]/srate);
4547
+  
4548
+  return rc;
4549
+}
4550
+
4551
+cmRC_t cmGoertzelFinal( cmGoertzel* p )
4552
+{ return cmOkRC; }
4553
+
4554
+cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* x, unsigned procSmpCnt, double* outV, unsigned chCnt )
4555
+{
4556
+  unsigned i,j;
4557
+
4558
+  for(i=0; i<chCnt; ++i)
4559
+  {
4560
+    cmGoertzelCh* ch = p->ch + i;
4561
+    
4562
+    ch->s1 = x[0];
4563
+    ch->s2 = x[1] + 2 * x[0] * ch->coeff;
4564
+    for(j=2; j<procSmpCnt; ++j)
4565
+    {
4566
+      ch->s0 = x[j] + ch->coeff * ch->s1 - ch->s2;
4567
+      ch->s2 = ch->s1;
4568
+      ch->s1 = ch->s0;
4569
+    }
4570
+    
4571
+    outV[i] = ch->s2*ch->s2 + ch->s1*ch->s1 - ch->coeff * ch->s2 * ch->s1;
4572
+  }
4573
+
4574
+  return cmOkRC;
4575
+}

+ 48
- 1
cmProc4.h View File

627
   cmRC_t         cmScModulatorDump(  cmScModulator* p );
627
   cmRC_t         cmScModulatorDump(  cmScModulator* p );
628
 
628
 
629
   //=======================================================================================================================
629
   //=======================================================================================================================
630
- 
630
+  //
631
+  // Record fragments of audio, store them, and play them back at a later time.
632
+  //
633
+
631
   typedef struct cmRecdPlayFrag_str
634
   typedef struct cmRecdPlayFrag_str
632
   {
635
   {
633
     unsigned                   labelSymId; // this fragments label
636
     unsigned                   labelSymId; // this fragments label
658
   } cmRecdPlay;
661
   } cmRecdPlay;
659
 
662
 
660
 
663
 
664
+  // srate        - system sample rate
665
+  // fragCnt      - total count of samples to record
666
+  // chCnt        - count of input and output audio channels.
667
+  // initFragSecs - amount of memory to pre-allocate for each fragment.
668
+  // maxLaSecs    -  maximum value for curLaSecs
669
+  // curLaSecs    -  current duration of look-ahead buffer 
670
+  //
671
+  // The look-ahead buffer is a circular buffer which hold the previous 'curLaSecs' seconds
672
+  // of incoming audio.  When recording is enabled with via cmRecdPlayBeginRecord() the
673
+  // look ahead buffer is automatically prepended to the fragment.
674
+
661
   cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
675
   cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
662
   cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp );
676
   cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp );
663
   cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
677
   cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
667
 
681
 
668
   cmRC_t         cmRecdPlaySetLaSecs( cmRecdPlay* p, double curLaSecs );
682
   cmRC_t         cmRecdPlaySetLaSecs( cmRecdPlay* p, double curLaSecs );
669
 
683
 
684
+  // Deactivates all active recorders and players, zeros the look-ahead buffer and
685
+  // rewinds all fragment play positions.  This function does not clear the audio from 
686
+  // frabments that have already been recorded.
670
   cmRC_t         cmRecdPlayRewind(      cmRecdPlay* p );
687
   cmRC_t         cmRecdPlayRewind(      cmRecdPlay* p );
688
+
671
   cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
689
   cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
672
   cmRC_t         cmRecdPlayEndRecord(   cmRecdPlay* p, unsigned labelSymId );
690
   cmRC_t         cmRecdPlayEndRecord(   cmRecdPlay* p, unsigned labelSymId );
673
   cmRC_t         cmRecdPlayBeginPlay(   cmRecdPlay* p, unsigned labelSymId );
691
   cmRC_t         cmRecdPlayBeginPlay(   cmRecdPlay* p, unsigned labelSymId );
674
   cmRC_t         cmRecdPlayEndPlay(     cmRecdPlay* p, unsigned labelSymId );
692
   cmRC_t         cmRecdPlayEndPlay(     cmRecdPlay* p, unsigned labelSymId );
675
 
693
 
694
+  // Begin fading out the specified fragment at a rate deteremined by 'dbPerSec'.
676
   cmRC_t         cmRecdPlayBeginFade(   cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
695
   cmRC_t         cmRecdPlayBeginFade(   cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
677
 
696
 
678
   cmRC_t         cmRecdPlayExec(        cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
697
   cmRC_t         cmRecdPlayExec(        cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
679
 
698
 
699
+  //=======================================================================================================================
700
+  // Goertzel Filter
701
+  //
702
+
703
+  typedef struct
704
+  {
705
+    double s0;
706
+    double s1;
707
+    double s2;
708
+    double coeff;
709
+  } cmGoertzelCh;
710
+
711
+  typedef struct
712
+  {
713
+    cmObj         obj;
714
+    cmGoertzelCh* ch;
715
+    unsigned      chCnt;
716
+    double        srate;
717
+  } cmGoertzel;
718
+
719
+  cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt );
720
+  cmRC_t cmGoertzelFree( cmGoertzel** pp );
721
+  cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt );
722
+  cmRC_t cmGoertzelFinal( cmGoertzel* p );
723
+  cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt,  double* outV, unsigned chCnt );
724
+
725
+
726
+
680
 #ifdef __cplusplus
727
 #ifdef __cplusplus
681
 }
728
 }
682
 #endif
729
 #endif

Loading…
Cancel
Save