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

cmProc2.h 60KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmProc2_h
  4. #define cmProc2_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"Processor Library 2" kw:[proclib]}
  9. //)
  10. //( { label:cmArray file_desc:"Expandable array designed to work easily with the cmProcObj model" kw:[proc]}
  11. // cmArray is an expandable array designed to work easily with the alloc/init/final/free model
  12. // used by this library. The arrays can be safely used by using the cmArrayAllocXXX macros
  13. // with static cmArray member fields during object allocation. cmArrayResizeXXX macros are then
  14. // used during the object initialization phase to allocate the actual array data space. Notice that
  15. // when used this way there is no need to call cmArrayFinal() prior to cmArrayResizeXXX().
  16. // The data memory used by cmArray's is allocated through the cmAllocData() and cmAllocDataZ()
  17. // macros. The resulting base memory address is therefore guaranteed to be aligned to a
  18. // 16 byte address boundary.
  19. typedef struct
  20. {
  21. cmObj obj;
  22. char* ptr;
  23. unsigned allocByteCnt;
  24. unsigned eleCnt;
  25. unsigned eleByteCnt;
  26. } cmArray;
  27. enum
  28. {
  29. kZeroArrayFl = 0x01
  30. };
  31. cmArray* cmArrayAllocate( cmCtx* c, cmArray* p, unsigned eleCnt, unsigned eleByteCnt, unsigned flags );
  32. cmRC_t cmArrayFree( cmArray** pp );
  33. cmRC_t cmArrayInit( cmArray* p, unsigned eleCnt, unsigned eleByteCnt, unsigned flags );
  34. cmRC_t cmArrayFinal( cmArray* p );
  35. char* cmArrayReallocDestroy( cmArray* p, unsigned newEleCnt, unsigned newEleByteCnt, unsigned flags );
  36. void cmArrayReallocDestroyV(cmArray* p, int eleByteCnt,unsigned flags, ... );
  37. char* cmArrayReallocPreserve(cmArray* p, unsigned newEleCnt, unsigned newEleByteCnt, unsigned flags );
  38. #define cmArrayAlloc( c, p ) cmArrayAllocate(c,p,0,0,0);
  39. #define cmArrayAllocInit( c, p, eleCnt, type ) cmArrayAllocate(c,p,eleCnt,sizeof(type),0)
  40. #define cmArrayAllocInitZ( c, p, eleCnt, type ) cmArrayAllocate(c,p,eleCnt,sizeof(type),kZeroArrayFl)
  41. #define cmArrayResize( c, p, newEleCnt, type ) (type*)cmArrayReallocDestroy(c,p,newEleCnt,sizeof(type), 0 )
  42. #define cmArrayResizeZ( c, p, newEleCnt, type ) (type*)cmArrayReallocDestroy(c,p,newEleCnt,sizeof(type), kZeroArrayFl )
  43. #define cmArrayResizePreserve( c, p, newEleCnt, type ) (type*)cmArrayReallocPreserve(c,p,newEleCnt,sizeof(type), 0 )
  44. #define cmArrayResizePreserveZ(c, p, newEleCnt, type ) (type*)cmArrayReallocPreserve(c,p,newEleCnt,sizeof(type), kZeroArrayFl )
  45. #define cmArrayResizeV( c, p, type, ... ) cmArrayReallocDestroyV(c,p,sizeof(type),0,##__VA_ARGS__)
  46. #define cmArrayResizeVZ( c, p, type, ... ) cmArrayReallocDestroyV(c,p,sizeof(type),kZeroArrayFl,##__VA_ARGS__)
  47. #define cmArrayPtr( type, p ) (type*)(p)->ptr
  48. #define cmArrayCount( p ) (p)->eleCnt
  49. //------------------------------------------------------------------------------------------------------------
  50. //)
  51. //( { label:cmAudioFileWr file_desc:"Audio file writer" kw:[proc]}
  52. typedef struct
  53. {
  54. cmObj obj;
  55. cmAudioFileH_t h;
  56. unsigned chCnt;
  57. unsigned curChCnt;
  58. unsigned procSmpCnt;
  59. char* fn;
  60. cmSample_t* bufV;
  61. } cmAudioFileWr;
  62. cmAudioFileWr* cmAudioFileWrAlloc( cmCtx* c, cmAudioFileWr* p, unsigned procSmpCnt, const char* fn, double srate, unsigned chCnt, unsigned bitsPerSample );
  63. cmRC_t cmAudioFileWrFree( cmAudioFileWr** pp );
  64. cmRC_t cmAudioFileWrInit( cmAudioFileWr* p, unsigned procSmpCnt, const char* fn, double srate, unsigned chCnt, unsigned bitsPerSample );
  65. cmRC_t cmAudioFileWrFinal( cmAudioFileWr* p );
  66. cmRC_t cmAudioFileWrExec( cmAudioFileWr* p, unsigned chIdx, const cmSample_t* sp, unsigned sn );
  67. void cmAudioFileWrTest();
  68. //------------------------------------------------------------------------------------------------------------
  69. //)
  70. //( { label:cmMatrixBuf file_desc:"Store and recall real values in matrix form." kw:[proc]}
  71. typedef struct
  72. {
  73. cmObj obj;
  74. unsigned rn;
  75. unsigned cn;
  76. cmSample_t *bufPtr;
  77. } cmMatrixBuf;
  78. /// Set p to NULL to dynamically allocate the object
  79. cmMatrixBuf* cmMatrixBufAllocFile(cmCtx* c, cmMatrixBuf* p, const char* fn );
  80. cmMatrixBuf* cmMatrixBufAllocCopy(cmCtx* c, cmMatrixBuf* p, unsigned rn, unsigned cn, const cmSample_t* sp );
  81. cmMatrixBuf* cmMatrixBufAlloc( cmCtx* c, cmMatrixBuf* p, unsigned rn, unsigned cn );
  82. cmRC_t cmMatrixBufFree( cmMatrixBuf**p );
  83. cmRC_t cmMatrixBufInitFile( cmMatrixBuf* p, const char* fn );
  84. cmRC_t cmMatrixBufInitCopy( cmMatrixBuf* p, unsigned rn, unsigned cn, const cmSample_t* sp );
  85. cmRC_t cmMatrixBufInit( cmMatrixBuf* p, unsigned rn, unsigned cn );
  86. cmRC_t cmMatrixBufFinal( cmMatrixBuf* p );
  87. cmSample_t* cmMatrixBufColPtr( cmMatrixBuf* p, unsigned ci );
  88. cmSample_t* cmMatrixBufRowPtr( cmMatrixBuf* p, unsigned ri );
  89. void cmMatrixBufTest();
  90. //------------------------------------------------------------------------------------------------------------
  91. //)
  92. //( { label:cmSigGen file_desc:"Generate periodic and noise signals." kw:[proc]}
  93. enum
  94. {
  95. kInvalidWfId,
  96. kSineWfId,
  97. kCosWfId,
  98. kSquareWfId,
  99. kTriangleWfId,
  100. kSawtoothWfId,
  101. kWhiteWfId,
  102. kPinkWfId,
  103. kPulseWfId,
  104. kImpulseWfId,
  105. kSilenceWfId,
  106. kPhasorWfId,
  107. kSeqWfId, // always incrementing integer sequence (srate,frq,otCnt is ignored)
  108. };
  109. typedef struct
  110. {
  111. cmObj obj;
  112. unsigned wfId;
  113. unsigned overToneCnt;
  114. double fundFrqHz;
  115. cmSample_t* outV;
  116. unsigned outN; // outN == procSmpCnt
  117. unsigned phase;
  118. cmSample_t delaySmp;
  119. double srate;
  120. } cmSigGen;
  121. /// Set p to NULL to dynamically allocate the object
  122. /// The last three arguments are optional. Set wfId to kInvalidWfId to allocate the signal generator without initializint it.
  123. cmSigGen* cmSigGenAlloc( cmCtx* c, cmSigGen* p, unsigned procSmpCnt, double srate, unsigned wfId, double fundFrqHz, unsigned overToneCnt );
  124. cmRC_t cmSigGenFree( cmSigGen** p );
  125. cmRC_t cmSigGenInit( cmSigGen* p, unsigned procSmpCnt, double srate, unsigned wfId, double fundFrqHz, unsigned overToneCnt );
  126. cmRC_t cmSigGenFinal( cmSigGen* p );
  127. cmRC_t cmSigGenExec( cmSigGen* p );
  128. //------------------------------------------------------------------------------------------------------------
  129. //)
  130. //( { label:cmDelay file_desc:"Fixed length audio delay." kw:[proc]}
  131. typedef struct
  132. {
  133. cmObj* obj;
  134. cmSample_t* bufPtr;
  135. unsigned bufSmpCnt; // count of samples in the delay line (bufSmpCnt = procSmpCnt+delaySmpCnt)
  136. unsigned procSmpCnt; // maximum legal samples to receive in a single call to cmDelayExec()
  137. unsigned delaySmpCnt; // delay time in samples
  138. int delayInIdx; // index into bufPtr[] of next element to receive an incoming sample
  139. unsigned outCnt; // count of valid buffers in outV[]
  140. cmSample_t* outV[2]; // pointers to output buffers
  141. unsigned outN[2]; // length of output buffers (the sum of the length of both output buffers is always procSmpCnt)
  142. } cmDelay;
  143. cmDelay* cmDelayAlloc( cmCtx* c, cmDelay* p, unsigned procSmpCnt, unsigned delaySmpCnt );
  144. cmRC_t cmDelayFree( cmDelay** p );
  145. cmRC_t cmDelayInit( cmDelay* p, unsigned procSmpCnt, unsigned delaySmpCnt );
  146. cmRC_t cmDelayFinal( cmDelay* p );
  147. cmRC_t cmDelayCopyIn( cmDelay* p, const cmSample_t* sp, unsigned sn );
  148. cmRC_t cmDelayAdvance( cmDelay* p, unsigned sn );
  149. cmRC_t cmDelayExec( cmDelay* p, const cmSample_t* sp, unsigned sn, bool bypassFl );
  150. void cmDelayTest();
  151. //------------------------------------------------------------------------------------------------------------
  152. //)
  153. //( { label:cmFIR file_desc:"Finite impulse response filter." kw:[proc]}
  154. typedef struct
  155. {
  156. cmObj obj;
  157. double* coeffV; // FIR coefficient vector (impulse response)
  158. unsigned coeffCnt; // count of elements in coeffV
  159. double* delayV; // delay vector contains one less elements than the coeff array
  160. cmSample_t* outV; // output signal
  161. unsigned outN; // length of the output signal (outN == ctx.procSmpCnt)
  162. unsigned delayIdx; // current next sample to receive input in the the delay line
  163. } cmFIR;
  164. enum { kHighPassFIRFl = 0x01 };
  165. // Note that the relative values of passHz and stopHz do not matter
  166. // for low-pass vs high-pass filters. In practice passHz and
  167. // stopHz can be swapped with no effect on the filter in either
  168. // case. Set p to NULL to dynamically allocate the object.
  169. cmFIR* cmFIRAllocKaiser(cmCtx* c, cmFIR* p, unsigned procSmpCnt, double srate, double passHz, double stopHz, double passDb, double stopDb, unsigned flags );
  170. // Set wndV[sincSmpCnt] to NULL to use a unity window otherwise set it to a window
  171. // function of length sincSmpCnt.
  172. cmFIR* cmFIRAllocSinc( cmCtx* c, cmFIR* p, unsigned procSmpCnt, double srate, unsigned sincSmpCnt, double fcHz, unsigned flags, const double* wndV );
  173. cmRC_t cmFIRFree( cmFIR** pp );
  174. cmRC_t cmFIRInitKaiser( cmFIR* p, unsigned procSmpCnt, double srate, double passHz, double stopHz, double passDb, double stopDb, unsigned flags );
  175. cmRC_t cmFIRInitSinc( cmFIR* p, unsigned procSmpCnt, double srate, unsigned sincSmpCnt, double fcHz, unsigned flags, const double* wndV );
  176. cmRC_t cmFIRFinal( cmFIR* p );
  177. cmRC_t cmFIRExec( cmFIR* p, const cmSample_t* sp, unsigned sn );
  178. void cmFIRTest0( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  179. void cmFIRTest1( cmCtx* ctx );
  180. //------------------------------------------------------------------------------------------------------------
  181. //)
  182. //( { label:cmFuncFilter file_desc:"Apply a generic function to a windowed signal with a one sample hop size.." kw:[proc]}
  183. typedef cmSample_t (*cmFuncFiltPtr_t)( const cmSample_t* sp, unsigned sn, void* userPtr );
  184. typedef struct
  185. {
  186. cmObj obj;
  187. cmFuncFiltPtr_t funcPtr;
  188. cmShiftBuf shiftBuf;
  189. cmSample_t* outV;
  190. unsigned outN; // outN == procSmpCnt
  191. unsigned curWndSmpCnt;
  192. unsigned wndSmpCnt;
  193. void* userPtr;
  194. } cmFuncFilter;
  195. /// Set p to NULL to dynamically allocate the object.
  196. cmFuncFilter* cmFuncFilterAlloc( cmCtx* c, cmFuncFilter* p, unsigned procSmpCnt, cmFuncFiltPtr_t funcPtr, void* userPtr, unsigned wndSmpCnt );
  197. cmRC_t cmFuncFilterFree( cmFuncFilter** pp );
  198. cmRC_t cmFuncFilterInit( cmFuncFilter* p, unsigned procSmpCnt, cmFuncFiltPtr_t funcPtr, void* userPtr, unsigned wndSmpCnt );
  199. cmRC_t cmFuncFilterFinal( cmFuncFilter* p );
  200. cmRC_t cmFuncFilterExec( cmFuncFilter* p, const cmSample_t* sp, unsigned sn );
  201. void cmFuncFilterTest();
  202. //------------------------------------------------------------------------------------------------------------
  203. //)
  204. //( { label:cmDhmm file_desc:"Discrete observation HMM" kw:[proc]}
  205. typedef struct
  206. {
  207. cmObj obj;
  208. unsigned stateN; // count of states
  209. unsigned symN; // count of discrete observation symbols
  210. cmReal_t* initV; // initial state probability vector init[ stateN ]
  211. cmReal_t* transM; // transition probability matrix trans[ stateN (current), stateN (next) ]
  212. cmReal_t* stsM; // state to symbol prob. matrix stsM[ stateN, symN ]
  213. } cmDhmm;
  214. cmDhmm* cmDhmmAlloc( cmCtx* c, cmDhmm* p, unsigned stateN, unsigned symN, cmReal_t* initV, cmReal_t* transM, cmReal_t* stsM );
  215. cmRC_t cmDhmmFree( cmDhmm** pp );
  216. cmRC_t cmDhmmInit( cmDhmm* p, unsigned stateN, unsigned symN, cmReal_t* initV, cmReal_t* transM, cmReal_t* stsM );
  217. cmRC_t cmDhmmFinal( cmDhmm* p );
  218. cmRC_t cmDhmmExec( cmDhmm* p );
  219. cmRC_t cmDhmmGenObsSequence( cmDhmm* p, unsigned* dbp, unsigned dn );
  220. cmRC_t cmDhmmForwardEval( cmDhmm* p, const cmReal_t* statePrV, const unsigned* obsV, unsigned obsN, cmReal_t* alphaM, unsigned flags, cmReal_t* logProbPtr );
  221. cmRC_t cmDhmmReport( cmDhmm* p );
  222. void cmDhmmTest();
  223. //------------------------------------------------------------------------------------------------------------
  224. //)
  225. //( { label:cmConvolve file_desc:"Convolve a signal with an impulse response." kw:[proc]}
  226. typedef struct
  227. {
  228. cmObj obj;
  229. cmFftSR* fft;
  230. cmIFftRS* ifft;
  231. cmComplexR_t* H;
  232. unsigned hn;
  233. cmSample_t* olaV; // olaV[hn-1];
  234. cmSample_t* outV; // outV[procSmpCnt]
  235. unsigned outN; // outN == procSmpCnt
  236. } cmConvolve;
  237. // After cmConvolveExec() outV[outN] contains the first outN samples
  238. // which are complete and can be used by the application.
  239. // The tail of the convolution is held in olaV[hn-1] and will
  240. // be automatically summed with the beginning of the next convolution
  241. // frame.
  242. // BUG BUG BUG
  243. // This code seems to have a problem when hn != procSmpCnt (or maybe hn > procSmpCnt ???).
  244. // See mas/main.c convolve() where procSmpCnt must be set to wndSmpCnt size or
  245. // only the first half of the window is emitted.
  246. // h[hn] is the impulse response to convolve with
  247. cmConvolve* cmConvolveAlloc( cmCtx* c, cmConvolve* p, const cmSample_t* h, unsigned hn, unsigned procSmpCnt );
  248. cmRC_t cmConvolveFree( cmConvolve** pp );
  249. cmRC_t cmConvolveInit( cmConvolve* p, const cmSample_t* h, unsigned hn, unsigned procSmpCnt );
  250. cmRC_t cmConvolveFinal( cmConvolve* p );
  251. // xn must be <= procSmpCnt
  252. cmRC_t cmConvolveExec( cmConvolve* p, const cmSample_t* x, unsigned xn );
  253. cmRC_t cmConvolveSignal( cmCtx* c, const cmSample_t* h, unsigned hn, const cmSample_t* x, unsigned xn, cmSample_t* y, unsigned yn );
  254. cmRC_t cmConvolveTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  255. //------------------------------------------------------------------------------------------------------------
  256. //)
  257. //( { label:cmBfcc file_desc:"Generate Bark Frequency Cepstral Coefficients from STFT frames." kw:[proc]}
  258. typedef struct
  259. {
  260. cmObj obj;
  261. cmReal_t* dctMtx; // dctMtx[ binCnt, bandCnt ]
  262. cmReal_t* filtMask; // filtMask[ bandCnt, bandCnt ]
  263. unsigned binCnt; // bin cnt of input magnitude spectrum
  264. unsigned bandCnt; // must be <= kDefaultBarkBandCnt
  265. cmReal_t* outV; // outV[binCnt]
  266. } cmBfcc;
  267. cmBfcc* cmBfccAlloc( cmCtx* ctx, cmBfcc* p, unsigned bandCnt, unsigned binCnt, double binHz );
  268. cmRC_t cmBfccFree( cmBfcc** pp );
  269. cmRC_t cmBfccInit( cmBfcc* p, unsigned bandCnt, unsigned binCnt, double binHz );
  270. cmRC_t cmBfccFinal( cmBfcc* p );
  271. cmRC_t cmBfccExec( cmBfcc* p, const cmReal_t* magV, unsigned binCnt );
  272. void cmBfccTest( cmRpt_t* rpt, cmLHeapH_t lhH, cmSymTblH_t stH );
  273. //------------------------------------------------------------------------------------------------------------
  274. //)
  275. //( { label:cmCepstrum file_desc:"Generate Cepstral Coefficients from STFT frames." kw:[proc]}
  276. typedef struct
  277. {
  278. cmObj obj;
  279. //cmIFftRR ft;
  280. unsigned dct_cn; // (binCnt-1)*2
  281. cmReal_t* dctM; // dctM[ outN, dct_cn ]
  282. unsigned binCnt; // bin cnt of input magnitude spectrum
  283. unsigned outN; // count of cepstral coeff's
  284. cmReal_t* outV; // outV[outN]
  285. } cmCeps;
  286. // outN is the number of cepstral coeff's in the output vector
  287. cmCeps* cmCepsAlloc( cmCtx* ctx, cmCeps* p, unsigned binCnt, unsigned outN );
  288. cmRC_t cmCepsFree( cmCeps** pp );
  289. cmRC_t cmCepsInit( cmCeps* p, unsigned binCnt, unsigned outN );
  290. cmRC_t cmCepsFinal( cmCeps* p );
  291. cmRC_t cmCepsExec( cmCeps* p, const cmReal_t* magV, const cmReal_t* phsV, unsigned binCnt );
  292. //------------------------------------------------------------------------------------------------------------
  293. //)
  294. //( { label:cmOla file_desc:"Generate a signal from an via overlap-add." kw:[proc]}
  295. //------------------------------------------------------------------------------------------------------------
  296. typedef struct
  297. {
  298. cmObj obj;
  299. cmWndFunc wf;
  300. unsigned wndSmpCnt;
  301. unsigned hopSmpCnt;
  302. unsigned procSmpCnt;
  303. cmSample_t* bufV; // bufV[wndSmpCnt] overlap add buffer
  304. cmSample_t* outV; // outV[hopSmpCnt] output vector
  305. cmSample_t* outPtr; // outPtr[procSmpCnt] output vector
  306. unsigned idx; // idx of next val in bufV[] to be moved to outV[]
  307. } cmOla;
  308. // hopSmpCnt must be <= wndSmpCnt.
  309. // hopSmpCnt must be an even multiple of procSmpCnt.
  310. // Call cmOlaExecR() or cmOlaExecS() at the spectral frame rate.
  311. // Call cmOlaExecOut() at the time domain audio frame rate.
  312. // Set wndTypeId to one of the cmWndFuncXXX enumerated widnow type id's.
  313. cmOla* cmOlaAlloc( cmCtx* ctx, cmOla* p, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned procSmpCnt, unsigned wndTypeId );
  314. cmRC_t cmOlaFree( cmOla** pp );
  315. cmRC_t cmOlaInit( cmOla* p, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned procSmpCnt, unsigned wndTypeId );
  316. cmRC_t cmOlaFinal( cmOla* p );
  317. cmRC_t cmOlaExecS( cmOla* p, const cmSample_t* xV, unsigned xN );
  318. cmRC_t cmOlaExecR( cmOla* p, const cmReal_t* xV, unsigned xN );
  319. const cmSample_t* cmOlaExecOut(cmOla* p );
  320. //------------------------------------------------------------------------------------------------------------
  321. //)
  322. //( { label:cmPhsToFrq file_desc:"Given STFT phase spectrum frames return the instantaneous frequency." kw:[proc]}
  323. //------------------------------------------------------------------------------------------------------------
  324. typedef struct
  325. {
  326. cmObj obj;
  327. cmReal_t* hzV; // hzV[binCnt] output vector - frequency in Hertz
  328. cmReal_t* phsV; // phsV[binCnt]
  329. cmReal_t* wV; // bin freq in rads/hop
  330. double srate;
  331. unsigned hopSmpCnt;
  332. unsigned binCnt;
  333. } cmPhsToFrq;
  334. cmPhsToFrq* cmPhsToFrqAlloc( cmCtx* c, cmPhsToFrq* p, double srate, unsigned binCnt, unsigned hopSmpCnt );
  335. cmRC_t cmPhsToFrqFree( cmPhsToFrq** p );
  336. cmRC_t cmPhsToFrqInit( cmPhsToFrq* p, double srate, unsigned binCnt, unsigned hopSmpCnt );
  337. cmRC_t cmPhsToFrqFinal(cmPhsToFrq* p );
  338. cmRC_t cmPhsToFrqExec( cmPhsToFrq* p, const cmReal_t* phsV );
  339. //------------------------------------------------------------------------------------------------------------
  340. //)
  341. //( { label:cmPvAnl file_desc:"Perform the phase-vocoder analysis stage." kw:[proc]}
  342. enum
  343. {
  344. kNoCalcHzPvaFl = 0x00,
  345. kCalcHzPvaFl = 0x01
  346. };
  347. typedef struct
  348. {
  349. cmObj obj;
  350. cmShiftBuf sb;
  351. cmFftSR ft;
  352. cmWndFunc wf;
  353. cmPhsToFrq pf;
  354. unsigned flags;
  355. unsigned procSmpCnt;
  356. double srate;
  357. unsigned wndSmpCnt;
  358. unsigned hopSmpCnt;
  359. unsigned binCnt;
  360. const cmReal_t* magV; // amplitude NOT power
  361. const cmReal_t* phsV;
  362. const cmReal_t* hzV;
  363. } cmPvAnl;
  364. cmPvAnl* cmPvAnlAlloc( cmCtx* ctx, cmPvAnl* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags );
  365. cmRC_t cmPvAnlFree( cmPvAnl** pp );
  366. cmRC_t cmPvAnlInit( cmPvAnl* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags );
  367. cmRC_t cmPvAnlFinal(cmPvAnl* p );
  368. // Returns true when a new spectrum has been computed
  369. bool cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN );
  370. //------------------------------------------------------------------------------------------------------------
  371. //)
  372. //( { label:cmPvSyn file_desc:"Perform the phase-vocoder synthesis stage." kw:[proc]}
  373. typedef struct
  374. {
  375. cmObj obj;
  376. cmIFftRS ft;
  377. cmWndFunc wf;
  378. cmOla ola;
  379. cmReal_t* minRphV;
  380. cmReal_t* maxRphV;
  381. cmReal_t* itrV;
  382. cmReal_t* phs0V;
  383. cmReal_t* mag0V;
  384. cmReal_t* phsV;
  385. cmReal_t* magV;
  386. double outSrate;
  387. unsigned procSmpCnt;
  388. unsigned wndSmpCnt;
  389. unsigned hopSmpCnt;
  390. unsigned binCnt;
  391. } cmPvSyn;
  392. cmPvSyn* cmPvSynAlloc( cmCtx* ctx, cmPvSyn* p, unsigned procSmpCnt, double outSrate, unsigned wndSmpCnt, unsigned hopSmpCnt,unsigned wndTypeId );
  393. cmRC_t cmPvSynFree( cmPvSyn** pp );
  394. cmRC_t cmPvSynInit( cmPvSyn* p, unsigned procSmpCnt, double outSrate, unsigned wndSmpCnt, unsigned hopSmpCnt,unsigned wndTypeId );
  395. cmRC_t cmPvSynFinal(cmPvSyn* p );
  396. cmRC_t cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV );
  397. const cmSample_t* cmPvSynExecOut(cmPvSyn* p );
  398. //------------------------------------------------------------------------------------------------------------
  399. //)
  400. //( { label:cmMidiSynth file_desc:"Synthesis independent MIDI synthesizer control structure." kw:[proc]}
  401. // callback selector values
  402. enum
  403. {
  404. kAttackMsId,
  405. kReleaseMsId,
  406. kDspMsId // return 0 if the voice is no longer active
  407. };
  408. // voice flags
  409. enum
  410. {
  411. kActiveMsFl = 0x01, // set if the voice is active
  412. kKeyGateMsFl = 0x02, // set if the key is down for this note
  413. };
  414. struct cmMidiSynth_str;
  415. struct cmMidiSynthCh_str;
  416. struct cmMidiVoice_str;
  417. // voice update callback - use voicePtr->pgm.cbDataPtr to get voice specific data
  418. typedef int (*cmMidiSynthCb_t)( struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* outChArray[], unsigned outChCnt );
  419. typedef struct
  420. {
  421. cmMidiByte_t pgm; // MIDI pgm number
  422. cmMidiSynthCb_t cbPtr; // voice update callback
  423. void* cbDataPtr; // user data pointer
  424. } cmMidiSynthPgm;
  425. typedef struct cmMidiVoice_str
  426. {
  427. unsigned index; // voice index
  428. unsigned flags; // see kXXXMsFl above
  429. cmMidiByte_t pitch; // note-on pitch
  430. cmMidiByte_t velocity; // note-on/off veloctiy
  431. cmMidiSynthPgm pgm; // pgm associated with this voice
  432. struct cmMidiSynthCh_str* chPtr; // pointer to owning ch
  433. struct cmMidiVoice_str* link; // link to next active/avail voice in chain
  434. } cmMidiVoice;
  435. typedef struct cmMidiSynthCh_str
  436. {
  437. cmMidiByte_t midiCtl[ kMidiCtlCnt ]; // current ctl values
  438. short pitchBend; // current pitch bend value
  439. cmMidiByte_t pgm; // last pgm received
  440. cmMidiVoice* active; // first active voice on this channel
  441. struct cmMidiSynth_str* synthPtr; // owning synth
  442. } cmMidiSynthCh;
  443. typedef struct cmMidiSynth_str
  444. {
  445. cmObj obj;
  446. cmMidiSynthCh chArray[ kMidiChCnt ]; // midi channel array
  447. unsigned voiceCnt; // count of voice records
  448. cmMidiVoice* avail; // avail voice chain
  449. unsigned activeVoiceCnt; // current count of active voices
  450. unsigned voiceStealCnt; // count of times voice stealing was required
  451. cmMidiVoice* voiceArray; // array of voice records
  452. cmMidiSynthPgm pgmArray[ kMidiPgmCnt ]; // array of pgm records
  453. unsigned procSmpCnt; // samples per DSP cycle
  454. unsigned outChCnt; // count of output channels
  455. cmSample_t* outM; // outM[ procSmpCnt, outChCnt ] output buffer
  456. cmSample_t** outChArray; // buffer of pointers to each output channel
  457. cmReal_t srate; // output signal sample rate
  458. } cmMidiSynth;
  459. cmMidiSynth* cmMidiSynthAlloc( cmCtx* ctx, cmMidiSynth* p, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate );
  460. cmRC_t cmMidiSynthFree( cmMidiSynth** pp );
  461. cmRC_t cmMidiSynthInit( cmMidiSynth* p, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate );
  462. cmRC_t cmMidiSynthFinal( cmMidiSynth* p );
  463. cmRC_t cmMidiSynthOnMidi(cmMidiSynth* p, const cmMidiPacket_t* pktArray, unsigned pktCnt );
  464. cmRC_t cmMidiSynthExec( cmMidiSynth* p, cmSample_t** outChArray, unsigned outChCnt );
  465. //------------------------------------------------------------------------------------------------------------
  466. //)
  467. //( { label:cmWtVoice file_desc:"Wavetable oscillator implementation for use with cmMidiSyn." kw:[proc]}
  468. // state id's
  469. enum
  470. {
  471. kOffWtId,
  472. kAtkWtId,
  473. kDcyWtId,
  474. kSusWtId,
  475. kRlsWtId
  476. };
  477. typedef struct
  478. {
  479. cmObj obj;
  480. cmReal_t hz; // current frq in Hz
  481. cmReal_t level; // current gain (0.0 to 1.0)
  482. cmReal_t phase; // osc phase (radians)
  483. unsigned durSmpCnt; // count of samples generated so far
  484. unsigned state; // osc state - see kXXXWtId above
  485. cmSample_t* outV; // signal output vector
  486. unsigned outN; // samples in outV[]
  487. } cmWtVoice;
  488. cmWtVoice* cmWtVoiceAlloc( cmCtx* ctx, cmWtVoice* p, unsigned procSmpCnt, cmReal_t hz );
  489. cmRC_t cmWtVoiceFree( cmWtVoice** pp );
  490. cmRC_t cmWtVoiceInit( cmWtVoice* p, unsigned procSmpCnt, cmReal_t hz );
  491. cmRC_t cmWtVoiceFinal( cmWtVoice* p );
  492. // 'sel' values are cmMidiSynthExec (kXXXMsId) values
  493. // Set outChArray[] to NULL to use internal audio buffer.
  494. int cmWtVoiceExec( cmWtVoice* p, struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* outChArray[], unsigned outChCnt );
  495. //------------------------------------------------------------------------------------------------------------
  496. //)
  497. //( { label:cmWtVoiceBank file_desc:"A bank of cmWtVoice oscillator for use with cmMidiSynth." kw:[proc]}
  498. typedef struct
  499. {
  500. cmObj obj;
  501. cmWtVoice** voiceArray; // osc state array
  502. unsigned voiceCnt;
  503. cmSample_t* buf;
  504. cmSample_t** chArray;
  505. unsigned chCnt;
  506. unsigned procSmpCnt; // count of samples in each chArray[i] sample vector
  507. double srate; // synth sample rate
  508. } cmWtVoiceBank;
  509. cmWtVoiceBank* cmWtVoiceBankAlloc( cmCtx* ctx, cmWtVoiceBank* p, double srate, unsigned procSmpCnt, unsigned voiceCnt, unsigned chCnt );
  510. cmRC_t cmWtVoiceBankFree( cmWtVoiceBank** pp );
  511. cmRC_t cmWtVoiceBankInit( cmWtVoiceBank* p, double srate, unsigned procSmpCnt, unsigned voiceCnt, unsigned chCnt );
  512. cmRC_t cmWtVoiceBankFinal( cmWtVoiceBank* p );
  513. // 'sel' values are cmMidiSynthExec (kXXXMsId) values
  514. // Set outChArray[] to NULL to use internal audio buffer.
  515. // Return 0 if the voice has gone inactive otherwise return 1.
  516. int cmWtVoiceBankExec( cmWtVoiceBank* p, struct cmMidiVoice_str* voicePtr, unsigned sel, cmSample_t* chArray[], unsigned chCnt );
  517. //------------------------------------------------------------------------------------------------------------
  518. //)
  519. //( { label:cmAudioFileBuf file_desc:"Generate a signal by caching all or part of an audio file." kw:[proc]}
  520. typedef struct
  521. {
  522. cmObj obj;
  523. cmSample_t* bufV; // bufV[ bufN ]
  524. unsigned bufN;
  525. cmAudioFileInfo_t info;
  526. unsigned begSmpIdx;
  527. unsigned chIdx;
  528. char* fn;
  529. } cmAudioFileBuf;
  530. // set 'durSmpCnt' to cmInvalidCnt to include all samples to the end of the file
  531. cmAudioFileBuf* cmAudioFileBufAlloc( cmCtx* ctx, cmAudioFileBuf* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned durSmpCnt );
  532. cmRC_t cmAudioFileBufFree( cmAudioFileBuf** pp );
  533. cmRC_t cmAudioFileBufInit( cmAudioFileBuf* p, unsigned procSmpCnt, const char* fn, unsigned chIdx, unsigned begSmpIdx, unsigned durSmpCnt );
  534. cmRC_t cmAudioFileBufFinal(cmAudioFileBuf* p );
  535. // Returns the count of samples copied into outV or 0 if smpIdx >= p->bufN.
  536. // If less than outN samples are available then the remaining samples are set to 0.
  537. unsigned cmAudioFileBufExec( cmAudioFileBuf* p, unsigned smpIdx, cmSample_t* outV, unsigned outN, bool sumIntoOutFl );
  538. //------------------------------------------------------------------------------------------------------------
  539. //)
  540. //( { label:cmMDelay file_desc:"Multi-tap audio delay with feedback." kw:[proc]}
  541. // Multi-delay. Each of the taps of this delay operates as a independent delay with feedback.
  542. // Delay line specification.
  543. typedef struct
  544. {
  545. cmReal_t delayGain; // delay gain
  546. cmReal_t delayMs; // delay time in milliseconds
  547. cmReal_t delaySmpFrac; // delay time in samples (next fractional delay index = inIdx - delaySmpFrac)
  548. cmSample_t* delayBuf; // delayBuf[delayBufSmpCnt] delay line memory
  549. int delayBufSmpCnt; // delay buffer length in samples
  550. int inIdx; // next delay input index
  551. } cmMDelayHead;
  552. typedef struct
  553. {
  554. cmObj obj;
  555. unsigned delayCnt; // count of taps
  556. cmMDelayHead* delayArray; // tap specs
  557. cmSample_t* outV; // outV[outN] output buffer
  558. unsigned outN; // procSmpCnt
  559. cmReal_t fbCoeff; // feedback coeff.
  560. cmReal_t srate; // system sample rate
  561. } cmMDelay;
  562. cmMDelay* cmMDelayAlloc( cmCtx* ctx, cmMDelay* p, unsigned procSmpCnt, cmReal_t srate, cmReal_t fbCoeff, unsigned delayCnt, const cmReal_t* delayMsArray, const cmReal_t* delayGainArray );
  563. cmRC_t cmMDelayFree( cmMDelay** pp );
  564. cmRC_t cmMDelayInit( cmMDelay* p, unsigned procSmpCnt, cmReal_t srate, cmReal_t fbCoeff, unsigned delayCnt, const cmReal_t* delayMsArray, const cmReal_t* delayGainArray );
  565. cmRC_t cmMDelayFinal( cmMDelay* p );
  566. cmRC_t cmMDelayExec( cmMDelay* p, const cmSample_t* sigV, cmSample_t* outV, unsigned sigN, bool bypassFl );
  567. void cmMDelaySetTapMs( cmMDelay* p, unsigned tapIdx, cmReal_t ms );
  568. void cmMDelaySetTapGain(cmMDelay* p, unsigned tapIdx, cmReal_t gain );
  569. void cmMDelayReport( cmMDelay* p, cmRpt_t* rpt );
  570. //------------------------------------------------------------------------------------------------------------
  571. //)
  572. //( { label:cmAudioSegPlayer file_desc:"Buffer and playback an arbitrary number of audio signals." kw:[proc]}
  573. enum
  574. {
  575. kEnableAspFl = 0x01,
  576. kDelAspFl = 0x02
  577. };
  578. typedef struct cmAudioSeg_str
  579. {
  580. cmAudioFileBuf* bufPtr; // pointer to the audio file buffer this segment is contained in
  581. unsigned id; // id (unique amoung segments)
  582. unsigned smpIdx; // offset into audioBuf[] of first sample
  583. unsigned smpCnt; // total count of samples to play
  584. unsigned outChIdx; // output buffer channel
  585. unsigned outSmpIdx; // outSmpIdx + smpIdx == next sample to play
  586. unsigned flags; // see kXXXAspFl
  587. } cmAudioSeg;
  588. typedef struct
  589. {
  590. cmObj obj;
  591. unsigned segCnt;
  592. cmAudioSeg* segArray;
  593. unsigned procSmpCnt;
  594. cmSample_t** outChArray;
  595. unsigned outChCnt;
  596. cmSample_t* outM;
  597. } cmAudioSegPlayer;
  598. cmAudioSegPlayer* cmAudioSegPlayerAlloc( cmCtx* ctx, cmAudioSegPlayer* p, unsigned procSmpCnt, unsigned outChCnt );
  599. cmRC_t cmAudioSegPlayerFree( cmAudioSegPlayer** pp );
  600. cmRC_t cmAudioSegPlayerInit( cmAudioSegPlayer* p, unsigned procSmpCnt, unsigned outChCnt );
  601. cmRC_t cmAudioSegPlayerFinal( cmAudioSegPlayer* p );
  602. cmRC_t cmAudioSegPlayerInsert( cmAudioSegPlayer* p, unsigned id, cmAudioFileBuf* bufPtr, unsigned smpIdx, unsigned smpCnt, unsigned outChIdx );
  603. cmRC_t cmAudioSegPlayerEdit( cmAudioSegPlayer* p, unsigned id, cmAudioFileBuf* bufPtr, unsigned smpIdx, unsigned smpCnt, unsigned outChIdx );
  604. cmRC_t cmAudioSegPlayerRemove( cmAudioSegPlayer* p, unsigned id, bool delFl );
  605. cmRC_t cmAudioSegPlayerEnable( cmAudioSegPlayer* p, unsigned id, bool enableFl, unsigned outSmpIdx );
  606. cmRC_t cmAudioSegPlayerReset( cmAudioSegPlayer* p );
  607. cmRC_t cmAudioSegPlayerExec( cmAudioSegPlayer* p, cmSample_t** outChPtr, unsigned chCnt, unsigned outSmpCnt );
  608. //------------------------------------------------------------------------------------------------------------
  609. //)
  610. /*
  611. cmReal_t (*cmCluster0DistFunc_t)( void* userPtr, const cmReal_t* v0, const cmReal_t* v1, unsigned binCnt );
  612. typedef struct
  613. {
  614. cmObj obj;
  615. unsigned flags;
  616. unsigned stateCnt;
  617. unsigned binCnt;
  618. cmReal_t* oM; // oM[ binCnt, stateCnt ]
  619. unsigned* tM; // tM[ stateCnt, stateCnt ]
  620. cmReal_t* dV; // dV[ state
  621. cmCluster0DistFunc_t distFunc;
  622. void* distUserPtr;
  623. unsigned cnt;
  624. } cmCluster0;
  625. enum
  626. {
  627. kCalcTransFl = 0x01,
  628. kCalcDurFl = 0x02
  629. };
  630. cmCluster0* cmCluster0Alloc( cmCtx* ctx, cmCluster0* ap, unsigned stateCnt, unsigned binCnt, unsigned flags, cmCluster0DistFunc_t distFunc, void* dstUserPtr );
  631. cmRC_t cmCluster0Free( cmCluster0** pp );
  632. cmRC_t cmCluster0Init( cmCluster0* p, unsigned stateCnt, unsigned binCnt, unsigned flags, cmCluster0DistFunc_t distFunc, void* dstUserPtr );
  633. cmRC_t cmCluster0Final( cmCluster0* p );
  634. cmRC_t cmCluster0Exec( cmCluster0* p, const cmReal_t* v, unsigned vn );
  635. */
  636. //( { label:cmNmf file_desc:"Non-negative matrix factorization implementation." kw:[proc]}
  637. typedef struct
  638. {
  639. cmObj obj;
  640. unsigned n;
  641. unsigned m;
  642. unsigned r;
  643. unsigned maxIterCnt;
  644. unsigned convergeCnt;
  645. cmReal_t* V; // V[n,m]
  646. cmReal_t* W; // W[n,r]
  647. cmReal_t* H; // H[r,m]
  648. cmReal_t* tr;
  649. cmReal_t* x;
  650. cmReal_t* t0nm;
  651. cmReal_t* t1nm;
  652. cmReal_t* Wt;
  653. cmReal_t* Ht;
  654. cmReal_t* trm;
  655. unsigned* crm;
  656. cmReal_t* tnr;
  657. unsigned* c0;
  658. unsigned* c1;
  659. unsigned* c0m;
  660. unsigned* c1m;
  661. unsigned* idxV;
  662. } cmNmf_t;
  663. cmNmf_t* cmNmfAlloc( cmCtx* ctx, cmNmf_t* ap, unsigned n, unsigned m, unsigned r, unsigned maxIterCnt, unsigned convergeCnt );
  664. cmRC_t cmNmfFree( cmNmf_t** pp );
  665. cmRC_t cmNmfInit( cmNmf_t* p, unsigned n, unsigned m, unsigned r, unsigned maxIterCnt, unsigned convergeCnt );
  666. cmRC_t cmNmfFinal(cmNmf_t* p );
  667. //
  668. cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* v, unsigned cn );
  669. //------------------------------------------------------------------------------------------------------------
  670. //)
  671. //( { label:cmVectArray file_desc:"Store and recall arrays of arbitrary length numeric vectors." kw:[proc]}
  672. // cmVectArray buffers row vectors of arbitrary length in memory.
  673. // The buffers may then be access using the cmVectArrayGetXXX() functions.
  674. // The entire contents of the file may be written to a file using atVectArrayWrite().
  675. // The file may then be read in back into memory using cmVectArrayAllocFromFile()
  676. // or in octave via readVectArray.m.
  677. // A rectantular matrix in memory may be written to a VectArray file in one operation
  678. // via the function cmVectArrayWriteMatrixXXX().
  679. typedef struct cmVectArrayVect_str
  680. {
  681. unsigned n; // length of this vector in values (not bytes)
  682. union
  683. {
  684. char* v; // raw memory vector pointer
  685. double* dV; // dV[n] vector of doubles
  686. float* fV; // fV[n] vecotr of floats
  687. cmSample_t* sV; // sV[n] vector of cmSample_t
  688. int* iV;
  689. unsigned* uV;
  690. } u;
  691. struct cmVectArrayVect_str* link; // link to next element record
  692. } cmVectArrayVect_t;
  693. enum
  694. {
  695. kDoubleVaFl = 0x01,
  696. kRealVaFl = 0x01,
  697. kFloatVaFl = 0x02,
  698. kSampleVaFl = 0x02,
  699. kIntVaFl = 0x04,
  700. kUIntVaFl = 0x08,
  701. kVaMask = 0x0f
  702. };
  703. typedef struct
  704. {
  705. cmObj obj;
  706. cmVectArrayVect_t* bp; // first list element
  707. cmVectArrayVect_t* ep; // last list element
  708. unsigned vectCnt; // count of elements in linked list
  709. unsigned flags; // data vector type (See: kFloatVaFl, kDoubleVaFl, ... )
  710. unsigned typeByteCnt; // size of a single data vector value (e.g. 4=float 8=double)
  711. unsigned maxEleCnt; // length of the longest data vector
  712. double* tempV;
  713. cmVectArrayVect_t* cur;
  714. } cmVectArray_t;
  715. // Flags must be set to one of the kXXXVAFl flag values.
  716. cmVectArray_t* cmVectArrayAlloc( cmCtx* ctx, unsigned flags );
  717. cmVectArray_t* cmVectArrayAllocFromFile(cmCtx* ctx, const char* fn );
  718. cmRC_t cmVectArrayFree( cmVectArray_t** pp );
  719. // Release all the stored vectors but do not release the object.
  720. cmRC_t cmVectArrayClear( cmVectArray_t* p );
  721. // Return the count of vectors contained in the vector array.
  722. cmRC_t cmVectArrayCount( const cmVectArray_t* p );
  723. // Return the maximum element count among all rows.
  724. unsigned cmVectArrayMaxRowCount( const cmVectArray_t* p );
  725. // Store a new vector by appending it to the end of the internal vector list.
  726. // Note:
  727. // 1. The true type of v[] in the call to cmVectArrayAppendV() must match
  728. // the data type set in p->flags.
  729. // 2. The 'vn' argument to atVectArrayAppendV() is an element count not
  730. // a byte count. The size of each element is determined by the data type
  731. // as set by atVectArrayAlloc().
  732. cmRC_t cmVectArrayAppendV( cmVectArray_t* p, const void* v, unsigned vn );
  733. cmRC_t cmVectArrayAppendS( cmVectArray_t* p, const cmSample_t* v, unsigned vn );
  734. cmRC_t cmVectArrayAppendR( cmVectArray_t* p, const cmReal_t* v, unsigned vn );
  735. cmRC_t cmVectArrayAppendF( cmVectArray_t* p, const float* v, unsigned vn );
  736. cmRC_t cmVectArrayAppendD( cmVectArray_t* p, const double* v, unsigned vn );
  737. cmRC_t cmVectArrayAppendI( cmVectArray_t* p, const int* v, unsigned vn );
  738. cmRC_t cmVectArrayAppendU( cmVectArray_t* p, const unsigned* v, unsigned vn );
  739. // Write a vector array in a format that can be read by readVectArray.m.
  740. cmRC_t cmVectArrayWrite( cmVectArray_t* p, const char* fn );
  741. cmRC_t cmVectArrayWriteDirFn(cmVectArray_t* p, const char* dir, const char* fn );
  742. // Print the vector array to rpt.
  743. cmRC_t cmVectArrayPrint( cmVectArray_t* p, cmRpt_t* rpt );
  744. typedef cmRC_t (*cmVectArrayForEachFuncS_t)( void* arg, unsigned idx, const cmSample_t* xV, unsigned xN );
  745. unsigned cmVectArrayForEachS( cmVectArray_t* p, unsigned idx, unsigned cnt, cmVectArrayForEachFuncS_t func, void* arg );
  746. // Write the vector v[vn] in the VectArray file format.
  747. // Note:
  748. // 1. The true type of v[] in cmVectArrayWriteVectoV() must match the
  749. // data type set in the 'flags' parameter.
  750. // 2. The 'vn' argument to atVectArrayWriteVectorV() is an element count not
  751. // a byte count. The size of each element is determined by the data type
  752. // as set by atVectArrayAlloc().
  753. cmRC_t cmVectArrayWriteVectorV( cmCtx* ctx, const char* fn, const void* v, unsigned vn, unsigned flags );
  754. cmRC_t cmVectArrayWriteVectorS( cmCtx* ctx, const char* fn, const cmSample_t* v, unsigned vn );
  755. cmRC_t cmVectArrayWriteVectorR( cmCtx* ctx, const char* fn, const cmReal_t* v, unsigned vn );
  756. cmRC_t cmVectArrayWriteVectorD( cmCtx* ctx, const char* fn, const double* v, unsigned vn );
  757. cmRC_t cmVectArrayWriteVectorF( cmCtx* ctx, const char* fn, const float* v, unsigned vn );
  758. cmRC_t cmVectArrayWriteVectorI( cmCtx* ctx, const char* fn, const int* v, unsigned vn );
  759. cmRC_t cmVectArrayWriteVectorU( cmCtx* ctx, const char* fn, const unsigned* v, unsigned vn );
  760. // Write the column-major matrix m[rn,cn] to the file 'fn'.
  761. // Notes:
  762. // 1. The true type of m[] in cmVectArrayWriteMatrixV() must match the
  763. // data type set in the 'flags' parameter.
  764. // 2. The 'rn','cn' arguments to atVectWriteMatrixV() is are element counts not
  765. // byte counts. The size of each element is determined by the data type
  766. // as set by atVectArrayAlloc().
  767. cmRC_t cmVectArrayWriteMatrixV( cmCtx* ctx, const char* fn, const void* m, unsigned rn, unsigned cn, unsigned flags );
  768. cmRC_t cmVectArrayWriteMatrixS( cmCtx* ctx, const char* fn, const cmSample_t* m, unsigned rn, unsigned cn );
  769. cmRC_t cmVectArrayWriteMatrixR( cmCtx* ctx, const char* fn, const cmReal_t* m, unsigned rn, unsigned cn );
  770. cmRC_t cmVectArrayWriteMatrixD( cmCtx* ctx, const char* fn, const double* m, unsigned rn, unsigned cn );
  771. cmRC_t cmVectArrayWriteMatrixF( cmCtx* ctx, const char* fn, const float* m, unsigned rn, unsigned cn );
  772. cmRC_t cmVectArrayWriteMatrixI( cmCtx* ctx, const char* fn, const int* m, unsigned rn, unsigned cn );
  773. cmRC_t cmVectArrayWriteMatrixU( cmCtx* ctx, const char* fn, const unsigned* m, unsigned rn, unsigned cn );
  774. // Read a VectArray file and return it as a matrix.
  775. // The returned memory must be released with a subsequent call to cmMemFree().
  776. // Note that the true type of the pointer address 'mRef' in the call to
  777. // cmVectArrayReadMatrixV() must match the data type of the cmVectArray_t
  778. // specified by 'fn'.
  779. cmRC_t cmVectArrayReadMatrixV( cmCtx* ctx, const char* fn, void** mRef, unsigned* rnRef, unsigned* cnRef );
  780. cmRC_t cmVectArrayReadMatrixS( cmCtx* ctx, const char* fn, cmSample_t** mRef, unsigned* rnRef, unsigned* cnRef );
  781. cmRC_t cmVectArrayReadMatrixR( cmCtx* ctx, const char* fn, cmReal_t** mRef, unsigned* rnRef, unsigned* cnRef );
  782. cmRC_t cmVectArrayReadMatrixD( cmCtx* ctx, const char* fn, double** mRef, unsigned* rnRef, unsigned* cnRef );
  783. cmRC_t cmVectArrayReadMatrixF( cmCtx* ctx, const char* fn, float** mRef, unsigned* rnRef, unsigned* cnRef );
  784. cmRC_t cmVectArrayReadMatrixI( cmCtx* ctx, const char* fn, int** mRef, unsigned* rnRef, unsigned* cnRef );
  785. cmRC_t cmVectArrayReadMatrixU( cmCtx* ctx, const char* fn, unsigned** mRef, unsigned* rnRef, unsigned* cnRef );
  786. // Row iteration control functions.
  787. cmRC_t cmVectArrayRewind( cmVectArray_t* p );
  788. cmRC_t cmVectArrayAdvance( cmVectArray_t* p, unsigned n );
  789. bool cmVectArrayIsEOL( const cmVectArray_t* p );
  790. unsigned cmVectArrayEleCount( const cmVectArray_t* p );
  791. // Copy the current row vector to v[].
  792. // Note that the true type of v[] in cmVectArrayGetV() must match the data type of 'p'.
  793. cmRC_t cmVectArrayGetV( cmVectArray_t* p, void* v, unsigned* vnRef );
  794. cmRC_t cmVectArrayGetS( cmVectArray_t* p, cmSample_t* v, unsigned* vnRef );
  795. cmRC_t cmVectArrayGetR( cmVectArray_t* p, cmReal_t* v, unsigned* vnRef );
  796. cmRC_t cmVectArrayGetD( cmVectArray_t* p, double* v, unsigned* vnRef );
  797. cmRC_t cmVectArrayGetF( cmVectArray_t* p, float* v, unsigned* vnRef );
  798. cmRC_t cmVectArrayGetI( cmVectArray_t* p, int* v, unsigned* vnRef );
  799. cmRC_t cmVectArrayGetU( cmVectArray_t* p, unsigned* v, unsigned* vnRef );
  800. // Set *resultFlRef to true if m[rn,cn] is equal to the cmVectArray_t specified by 'fn'.
  801. // Note that the true type of 'm[]' in the call to cmVectArrayMatrixIsEqualV()
  802. // must match the data type set in 'flags'.
  803. cmRC_t cmVectArrayMatrixIsEqualV( cmCtx* ctx, const char* fn, const void* m, unsigned rn, unsigned cn, bool* resultFlRef, unsigned flags );
  804. cmRC_t cmVectArrayMatrixIsEqualS( cmCtx* ctx, const char* fn, const cmSample_t* m, unsigned rn, unsigned cn, bool* resultFlRef );
  805. cmRC_t cmVectArrayMatrixIsEqualR( cmCtx* ctx, const char* fn, const cmReal_t* m, unsigned rn, unsigned cn, bool* resultFlRef );
  806. cmRC_t cmVectArrayMatrixIsEqualD( cmCtx* ctx, const char* fn, const double* m, unsigned rn, unsigned cn, bool* resultFlRef );
  807. cmRC_t cmVectArrayMatrixIsEqualF( cmCtx* ctx, const char* fn, const float* m, unsigned rn, unsigned cn, bool* resultFlRef );
  808. cmRC_t cmVectArrayMatrixIsEqualI( cmCtx* ctx, const char* fn, const int* m, unsigned rn, unsigned cn, bool* resultFlRef );
  809. cmRC_t cmVectArrayMatrixIsEqualU( cmCtx* ctx, const char* fn, const unsigned* m, unsigned rn, unsigned cn, bool* resultFlRef );
  810. // If a vector array is composed of repeating blocks of 'groupCnt' sub-vectors
  811. // where the concatenated ith sub-vectors in each group form a single super-vector then
  812. // this function will return the super-vector. Use cmMemFree(*vRef) to release
  813. // the returned super-vector.
  814. cmRC_t cmVectArrayFormVectR( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, cmReal_t** vRef, unsigned* vnRef );
  815. cmRC_t cmVectArrayFormVectF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, float** vRef, unsigned* vnRef );
  816. cmRC_t cmVectArrayFormVectColF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, float** vRef, unsigned* vnRef );
  817. cmRC_t cmVectArrayFormVectColU( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, unsigned** vRef, unsigned* vnRef );
  818. cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn, bool genFl );
  819. //------------------------------------------------------------------------------------------------------------
  820. //)
  821. //( { label:cmWhFilt file_desc:"Spectral whitening filter." kw:[proc]}
  822. // Spectral whitening filter.
  823. // Based on: Klapuri, A., 2006: Multiple fundamental frequency estimation by summing
  824. // harmonic amplitudes.
  825. typedef struct
  826. {
  827. cmObj obj;
  828. unsigned binCnt; //
  829. cmReal_t binHz; //
  830. unsigned bandCnt; //
  831. cmReal_t coeff; //
  832. cmReal_t* whiV; // whiV[bandCnt+2] - fractional bin index of each center frequency
  833. cmReal_t* whM; // whM[binCnt,bandCnt]
  834. cmReal_t* iV; // iV[ binCnt ] - working memory
  835. } cmWhFilt;
  836. cmWhFilt* cmWhFiltAlloc( cmCtx* c, cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz );
  837. cmRC_t cmWhFiltFree( cmWhFilt** pp );
  838. cmRC_t cmWhFiltInit( cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz );
  839. cmRC_t cmWhFiltFinal( cmWhFilt* p );
  840. cmRC_t cmWhFiltExec( cmWhFilt* p, const cmReal_t* xV, cmReal_t* yV, unsigned xyN );
  841. //-----------------------------------------------------------------------------------------------------------------------
  842. //)
  843. //( { label:cmFrqTrk file_desc:"Track sinusoids from STFT frame data." kw:[proc]}
  844. typedef enum
  845. {
  846. kNoStateFrqTrkId,
  847. kDlyFrqTrkId,
  848. kAtkFrqTrkId,
  849. kSusFrqTrkId,
  850. kDcyFrqTrkId
  851. } cmFrqTrkAttenStateId_t;
  852. typedef struct
  853. {
  854. double srate; // system sample rate
  855. unsigned chCnt; // tracking channel count
  856. unsigned binCnt; // count of spectrum elements passed in each call to cmFrqTrkExec()
  857. unsigned hopSmpCnt; // phase vocoder hop count in samples
  858. cmReal_t stRange; // maximum allowable semi-tones between a tracker and a peak
  859. cmReal_t wndSecs; // duration of the
  860. cmReal_t minTrkSec; // minimum track length before track is considered stable
  861. cmReal_t maxTrkDeadSec; // maximum length of time a tracker may fail to connect to a peak before being declared disconnected.
  862. cmReal_t pkThreshDb; // minimum amplitide in Decibels of a selected spectral peak.
  863. cmReal_t pkAtkThreshDb; // minimum amplitude in Decibels for the first frame of a new track.
  864. cmReal_t pkMaxHz; // maximum frequency to track
  865. cmReal_t whFiltCoeff;
  866. cmReal_t attenThresh;
  867. cmReal_t attenGain;
  868. cmReal_t attenDlySec;
  869. cmReal_t attenAtkSec;
  870. const char* logFn; // log file name or NULL if no file is to be written
  871. const char* levelFn; // level file name or NULL if no file is to be written
  872. const char* specFn; // spectrum file name or NULL if no file is to be written
  873. const char* attenFn;
  874. } cmFrqTrkArgs_t;
  875. typedef struct
  876. {
  877. bool activeFl;
  878. unsigned id;
  879. unsigned tN; // age of this track in frames
  880. unsigned dN; // count of consecutive times this ch has not connected
  881. cmReal_t hz; // current center frequency
  882. cmReal_t db; // current magnitude
  883. cmReal_t* dbV; // dbV[]
  884. cmReal_t* hzV; // hzV[]
  885. unsigned si;
  886. unsigned sn;
  887. cmReal_t db_mean;
  888. cmReal_t db_std;
  889. cmReal_t hz_mean;
  890. cmReal_t hz_std;
  891. cmReal_t score;
  892. cmFrqTrkAttenStateId_t state;
  893. int attenPhsIdx;
  894. cmReal_t attenGain;
  895. } cmFrqTrkCh_t;
  896. struct cmBinMtxFile_str;
  897. typedef struct cmFrqTrk_str
  898. {
  899. cmObj obj;
  900. cmFrqTrkArgs_t a;
  901. cmFrqTrkCh_t* ch; // ch[ a.chCnt ]
  902. unsigned hN; // count of magnitude buffer frames
  903. unsigned sN; // count of frames in channel statistics buffers
  904. unsigned bN; // count of bins in peak matrices
  905. cmReal_t* dbM; // dbM[ hN, bN ]
  906. unsigned hi; // next row of dbM to fill
  907. unsigned fN; // total count of frames processed.
  908. cmReal_t binHz;
  909. cmReal_t* dbV;
  910. unsigned* pkiV;
  911. unsigned deadN_max; // max. count of hops a tracker may fail to connect before being set to inactive
  912. unsigned minTrkN; // minimum track length in hops
  913. unsigned nextTrkId;
  914. unsigned newTrkCnt;
  915. unsigned curTrkCnt;
  916. unsigned deadTrkCnt;
  917. cmReal_t* aV;
  918. int attenDlyPhsMax;
  919. int attenPhsMax;
  920. cmWhFilt* wf;
  921. cmVectArray_t* logVa;
  922. cmVectArray_t* levelVa;
  923. cmVectArray_t* specVa;
  924. cmVectArray_t* attenVa;
  925. cmChar_t* logFn;
  926. cmChar_t* levelFn;
  927. cmChar_t* specFn;
  928. cmChar_t* attenFn;
  929. } cmFrqTrk;
  930. //
  931. // 1. Calculate the mean spectral magnitude profile over the last hN frames.
  932. // 2. Locate the peaks in the profile.
  933. // 3. Allow each active tracker to select the closest peak to extend its life.
  934. // a) The distance between the trackers current location and a given
  935. // peak is measured based on magnitude and frequency over time.
  936. // b) There is a frequency range limit outside of which a given track-peak
  937. // connection may not go.
  938. // c) There is an amplitude threshold below which a track may not fall.
  939. cmFrqTrk* cmFrqTrkAlloc( cmCtx* c, cmFrqTrk* p, const cmFrqTrkArgs_t* a );
  940. cmRC_t cmFrqTrkFree( cmFrqTrk** pp );
  941. cmRC_t cmFrqTrkInit( cmFrqTrk* p, const cmFrqTrkArgs_t* a );
  942. cmRC_t cmFrqTrkFinal( cmFrqTrk* p );
  943. cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV );
  944. void cmFrqTrkPrint( cmFrqTrk* p );
  945. //-----------------------------------------------------------------------------------------------------------------------
  946. //)
  947. //( { label:cmFbCtl file_desc:"Perform acoustic feedback control by attenuating loud sinusoid signals." kw:[proc]}
  948. typedef struct
  949. {
  950. double srate;
  951. unsigned binCnt;
  952. unsigned hopSmpCnt;
  953. unsigned bufMs;
  954. cmReal_t maxHz;
  955. } cmFbCtlArgs_t;
  956. typedef struct
  957. {
  958. cmObj obj;
  959. cmFbCtlArgs_t a;
  960. unsigned binCnt;
  961. unsigned frmCnt;
  962. cmReal_t* bM; // bM[ frmCnt, binCnt ];
  963. unsigned bfi; // current buffer frame (column) index
  964. unsigned bfN; // currrent count of frames in the buffer
  965. cmReal_t* rmsV; // rmsV[ frmCnt ];
  966. cmReal_t* sV; // sV[ binCnt ]
  967. cmReal_t* uV;
  968. cmVectArray_t* sva;
  969. cmVectArray_t* uva;
  970. } cmFbCtl_t;
  971. cmFbCtl_t* cmFbCtlAlloc( cmCtx* c, cmFbCtl_t* p, const cmFbCtlArgs_t* a );
  972. cmRC_t cmFbCtlFree( cmFbCtl_t** pp );
  973. cmRC_t cmFbCtlInit( cmFbCtl_t* p, const cmFbCtlArgs_t* a );
  974. cmRC_t cmFbCtlFinal(cmFbCtl_t* p );
  975. cmRC_t cmFbCtlExec( cmFbCtl_t* p, const cmReal_t* xV );
  976. //------------------------------------------------------------------------------------------------------------
  977. //)
  978. //( { label:cmExpander file_desc:"Expander implementation for audio dynamics processing." kw:[proc]}
  979. typedef struct
  980. {
  981. cmObj obj;
  982. cmReal_t* rmsV; // rmsV[rmsN]
  983. unsigned rmsN; //
  984. unsigned rmsIdx;//
  985. cmReal_t rmsValue; // last RMS value
  986. cmSample_t* envV; // envV[envN]
  987. unsigned envN; // atkSmp + rlsSmp;
  988. unsigned threshN;
  989. unsigned threshIdx;
  990. float threshLvl;
  991. float rlsLvl;
  992. unsigned envIdx;
  993. double gain;
  994. unsigned atkCnt;
  995. } cmExpander;
  996. cmExpander* cmExpanderAlloc( cmCtx* c, cmExpander* p, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs );
  997. cmRC_t cmExpanderFree( cmExpander** pp );
  998. cmRC_t cmExpanderInit( cmExpander* p, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs );
  999. cmRC_t cmExpanderFinal( cmExpander* p );
  1000. cmRC_t cmExpanderExec( cmExpander* p, cmSample_t* x, cmSample_t* y, unsigned xyN );
  1001. cmRC_t cmExpanderExecD( cmExpander* p, double* x, double* y, unsigned xyN );
  1002. //-----------------------------------------------------------------------------------------------------------------------
  1003. //)
  1004. //( { label:cmExpanderBank file_desc:"Bank of audio dynamics expanders based on cmExpander." kw:[proc]}
  1005. typedef struct
  1006. {
  1007. cmObj obj;
  1008. cmExpander** b; // b[bandN]
  1009. unsigned bandN;
  1010. double rmsValue;
  1011. unsigned atkCnt;
  1012. } cmExpanderBank;
  1013. cmExpanderBank* cmExpanderBankAlloc( cmCtx* c, cmExpanderBank* p, unsigned bandN, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs );
  1014. cmRC_t cmExpanderBankFree( cmExpanderBank** pp );
  1015. cmRC_t cmExpanderBankInit( cmExpanderBank* p, unsigned bandN, double srate, unsigned procSmpCnt, double threshDb, double rlsDb, double threshMs, double rmsMs, double atkMs, double rlsMs );
  1016. cmRC_t cmExpanderBankFinal( cmExpanderBank* p );
  1017. cmRC_t cmExpanderBankExec( cmExpanderBank* p, cmSample_t* x, unsigned bandN );
  1018. cmRC_t cmExpanderBankExecD( cmExpanderBank* p, double* x, unsigned bandN );
  1019. //-----------------------------------------------------------------------------------------------------------------------
  1020. //)
  1021. //( { label:cmSpecDist file_desc:"Spectral distortion algorithm based on non-linear transform." kw:[proc]}
  1022. enum
  1023. {
  1024. kBypassModeSdId, // 0 - no effect
  1025. kBasicModeSdId, // 1 - fixed thresh
  1026. kSpecCentSdId, // 2 - thresh = max magn - (offset * spec_cent)
  1027. kAmpEnvSdId, // 3 - thresh = max magn - offset
  1028. kBumpSdId,
  1029. kModeSdCnt
  1030. };
  1031. typedef struct
  1032. {
  1033. cmObj obj;
  1034. double srate;
  1035. unsigned wndSmpCnt;
  1036. unsigned hopFcmt;
  1037. unsigned hopSmpCnt;
  1038. unsigned procSmpCnt;
  1039. cmPvAnl* pva;
  1040. cmPvSyn* pvs;
  1041. cmFrqTrk* ft;
  1042. cmFbCtl_t* fbc;
  1043. cmExpanderBank* exb;
  1044. unsigned mode;
  1045. double thresh;
  1046. double uprSlope;
  1047. double lwrSlope;
  1048. double offset;
  1049. bool invertFl;
  1050. double spcBwHz; // spectral centroid bandwidth in Hz
  1051. double spcSmArg; // spectral centroid smoothing
  1052. double spcMin;
  1053. double spcMax;
  1054. unsigned spcBinCnt; // count of bins used in the spectral centroid
  1055. cmReal_t* hzV; // hzV[spcBinCnt];
  1056. cmReal_t spc;
  1057. unsigned spcCnt;
  1058. cmReal_t spcSum;
  1059. cmReal_t spcSqSum;
  1060. cmReal_t aeSmMax; // smoothed max bin magn - used by spectral centroid
  1061. cmReal_t aeSmOffs; // smoothed offset
  1062. cmReal_t ae;
  1063. cmReal_t aeMin;
  1064. cmReal_t aeMax;
  1065. cmReal_t aeUnit;
  1066. cmReal_t ogain;
  1067. cmReal_t ogain0;
  1068. unsigned phaseModIndex;
  1069. unsigned fi; // total count of frames processed by cmSpecDistExec()
  1070. unsigned hN;
  1071. unsigned hi;
  1072. cmReal_t* iSpecM; // iSpecMtx[hN binN]
  1073. cmReal_t* iSpecV; // mean of rows of iSpecM
  1074. cmVectArray_t* iSpecVa;
  1075. cmReal_t* oSpecM; // oSpecMtx[hN binN]
  1076. cmReal_t* oSpecV; // mean of rows of oSpecM
  1077. cmVectArray_t* oSpecVa;
  1078. cmVectArray_t* statVa;
  1079. } cmSpecDist_t;
  1080. cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
  1081. cmRC_t cmSpecDistFree( cmSpecDist_t** pp );
  1082. cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
  1083. cmRC_t cmSpecDistFinal(cmSpecDist_t* p );
  1084. cmRC_t cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn );
  1085. const cmSample_t* cmSpecDistOut( cmSpecDist_t* p );
  1086. //------------------------------------------------------------------------------------------------------------
  1087. //)
  1088. //( { label:cmSpecDist file_desc:"Spectral distortion 2 algorithm based on non-linear transform." kw:[proc]}
  1089. typedef struct
  1090. {
  1091. cmObj obj;
  1092. double srate;
  1093. unsigned wndSmpCnt;
  1094. unsigned hopFcmt;
  1095. unsigned hopSmpCnt;
  1096. unsigned procSmpCnt;
  1097. double igain;
  1098. cmSample_t* igainV;
  1099. cmPvAnl* pva;
  1100. cmPvSyn* pvs;
  1101. double ceiling;
  1102. double expo;
  1103. double mix;
  1104. double thresh;
  1105. double uprSlope;
  1106. double lwrSlope;
  1107. cmReal_t ogain;
  1108. unsigned fi; // total count of frames processed by cmSpecDistExec()
  1109. } cmSpecDist2_t;
  1110. cmSpecDist2_t* cmSpecDist2Alloc( cmCtx* ctx,cmSpecDist2_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
  1111. cmRC_t cmSpecDist2Free( cmSpecDist2_t** pp );
  1112. cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
  1113. cmRC_t cmSpecDist2Final(cmSpecDist2_t* p );
  1114. cmRC_t cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn );
  1115. const cmSample_t* cmSpecDist2Out( cmSpecDist2_t* p );
  1116. void cmSpecDist2Report( cmSpecDist2_t* p );
  1117. //------------------------------------------------------------------------------------------------------------
  1118. //)
  1119. //( { label:cmBinMtxFile file_desc:"Write a binary matrix which can be read by readBinFile.m." kw:[proc]}
  1120. // Write a binary matrix file in the format acceppted by the octave function readBinFile.m
  1121. typedef struct cmBinMtxFile_str
  1122. {
  1123. cmObj obj;
  1124. cmFileH_t fh;
  1125. unsigned rowCnt;
  1126. unsigned maxRowEleCnt;
  1127. unsigned eleByteCnt;
  1128. } cmBinMtxFile_t;
  1129. cmBinMtxFile_t* cmBinMtxFileAlloc( cmCtx* ctx, cmBinMtxFile_t* ap, const cmChar_t* fn );
  1130. cmRC_t cmBinMtxFileFree( cmBinMtxFile_t** pp );
  1131. cmRC_t cmBinMtxFileInit( cmBinMtxFile_t* p, const cmChar_t* fn );
  1132. cmRC_t cmBinMtxFileFinal( cmBinMtxFile_t* p );
  1133. // Write one row of 'xn' columns to the matrix file.
  1134. cmRC_t cmBinMtxFileExecS( cmBinMtxFile_t* p, const cmSample_t* x, unsigned xn );
  1135. cmRC_t cmBinMtxFileExecR( cmBinMtxFile_t* p, const cmReal_t* x, unsigned xn );
  1136. bool cmBinMtxFileIsValid( cmBinMtxFile_t* p );
  1137. // Write a binary matrix file.
  1138. // The matrix data is provided as sp[rowCnt,colCnt] or rp[rowCnt,colCnt].
  1139. // The matrix is assumed to be in column major order (like all matrices in the cm library)
  1140. // Either 'sp' or 'rp' must be given but not both.
  1141. // 'ctx' is optional and defaults to NULL.
  1142. // If 'ctx' is not provided then 'rpt' must be provided.
  1143. // If 'ctx' is provided then 'rpt' is not used.
  1144. // See cmAudioFileReadWriteTest() in cmProcTest.c for an example usage.
  1145. cmRC_t cmBinMtxFileWrite( const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, const cmSample_t* sp, const cmReal_t* rp, cmCtx* ctx, cmRpt_t* rpt );
  1146. // Return the matrix file geometry.
  1147. // rowCntPtr,colCntPtr and eleByteCntPtr are optional
  1148. cmRC_t cmBinMtxFileSize( cmCtx_t* ctx, const cmChar_t* fn, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleByteCntPtr );
  1149. // Fill buf[rowCnt*colCnt*byteEleCnt] buffer from the binary matrix file 'fn'.
  1150. // rowCnt,colCnt,eleByteCnt must be exactly the same as the actual file.
  1151. // Use cmBinMtxFileSize() to determine the buffer size prior to calling this function.
  1152. // colCntV[colCnt] is optional.
  1153. cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, unsigned eleByteCnt, void* buf, unsigned* colCntV );
  1154. //)
  1155. #ifdef __cplusplus
  1156. }
  1157. #endif
  1158. #endif