libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmProc.h 33KB

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