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.

cmProc.h 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. #ifndef cmProc_h
  2. #define cmProc_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. //------------------------------------------------------------------------------------------------------------
  7. typedef struct
  8. {
  9. cmObj obj;
  10. cmAudioFileH_t h; // audio file handle
  11. cmAudioFileInfo_t info; // audio file info record
  12. unsigned chIdx;
  13. cmSample_t* outV; // buffer of audio from last read
  14. unsigned outN; // length of outV in samples
  15. cmChar_t* fn; // name of audio file
  16. unsigned lastReadFrmCnt; // count of samples actually read on last read
  17. bool eofFl;
  18. unsigned begFrmIdx;
  19. unsigned endFrmIdx;
  20. unsigned curFrmIdx; // frame index of the next frame to read
  21. cmMtxFile* mfp;
  22. } cmAudioFileRd;
  23. /// set p to NULL to dynamically allocate the object
  24. /// fn and chIdx are optional - set fn to NULL to allocate the reader without opening a file.
  25. /// If fn is valid then chIdx must also be valid.
  26. /// Set 'endSmpIdx' to cmInvalidIdx to not limit the range of samples returned.
  27. cmAudioFileRd* cmAudioFileRdAlloc( cmCtx* c, cmAudioFileRd* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
  28. cmRC_t cmAudioFileRdFree( cmAudioFileRd** p );
  29. cmRC_t cmAudioFileRdOpen( cmAudioFileRd* p, unsigned procSmpCnt, const cmChar_t* fn, unsigned chIdx, unsigned begSmpIdx, unsigned endSmpIdx );
  30. cmRC_t cmAudioFileRdClose( cmAudioFileRd* p );
  31. /// Returns cmEofRC if the end of file is encountered.
  32. cmRC_t cmAudioFileRdRead( cmAudioFileRd* p );
  33. cmRC_t cmAudioFileRdSeek( cmAudioFileRd* p, unsigned frmIdx );
  34. /// Find the overall minimum, maximum, and mean sample values without changing the current file location.
  35. cmRC_t cmAudioFileRdMinMaxMean( cmAudioFileRd* p, unsigned chIdx, cmSample_t* minPtr, cmSample_t* maxPtr, cmSample_t* meanPtr );
  36. //------------------------------------------------------------------------------------------------------------
  37. /// The buffer is intended to synchronize sample block rates between processes and to provide an overlapped
  38. /// input buffer.
  39. typedef struct
  40. {
  41. cmObj obj;
  42. unsigned bufSmpCnt; // wndSmpCnt + hopSmpCnt
  43. cmSample_t* bufV;
  44. cmSample_t* outV; // output window outV[ outN ]
  45. unsigned outN; // outN == wndSmpCnt
  46. unsigned procSmpCnt; // input sample count
  47. unsigned wndSmpCnt; // output sample count
  48. unsigned hopSmpCnt; // count of samples to shift the buffer by on each call to cmShiftExec()
  49. cmSample_t* inPtr; // ptr to location in outV[] to recv next sample
  50. bool fl; // reflects the last value returned by cmShiftBufExec().
  51. } cmShiftBuf;
  52. /// Set p to NULL to dynamically allocate the object. hopSmpCnt must be <= wndSmpCnt.
  53. cmShiftBuf* cmShiftBufAlloc( cmCtx* c, cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
  54. cmRC_t cmShiftBufFree( cmShiftBuf** p );
  55. cmRC_t cmShiftBufInit( cmShiftBuf* p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt );
  56. cmRC_t cmShiftBufFinal( cmShiftBuf* p );
  57. /// Returns true if a new hop is ready to be read otherwise returns false.
  58. /// In general cmShiftBufExec() should be called in a loop until it returns false.
  59. /// Note that 'sp' and 'sn' are ignored except for the first call after the function returns false.
  60. /// This means that when called in a loop 'sp' and 'sn' are only used on the first time through the loop.
  61. /// When procSmpCnt is less than hopSmpCnt the loop will only execute when at least wndSmpCnt
  62. /// new samples have been buffered.
  63. /// When procSmpCnt is greater than hopSmpCnt the loop will execute multiple times until less
  64. // than wndSmpCnt new samples are available.
  65. /// Note that 'sn' must always be less than or equal to procSmpCnt.
  66. ///
  67. /// Example:
  68. /// while( fill(sp,sn) ) // fill sp[] with sn samples
  69. /// {
  70. /// // shift by hopSmpCnt samples on all passes - insert new samples on first pass
  71. /// while( cmShiftBufExec(p,sp,sn) )
  72. /// proc(p->outV,p->outN); // process p->outV[wndSmpCnt]
  73. /// }
  74. bool cmShiftBufExec( cmShiftBuf* p, const cmSample_t* sp, unsigned sn );
  75. void cmShiftBufTest( cmCtx* c );
  76. //------------------------------------------------------------------------------------------------------------
  77. /*
  78. typedef struct
  79. {
  80. cmComplexS_t* complexV;
  81. cmSample_t* outV;
  82. cmFftPlanS_t plan;
  83. } cmIFftObjS;
  84. typedef struct
  85. {
  86. cmComplexR_t* complexV;
  87. cmReal_t* outV;
  88. cmFftPlanR_t plan;
  89. } cmIFftObjR;
  90. typedef struct
  91. {
  92. cmObj obj;
  93. unsigned binCnt;
  94. unsigned outN;
  95. union
  96. {
  97. cmIFftObjS sr;
  98. cmIFftObjR rr;
  99. }u;
  100. } cmIFft;
  101. cmIFft* cmIFftAllocS( cmCtx* c, cmIFft* p, unsigned binCnt );
  102. cmIFft* cmIFftAllocR( cmCtx* c, cmIFft* p, unsigned binCnt );
  103. cmRC_t cmIFftFreeS( cmIFft** pp );
  104. cmRC_t cmIFftFreeR( cmIFft** pp );
  105. cmRC_t cmIFftInitS( cmIFft* p, unsigned binCnt );
  106. cmRC_t cmIFftInitR( cmIFft* p, unsigned binCnt );
  107. cmRC_t cmIFftFinalS( cmIFft* p );
  108. cmRC_t cmIFftFinalR( cmIFft* p );
  109. // x must contain 'binCnt' elements.
  110. cmRC_t cmIFftExecS( cmIFft* p, cmComplexS_t* x );
  111. cmRC_t cmIFftExecR( cmIFft* p, cmComplexR_t* x );
  112. cmRC_t cmIFftExecPolarS( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
  113. cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
  114. cmRC_t cmIFftExecRectS( cmIFft* p, const cmReal_t* rV, const cmReal_t* iV );
  115. cmRC_t cmIFftExecPolarR( cmIFft* p, const cmReal_t* magV, const cmReal_t* phsV );
  116. void cmIFftTest( cmRpt_t* rptFuncPtr );
  117. */
  118. //------------------------------------------------------------------------------------------------------------
  119. enum
  120. {
  121. kInvalidWndId = 0x000,
  122. kHannWndId = 0x001,
  123. kHammingWndId = 0x002,
  124. kTriangleWndId = 0x004,
  125. kKaiserWndId = 0x008,
  126. kHannMatlabWndId= 0x010,
  127. kUnityWndId = 0x020,
  128. kWndIdMask = 0x0ff,
  129. kNormByLengthWndFl = 0x100, // mult by 1/wndSmpCnt
  130. kNormBySumWndFl = 0x200 // mult by wndSmpCnt/sum(wndV)
  131. };
  132. typedef struct
  133. {
  134. cmObj obj;
  135. unsigned wndId;
  136. unsigned flags;
  137. cmSample_t* wndV;
  138. cmSample_t* outV;
  139. unsigned outN; // same as wndSmpCnt
  140. double kslRejectDb;
  141. cmMtxFile* mfp;
  142. } cmWndFunc;
  143. /// Set p to NULL to dynamically allocate the object
  144. /// if wndId is set to a valid value this function will internally call cmWndFuncInit()
  145. cmWndFunc* cmWndFuncAlloc( cmCtx* c, cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaierSideLobeRejectDb );
  146. cmRC_t cmWndFuncFree( cmWndFunc** pp );
  147. cmRC_t cmWndFuncInit( cmWndFunc* p, unsigned wndId, unsigned wndSmpCnt, double kaiserSideLobeRejectDb );
  148. cmRC_t cmWndFuncFinal( cmWndFunc* p );
  149. cmRC_t cmWndFuncExec( cmWndFunc* p, const cmSample_t* sp, unsigned sn );
  150. void cmWndFuncTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  151. //------------------------------------------------------------------------------------------------------------
  152. /// Spectral frame delay. A circular buffer for spectral (or other fixed length) vectors.
  153. typedef struct
  154. {
  155. cmObj obj;
  156. cmSample_t* bufPtr;
  157. unsigned maxDelayCnt;
  158. int inIdx;
  159. unsigned outN; // outN == binCnt
  160. } cmSpecDelay;
  161. /// Set p to NULL to dynamically allocate the object.
  162. /// Allocate a spectral frame delay capable of delaying for 'maxDelayCnt' hops and
  163. /// where each vector contains 'binCnt' elements.
  164. cmSpecDelay* cmSpecDelayAlloc( cmCtx* c, cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
  165. cmRC_t cmSpecDelayFree( cmSpecDelay** p );
  166. cmRC_t cmSpecDelayInit( cmSpecDelay* p, unsigned maxDelayCnt, unsigned binCnt );
  167. cmRC_t cmSpecDelayFinal(cmSpecDelay* p );
  168. /// Give an input vector to the delay. 'sn' must <= binCnt
  169. cmRC_t cmSpecDelayExec( cmSpecDelay* p, const cmSample_t* sp, unsigned sn );
  170. /// Get a pointer to a delayed vector. 'delayCnt' indicates the length of the delay in hops.
  171. /// (e.g. 1 is the previous hop, 2 is two hops previous, ... )
  172. const cmSample_t* cmSpecDelayOutPtr(cmSpecDelay* p, unsigned delayCnt );
  173. //------------------------------------------------------------------------------------------------------------
  174. typedef struct cmFilter_str
  175. {
  176. cmObj obj;
  177. cmReal_t* a; // feedback coeff's
  178. int an; // count of fb coeff's
  179. cmReal_t* b; // feedforward coeff's
  180. int bn; // count of ff coeffs'
  181. cmReal_t* d; // delay
  182. int di; //
  183. int cn; // length of delay
  184. cmReal_t b0; // 1st feedforward coeff
  185. cmSample_t* outSmpV; // signal output vector
  186. cmReal_t* outRealV;
  187. unsigned outN; // length of outV (procSmpCnt)
  188. } cmFilter;
  189. // d[dn] is the initial value of the delay line where dn = max(an,bn)-1.
  190. // Set d to NULL to intialize the delays to 0.
  191. cmFilter* cmFilterAlloc( cmCtx* c, cmFilter* p, const cmReal_t* b, unsigned bn, const cmReal_t* a, unsigned an, unsigned procSmpCnt, const cmReal_t* d );
  192. cmFilter* cmFilterAllocEllip( cmCtx* c, cmFilter* p, cmReal_t srate, cmReal_t passHz, cmReal_t stopHz, cmReal_t passDb, cmReal_t stopDb, unsigned procSmpCnt, const cmReal_t* d );
  193. cmRC_t cmFilterFree( cmFilter** pp );
  194. cmRC_t cmFilterInit( cmFilter* p, const cmReal_t* b, unsigned bn, const cmReal_t* a, unsigned an, unsigned procSmpCnt, const cmReal_t* d );
  195. cmRC_t cmFilterInitEllip( cmFilter* p, cmReal_t srate, cmReal_t passHz, cmReal_t stopHz, cmReal_t passDb, cmReal_t stopDb, unsigned procSmpCnt, const cmReal_t* d );
  196. cmRC_t cmFilterFinal( cmFilter* p );
  197. // If y==NULL or yn==0 then the output is sent to p->outV[p->outN].
  198. // This function can safely filter a signal in plcme therefore it is allowable for x[] and y[] to refer to the same memory.
  199. // If x[] overlaps y[] then y must be <= x.
  200. cmRC_t cmFilterExecS( cmFilter* p, const cmSample_t* x, unsigned xn, cmSample_t* y, unsigned yn );
  201. cmRC_t cmFilterExecR( cmFilter* p, const cmReal_t* x, unsigned xn, cmReal_t* y, unsigned yn );
  202. cmRC_t cmFilterSignal( cmCtx* c, const cmReal_t b[], unsigned bn, const cmReal_t a[], unsigned an, const cmSample_t* x, unsigned xn, cmSample_t* y, unsigned yn );
  203. // Perform forward-reverse filtering.
  204. cmRC_t cmFilterFilterS(cmCtx* c, const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const cmSample_t* x, unsigned xn, cmSample_t* y, unsigned yn );
  205. cmRC_t cmFilterFilterR(cmCtx* c, const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const cmReal_t* x, unsigned xn, cmReal_t* y, unsigned yn );
  206. void cmFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  207. void cmFilterFilterTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  208. //------------------------------------------------------------------------------------------------------------
  209. typedef struct
  210. {
  211. cmObj obj;
  212. cmSpecDelay phsDelay;
  213. cmSpecDelay magDelay;
  214. unsigned binCnt;
  215. cmSample_t out;
  216. //cmMtxFile* mfp;
  217. //unsigned cdfSpRegId;
  218. } cmComplexDetect;
  219. /// Set p to NULL to dynamically allocate the object.
  220. cmComplexDetect* cmComplexDetectAlloc(cmCtx* c, cmComplexDetect* p, unsigned binCnt );
  221. cmRC_t cmComplexDetectFree( cmComplexDetect** pp);
  222. cmRC_t cmComplexDetectInit( cmComplexDetect* p, unsigned binCnt );
  223. cmRC_t cmComplexDetectFinal(cmComplexDetect* p);
  224. cmRC_t cmComplexDetectExec( cmComplexDetect* p, const cmSample_t* magV, const cmSample_t* phsV, unsigned binCnt );
  225. //------------------------------------------------------------------------------------------------------------
  226. typedef struct
  227. {
  228. cmObj obj;
  229. double threshold;
  230. unsigned medSmpCnt;
  231. unsigned frmCnt; // expected number of frames to store
  232. unsigned dfi;
  233. cmSample_t* df;
  234. cmSample_t* fdf;
  235. cmSample_t onrate;
  236. //cmMtxFile* mfp;
  237. } cmComplexOnset;
  238. cmComplexOnset* cmComplexOnsetAlloc( cmCtx* c, cmComplexOnset* p, unsigned procSmpCnt, double srate, unsigned medFiltWndSmpCnt, double threshold, unsigned frameCnt );
  239. cmRC_t cmComplexOnsetFree( cmComplexOnset** pp);
  240. cmRC_t cmComplexOnsetInit( cmComplexOnset* p, unsigned procSmpCnt, double srate, unsigned medFiltWndSmpCnt, double threshold, unsigned frameCnt );
  241. cmRC_t cmComplexOnsetFinal( cmComplexOnset* p);
  242. cmRC_t cmComplexOnsetExec( cmComplexOnset* p, cmSample_t cdf );
  243. cmRC_t cmComplexOnsetCalc( cmComplexOnset* p );
  244. //------------------------------------------------------------------------------------------------------------
  245. typedef struct
  246. {
  247. cmObj obj;
  248. unsigned melBandCnt;
  249. unsigned dctCoeffCnt;
  250. unsigned binCnt;
  251. cmReal_t* melM;
  252. cmReal_t* dctM;
  253. cmReal_t* outV;
  254. unsigned outN; // outN == dctCoeffCnt
  255. cmMtxFile* mfp;
  256. unsigned mfccSpRegId; // cmStatsProc regId
  257. } cmMfcc;
  258. cmMfcc* cmMfccAlloc( cmCtx* c, cmMfcc* p, double srate, unsigned melBandCnt, unsigned dctCoeffCnt, unsigned binCnt );
  259. cmRC_t cmMfccFree( cmMfcc** pp );
  260. cmRC_t cmMfccInit( cmMfcc* p, double srate, unsigned melBandCnt, unsigned dctCoeffCnt, unsigned binCnt );
  261. cmRC_t cmMfccFinal( cmMfcc* p );
  262. cmRC_t cmMfccExecPower( cmMfcc* p, const cmReal_t* magPowV, unsigned binCnt );
  263. cmRC_t cmMfccExecAmplitude( cmMfcc* p, const cmReal_t* magAmpV, unsigned binCnt );
  264. void cmMfccTest();
  265. //------------------------------------------------------------------------------------------------------------
  266. typedef struct
  267. {
  268. cmObj obj;
  269. cmReal_t* ttmV; // Terhardt outer ear filter
  270. cmReal_t* sfM; // Shroeder spreading function
  271. unsigned* barkIdxV; // Bark to bin map
  272. unsigned* barkCntV; //
  273. cmReal_t* outV; // specific loudness in sones
  274. unsigned outN; // outN == barkBandCnt;
  275. cmReal_t overallLoudness; // overall loudness in sones
  276. unsigned binCnt; // expected length of incoming power spectrum
  277. unsigned barkBandCnt; // count of bark bands
  278. unsigned flags; //
  279. cmMtxFile* mfp;
  280. unsigned sonesSpRegId;
  281. unsigned loudSpRegId;
  282. } cmSones;
  283. enum { kDontUseEqlLoudSonesFl=0x00, kUseEqlLoudSonesFl=0x01 };
  284. cmSones* cmSonesAlloc( cmCtx* c, cmSones* p, double srate, unsigned barkBandCnt, unsigned binCnt, unsigned flags );
  285. cmRC_t cmSonesFree( cmSones** pp );
  286. cmRC_t cmSonesInit( cmSones* p, double srate, unsigned barkBandCnt, unsigned binCnt, unsigned flags );
  287. cmRC_t cmSonesFinal( cmSones* p );
  288. cmRC_t cmSonesExec( cmSones* p, const cmReal_t* magPowV, unsigned binCnt );
  289. void cmSonesTest();
  290. //------------------------------------------------------------------------------------------------------------
  291. typedef struct
  292. {
  293. cmObj obj;
  294. unsigned cBufCnt;
  295. unsigned cBufCurCnt;
  296. unsigned cBufIdx;
  297. double cBufSum;
  298. unsigned cCntSum;
  299. cmReal_t* cBufPtr;
  300. unsigned* cCntPtr;
  301. cmSample_t offset;
  302. double dBref;
  303. cmSample_t* outV;
  304. unsigned outN; // (outN == procSmpCnt)
  305. unsigned flags;
  306. cmMtxFile* mfp;
  307. } cmAudioOffsetScale;
  308. /// This processor adds an offset to an audio signal and scales into dB (SPL) using one of two techniques
  309. /// 1) Measures the effective sound pressure (via RMS) and then scales the signal to the reference dB (SPL)
  310. /// In this case dBref is commonly set to 70. See Timony, 2004, Implementing Loudness Models in Matlab.
  311. ///
  312. /// 2) treats the dBref as the maximum dB (SPL) and scales the signal by this amount without regard
  313. /// measured signal level. In this case dBref is commonly set to 96 (max. dB (SPL) value for 16 bits)
  314. /// and rmsWndSecs is ignored.
  315. ///
  316. /// Note that setting rmsWndSecs to zero has the effect of using procSmpCnt as the window length.
  317. enum { kNoAudioScaleFl=0x01, kRmsAudioScaleFl=0x02, kFixedAudioScaleFl=0x04 };
  318. cmAudioOffsetScale* cmAudioOffsetScaleAlloc( cmCtx* c, cmAudioOffsetScale* p, unsigned procSmpCnt, double srate, cmSample_t offset, double rmsWndSecs, double dBref, unsigned flags );
  319. cmRC_t cmAudioOffsetScaleFree( cmAudioOffsetScale** pp );
  320. cmRC_t cmAudioOffsetScaleInit( cmAudioOffsetScale* p, unsigned procSmpCnt, double srate, cmSample_t offset, double rmsWndSecs, double dBref, unsigned flags );
  321. cmRC_t cmAudioOffsetScaleFinal( cmAudioOffsetScale* p );
  322. cmRC_t cmAudioOffsetScaleExec( cmAudioOffsetScale* p, const cmSample_t* sp, unsigned sn );
  323. //------------------------------------------------------------------------------------------------------------
  324. typedef struct
  325. {
  326. cmObj obj;
  327. cmReal_t* rmsV;
  328. cmReal_t* hfcV;
  329. cmReal_t* scnV;
  330. cmReal_t rmsSum;
  331. cmReal_t hfcSum;
  332. cmReal_t scnSum;
  333. cmReal_t ssSum;
  334. cmReal_t rms; // RMS output
  335. cmReal_t hfc; // high-frequency content output
  336. cmReal_t sc; // spectral centroid output
  337. cmReal_t ss; // spectral spread output
  338. unsigned binCnt;
  339. unsigned flags;
  340. unsigned wndFrmCnt;
  341. unsigned frameIdx;
  342. unsigned frameCnt;
  343. double binHz;
  344. cmMtxFile* mfp;
  345. unsigned rmsSpRegId;
  346. unsigned hfcSpRegId;
  347. unsigned scSpRegId;
  348. unsigned ssSpRegId;
  349. } cmSpecMeas;
  350. /// Set wndFrmCnt to the number of spectral frames to take the measurement over.
  351. /// Setting wndFrmCnt to 1 has the effect of calculating the value on the current frame only.
  352. /// Set flags = kWholeSigSpecMeasFl to ignore wndFrmCnt and calculate the result on the entire signal.
  353. /// In effect this treats the entire signal as the length of the measurement window.
  354. enum { kWholeSigSpecMeasFl=0x00, kUseWndSpecMeasFl=0x01 };
  355. cmSpecMeas* cmSpecMeasAlloc( cmCtx* c, cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags );
  356. cmRC_t cmSpecMeasFree( cmSpecMeas** pp );
  357. cmRC_t cmSpecMeasInit( cmSpecMeas* p, double srate, unsigned binCnt, unsigned wndFrmCnt, unsigned flags );
  358. cmRC_t cmSpecMeasFinal( cmSpecMeas* p );
  359. cmRC_t cmSpecMeasExec( cmSpecMeas* p, const cmReal_t* magPowV, unsigned binCnt );
  360. //------------------------------------------------------------------------------------------------------------
  361. typedef struct
  362. {
  363. cmObj obj;
  364. cmShiftBuf* sbp; // shift buffer used internally if procSmpCnt < measSmpCnt
  365. cmShiftBuf shiftBuf;
  366. double srate; //
  367. cmReal_t zcr; // zero crossing rate per second
  368. cmSample_t zcrDelay; // used internally by zero crossing count algorithm
  369. unsigned measSmpCnt; // length of measurement window in samples
  370. unsigned procSmpCnt; // expected number of samples per call to exec
  371. unsigned zcrSpRegId;
  372. cmMtxFile* mfp;
  373. } cmSigMeas;
  374. // procSmpCnt must be <= measSmpCnt
  375. cmSigMeas* cmSigMeasAlloc( cmCtx* c, cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt );
  376. cmRC_t cmSigMeasFree( cmSigMeas** pp );
  377. cmRC_t cmSigMeasInit( cmSigMeas* p, double srate, unsigned procSmpCnt, unsigned measSmpCnt );
  378. cmRC_t cmSigMeasFinal( cmSigMeas* p );
  379. cmRC_t cmSigMeasExec( cmSigMeas* p, const cmSample_t* sigV, unsigned smpCnt );
  380. //------------------------------------------------------------------------------------------------------------
  381. typedef struct
  382. {
  383. cmObj obj;
  384. cmFilter filt;
  385. cmSample_t* outV;
  386. unsigned outN;
  387. unsigned upFact;
  388. unsigned dnFact;
  389. unsigned upi;
  390. unsigned dni;
  391. cmMtxFile* mfp;
  392. } cmSRC;
  393. /// The srate paramater is the sample rate of the source signal provided via cmSRCExec()
  394. cmSRC* cmSRCAlloc( cmCtx* c, cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact );
  395. cmRC_t cmSRCFree( cmSRC** pp );
  396. cmRC_t cmSRCInit( cmSRC* p, double srate, unsigned procSmpCnt, unsigned upFact, unsigned dnFact );
  397. cmRC_t cmSRCFinal( cmSRC* p );
  398. cmRC_t cmSRCExec( cmSRC* p, const cmSample_t* sp, unsigned sn );
  399. void cmSRCTest();
  400. //------------------------------------------------------------------------------------------------------------
  401. typedef struct
  402. {
  403. cmObj obj;
  404. cmComplexR_t* fiV;
  405. cmComplexR_t* foV;
  406. cmComplexR_t* skM; // skM[ wndSmpCnt, constQBinCnt ]
  407. unsigned* skBegV; // skBegV[ constQBinCnt ] indexes used to decrease the size of the mtx mult in cmConstQExex()
  408. unsigned* skEndV; // skEndV[ constQBinCnt ]
  409. unsigned wndSmpCnt; // window length of the complex FFT required to feed this transform
  410. unsigned constQBinCnt; // count of bins in the const Q output
  411. unsigned binsPerOctave; //
  412. cmComplexR_t* outV; // outV[ constQBinCnt ]
  413. cmReal_t* magV; // outV[ constQBinCnt ]
  414. cmMtxFile* mfp;
  415. } cmConstQ;
  416. cmConstQ* cmConstQAlloc( cmCtx* c, cmConstQ* p, double srate, unsigned minMidiPitch, unsigned maxMidiPitch, unsigned binsPerOctave, double thresh );
  417. cmRC_t cmConstQFree( cmConstQ** pp );
  418. cmRC_t cmConstQInit( cmConstQ* p, double srate, unsigned minMidiPitch, unsigned maxMidiPitch, unsigned binsPerOctave, double thresh );
  419. cmRC_t cmConstQFinal( cmConstQ* p );
  420. cmRC_t cmConstQExec( cmConstQ* p, const cmComplexR_t* ftV, unsigned binCnt );
  421. //------------------------------------------------------------------------------------------------------------
  422. typedef struct
  423. {
  424. cmObj obj;
  425. cmReal_t* hpcpM; // hpcpM[ frameCnt , binsPerOctave ] - stored hpcp
  426. cmReal_t* fhpcpM;// fhpcpM[ binsPerOctave, frameCnt ] - filtered hpcp (note transposed relative to hpcpA)
  427. unsigned* histV; // histM[ binsPerOctave/12 ]
  428. cmReal_t* outM; // outM[ 12, frameCnt ];
  429. unsigned histN; // binsPerOctave/12
  430. unsigned binsPerOctave; // const-q bins representing 1 octave
  431. unsigned constQBinCnt; // total count of const-q bins
  432. unsigned frameCnt; // expected count of hpcp vectors to store.
  433. unsigned frameIdx; // next column in hpcpM[] to receive input
  434. unsigned cqMinMidiPitch;
  435. unsigned medFiltOrder;
  436. cmReal_t* meanV; // meanV[12]
  437. cmReal_t* varV; // varV[12]
  438. cmMtxFile* mf0p; // debug files
  439. cmMtxFile* mf1p;
  440. cmMtxFile* mf2p;
  441. } cmHpcp;
  442. cmHpcp* cmTunedHpcpAlloc( cmCtx* c, cmHpcp* p, unsigned binsPerOctave, unsigned constQBinCnt, unsigned cqMinMidiPitch, unsigned frameCnt, unsigned medFiltOrder );
  443. cmRC_t cmTunedHpcpFree( cmHpcp** pp );
  444. cmRC_t cmTunedHpcpInit( cmHpcp* p, unsigned binsPerOctave, unsigned constQBinCnt, unsigned cqMinMidiPitch, unsigned frameCnt, unsigned medFiltOrder );
  445. cmRC_t cmTunedHpcpFinal( cmHpcp* p );
  446. cmRC_t cmTunedHpcpExec( cmHpcp* p, const cmComplexR_t* constQBinPtr, unsigned constQBinCnt );
  447. cmRC_t cmTunedHpcpTuneAndFilter( cmHpcp* p);
  448. //------------------------------------------------------------------------------------------------------------
  449. //------------------------------------------------------------------------------------------------------------
  450. struct cmFftRR_str;
  451. struct cmIFftRR_str;
  452. typedef struct
  453. {
  454. cmObj obj;
  455. struct cmFftRR_str* fft;
  456. struct cmIFftRR_str* ifft;
  457. unsigned frmCnt; // 512 length of df
  458. unsigned maxLagCnt; // 128 length of longest CMF lag
  459. unsigned histBinCnt; // 15 count of histogram elements and rows in H[]
  460. unsigned hColCnt; // 128 count of columns in H[]
  461. cmReal_t* m; // m[ frmCnt x maxLagCnt ]
  462. cmReal_t* H; // histogram transformation mtx
  463. cmReal_t* df; // df[ frmCnt ] onset detection function
  464. cmReal_t* fdf; // fdf[ frmCnt ] filtered onset detection function
  465. unsigned dfi; // index next df[] location to receive an incoming value
  466. cmReal_t* histV; // histV[ histBinCnt ] histogram output
  467. cmMtxFile* mfp;
  468. } cmBeatHist;
  469. cmBeatHist* cmBeatHistAlloc( cmCtx* c, cmBeatHist* p, unsigned frmCnt );
  470. cmRC_t cmBeatHistFree( cmBeatHist** pp );
  471. cmRC_t cmBeatHistInit( cmBeatHist* p, unsigned frmCnt );
  472. cmRC_t cmBeatHistFinal( cmBeatHist* p );
  473. cmRC_t cmBeatHistExec( cmBeatHist* p, cmSample_t df );
  474. cmRC_t cmBeatHistCalc( cmBeatHist* p );
  475. //------------------------------------------------------------------------------------------------------------
  476. // Gaussian Mixture Model containing N Gaussian PDF's each of dimension D
  477. typedef struct
  478. {
  479. cmObj obj;
  480. unsigned K; // count of components
  481. unsigned D; // dimensionality of each component
  482. cmReal_t* gV; // gM[ K ] mixture gain vector
  483. cmReal_t* uM; // uM[ D x K ] component mean column vectors
  484. cmReal_t* sMM; // sMM[D x D x K ] component covariance matrices - each column is a DxD matrix
  485. cmReal_t* isMM; // isMM[D x D x K] inverted covar matrices
  486. cmReal_t* uMM; // uMM[ D x D x K] upper triangle factor of chol(sMM)
  487. cmReal_t* logDetV;// detV[ K ] determinent of covar matrices
  488. cmReal_t* t; // t[ D x D ]scratch matrix used for training
  489. unsigned uflags; // user defined flags
  490. } cmGmm_t;
  491. enum { cmMdgNoFlags=0x0, cmGmmDiagFl=0x01, cmGmmSkipKmeansFl=0x02 };
  492. cmGmm_t* cmGmmAlloc( cmCtx* c, cmGmm_t* p, unsigned N, unsigned D, const cmReal_t* gV, const cmReal_t* uM, const cmReal_t* sMM, unsigned flags );
  493. cmRC_t cmGmmFree( cmGmm_t** pp );
  494. cmRC_t cmGmmInit( cmGmm_t* p, unsigned N, unsigned D, const cmReal_t* gV, const cmReal_t* uM, const cmReal_t* sMM, unsigned flags );
  495. cmRC_t cmGmmFinal( cmGmm_t* p );
  496. // Estimate the parameters of the GMM using the training data in xM[p->D,xN].
  497. // *iterCntPtr on input is the number of iterations with no change in class assignment to signal convergence.
  498. // *iterCntPtr on output is the total number of interations required to converge.
  499. cmRC_t cmGmmTrain( cmGmm_t* p, const cmReal_t* xM, unsigned xN, unsigned* iterCntPtr );
  500. // Return a pointer to the feature vector at frmIdx containing D elements.
  501. typedef const cmReal_t* (*cmGmmReadFunc_t)( void* userPtr, unsigned colIdx );
  502. // Same as cmGmmTrain() but uses a function to access the feature vector.
  503. // The optional matrix uM[D,K] contains the initial mean values or NULL if not used.
  504. // The optional flag array roFlV[K] is used to indicate read-only components and is only used
  505. // when the uM[] arg. is non-NULL. Set roFlV[i] to true to indicate that the mean value supplied by
  506. // the uM[] arg. should not be alterned by the training process.
  507. // If 'maxIterCnt' is positive then it is the maximum number of iterations the training process will make
  508. // otherwise it is ignored.
  509. cmRC_t cmGmmTrain2( cmGmm_t* p, cmGmmReadFunc_t readFunc, void* userFuncPtr, unsigned xN, unsigned* iterCntPtr, const cmReal_t* uM, const bool* roFlV, int maxIterCnt );
  510. // Generate data yN data points from the GMM and store the result in yM[p->D,yN].
  511. cmRC_t cmGmmGenerate( cmGmm_t* p, cmReal_t* yM, unsigned yN );
  512. // Evaluate the probability of each column of xM[p->D,xN] and return the result in y[xN].
  513. // If yM[xN,K] is non-NULL then the individual component prob. values are returned
  514. cmRC_t cmGmmEval( cmGmm_t* p, const cmReal_t* xM, unsigned xN, cmReal_t* yV, cmReal_t* yM);
  515. // Same as cmGmmEval() but uses a a function to access each data vector
  516. cmRC_t cmGmmEval2( cmGmm_t* p, cmGmmReadFunc_t readFunc, void* userFuncPtr, unsigned xN, cmReal_t* yV, cmReal_t* yM);
  517. // Evaluate each component for a single data point
  518. // xV[D] - observed data point
  519. // yV[K] - output contains the evaluation for each component
  520. cmRC_t cmGmmEval3( cmGmm_t* p, const cmReal_t* xV, cmReal_t* yV );
  521. void cmGmmPrint( cmGmm_t* p, bool detailsFl );
  522. void cmGmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  523. //------------------------------------------------------------------------------------------------------------
  524. // Continuous Hidden Markov Model
  525. typedef struct
  526. {
  527. cmObj obj;
  528. unsigned N; // count of states
  529. unsigned K; // count of components per mixture
  530. unsigned D; // dimensionality of the observation data
  531. cmReal_t* iV; // iV[ N ] initial state probability mtx
  532. cmReal_t* aM; // aM[ N x N] transition probability mtx
  533. cmGmm_t** bV; // bV[ N ] observation probability mtx (array of pointers to GMM's)
  534. cmReal_t* bM; // bM[ N,T] state-observation probability matrix
  535. cmMtxFile* mfp;
  536. } cmChmm_t;
  537. // Continuous HMM consisting of stateN states where the observations
  538. // associated with each state are generated by a Gaussian mixture PDF.
  539. // stateN - count of states
  540. // mixN - count of components in the mixtures
  541. // dimN - dimensionality of the observation data
  542. cmChmm_t* cmChmmAlloc( cmCtx* c, cmChmm_t* p, unsigned stateN, unsigned mixN, unsigned dimN, const cmReal_t* iV, const cmReal_t* aM );
  543. cmRC_t cmChmmFree( cmChmm_t** pp );
  544. cmRC_t cmChmmInit( cmChmm_t* p, unsigned stateN, unsigned mixN, unsigned dimN, const cmReal_t* iV, const cmReal_t* aM );
  545. cmRC_t cmChmmFinal( cmChmm_t* p );
  546. // Set the iV,aM and bV parameters to well-formed random values.
  547. cmRC_t cmChmmRandomize( cmChmm_t* p, const cmReal_t* oM, unsigned T );
  548. // Train the HMM using segmental k-means to initialize the model parameters.
  549. // threshProb is the min change in fit between the data and the model above which the procedure will continue to iterate.
  550. // maxIterCnt is the maximum number of iterations the algorithm will make without regard for threshProb.
  551. // iterCnt is the value of iterCnt used in the call cmChmmTrain() on each iteration
  552. cmRC_t cmChmmSegKMeans( cmChmm_t* p, const cmReal_t* oM, unsigned T, cmReal_t threshProb, unsigned maxIterCnt, unsigned iterCnt );
  553. cmRC_t cmChmmSetGmm( cmChmm_t* p, unsigned i, const cmReal_t* wV, const cmReal_t* uM, const cmReal_t* sMM, unsigned flags );
  554. // oM[D,T] - observation matrix
  555. // alphaM[N,T] - prob of being in each state and observtin oM(:,t)
  556. // logPrV[T] - (optional) record the log prob of the data given the model at each time step
  557. // Returns sum(logPrV[T])
  558. cmReal_t cmChmmForward( const cmChmm_t* p, const cmReal_t* oM, unsigned T, cmReal_t* alphaM, cmReal_t* logPrV );
  559. void cmChmmBackward( const cmChmm_t* p, const cmReal_t* oM, unsigned T, cmReal_t* betaM );
  560. // bM[N,T] the state-observation probability table is optional
  561. cmReal_t cmChmmCompare( const cmChmm_t* p0, const cmChmm_t* p1, unsigned T );
  562. // Generate a series of observations.
  563. // oM[ p->D , T ] - output matrix
  564. // sV[ T ] - optional vector to record the state used to generate the ith observation.
  565. cmRC_t cmChmmGenerate( const cmChmm_t* p, cmReal_t* oM, unsigned T, unsigned* sV );
  566. // Infer the HMM parameters (p->iV,p->aM,p->bV) from the observations oM[D,T]
  567. enum { kNoTrainMixCoeffChmmFl=0x01, kNoTrainMeanChmmFl=0x02, kNoTrainCovarChmmFl=0x04 };
  568. cmRC_t cmChmmTrain( cmChmm_t* p, const cmReal_t* oM, unsigned T, unsigned iterCnt, cmReal_t thresh, unsigned flags );
  569. // Determine the ML state sequence yV[T] given the observations oM[D,T].
  570. cmRC_t cmChmmDecode( cmChmm_t* p, const cmReal_t* oM, unsigned T, unsigned* yV );
  571. void cmChmmPrint( cmChmm_t* p );
  572. void cmChmmTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  573. //------------------------------------------------------------------------------------------------------------
  574. // Chord recognizer
  575. typedef struct
  576. {
  577. cmObj obj;
  578. cmChmm_t* h; // hmm
  579. unsigned N; // state count N=24
  580. unsigned D; // data dimension D=12
  581. unsigned S; // tonal space dim S=6
  582. unsigned T; // frames in chromaM
  583. cmReal_t* iV; // iV[N]
  584. cmReal_t* aM; // aM[N,N]
  585. cmReal_t* uM; // uM[D,N]
  586. cmReal_t* sMM; // sMM[D*D,N]
  587. cmReal_t* phiM; // phiM[S,T]
  588. cmReal_t* chromaM; // chromaM[D,T]
  589. cmReal_t* tsM; // tsM[S,T]
  590. cmReal_t* cdtsV; // cdts[1,T]
  591. cmReal_t triadSeqMode;
  592. cmReal_t triadSeqVar;
  593. cmReal_t triadIntMean;
  594. cmReal_t triadIntVar;
  595. cmReal_t* tsMeanV; // tsMeanV[S];
  596. cmReal_t* tsVarV; // tsVarV[S]
  597. cmReal_t cdtsMean;
  598. cmReal_t cdtsVar;
  599. } cmChord;
  600. cmChord* cmChordAlloc( cmCtx* c, cmChord* p, const cmReal_t* chromaM, unsigned T );
  601. cmRC_t cmChordFree( cmChord** p );
  602. cmRC_t cmChordInit( cmChord* p, const cmReal_t* chromaM, unsigned T );
  603. cmRC_t cmChordFinal( cmChord* p );
  604. void cmChordTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  605. #ifdef __cplusplus
  606. }
  607. #endif
  608. #endif