libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmProc.h 33KB

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