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

cmDspPgmPPMain.c 76KB

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