libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmProc5.c 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmLinkedHeap.h"
  9. #include "cmFloatTypes.h"
  10. #include "cmComplexTypes.h"
  11. #include "cmFileSys.h"
  12. #include "cmJson.h"
  13. #include "cmSymTbl.h"
  14. #include "cmAudioFile.h"
  15. #include "cmText.h"
  16. #include "cmProcObj.h"
  17. #include "cmProcTemplate.h"
  18. #include "cmMath.h"
  19. #include "cmProc.h"
  20. #include "cmProc5.h"
  21. #include "cmVectOps.h"
  22. //=======================================================================================================================
  23. cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt, unsigned procSmpCnt, unsigned hopSmpCnt, unsigned wndSmpCnt )
  24. {
  25. cmGoertzel* op = cmObjAlloc(cmGoertzel,c,p);
  26. op->shb = cmShiftBufAlloc(c,NULL,0,0,0);
  27. if( srate > 0 )
  28. if( cmGoertzelInit(op,srate,fcHzV,chCnt,procSmpCnt,wndSmpCnt,hopSmpCnt) != cmOkRC )
  29. cmGoertzelFree(&op);
  30. return op;
  31. }
  32. cmRC_t cmGoertzelFree( cmGoertzel** pp )
  33. {
  34. cmRC_t rc = cmOkRC;
  35. if( pp==NULL || *pp==NULL )
  36. return rc;
  37. cmGoertzel* p = *pp;
  38. if((rc = cmGoertzelFinal(p)) != cmOkRC )
  39. return rc;
  40. cmShiftBufFree(&p->shb);
  41. cmMemFree(p->ch);
  42. cmMemFree(p->wnd);
  43. cmObjFree(pp);
  44. return rc;
  45. }
  46. cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt, unsigned procSmpCnt, unsigned hopSmpCnt, unsigned wndSmpCnt )
  47. {
  48. cmRC_t rc;
  49. unsigned i;
  50. if((rc = cmGoertzelFinal(p)) != cmOkRC )
  51. return rc;
  52. p->ch = cmMemResizeZ(cmGoertzelCh,p->ch,chCnt);
  53. p->chCnt = chCnt;
  54. p->srate = srate;
  55. p->wnd = cmMemResizeZ(cmSample_t,p->wnd,wndSmpCnt);
  56. cmVOS_Hann(p->wnd,wndSmpCnt);
  57. cmShiftBufInit(p->shb,procSmpCnt,wndSmpCnt,hopSmpCnt);
  58. for(i=0; i<p->chCnt; ++i)
  59. {
  60. cmGoertzelSetFcHz(p,i,fcHzV[i]);
  61. }
  62. return rc;
  63. }
  64. cmRC_t cmGoertzelFinal( cmGoertzel* p )
  65. { return cmOkRC; }
  66. cmRC_t cmGoertzelSetFcHz( cmGoertzel* p, unsigned chIdx, double hz )
  67. {
  68. assert( chIdx < p->chCnt );
  69. p->ch[chIdx].hz = hz;
  70. p->ch[chIdx].coeff = 2*cos(2*M_PI*hz/p->srate);
  71. return cmOkRC;
  72. }
  73. cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* inpV, unsigned procSmpCnt, double* outV, unsigned chCnt )
  74. {
  75. unsigned i,j;
  76. while( cmShiftBufExec(p->shb,inpV,procSmpCnt) )
  77. {
  78. unsigned xn = p->shb->wndSmpCnt;
  79. cmSample_t x[ xn ];
  80. cmVOS_MultVVV(x,xn,p->wnd,p->shb->outV);
  81. for(i=0; i<chCnt; ++i)
  82. {
  83. cmGoertzelCh* ch = p->ch + i;
  84. ch->s2 = x[0];
  85. ch->s1 = x[1] + 2 * x[0] * ch->coeff;
  86. for(j=2; j<xn; ++j)
  87. {
  88. ch->s0 = x[j] + ch->coeff * ch->s1 - ch->s2;
  89. ch->s2 = ch->s1;
  90. ch->s1 = ch->s0;
  91. }
  92. outV[i] = ch->s2*ch->s2 + ch->s1*ch->s1 - ch->coeff * ch->s2 * ch->s1;
  93. }
  94. }
  95. return cmOkRC;
  96. }