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

cmProc3.h 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. #ifndef cmProc3_h
  2. #define cmProc3_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. //( { file_desc:"Processor Library 3" kw:[proclib]}
  7. //)
  8. //( { label:cmPitchShift file_desc:"Time-domain pitch shifter based on sample rate conversion." kw:[proc]}
  9. typedef struct
  10. {
  11. double wi;
  12. double xi;
  13. int yn;
  14. cmSample_t* y;
  15. int yii;
  16. int yoi;
  17. int ynn;
  18. } cmPitchShiftOsc_t;
  19. typedef struct
  20. {
  21. cmObj obj;
  22. unsigned procSmpCnt;
  23. double srate;
  24. int outN; // procSmpCnt
  25. int wn; //
  26. int xn; //
  27. int bn; //
  28. cmSample_t* b; // b[bn]
  29. cmSample_t* x; // x[xn]
  30. cmSample_t* wnd; // wnd[wn]
  31. cmSample_t* outV; // outV[outN];
  32. int xni; //
  33. bool cubeFl; //
  34. cmPitchShiftOsc_t osc[2]; //
  35. } cmPitchShift;
  36. cmPitchShift* cmPitchShiftAlloc( cmCtx* c, cmPitchShift* p, unsigned procSmpCnt, cmReal_t srate );
  37. cmRC_t cmPitchShiftFree( cmPitchShift** pp );
  38. cmRC_t cmPitchShiftInit( cmPitchShift* p, unsigned procSmpCnt, cmReal_t srate );
  39. cmRC_t cmPitchShiftFinal(cmPitchShift* p );
  40. cmRC_t cmPitchShiftExec( cmPitchShift* p, const cmSample_t* x, cmSample_t* y, unsigned n, double shiftRatio, bool bypassFl );
  41. //------------------------------------------------------------------------------------------------------------
  42. //)
  43. //( { label:cmLoopRecord file_desc:"Audio interactive loop recorder." kw:[proc]}
  44. typedef struct
  45. {
  46. double xi; // index into xV[]
  47. double wi; // index into wV[]
  48. cmSample_t u; // cross-fade window polarity
  49. } cmLoopRecdOsc;
  50. typedef struct
  51. {
  52. cmLoopRecdOsc osc[2]; //
  53. cmSample_t* xV; // xV[ xN ]
  54. int xN; // maxRecdSmpCnt
  55. int xfN; // cross-fade sample count
  56. int xii; // xV[] recording input index
  57. cmSample_t* wV; // wV[ xN ] window function (actually contains xii values after recording)
  58. } cmLoopRecdBuf;
  59. typedef struct
  60. {
  61. cmObj obj;
  62. cmSample_t* bufMem;
  63. unsigned maxRecdSmpCnt;
  64. cmLoopRecdBuf* bufArray;
  65. unsigned bufArrayCnt;
  66. cmSample_t* outV;
  67. unsigned outN;
  68. unsigned procSmpCnt;
  69. unsigned xfadeSmpCnt;
  70. unsigned recdBufIdx;
  71. unsigned playBufIdx;
  72. bool recdFl;
  73. bool playFl;
  74. } cmLoopRecord;
  75. cmLoopRecord* cmLoopRecordAlloc( cmCtx* c, cmLoopRecord* p, unsigned procSmpCnt, unsigned maxRecdSmpCnt, unsigned xfadeSmpCnt );
  76. cmRC_t cmLoopRecordFree( cmLoopRecord** pp );
  77. cmRC_t cmLoopRecordInit( cmLoopRecord* p, unsigned procSmpCnt, unsigned maxRecdSmpCnt, unsigned xfadeSmpCnt );
  78. cmRC_t cmLoopRecordFinal( cmLoopRecord* p );
  79. // rgain=recorder output gain, pgain=pass through gain
  80. cmRC_t cmLoopRecordExec( cmLoopRecord* p, const cmSample_t* x, cmSample_t* y, unsigned xn, bool bypassFl, bool recdFl, bool playFl, double ratio, double pgain, double rgain );
  81. //------------------------------------------------------------------------------------------------------------
  82. //)
  83. //( { label:cmGateDetector file_desc:"Detect when a signal onsets and offsets." kw:[proc]}
  84. typedef struct
  85. {
  86. cmObj obj;
  87. unsigned rmsN;
  88. cmSample_t* rmsV; // rmsV[rmsN] previous rmsN values. rmsV[rmsN-1] == rms
  89. cmSample_t rms; // RMS of last procSmpCnt samples
  90. unsigned wndN;
  91. cmSample_t* wndV;
  92. cmSample_t mean;
  93. cmSample_t d0;
  94. unsigned durSmpCnt; // duration of the current gate polarity in samples
  95. bool gateFl;
  96. bool deltaFl;
  97. cmReal_t onThreshPct;
  98. cmReal_t onThreshDb;
  99. cmReal_t offThreshDb; //
  100. } cmGateDetect;
  101. cmGateDetect* cmGateDetectAlloc( cmCtx* c, cmGateDetect* p, unsigned procSmpCnt, cmReal_t onThreshPct, cmReal_t onThreshDb, cmReal_t offThreshDb );
  102. cmRC_t cmGateDetectFree( cmGateDetect** p );
  103. cmRC_t cmGateDetectInit( cmGateDetect* p, unsigned procSmpCnt, cmReal_t onThreshPct, cmReal_t onThreshDb, cmReal_t offThreshDb );
  104. cmRC_t cmGateDetectFinal(cmGateDetect* p );
  105. cmRC_t cmGateDetectExec( cmGateDetect* p, const cmSample_t* x, unsigned xn );
  106. //------------------------------------------------------------------------------------------------------------
  107. //)
  108. //( { label:cmGateDetector2 file_desc:"Improved gate detector to detect when a signal onsets and offsets." kw:[proc]}
  109. typedef struct
  110. {
  111. unsigned medCnt; // length of the median filter
  112. unsigned avgCnt; // length of the (rms - med) moving avg. filter
  113. unsigned suprCnt; // length of the supression window
  114. unsigned offCnt; // length of the offset detection window
  115. cmReal_t suprCoeff; // supression signal shape coeff
  116. cmReal_t onThreshDb; // onset threshold
  117. cmReal_t offThreshDb; // offset threshold
  118. } cmGateDetectParams;
  119. typedef struct
  120. {
  121. cmObj obj;
  122. cmGateDetectParams args;
  123. cmSample_t* medV; // medV[medCnt]
  124. unsigned medIdx;
  125. cmSample_t* avgV; // avgV[avgCnt]
  126. unsigned avgIdx;
  127. cmSample_t* fcofV; // fcofV[medCnt]
  128. cmSample_t* fdlyV; // fdlyV[medCnt]
  129. cmSample_t* suprV; // suprV[suprCnt]
  130. unsigned suprIdx;
  131. cmSample_t* pkV; // pkV[3]
  132. cmSample_t* offV; // offV[offCnt]
  133. unsigned offIdx;
  134. unsigned pkFl; //
  135. bool gateFl; // set by onset, cleared by offset
  136. bool onFl; // set if an onset was detected
  137. bool offFl; // set if an offset was detected
  138. cmReal_t onThresh;
  139. cmReal_t offThresh;
  140. cmSample_t rms; // RMS
  141. cmSample_t med; // median RMS over last medCnt exec's
  142. cmSample_t dif; // max(0, RMS - median_RMS)
  143. cmSample_t avg; // avg dif's over last avgCnt exec's
  144. cmSample_t ons; // dif - avg
  145. cmSample_t flt; // filtered(ons)
  146. cmSample_t sup; // flt w/ suppression
  147. } cmGateDetect2;
  148. cmGateDetect2* cmGateDetectAlloc2( cmCtx* c, cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args );
  149. cmRC_t cmGateDetectFree2( cmGateDetect2** p );
  150. cmRC_t cmGateDetectInit2( cmGateDetect2* p, unsigned procSmpCnt, const cmGateDetectParams* args );
  151. cmRC_t cmGateDetectFinal2(cmGateDetect2* p );
  152. cmRC_t cmGateDetectExec2( cmGateDetect2* p, const cmSample_t* x, unsigned xn );
  153. void cmGateDetectSetOnThreshDb2( cmGateDetect2* p, cmReal_t db );
  154. void cmGateDetectSetOffThreshDb2( cmGateDetect2* p, cmReal_t db );
  155. //------------------------------------------------------------------------------------------------------------
  156. //)
  157. //( { label:cmAutoGain file_desc:"Automatically balance a set of audio signals by adjusting their level." kw:[proc fluxo]}
  158. //
  159. // Calculate a set of automatic gain adjustments for a set of audio channels.
  160. //
  161. // 1) Call cmAutoGainInit() to reset the object.
  162. // 2) Call cmAutoGainStartCh() and provide an id to identify the channel.
  163. // 3) Call cmAutoGainProcCh() with audio from the channel identified in 2)
  164. // 4) Repeat 2) and 3) for for all channels.
  165. // 5) Call cmAutoGainCalcGains() to set the value of cmAutoGainCh.gain.
  166. //
  167. // The gain coefficents are set to balance the overall gain.
  168. // (i.e. Loud channels are decreased and quiet channels are increased.)
  169. typedef struct
  170. {
  171. unsigned id; // channel id
  172. cmReal_t gain; // gain adjustment coefficient
  173. unsigned onCnt; // count of onsets detected
  174. unsigned offCnt; // count of offsets detected
  175. cmReal_t gateMaxAvg; // average of the max values for each detected event
  176. } cmAutoGainCh;
  177. typedef struct
  178. {
  179. cmObj obj;
  180. cmShiftBuf* sbp;
  181. cmGateDetect2* gdp;
  182. cmAutoGainCh* chArray; //
  183. unsigned chCnt;
  184. cmAutoGainCh* chp;
  185. unsigned gateCnt;
  186. cmReal_t gateSum;
  187. cmReal_t gateMax;
  188. cmReal_t minRms;
  189. } cmAutoGain;
  190. cmAutoGain* cmAutoGainAlloc( cmCtx* c, cmAutoGain* p, unsigned procSmpCnt, cmReal_t srate, cmReal_t hopMs, unsigned chCnt, const cmGateDetectParams* gd_args );
  191. cmRC_t cmAutoGainFree( cmAutoGain** p );
  192. cmRC_t cmAutoGainInit( cmAutoGain* p, unsigned procSmpCnt, cmReal_t srate, cmReal_t hopMs, unsigned chCnt, const cmGateDetectParams* gd_args );
  193. cmRC_t cmAutoGainFinal( cmAutoGain* p );
  194. // Notify the object that the following calls to cmAutoGainProcCh()
  195. // should be associed with the channel 'id'.
  196. cmRC_t cmAutoGainStartCh( cmAutoGain* p, unsigned id );
  197. // Examine the signal arriving from the channel specified in the previous
  198. // call to cmAutoGainProcCh() and determine the max RMS value for each
  199. // event contained in the signal.
  200. cmRC_t cmAutoGainProcCh( cmAutoGain* p, const cmSample_t* x, unsigned xn );
  201. // Calculate the cmAutoGainCh.gain coefficient for each channel.
  202. cmRC_t cmAutoGainCalcGains( cmAutoGain* p );
  203. void cmAutoGainPrint( cmAutoGain* p, cmRpt_t* rpt );
  204. //------------------------------------------------------------------------------------------------------------
  205. //)
  206. //( { label:cmChCfg file_desc:"Configure a 'fluxo' pickup channel." kw:[proc fluxo]}
  207. typedef struct
  208. {
  209. unsigned ch;
  210. unsigned ssi;
  211. const cmChar_t* pitchStr;
  212. unsigned midi;
  213. cmReal_t gain;
  214. bool nsFl; // noise shaper channel
  215. bool cdFl; // chord detector channel
  216. } cmChCfgCh;
  217. typedef struct
  218. {
  219. cmObj obj;
  220. cmChCfgCh* chArray;
  221. unsigned chCnt;
  222. unsigned nsChCnt; // count of noise-shaper channels
  223. const cmChar_t* fn;
  224. cmJsonH_t jsH;
  225. cmJsonNode_t* cap;
  226. } cmChCfg;
  227. cmChCfg* cmChCfgAlloc( cmCtx* c, cmChCfg* p, cmCtx_t* ctx, const cmChar_t* fn );
  228. cmRC_t cmChCfgFree( cmChCfg** pp );
  229. cmRC_t cmChCfgInit( cmChCfg* p, cmCtx_t* ctx, const cmChar_t* fn );
  230. cmRC_t cmChCfgFinal( cmChCfg* p );
  231. cmRC_t cmChCfgWrite( cmChCfg* p );
  232. void cmChCfgPrint( cmChCfg* p, cmRpt_t* rpt );
  233. unsigned cmChCfgChannelCount( cmCtx_t* ctx, const cmChar_t* fn, unsigned* nsChCntPtr );
  234. unsigned cmChCfgChannelIndex( cmCtx_t* ctx, const cmChar_t* fn, unsigned chIdx );
  235. //------------------------------------------------------------------------------------------------------------
  236. //)
  237. //( { label:cmChordDetector file_desc:"Chord detector based on evaluating signals from cmGateDetector2." kw:[proc]}
  238. typedef struct
  239. {
  240. bool readyFl; // This channel has received an offset since it was last a candidate.
  241. bool candFl; // This channel is a chord candidate
  242. unsigned candSmpTime; // Time that this channel became a candidate
  243. cmReal_t candRMS; // RMS when this channel became a candidate
  244. bool chordFl; // This channel is part of the current chord
  245. bool gateFl; // Previous gate state
  246. } cmChordDetectCh;
  247. typedef struct
  248. {
  249. cmObj obj;
  250. unsigned maxTimeSpanSmpCnt; // maximum time between onsets of first and last note of chord
  251. unsigned minNotesPerChord; // the min. number of notes required to form a chord
  252. unsigned chCnt; // count of channels
  253. cmChordDetectCh* chArray; // channel state array
  254. bool detectFl; // true when a new chord has been detected
  255. unsigned timeSmp; // current time
  256. cmReal_t srate;
  257. } cmChordDetect;
  258. cmChordDetect* cmChordDetectAlloc( cmCtx*c, cmChordDetect* p, cmReal_t srate, unsigned chCnt, cmReal_t maxTimeSpanMs, unsigned minNotesPerChord );
  259. cmRC_t cmChordDetectFree( cmChordDetect** pp );
  260. cmRC_t cmChordDetectInit( cmChordDetect* p, cmReal_t srate, unsigned chCnt, cmReal_t maxTimeSpanMs, unsigned minNotesPerChord );
  261. cmRC_t cmChordDetectFinal( cmChordDetect* p );
  262. cmRC_t cmChordDetectExec( cmChordDetect* p, unsigned procSmpCnt, const bool* gateV, const cmReal_t* rmsV, unsigned chCnt );
  263. cmRC_t cmChordDetectSetSpanMs( cmChordDetect* p, cmReal_t maxTimeSpanMs );
  264. //------------------------------------------------------------------------------------------------------------
  265. //)
  266. //( { label:cmXfader file_desc:"Audio cross fade controller." kw:[proc]}
  267. // This object is not really a cross-fader. It is really just a multichannel
  268. // fader - which just calculates the fade gain but does not actually apply it
  269. // to the audio signal - unless you use cmXfaderExecAudio()
  270. typedef struct
  271. {
  272. cmReal_t ep_gain; // equal power xfade gain
  273. cmReal_t gain; // linear gain
  274. bool gateFl; // true if channel is on
  275. bool onFl; // true if gateFl transitioned to true on this cycle
  276. bool offFl; // true if gateFl transitioned to false on this cycle
  277. } cmXfaderCh;
  278. typedef struct
  279. {
  280. cmObj obj;
  281. unsigned chCnt;
  282. cmXfaderCh* chArray;
  283. unsigned fadeSmpCnt;
  284. unsigned fadeInSmpCnt;
  285. unsigned fadeOutSmpCnt;
  286. cmReal_t srate;
  287. bool gateFl; // true if any channels are on
  288. bool onFl; // true on cycle where gate transitions to 'on'.
  289. bool offFl; // true on cycle where gate transitions to 'off'.
  290. } cmXfader;
  291. cmXfader* cmXfaderAlloc( cmCtx*c, cmXfader* p, cmReal_t srate, unsigned chCnt, cmReal_t fadeTimeMs );
  292. cmRC_t cmXfaderFree( cmXfader** pp );
  293. cmRC_t cmXfaderInit( cmXfader* p, cmReal_t srate, unsigned chCnt, cmReal_t fadeTimeMs );
  294. cmRC_t cmXfaderFinal( cmXfader* p );
  295. cmRC_t cmXfaderExec( cmXfader* p, unsigned procSmpCnt, const bool* gateV, unsigned chCnt );
  296. cmRC_t cmXfaderExecAudio( cmXfader* p, unsigned procSmpCnt, const bool* gateV, unsigned chCnt, const cmSample_t* x[], cmSample_t* y );
  297. void cmXfaderSetXfadeTime( cmXfader* p, cmReal_t fadeTimeMs );
  298. void cmXfaderSetXfadeInTime( cmXfader* p, cmReal_t fadeTimeMs );
  299. void cmXfaderSetXfadeOutTime( cmXfader* p, cmReal_t fadeTimeMs );
  300. // Set all gates to false except chIdx.
  301. void cmXfaderSelectOne( cmXfader* p, unsigned chIdx );
  302. void cmXfaderAllOff( cmXfader* p );
  303. void cmXfaderJumpToDestinationGain( cmXfader* p ); // jump to dest. gain based on gate state
  304. //------------------------------------------------------------------------------------------------------------
  305. //)
  306. //( { label:cmFader file_desc:"Fade in/out an audio signal based on the state of a gate control signal." kw:[proc]}
  307. // This fader object accepts a gate signal. When the gate is high it increments
  308. // the gain until it reaches 1.0. When the gate is low it decrements the gain
  309. // until it reaches 0.0. The fade time is the lenght of time the gain will take
  310. // to transition from 0.0 to 1.0 or 1.0 to 0.0.
  311. typedef struct
  312. {
  313. cmObj obj;
  314. unsigned fadeSmpCnt; // time to fade from 0->1 or 1->0
  315. cmReal_t srate;
  316. cmReal_t gain;
  317. } cmFader;
  318. cmFader* cmFaderAlloc( cmCtx*c, cmFader* p, cmReal_t srate, cmReal_t fadeTimeMs );
  319. cmRC_t cmFaderFree( cmFader** pp );
  320. cmRC_t cmFaderInit( cmFader* p, cmReal_t srate, cmReal_t fadeTimeMs );
  321. cmRC_t cmFaderFinal( cmFader* p );
  322. cmRC_t cmFaderExec( cmFader* p, unsigned procSmpCnt, bool gateFl, bool mixFl, const cmSample_t* x, cmSample_t* y );
  323. void cmFaderSetFadeTime( cmFader* p, cmReal_t fadeTimeMs );
  324. //------------------------------------------------------------------------------------------------------------
  325. //)
  326. //( { label:cmCombFilt file_desc:"Comb and Inverse Comb filter algorithm with a variable fractional delay." kw:[proc]}
  327. struct cmIDelay_str;
  328. typedef struct
  329. {
  330. cmObj obj;
  331. cmReal_t srate; // system sample rate
  332. bool feedbackFl; // set if this is a feedback comb filter
  333. cmReal_t minHz; // lowest comb frequency this comb filter can support
  334. cmReal_t hz; // location of first comb
  335. cmReal_t alpha; // filter coeff.
  336. cmReal_t dN; // max length of the the cf delay line
  337. unsigned dn; // current length of cf delay line
  338. cmReal_t* d; // d[dn] filter delay line
  339. cmReal_t* b; // b[dn] feedforward coeff's
  340. cmReal_t* a; // a[dn] feedback coeff's
  341. cmReal_t b0; // feedforward coeff 0
  342. bool bypassFl; // bypass enable flag
  343. struct cmIDelay_str* idp;
  344. } cmCombFilt;
  345. cmCombFilt* cmCombFiltAlloc( cmCtx* c, cmCombFilt* p, cmReal_t srate, bool feedbackFl, cmReal_t minHz, cmReal_t alpha, cmReal_t hz, bool bypassFl );
  346. cmRC_t cmCombFiltFree( cmCombFilt** pp);
  347. cmRC_t cmCombFiltInit( cmCombFilt* p, cmReal_t srate, bool feedbackFl, cmReal_t minHz, cmReal_t alpha, cmReal_t hz, bool bypassFl );
  348. cmRC_t cmCombFiltFinal( cmCombFilt* p );
  349. cmRC_t cmCombFiltExec( cmCombFilt* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  350. void cmCombFiltSetAlpha( cmCombFilt* p, cmReal_t alpha );
  351. cmRC_t cmCombFiltSetHz( cmCombFilt* p, cmReal_t hz );
  352. //------------------------------------------------------------------------------------------------------------
  353. //)
  354. //( { label:cmDcFilt file_desc:"DC Filter algorithm." kw:[proc]}
  355. typedef struct
  356. {
  357. cmObj obj;
  358. cmReal_t d[2]; //
  359. cmReal_t b[1]; //
  360. cmReal_t a[1]; // a[dn] feedback coeff's
  361. cmReal_t b0; // feedforward coeff 0
  362. bool bypassFl;
  363. } cmDcFilt;
  364. cmDcFilt* cmDcFiltAlloc( cmCtx* c, cmDcFilt* p, bool bypassFl );
  365. cmRC_t cmDcFiltFree( cmDcFilt** pp);
  366. cmRC_t cmDcFiltInit( cmDcFilt* p, bool bypassFl );
  367. cmRC_t cmDcFiltFinal( cmDcFilt* p );
  368. cmRC_t cmDcFiltExec( cmDcFilt* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  369. //------------------------------------------------------------------------------------------------------------
  370. //)
  371. //( { label:cmIDelay file_desc:"Variable interpolating fractional audio delay line." kw:[proc]}
  372. typedef struct cmIDelay_str
  373. {
  374. cmObj obj;
  375. cmSample_t* d; // d[dn] delay line
  376. int dn; // sizeo of delay
  377. cmSample_t* m; // memory buffer
  378. int mn; // size of memory bufer (dn+3)
  379. int ii; // input index
  380. unsigned tn; // count of taps
  381. cmReal_t* ti; // ti[tn] tap locations (fractional delay from t->ii)
  382. cmReal_t* tff; // tg[tn] tap out gain
  383. cmReal_t* tfb;// tfb[tn] tap feedback gain
  384. cmReal_t srate;
  385. } cmIDelay;
  386. cmIDelay* cmIDelayAlloc( cmCtx* c, cmIDelay* p, cmReal_t srate, cmReal_t maxDelayMs, const cmReal_t* tapMs, const cmReal_t* tapFfGain, const cmReal_t* tapFbGain, unsigned tapCnt );
  387. cmRC_t cmIDelayFree( cmIDelay** pp );
  388. cmRC_t cmIDelayInit( cmIDelay* p, cmReal_t srate, cmReal_t maxDelayMs, const cmReal_t* tapMs, const cmReal_t* tapFfGain, const cmReal_t* tapFbGain, unsigned tapCnt );
  389. cmRC_t cmIDelayFinal(cmIDelay* p );
  390. cmRC_t cmIDelayExec( cmIDelay* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  391. cmRC_t cmIDelaySetTapMs( cmIDelay* p, unsigned tapIdx, cmReal_t tapMs );
  392. //------------------------------------------------------------------------------------------------------------
  393. //)
  394. //( { label:cmGroupSel file_desc:"Assign channel to dynamic groups under gate control." kw:[proc]}
  395. // This object sequentially assigns channels to groups when their gates go high.
  396. // 'chsPerGroup' channels will be assigned to each group. No channel will be
  397. // assigned to any group unless there are at least 'chsPerGroup' available
  398. // (unassigned) channels.
  399. // Channels are released from groups when one of the member channels gates goes low.
  400. //
  401. typedef struct
  402. {
  403. cmReal_t rms; // current rms of this input channel
  404. bool gateFl; // current gate state of this input channel
  405. bool readyFl; // this channel is available to be assigned to a group
  406. bool offsetFl; // the gate went low during this cycle (cleared on exec)
  407. unsigned groupIdx; // group this channel is assigned to or cmInvalidIdx if it is not assigned to any group
  408. } cmGroupSelCh;
  409. typedef struct
  410. {
  411. unsigned* chIdxArray; // chIdxArray[p->chCnt] array of indexes to channels assigned to this group
  412. unsigned chIdxCnt; // count indexes in chIdxArray[] or 0 if the channel is not in use
  413. bool releaseFl; // true during the cycle that this group was released on
  414. bool createFl; // true during the cycle that this group was created on
  415. } cmGroupSelGrp;
  416. typedef struct
  417. {
  418. cmObj obj;
  419. cmGroupSelCh* chArray; // chArray[chCnt]
  420. unsigned chCnt; // count of channels
  421. cmGroupSelGrp* groupArray; // groupArray[groupCnt]
  422. unsigned groupCnt; // count of groups - must be <= chCnt - can be changed at any time
  423. unsigned chsPerGroup; // channels per group
  424. bool updateFl; // set during exec if channels were assigned or released
  425. } cmGroupSel;
  426. cmGroupSel* cmGroupSelAlloc( cmCtx* c, cmGroupSel* p, unsigned chCnt, unsigned groupCnt, unsigned chsPerGroup );
  427. cmRC_t cmGroupSelFree( cmGroupSel** pp );
  428. cmRC_t cmGroupSelInit( cmGroupSel* p, unsigned chCnt, unsigned groupCnt, unsigned chsPerGroup );
  429. cmRC_t cmGroupSelFinal( cmGroupSel* p );
  430. cmRC_t cmGroupSetChannelGate( cmGroupSel* p, unsigned chIdx, bool gateFl );
  431. cmRC_t cmGroupSetChannelRMS( cmGroupSel* p, unsigned chIdx, cmReal_t rms );
  432. // After exec if the p->updateFl is set then iterate through
  433. // p->groupArray[]. Groups that have been created will have their 'createFl' set
  434. // and groups that will be removed on the next cycle have their 'releaseFl' set.
  435. cmRC_t cmGroupSelExec( cmGroupSel* p );
  436. //------------------------------------------------------------------------------------------------------------
  437. //)
  438. //( { label:cmAudioNofM file_desc:"Route N of M possible input channels to N output channels under gate control." kw:[proc]}
  439. // Route N of M input channels to N output channels.
  440. // The N channels are selected from the first N gates to go high.
  441. typedef struct cmAudioNofM_In_str
  442. {
  443. bool gateFl;
  444. bool onsetFl;
  445. bool offsetFl;
  446. unsigned outChIdx;
  447. cmFader* fader;
  448. struct cmAudioNofM_In_str* link;
  449. } cmAudioNofM_In;
  450. typedef struct
  451. {
  452. struct cmAudioNofM_In_str* list;
  453. } cmAudioNofM_Out;
  454. typedef struct
  455. {
  456. cmObj obj;
  457. unsigned iChCnt; // (M) input channel count
  458. cmAudioNofM_In* inArray; // chArray[ M ] - input channel array
  459. unsigned oChCnt; // (N) output channel count
  460. cmAudioNofM_Out* outArray; // outArray[N] - output channel array
  461. unsigned nxtOutChIdx; // ch assoc;d with the next onset gate will be assined to this output channel
  462. } cmAudioNofM;
  463. cmAudioNofM* cmAudioNofMAlloc( cmCtx* c, cmAudioNofM* p, cmReal_t srate, unsigned iChCnt, unsigned oChCnt, cmReal_t fadeTimeMs );
  464. cmRC_t cmAudioNofMFree( cmAudioNofM** pp );
  465. cmRC_t cmAudioNofMInit( cmAudioNofM* p, cmReal_t srate, unsigned iChCnt, unsigned oChCnt, cmReal_t fadeTimeMs );
  466. cmRC_t cmAudioNofMFinal( cmAudioNofM* p );
  467. cmRC_t cmAudioNofMSetChannelGate( cmAudioNofM* p, unsigned inChIdx, bool gateFl );
  468. // Sum the audio contained in x[inChCnt][n] into y[outChCnt][n] according
  469. // to the state of the object.
  470. // Notes
  471. // 1) y[n] should be zeroed by the caller as the output is summed into this buffer.
  472. // 2) inChCnt should equal p->iChCnt and outChCnt should equal p->oChCnt
  473. cmRC_t cmAudioNofMExec( cmAudioNofM* p, const cmSample_t* x[], unsigned inChCnt, cmSample_t* y[], unsigned outChCnt, unsigned n );
  474. cmRC_t cmAudioNofMSetFadeMs( cmAudioNofM* p, cmReal_t fadeTimeMs );
  475. //------------------------------------------------------------------------------------------------------------
  476. //)
  477. //( { label:cmAdsr file_desc:"ADSR audio evelope generator." kw:[proc]}
  478. enum { kDlyAdsrId, kAtkAdsrId, kDcyAdsrId, kSusAdsrId, kRlsAdsrId, kDoneAdsrId };
  479. typedef struct
  480. {
  481. cmObj obj;
  482. cmReal_t srate;
  483. bool trigModeFl; // gate on triggers start, gate-off ignored
  484. cmReal_t levelMin;
  485. cmReal_t scaleDur; //
  486. int dlySmp;
  487. int atkSmp;
  488. cmReal_t atkLevel;
  489. int dcySmp;
  490. int susSmp; // only used in trigger mode
  491. cmReal_t susLevel;
  492. int rlsSmp;
  493. unsigned state; // current state
  494. int durSmp; // time in current state
  495. cmReal_t level; // current level
  496. bool gateFl; // last gate state
  497. cmReal_t atkBegLevel; // attack starting level
  498. cmReal_t atkDurSmp; // attack duration
  499. cmReal_t rlsLevel; // release starting level
  500. cmReal_t rlsDurSmp; // release duration
  501. cmReal_t actAtkLevel;
  502. cmReal_t actSusLevel;
  503. } cmAdsr;
  504. cmAdsr* cmAdsrAlloc( cmCtx* c, cmAdsr* p, cmReal_t srate, bool trigFl, cmReal_t minL, cmReal_t dlyMs, cmReal_t atkMs, cmReal_t atkL, cmReal_t dcyMs, cmReal_t susMs, cmReal_t susL, cmReal_t rlsMs );
  505. cmRC_t cmAdsrFree( cmAdsr** pp );
  506. cmRC_t cmAdsrInit( cmAdsr* p, cmReal_t srate, bool trigFl, cmReal_t minL, cmReal_t dlyMs, cmReal_t atkMs, cmReal_t atkL, cmReal_t dcyMs, cmReal_t susMs, cmReal_t susL, cmReal_t rlsMs );
  507. cmRC_t cmAdsrFinal( cmAdsr* p );
  508. cmReal_t cmAdsrExec( cmAdsr* p, unsigned procSmpCnt, bool gateFl, cmReal_t tscale, cmReal_t ascale );
  509. void cmAdsrSetTime( cmAdsr* p, cmReal_t ms, unsigned id );
  510. void cmAdsrSetLevel( cmAdsr* p, cmReal_t level, unsigned id );
  511. void cmAdsrReport( cmAdsr* p, cmRpt_t* rpt );
  512. //------------------------------------------------------------------------------------------------------------
  513. //)
  514. //( { label:cmCompressor file_desc:"Audio dynamics compressor algorithm." kw:[proc]}
  515. enum { kAtkCompId, kRlsCompId };
  516. typedef struct
  517. {
  518. cmObj obj;
  519. cmReal_t srate; // system sample rate
  520. unsigned procSmpCnt; // samples per exec cycle
  521. cmReal_t inGain; // input gain
  522. cmReal_t threshDb; // threshold in dB (max:100 min:0)
  523. cmReal_t ratio_num; // numerator of the ratio
  524. unsigned atkSmp; // time to reduce the signal by 10.0 db
  525. unsigned rlsSmp; // time to increase the signal by 10.0 db
  526. cmReal_t outGain; // makeup gain
  527. bool bypassFl; // bypass enable
  528. cmSample_t* rmsWnd; // rmsWnd[rmsWndAllocCnt]
  529. unsigned rmsWndAllocCnt; //
  530. unsigned rmsWndCnt; // current RMS window size (rmsWndCnt must be <= rmsWndAllocCnt)
  531. unsigned rmsWndIdx; // next RMS window input index
  532. unsigned state; // env. state
  533. cmReal_t rmsDb; // current incoming signal RMS (max:100 min:0)
  534. cmReal_t gain; // current compressor gain
  535. cmReal_t timeConstDb; // the atk/rls will incr/decr by 'timeConstDb' per atkMs/rlsMs.
  536. cmReal_t pkDb; //
  537. cmReal_t accumDb; //
  538. } cmCompressor;
  539. cmCompressor* cmCompressorAlloc( cmCtx* c, cmCompressor* p, cmReal_t srate, unsigned procSmpCnt, cmReal_t inGain, cmReal_t rmsWndMaxMs, cmReal_t rmsWndMs, cmReal_t threshDb, cmReal_t ratio, cmReal_t atkMs, cmReal_t rlsMs, cmReal_t outGain, bool bypassFl );
  540. cmRC_t cmCompressorFree( cmCompressor** pp );
  541. cmRC_t cmCompressorInit( cmCompressor* p, cmReal_t srate, unsigned procSmpCnt, cmReal_t inGain, cmReal_t rmsWndMaxMs, cmReal_t rmsWndMs, cmReal_t threshDb, cmReal_t ratio, cmReal_t atkMs, cmReal_t rlsMs, cmReal_t outGain, bool bypassFl );
  542. cmRC_t cmCompressorFinal( cmCompressor* p );
  543. cmRC_t cmCompressorExec( cmCompressor* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  544. void cmCompressorSetAttackMs( cmCompressor* p, cmReal_t ms );
  545. void cmCompressorSetReleaseMs( cmCompressor* p, cmReal_t ms );
  546. void cmCompressorSetThreshDb( cmCompressor* p, cmReal_t thresh );
  547. void cmCompressorSetRmsWndMs( cmCompressor* p, cmReal_t ms );
  548. //------------------------------------------------------------------------------------------------------------
  549. //)
  550. //( { label:cmBiQuad file_desc:"General purpose Biquad filter algorithm." kw:[proc]}
  551. // BiQuad Audio Eq's based on Robert Bristow-Johnson's recipes.
  552. // http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
  553. // See filter_rbj.m for equivalent octave code.
  554. enum
  555. {
  556. kLpfBqId,
  557. kHpFBqId,
  558. kBpfBqId,
  559. kNotchBqId,
  560. kAllpassBqId,
  561. kPeakBqId,
  562. kLowShelfBqId,
  563. kHighShelfBqId
  564. };
  565. typedef struct
  566. {
  567. cmObj obj;
  568. cmReal_t srate;
  569. unsigned mode;
  570. cmReal_t f0Hz;
  571. cmReal_t Q;
  572. cmReal_t gainDb;
  573. cmReal_t d[4];
  574. cmReal_t b[3];
  575. cmReal_t a[3];
  576. bool bypassFl;
  577. } cmBiQuadEq;
  578. cmBiQuadEq* cmBiQuadEqAlloc( cmCtx* c, cmBiQuadEq* p, cmReal_t srate, unsigned mode, cmReal_t f0Hz, cmReal_t Q, cmReal_t gainDb, bool bypassFl );
  579. cmRC_t cmBiQuadEqFree( cmBiQuadEq** pp );
  580. cmRC_t cmBiQuadEqInit( cmBiQuadEq* p, cmReal_t srate, unsigned mode, cmReal_t f0Hz, cmReal_t Q, cmReal_t gainDb, bool bypassFl );
  581. cmRC_t cmBiQuadEqFinal( cmBiQuadEq* p );
  582. cmRC_t cmBiQuadEqExec( cmBiQuadEq* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  583. void cmBiQuadEqSet( cmBiQuadEq* p, unsigned mode, cmReal_t f0Hz, cmReal_t Q, cmReal_t gainDb );
  584. //------------------------------------------------------------------------------------------------------------
  585. //)
  586. //( { label:cmDistDs file_desc:"Guitar style distortion effect." kw:[proc]}
  587. typedef struct
  588. {
  589. cmObj obj;
  590. cmReal_t srate;
  591. cmReal_t downSrate;
  592. cmReal_t bits;
  593. bool rectFl;
  594. bool fullFl;
  595. cmReal_t clipDb;
  596. cmReal_t inGain;
  597. cmReal_t outGain;
  598. bool bypassFl;
  599. double fracIdx;
  600. cmSample_t lastVal;
  601. cmSample_t lastY;
  602. cmSample_t lastX;
  603. } cmDistDs;
  604. cmDistDs* cmDistDsAlloc( cmCtx* c, cmDistDs* p, cmReal_t srate, cmReal_t inGain, cmReal_t downSrate, cmReal_t bits, bool rectFl, bool fullFl, cmReal_t clipDb, cmReal_t outGain, bool bypassFl );
  605. cmRC_t cmDistDsFree( cmDistDs** p );
  606. cmRC_t cmDistDsInit( cmDistDs* p, cmReal_t srate, cmReal_t inGain, cmReal_t downSrate, cmReal_t bits, bool rectFl, bool fullFl, cmReal_t clipDb, cmReal_t outGain, bool bypassFl );
  607. cmRC_t cmDistDsFinal( cmDistDs* p );
  608. cmRC_t cmDistDsExec( cmDistDs* p, const cmSample_t* x, cmSample_t* y, unsigned n );
  609. //------------------------------------------------------------------------------------------------------------
  610. //)
  611. //=======================================================================================================================
  612. /*
  613. typedef struct
  614. {
  615. cmObj obj;
  616. } cmUnitDelay;
  617. cmUnitDelay* cmUnitDelayAlloc( cmCtx* c, cmUnitDelay* p, cmReal_t srate, unsigned smpCnt, unsigned inCnt, unsigned outCnt, const cmReal_t delayMsV, unsigned delayCnt );
  618. cmRC_t cmUnitDelayFree( cmUnitDelay* p );
  619. cmRC_t cmUnitDelayInit( cmUnitDelay* p, cmReal_t srate, unsigned smpCnt, braunsigned inCnt, unsigned outCnt, const cmReal_t delayMsV, unsigned delayCnt );
  620. cmRC_t cmUnitDelayFinal( cmUnitDelay* p );
  621. cmRC_t cmUnitDelayExec( cmUnitDelay* p, const cmSample_t** x, unsigned inChCnt, cmSample_t** y, unsigned outChCnt, unsigned smpCnt );
  622. */
  623. #ifdef __cplusplus
  624. }
  625. #endif
  626. #endif