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

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