libcm is a C development framework with an emphasis on audio signal processing applications.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmFloatTypes.h"
  4. #include "cmRpt.h"
  5. #include "cmErr.h"
  6. #include "cmCtx.h"
  7. #include "cmMem.h"
  8. #include "cmMallocDebug.h"
  9. #include "cmLinkedHeap.h"
  10. #include "cmFileSys.h"
  11. #include "cmSymTbl.h"
  12. #include "cmJson.h"
  13. #include "cmText.h"
  14. #include "cmPrefs.h"
  15. #include "cmDspValue.h"
  16. #include "cmMsgProtocol.h"
  17. #include "cmThread.h"
  18. #include "cmUdpPort.h"
  19. #include "cmUdpNet.h"
  20. #include "cmSerialPort.h"
  21. #include "cmTime.h"
  22. #include "cmAudioSys.h"
  23. #include "cmProcObj.h"
  24. #include "cmDspCtx.h"
  25. #include "cmDspClass.h"
  26. #include "cmDspSys.h"
  27. #include "cmDspPgm.h"
  28. #include "cmDspPgmPPMain.h"
  29. #include "cmAudioFile.h"
  30. #include "cmProcObj.h"
  31. #include "cmProc.h"
  32. #include "cmProc3.h"
  33. #include "cmVectOpsTemplateMain.h"
  34. #define COL_WIDTH (150)
  35. cmDspInst_t** allocInstPtrArray( cmDspSysH_t h, unsigned cnt )
  36. { return cmLhAllocZ(cmDspSysLHeap(h),cmDspInst_t*,cnt); }
  37. #define formLabel( h, lbl, i) cmTsPrintfH( cmDspSysLHeap(h), "%s-%i", lbl, i )
  38. //=====================================================================================================================
  39. cmDspInst_t* _cmDspSys_PresetMgmt( cmDspSysH_t h, const cmChar_t* preLbl, unsigned presetGroupSymId )
  40. {
  41. cmLHeapH_t lhH = cmDspSysLHeap(h);
  42. cmDspInst_t* preset = cmDspSysAllocInst( h, "Preset", NULL, 1, presetGroupSymId );
  43. cmDspInst_t* presetLbl = cmDspSysAllocInst( h, "Text", NULL, 2, "", "Preset Label" );
  44. cmDspInst_t* storeBtn = cmDspSysAllocInst( h, "Button", cmTsPrintfH(lhH,"%s-store", preLbl), 2, kButtonDuiId, 0.0);
  45. cmDspInst_t* recallBtn = cmDspSysAllocInst( h, "Button", cmTsPrintfH(lhH,"%s-recall",preLbl), 2, kButtonDuiId, 0.0);
  46. cmDspInst_t* ptsStore = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "store" );
  47. cmDspInst_t* ptsRecall = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "recall" );
  48. cmDspSysInstallCb( h, presetLbl, "val", preset, "label",NULL);
  49. cmDspSysInstallCb( h, storeBtn, "out", ptsStore, "store", NULL );
  50. cmDspSysInstallCb( h, recallBtn, "out", ptsRecall, "recall", NULL );
  51. cmDspSysInstallCb( h, ptsStore, "out", preset, "cmd", NULL );
  52. cmDspSysInstallCb( h, ptsRecall, "out", preset, "cmd", NULL );
  53. return preset;
  54. }
  55. //=====================================================================================================================
  56. typedef struct
  57. {
  58. unsigned circuitSymId; // enable/disable symId
  59. cmDspInst_t** aout; // aout[ ctx->outChCnt ]
  60. const cmChar_t* aoutLbl; // "out"
  61. } cmDspPP_Circuit_t;
  62. //=====================================================================================================================
  63. typedef struct
  64. {
  65. cmDspPP_Circuit_t c;
  66. cmDspInst_t** sfmt;
  67. cmDspInst_t** rmtr;
  68. cmDspInst_t** gmtr;
  69. } cmDspPP_TestCircuit_t;
  70. cmDspRC_t _cmDspPP_TestCircuitAlloc(
  71. cmDspSysH_t h,
  72. _cmDspPP_Ctx_t* ctx,
  73. cmDspPP_TestCircuit_t* p,
  74. const cmChar_t* title,
  75. const cmChar_t* preLbl,
  76. cmDspInst_t* selChk,
  77. cmDspInst_t** ain,
  78. cmDspInst_t* ptIn )
  79. {
  80. cmDspRC_t rc;
  81. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  82. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
  83. _cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
  84. cmDspSysNewColumn(h,COL_WIDTH);
  85. p->c.aout = allocInstPtrArray(h, ctx->oChCnt);
  86. // make processors for each input channel
  87. cmDspInst_t** sfmt = cmDspSysAllocInstArray( h, ctx->iChCnt, "Sprintf", NULL, NULL, 1, "gate-%i:");
  88. cmDspInst_t** rmtr = cmDspSysAllocInstArray( h, ctx->iChCnt, "Meter", "RMS", NULL, 3, 0.0, 0.0, 1.0 );
  89. cmDspSysNewColumn(h,COL_WIDTH);
  90. cmDspInst_t** gmtr = cmDspSysAllocInstArray( h, ctx->iChCnt, "Meter", "Gate",NULL, 3, 0.0, 0.0, 1.0 );
  91. // make processors for each output channel
  92. if( ctx->oChCnt )
  93. p->c.aout[0] = cmDspSysAllocInst( h, "AMix", NULL, 1, ctx->iChCnt );
  94. p->c.aoutLbl = "out";
  95. // check for allocation errors
  96. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  97. goto errLabel;
  98. if( ctx->oChCnt )
  99. cmDspSysConnectAudioN11N(h, ain, "out", p->c.aout[0], "in", ctx->iChCnt );
  100. cmDspSysInstallCb1NN1(h, ptIn, "f-out", rmtr, "in", ctx->iChCnt ); // RMS input
  101. cmDspSysInstallCb1NN1(h, ptIn, "b-out", gmtr, "in", ctx->iChCnt ); // Gate input
  102. cmDspSysInstallCb1NN1(h, ptIn, "b-out", sfmt, "in-0", ctx->iChCnt ); // format string
  103. //cmDspSysInstallCbN111(h, p->sfmt, "out", ctx->print, "in", ctx->iChCnt);// print string
  104. errLabel:
  105. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  106. return rc;
  107. }
  108. //=====================================================================================================================
  109. typedef struct
  110. {
  111. cmDspInst_t** tmop;
  112. cmDspInst_t** amop;
  113. cmDspInst_t** cf;
  114. cmDspInst_t** sg;
  115. cmDspInst_t** eq;
  116. cmDspInst_t** env;
  117. cmDspInst_t** rtr;
  118. cmDspInst_t** bts;
  119. cmDspInst_t* mix;
  120. } cmDspSys_NShp_t;
  121. cmDspSys_NShp_t* _cmDspSys_NShpAlloc( cmDspSysH_t h, unsigned pgSymId, const cmChar_t* preLbl, unsigned chCnt, bool seqFl )
  122. {
  123. cmDspRC_t rc = kOkDspRC;
  124. unsigned secCnt = 3;
  125. double cntMin = 1;
  126. double cntMax = secCnt;
  127. unsigned sgShapeId = 2;
  128. unsigned sgOtCnt = 5;
  129. double cfMinHz = 20.0;
  130. double cfHz = 500;
  131. double cfAlpha = 0.9;
  132. bool cfFbFl = true;
  133. bool cfBypassFl = false;
  134. double adsrMaxMs = 20000;
  135. double adsrMinMs = 0;
  136. double adsrIncMs = 1;
  137. double adsrMaxLevel = 100.0;
  138. double adsrSusLevel = 100.0;
  139. double adsrMinLevel = 0.0;
  140. double adsrIncLevel = 0.001;
  141. bool eqBypassFl = false;
  142. unsigned eqModeSymId = cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"LP");
  143. double eqF0hz = 250;
  144. double eqQ = 1.0;
  145. double eqFgain = 1.0;
  146. bool mtBypassFl = false;
  147. double mtTimeScale= 1.0;
  148. double mtFeedback = 0.5;
  149. double multMin = 0.0;
  150. double multMax = 100.0;
  151. double multInc = 0.01;
  152. double offsMin = 0.0;
  153. double offsMax = 100.0;
  154. double offsInc = 0.01;
  155. cmDspSys_NShp_t* p = cmLhAllocZ( cmDspSysLHeap(h),cmDspSys_NShp_t,1);
  156. cmDspInst_t** bts = NULL;
  157. cmDspInst_t** rtr = NULL;
  158. cmDspInst_t** cnt0 = NULL;
  159. cmDspInst_t** cnt1 = NULL;
  160. cmDspInst_t** cnt2 = NULL;
  161. cmDspInst_t** seq0 = NULL;
  162. cmDspInst_t** seq1 = NULL;
  163. cmDspInst_t** seq2 = NULL;
  164. cmDspSysNewColumn(h,COL_WIDTH);
  165. cmDspInst_t** sg = p->sg = cmDspSysAllocInstArray( h, chCnt, "SigGen", NULL, NULL, 2, 1000.0, sgShapeId, 1.0, sgOtCnt );
  166. cmDspInst_t** cf = p->cf = cmDspSysAllocInstArray( h, chCnt, "CombFilt", NULL, NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
  167. cmDspInst_t** eq = p->eq = cmDspSysAllocInstArray( h, chCnt, "BiQuadEq", NULL, NULL, 5, eqBypassFl, eqModeSymId, eqF0hz, eqQ, eqFgain );
  168. cmDspInst_t** mt = cmDspSysAllocInstArray( h, chCnt, "MtDelay", NULL, NULL, 9, mtBypassFl, mtTimeScale, mtFeedback, 20.0, 0.8, 15.0, 0.9, 12.0, 0.9 );
  169. // adsr time/ampl scale/offset
  170. cmDspInst_t** tmop = p->tmop= cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  171. cmDspInst_t** toop = cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
  172. cmDspInst_t** amop = p->amop= cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  173. cmDspInst_t** aoop = cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
  174. cmDspInst_t** env = p->env = cmDspSysAllocInstArray( h, chCnt, "Adsr", NULL, NULL, 2, true, adsrMinLevel );
  175. cmDspInst_t** d2l = cmDspSysAllocInstArray( h, chCnt, "DbToLin", NULL, NULL, 0 );
  176. if( seqFl )
  177. {
  178. bts = p->bts = cmDspSysAllocInstArray( h, chCnt, "GateToSym",NULL, NULL, 0 );
  179. rtr = p->rtr = cmDspSysAllocInstArray( h, chCnt, "Router", NULL, NULL, 2, secCnt, 0 );
  180. cnt0 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
  181. cnt1 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
  182. cnt2 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
  183. seq0 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq0");
  184. seq1 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq1");
  185. seq2 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq2");
  186. }
  187. // output mixer
  188. cmDspInst_t* mix = p->mix = cmDspSysAllocInst( h, "AMix", NULL, 2, chCnt, 0.0 );
  189. // comb filter parameters
  190. cmDspSysNewColumn(h,COL_WIDTH);
  191. cmDspInst_t* alpha = cmDspSysAllocScalarP( h, pgSymId, preLbl, "alpha", -1.0, 1.0, 0.001, cfAlpha );
  192. // time/amp scale multiply and offset controls
  193. cmDspInst_t* tmul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Mult", multMin, multMax, multInc, 1.0);
  194. cmDspInst_t* toff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Offs", offsMin, offsMax, offsInc, 0.0);
  195. cmDspInst_t* amul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Mult", multMin, multMax, multInc, 1.0);
  196. cmDspInst_t* aoff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Offs", offsMin, offsMax, offsInc, 0.0);
  197. // ADSR parameters
  198. cmDspInst_t* dly = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 0.0);
  199. cmDspInst_t* atk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Atk Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 5000.0);
  200. cmDspInst_t* dcy = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dcy Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
  201. cmDspInst_t* hold = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Hold Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
  202. cmDspInst_t* rls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Rls Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 9000.0);
  203. cmDspInst_t* alvl = cmDspSysAllocScalarP( h, pgSymId, preLbl, "AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);
  204. cmDspInst_t* sus = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sustain", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel );
  205. cmDspSysNewColumn(h,COL_WIDTH);
  206. cmDspInst_t* eqbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Eq Byp", 0 );
  207. cmDspInst_t* eqmode = cmDspSysAllocMsgListP(h, pgSymId, preLbl, "Mode", NULL, "biQuadEqMode", 1);
  208. cmDspInst_t* eqq = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Q", -100.0, 100.0, 0.1, eqQ);
  209. cmDspInst_t* eqfgn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Filt Gain", 0.0, 1.0, 0.1, eqFgain);
  210. cmDspInst_t* mtfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Mt Feedback", 0.0, 1.0, 0.01, mtFeedback);
  211. cmDspInst_t* mtscale= cmDspSysAllocScalarP( h, pgSymId, preLbl, "Mt Time Scale", 0.01, 10.0, 0.01, mtTimeScale);
  212. cmDspInst_t* sgsh = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg Shape", 0.0, 8.0, 1.0, ((double)sgShapeId));
  213. cmDspInst_t* sgot = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg OT Cnt", 0.0, 10.0, 1.0, ((double)sgOtCnt));
  214. // check for allocation errors
  215. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  216. goto errLabel;
  217. cmDspSysConnectAudioN1N1( h, sg, "out", cf, "in", chCnt ); // sg -> CF
  218. cmDspSysConnectAudioN1N1( h, cf, "out", eq, "in", chCnt ); // CF -> EQ
  219. cmDspSysConnectAudioN1N1( h, eq, "out", mt, "in", chCnt ); // EQ -> MT
  220. cmDspSysConnectAudioN11N( h, mt, "out", mix, "in", chCnt ); // MT -> mix
  221. cmDspSysInstallCb11N1( h, tmul, "val", tmop, "in-1", chCnt );
  222. cmDspSysInstallCb11N1( h, toff, "val", toop, "in-1", chCnt );
  223. cmDspSysInstallCbN1N1( h, tmop, "out", toop, "in-0", chCnt );
  224. cmDspSysInstallCbN1N1( h, toop, "out", env, "tscale", chCnt );
  225. cmDspSysInstallCb11N1( h, amul, "val", amop, "in-1", chCnt );
  226. cmDspSysInstallCb11N1( h, aoff, "val", aoop, "in-1", chCnt );
  227. cmDspSysInstallCbN1N1( h, amop, "out", aoop, "in-0", chCnt );
  228. cmDspSysInstallCbN1N1( h, aoop, "out", env, "ascale", chCnt );
  229. cmDspSysInstallCbN1N1( h, env, "out", d2l, "in", chCnt ); // adsr -> dbtolin
  230. cmDspSysInstallCbN11N( h, d2l, "out", mix, "gain", chCnt ); // db2lin -> mix (gain)
  231. cmDspSysInstallCbN1N1( h, env, "out", d2l, "in", chCnt );
  232. cmDspSysInstallCbN11N( h, d2l, "out", mix, "gain", chCnt );
  233. cmDspSysInstallCb11N1( h, alpha, "val", cf, "alpha", chCnt ); // CF alpha
  234. cmDspSysInstallCb11N1( h, sgsh, "val", sg, "shape", chCnt );
  235. cmDspSysInstallCb11N1( h, sgot, "val", sg, "ot", chCnt );
  236. cmDspSysInstallCb11N1( h, dly, "val", env, "dly", chCnt );
  237. cmDspSysInstallCb11N1( h, atk, "val", env, "atk", chCnt );
  238. cmDspSysInstallCb11N1( h, dcy, "val", env, "dcy", chCnt );
  239. cmDspSysInstallCb11N1( h, hold, "val", env, "hold", chCnt );
  240. cmDspSysInstallCb11N1( h, rls, "val", env, "rls", chCnt );
  241. cmDspSysInstallCb11N1( h, alvl, "val", env, "alvl", chCnt );
  242. cmDspSysInstallCb11N1( h, sus, "val", env, "sus", chCnt );
  243. cmDspSysInstallCb11N1( h, eqbyp, "out", eq, "bypass", chCnt );
  244. cmDspSysInstallCb11N1( h, eqmode, "mode", eq, "mode", chCnt );
  245. cmDspSysInstallCb11N1( h, eqq, "val", eq, "Q", chCnt );
  246. cmDspSysInstallCb11N1( h, eqfgn, "val", eq, "gain", chCnt );
  247. cmDspSysInstallCb11N1( h, mtfb, "val", mt, "fb", chCnt );
  248. cmDspSysInstallCb11N1( h, mtscale,"val", mt, "scale", chCnt );
  249. if( seqFl )
  250. {
  251. cmDspSysInstallCbN1N1( h, bts, "out", rtr, "s-in", chCnt );
  252. cmDspSysInstallCbN1N1( h, rtr, "s-out-0", cnt0, "next", chCnt );
  253. cmDspSysInstallCbN1N1( h, rtr, "s-out-1", cnt1, "next", chCnt );
  254. cmDspSysInstallCbN1N1( h, rtr, "s-out-2", cnt2, "next", chCnt );
  255. cmDspSysInstallCbN1N1(h, seq0, "cnt", cnt0, "max", chCnt );
  256. cmDspSysInstallCbN1N1(h, seq1, "cnt", cnt1, "max", chCnt );
  257. cmDspSysInstallCbN1N1(h, seq2, "cnt", cnt2, "max", chCnt );
  258. cmDspSysInstallCbN1N1(h, cnt0, "out", seq0, "sel", chCnt );
  259. cmDspSysInstallCbN1N1(h, cnt1, "out", seq1, "sel", chCnt );
  260. cmDspSysInstallCbN1N1(h, cnt2, "out", seq2, "sel", chCnt );
  261. cmDspSysInstallCbN1N1(h, seq0, "hz", cf, "hz", chCnt );
  262. cmDspSysInstallCbN1N1(h, seq1, "hz", cf, "hz", chCnt );
  263. cmDspSysInstallCbN1N1(h, seq2, "hz", cf, "hz", chCnt );
  264. cmDspSysInstallCbN1N1(h, seq0, "hz", eq, "f0", chCnt );
  265. cmDspSysInstallCbN1N1(h, seq1, "hz", eq, "f0", chCnt );
  266. cmDspSysInstallCbN1N1(h, seq2, "hz", eq, "f0", chCnt );
  267. cmDspSysInstallCbN1N1(h, seq0, "hz", sg, "hz", chCnt );
  268. cmDspSysInstallCbN1N1(h, seq1, "hz", sg, "hz", chCnt );
  269. cmDspSysInstallCbN1N1(h, seq2, "hz", sg, "hz", chCnt );
  270. }
  271. errLabel:
  272. if(cmDspSysLastRC(h) != kOkDspRC )
  273. p = NULL;
  274. return p;
  275. }
  276. typedef struct
  277. {
  278. cmDspPP_Circuit_t c;
  279. cmDspSys_NShp_t* ns0p;
  280. cmDspSys_NShp_t* ns1p;
  281. } cmDspPP_NSh_Circuit_t;
  282. cmDspRC_t _cmDspPP_NoiseShaperAlloc(
  283. cmDspSysH_t h,
  284. cmErr_t* err,
  285. cmDspPP_NSh_Circuit_t* p,
  286. const cmChar_t* title,
  287. const cmChar_t* preLbl,
  288. cmDspInst_t* selChk,
  289. cmDspInst_t* ptIn,
  290. unsigned iChCnt,
  291. unsigned oChCnt)
  292. {
  293. cmDspRC_t rc = kOkDspRC;
  294. double secCnt = 3;
  295. unsigned nsCnt = 0;
  296. unsigned nsCnt1 = 0;
  297. const cmChar_t* nsPitchRsrcStr = "nsMidi";
  298. const cmChar_t* nsChIdxRsrcStr = "nsSelCh";
  299. // get the active channel list (indexes of the input channels which will be used by the noise shaper);
  300. if( cmDspRsrcArrayCount( h, &nsCnt1, nsChIdxRsrcStr, NULL ) != kOkDspRC )
  301. return cmErrMsg(err,kPgmCfgFailDspRC,"The noise shaper channel index list '%s' could not be read.",cmStringNullGuard(nsChIdxRsrcStr));
  302. // get the pitches associated with each active channel
  303. if( cmDspRsrcArrayCount( h, &nsCnt, nsPitchRsrcStr, NULL ) != kOkDspRC )
  304. return cmErrMsg(err,kPgmCfgFailDspRC,"The noise shaper pitch list '%s' could not be read.",cmStringNullGuard(nsPitchRsrcStr));
  305. // the channel and pitch list must contain the same number of elements
  306. assert( nsCnt1 == nsCnt );
  307. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  308. unsigned presetGrpSymId = cmDspSysPresetRegisterGroup(h,title);
  309. _cmDspSys_PresetMgmt(h,preLbl,presetGrpSymId);
  310. cmDspSysNewColumn(h,COL_WIDTH);
  311. //cmDspInst_t* printBtn = cmDspSysAllocInst( h, "Button", "_print", 2, kButtonDuiId, 0.0);
  312. //cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, p->c.circuitSymId );
  313. //cmDspSysInstallCb( h, printBtn, "sym", bcast, "msg", NULL );
  314. p->c.aout = allocInstPtrArray(h,oChCnt);
  315. // nom - selects active channels from among all possible input channels - coming from the EF's
  316. cmDspInst_t* nom = cmDspSysAllocInst( h, "NofM", NULL, 2, iChCnt, nsCnt ); // EF's -> Nsh switch
  317. // Allocate the noise shapers
  318. p->ns0p = _cmDspSys_NShpAlloc( h, presetGrpSymId, "f", nsCnt, false );
  319. p->ns1p = _cmDspSys_NShpAlloc( h, presetGrpSymId, "s", nsCnt, true );
  320. cmDspSysNewColumn(h,COL_WIDTH);
  321. cmDspInst_t* sectn = cmDspSysAllocScalar( h, "Section", 0, secCnt-1, 1.0, 0.0);
  322. cmDspInst_t* pts = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "off", "send" );
  323. cmDspInst_t* pitarr = cmDspSysAllocInst( h, "Array", NULL, 1, nsPitchRsrcStr );
  324. cmDspInst_t* charr = cmDspSysAllocInst( h, "Array", NULL, 1, nsChIdxRsrcStr );
  325. cmDspInst_t** eqpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
  326. cmDspInst_t** cfpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
  327. cmDspInst_t** sgpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
  328. // check for allocation errors
  329. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  330. goto errLabel;
  331. assert( oChCnt >= 2 );
  332. // put the 'f' noise in ch:0 and the 's' noise in ch:1
  333. p->c.aoutLbl = "out";
  334. p->c.aout[1] = p->ns0p->mix;
  335. p->c.aout[0] = p->ns1p->mix;
  336. // selChk is the circuit selector check box in the main window
  337. cmDspSysInstallCb( h, selChk, "out", pts, "off", NULL ); // First send 'off' to nom to clear its selector
  338. cmDspSysInstallCb( h, selChk, "out", pts, "send", NULL ); // Second send 'send' to charr to select active ports on nom.
  339. cmDspSysInstallCb( h, pts, "off", nom, "cmd", NULL ); // Clear the nom (all inputs are turned off)
  340. cmDspSysInstallCb( h, pts, "send", charr, "cmd", NULL ); // Send the active channel indexes to the nom
  341. cmDspSysInstallCb( h, pts, "send", pitarr, "cmd", NULL ); // Send the pitch values to the circuits (eq,cf,sg,..)
  342. cmDspSysInstallCb( h, charr, "done", nom, "cmd", NULL ); // Tell the nom when its setup is complete
  343. cmDspSysInstallCb1N11( h, charr, "out", nom, "seli", nsCnt ); // EF nom channel index selectors
  344. cmDspSysInstallCb1N1N( h, ptIn, "b-out", nom, "b-in", iChCnt ); // EF -> nom (gates)
  345. cmDspSysInstallCb1N1N( h, ptIn, "f-out", nom, "f-in", iChCnt ); // EF -> nom (rms)
  346. cmDspSysInstallCb1NN1( h, pitarr, "out", cfpc, "midi", nsCnt ); // pitch array -> pitch converter
  347. cmDspSysInstallCb1NN1( h, pitarr, "out", eqpc, "midi", nsCnt );
  348. cmDspSysInstallCb1NN1( h, pitarr, "out", sgpc, "midi", nsCnt );
  349. cmDspSysInstallCbN1N1( h, cfpc, "hz", p->ns0p->cf, "hz", nsCnt ); // pitch cvt -> CF (Hz)
  350. cmDspSysInstallCbN1N1( h, eqpc, "hz", p->ns0p->eq, "f0", nsCnt ); // pitch cvt -> Eq (Hz)
  351. cmDspSysInstallCbN1N1( h, sgpc, "hz", p->ns0p->sg, "hz", nsCnt ); // pitch cvt -> SG (Hz)
  352. cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns0p->env, "gate", nsCnt ); // EF -> adsr (gate)
  353. cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns1p->env, "gate", nsCnt ); //
  354. cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns0p->tmop, "in-0", nsCnt ); // EF (level) -> adsr time scale
  355. cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns0p->amop, "in-0", nsCnt ); // EF (level) -> adsr ampl scale
  356. cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns1p->tmop, "in-0", nsCnt ); // EF (level) -> adsr time scale
  357. cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns1p->amop, "in-0", nsCnt ); // EF (level) -> adsr ampl scale
  358. cmDspSysInstallCb11N1( h, sectn, "val", p->ns1p->rtr, "sel", nsCnt ); // section scalar -> rtr sel input
  359. cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns1p->bts, "on", nsCnt ); // nom gate -> bool-to-sym -> rtr input
  360. errLabel:
  361. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  362. return rc;
  363. }
  364. //=====================================================================================================================
  365. typedef struct
  366. {
  367. cmDspInst_t* start; // circ. sel check -> start
  368. cmDspInst_t** tmop; // level -> time scale input
  369. cmDspInst_t** amop; // level -> ampl scale input
  370. cmDspInst_t** adsr; // gate -> adsr input
  371. cmDspInst_t** mix; // audio -> input mixer
  372. cmDspInst_t** ps; // pitch shifter
  373. cmDspInst_t** eq;
  374. cmDspInst_t** mt; // output prior to the mixer
  375. cmDspInst_t* mixo; // output mixer -> aout
  376. } cmDspFx0_Chain_t;
  377. cmDspRC_t _cmDspFx0_ChainAlloc(
  378. cmDspSysH_t h,
  379. cmErr_t* err,
  380. unsigned pgSymId,
  381. const cmChar_t* preLbl,
  382. const cmChar_t* rsrc,
  383. unsigned chainChCnt,
  384. cmDspFx0_Chain_t* p )
  385. {
  386. cmDspRC_t rc = kOkDspRC;
  387. double multMin = 0.0;
  388. double multMax = 100.0;
  389. double multInc = 0.01;
  390. double offsMin = 0.0;
  391. double offsMax = 100.0;
  392. double offsInc = 0.01;
  393. double adsrMaxMs = 20000;
  394. double adsrMinMs = 0;
  395. double adsrIncMs = 1;
  396. double adsrMaxLevel = 100.0;
  397. double adsrSusLevel = 100.0;
  398. double adsrMinLevel = 0.0;
  399. double adsrIncLevel = 0.001;
  400. unsigned sgShapeId = 2;
  401. unsigned sgOtCnt = 5;
  402. bool lpBypassFl = true;
  403. bool cmpBypassFl = false;
  404. double cmpInGain = 1.0;
  405. double cmpThreshDb = -40.0;
  406. double cmpRatio_num = 4.0;
  407. double cmpAtkMs = 15.0;
  408. double cmpRlsMs = 50.0;
  409. double cmpMakeup = 4.0;
  410. double cmpWndMaxMs = 1000.0;
  411. double cmpWndMs = 200.0;
  412. double cmpMaxGain = 100.0;
  413. bool distBypassFl = false;
  414. double distInGain = 4.0;
  415. double distDsrate = 44100.0;
  416. double distBits = 24.0;
  417. bool distRectifyFl = false;
  418. bool distFullRectFl = false;
  419. double distClipDb = -10.0;
  420. double cfMinHz = 20.0;
  421. double cfHz = 500;
  422. double cfAlpha = 0.9;
  423. bool cfFbFl = true;
  424. bool cfBypassFl = true;
  425. bool eqBypassFl = false;
  426. unsigned eqModeSymId = cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"LP");
  427. double eqF0hz = 250;
  428. double eqQ = 1.0;
  429. double eqFgain = 1.0;
  430. bool psBypassFl = true;
  431. double psMaxRatio = 10.0;
  432. double psRatio = 1.0;
  433. double dlyFb = 0.0;
  434. double dlyMaxMs = 3000.0;
  435. double dlyMs = 1;
  436. bool mtBypassFl = true;
  437. double mtTimeScale = 1.0;
  438. double mtFeedback = 0.0;
  439. double stOffs = 96;
  440. double voiceMult = 1.0 / chainChCnt;
  441. cmDspInst_t** adsr = p->adsr= cmDspSysAllocInstArray(h, chainChCnt, "Adsr", NULL, NULL, 2, true, adsrMinLevel );
  442. cmDspInst_t** dtl = cmDspSysAllocInstArray(h, chainChCnt, "DbToLin", NULL, NULL, 0 );
  443. cmDspInst_t** phs = cmDspSysAllocInstArray(h, chainChCnt, "Phasor", NULL, NULL, 1, cmDspSysSampleRate(h) );
  444. cmDspInst_t** wt = cmDspSysAllocInstArray(h, chainChCnt, "WaveTable", NULL, NULL, 4, ((unsigned)cmDspSysSampleRate(h)), 2, NULL, NULL, -1 );
  445. //cmDspInst_t** sgmul= cmDspSysAllocScalarA( h, chainChCnt, pgSymId, preLbl, "Sg Mult", 0.0, 10.0, 0.01, 1.0 );
  446. //cmDspInst_t** mul = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  447. cmDspInst_t** mixa = p->mix = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 1, 1);
  448. cmDspInst_t** mixs = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 2, 1, 0.0);
  449. cmDspInst_t** mixm = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 3, 2, 0.5, 0.5);
  450. cmDspInst_t** loop = cmDspSysAllocInstArray(h, chainChCnt, "LoopRecd", NULL, NULL, 0 );
  451. cmDspInst_t** ps = p->ps = cmDspSysAllocInstArray(h, chainChCnt, "PShift", NULL, NULL, 2, psBypassFl, psRatio );
  452. cmDspInst_t** cmp = cmDspSysAllocInstArray(h, chainChCnt, "Compressor",NULL, NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpInGain, cmpMakeup, cmpWndMs, cmpWndMaxMs );
  453. cmDspInst_t** dist = cmDspSysAllocInstArray(h, chainChCnt, "DistDs", NULL, NULL, 3, distBypassFl, distInGain, distDsrate, distBits );
  454. cmDspInst_t** cf = cmDspSysAllocInstArray(h, chainChCnt, "CombFilt", NULL, NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
  455. cmDspInst_t** eq = p->eq = cmDspSysAllocInstArray(h, chainChCnt, "BiQuadEq", NULL, NULL, 5, eqBypassFl, eqModeSymId, eqF0hz, eqQ, eqFgain );
  456. cmDspInst_t** dly = cmDspSysAllocInstArray(h, chainChCnt, "Delay", NULL, NULL, 2, dlyMaxMs, dlyFb );
  457. cmDspInst_t** mt = p->mt = cmDspSysAllocInstArray(h, chainChCnt, "MtDelay", NULL, NULL, 5, mtBypassFl, mtTimeScale, mtFeedback, 20.0, 0.3 );
  458. cmDspInst_t* mixo = p->mixo= cmDspSysAllocInst( h, "AMix", NULL, 1, chainChCnt );
  459. cmDspSysNewColumn(h,COL_WIDTH);
  460. cmDspInst_t** dlyms = cmDspSysAllocScalarA( h, chainChCnt, pgSymId, preLbl, "Dly ms", 0.0, 10000.0, 1.0, dlyMs);
  461. cmDspInst_t* start = p->start = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "send" ); // all msgs to start send the 'hz' symbol
  462. cmDspInst_t** sgpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
  463. cmDspInst_t** cfpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
  464. cmDspInst_t** eqpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
  465. cmDspInst_t* midiV = cmDspSysAllocInst( h, "Array", NULL, 1, rsrc );
  466. cmDspSysNewColumn(h,COL_WIDTH);
  467. cmDspInst_t** tmop = p->tmop= cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  468. cmDspInst_t** toop = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
  469. cmDspInst_t** amop = p->amop= cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  470. cmDspInst_t** aoop = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
  471. // time/amp scale multiply and offset controls
  472. cmDspInst_t* tmul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Mult", multMin, multMax, multInc, 1.0);
  473. cmDspInst_t* toff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Offs", offsMin, offsMax, offsInc, 0.0);
  474. cmDspInst_t* amul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Mult", multMin, multMax, multInc, 1.0);
  475. cmDspInst_t* aoff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Offs", offsMin, offsMax, offsInc, 0.0);
  476. // ADSR controls
  477. cmDspInst_t* adly = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Dly", adsrMinMs, adsrMaxMs, adsrIncMs, 0.0);
  478. cmDspInst_t* atk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Atk", adsrMinMs, adsrMaxMs, adsrIncMs, 20.0);
  479. cmDspInst_t* dcy = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Dcy", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
  480. cmDspInst_t* hold = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Hold", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
  481. cmDspInst_t* rls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Rls", adsrMinMs, adsrMaxMs, adsrIncMs, 1000.0);
  482. cmDspInst_t* alvl = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);
  483. cmDspInst_t* sus = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-SusLvl", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel );
  484. //cmDspInst_t* zero = cmDspSysAllocScalarP( h, pgSymId, preLbl, "zero", 0.0, 0.0, 0.0, 0.0);
  485. // SigGen controls
  486. cmDspInst_t* sgsh = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg Shape", 0.0, 11.0, 1.0, ((double)sgShapeId));
  487. cmDspInst_t* sgot = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg OT Cnt", 0.0, 20.0, 1.0, ((double)sgOtCnt));
  488. cmDspInst_t* sgpoffs = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Sg ST off", -stOffs, stOffs, 0.01, 0.0 );
  489. cmDspSysNewColumn(h,COL_WIDTH);
  490. // Loop recorder controls
  491. cmDspInst_t* lpByp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Lp Byps", lpBypassFl );
  492. cmDspInst_t* lpRcd = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Lp Recd", false );
  493. cmDspInst_t* lpRat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Lp Ratio",0.0, 10.0, 0.01, 1.0 );
  494. // Pitch Shifter controls
  495. cmDspInst_t* psbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "PS Byp", psBypassFl );
  496. cmDspInst_t* psrat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "PS Ratio", 0.0, psMaxRatio, 0.01, psRatio );
  497. cmDspSysNewColumn(h,COL_WIDTH);
  498. // Compressor controls
  499. cmDspInst_t* cbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Byp Cmp", cmpBypassFl);
  500. cmDspInst_t* cgain = cmDspSysAllocScalarP( h, pgSymId, preLbl, "In Gain", 0.0, cmpMaxGain, 0.01,cmpInGain );
  501. cmDspInst_t* cthr = cmDspSysAllocScalarP( h, pgSymId, preLbl, "ThreshDb", -100.0, 0.0, 0.1, cmpThreshDb);
  502. cmDspInst_t* crat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ratio", 0.1, 100.0, 0.1, cmpRatio_num);
  503. cmDspInst_t* catk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Atk Ms", 0.0, 1000.0, 0.1, cmpAtkMs);
  504. cmDspInst_t* crls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Rls Ms", 0.0, 1000.0, 0.1, cmpRlsMs);
  505. cmDspInst_t* cmkup = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Makeup", 0.0, cmpMaxGain, 0.01, cmpMakeup);
  506. cmDspInst_t* cwnd = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Wnd Ms", 1.0, cmpWndMaxMs,1.0, cmpWndMs );
  507. // Distortion controls
  508. cmDspInst_t* dbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Dist Byp", distBypassFl);
  509. cmDspInst_t* drct = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Rectify", distRectifyFl);
  510. cmDspInst_t* dful = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Full/Half", distFullRectFl);
  511. cmDspInst_t* dsr = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dsrate", 0.0, 96000.0, 1.0, distDsrate);
  512. cmDspInst_t* dbt = cmDspSysAllocScalarP( h, pgSymId, preLbl, "bits", 2.0, 32.0, 1.0, distBits);
  513. cmDspInst_t* dclip = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Clip dB", -100.0, 0.0, 0.1, distClipDb);
  514. cmDspInst_t* dogn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Out Gain", 0.0, 10.0, 0.01, 1.0);
  515. cmDspSysNewColumn(h,COL_WIDTH);
  516. // Comb filter controls
  517. cmDspInst_t* cfbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "CF Byp", cfBypassFl);
  518. cmDspInst_t* cfalpha = cmDspSysAllocScalarP( h, pgSymId, preLbl, "CF alpha", -1.0, 1.0, 0.001, cfAlpha );
  519. cmDspInst_t* cfpoffs = cmDspSysAllocScalarP( h, pgSymId, preLbl, "CF ST off", -stOffs, stOffs, 0.01, 0.0 );
  520. // Eq controls
  521. cmDspInst_t* eqbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Eq Byp", 0 );
  522. cmDspInst_t* eqmode = cmDspSysAllocMsgListP(h, pgSymId, preLbl, "Mode", NULL, "biQuadEqMode", 1);
  523. cmDspInst_t* eqq = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Eq Q", -100.0, 100.0, 0.1, eqQ);
  524. cmDspInst_t* eqfgn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Filt Gain", 0.0, 10.0, 0.1, eqFgain);
  525. cmDspInst_t* eqpoffs = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Eq ST off", -stOffs, stOffs, 0.01, 0.0 );
  526. // Delay Controls
  527. cmDspInst_t* dlybyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Dly Byp", 0 );
  528. //cmDspInst_t* dlyms = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Time", 0.0, dlyMaxMs, 1.0, dlyMs );
  529. cmDspInst_t* dlyfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Fb", -1.0, 1.0, 0.001, dlyFb );
  530. // multi-tap controls
  531. cmDspInst_t* mtbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Mt Byp", mtBypassFl);
  532. cmDspInst_t* mtfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Feedback", 0.0, 1.0, 0.01, mtFeedback);
  533. cmDspInst_t* mtscale= cmDspSysAllocScalarP( h, pgSymId, preLbl, "Tm Scale", 0.01, 10.0, 0.01, mtTimeScale);
  534. // voice scaler
  535. cmDspInst_t* vmult = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Voc Scale", 0.0, 10.0, 0.001, voiceMult);
  536. // Compression Meters
  537. cmDspSysNewColumn(h,COL_WIDTH);
  538. cmDspSysAllocLabel(h,"Compression",kLeftAlignDuiId);
  539. cmDspInst_t** cmtr = cmDspSysAllocInstArray(h, chainChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0);
  540. // Check for allocation errors
  541. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  542. goto errLabel;
  543. // NOTE:
  544. // NOTE: ain goes to mix "in-0"
  545. // NOTE:
  546. // audio connections -
  547. cmDspSysConnectAudioN1N1(h, phs, "out", wt, "phs", chainChCnt ); // phs -> wt
  548. cmDspSysConnectAudioN1N1(h, wt, "out", mixs, "in", chainChCnt ); // wt -> mix
  549. cmDspSysConnectAudioN1N1(h, mixs, "out", mixm, "in-0", chainChCnt ); //
  550. cmDspSysConnectAudioN1N1(h, mixa, "out", mixm, "in-1", chainChCnt ); //
  551. cmDspSysConnectAudioN1N1(h, mixm, "out", loop, "in", chainChCnt ); // mix -> loop
  552. cmDspSysConnectAudioN1N1(h, loop, "out", ps, "in", chainChCnt ); // loop -> ps
  553. cmDspSysConnectAudioN1N1(h, ps, "out", cmp, "in", chainChCnt ); // ps -> cmp
  554. cmDspSysConnectAudioN1N1(h, cmp, "out", dist, "in", chainChCnt ); // cmp -> dist
  555. cmDspSysConnectAudioN1N1(h, dist, "out", cf, "in", chainChCnt ); // dist -> cf
  556. cmDspSysConnectAudioN1N1(h, cf, "out", eq, "in", chainChCnt ); // cf -> eq
  557. cmDspSysConnectAudioN1N1(h, eq, "out", dly, "in", chainChCnt ); // cf -> dly
  558. cmDspSysConnectAudioN1N1(h, dly, "out", mt, "in", chainChCnt ); // dly -> mt
  559. cmDspSysConnectAudioN11N(h, mt, "out", mixo, "in", chainChCnt ); // mt -> mixo
  560. cmDspSysInstallCb( h, start, "send", midiV, "cmd", NULL ); // force the hz value to be sent out the midV
  561. cmDspSysInstallCb1NN1( h, midiV, "out", sgpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
  562. cmDspSysInstallCb1NN1( h, midiV, "out", cfpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
  563. cmDspSysInstallCb1NN1( h, midiV, "out", eqpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
  564. //cmDspSysInstallCb11N1( h, zero, "val", mix, "gain-0", chainChCnt );
  565. //cmDspSysInstallCb11N1( h, zero, "val", mixs, "gain", chainChCnt ); // force the osc mixer to start turned off
  566. // Adssr scale/offset controls
  567. cmDspSysInstallCb11N1( h, tmul, "val", tmop, "in-1", chainChCnt );
  568. cmDspSysInstallCb11N1( h, toff, "val", toop, "in-1", chainChCnt );
  569. cmDspSysInstallCbN1N1( h, tmop, "out", toop, "in-0", chainChCnt );
  570. cmDspSysInstallCbN1N1( h, toop, "out", adsr, "tscale", chainChCnt );
  571. cmDspSysInstallCb11N1( h, amul, "val", amop, "in-1", chainChCnt );
  572. cmDspSysInstallCb11N1( h, aoff, "val", aoop, "in-1", chainChCnt );
  573. cmDspSysInstallCbN1N1( h, amop, "out", aoop, "in-0", chainChCnt );
  574. cmDspSysInstallCbN1N1( h, aoop, "out", adsr, "ascale", chainChCnt );
  575. // ADSR parameter controls
  576. cmDspSysInstallCb11N1( h, adly, "val", adsr, "dly", chainChCnt );
  577. cmDspSysInstallCb11N1( h, atk, "val", adsr, "atk", chainChCnt );
  578. cmDspSysInstallCb11N1( h, dcy, "val", adsr, "dcy", chainChCnt );
  579. cmDspSysInstallCb11N1( h, hold, "val", adsr, "hold", chainChCnt );
  580. cmDspSysInstallCb11N1( h, rls, "val", adsr, "rls", chainChCnt );
  581. cmDspSysInstallCb11N1( h, alvl, "val", adsr, "alvl", chainChCnt );
  582. cmDspSysInstallCb11N1( h, sus, "val", adsr, "sus", chainChCnt );
  583. cmDspSysInstallCbN1N1( h, adsr, "out", dtl, "in", chainChCnt ); // adsr -> dbToLin
  584. cmDspSysInstallCbN1N1( h, dtl, "out", mixs, "gain", chainChCnt ); // dbToLin -> mix (gain)
  585. // SigGen parameter controls
  586. //cmDspSysInstallCb11N1( h, start, "send", sgmul, "send", chainChCnt ); // send cur sgmul value to mul in-0
  587. //cmDspSysInstallCbN1N1( h, sgpc, "hz", mul, "in-1", chainChCnt ); // send hz value to mul in-1
  588. //cmDspSysInstallCbN1N1( h, sgmul, "val", mul, "in-0", chainChCnt );
  589. cmDspSysInstallCb11N1( h, sgpoffs, "val", sgpc, "offs", chainChCnt );
  590. //cmDspSysInstallCbN1N1( h, mul, "out", phs, "mult", chainChCnt );
  591. cmDspSysInstallCbN1N1( h, sgpc, "hz", phs, "mult", chainChCnt );
  592. cmDspSysInstallCb11N1( h, sgsh, "val", wt, "shape", chainChCnt );
  593. cmDspSysInstallCb11N1( h, sgot, "val", wt, "ot", chainChCnt );
  594. // Pitch Shift parameter controls
  595. cmDspSysInstallCb11N1( h, psbyp, "out", ps, "bypass", chainChCnt );
  596. cmDspSysInstallCb11N1( h, psrat, "val", ps, "ratio", chainChCnt );
  597. // Loop recorder parameter controls
  598. cmDspSysInstallCb11N1(h, lpByp, "out", loop, "bypass", chainChCnt );
  599. cmDspSysInstallCb11N1(h, lpRcd, "out", loop, "recd", chainChCnt );
  600. cmDspSysInstallCb11N1(h, lpRat, "val", loop, "ratio", chainChCnt );
  601. // Compressor paramter controls
  602. cmDspSysInstallCb11N1(h, cbyp, "out", cmp, "bypass", chainChCnt );
  603. cmDspSysInstallCb11N1(h, cgain, "val", cmp, "igain", chainChCnt );
  604. cmDspSysInstallCb11N1(h, cthr, "val", cmp, "thr", chainChCnt );
  605. cmDspSysInstallCb11N1(h, crat, "val", cmp, "ratio", chainChCnt );
  606. cmDspSysInstallCb11N1(h, catk, "val", cmp, "atk", chainChCnt );
  607. cmDspSysInstallCb11N1(h, crls, "val", cmp, "rls", chainChCnt );
  608. cmDspSysInstallCb11N1(h, cmkup, "val", cmp, "ogain", chainChCnt );
  609. cmDspSysInstallCb11N1(h, cwnd, "val", cmp, "wnd", chainChCnt );
  610. cmDspSysInstallCbN1N1(h, cmp, "env", cmtr, "in", chainChCnt ); // compressor meter
  611. // Distortion parameter controls
  612. cmDspSysInstallCb11N1(h, dbyp, "out", dist, "bypass",chainChCnt );
  613. cmDspSysInstallCb11N1(h, dsr, "val", dist, "srate", chainChCnt );
  614. cmDspSysInstallCb11N1(h, dbt, "val", dist, "bits", chainChCnt );
  615. cmDspSysInstallCb11N1(h, drct, "out", dist, "rect", chainChCnt );
  616. cmDspSysInstallCb11N1(h, dful, "out", dist, "full", chainChCnt );
  617. cmDspSysInstallCb11N1(h, dclip, "val", dist, "clip", chainChCnt );
  618. cmDspSysInstallCb11N1(h, dogn, "val", dist, "ogain", chainChCnt );
  619. // Comb filter parameter controls
  620. cmDspSysInstallCb11N1(h, cfbyp, "out", cf, "bypass",chainChCnt );
  621. cmDspSysInstallCb11N1(h, cfalpha, "val", cf, "alpha", chainChCnt );
  622. cmDspSysInstallCb11N1(h, cfpoffs, "val", cfpc, "offs", chainChCnt );
  623. cmDspSysInstallCbN1N1(h, cfpc, "hz", cf, "hz", chainChCnt );
  624. //cmDspSysInstallCbN1N1(h, mul, "out", cf, "hz", chainChCnt );
  625. // EQ parameter controls
  626. cmDspSysInstallCb11N1( h, eqbyp, "out", eq, "bypass", chainChCnt );
  627. cmDspSysInstallCb11N1( h, eqmode, "mode", eq, "mode", chainChCnt );
  628. cmDspSysInstallCb11N1( h, eqq, "val", eq, "Q", chainChCnt );
  629. cmDspSysInstallCb11N1( h, eqfgn, "val", eq, "gain", chainChCnt );
  630. cmDspSysInstallCb11N1( h, eqpoffs, "val", eqpc, "offs", chainChCnt );
  631. cmDspSysInstallCbN1N1( h, eqpc, "hz", eq, "f0", chainChCnt ); // chCfg -> Eq Hz
  632. //cmDspSysInstallCbN1N1( h, mul, "out", eq, "f0", chainChCnt );
  633. // Delay parameter controls
  634. cmDspSysInstallCb11N1( h, dlybyp, "out", dly, "bypass", chainChCnt );
  635. //cmDspSysInstallCb11N1( h, dlyms, "val", dly, "time", chainChCnt );
  636. cmDspSysInstallCb11N1( h, dlyfb, "val", dly, "fb", chainChCnt );
  637. cmDspSysInstallCbN1N1( h, dlyms, "val", dly, "time", chainChCnt );
  638. // Multi-tap parameter controls
  639. cmDspSysInstallCb11N1( h, mtbyp, "out", mt, "bypass", chainChCnt );
  640. cmDspSysInstallCb11N1( h, mtfb, "val", mt, "fb", chainChCnt );
  641. cmDspSysInstallCb11N1( h, mtscale, "val", mt, "scale", chainChCnt );
  642. cmDspSysInstallCb111N( h, vmult, "val", mixo, "gain", chainChCnt );
  643. errLabel:
  644. return rc;
  645. }
  646. //=====================================================================================================================
  647. typedef struct
  648. {
  649. cmDspPP_Circuit_t c;
  650. cmDspFx0_Chain_t fx;
  651. } cmDspPP_Fx0_t;
  652. cmDspRC_t _cmDspPP_Fx0Alloc(
  653. cmDspSysH_t h,
  654. _cmDspPP_Ctx_t* ctx,
  655. cmDspPP_Fx0_t* p,
  656. const cmChar_t* title,
  657. const cmChar_t* preLbl,
  658. cmDspInst_t* selChk,
  659. cmDspInst_t** ain,
  660. cmDspInst_t* ptIn )
  661. {
  662. cmDspRC_t rc;
  663. unsigned i;
  664. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  665. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
  666. _cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
  667. cmDspSysNewColumn(h,COL_WIDTH);
  668. unsigned fxChCnt = ctx->iChCnt;
  669. // make processors for each input channel
  670. if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, preLbl, "midiList", fxChCnt, &p->fx)) != kOkDspRC )
  671. goto errLabel;
  672. // make mixers for each output channel
  673. p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL,NULL, 1, fxChCnt );
  674. p->c.aoutLbl = "out";
  675. // check for allocation errors
  676. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  677. goto errLabel;
  678. cmDspSysConnectAudioN1N1(h, ain, "out", p->fx.mix, "in", ctx->iChCnt ); // ain -> sg/ain mixer
  679. cmDspSysInstallCb1NN1( h, ptIn, "b-out", p->fx.adsr, "gate", ctx->iChCnt ); // gate -> adsr
  680. cmDspSysInstallCb1NN1( h, ptIn, "f-out", p->fx.tmop, "in-0", ctx->iChCnt ); // level ->adsr (tscale)
  681. cmDspSysInstallCb1NN1( h, ptIn, "f-out", p->fx.amop, "in-0", ctx->iChCnt ); // level ->adsr (ascale)
  682. if(0)
  683. {
  684. for(i=0; i<ctx->iChCnt; ++i)
  685. {
  686. cmDspSysConnectAudio( h, ain[i], "out", p->fx.mix[ ctx->iChCnt + i], "in" ); // ain -> sg/ain mixer
  687. cmDspSysInstallCb( h, ptIn, formLabel(h,"b-out",i), p->fx.adsr[ ctx->iChCnt + i], "gate", NULL ); // gate -> adsr
  688. cmDspSysInstallCb( h, ptIn, formLabel(h,"f-out",i), p->fx.tmop[ ctx->iChCnt + i], "in-0", NULL ); // level ->adsr (tscale)
  689. cmDspSysInstallCb( h, ptIn, formLabel(h,"f-out",i), p->fx.amop[ ctx->iChCnt + i], "in-0", NULL ); // level ->adsr (ascale)
  690. }
  691. }
  692. for( i=0; i<ctx->oChCnt; ++i)
  693. {
  694. cmDspSysConnectAudioN11N(h, p->fx.mt, "out", p->c.aout[i], "in", fxChCnt ); // fx.mix -> mixer
  695. }
  696. // reset the chain - called by the master 'reset' button
  697. cmDspSysInstallCb( h, selChk, "out", p->fx.start, "send", NULL );
  698. errLabel:
  699. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  700. return rc;
  701. }
  702. //=====================================================================================================================
  703. #define cdChainCnt (5)
  704. typedef struct
  705. {
  706. const cmChar_t* preLbl;
  707. const cmChar_t* title;
  708. const cmChar_t* midiRsrc;
  709. const cmChar_t* chanRsrc;
  710. unsigned chCnt;
  711. cmDspInst_t* nom;
  712. cmDspInst_t* ogain;
  713. cmDspInst_t** mtr;
  714. cmDspInst_t** envm;
  715. unsigned* map;
  716. } cmDspPP_Cd0_Desc_t;
  717. typedef struct
  718. {
  719. cmDspPP_Circuit_t c;
  720. cmDspFx0_Chain_t ch[ cdChainCnt ];
  721. } cmDspPP_Cd0_t;
  722. cmDspRC_t _cmDspPP_Cd0Alloc(
  723. cmDspSysH_t h,
  724. _cmDspPP_Ctx_t* ctx,
  725. cmDspPP_Cd0_t* p,
  726. const cmChar_t* title,
  727. const cmChar_t* preLbl,
  728. cmDspInst_t* selChk,
  729. cmDspInst_t** ain,
  730. cmDspInst_t* ptIn )
  731. {
  732. cmDspRC_t rc = kOkDspRC;
  733. cmReal_t cdMaxTimeSpanMs = 50;
  734. cmReal_t cdMinNoteCnt = 2;
  735. cmReal_t nomXfadeMs = 25.0;
  736. unsigned i,j;
  737. cmDspPP_Cd0_Desc_t desc[] =
  738. {
  739. { "ch","Chose", "CDmidi", "CDchan", 0, NULL, NULL, NULL, NULL, NULL },
  740. { "ot","Other", "CDmidi", "CDchan", 0, NULL, NULL, NULL, NULL, NULL },
  741. { "g0","Grp0", "CD0midi", "CD0chan", 0, NULL, NULL, NULL, NULL, NULL },
  742. { "g1","Grp1", "CD1midi", "CD1chan", 0, NULL, NULL, NULL, NULL, NULL },
  743. { "ee","Else", "NONmidi", "NONchan", 0, NULL, NULL, NULL, NULL, NULL }
  744. };
  745. assert( sizeof(desc)/sizeof(desc[0]) == cdChainCnt );
  746. for(i=0; i<cdChainCnt; ++i)
  747. {
  748. // read channel index resource array
  749. if( cmDspRsrcUIntArray( h, &desc[i].chCnt, &desc[i].map, desc[i].chanRsrc, NULL ) != kOkDspRC )
  750. return cmErrMsg(ctx->err,kInvalidArgDspRC,"The chord detector channel index resource '%s' could not be read.",cmStringNullGuard(desc[i].chanRsrc));
  751. }
  752. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  753. /*
  754. cmDspInst_t* printBtn = cmDspSysAllocInst( h, "Button", "_print", 2, kButtonDuiId, 0.0);
  755. cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, p->c.circuitSymId );
  756. cmDspSysInstallCb( h, printBtn, "sym", bcast, "msg", NULL );
  757. */
  758. cmDspInst_t* cd = cmDspSysAllocInst(h, "ChordDetect", NULL, 1, "cdSel" );
  759. cmDspInst_t* ns = cmDspSysAllocInst(h, "NoteSelect", NULL, 1, ctx->iChCnt );
  760. // allocate the switching noms and gain controls
  761. for(i=0; i<cdChainCnt; ++i)
  762. {
  763. desc[i].nom = cmDspSysAllocInst( h, "NofM", NULL, 3, desc[i].chCnt, desc[i].chCnt, nomXfadeMs );
  764. desc[i].ogain = cmDspSysAllocScalar(h,formLabel(h,"Out Gn",i),0.0,10.0,0.01,1.0);
  765. }
  766. // chord detector parameters
  767. cmDspInst_t* cdSpanMs = cmDspSysAllocScalar(h,"Span Ms", 10.0,1000.0,1.0,cdMaxTimeSpanMs);
  768. cmDspInst_t* cdNoteCnt = cmDspSysAllocScalar(h,"Note Cnt", 1.0, 100.0,1.0,cdMinNoteCnt );
  769. cmDspInst_t* cdCount = cmDspSysAllocScalar(h,"Ch. Count", 0, 1, 0, 0);
  770. cmDspInst_t* nomXfade = cmDspSysAllocScalar(h,"Xfade ms", 0, 1000, 0, nomXfadeMs);
  771. cmDspInst_t* btn = cmDspSysAllocButton(h,"print",0);
  772. // note select gate meters
  773. for(j=0; j<cdChainCnt; ++j)
  774. {
  775. cmDspSysNewColumn(h,50);
  776. cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
  777. desc[j].mtr = cmDspSysAllocInstArray(h, ctx->iChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  778. }
  779. // audio output meters
  780. for(j=0; j<cdChainCnt; ++j)
  781. {
  782. cmDspSysNewColumn(h,COL_WIDTH);
  783. cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
  784. desc[j].envm = cmDspSysAllocInstArray(h,desc[j].chCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  785. }
  786. // create the fx chains
  787. for(i=0; i<cdChainCnt; ++i )
  788. {
  789. cmDspSysNewPage(h,desc[i].title);
  790. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,desc[i].title);
  791. _cmDspSys_PresetMgmt(h,desc[i].preLbl,presetGroupSymId);
  792. cmDspSysNewColumn(h,COL_WIDTH);
  793. // create an fx chain with desc[i].chCnt channels
  794. if((rc = _cmDspFx0_ChainAlloc(h, ctx->err, presetGroupSymId, desc[i].preLbl, desc[i].midiRsrc, desc[i].chCnt, p->ch + i)) != kOkDspRC )
  795. goto errLabel;
  796. }
  797. // make mixers for each chain
  798. p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, cdChainCnt );
  799. p->c.aoutLbl = "out";
  800. // check for allocation errors
  801. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  802. goto errLabel;
  803. cmDspSysInstallCb1N1N(h, ptIn, "b-out", cd, "gate", ctx->iChCnt ); // EF -> CD gate
  804. cmDspSysInstallCb1N1N(h, ptIn, "f-out", cd, "rms", ctx->iChCnt ); // EF -> CD rms
  805. cmDspSysInstallCb1N1N(h, cd, "gate", ns, "gate", ctx->iChCnt ); // CD -> NS gate
  806. cmDspSysInstallCb1N1N(h, cd, "rms", ns, "rms", ctx->iChCnt ); // CD -> NS rms
  807. cmDspSysInstallCb(h, cd, "detect", ns, "trig", NULL ); // CD -> NS trigger
  808. // chord detector paramter controls
  809. cmDspSysInstallCb(h, cdSpanMs, "val", cd, "span", NULL );
  810. cmDspSysInstallCb(h, cdNoteCnt, "val", cd, "notes", NULL );
  811. cmDspSysInstallCb(h, cd, "count", cdCount, "val", NULL );
  812. for(i=0; i<cdChainCnt; ++i)
  813. {
  814. cmDspSysInstallCb( h, nomXfade, "val", desc[i].nom, "ms", NULL );
  815. cmDspSysInstallCb1N1NM( h, ns, formLabel(h,"gate",i), ctx->iChCnt, desc[i].nom, "sel", desc[i].chCnt, desc[i].map ); // NS -> nom's (selectors)
  816. cmDspSysInstallCb1NN1 ( h, ns, formLabel(h,"gate",i), desc[i].mtr, "in", ctx->iChCnt ); // NS -> Meter
  817. cmDspSysInstallCb( h, ns, "done", desc[i].nom, "cmd", NULL ); // NS -> nom's (done triggers)
  818. cmDspSysConnectAudioN11NM( h, ain, "out", ctx->iChCnt, desc[i].nom, "a-in", desc[i].chCnt, desc[i].map ); // ain -> nom's
  819. cmDspSysInstallCb1N1NM( h, ptIn, "b-out", ctx->iChCnt, desc[i].nom, "b-in", desc[i].chCnt, desc[i].map ); // NS -> nom (gate)
  820. cmDspSysInstallCb1N1NM( h, ptIn, "f-out", ctx->iChCnt, desc[i].nom, "f-in", desc[i].chCnt, desc[i].map ); // NS -> nom (rms)
  821. cmDspSysConnectAudio1NN1(h, desc[i].nom, "a-out", p->ch[i].mix, "in", desc[i].chCnt ); // nom -> chain sg/ain mixer (audio)
  822. cmDspSysInstallCb1NN1( h, desc[i].nom, "b-out", p->ch[i].adsr, "gate", desc[i].chCnt ); // nom -> chain adsr (gate)
  823. cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].tmop, "in-0", desc[i].chCnt ); // nom -> chain adsr (tscale)
  824. cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].amop, "in-0", desc[i].chCnt ); // nom -> chain adsr (ascale)
  825. cmDspSysInstallCb( h, btn, "sym", desc[i].nom, "cmd", NULL );
  826. cmDspSysConnectAudioN1N1( h, p->ch[i].mt, "out", desc[i].envm, "in", desc[i].chCnt ); // chain aout -> mtr
  827. cmDspSysConnectAudio11N1( h, p->ch[i].mixo, "out", p->c.aout, formLabel(h,"in", i), ctx->oChCnt); // chain aout -> mix out
  828. // reset the chain - (called by the master 'reset' button)
  829. cmDspSysInstallCb( h, selChk, "out", p->ch[i].start, "send", NULL );
  830. }
  831. errLabel:
  832. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  833. return rc;
  834. }
  835. //=====================================================================================================================
  836. #define cd1ChainCnt (10)
  837. typedef struct
  838. {
  839. const cmChar_t* preLbl;
  840. const cmChar_t* title;
  841. unsigned chCnt;
  842. cmDspInst_t* nom;
  843. cmDspInst_t* ogain;
  844. cmDspInst_t** mtr;
  845. cmDspInst_t** envm;
  846. const cmChar_t* midiRsrc;
  847. unsigned* midi;
  848. const cmChar_t* chanRsrc;
  849. unsigned* chan;
  850. } cmDspPP_Cd1_Desc_t;
  851. typedef struct
  852. {
  853. cmDspPP_Circuit_t c;
  854. cmDspFx0_Chain_t ch[ cd1ChainCnt ];
  855. } cmDspPP_Cd1_t;
  856. cmDspRC_t _cmDspPP_Cd1Alloc(
  857. cmDspSysH_t h,
  858. _cmDspPP_Ctx_t* ctx,
  859. cmDspPP_Cd1_t* p,
  860. const cmChar_t* title,
  861. const cmChar_t* preLbl,
  862. cmDspInst_t* selChk,
  863. cmDspInst_t** ain,
  864. cmDspInst_t* ptIn )
  865. {
  866. cmDspRC_t rc = kOkDspRC;
  867. cmReal_t cdMaxTimeSpanMs = 50;
  868. cmReal_t cdMinNoteCnt = 2;
  869. cmReal_t nomXfadeMs = 25.0;
  870. unsigned cdNetNodeId = cmInvalidId;
  871. const cmChar_t* cdNetNodeLabel = NULL;
  872. const cmChar_t* nonCdNetNodeLabel = NULL;
  873. unsigned cdChCnt = 0;
  874. cmDspInst_t* cd = NULL;
  875. cmDspInst_t* ns = NULL;
  876. cmDspInst_t* cdSpanMs = NULL;
  877. cmDspInst_t* cdNoteCnt = NULL;
  878. cmDspInst_t* cdCount = NULL;
  879. cmDspInst_t* btn = NULL;
  880. unsigned cd1ChainCnto2 = cd1ChainCnt/2;
  881. unsigned pgSymId = cmInvalidId;
  882. unsigned i,j;
  883. cmDspPP_Cd1_Desc_t desc[] =
  884. {
  885. // resources for local (this) machine
  886. { "ch0","Ch0", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  887. { "ot0","Oth0", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  888. { "g00","Gr00", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  889. { "g01","Gr01", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  890. { "ee0","Ee00", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  891. // resources for remote (other) machine
  892. { "ch1","Ch1", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  893. { "ot1","Oth1", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  894. { "g10","Gr10", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  895. { "g11","Gr11", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
  896. { "ee1","Ee01", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
  897. };
  898. assert( (sizeof(desc)/sizeof(desc[0])) == cd1ChainCnt );
  899. // get the chord detector network node label of this machine
  900. if( cmDspRsrcString(h, &cdNetNodeLabel, "cdLocalNetNode", NULL ) != kOkDspRC )
  901. {
  902. rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The resource 'cdLocalNetNode' could not be read.");
  903. goto errLabel;
  904. }
  905. // convert the chord detector network node label to an id
  906. if( (cdNetNodeId = cmDspSysNetNodeLabelToId(h,cdNetNodeLabel)) == cmInvalidId )
  907. {
  908. rc = cmErrMsg(ctx->err,kInvalidArgDspRC,"The chord detector network node label '%s' is not valid.",cmStringNullGuard(cdNetNodeLabel));
  909. goto errLabel;
  910. }
  911. // get the label of the network node which is not running the chord detector
  912. if( cmDspRsrcString(h, &nonCdNetNodeLabel, "cdRemoteNetNode", NULL ) != kOkDspRC )
  913. {
  914. rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The resource 'cdRemoteNetNode' could not be read.");
  915. goto errLabel;
  916. }
  917. // validate the non-chord detector network node label
  918. if( cmDspSysNetNodeLabelToId(h,nonCdNetNodeLabel) == cmInvalidId )
  919. {
  920. rc = cmErrMsg(ctx->err,kInvalidArgDspRC,"The net node label '%s' is not valid.",cmStringNullGuard(nonCdNetNodeLabel));
  921. goto errLabel;
  922. }
  923. // is this the chord detector node
  924. bool cdIsLocalFl = cdNetNodeId == cmDspSysNetNodeId(h);
  925. unsigned ii = cdIsLocalFl ? 0 : cd1ChainCnto2;
  926. unsigned nn = ii + cd1ChainCnto2;
  927. // read all the resource arrays
  928. for(i=0; i<cd1ChainCnt; ++i)
  929. {
  930. desc[i].midiRsrc = cmTsPrintfH( cmDspSysLHeap(h), "nsMidi-%i",i);
  931. desc[i].chanRsrc = cmTsPrintfH( cmDspSysLHeap(h), "nsChan-%i",i);
  932. if( cmDspRsrcUIntArray(h,&desc[i].chCnt,&desc[i].midi,desc[i].midiRsrc,NULL) != kOkDspRC )
  933. {
  934. rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The note selector MIDI pitch resource '%s' could not be read.",cmStringNullGuard(desc[i].midiRsrc));
  935. goto errLabel;
  936. }
  937. if( cmDspRsrcUIntArray(h,&desc[i].chCnt,&desc[i].chan,desc[i].chanRsrc,NULL) != kOkDspRC )
  938. {
  939. rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The note selector channel map resource '%s' could not be read.",cmStringNullGuard(desc[i].chanRsrc));
  940. goto errLabel;
  941. }
  942. }
  943. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  944. if( cdIsLocalFl )
  945. {
  946. // get the count of chord detector input channels
  947. if( cmDspRsrcArrayCount(h,&cdChCnt,"ChordList",NULL) != kOkDspRC )
  948. return cmErrMsg(ctx->err,kInvalidArgDspRC,"The 'ChordList' resource could not be read.");
  949. cd = cmDspSysAllocInst(h, "ChordDetect", "cd", 1, "ChordList" );
  950. ns = cmDspSysAllocInst(h, "NetNoteSelect", "ns", 1, cdChCnt );
  951. // chord detector parameters
  952. cdSpanMs = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Span Ms", 10.0,1000.0,1.0,cdMaxTimeSpanMs);
  953. cdNoteCnt = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Note Cnt", 1.0, 100.0,1.0,cdMinNoteCnt );
  954. cdCount = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Ch. Count", 0, 1,0,0);
  955. }
  956. cmDspInst_t* nomXfade = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Xfade ms", 0, 1000, 0, nomXfadeMs);
  957. btn = cmDspSysAllocButtonP(h,preLbl,"print",0);
  958. // allocate the switching noms and gain controls
  959. for(i=ii; i<nn; ++i)
  960. {
  961. desc[i].nom = cmDspSysAllocInst( h, "NofM", formLabel(h,"nom",i), 3, desc[i].chCnt, desc[i].chCnt, nomXfadeMs );
  962. desc[i].ogain = cmDspSysAllocScalarP(h, pgSymId, preLbl, formLabel(h,"Out Gn",i),0.0,10.0,0.01,1.0);
  963. }
  964. // note-select gate meters
  965. for(j=ii; cdIsLocalFl && j<nn; ++j)
  966. {
  967. cmDspSysNewColumn(h,50);
  968. cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
  969. desc[j].mtr = cmDspSysAllocInstArray(h, cdChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  970. }
  971. // audio output meters
  972. for(j=ii; j<nn; ++j)
  973. {
  974. cmDspSysNewColumn(h,50);
  975. cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
  976. desc[j].envm = cmDspSysAllocInstArray(h,desc[j].chCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  977. }
  978. // create the fx chains
  979. for(i=ii; i<nn; ++i )
  980. {
  981. cmDspSysNewPage(h,desc[i].title);
  982. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,desc[i].title);
  983. _cmDspSys_PresetMgmt(h,desc[i].preLbl,presetGroupSymId);
  984. cmDspSysNewColumn(h,200);
  985. // create an fx chain with desc[i].chCnt channels
  986. if((rc = _cmDspFx0_ChainAlloc(h, ctx->err, presetGroupSymId, desc[i].preLbl, desc[i].midiRsrc, desc[i].chCnt, p->ch + i)) != kOkDspRC )
  987. goto errLabel;
  988. }
  989. // make mixers for each chain
  990. p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, cd1ChainCnto2 );
  991. p->c.aoutLbl = "out";
  992. // check for allocation errors
  993. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  994. goto errLabel;
  995. if( cdIsLocalFl )
  996. {
  997. cmDspSysInstallCb1N1N(h, ptIn, "b-out", cd, "gate", ctx->iChCnt ); // EF -> CD gate
  998. cmDspSysInstallCb1N1N(h, ptIn, "f-out", cd, "rms", ctx->iChCnt ); // EF -> CD rms
  999. cmDspSysInstallCb1N1N(h, cd, "gate", ns, "gate", cdChCnt ); // CD -> NS gate
  1000. cmDspSysInstallCb1N1N(h, cd, "rms", ns, "rms", cdChCnt ); // CD -> NS rms
  1001. cmDspSysInstallCb(h, cd, "detect", ns, "trig", NULL ); // CD -> NS trigger
  1002. // chord detector paramter controls
  1003. cmDspSysInstallCb(h, cdSpanMs, "val", cd, "span", NULL );
  1004. cmDspSysInstallCb(h, cdNoteCnt, "val", cd, "notes", NULL );
  1005. cmDspSysInstallCb(h, cd, "count", cdCount, "val", NULL );
  1006. }
  1007. else
  1008. {
  1009. cmDspSysInstallNetCb1N1N(h, ptIn, "b-out", cdNetNodeLabel, "cd", "gate", 16, ctx->iChCnt );
  1010. cmDspSysInstallNetCb1N1N(h, ptIn, "f-out", cdNetNodeLabel, "cd", "rms", 16, ctx->iChCnt );
  1011. }
  1012. for(i=ii; i<nn; ++i)
  1013. {
  1014. if( cdIsLocalFl )
  1015. {
  1016. // local NS -> nom's (selectors)
  1017. cmDspSysInstallCb1N1N( h, ns, formLabel(h,"gate",i), desc[i].nom, "sel", desc[i].chCnt );
  1018. cmDspSysInstallCb( h, ns, "done", desc[i].nom, "cmd", NULL ); // NS -> nom's (done triggers)
  1019. // local NS -> meters
  1020. cmDspSysInstallCb1NN1M2( h, ns, formLabel(h,"gate",i), desc[i].chCnt, desc[i].chan, desc[i].mtr, "in", cdChCnt );
  1021. }
  1022. cmDspSysConnectAudioN11NM( h, ain, "out", ctx->iChCnt, desc[i].nom, "a-in", desc[i].chCnt, desc[i].chan ); // ain -> nom's
  1023. cmDspSysInstallCb1N1NM( h, ptIn, "b-out", ctx->iChCnt, desc[i].nom, "b-in", desc[i].chCnt, desc[i].chan ); // EF -> nom (gate)
  1024. cmDspSysInstallCb1N1NM( h, ptIn, "f-out", ctx->iChCnt, desc[i].nom, "f-in", desc[i].chCnt, desc[i].chan ); // EF -> nom (level)
  1025. cmDspSysConnectAudio1NN1(h, desc[i].nom, "a-out", p->ch[i].mix, "in", desc[i].chCnt ); // nom -> chain sg/ain mixer (audio)
  1026. cmDspSysInstallCb1NN1( h, desc[i].nom, "b-out", p->ch[i].adsr, "gate", desc[i].chCnt ); // nom -> chain adsr (gate)
  1027. cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].tmop, "in-0", desc[i].chCnt ); // nom -> chain adsr (tscale)
  1028. cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].amop, "in-0", desc[i].chCnt ); // nom -> chain adsr (ascale)
  1029. cmDspSysInstallCb( h, btn, "sym", desc[i].nom, "cmd", NULL );
  1030. cmDspSysInstallCb( h, nomXfade, "val", desc[i].nom, "ms", NULL );
  1031. cmDspSysConnectAudioN1N1( h, p->ch[i].mt, "out", desc[i].envm, "in", desc[i].chCnt ); // chain aout -> mtr
  1032. cmDspSysConnectAudio11N1( h, p->ch[i].mixo, "out", p->c.aout, formLabel(h,"in", i-ii), ctx->oChCnt); // chain aout -> mix out
  1033. cmDspSysInstallCb11N1( h, desc[i].ogain, "val", p->c.aout, formLabel(h,"gain",i-ii), ctx->oChCnt); // chain ogain -> mix gain
  1034. // reset the chain - (called by the master 'reset' button)
  1035. cmDspSysInstallCb( h, selChk, "out", p->ch[i].start, "send", NULL );
  1036. }
  1037. // local note-select to remote 'nom' connections
  1038. if( cdIsLocalFl )
  1039. {
  1040. for(i=cd1ChainCnto2; i<cd1ChainCnt; ++i)
  1041. {
  1042. // NS -> nom's (selectors and done trigger)
  1043. cmDspSysInstallNetCb1N1N( h, ns, formLabel(h,"gate",i), nonCdNetNodeLabel, cmTsPrintfS("nom-%i",i), "sel", 0, desc[i].chCnt );
  1044. cmDspSysInstallNetCb( h, ns, "done", nonCdNetNodeLabel, cmTsPrintfS("nom-%i",i), "cmd" );
  1045. // NS -> meters
  1046. unsigned map[ ctx->iChCnt ];
  1047. cmVOU_AddVVS(map,ctx->iChCnt,desc[i].chan,ctx->iChCnt );
  1048. cmDspSysInstallCb1NN1M2( h, ns, formLabel(h,"gate",i), desc[i].chCnt, map, desc[i-cd1ChainCnto2].mtr, "in", cdChCnt );
  1049. }
  1050. }
  1051. errLabel:
  1052. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  1053. return rc;
  1054. }
  1055. //=====================================================================================================================
  1056. typedef struct
  1057. {
  1058. cmDspInst_t* phs;
  1059. cmDspInst_t* wt;
  1060. cmDspInst_t* sel;
  1061. cmDspInst_t* bts;
  1062. cmDspInst_t* gain;
  1063. } cmDspPP_Fp_t;
  1064. cmDspRC_t _cmDspPP_FilePlayer(
  1065. cmDspSysH_t h,
  1066. const cmChar_t* fn,
  1067. const cmChar_t* label,
  1068. cmDspPP_Fp_t* p
  1069. )
  1070. {
  1071. cmDspRC_t rc = kOkDspRC;
  1072. int wtPlayCnt = 1;
  1073. int wtMode = 1; // file
  1074. int wtBeg = 0;
  1075. int wtEnd = -1;
  1076. unsigned wtOffSymId = cmDspSysRegisterStaticSymbol(h,"off");
  1077. bool selFl = false;
  1078. p->sel = cmDspSysAllocCheck( h,label,selFl);
  1079. p->phs = cmDspSysAllocInst( h,"Phasor", NULL, 0 );
  1080. p->wt = cmDspSysAllocInst( h,"WaveTable",NULL, 7, ((int)cmDspSysSampleRate(h)), wtMode, fn, wtPlayCnt, wtBeg, wtEnd, wtOffSymId );
  1081. p->bts = cmDspSysAllocInst( h,"GateToSym", NULL, 0 );
  1082. p->gain = cmDspSysAllocScalar(h,NULL,0.0,10.0,0.01,1.0);
  1083. // check for allocation errors
  1084. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  1085. goto errLabel;
  1086. cmDspSysConnectAudio(h,p->phs,"out",p->wt,"phs");
  1087. cmDspSysInstallCb( h, p->sel, "out", p->bts, "both", NULL );
  1088. cmDspSysInstallCb( h, p->bts, "out", p->wt, "cmd", NULL );
  1089. cmDspSysInstallCb( h, p->sel, "out", p->phs, "phs", NULL );
  1090. errLabel:
  1091. return rc;
  1092. }
  1093. typedef struct
  1094. {
  1095. cmDspPP_Circuit_t c;
  1096. } cmDspPP_Sp0_t;
  1097. cmDspRC_t _cmDspPP_SmpPlayAlloc(
  1098. cmDspSysH_t h,
  1099. _cmDspPP_Ctx_t* ctx,
  1100. cmDspPP_Sp0_t* p,
  1101. const cmChar_t* title,
  1102. const cmChar_t* preLbl,
  1103. cmDspInst_t* selChk,
  1104. cmDspInst_t** ain,
  1105. cmDspInst_t* ptIn,
  1106. const cmChar_t** fnArray,
  1107. const cmChar_t** titleArray,
  1108. unsigned fnCnt )
  1109. {
  1110. cmDspRC_t rc;
  1111. unsigned i,j;
  1112. cmDspPP_Fp_t fp[ fnCnt ];
  1113. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  1114. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
  1115. _cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
  1116. cmDspSysNewColumn(h,COL_WIDTH);
  1117. // make sample players
  1118. for(i=0; i<fnCnt; ++i)
  1119. {
  1120. if((rc = _cmDspPP_FilePlayer(h, fnArray[i], titleArray[i], fp + i )) != kOkDspRC )
  1121. break;
  1122. }
  1123. // make processors for each output channel
  1124. p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, fnCnt );
  1125. p->c.aoutLbl = "out";
  1126. // check for allocation errors
  1127. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  1128. goto errLabel;
  1129. for(i=0; i<ctx->oChCnt; ++i)
  1130. for(j=0; j<fnCnt; ++j)
  1131. {
  1132. cmDspSysConnectAudio(h, fp[j].wt, "out", p->c.aout[i], formLabel(h,"in",j) );
  1133. cmDspSysInstallCb( h, fp[j].gain, "val", p->c.aout[i], formLabel(h,"gain",j), NULL);
  1134. }
  1135. errLabel:
  1136. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  1137. return rc;
  1138. }
  1139. //=====================================================================================================================
  1140. typedef struct
  1141. {
  1142. cmDspPP_Circuit_t c;
  1143. cmDspFx0_Chain_t fx0;
  1144. cmDspFx0_Chain_t fx1;
  1145. } cmDspPP_Gliss_t;
  1146. cmDspRC_t _cmDspPP_GlissAlloc(
  1147. cmDspSysH_t h,
  1148. _cmDspPP_Ctx_t* ctx,
  1149. cmDspPP_Gliss_t* p,
  1150. const cmChar_t* title,
  1151. const cmChar_t* preLbl,
  1152. cmDspInst_t* selChk,
  1153. cmDspInst_t** ain,
  1154. cmDspInst_t* ptIn )
  1155. {
  1156. cmDspRC_t rc;
  1157. const cmChar_t* glissChIdxRsrcStr = "glissChIdx";
  1158. const cmChar_t* glissPitchRsrcStr = "glissPitch";
  1159. const cmChar_t* glissSlineRsrcStr = "glissSline";
  1160. unsigned chCnt = 0;
  1161. unsigned i ;
  1162. p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
  1163. unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
  1164. _cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
  1165. cmDspSysNewColumn(h,COL_WIDTH);
  1166. p->c.aout = allocInstPtrArray(h, ctx->oChCnt);
  1167. // get the active channel list (indexes of the input channels which will be used by glisser);
  1168. if( cmDspRsrcArrayCount( h, &chCnt, glissChIdxRsrcStr, NULL ) != kOkDspRC )
  1169. return cmErrMsg(ctx->err,kPgmCfgFailDspRC,"The noise shaper channel index list '%s' could not be read.",cmStringNullGuard(glissChIdxRsrcStr));
  1170. cmDspInst_t* print = cmDspSysAllocInst( h, "Printer", NULL, 0 );
  1171. cmDspInst_t* nom = cmDspSysAllocInst( h, "NofM", NULL, 2, ctx->iChCnt, chCnt );
  1172. cmDspInst_t* pts = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "off", "send" );
  1173. cmDspInst_t* pitarr = cmDspSysAllocInst( h, "Array", NULL, 1, glissPitchRsrcStr );
  1174. cmDspInst_t* charr = cmDspSysAllocInst( h, "Array", NULL, 1, glissChIdxRsrcStr );
  1175. cmDspInst_t** gts = cmDspSysAllocInstArray( h, chCnt, "GateToSym", NULL, NULL, 0 );
  1176. cmDspInst_t** pcvt = cmDspSysAllocInstArray( h, chCnt, "PitchCvt", NULL, NULL, 0 );
  1177. cmDspInst_t** sline = allocInstPtrArray(h, chCnt);
  1178. for(i=0; i<chCnt; ++i)
  1179. sline[i] = cmDspSysAllocInst( h, "SegLine", NULL, 1, formLabel(h,glissSlineRsrcStr,i) );
  1180. if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, formLabel(h,preLbl,0), glissPitchRsrcStr, chCnt, &p->fx0)) != kOkDspRC )
  1181. goto errLabel;
  1182. cmDspSysNewPage(h,"G-Thru");
  1183. if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, formLabel(h,preLbl,1), glissPitchRsrcStr, chCnt, &p->fx1)) != kOkDspRC )
  1184. goto errLabel;
  1185. cmDspInst_t** mix = cmDspSysAllocInstArray( h, chCnt, "AMix", NULL, NULL, 1, 2 );
  1186. p->c.aout = cmDspSysAllocInstArray( h, ctx->iChCnt, "AMix", NULL, NULL, 1, chCnt );
  1187. p->c.aoutLbl = "out";
  1188. // check for allocation errors
  1189. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  1190. goto errLabel;
  1191. // selChk is the circuit selector check box in the main window
  1192. cmDspSysInstallCb( h, selChk, "out", pts, "off", NULL ); // First send 'off' to nom to clear its selector
  1193. cmDspSysInstallCb( h, selChk, "out", pts, "send", NULL ); // Second send 'send' to charr to select active ports on nom.
  1194. cmDspSysInstallCb( h, pts, "off", nom, "cmd", NULL ); // Clear the nom (all inputs are turned off)
  1195. cmDspSysInstallCb( h, pts, "send", charr, "cmd", NULL ); // Send the active channel indexes to the nom
  1196. cmDspSysInstallCb( h, pts, "send", pitarr, "cmd", NULL ); // Send the pitch values to the circuits (eq,cf,sg,..)
  1197. cmDspSysInstallCb11N1( h, pts, "send", sline, "cmd", chCnt );
  1198. cmDspSysInstallCb( h, charr, "done", nom, "cmd", NULL ); // Tell the nom when its setup is complete
  1199. cmDspSysInstallCb1N11( h, charr, "out", nom, "seli", chCnt ); // EF nom channel index selectors
  1200. cmDspSysConnectAudioN11N(h, ain, "out", nom, "a-in", ctx->iChCnt ); // ain -> nom
  1201. cmDspSysInstallCb1N1N( h, ptIn, "b-out", nom, "b-in", ctx->iChCnt ); // EF -> nom (gates)
  1202. cmDspSysInstallCb1N1N( h, ptIn, "f-out", nom, "f-in", ctx->iChCnt ); // EF -> nom (level)
  1203. cmDspSysInstallCb1NN1( h, pitarr, "out", pcvt, "midi", chCnt ); // pitch array -> pitch converter
  1204. cmDspSysInstallCb1NN1( h, nom, "b-out", gts, "on", chCnt );
  1205. cmDspSysInstallCbN1N1( h, gts, "out", sline, "trig", chCnt );
  1206. cmDspSysInstallCbN1N1( h, sline, "out", pcvt, "offs", chCnt );
  1207. cmDspSysInstallCbN1N1( h, pcvt, "ratio", p->fx0.ps,"ratio",chCnt );
  1208. cmDspSysInstallCbN111( h, sline, "out", print, "in", chCnt );
  1209. cmDspSysConnectAudio1NN1( h, nom, "a-out", p->fx0.mix, "in", chCnt ); // ain -> sg/ain mixer
  1210. cmDspSysInstallCb1NN1( h, nom, "b-out", p->fx0.adsr, "gate", chCnt ); // gate -> adsr
  1211. cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx0.tmop, "in-0", chCnt ); // level ->adsr (tscale)
  1212. cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx0.amop, "in-0", chCnt ); // level ->adsr (ascale)
  1213. cmDspSysConnectAudio1NN1( h, nom, "a-out", p->fx1.mix, "in", chCnt ); // ain -> sg/ain mixer
  1214. cmDspSysInstallCb1NN1( h, nom, "b-out", p->fx1.adsr, "gate", chCnt ); // gate -> adsr
  1215. cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx1.tmop, "in-0", chCnt ); // level ->adsr (tscale)
  1216. cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx1.amop, "in-0", chCnt ); // level ->adsr (ascale)
  1217. cmDspSysConnectAudioN1N1( h, p->fx0.mt, "out", mix, "in-0", chCnt );
  1218. cmDspSysConnectAudioN1N1( h, p->fx1.mt, "out", mix, "in-1", chCnt );
  1219. for( i=0; i<ctx->oChCnt; ++i)
  1220. {
  1221. cmDspSysConnectAudioN11N(h, mix, "out", p->c.aout[i], "in", chCnt );
  1222. }
  1223. // reset the chain - called by the master 'reset' button
  1224. cmDspSysInstallCb( h, selChk, "out", p->fx0.start, "send", NULL );
  1225. cmDspSysInstallCb( h, selChk, "out", p->fx1.start, "send", NULL );
  1226. errLabel:
  1227. cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
  1228. return rc;
  1229. }
  1230. //=====================================================================================================================
  1231. _cmDspPP_CircDesc_t _cmDspPP_CircDescArray[] =
  1232. {
  1233. { "Test"," tc" },
  1234. { "N Shaper", "ns" },
  1235. { "Fx0", "fx0" },
  1236. { "Smp Play", "sp" },
  1237. { "CD", "cd" },
  1238. { "Net CD", "ncd" },
  1239. { "Gliss", "gss" }
  1240. };
  1241. unsigned _cmDspPP_CircuitDescCount()
  1242. {
  1243. return sizeof(_cmDspPP_CircDescArray)/sizeof(_cmDspPP_CircDescArray[0]);
  1244. }
  1245. const _cmDspPP_CircDesc_t* _cmDspPP_CircuitDesc( unsigned idx )
  1246. {
  1247. assert(idx < _cmDspPP_CircuitDescCount());
  1248. return _cmDspPP_CircDescArray + idx;
  1249. }
  1250. cmDspRC_t _cmDspPP_CircuitSwitchAlloc(
  1251. cmDspSysH_t h,
  1252. _cmDspPP_Ctx_t* ctx,
  1253. cmDspPP_CircuitSwitch_t* p,
  1254. cmDspInst_t* reset,
  1255. cmDspInst_t** sel,
  1256. cmDspInst_t** ain,
  1257. cmDspInst_t** ef )
  1258. {
  1259. cmDspRC_t rc = kOkDspRC;
  1260. double xfadeMs = 50.0;
  1261. unsigned enaSym = cmDspSysRegisterStaticSymbol(h,"_enable");
  1262. unsigned disSym = cmDspSysRegisterStaticSymbol(h,"_disable");
  1263. unsigned i;
  1264. cmDspPP_TestCircuit_t Tst; memset(&Tst,0,sizeof(Tst));
  1265. cmDspPP_NSh_Circuit_t NSh; memset(&NSh,0,sizeof(NSh));
  1266. cmDspPP_Fx0_t Fx0; memset(&Fx0,0,sizeof(Fx0));
  1267. cmDspPP_Cd0_t Cd0; memset(&Cd0,0,sizeof(Cd0));
  1268. cmDspPP_Cd1_t Cd1; memset(&Cd1,0,sizeof(Cd1));
  1269. cmDspPP_Sp0_t Sp0; memset(&Sp0,0,sizeof(Sp0));
  1270. cmDspPP_Gliss_t Gls; memset(&Gls,0,sizeof(Gls));
  1271. const cmChar_t* spFnArr[] =
  1272. {
  1273. "/home/kevin/media/audio/PP/Siren Blast 2 Peaking.wav",
  1274. "/home/kevin/media/audio/PP/Siren Blast 2.wav"
  1275. };
  1276. const cmChar_t* spLblArr[] =
  1277. {
  1278. "File 0",
  1279. "File 1"
  1280. };
  1281. unsigned spCnt = sizeof(spFnArr) / sizeof(spFnArr[0]);
  1282. unsigned splCnt = sizeof(spLblArr) / sizeof(spLblArr[0]);
  1283. assert( spCnt == splCnt );
  1284. p->circuitCnt = _cmDspPP_CircuitDescCount();
  1285. cmDspInst_t* ofd[ p->circuitCnt ];
  1286. cmDspPP_Circuit_t* carr[ p->circuitCnt ];
  1287. cmDspInst_t** mxm = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  1288. for(i = 0; rc==kOkDspRC && i<p->circuitCnt; ++i)
  1289. {
  1290. const cmChar_t* title = _cmDspPP_CircDescArray[i].title;
  1291. const cmChar_t* preLbl = _cmDspPP_CircDescArray[i].preLbl;
  1292. cmDspSysNewPage(h, title );
  1293. carr[i] = NULL;
  1294. // allocate the input switches for this circuit
  1295. cmDspInst_t* bts = cmDspSysAllocInst(h,"GateToSym", NULL, 0 );
  1296. cmDspInst_t* bts_ena = cmDspSysAllocInst(h,"GateToSym", NULL, 2, enaSym, disSym );
  1297. cmDspInst_t* ipt = cmDspSysAllocInst(h,"NofM", NULL, 2, ctx->iChCnt, ctx->iChCnt );
  1298. // allocate the circuits
  1299. switch( i )
  1300. {
  1301. case 0:
  1302. if((rc = _cmDspPP_TestCircuitAlloc(h,ctx,&Tst,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
  1303. carr[i] = &Tst.c;
  1304. break;
  1305. case 1:
  1306. if((rc = _cmDspPP_NoiseShaperAlloc(h,ctx->err,&NSh,title,preLbl,sel[i],ipt,ctx->iChCnt,ctx->oChCnt)) == kOkDspRC )
  1307. carr[i] = &NSh.c;
  1308. break;
  1309. case 2:
  1310. if((rc =_cmDspPP_Fx0Alloc(h,ctx,&Fx0,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
  1311. carr[i] = &Fx0.c;
  1312. break;
  1313. case 3:
  1314. if((rc =_cmDspPP_SmpPlayAlloc(h,ctx,&Sp0,title,preLbl,sel[i],ain,ipt,spFnArr,spLblArr,spCnt)) == kOkDspRC )
  1315. carr[i] = &Sp0.c;
  1316. break;
  1317. case 4:
  1318. if((rc =_cmDspPP_Cd0Alloc(h,ctx,&Cd0,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
  1319. carr[i] = &Cd0.c;
  1320. break;
  1321. case 5:
  1322. if((rc = _cmDspPP_Cd1Alloc(h,ctx,&Cd1,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
  1323. carr[i] = &Cd1.c;
  1324. break;
  1325. case 6:
  1326. if((rc = _cmDspPP_GlissAlloc(h,ctx,&Gls,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
  1327. carr[i] = &Gls.c;
  1328. break;
  1329. default:
  1330. { assert(0); }
  1331. }
  1332. if( rc == kOkDspRC && carr[i] != NULL )
  1333. {
  1334. printf("title:%s circuit sym id:%i\n",title,carr[i]->circuitSymId);
  1335. cmDspInst_t* pts_dis = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "_disable");
  1336. cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, carr[i]->circuitSymId );
  1337. ofd[i] = cmDspSysAllocInst( h, "Xfader", NULL, 2, ctx->oChCnt, xfadeMs );
  1338. cmDspSysNewColumn(h,COL_WIDTH);
  1339. cmDspInst_t** fdm = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
  1340. // check for allocation errors
  1341. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  1342. goto errLabel;
  1343. cmDspSysConnectAudio1NN1( h, ofd[i], "out", fdm, "in", ctx->oChCnt ); // fdr -> meter
  1344. cmDspSysInstallCb( h, sel[i], "out", bts, "both", NULL ); // Convert circuit selection gate to 'on'/'off' symbols
  1345. cmDspSysInstallCb( h, bts, "out", ipt, "cmd", NULL ); // send 'on'/'off' to this circuits Gate/RMS switch
  1346. cmDspSysInstallCb( h, sel[i], "out", bts_ena, "both", NULL ); // Convert circuit selection gate to '_enable/_disable' symbols
  1347. cmDspSysInstallCb( h, bts_ena,"out", bcast, "msg", NULL ); // send '_enable/_disable' to this circuits instances.
  1348. cmDspSysInstallCb( h, reset, "out", pts_dis, "_disable",NULL ); // Convert 'reset' button output to '_disable' symbol
  1349. cmDspSysInstallCb( h, ofd[i], "off", pts_dis, "_disable",NULL ); // Convert circuit output fader 'off' event to '_disable' symbol.
  1350. cmDspSysInstallCb( h, pts_dis,"out", bcast, "msg", NULL ); // Bcast _disable symbol generated from 'reset' btn or fader 'off'
  1351. cmDspSysInstallCb( h, sel[i], "out", ofd[i], "mgate", NULL ); // Convert circuit selection gate to master fader gate 'on'/'off' msg's
  1352. cmDspSysInstallCbN11N( h, ef, "gate", ipt, "b-in", ctx->iChCnt ); // EF -> circuit (gate) pass-through
  1353. cmDspSysInstallCbN11N( h, ef, "level", ipt, "f-in", ctx->iChCnt ); // EF -> circuit (RMS) pass-through
  1354. }
  1355. }
  1356. p->omix = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMix",NULL,NULL,1,p->circuitCnt);
  1357. // check for allocation errors
  1358. if(rc!=kOkDspRC || (rc = cmDspSysLastRC(h)) != kOkDspRC )
  1359. goto errLabel;
  1360. for(i=0; i<p->circuitCnt; ++i)
  1361. {
  1362. unsigned j;
  1363. for(j=0; j<ctx->oChCnt; ++j)
  1364. if( carr[i] != NULL && carr[i]->aout != NULL && carr[i]->aout[j] != NULL )
  1365. {
  1366. // circuit-> out fader
  1367. cmDspSysConnectAudio( h, carr[i]->aout[j], carr[i]->aoutLbl, ofd[i], cmDspSysPrintLabel("in",j) );
  1368. // out fader -> mixer
  1369. cmDspSysConnectAudio( h, ofd[i], cmDspSysPrintLabel("out",j), p->omix[j], cmDspSysPrintLabel2("in",i) );
  1370. }
  1371. }
  1372. cmDspSysConnectAudioN1N1( h, p->omix, "out", mxm, "in", ctx->oChCnt ); // mix -> meters
  1373. errLabel:
  1374. return rc;
  1375. }
  1376. cmDspRC_t _cmDspPP_CircuitSwitchFree( cmDspSysH_t h, cmDspPP_CircuitSwitch_t* p)
  1377. {
  1378. return kOkDspRC;
  1379. }