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

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