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

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