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.

cmProc3.h 32KB

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