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

cmDspPgmKrTimeLineLiteAf.c 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. //( { file_desc:"'snap' Performance analysis Simplified Time Line program." kw:[snap]}
  2. #include "cmPrefix.h"
  3. #include "cmGlobal.h"
  4. #include "cmFloatTypes.h"
  5. #include "cmRpt.h"
  6. #include "cmErr.h"
  7. #include "cmCtx.h"
  8. #include "cmMem.h"
  9. #include "cmMallocDebug.h"
  10. #include "cmLinkedHeap.h"
  11. #include "cmText.h"
  12. #include "cmFileSys.h"
  13. #include "cmSymTbl.h"
  14. #include "cmJson.h"
  15. #include "cmPrefs.h"
  16. #include "cmDspValue.h"
  17. #include "cmMsgProtocol.h"
  18. #include "cmThread.h"
  19. #include "cmUdpPort.h"
  20. #include "cmUdpNet.h"
  21. #include "cmSerialPort.h"
  22. #include "cmTime.h"
  23. #include "cmAudioSys.h"
  24. #include "cmProcObj.h"
  25. #include "cmDspCtx.h"
  26. #include "cmDspClass.h"
  27. #include "cmDspSys.h"
  28. #include "cmDspPgm.h"
  29. #include "cmAudioFile.h"
  30. #include "cmProcObj.h"
  31. #include "cmProc.h"
  32. #include "cmProc3.h"
  33. #include "cmVectOpsTemplateMain.h"
  34. #include "cmVectOps.h"
  35. #include "cmDspPgmKrChain.h"
  36. //)
  37. //( { label:cmDspPgm_TimeLineLite file_desc:"Simplified score vs. the performance and generating related audio transforms." kw:[spgm] }
  38. cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
  39. {
  40. cmDspRC_t rc = kOkDspRC;
  41. cmCtx_t* cmCtx = cmDspSysPgmCtx(h);
  42. cmErr_t err;
  43. krRsrc_t r;
  44. unsigned sfBufCnt = 7; // length of the MIDI event buffer
  45. unsigned sfMaxWndCnt = 10; // length of the score event buffer
  46. unsigned sfMinVel = 5; // ignore MIDI events below this velocity
  47. bool sfEnaMeasFl = true;
  48. memset(&r,0,sizeof(r));
  49. cmErrSetup(&err,&cmCtx->rpt,"Kr TimelineLite");
  50. if( krLoadRsrc(h,&err,&r) != kOkDspRC )
  51. return rc;
  52. //int baseAudioInCh = 0; // 2;
  53. int baseAudioOutCh = 0;// 2;
  54. cmDspInst_t* tlp = cmDspSysAllocInst(h,"TimeLine", "tl", 2, r.tlFn, r.tlPrefixPath );
  55. cmDspInst_t* scp = cmDspSysAllocInst(h,"Score", "sc", 1, r.scFn );
  56. cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 2, "on", "off" );
  57. cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 0 );
  58. cmDspInst_t* wt0 = cmDspSysAllocInst(h,"WaveTable", NULL, 7, ((int)cmDspSysSampleRate(h)), 1, NULL, -1, 0, -1, 0 );
  59. cmDspInst_t* wt1 = cmDspSysAllocInst(h,"WaveTable", NULL, 7, ((int)cmDspSysSampleRate(h)), 1, NULL, -1, 0, -1, 1 );
  60. cmDspInst_t* mfp = cmDspSysAllocInst(h,"MidiFilePlay",NULL, 0 );
  61. cmDspInst_t* nmp = cmDspSysAllocInst(h,"NanoMap", NULL, 0 );
  62. cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 5, r.scFn, sfBufCnt, sfMaxWndCnt, sfMinVel, sfEnaMeasFl );
  63. cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 );
  64. cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" );
  65. cmDspInst_t* its = cmDspSysAllocInst(h,"IntToSym", NULL, 2, 0, "off");
  66. unsigned preGrpSymId = cmDspSysPresetRegisterGroup(h,"tl");
  67. unsigned cmpPreGrpSymId = cmDspSysPresetRegisterGroup(h,"tl_cmp");
  68. cmDspTlXform_t c0,c1;
  69. cmDspSysNewPage(h,"Controls-0");
  70. _cmDspSys_TlXformChain(h, &c0, preGrpSymId, cmpPreGrpSymId, amp, modp, 0, 0 );
  71. cmDspSysNewPage(h,"Controls-1");
  72. _cmDspSys_TlXformChain(h, &c1, preGrpSymId, cmpPreGrpSymId, amp, modp, 1, 1 );
  73. cmDspInst_t* lmix = cmDspSysAllocInst(h, "AMix", NULL, 1, 2 );
  74. cmDspInst_t* rmix = cmDspSysAllocInst(h, "AMix", NULL, 1, 2 );
  75. cmDspInst_t* ao0 = cmDspSysAllocInst(h,"AudioOut", NULL, 1, baseAudioOutCh+0 );
  76. cmDspInst_t* ao1 = cmDspSysAllocInst(h,"AudioOut", NULL, 1, baseAudioOutCh+1 );
  77. cmDspSysNewPage(h,"Main");
  78. //cmDspInst_t* notesOffb= cmDspSysAllocInst(h,"Button", "notesOff", 2, kButtonDuiId, 1.0 );
  79. cmDspInst_t* onb = cmDspSysAllocInst(h,"Button", "start", 2, kButtonDuiId, 1.0 );
  80. cmDspInst_t* offb = cmDspSysAllocInst(h,"Button", "stop", 2, kButtonDuiId, 1.0 );
  81. cmDspInst_t* mod_sel = cmDspSysAllocMsgList(h, NULL, "mod_sel", 1 );
  82. cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL, 1, ">" );
  83. cmDspInst_t* prd = cmDspSysAllocInst(h,"Printer", NULL, 1, "DYNM:" );
  84. cmDspInst_t* pre = cmDspSysAllocInst(h,"Printer", NULL, 1, "EVEN:" );
  85. cmDspInst_t* prt = cmDspSysAllocInst(h,"Printer", NULL, 1, "TMPO:");
  86. cmDspInst_t* prc = cmDspSysAllocInst(h,"Printer", NULL, 1, "COST:");
  87. // Record <-> Live switches
  88. cmDspInst_t* tlRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0); // time line swich
  89. cmDspInst_t* mfpRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0);
  90. //cmDspSysNewColumn(h,0);
  91. cmDspInst_t* ogain0 = cmDspSysAllocInst(h,"Scalar", "Dry Out Gain-0", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  92. cmDspInst_t* ogain1 = cmDspSysAllocInst(h,"Scalar", "Dry Out Gain-1", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  93. cmDspInst_t* ogain2 = cmDspSysAllocInst(h,"Scalar", "Wet Out Gain-2", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  94. cmDspInst_t* ogain3 = cmDspSysAllocInst(h,"Scalar", "Wet Out Gain-3", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  95. cmDspInst_t* ogainW = cmDspSysAllocInst(h,"Scalar", "Wet Master", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  96. cmDspInst_t* ogainD = cmDspSysAllocInst(h,"Scalar", "Dry Master", 5, kNumberDuiId, 0.0, 10.0,0.01, 1.0 );
  97. cmDspInst_t* gmult0 = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  98. cmDspInst_t* gmult1 = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  99. cmDspInst_t* gmult2 = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  100. cmDspInst_t* gmult3 = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
  101. // Audio file recording
  102. cmDspInst_t* recdGain= cmDspSysAllocInst(h,"Scalar", "Recd Gain", 5, kNumberDuiId, 0.0, 100.0,0.01, 1.5 );
  103. cmDspInst_t* recdChk = cmDspSysAllocInst(h,"Button", "Record", 2, kCheckDuiId, 0.0 );
  104. cmDspInst_t* recdPtS = cmDspSysAllocInst(h,"GateToSym", NULL, 2, cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"open"),cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"close"));
  105. cmDspInst_t* afop = cmDspSysAllocInst(h,"AudioFileOut",NULL, 2, r.recordDir,2);
  106. cmDspInst_t* mi0p = cmDspSysAllocInst(h,"AMeter","In 0", 0);
  107. cmDspInst_t* mi1p = cmDspSysAllocInst(h,"AMeter","In 1", 0);
  108. cmDspInst_t* meas = cmDspSysAllocInst(h,"Scalar", "Begin Meas", 5, kNumberDuiId, 1.0, 1000.0, 1.0, 1.0 );
  109. cmDspInst_t* emeas = cmDspSysAllocInst(h,"Scalar", "End Meas", 5, kNumberDuiId, 1.0, 1000.0, 1.0, 1.0 );
  110. cmDspSysInstallCb( h, meas, "val", scp, "meas", NULL);
  111. cmDspSysInstallCb( h, meas, "val", tlp, "meas", NULL);
  112. //--------------- Preset controls
  113. cmDspSysNewColumn(h,0);
  114. cmDspInst_t* preset = cmDspSysAllocInst( h, "Preset", NULL, 1, preGrpSymId );
  115. cmDspInst_t* presetLbl = cmDspSysAllocInst( h, "Text", "Preset", 1, "" );
  116. cmDspInst_t* storeBtn = cmDspSysAllocButton( h, "store", 0);
  117. cmDspInst_t* recallBtn = cmDspSysAllocButton( h, "recall", 0);
  118. cmDspSysInstallCb( h, presetLbl, "val", preset, "label",NULL);
  119. cmDspSysInstallCb( h, storeBtn, "sym", preset, "cmd", NULL );
  120. cmDspSysInstallCb( h, recallBtn, "sym", preset, "cmd", NULL );
  121. cmDspInst_t* prePath = cmDspSysAllocInst( h, "Fname", "prePath", 3, true,NULL,r.tlPrefixPath);
  122. //cmDspSysNewColumn(h,0);
  123. //--------------- Recorded performance evaluation and Active Measurement related controls
  124. cmDspInst_t* clrBtn = cmDspSysAllocButton( h, "clear", 0);
  125. cmDspInst_t* prtBtn = cmDspSysAllocButton( h, "dump", 0);
  126. cmDspInst_t* amCmd = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "add", "rewind" );
  127. if((rc = cmDspSysLastRC(h)) != kOkDspRC )
  128. return rc;
  129. // Output Audio file recording.
  130. cmDspSysInstallCb(h, recdGain,"val", afop, "gain0", NULL );
  131. cmDspSysInstallCb(h, recdGain,"val", afop, "gain1", NULL );
  132. cmDspSysInstallCb(h, recdChk, "out", recdPtS, "on", NULL );
  133. cmDspSysInstallCb(h, recdChk, "out", recdPtS, "off", NULL );
  134. cmDspSysInstallCb(h, recdPtS, "out", afop, "sel", NULL );
  135. // Audio connections
  136. cmDspSysConnectAudio(h, php, "out", wt0, "phs" ); // phasor -> wave table
  137. cmDspSysConnectAudio(h, php, "out", wt1, "phs" ); //
  138. cmDspSysConnectAudio(h, wt0, "out", lmix, "in-0" ); // wave table -> audio out (dry output)
  139. cmDspSysConnectAudio(h, wt1, "out", rmix, "in-0" ); //
  140. //cmDspSysConnectAudio(h, wt0, "out", lmix, "in-1" ); // wave table -> audio out (dry output)
  141. //cmDspSysConnectAudio(h, wt1, "out", rmix, "in-1" ); //
  142. cmDspSysConnectAudio( h, wt0, "out", mi0p, "in" ); //
  143. cmDspSysConnectAudio( h, wt0, "out", c0.kr0, "in" ); // ain -> ch0.kr0
  144. cmDspSysConnectAudio( h, wt0, "out", c0.kr1, "in" ); // ain -> ch0.kr1
  145. cmDspSysConnectAudio( h, c0.cmp,"out", lmix, "in-1" ); // ch0.cmp -> aout
  146. cmDspSysConnectAudio( h, c0.cmp,"out", afop, "in0"); // ch0.cmp -> audio_file_out
  147. cmDspSysConnectAudio( h, wt1, "out", mi1p, "in" ); //
  148. cmDspSysConnectAudio( h, wt1, "out", c1.kr0, "in" ); // ain -> ch1.kr0
  149. cmDspSysConnectAudio( h, wt1, "out", c1.kr1, "in" ); // ain -> ch1.kr1
  150. cmDspSysConnectAudio( h, c1.cmp,"out", rmix, "in-1" ); // ch1.cmp -> aout
  151. cmDspSysConnectAudio( h, c1.cmp,"out", afop, "in1"); // ch1.cmp ->audio_file_out
  152. cmDspSysConnectAudio( h, lmix, "out", ao0, "in" );
  153. cmDspSysConnectAudio( h, rmix, "out", ao1, "in" );
  154. cmDspSysInstallCb( h, clrBtn, "sym", amp, "cmd", NULL ); // clear active meas.
  155. cmDspSysInstallCb( h, prtBtn, "sym", modp, "cmd", NULL ); // print active meas
  156. //cmDspSysInstallCb( h, prtBtn, "sym", scp, "cmd", NULL ); // print the score
  157. cmDspSysInstallCb( h, amCmd, "add", amp, "cmd", NULL ); // add active meas
  158. cmDspSysInstallCb( h, amCmd, "rewind", amp, "cmd", NULL ); // rewind active meas
  159. //cmDspSysInstallCb( h, sfp, "out", amRt, "f-in", NULL ); // sfp-active meas router (rtr is switched by live btn)
  160. //cmDspSysInstallCb( h, amRt, "f-out-0",amp, "sfloc", NULL );
  161. cmDspSysInstallCb( h, sfp, "out", amp, "sfloc", NULL );
  162. cmDspSysInstallCb( h, sfp, "vloc", amp, "loc", NULL ); // live meas's to active meas unit
  163. cmDspSysInstallCb( h, sfp, "vval", amp, "val", NULL ); //
  164. cmDspSysInstallCb( h, sfp, "vcost",amp, "cst", NULL ); //
  165. cmDspSysInstallCb( h, sfp, "vtyp", amp, "type", NULL ); //
  166. cmDspSysInstallCb( h, sfp, "vtyp", amCmd, "add", NULL); //
  167. // ***** delete this to prevent the score follower from driving the active-measure unit in 'live' mode
  168. //cmDspSysInstallCb( h, amRt, "f-out-1",amp, "sfloc", NULL );
  169. // *****
  170. // active measure loc to xfad channel trigger
  171. /*
  172. cmDspSysInstallCb( h, amp, "scloc",c0.achan, "trig", NULL ); // See Also: modp.sw ->achan.trig
  173. cmDspSysInstallCb( h, amp, "scloc",c1.achan, "trig", NULL );
  174. cmDspSysInstallCb( h, recallBtn, "sym", c0.achan, "trig", NULL );
  175. cmDspSysInstallCb( h, recallBtn, "sym", c1.achan, "trig", NULL );
  176. */
  177. cmDspSysInstallCb( h, amp, "even", pre, "in", NULL ); // active meas output to printers
  178. cmDspSysInstallCb( h, amp, "even", modp, "even", NULL );
  179. cmDspSysInstallCb( h, amp, "dyn", prd, "in", NULL );
  180. cmDspSysInstallCb( h, amp, "dyn", modp, "dyn", NULL );
  181. cmDspSysInstallCb( h, amp, "tempo", prt, "in", NULL );
  182. cmDspSysInstallCb( h, amp, "tempo", modp, "tempo",NULL );
  183. cmDspSysInstallCb( h, amp, "cost", prc, "in", NULL );
  184. cmDspSysInstallCb( h, amp, "cost", modp, "cost", NULL );
  185. /*
  186. cmDspSysInstallCb( h, sfp, "vloc", pre, "in", NULL ); // live meas's to active meas unit
  187. cmDspSysInstallCb( h, sfp, "vval", prd, "in", NULL ); //
  188. cmDspSysInstallCb( h, sfp, "vcost",prt, "in", NULL ); //
  189. cmDspSysInstallCb( h, sfp, "vtyp", prc, "in", NULL ); //
  190. */
  191. // wave-table to time-line cursor
  192. cmDspSysInstallCb( h, wt0, "fidx",tlp, "curs", NULL);
  193. cmDspSysInstallCb(h, prePath, "out", tlp, "path", NULL );
  194. //cmDspSysInstallCb(h, notesOffb, "sym", pic, "alloff", NULL );
  195. // start connections
  196. cmDspSysInstallCb(h, onb, "sym", tlRt, "s-in", NULL );
  197. cmDspSysInstallCb(h, tlRt, "s-out-0",tlp, "reset", NULL );
  198. cmDspSysInstallCb(h, onb, "sym", scp, "send", NULL );
  199. cmDspSysInstallCb(h, onb, "sym", mfpRt,"s-in", NULL );
  200. cmDspSysInstallCb(h, mfpRt,"s-out-0",mfp, "sel", NULL );
  201. cmDspSysInstallCb(h, onb, "sym", pts, "on", NULL );
  202. cmDspSysInstallCb(h, pts, "on", wt0, "cmd", NULL );
  203. cmDspSysInstallCb(h, pts, "on", wt1, "cmd", NULL );
  204. cmDspSysInstallCb(h, pts, "on", modp, "cmd", NULL );
  205. cmDspSysInstallCb(h, onb, "sym", amCmd, "rewind", NULL );
  206. cmDspSysInstallCb(h, onb, "out", c0.achan,"reset", NULL );
  207. cmDspSysInstallCb(h, onb, "out", c1.achan,"reset", NULL );
  208. cmDspSysInstallCb(h, mod_sel,"out", modp, "sel", NULL );
  209. // stop connections
  210. cmDspSysInstallCb(h, tlp, "mfn", pts, "off", NULL ); // Prevents WT start on new audio file from TL.
  211. cmDspSysInstallCb(h, offb, "sym", mfp, "sel", NULL );
  212. cmDspSysInstallCb(h, offb, "sym", pts, "off", NULL );
  213. cmDspSysInstallCb(h, pts, "off", wt0, "cmd", NULL );
  214. cmDspSysInstallCb(h, pts, "off", wt1, "cmd", NULL );
  215. cmDspSysInstallCb(h, pts, "off", modp,"cmd", NULL );
  216. // time-line to MIDI file player selection
  217. cmDspSysInstallCb(h, tlp, "mbsi", mfp, "bsi", NULL );
  218. cmDspSysInstallCb(h, tlp, "mesi", mfp, "esi", NULL );
  219. cmDspSysInstallCb(h, tlp, "mfn", mfp, "fn", NULL );
  220. // time-line to Audio file player selection
  221. cmDspSysInstallCb(h, tlp, "absi", wt0, "beg", NULL );
  222. cmDspSysInstallCb(h, tlp, "aesi", wt0, "end", NULL );
  223. cmDspSysInstallCb(h, tlp, "afn", wt0, "fn", NULL );
  224. cmDspSysInstallCb(h, tlp, "absi", wt1, "beg", NULL );
  225. cmDspSysInstallCb(h, tlp, "aesi", wt1, "end", NULL );
  226. cmDspSysInstallCb(h, tlp, "afn", wt1, "fn", NULL );
  227. // score to score follower - to set initial search location
  228. cmDspSysInstallCb(h, scp, "sel", sfp, "index", NULL );
  229. cmDspSysInstallCb(h, scp, "sel", modp,"reset", NULL );
  230. cmDspSysInstallCb(h, scp, "sel", prp, "in", NULL );
  231. cmDspInst_t* msrc = mfp; // switch MIDI source (mfp or mip)
  232. // MIDI file player to score follower and sampler
  233. cmDspSysInstallCb(h, msrc, "smpidx", sfp, "smpidx",NULL );
  234. //cmDspSysInstallCb(h, mfp, "id", sfp, "muid", NULL );
  235. cmDspSysInstallCb(h, msrc, "d1", sfp, "d1", NULL );
  236. cmDspSysInstallCb(h, msrc, "d1", nmp, "d1", NULL );
  237. cmDspSysInstallCb(h, msrc, "d0", sfp, "d0", NULL );
  238. cmDspSysInstallCb(h, msrc, "d0", nmp, "d0", NULL );
  239. cmDspSysInstallCb(h, msrc, "status", sfp, "status",NULL );
  240. cmDspSysInstallCb(h, msrc, "status", nmp, "status",NULL );
  241. // score follower to recd_play,modulator and printers
  242. cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL );
  243. cmDspSysInstallCb(h, sfp, "recent", prp, "in", NULL ); // report 'recent' but only act on 'max' loc index
  244. cmDspSysInstallCb( h, emeas, "val", its, "off-int", NULL);
  245. cmDspSysInstallCb( h, sfp, "out", its, "in", NULL);
  246. cmDspSysInstallCb( h, its, "out", offb, "in", NULL);
  247. cmDspSysInstallCb( h, its, "out", prp, "in", NULL);
  248. cmDspSysInstallCb(h, modp, "dgain0", ogain0, "val", NULL );
  249. cmDspSysInstallCb(h, modp, "dgain1", ogain1, "val", NULL );
  250. cmDspSysInstallCb(h, modp, "wgain0", ogain2, "val", NULL );
  251. cmDspSysInstallCb(h, modp, "wgain1", ogain3, "val", NULL );
  252. cmDspSysInstallCb(h, ogain0, "val", gmult0, "in-0", NULL );
  253. cmDspSysInstallCb(h, ogainD, "val", gmult0, "in-1", NULL );
  254. cmDspSysInstallCb(h, ogain1, "val", gmult1, "in-0", NULL );
  255. cmDspSysInstallCb(h, ogainD, "val", gmult1, "in-1", NULL );
  256. cmDspSysInstallCb(h, ogain2, "val", gmult2, "in-0", NULL );
  257. cmDspSysInstallCb(h, ogainW, "val", gmult2, "in-1", NULL );
  258. cmDspSysInstallCb(h, ogain3, "val", gmult3, "in-0", NULL );
  259. cmDspSysInstallCb(h, ogainW, "val", gmult3, "in-1", NULL );
  260. cmDspSysInstallCb(h, gmult0, "out", lmix, "gain-0", NULL ); // output gain control - dry 0
  261. cmDspSysInstallCb(h, gmult1, "out", rmix, "gain-0", NULL ); // dry 1
  262. cmDspSysInstallCb(h, gmult2, "out", lmix, "gain-1", NULL ); // wet 0
  263. cmDspSysInstallCb(h, gmult3, "out", rmix, "gain-1", NULL ); // wet 1
  264. return rc;
  265. }
  266. //------------------------------------------------------------------------------
  267. //)