|
@@ -2571,3 +2571,125 @@ struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx )
|
2571
|
2571
|
|
2572
|
2572
|
return &_cmRecdPlayDC;
|
2573
|
2573
|
}
|
|
2574
|
+
|
|
2575
|
+//==========================================================================================================================================
|
|
2576
|
+enum
|
|
2577
|
+{
|
|
2578
|
+ kInGrId,
|
|
2579
|
+ kOutBaseGrId,
|
|
2580
|
+};
|
|
2581
|
+
|
|
2582
|
+cmDspClass_t _cmGoertzelDC;
|
|
2583
|
+
|
|
2584
|
+typedef struct
|
|
2585
|
+{
|
|
2586
|
+ cmDspInst_t inst;
|
|
2587
|
+ cmGoertzel* g;
|
|
2588
|
+ double outPhs;
|
|
2589
|
+} cmDspGoertzel_t;
|
|
2590
|
+
|
|
2591
|
+
|
|
2592
|
+cmDspInst_t* _cmDspGoertzelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
|
2593
|
+{
|
|
2594
|
+
|
|
2595
|
+ if( va_cnt !=2 )
|
|
2596
|
+ {
|
|
2597
|
+ cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'Goertzel' constructor must have two arguments: a channel count and frequency array.");
|
|
2598
|
+ return NULL;
|
|
2599
|
+ }
|
|
2600
|
+
|
|
2601
|
+ va_list vl1;
|
|
2602
|
+ va_copy(vl1,vl);
|
|
2603
|
+
|
|
2604
|
+ int chCnt = va_arg(vl,int);
|
|
2605
|
+ double* hzV = va_arg(vl,double*);
|
|
2606
|
+
|
|
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",
|
|
2610
|
+ 0 );
|
|
2611
|
+
|
|
2612
|
+ va_end(vl1);
|
|
2613
|
+
|
|
2614
|
+ p->g = cmGoertzelAlloc(ctx->cmProcCtx, NULL, cmDspSysSampleRate(ctx->dspH), hzV, chCnt );
|
|
2615
|
+
|
|
2616
|
+
|
|
2617
|
+ return &p->inst;
|
|
2618
|
+}
|
|
2619
|
+
|
|
2620
|
+cmDspRC_t _cmDspGoertzelFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
2621
|
+{
|
|
2622
|
+ cmDspRC_t rc = kOkDspRC;
|
|
2623
|
+ cmDspGoertzel_t* p = (cmDspGoertzel_t*)inst;
|
|
2624
|
+
|
|
2625
|
+ cmGoertzelFree(&p->g);
|
|
2626
|
+
|
|
2627
|
+ return rc;
|
|
2628
|
+}
|
|
2629
|
+
|
|
2630
|
+cmDspRC_t _cmDspGoertzelReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
2631
|
+{
|
|
2632
|
+ cmDspGoertzel_t* p = (cmDspGoertzel_t*)inst;
|
|
2633
|
+
|
|
2634
|
+ cmDspApplyAllDefaults(ctx,inst);
|
|
2635
|
+
|
|
2636
|
+ p->outPhs = 0;
|
|
2637
|
+
|
|
2638
|
+ return kOkDspRC;
|
|
2639
|
+}
|
|
2640
|
+
|
|
2641
|
+cmDspRC_t _cmDspGoertzelExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
2642
|
+{
|
|
2643
|
+ cmDspRC_t rc = kOkDspRC;
|
|
2644
|
+ cmDspGoertzel_t* p = (cmDspGoertzel_t*)inst;
|
|
2645
|
+ const cmSample_t* x = cmDspAudioBuf(ctx,inst,kInGrId,0);
|
|
2646
|
+ unsigned n = cmDspAudioBufSmpCount(ctx,inst,kInGrId,0);
|
|
2647
|
+ double outMs = 50.0;
|
|
2648
|
+ double outPhsMax = outMs * cmDspSysSampleRate(ctx->dspH) / 1000.0;
|
|
2649
|
+ double outV[ p->g->chCnt ];
|
|
2650
|
+ unsigned i;
|
|
2651
|
+
|
|
2652
|
+ if( x != NULL )
|
|
2653
|
+ {
|
|
2654
|
+ cmGoertzelExec(p->g,x,n,outV,p->g->chCnt);
|
|
2655
|
+
|
|
2656
|
+ p->outPhs += n;
|
|
2657
|
+ if( p->outPhs > outPhsMax )
|
|
2658
|
+ {
|
|
2659
|
+ while( p->outPhs > outPhsMax )
|
|
2660
|
+ p->outPhs -= outPhsMax;
|
|
2661
|
+
|
|
2662
|
+ for(i=0; i<p->g->chCnt; ++i)
|
|
2663
|
+ {
|
|
2664
|
+ cmDspSetDouble(ctx,inst,kOutBaseGrId+i,outV[i]);
|
|
2665
|
+ //printf("%f ",outV[i]);
|
|
2666
|
+ }
|
|
2667
|
+ //printf("\n");
|
|
2668
|
+ }
|
|
2669
|
+ }
|
|
2670
|
+
|
|
2671
|
+ return rc;
|
|
2672
|
+}
|
|
2673
|
+
|
|
2674
|
+cmDspRC_t _cmDspGoertzelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
2675
|
+{
|
|
2676
|
+ cmDspSetEvent(ctx,inst,evt);
|
|
2677
|
+
|
|
2678
|
+ return kOkDspRC;
|
|
2679
|
+}
|
|
2680
|
+
|
|
2681
|
+struct cmDspClass_str* cmGoertzelClassCons( cmDspCtx_t* ctx )
|
|
2682
|
+{
|
|
2683
|
+ cmDspClassSetup(&_cmGoertzelDC,ctx,"Goertzel",
|
|
2684
|
+ NULL,
|
|
2685
|
+ _cmDspGoertzelAlloc,
|
|
2686
|
+ _cmDspGoertzelFree,
|
|
2687
|
+ _cmDspGoertzelReset,
|
|
2688
|
+ _cmDspGoertzelExec,
|
|
2689
|
+ _cmDspGoertzelRecv,
|
|
2690
|
+ NULL,
|
|
2691
|
+ NULL,
|
|
2692
|
+ "Goertzel Tone Detector Filter");
|
|
2693
|
+
|
|
2694
|
+ return &_cmGoertzelDC;
|
|
2695
|
+}
|