cmProc4.h/c : Added the cmGoertzel tone detector object.
This commit is contained in:
parent
0857f64730
commit
b206e2d457
71
cmProc4.c
71
cmProc4.c
@ -4502,3 +4502,74 @@ cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_
|
|||||||
|
|
||||||
return cmOkRC;
|
return cmOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
|
cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt )
|
||||||
|
{
|
||||||
|
cmGoertzel* op = cmObjAlloc(cmGoertzel,c,p);
|
||||||
|
|
||||||
|
if( cmGoertzelInit(op,srate,fcHzV,chCnt) != cmOkRC )
|
||||||
|
cmGoertzelFree(&op);
|
||||||
|
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmGoertzelFree( cmGoertzel** pp )
|
||||||
|
{
|
||||||
|
cmRC_t rc = cmOkRC;
|
||||||
|
if( pp==NULL || *pp==NULL )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmGoertzel* p = *pp;
|
||||||
|
if((rc = cmGoertzelFinal(p)) != cmOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
cmMemFree(p->ch);
|
||||||
|
cmObjFree(pp);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt )
|
||||||
|
{
|
||||||
|
cmRC_t rc;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if((rc = cmGoertzelFinal(p)) != cmOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
p->ch = cmMemResizeZ(cmGoertzelCh,p->ch,chCnt);
|
||||||
|
p->chCnt = chCnt;
|
||||||
|
p->srate = srate;
|
||||||
|
|
||||||
|
for(i=0; i<p->chCnt; ++i)
|
||||||
|
p->ch[i].coeff = 2*cos(2*M_PI*fcHzV[i]/srate);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmRC_t cmGoertzelFinal( cmGoertzel* p )
|
||||||
|
{ return cmOkRC; }
|
||||||
|
|
||||||
|
cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* x, unsigned procSmpCnt, double* outV, unsigned chCnt )
|
||||||
|
{
|
||||||
|
unsigned i,j;
|
||||||
|
|
||||||
|
for(i=0; i<chCnt; ++i)
|
||||||
|
{
|
||||||
|
cmGoertzelCh* ch = p->ch + i;
|
||||||
|
|
||||||
|
ch->s1 = x[0];
|
||||||
|
ch->s2 = x[1] + 2 * x[0] * ch->coeff;
|
||||||
|
for(j=2; j<procSmpCnt; ++j)
|
||||||
|
{
|
||||||
|
ch->s0 = x[j] + ch->coeff * ch->s1 - ch->s2;
|
||||||
|
ch->s2 = ch->s1;
|
||||||
|
ch->s1 = ch->s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outV[i] = ch->s2*ch->s2 + ch->s1*ch->s1 - ch->coeff * ch->s2 * ch->s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmOkRC;
|
||||||
|
}
|
||||||
|
49
cmProc4.h
49
cmProc4.h
@ -627,7 +627,10 @@ extern "C" {
|
|||||||
cmRC_t cmScModulatorDump( cmScModulator* p );
|
cmRC_t cmScModulatorDump( cmScModulator* p );
|
||||||
|
|
||||||
//=======================================================================================================================
|
//=======================================================================================================================
|
||||||
|
//
|
||||||
|
// Record fragments of audio, store them, and play them back at a later time.
|
||||||
|
//
|
||||||
|
|
||||||
typedef struct cmRecdPlayFrag_str
|
typedef struct cmRecdPlayFrag_str
|
||||||
{
|
{
|
||||||
unsigned labelSymId; // this fragments label
|
unsigned labelSymId; // this fragments label
|
||||||
@ -658,6 +661,17 @@ extern "C" {
|
|||||||
} cmRecdPlay;
|
} cmRecdPlay;
|
||||||
|
|
||||||
|
|
||||||
|
// srate - system sample rate
|
||||||
|
// fragCnt - total count of samples to record
|
||||||
|
// chCnt - count of input and output audio channels.
|
||||||
|
// initFragSecs - amount of memory to pre-allocate for each fragment.
|
||||||
|
// maxLaSecs - maximum value for curLaSecs
|
||||||
|
// curLaSecs - current duration of look-ahead buffer
|
||||||
|
//
|
||||||
|
// The look-ahead buffer is a circular buffer which hold the previous 'curLaSecs' seconds
|
||||||
|
// of incoming audio. When recording is enabled with via cmRecdPlayBeginRecord() the
|
||||||
|
// look ahead buffer is automatically prepended to the fragment.
|
||||||
|
|
||||||
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||||
cmRC_t cmRecdPlayFree( cmRecdPlay** pp );
|
cmRC_t cmRecdPlayFree( cmRecdPlay** pp );
|
||||||
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||||
@ -667,16 +681,49 @@ extern "C" {
|
|||||||
|
|
||||||
cmRC_t cmRecdPlaySetLaSecs( cmRecdPlay* p, double curLaSecs );
|
cmRC_t cmRecdPlaySetLaSecs( cmRecdPlay* p, double curLaSecs );
|
||||||
|
|
||||||
|
// Deactivates all active recorders and players, zeros the look-ahead buffer and
|
||||||
|
// rewinds all fragment play positions. This function does not clear the audio from
|
||||||
|
// frabments that have already been recorded.
|
||||||
cmRC_t cmRecdPlayRewind( cmRecdPlay* p );
|
cmRC_t cmRecdPlayRewind( cmRecdPlay* p );
|
||||||
|
|
||||||
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
|
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
|
||||||
cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId );
|
cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId );
|
||||||
cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId );
|
cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId );
|
||||||
cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId );
|
cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId );
|
||||||
|
|
||||||
|
// Begin fading out the specified fragment at a rate deteremined by 'dbPerSec'.
|
||||||
cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
|
cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
|
||||||
|
|
||||||
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
|
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
|
||||||
|
|
||||||
|
//=======================================================================================================================
|
||||||
|
// Goertzel Filter
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double s0;
|
||||||
|
double s1;
|
||||||
|
double s2;
|
||||||
|
double coeff;
|
||||||
|
} cmGoertzelCh;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmObj obj;
|
||||||
|
cmGoertzelCh* ch;
|
||||||
|
unsigned chCnt;
|
||||||
|
double srate;
|
||||||
|
} cmGoertzel;
|
||||||
|
|
||||||
|
cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt );
|
||||||
|
cmRC_t cmGoertzelFree( cmGoertzel** pp );
|
||||||
|
cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt );
|
||||||
|
cmRC_t cmGoertzelFinal( cmGoertzel* p );
|
||||||
|
cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt, double* outV, unsigned chCnt );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user