|
@@ -2575,8 +2575,9 @@ struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx )
|
2575
|
2575
|
//==========================================================================================================================================
|
2576
|
2576
|
enum
|
2577
|
2577
|
{
|
|
2578
|
+ kHopFactGrId,
|
2578
|
2579
|
kInGrId,
|
2579
|
|
- kOutBaseGrId,
|
|
2580
|
+ kHzBaseGrId,
|
2580
|
2581
|
};
|
2581
|
2582
|
|
2582
|
2583
|
cmDspClass_t _cmGoertzelDC;
|
|
@@ -2586,13 +2587,15 @@ typedef struct
|
2586
|
2587
|
cmDspInst_t inst;
|
2587
|
2588
|
cmGoertzel* g;
|
2588
|
2589
|
double outPhs;
|
|
2590
|
+ unsigned outBaseGrId;
|
|
2591
|
+ unsigned chCnt;
|
2589
|
2592
|
} cmDspGoertzel_t;
|
2590
|
2593
|
|
2591
|
2594
|
|
2592
|
2595
|
cmDspInst_t* _cmDspGoertzelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
2593
|
2596
|
{
|
2594
|
2597
|
|
2595
|
|
- if( va_cnt !=2 )
|
|
2598
|
+ if( va_cnt !=3 )
|
2596
|
2599
|
{
|
2597
|
2600
|
cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'Goertzel' constructor must have two arguments: a channel count and frequency array.");
|
2598
|
2601
|
return NULL;
|
|
@@ -2601,22 +2604,61 @@ cmDspInst_t* _cmDspGoertzelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
|
2601
|
2604
|
va_list vl1;
|
2602
|
2605
|
va_copy(vl1,vl);
|
2603
|
2606
|
|
2604
|
|
- int chCnt = va_arg(vl,int);
|
2605
|
|
- double* hzV = va_arg(vl,double*);
|
|
2607
|
+ unsigned hopFact = va_arg(vl,unsigned);
|
|
2608
|
+ int chCnt = va_arg(vl,int);
|
|
2609
|
+ double* hzV = va_arg(vl,double*);
|
|
2610
|
+ unsigned outBaseGrId = kHzBaseGrId + chCnt;
|
|
2611
|
+ unsigned i;
|
2606
|
2612
|
|
2607
|
|
- cmDspGoertzel_t* p = cmDspInstAllocV(cmDspGoertzel_t,ctx,classPtr,instSymId,id,storeSymId,0,vl1,
|
2608
|
|
- 1, "in", kInGrId, 0,1, kInDsvFl | kAudioBufDsvFl, "Audio input",
|
2609
|
|
- chCnt, "out", kOutBaseGrId, 0,1, kOutDsvFl | kDoubleDsvFl, "Detector output",
|
|
2613
|
+ cmDspGoertzel_t* p = cmDspInstAllocV(cmDspGoertzel_t,ctx,classPtr,instSymId,id,storeSymId,1,vl1,
|
|
2614
|
+ 1, "hop", kHopFactGrId, 0,0, kInDsvFl | kDoubleDsvFl, "Hop factor",
|
|
2615
|
+ 1, "in", kInGrId, 0,1, kInDsvFl | kAudioBufDsvFl, "Audio input",
|
|
2616
|
+ chCnt, "hz", kHzBaseGrId, 0,0, kInDsvFl | kDoubleDsvFl, "Hz input.",
|
|
2617
|
+ chCnt, "out", outBaseGrId, 0,1, kOutDsvFl | kDoubleDsvFl, "Detector output",
|
2610
|
2618
|
0 );
|
2611
|
2619
|
|
2612
|
2620
|
va_end(vl1);
|
2613
|
2621
|
|
2614
|
|
- p->g = cmGoertzelAlloc(ctx->cmProcCtx, NULL, cmDspSysSampleRate(ctx->dspH), hzV, chCnt );
|
2615
|
|
-
|
|
2622
|
+
|
|
2623
|
+ p->outBaseGrId = outBaseGrId;
|
|
2624
|
+ p->chCnt = chCnt;
|
|
2625
|
+
|
|
2626
|
+ p->g = cmGoertzelAlloc(ctx->cmProcCtx, NULL, 0, NULL, 0,0,0,0 );
|
|
2627
|
+ cmDspSetDefaultUInt(ctx,&p->inst, kHopFactGrId, 0, cmMax(hopFact,1));
|
|
2628
|
+
|
|
2629
|
+ for(i=0; i<chCnt; ++i)
|
|
2630
|
+ cmDspSetDefaultDouble(ctx,&p->inst, kHzBaseGrId+i, 0.0, hzV[i] );
|
2616
|
2631
|
|
2617
|
2632
|
return &p->inst;
|
2618
|
2633
|
}
|
2619
|
2634
|
|
|
2635
|
+cmDspRC_t _cmDspGoertzelSetup( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
|
2636
|
+{
|
|
2637
|
+ cmDspRC_t rc = kOkDspRC;
|
|
2638
|
+ cmDspGoertzel_t* p = (cmDspGoertzel_t*)inst;
|
|
2639
|
+ unsigned hopFact = cmDspUInt(inst,kHopFactGrId);
|
|
2640
|
+ unsigned procSmpCnt = cmDspAudioBufSmpCount(ctx,inst,kInGrId,0);
|
|
2641
|
+ unsigned wndSmpCnt = procSmpCnt * hopFact;
|
|
2642
|
+ double fcHzV[ p->chCnt ];
|
|
2643
|
+ unsigned i;
|
|
2644
|
+
|
|
2645
|
+ for(i=0; i<p->chCnt; ++i)
|
|
2646
|
+ {
|
|
2647
|
+ double hz;
|
|
2648
|
+ if( p->g->ch == NULL || p->g->ch[i].hz == 0 )
|
|
2649
|
+ hz = cmDspDouble(inst,kHzBaseGrId);
|
|
2650
|
+ else
|
|
2651
|
+ hz = p->g->ch[i].hz;
|
|
2652
|
+
|
|
2653
|
+ fcHzV[i] = hz;
|
|
2654
|
+ }
|
|
2655
|
+
|
|
2656
|
+ if( cmGoertzelInit(p->g,cmDspSysSampleRate(ctx->dspH),fcHzV,p->chCnt,procSmpCnt,procSmpCnt,wndSmpCnt) != cmOkRC )
|
|
2657
|
+ rc = cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to initialize the internal Goertzel detector.");
|
|
2658
|
+
|
|
2659
|
+ return rc;
|
|
2660
|
+}
|
|
2661
|
+
|
2620
|
2662
|
cmDspRC_t _cmDspGoertzelFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
2621
|
2663
|
{
|
2622
|
2664
|
cmDspRC_t rc = kOkDspRC;
|
|
@@ -2635,7 +2677,7 @@ cmDspRC_t _cmDspGoertzelReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
2635
|
2677
|
|
2636
|
2678
|
p->outPhs = 0;
|
2637
|
2679
|
|
2638
|
|
- return kOkDspRC;
|
|
2680
|
+ return _cmDspGoertzelSetup(ctx, inst );
|
2639
|
2681
|
}
|
2640
|
2682
|
|
2641
|
2683
|
cmDspRC_t _cmDspGoertzelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
@@ -2646,12 +2688,12 @@ cmDspRC_t _cmDspGoertzelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
2646
|
2688
|
unsigned n = cmDspAudioBufSmpCount(ctx,inst,kInGrId,0);
|
2647
|
2689
|
double outMs = 50.0;
|
2648
|
2690
|
double outPhsMax = outMs * cmDspSysSampleRate(ctx->dspH) / 1000.0;
|
2649
|
|
- double outV[ p->g->chCnt ];
|
|
2691
|
+ double outV[ p->chCnt ];
|
2650
|
2692
|
unsigned i;
|
2651
|
2693
|
|
2652
|
2694
|
if( x != NULL )
|
2653
|
2695
|
{
|
2654
|
|
- cmGoertzelExec(p->g,x,n,outV,p->g->chCnt);
|
|
2696
|
+ cmGoertzelExec(p->g,x,n,outV,p->chCnt);
|
2655
|
2697
|
|
2656
|
2698
|
p->outPhs += n;
|
2657
|
2699
|
if( p->outPhs > outPhsMax )
|
|
@@ -2659,9 +2701,9 @@ cmDspRC_t _cmDspGoertzelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
2659
|
2701
|
while( p->outPhs > outPhsMax )
|
2660
|
2702
|
p->outPhs -= outPhsMax;
|
2661
|
2703
|
|
2662
|
|
- for(i=0; i<p->g->chCnt; ++i)
|
|
2704
|
+ for(i=0; i<p->chCnt; ++i)
|
2663
|
2705
|
{
|
2664
|
|
- cmDspSetDouble(ctx,inst,kOutBaseGrId+i,outV[i]);
|
|
2706
|
+ cmDspSetDouble(ctx,inst,p->outBaseGrId+i,outV[i]);
|
2665
|
2707
|
//printf("%f ",outV[i]);
|
2666
|
2708
|
}
|
2667
|
2709
|
//printf("\n");
|
|
@@ -2673,8 +2715,19 @@ cmDspRC_t _cmDspGoertzelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
2673
|
2715
|
|
2674
|
2716
|
cmDspRC_t _cmDspGoertzelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
2675
|
2717
|
{
|
|
2718
|
+ cmDspGoertzel_t* p = (cmDspGoertzel_t*)inst;
|
|
2719
|
+
|
2676
|
2720
|
cmDspSetEvent(ctx,inst,evt);
|
2677
|
2721
|
|
|
2722
|
+ if( kHzBaseGrId <= evt->dstVarId && evt->dstVarId < kHzBaseGrId+p->chCnt )
|
|
2723
|
+ cmGoertzelSetFcHz(p->g, evt->dstVarId - kHzBaseGrId, cmDspDouble(inst,evt->dstVarId));
|
|
2724
|
+ else
|
|
2725
|
+ {
|
|
2726
|
+ if( evt->dstVarId==kHopFactGrId )
|
|
2727
|
+ {
|
|
2728
|
+ _cmDspGoertzelSetup(ctx,inst);
|
|
2729
|
+ }
|
|
2730
|
+ }
|
2678
|
2731
|
return kOkDspRC;
|
2679
|
2732
|
}
|
2680
|
2733
|
|