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

cmDspPgmPPMain.c 76KB

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. }