You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1012 lines
29KB

  1. #include "mscHack.hpp"
  2. //#include "mscHack_Controls.hpp"
  3. #include "dsp/digital.hpp"
  4. //#include "CLog.h"
  5. namespace rack_plugin_mscHack {
  6. #define PATTERNS 16
  7. #define STEPS 16
  8. #define CHANNELS 3
  9. #define LIGHT_LAMBDA ( 0.065f )
  10. #define CHANNEL_OFF_H 91
  11. //-----------------------------------------------------
  12. // Module Definition
  13. //
  14. //-----------------------------------------------------
  15. struct Seq_3x16x16 : Module
  16. {
  17. enum ParamIds
  18. {
  19. PARAM_RAND,
  20. PARAM_CPY_NEXT = PARAM_RAND + CHANNELS,
  21. PARAM_RUN = PARAM_CPY_NEXT + CHANNELS,
  22. PARAM_RESET,
  23. PARAM_SLIDERS,
  24. PARAM_STEPS = PARAM_SLIDERS + ( CHANNELS * STEPS ),
  25. PARAM_PATTERNS = PARAM_STEPS + ( CHANNELS * STEPS ),
  26. PARAM_STEP_NUM = PARAM_PATTERNS + ( CHANNELS * PATTERNS ),
  27. PARAM_GLOBAL_PAT = PARAM_STEP_NUM + ( STEPS ),
  28. nPARAMS = PARAM_GLOBAL_PAT + ( PATTERNS )
  29. };
  30. enum InputIds
  31. {
  32. INPUT_EXT_CLOCK,
  33. INPUT_RESET,
  34. INPUT_GLOBAL_PAT_CHANGE,
  35. INPUT_PAT_CHANGE,
  36. nINPUTS = INPUT_PAT_CHANGE + CHANNELS
  37. };
  38. enum OutputIds
  39. {
  40. OUT_GATES,
  41. OUT_CV = OUT_GATES + CHANNELS,
  42. nOUTPUTS = OUT_CV + CHANNELS
  43. };
  44. enum LightIds
  45. {
  46. LIGHT_RUN,
  47. LIGHT_RESET,
  48. LIGHT_STEP_NUM,
  49. LIGHT_STEP = LIGHT_STEP_NUM + ( STEPS ),
  50. LIGHT_PAT = LIGHT_STEP + ( CHANNELS * STEPS ),
  51. LIGHT_COPY = LIGHT_PAT + ( CHANNELS * PATTERNS ),
  52. LIGHT_RAND = LIGHT_COPY + CHANNELS,
  53. LIGHT_GLOBAL_PAT = LIGHT_RAND + CHANNELS,
  54. nLIGHTS = LIGHT_GLOBAL_PAT + PATTERNS
  55. };
  56. enum GateMode
  57. {
  58. TRIGGER,
  59. RETRIGGER,
  60. CONTINUOUS,
  61. };
  62. CLog lg;
  63. bool m_bInitJson = false;
  64. GateMode m_GateMode = TRIGGER;
  65. PulseGenerator m_PulseStep;
  66. bool m_bRunning = true;
  67. float m_fPhase = 0.0;
  68. // Inputs
  69. SchmittTrigger m_SchTrigClock;
  70. SchmittTrigger m_SchTrigRun;
  71. SchmittTrigger m_SchTrigReset;
  72. SchmittTrigger m_SchTrigPatChange[ CHANNELS ];
  73. // random pattern button
  74. SchmittTrigger m_SchTrigRandPat;
  75. // copy next buttons
  76. SchmittTrigger m_SchTrigCopyNext;
  77. // number of steps
  78. int m_nSteps = STEPS;
  79. SchmittTrigger m_SchTrigStepNumbers[ STEPS ];
  80. // Level settings
  81. ParamWidget *m_pLevelToggleParam2[ CHANNELS ][ STEPS ] = {};
  82. SchmittTrigger m_SchTrigLevels[ CHANNELS ][ STEPS ];
  83. float m_fLevels[ PATTERNS ][ CHANNELS ][ STEPS ] = {};
  84. // Global Pattern Select
  85. SchmittTrigger m_SchTrigGlobalPatternSelect;
  86. int m_GlobalSelect = 0;
  87. bool m_bGlobalPatternChangePending = false;
  88. int m_GlobalPendingLight = 0;
  89. // Pattern Select
  90. int m_PatternSelect[ CHANNELS ] = {0};
  91. SchmittTrigger m_SchTrigPatternSelects[ CHANNELS ][ PATTERNS ];
  92. bool m_bPatternPending = false;
  93. bool m_bPatternChangePending[ CHANNELS ] = {0};
  94. int m_PendingLight[ CHANNELS ] = {0};
  95. // Steps
  96. int m_CurrentStep = 0;
  97. SchmittTrigger m_SchTrigSteps[ CHANNELS ][ STEPS ];
  98. bool m_bStepStates[ PATTERNS ][ CHANNELS ][ STEPS ] = {};
  99. float m_fLightStepLevels[ CHANNELS ][ STEPS ] = {};
  100. // Contructor
  101. Seq_3x16x16() : Module( nPARAMS, nINPUTS, nOUTPUTS, nLIGHTS ){}
  102. // Overrides
  103. void step() override;
  104. json_t* toJson() override;
  105. void fromJson(json_t *rootJ) override;
  106. void onRandomize() override;
  107. void onReset() override;
  108. void Randomize_Channel( int ch );
  109. void CopyNext( int ch );
  110. void ChangePattern( int ch, int index, bool bForceChange );
  111. void SetSteps( int nSteps );
  112. void SetGlobalPattern( int step );
  113. };
  114. //-----------------------------------------------------
  115. // Procedure: MySquareButton_CopyNext
  116. //
  117. //-----------------------------------------------------
  118. struct MySquareButton_CopyNext : MySquareButton
  119. {
  120. Seq_3x16x16 *mymodule;
  121. int param;
  122. void onChange( EventChange &e ) override
  123. {
  124. mymodule = (Seq_3x16x16*)module;
  125. if( mymodule && value == 1.0 )
  126. {
  127. param = paramId - Seq_3x16x16::PARAM_CPY_NEXT;
  128. mymodule->CopyNext( param );
  129. }
  130. MomentarySwitch::onChange( e );
  131. }
  132. };
  133. //-----------------------------------------------------
  134. // Procedure: MySquareButton_Rand
  135. //
  136. //-----------------------------------------------------
  137. struct MySquareButton_Rand : MySquareButton
  138. {
  139. Seq_3x16x16 *mymodule;
  140. int param;
  141. void onChange( EventChange &e ) override
  142. {
  143. mymodule = (Seq_3x16x16*)module;
  144. if( mymodule && value == 1.0 )
  145. {
  146. param = paramId - Seq_3x16x16::PARAM_RAND;
  147. mymodule->Randomize_Channel( param );
  148. }
  149. MomentarySwitch::onChange( e );
  150. }
  151. };
  152. //-----------------------------------------------------
  153. // Procedure: MySquareButton_GlobalPattern
  154. //
  155. //-----------------------------------------------------
  156. struct MySquareButton_GlobalPattern : MySquareButton //SVGSwitch, MomentarySwitch
  157. {
  158. Seq_3x16x16 *mymodule;
  159. int param;
  160. void onChange( EventChange &e ) override
  161. {
  162. mymodule = (Seq_3x16x16*)module;
  163. if( mymodule && value == 1.0 )
  164. {
  165. param = paramId - Seq_3x16x16::PARAM_GLOBAL_PAT;
  166. if( mymodule->m_bRunning )
  167. {
  168. if( param != mymodule->m_GlobalSelect && !mymodule->m_bGlobalPatternChangePending )
  169. {
  170. mymodule->m_bGlobalPatternChangePending = true;
  171. mymodule->m_GlobalPendingLight = param;
  172. }
  173. }
  174. else
  175. {
  176. mymodule->SetGlobalPattern( param );
  177. }
  178. }
  179. MomentarySwitch::onChange( e );
  180. }
  181. };
  182. //-----------------------------------------------------
  183. // Procedure: MySquareButton_Pattern
  184. //
  185. //-----------------------------------------------------
  186. struct MySquareButton_Pattern : MySquareButton //SVGSwitch, MomentarySwitch
  187. {
  188. Seq_3x16x16 *mymodule;
  189. int ch, stp, param;
  190. void onChange( EventChange &e ) override
  191. {
  192. mymodule = (Seq_3x16x16*)module;
  193. if( mymodule && value == 1.0 )
  194. {
  195. param = paramId - Seq_3x16x16::PARAM_PATTERNS;
  196. ch = param / STEPS;
  197. stp = param - (ch * STEPS);
  198. //mymodule->lg.f( (char*)"pat = %d, ch = %d, stp = %d\n", param, ch, stp );
  199. if( mymodule->m_bRunning )
  200. {
  201. if( stp != mymodule->m_PatternSelect[ ch ] && !mymodule->m_bPatternChangePending[ ch ] )
  202. {
  203. mymodule->m_bPatternPending = true;
  204. mymodule->m_bPatternChangePending[ ch ] = true;
  205. mymodule->m_PendingLight[ ch ] = stp;
  206. }
  207. }
  208. else
  209. {
  210. mymodule->ChangePattern( ch, stp, false );
  211. }
  212. }
  213. MomentarySwitch::onChange( e );
  214. }
  215. };
  216. //-----------------------------------------------------
  217. // Procedure: MySquareButton_Step
  218. //
  219. //-----------------------------------------------------
  220. struct MySquareButton_Step : MySquareButton //SVGSwitch, MomentarySwitch
  221. {
  222. Seq_3x16x16 *mymodule;
  223. int ch, stp, param;
  224. void onChange( EventChange &e ) override
  225. {
  226. mymodule = (Seq_3x16x16*)module;
  227. if( mymodule && value == 1.0 )
  228. {
  229. param = paramId - Seq_3x16x16::PARAM_STEPS;
  230. ch = param / STEPS;
  231. stp = param - (ch * STEPS);
  232. //lg.f( (char*)"step = %d, ch = %d, stp = %d\n", param, ch, stp );
  233. mymodule->m_bStepStates[ mymodule->m_PatternSelect[ ch ] ][ ch ][ stp ] = !mymodule->m_bStepStates[ mymodule->m_PatternSelect[ ch ] ][ ch ][ stp ];
  234. mymodule->lights[ Seq_3x16x16::LIGHT_STEP + ( ch * STEPS ) + stp ].value = mymodule->m_bStepStates[ mymodule->m_PatternSelect[ ch ] ][ ch ][ stp ] ? 1.0f : 0.0f;
  235. }
  236. MomentarySwitch::onChange( e );
  237. }
  238. };
  239. //-----------------------------------------------------
  240. // Procedure: MySquareButton_Step
  241. //
  242. //-----------------------------------------------------
  243. struct MySquareButton_StepNum : MySquareButton
  244. {
  245. Seq_3x16x16 *mymodule;
  246. int stp, i;
  247. void onChange( EventChange &e ) override
  248. {
  249. mymodule = (Seq_3x16x16*)module;
  250. if( mymodule && value == 1.0 )
  251. {
  252. stp = paramId - Seq_3x16x16::PARAM_STEP_NUM;
  253. mymodule->SetSteps( stp + 1 );
  254. }
  255. MomentarySwitch::onChange( e );
  256. }
  257. };
  258. //-----------------------------------------------------
  259. // Procedure: MySlider_Levels
  260. //
  261. //-----------------------------------------------------
  262. struct MySlider_Levels : MySlider_01
  263. {
  264. Seq_3x16x16 *mymodule;
  265. int ch, stp, param;
  266. void onChange( EventChange &e ) override
  267. {
  268. mymodule = (Seq_3x16x16*)module;
  269. if( mymodule )
  270. {
  271. param = paramId - Seq_3x16x16::PARAM_SLIDERS;
  272. ch = param / STEPS;
  273. stp = param - (ch * STEPS);
  274. //lg.f( "slider = %d, ch = %d, stp = %d, value = %.3f\n", param, ch, stp, value );
  275. mymodule->m_fLevels[ mymodule->m_PatternSelect[ ch ] ][ ch ][ stp ] = value;
  276. }
  277. SVGFader::onChange( e );
  278. }
  279. };
  280. //-----------------------------------------------------
  281. // Procedure: Widget
  282. //
  283. //-----------------------------------------------------
  284. struct Seq_3x16x16_Widget : ModuleWidget {
  285. Seq_3x16x16_Widget( Seq_3x16x16 *module );
  286. };
  287. Seq_3x16x16_Widget::Seq_3x16x16_Widget( Seq_3x16x16 *module ) : ModuleWidget(module)
  288. {
  289. int i, ch, stp, x, y;
  290. box.size = Vec(15*23, 380);
  291. {
  292. SVGPanel *panel = new SVGPanel();
  293. panel->box.size = box.size;
  294. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Seq_3x16x16.svg")));
  295. addChild(panel);
  296. }
  297. //module->lg.Open("Seq_3x16x16.txt");
  298. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  299. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  300. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  301. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  302. // clk/run button
  303. addParam(ParamWidget::create<LEDButton>(Vec( 78, 17 ), module, Seq_3x16x16::PARAM_RUN, 0.0, 1.0, 0.0 ) );
  304. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>( Vec( 78 + 5, 17 + 5 ), module, Seq_3x16x16::LIGHT_RUN ) );
  305. addInput(Port::create<MyPortInSmall>( Vec( 47, 17 ), Port::INPUT, module, Seq_3x16x16::INPUT_EXT_CLOCK ) );
  306. // reset button
  307. addParam(ParamWidget::create<LEDButton>( Vec( 143, 17 ), module, Seq_3x16x16::PARAM_RESET, 0.0, 1.0, 0.0 ) );
  308. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>( Vec( 143 + 5, 17 + 5 ), module, Seq_3x16x16::LIGHT_RESET ) );
  309. addInput(Port::create<MyPortInSmall>( Vec( 117, 17 ), Port::INPUT, module, Seq_3x16x16::INPUT_RESET ) );
  310. //----------------------------------------------------
  311. // Step Select buttons
  312. y = 41;
  313. x = 50;
  314. for ( stp = 0; stp < STEPS; stp++ )
  315. {
  316. // step button
  317. addParam(ParamWidget::create<MySquareButton_StepNum>( Vec( x, y ), module, Seq_3x16x16::PARAM_STEP_NUM + stp, 0.0, 1.0, 0.0 ) );
  318. addChild(ModuleLightWidget::create<SmallLight<DarkRedValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_STEP_NUM + stp ) );
  319. if( ( stp & 0x3 ) == 0x3 )
  320. x += 20;
  321. else
  322. x += 15;
  323. module->lights[ Seq_3x16x16::LIGHT_STEP_NUM + stp ].value = 1.0;
  324. }
  325. //----------------------------------------------------
  326. // All the Channel buttons
  327. // channel
  328. for ( ch = 0; ch < CHANNELS; ch++ )
  329. {
  330. x = 50;
  331. // step
  332. for ( stp = 0; stp < STEPS; stp++ )
  333. {
  334. y = 64 + (ch * CHANNEL_OFF_H);
  335. // level button
  336. module->m_pLevelToggleParam2[ ch ][ stp ] = ParamWidget::create<MySlider_Levels>( Vec( x, y ), module, Seq_3x16x16::PARAM_SLIDERS + ( ch * STEPS ) + stp , 0.0, 6.0, 0.0);
  337. addParam( module->m_pLevelToggleParam2[ ch ][ stp ] );
  338. y += 46;
  339. // step button
  340. addParam(ParamWidget::create<MySquareButton_Step>( Vec( x, y ), module, Seq_3x16x16::PARAM_STEPS + ( ch * STEPS ) + stp, 0.0, 1.0, 0.0 ) );
  341. addChild(ModuleLightWidget::create<SmallLight<DarkGreenValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_STEP + ( ch * STEPS ) + stp ) );
  342. if( ( stp & 0x3 ) == 0x3 )
  343. x += 20;
  344. else
  345. x += 15;
  346. }
  347. x = 45;
  348. y = 130 + (ch * CHANNEL_OFF_H);
  349. for ( i = 0; i < PATTERNS; i++ )
  350. {
  351. // pattern button
  352. addParam(ParamWidget::create<MySquareButton_Pattern>( Vec( x, y ), module, Seq_3x16x16::PARAM_PATTERNS + ( ch * PATTERNS ) + i, 0.0, 1.0, 0.0 ) );
  353. addChild(ModuleLightWidget::create<SmallLight<OrangeValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_PAT + ( ch * PATTERNS ) + i ) );
  354. x += 13;
  355. }
  356. x = 260;
  357. y = 126 + (ch * CHANNEL_OFF_H);
  358. // copy next button
  359. addParam(ParamWidget::create<MySquareButton_CopyNext>( Vec( x, y ), module, Seq_3x16x16::PARAM_CPY_NEXT + ch, 0.0, 1.0, 0.0 ) );
  360. addChild(ModuleLightWidget::create<SmallLight<CyanValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_COPY + ch ) );
  361. x = 290;
  362. // random button
  363. addParam(ParamWidget::create<MySquareButton_Rand>( Vec( x, y ), module, Seq_3x16x16::PARAM_RAND + ch, 0.0, 1.0, 0.0 ) );
  364. addChild(ModuleLightWidget::create<SmallLight<CyanValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_RAND + ch ) );
  365. // pattern change input trigger
  366. addInput(Port::create<MyPortInSmall>( Vec( 17, 127 + (ch * CHANNEL_OFF_H) ), Port::INPUT, module, Seq_3x16x16::INPUT_PAT_CHANGE + ch ) );
  367. x = 310;
  368. y = 65 + (ch * CHANNEL_OFF_H);
  369. // outputs
  370. addOutput(Port::create<MyPortOutSmall>( Vec( x, y ), Port::OUTPUT, module, Seq_3x16x16::OUT_CV + ch ) );
  371. addOutput(Port::create<MyPortOutSmall>( Vec( x, y + 42 ), Port::OUTPUT, module, Seq_3x16x16::OUT_GATES + ch ) );
  372. }
  373. //----------------------------------------------------
  374. // Global patter select buttons
  375. x = 45;
  376. y = 340;
  377. for ( stp = 0; stp < PATTERNS; stp++ )
  378. {
  379. // pattern button
  380. addParam(ParamWidget::create<MySquareButton_GlobalPattern>( Vec( x, y ), module, Seq_3x16x16::PARAM_GLOBAL_PAT + stp, 0.0, 1.0, 0.0 ) );
  381. addChild(ModuleLightWidget::create<SmallLight<OrangeValueLight>>( Vec( x + 2, y + 3 ), module, Seq_3x16x16::LIGHT_GLOBAL_PAT + stp ) );
  382. x += 13;
  383. }
  384. // pattern change input trigger
  385. addInput(Port::create<MyPortInSmall>( Vec( 17, 338 ), Port::INPUT, module, Seq_3x16x16::INPUT_GLOBAL_PAT_CHANGE ) );
  386. module->lights[ Seq_3x16x16::LIGHT_GLOBAL_PAT ].value = 1.0;
  387. module->m_GlobalSelect = 0;
  388. module->ChangePattern( 0, PATTERNS, false );
  389. module->ChangePattern( 1, PATTERNS, false );
  390. module->ChangePattern( 2, PATTERNS, false );
  391. }
  392. //-----------------------------------------------------
  393. // Procedure:
  394. //
  395. //-----------------------------------------------------
  396. json_t *Seq_3x16x16::toJson()
  397. {
  398. bool *pgateState;
  399. float *pfloat;
  400. json_t *rootJ = json_object();
  401. // running
  402. json_object_set_new(rootJ, "running", json_boolean (m_bRunning));
  403. // steps
  404. pgateState = &m_bStepStates[ 0 ][ 0 ][ 0 ];
  405. json_t *gatesJ = json_array();
  406. for (int i = 0; i < ( PATTERNS * CHANNELS * STEPS ); i++)
  407. {
  408. json_t *gateJ = json_integer( (int) pgateState[ i ] );
  409. json_array_append_new( gatesJ, gateJ );
  410. }
  411. json_object_set_new( rootJ, "steps", gatesJ );
  412. // level settings
  413. pfloat = &m_fLevels[ 0 ][ 0 ][ 0 ];
  414. json_t *gatesJ_3 = json_array();
  415. for (int i = 0; i < ( PATTERNS * CHANNELS * STEPS ); i++)
  416. {
  417. json_t *gateJ = json_real( pfloat[ i ] );
  418. json_array_append_new(gatesJ_3, gateJ);
  419. }
  420. json_object_set_new(rootJ, "levelsettings", gatesJ_3);
  421. // number of steps
  422. json_t *stepsJ = json_integer( m_nSteps );
  423. json_object_set_new(rootJ, "numberofsteps", stepsJ);
  424. // gateMode
  425. json_t *gateModeJ = json_integer((int) m_GateMode );
  426. json_object_set_new(rootJ, "gateMode", gateModeJ);
  427. return rootJ;
  428. }
  429. //-----------------------------------------------------
  430. // Procedure: fromJson
  431. //
  432. //-----------------------------------------------------
  433. void Seq_3x16x16::fromJson(json_t *rootJ)
  434. {
  435. bool *pgateState;
  436. float *pfloat;
  437. // running
  438. json_t *runningJ = json_object_get(rootJ, "running");
  439. if (runningJ)
  440. m_bRunning = json_is_true(runningJ);
  441. // steps
  442. pgateState = &m_bStepStates[ 0 ][ 0 ][ 0 ];
  443. json_t *StepsJ = json_object_get(rootJ, "steps");
  444. if (StepsJ)
  445. {
  446. for (int i = 0; i < ( PATTERNS * CHANNELS * STEPS ); i++)
  447. {
  448. json_t *gateJ = json_array_get(StepsJ, i);
  449. if (gateJ)
  450. pgateState[ i ] = json_integer_value( gateJ );
  451. }
  452. }
  453. // level settings
  454. pfloat = &m_fLevels[ 0 ][ 0 ][ 0 ];
  455. json_t *LvlSettingsJ = json_object_get(rootJ, "levelsettings");
  456. if (LvlSettingsJ)
  457. {
  458. for (int i = 0; i < ( PATTERNS * CHANNELS * STEPS ); i++)
  459. {
  460. json_t *gateJ = json_array_get(LvlSettingsJ, i);
  461. if (gateJ)
  462. pfloat[ i ] = json_real_value(gateJ);
  463. //lg.f("loading %.3f\n", pfloat[ i ] );
  464. }
  465. }
  466. // number of steps
  467. json_t *nStepsJ = json_object_get(rootJ, "numberofsteps");
  468. if (nStepsJ)
  469. m_nSteps = (GateMode)json_integer_value( nStepsJ );
  470. // gateMode
  471. json_t *gateModeJ = json_object_get(rootJ, "gateMode");
  472. if (gateModeJ)
  473. m_GateMode = (GateMode)json_integer_value(gateModeJ);
  474. SetSteps( m_nSteps );
  475. //lg.f("json read complete\n");
  476. m_bInitJson = true;
  477. }
  478. //-----------------------------------------------------
  479. // Procedure: reset
  480. //
  481. //-----------------------------------------------------
  482. void Seq_3x16x16::onReset()
  483. {
  484. //lg.f("init\n");
  485. memset( m_fLevels, 0, sizeof(m_fLevels) );
  486. memset( m_bStepStates, 0, sizeof(m_bStepStates) );
  487. for( int ch = 0; ch < CHANNELS; ch ++ )
  488. {
  489. for( int i = 0; i < STEPS; i ++ )
  490. {
  491. lights[ LIGHT_STEP + ( ch * STEPS ) + i ].value = 0.0;
  492. m_fLightStepLevels[ ch ][ i ] = 0.0;
  493. }
  494. }
  495. ChangePattern( 0, PATTERNS, false );
  496. ChangePattern( 1, PATTERNS, false );
  497. ChangePattern( 2, PATTERNS, false );
  498. SetSteps( 16 );
  499. }
  500. //-----------------------------------------------------
  501. // Procedure: randomize
  502. //
  503. //-----------------------------------------------------
  504. float stepchance[ 16 ] = { 0.9, 0.5, 0.8, 0.4, 0.9, 0.5, 0.8, 0.4, 0.9, 0.5, 0.8, 0.4, 0.9, 0.5, 0.8, 0.4 };
  505. void Seq_3x16x16::Randomize_Channel( int ch )
  506. {
  507. int stp, pat;
  508. int octave;
  509. pat = m_PatternSelect[ ch ];
  510. octave = (int)( randomUniform() * 4.0 );
  511. for( stp = 0; stp < STEPS; stp++ )
  512. {
  513. m_fLevels[ pat ][ ch ][ stp ] = (float)octave + ( randomUniform() * 2.0 );
  514. m_bStepStates[ pat ][ ch ][ stp ] = ( randomUniform() < stepchance[ stp ] ) ? true : false;
  515. }
  516. ChangePattern( ch, pat, true );
  517. }
  518. //-----------------------------------------------------
  519. // Procedure: randomize
  520. //
  521. //-----------------------------------------------------
  522. void Seq_3x16x16::onRandomize()
  523. {
  524. int ch, stp, pat;
  525. int octave;
  526. for( ch = 0; ch < CHANNELS; ch++ )
  527. {
  528. for( pat = 0; pat < PATTERNS; pat++ )
  529. {
  530. octave = (int)( randomUniform() * 4.0 );
  531. for( stp = 0; stp < STEPS; stp++ )
  532. {
  533. m_fLevels[ pat ][ ch ][ stp ] = (float)octave + ( randomUniform() * 2.0 );
  534. m_bStepStates[ pat ][ ch ][ stp ] = ( randomUniform() < stepchance[ stp ] ) ? true : false;
  535. }
  536. }
  537. }
  538. ChangePattern( 0, 0, true );
  539. ChangePattern( 1, 0, true );
  540. ChangePattern( 2, 0, true );
  541. }
  542. //-----------------------------------------------------
  543. // Procedure: CopyNext
  544. //
  545. //-----------------------------------------------------
  546. void Seq_3x16x16::CopyNext( int ch )
  547. {
  548. int stp, pat;
  549. pat = m_PatternSelect[ ch ];
  550. // don't copy from the last pattern
  551. if( pat == (PATTERNS - 1) )
  552. return;
  553. for( stp = 0; stp < STEPS; stp++ )
  554. {
  555. m_fLevels[ pat + 1 ][ ch ][ stp ] = m_fLevels[ pat ][ ch ][ stp ];
  556. m_bStepStates[ pat + 1 ][ ch ][ stp ] = m_bStepStates[ pat ][ ch ][ stp ];
  557. }
  558. ChangePattern( ch, pat + 1, true );
  559. }
  560. //-----------------------------------------------------
  561. // Procedure: ChangePattern
  562. //
  563. //-----------------------------------------------------
  564. void Seq_3x16x16::ChangePattern( int ch, int index, bool bForceChange )
  565. {
  566. int stp, i;
  567. if( !bForceChange && index == m_PatternSelect[ ch ] )
  568. return;
  569. if( index < 0 )
  570. index = PATTERNS - 1;
  571. else if( index >= PATTERNS )
  572. index = 0;
  573. m_PatternSelect[ ch ] = index;
  574. // update lights
  575. for( stp = 0; stp < STEPS; stp++ )
  576. lights[ LIGHT_STEP + ( ch * STEPS ) + stp ].value = m_bStepStates[ m_PatternSelect[ ch ] ][ ch ][ stp ] ? 1.0 : 0.0;
  577. for( i = 0; i < PATTERNS; i++ )
  578. {
  579. if( m_PatternSelect[ ch ] == i )
  580. lights[ LIGHT_PAT + ( ch * PATTERNS ) + i ].value = 1.0f;
  581. else
  582. lights[ LIGHT_PAT + ( ch * PATTERNS ) + i ].value = 0.0f;
  583. }
  584. // step
  585. for( stp = 0; stp < STEPS; stp++ )
  586. {
  587. // level button
  588. m_pLevelToggleParam2[ ch ][ stp ]->setValue( m_fLevels[ m_PatternSelect[ ch ] ][ ch ][ stp ] );
  589. }
  590. }
  591. //-----------------------------------------------------
  592. // Procedure: SetSteps
  593. //
  594. //-----------------------------------------------------
  595. void Seq_3x16x16::SetSteps( int nSteps )
  596. {
  597. int i;
  598. if( nSteps < 1 || nSteps > STEPS )
  599. nSteps = STEPS;
  600. m_nSteps = nSteps;
  601. for ( i = 0; i < STEPS; i++ )
  602. {
  603. // level button
  604. if( i < nSteps )
  605. lights[ LIGHT_STEP_NUM + i ].value = 1.0f;
  606. else
  607. lights[ LIGHT_STEP_NUM + i ].value = 0.0f;
  608. }
  609. }
  610. //-----------------------------------------------------
  611. // Procedure: SetGlobalPattern
  612. //
  613. //-----------------------------------------------------
  614. void Seq_3x16x16::SetGlobalPattern( int step )
  615. {
  616. for ( int i = 0; i < PATTERNS; i++ )
  617. lights[ LIGHT_GLOBAL_PAT + i ].value = 0.0f;
  618. lights[ LIGHT_GLOBAL_PAT + step ].value = 1.0;
  619. m_GlobalSelect = step;
  620. ChangePattern( 0, step, false );
  621. ChangePattern( 1, step, false );
  622. ChangePattern( 2, step, false );
  623. }
  624. //-----------------------------------------------------
  625. // Procedure: step
  626. //
  627. //-----------------------------------------------------
  628. void Seq_3x16x16::step()
  629. {
  630. bool bNextStep = false, bPulse, bGatesOn, bChTrig;
  631. int ch, stp;
  632. float fout, fnote;
  633. int octave;
  634. static float fpendinglight = 0.0f;
  635. static bool bUp = true;
  636. // pending light value
  637. if( bUp )
  638. {
  639. fpendinglight += ( 1.0 / engineGetSampleRate() ) * 1.5 ;
  640. if( fpendinglight >= 0.5f )
  641. {
  642. fpendinglight = 0.5f;
  643. bUp = false;
  644. }
  645. }
  646. else
  647. {
  648. fpendinglight -= ( 1.0 / engineGetSampleRate() ) * 2;
  649. if( fpendinglight <= 0.0f )
  650. {
  651. fpendinglight = 0.0f;
  652. bUp = true;
  653. }
  654. }
  655. // Run
  656. if( m_SchTrigRun.process( params[ PARAM_RUN ].value ) )
  657. m_bRunning = !m_bRunning;
  658. lights[ LIGHT_RUN ].value = m_bRunning ? 1.0f : 0.0f;
  659. // Random and copy buttons
  660. for( ch = 0; ch < CHANNELS; ch++ )
  661. {
  662. if( m_SchTrigRandPat.process( params[ PARAM_RAND + ch ].value ) )
  663. lights[ LIGHT_RAND + ch ].value = 1.0f;
  664. if( m_SchTrigCopyNext.process( params[ PARAM_CPY_NEXT + ch ].value ) )
  665. lights[ LIGHT_COPY + ch ].value = 1.0f;
  666. lights[ LIGHT_RAND + ch ].value -= lights[ LIGHT_RAND + ch ].value / LIGHT_LAMBDA / engineGetSampleRate();
  667. lights[ LIGHT_COPY + ch ].value -= lights[ LIGHT_COPY + ch ].value / LIGHT_LAMBDA / engineGetSampleRate();
  668. }
  669. if( m_bRunning )
  670. {
  671. if( inputs[ INPUT_EXT_CLOCK ].active )
  672. {
  673. // External clock
  674. if( m_SchTrigClock.process( inputs[ INPUT_EXT_CLOCK ].value ) )
  675. {
  676. m_fPhase = 0.0f;
  677. bNextStep = true;
  678. }
  679. }
  680. }
  681. else
  682. {
  683. // cancel any pending pattern changes
  684. if( m_bGlobalPatternChangePending )
  685. {
  686. m_bGlobalPatternChangePending = false;
  687. SetGlobalPattern( m_GlobalPendingLight );
  688. }
  689. m_bPatternPending = false;
  690. for( ch = 0; ch < CHANNELS; ch++ )
  691. {
  692. // pat change trigger
  693. if( m_bPatternChangePending[ ch ] )
  694. {
  695. m_bPatternChangePending[ ch ] = false;
  696. ChangePattern( ch, m_PendingLight[ ch ], false );
  697. }
  698. }
  699. }
  700. // Reset
  701. if( m_SchTrigReset.process( params[ PARAM_RESET ].value + inputs[ INPUT_RESET ].value ) )
  702. {
  703. m_fPhase = 0.0f;
  704. m_CurrentStep = m_nSteps;
  705. bNextStep = true;
  706. lights[ LIGHT_RESET ].value = 1.0f;
  707. }
  708. if( bNextStep )
  709. {
  710. m_CurrentStep += 1;
  711. if( m_CurrentStep >= m_nSteps )
  712. m_CurrentStep = 0;
  713. for( ch = 0; ch < CHANNELS; ch++ )
  714. m_fLightStepLevels[ ch ][ m_CurrentStep ] = 1.0f;
  715. m_PulseStep.trigger( 1e-3 );
  716. // resolve any pending pattern changes
  717. if( m_CurrentStep == 0 )
  718. {
  719. if( m_bGlobalPatternChangePending )
  720. {
  721. m_bGlobalPatternChangePending = false;
  722. SetGlobalPattern( m_GlobalPendingLight );
  723. // cancel other changes on a global change
  724. m_bPatternChangePending[ 0 ] = false;
  725. m_bPatternChangePending[ 1 ] = false;
  726. m_bPatternChangePending[ 2 ] = false;
  727. m_bPatternPending = false;
  728. }
  729. for( ch = 0; ch < CHANNELS; ch++ )
  730. {
  731. // pat change trigger
  732. if( m_bPatternChangePending[ ch ] )
  733. {
  734. m_bPatternChangePending[ ch ] = false;
  735. ChangePattern( ch, m_PendingLight[ ch ], false );
  736. }
  737. }
  738. }
  739. }
  740. // global pattern pending change light blinky
  741. if( m_bGlobalPatternChangePending )
  742. {
  743. lights[ LIGHT_GLOBAL_PAT + m_GlobalPendingLight ].value = fpendinglight;
  744. }
  745. // channel pattern pending change light blinky
  746. if( m_bPatternPending )
  747. {
  748. m_bPatternPending = false;
  749. for( ch = 0; ch < CHANNELS; ch++ )
  750. {
  751. // pat change trigger
  752. if( m_bPatternChangePending[ ch ] )
  753. {
  754. m_bPatternPending = true;
  755. lights[ LIGHT_PAT + (ch * PATTERNS) + m_PendingLight[ ch ] ].value = fpendinglight;
  756. }
  757. }
  758. }
  759. lights[ LIGHT_RESET ].value -= lights[ LIGHT_RESET ].value / LIGHT_LAMBDA / engineGetSampleRate();
  760. bPulse = m_PulseStep.process( 1.0 / engineGetSampleRate() );
  761. // Step buttons
  762. for( ch = 0; ch < CHANNELS; ch++ )
  763. {
  764. bChTrig = false;
  765. for( stp = 0; stp < STEPS; stp++ )
  766. {
  767. bGatesOn = ( m_bRunning && stp == m_CurrentStep && m_bStepStates[ m_PatternSelect[ ch ] ][ ch ][ stp ] );
  768. if( m_GateMode == TRIGGER )
  769. bGatesOn = bGatesOn && bPulse;
  770. else if( m_GateMode == RETRIGGER )
  771. bGatesOn = bGatesOn && !bPulse;
  772. if( bGatesOn )
  773. bChTrig = true;
  774. m_fLightStepLevels[ ch ][ stp ] -= m_fLightStepLevels[ ch ][ stp ] / LIGHT_LAMBDA / engineGetSampleRate();
  775. lights[ LIGHT_STEP + (ch * STEPS) + stp ].value = m_bStepStates[ m_PatternSelect[ ch ] ][ ch ][ stp ] ? 1.0 - m_fLightStepLevels[ ch ][ stp ] : m_fLightStepLevels[ ch ][ stp ];
  776. }
  777. // trigger
  778. outputs[ OUT_GATES + ch ].value = bChTrig ? CV_MAX : 0.0;
  779. }
  780. // outputs
  781. for( ch = 0; ch < CHANNELS; ch++ )
  782. {
  783. // set CV
  784. if( m_bRunning && m_bStepStates[ m_PatternSelect[ ch ] ][ ch ][ m_CurrentStep ] )
  785. {
  786. // quantizie note
  787. fout = params[ PARAM_SLIDERS + ( ch * STEPS ) + m_CurrentStep ].value;
  788. octave = round( fout );
  789. fnote = round( ( fout - (float)octave ) * 12.0f );
  790. outputs[ OUT_CV + ch ].value = (float)octave + fnote/12.0f;
  791. }
  792. }
  793. if( m_bRunning )
  794. {
  795. // external pattern select change
  796. for( ch = 0; ch < CHANNELS; ch++ )
  797. {
  798. // pat change trigger - ignore if already pending
  799. if( m_SchTrigPatChange[ ch ].process( inputs[ INPUT_PAT_CHANGE + ch ].value ) && !m_bPatternChangePending[ ch ] )
  800. {
  801. m_bPatternPending = true;
  802. m_bPatternChangePending[ ch ] = true;
  803. m_PendingLight[ ch ] = ( m_PatternSelect[ ch ] + 1 ) & 0xF;
  804. }
  805. }
  806. // global pat change trigger - ignore if already pending
  807. if( m_SchTrigGlobalPatternSelect.process( inputs[ INPUT_GLOBAL_PAT_CHANGE ].value ) && !m_bGlobalPatternChangePending )
  808. {
  809. m_bGlobalPatternChangePending = true;
  810. m_GlobalPendingLight = ( m_GlobalSelect + 1 ) & 0xF;
  811. }
  812. }
  813. }
  814. } // namespace rack_plugin_mscHack
  815. using namespace rack_plugin_mscHack;
  816. RACK_PLUGIN_MODEL_INIT(mscHack, Seq_3x16x16) {
  817. Model *modelSeq_3x16x16 = Model::create<Seq_3x16x16, Seq_3x16x16_Widget>( "mscHack", "Seq_3ch_16step", "SEQ 3 x 16", SEQUENCER_TAG, MULTIPLE_TAG );
  818. return modelSeq_3x16x16;
  819. }