libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmProc.h 33KB

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