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.

803 lines
19KB

  1. #include "mscHack.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_mscHack {
  4. //-----------------------------------------------------
  5. // General Definition
  6. //-----------------------------------------------------
  7. #define nCHANNELS 3
  8. #define SEMI ( 1.0f / 12.0f )
  9. //-----------------------------------------------------
  10. // Reverb Definition
  11. //-----------------------------------------------------
  12. #define REV_TAPS 16
  13. #define REV_BUF_SIZE 0x4000
  14. #define REV_BUF_MAX 0x3FFF
  15. typedef struct
  16. {
  17. float buf[ REV_BUF_SIZE ];
  18. unsigned int in;
  19. unsigned int out[ REV_TAPS ];
  20. }REVERB_STRUCT;
  21. //-----------------------------------------------------
  22. // filter
  23. //-----------------------------------------------------
  24. enum FILTER_TYPES
  25. {
  26. FILTER_OFF,
  27. FILTER_LP,
  28. FILTER_HP,
  29. FILTER_BP,
  30. FILTER_NT
  31. };
  32. typedef struct
  33. {
  34. int type;
  35. float basef, q, f, qmod, fmod;
  36. float lp1, bp1;
  37. }FILTER_STRUCT;
  38. //-----------------------------------------------------
  39. // Morph oscillator
  40. //-----------------------------------------------------
  41. #define nMORPH_WAVES 3
  42. enum MOD_TYPES
  43. {
  44. MOD_MORPH,
  45. MOD_LEVEL,
  46. MOD_DET1,
  47. MOD_DET2,
  48. nMODS
  49. };
  50. typedef struct
  51. {
  52. float inc;
  53. float semi;
  54. float fval[ nMODS ];
  55. //FILTER_STRUCT filter;
  56. }MORPH_OSC_STRUCT;
  57. enum GLOBAL_OSCS
  58. {
  59. GOSC_FILTER,
  60. GOSC_NOISE,
  61. nGLOBALOSCS
  62. };
  63. typedef struct
  64. {
  65. float finc;
  66. float fval;
  67. }GLOBAL_OSC_STRUCT;
  68. //-----------------------------------------------------
  69. // Module Definition
  70. //
  71. //-----------------------------------------------------
  72. struct Dronez : Module
  73. {
  74. enum ParamIds
  75. {
  76. PARAM_SPEED,
  77. nPARAMS
  78. };
  79. enum InputIds
  80. {
  81. IN_VOCT,
  82. IN_RANDTRIG,
  83. nINPUTS
  84. };
  85. enum OutputIds
  86. {
  87. OUT_L,
  88. OUT_R,
  89. nOUTPUTS
  90. };
  91. enum LightIds
  92. {
  93. nLIGHTS
  94. };
  95. enum FADE_STATE
  96. {
  97. FADE_IDLE,
  98. FADE_OUT,
  99. FADE_IN,
  100. };
  101. bool m_bInitialized = false;
  102. CLog lg;
  103. // Contructor
  104. Dronez() : Module(nPARAMS, nINPUTS, nOUTPUTS, nLIGHTS){}
  105. Label *m_pTextLabel = NULL;
  106. Label *m_pTextLabel2 = NULL;
  107. // oscillators
  108. MORPH_OSC_STRUCT m_osc[ nCHANNELS ] = {};
  109. EnvelopeData m_wav[ nCHANNELS ][ nMORPH_WAVES ] = {};
  110. EnvelopeData m_mod[ nCHANNELS ][ nMODS ] = {};
  111. EnvelopeData m_global[ nGLOBALOSCS ];
  112. GLOBAL_OSC_STRUCT m_GlobalOsc[ nGLOBALOSCS ] = {};
  113. float m_cuttoff = 0.5, m_rez = 0.5;
  114. float m_finc[ nCHANNELS ][ nMODS ] = {};
  115. FILTER_STRUCT m_filter={};
  116. // reverb
  117. REVERB_STRUCT m_reverb = {};
  118. // random seed
  119. SchmittTrigger m_SchmitTrigRand;
  120. MyLEDButton *m_pButtonSeed[ 32 ] = {};
  121. MyLEDButton *m_pButtonRand = NULL;
  122. int m_Seed = 0;
  123. int m_FadeState = FADE_IN;
  124. float m_fFade = 0.0f;
  125. float speeds[ 9 ] = { 0.1f, 0.25f, 0.50f, 0.75f, 1.0f, 1.5f, 2.0f, 4.0f, 8.0f };
  126. //-----------------------------------------------------
  127. // MySpeed_Knob
  128. //-----------------------------------------------------
  129. struct MySpeed_Knob : Knob_Yellow3_20_Snap
  130. {
  131. Dronez *mymodule;
  132. char strVal[ 10 ] = {};
  133. void onChange( EventChange &e ) override
  134. {
  135. mymodule = (Dronez*)module;
  136. if( mymodule )
  137. {
  138. if( !mymodule->m_bInitialized )
  139. return;
  140. sprintf( strVal, "x%.2f", mymodule->speeds[ (int)value ] );
  141. mymodule->m_pTextLabel2->text = strVal;
  142. }
  143. RoundKnob::onChange( e );
  144. }
  145. };
  146. void putx( int x );
  147. void putf( float fval );
  148. int getseed( void );
  149. void putseed( int seed );
  150. void ChangeSeedPending( int seed );
  151. void BuildWave( int ch );
  152. void BuildDrone( void );
  153. void RandWave( EnvelopeData *pEnv, float min=0.0f, float max= 1.0f );
  154. void RandPresetWaveAdjust( EnvelopeData *pEnv );
  155. // audio
  156. void ChangeFilterCutoff( FILTER_STRUCT *pf, float cutfreq );
  157. void processFilter( FILTER_STRUCT *pfilter, float *pIn );
  158. void processReverb( float In, float *pL, float *pR );
  159. // Overrides
  160. void step() override;
  161. void JsonParams( bool bTo, json_t *root);
  162. json_t* toJson() override;
  163. void fromJson(json_t *rootJ) override;
  164. void onRandomize() override;
  165. void onReset() override;
  166. void onCreate() override;
  167. void onDelete() override;
  168. };
  169. //-----------------------------------------------------
  170. // Dronez_SeedButton
  171. //-----------------------------------------------------
  172. void Dronez_SeedButton( void *pClass, int id, bool bOn )
  173. {
  174. Dronez *mymodule;
  175. mymodule = (Dronez*)pClass;
  176. mymodule->ChangeSeedPending( mymodule->getseed() );
  177. }
  178. //-----------------------------------------------------
  179. // Dronez_RandButton
  180. //-----------------------------------------------------
  181. void Dronez_RandButton( void *pClass, int id, bool bOn )
  182. {
  183. Dronez *mymodule;
  184. mymodule = (Dronez*)pClass;
  185. mymodule->ChangeSeedPending( (int)randomu32() );
  186. }
  187. //-----------------------------------------------------
  188. // Procedure: Widget
  189. //
  190. //-----------------------------------------------------
  191. struct Dronez_Widget : ModuleWidget {
  192. Dronez_Widget( Dronez *module );
  193. };
  194. Dronez_Widget::Dronez_Widget( Dronez *module ) : ModuleWidget(module)
  195. {
  196. int i, x, y;
  197. box.size = Vec( 15*5, 380 );
  198. {
  199. SVGPanel *panel = new SVGPanel();
  200. panel->box.size = box.size;
  201. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Dronez.svg")));
  202. addChild(panel);
  203. }
  204. addInput(Port::create<MyPortInSmall>( Vec( 10, 20 ), Port::INPUT, module, Dronez::IN_VOCT ) );
  205. addInput(Port::create<MyPortInSmall>( Vec( 10, 241 ), Port::INPUT, module, Dronez::IN_RANDTRIG ) );
  206. // random button
  207. module->m_pButtonRand = new MyLEDButton( 40, 238, 25, 25, 20.0, DWRGB( 180, 180, 180 ), DWRGB( 255, 0, 0 ), MyLEDButton::TYPE_MOMENTARY, 0, module, Dronez_RandButton );
  208. addChild( module->m_pButtonRand );
  209. addOutput(Port::create<MyPortOutSmall>( Vec( 48, 20 ), Port::OUTPUT, module, Dronez::OUT_L ) );
  210. addOutput(Port::create<MyPortOutSmall>( Vec( 48, 45 ), Port::OUTPUT, module, Dronez::OUT_R ) );
  211. y = 95;
  212. x = 9;
  213. //module->lg.Open("c://users//mark//documents//rack//Dronez.txt");
  214. for( i = 31; i >=0; i-- )
  215. {
  216. module->m_pButtonSeed[ i ] = new MyLEDButton( x, y, 11, 11, 8.0, DWRGB( 180, 180, 180 ), DWRGB( 255, 255, 0 ), MyLEDButton::TYPE_SWITCH, i, module, Dronez_SeedButton );
  217. addChild( module->m_pButtonSeed[ i ] );
  218. if( i % 4 == 0 )
  219. {
  220. y += 15;
  221. x = 9;
  222. }
  223. else
  224. {
  225. x += 15;
  226. }
  227. }
  228. addParam(ParamWidget::create<Dronez::MySpeed_Knob>( Vec( 10, 280 ), module, Dronez::PARAM_SPEED, 0.0, 8.0, 4.0 ) );
  229. module->m_pTextLabel2 = new Label();
  230. module->m_pTextLabel2->box.pos = Vec( 30, 280 );
  231. module->m_pTextLabel2->text = "x1.00";
  232. addChild( module->m_pTextLabel2 );
  233. module->m_pTextLabel = new Label();
  234. module->m_pTextLabel->box.pos = Vec( 0, 213 );
  235. module->m_pTextLabel->text = "----";
  236. addChild( module->m_pTextLabel );
  237. addChild(Widget::create<ScrewSilver>(Vec(30, 0)));
  238. addChild(Widget::create<ScrewSilver>(Vec(30, 365)));
  239. module->putseed( (int)randomu32() );
  240. module->BuildDrone();
  241. }
  242. //-----------------------------------------------------
  243. // Procedure: JsonParams
  244. //
  245. //-----------------------------------------------------
  246. void Dronez::JsonParams( bool bTo, json_t *root)
  247. {
  248. JsonDataInt( bTo, "m_Seed", root, &m_Seed, 1 );
  249. }
  250. //-----------------------------------------------------
  251. // Procedure: toJson
  252. //
  253. //-----------------------------------------------------
  254. json_t *Dronez::toJson()
  255. {
  256. json_t *root = json_object();
  257. if( !root )
  258. return NULL;
  259. JsonParams( TOJSON, root );
  260. return root;
  261. }
  262. //-----------------------------------------------------
  263. // Procedure: fromJson
  264. //
  265. //-----------------------------------------------------
  266. void Dronez::fromJson( json_t *root )
  267. {
  268. //char strVal[ 10 ] = {};
  269. JsonParams( FROMJSON, root );
  270. ChangeSeedPending( m_Seed );
  271. //sprintf( strVal, "x%.2f", speeds[ (int)params[ PARAM_SPEED ].value ] );
  272. //m_pTextLabel2->text = strVal;
  273. }
  274. //-----------------------------------------------------
  275. // Procedure: onCreate
  276. //
  277. //-----------------------------------------------------
  278. void Dronez::onCreate()
  279. {
  280. }
  281. //-----------------------------------------------------
  282. // Procedure: onDelete
  283. //
  284. //-----------------------------------------------------
  285. void Dronez::onDelete()
  286. {
  287. }
  288. //-----------------------------------------------------
  289. // Procedure: onReset
  290. //
  291. //-----------------------------------------------------
  292. void Dronez::onReset()
  293. {
  294. }
  295. //-----------------------------------------------------
  296. // Procedure: onRandomize
  297. //
  298. //-----------------------------------------------------
  299. void Dronez::onRandomize()
  300. {
  301. ChangeSeedPending( (int)randomu32() );
  302. }
  303. //-----------------------------------------------------
  304. // Procedure: getseed
  305. //
  306. //-----------------------------------------------------
  307. int Dronez::getseed( void )
  308. {
  309. int seed = 0, shift= 1;;
  310. for( int i = 0; i < 32; i++ )
  311. {
  312. if( m_pButtonSeed[ i ]->m_bOn )
  313. seed |= shift;
  314. shift<<=1;
  315. }
  316. return seed;
  317. }
  318. //-----------------------------------------------------
  319. // Procedure: putseed
  320. //
  321. //-----------------------------------------------------
  322. void Dronez::putseed( int seed )
  323. {
  324. m_Seed = seed;
  325. init_rand( seed );
  326. putx( seed );
  327. for( int i = 0; i < 32; i++ )
  328. {
  329. m_pButtonSeed[ i ]->Set( (bool)(seed & 1) );
  330. seed>>=1;
  331. }
  332. }
  333. //-----------------------------------------------------
  334. // Procedure: ChangeSeedPending
  335. //
  336. //-----------------------------------------------------
  337. void Dronez::ChangeSeedPending( int seed )
  338. {
  339. m_FadeState = FADE_OUT;
  340. putseed( seed );
  341. }
  342. //-----------------------------------------------------
  343. // Procedure: RandWave
  344. //-----------------------------------------------------
  345. void Dronez::RandWave( EnvelopeData *pEnv, float min, float max )
  346. {
  347. int i;
  348. for( i = 0; i < ENVELOPE_HANDLES - 1; i++ )
  349. pEnv->setVal( i, frand_mm( min, max ) );
  350. pEnv->setVal( i, pEnv->m_HandleVal[ 0 ] );
  351. }
  352. //-----------------------------------------------------
  353. // Procedure: RandPresetWaveAdjust
  354. //-----------------------------------------------------
  355. void Dronez::RandPresetWaveAdjust( EnvelopeData *pEnv )
  356. {
  357. int i;
  358. float fval;
  359. if( frand_perc( 25.0f ) )
  360. {
  361. RandWave( pEnv, 0.0f, 1.0f );
  362. }
  363. else
  364. {
  365. //pEnv->Preset( (int)frand_mm( 2.0f, 7.25f) );
  366. pEnv->Preset( EnvelopeData::PRESET_SIN );
  367. for( i = 0; i < ENVELOPE_HANDLES - 1; i++ )
  368. {
  369. fval = clamp( pEnv->m_HandleVal[ i ] + frand_mm( -0.01f, 0.01f ), -1.0f, 1.0f );
  370. pEnv->setVal( i, fval );
  371. }
  372. }
  373. }
  374. //-----------------------------------------------------
  375. // Procedure: BuildWave
  376. //
  377. //-----------------------------------------------------
  378. float semis[ 8 ] = { (SEMI * 5.0f), (SEMI * 6.0f), (SEMI * 9.0f), (SEMI * 11.0f), (SEMI * 21.0f), (SEMI * 12.0f), (SEMI * 24.0f), (SEMI * 29.0f) };
  379. void Dronez::BuildWave( int ch )
  380. {
  381. m_osc[ ch ].semi = semis[ srand() & 0x7 ];
  382. // audio waves
  383. m_wav[ ch ][ 0 ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_Audio, false, 1.0f );
  384. RandPresetWaveAdjust( &m_wav[ ch ][ 0 ] );
  385. //RandWave( &m_wav[ ch ][ 0 ], 0.0f, 1.0f );
  386. m_wav[ ch ][ 1 ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_Audio, false, 1.0f );
  387. //RandPresetWaveAdjust( &m_wav[ ch ][ 1 ], -0.1f, 0.1f );
  388. m_wav[ ch ][ 1 ].Preset( (int)frand_mm( 2.0f, 7.2f) );
  389. m_wav[ ch ][ 2 ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_Audio, false, 1.0f );
  390. RandPresetWaveAdjust( &m_wav[ ch ][ 2 ] );
  391. //RandWave( &m_wav[ ch ][ 2 ], 0.0f, 1.0f );
  392. // modulation waveforms
  393. m_mod[ ch ][ MOD_MORPH ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_n1to1, false, 1.0f );
  394. m_finc[ ch ][ MOD_MORPH ] = 1.0f / frand_mm( 14.5f, 38.0f );
  395. RandWave( &m_mod[ ch ][ MOD_MORPH ], 0.3f, 0.7f );
  396. m_mod[ ch ][ MOD_LEVEL ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_0to1, false, 1.0f );
  397. m_finc[ ch ][ MOD_LEVEL ] = 1.0f / frand_mm( 14.5f, 38.0f );
  398. RandWave( &m_mod[ ch ][ MOD_LEVEL ], 0.1f, 0.4f );
  399. m_mod[ ch ][ MOD_DET1 ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_0to1, false, 1.0f );
  400. m_finc[ ch ][ MOD_DET1 ] = 1.0f / frand_mm( 14.5f, 38.0f );
  401. RandWave( &m_mod[ ch ][ MOD_DET1 ], 0.01f, 0.1f );
  402. m_mod[ ch ][ MOD_DET2 ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_0to1, false, 1.0f );
  403. m_finc[ ch ][ MOD_DET2 ] = 1.0f / frand_mm( 14.5f, 38.0f );
  404. RandWave( &m_mod[ ch ][ MOD_DET2 ], 0.01f, 0.1f );
  405. }
  406. //-----------------------------------------------------
  407. // Procedure: BuildDrone
  408. //
  409. //-----------------------------------------------------
  410. void Dronez::BuildDrone( void )
  411. {
  412. int i, ch;
  413. init_rand( m_Seed );
  414. for( ch = 0; ch < nCHANNELS; ch++ )
  415. {
  416. BuildWave( ch );
  417. }
  418. m_global[ GOSC_FILTER ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_0to1, false, 1.0f );
  419. m_GlobalOsc[ GOSC_FILTER ].finc = 1.0f / frand_mm( 14.5f, 38.0f );
  420. RandWave( &m_global[ GOSC_FILTER ], 0.01f, 1.0f );
  421. //m_GlobalOsc[GOSC_FILTERi ].Env.Preset( EnvelopeData::PRESET_SIN );
  422. //RandPresetWaveAdjust( &m_GlobalOsc[GOSC_FILTER ].Env );
  423. m_global[ GOSC_NOISE ].Init( EnvelopeData::MODE_LOOP, EnvelopeData::RANGE_0to1, false, 1.0f );
  424. m_GlobalOsc[ GOSC_NOISE ].finc = 1.0f / frand_mm( 14.5f, 38.0f );
  425. RandWave( &m_global[ GOSC_NOISE ], 0.01f, 0.3f );
  426. //m_GlobalOsc[GOSC_NOISE ].Env.Preset( EnvelopeData::PRESET_SIN );
  427. //RandPresetWaveAdjust( &m_GlobalOsc[ GOSC_NOISE ].Env );
  428. m_cuttoff = frand_mm( 0.05f, 0.4f );
  429. m_rez = frand_mm( 0.1f, 0.8f );
  430. //-----------------------------------------------------
  431. // Reverb
  432. for( i = 0; i < REV_TAPS; i++ )
  433. m_reverb.out[ i ] = ( m_reverb.in - (int)( engineGetSampleRate() * frand_mm( 0.01f, .1f ) ) ) & REV_BUF_MAX;
  434. m_bInitialized = true;
  435. }
  436. //-----------------------------------------------------
  437. // Procedure: putf
  438. //
  439. //-----------------------------------------------------
  440. void Dronez::putf( float fval )
  441. {
  442. char strVal[ 10 ] = {};
  443. sprintf( strVal, "%.3f", fval );
  444. m_pTextLabel->text = strVal;
  445. }
  446. //-----------------------------------------------------
  447. // Procedure: putf
  448. //
  449. //-----------------------------------------------------
  450. void Dronez::putx( int x )
  451. {
  452. char strVal[ 10 ] = {};
  453. sprintf( strVal, "%.8X", x );
  454. m_pTextLabel->text = strVal;
  455. }
  456. //-----------------------------------------------------
  457. // Procedure: ChangeFilterCutoff
  458. //
  459. //-----------------------------------------------------
  460. void Dronez::ChangeFilterCutoff( FILTER_STRUCT *pf, float cutfreq )
  461. {
  462. float fx, fx2, fx3, fx5, fx7;
  463. // clamp at 1.0 and 20/samplerate
  464. cutfreq = fmax(cutfreq, 20 / engineGetSampleRate());
  465. cutfreq = fmin(cutfreq, 1.0);
  466. // calculate eq rez freq
  467. fx = 3.141592 * (cutfreq * 0.026315789473684210526315789473684) * 2 * 3.141592;
  468. fx2 = fx*fx;
  469. fx3 = fx2*fx;
  470. fx5 = fx3*fx2;
  471. fx7 = fx5*fx2;
  472. pf->f = 2.0 * (fx
  473. - (fx3 * 0.16666666666666666666666666666667)
  474. + (fx5 * 0.0083333333333333333333333333333333)
  475. - (fx7 * 0.0001984126984126984126984126984127));
  476. }
  477. //-----------------------------------------------------
  478. // Procedure: Filter
  479. //
  480. //-----------------------------------------------------
  481. #define MULTI (0.33333333333333333333333333333333f)
  482. void Dronez::processFilter( FILTER_STRUCT *pf, float *pIn )
  483. {
  484. float rez, hp1;
  485. float input, lowpass, bandpass, highpass;
  486. rez = 1.0 - m_rez;
  487. input = *pIn / AUDIO_MAX;
  488. input = input + 0.000000001;
  489. pf->lp1 = pf->lp1 + pf->f * pf->bp1;
  490. hp1 = input - pf->lp1 - rez * pf->bp1;
  491. pf->bp1 = pf->f * hp1 + pf->bp1;
  492. lowpass = pf->lp1;
  493. highpass = hp1;
  494. bandpass = pf->bp1;
  495. pf->lp1 = pf->lp1 + pf->f * pf->bp1;
  496. hp1 = input - pf->lp1 - rez * pf->bp1;
  497. pf->bp1 = pf->f * hp1 + pf->bp1;
  498. lowpass = lowpass + pf->lp1;
  499. highpass = highpass + hp1;
  500. bandpass = bandpass + pf->bp1;
  501. input = input - 0.000000001;
  502. pf->lp1 = pf->lp1 + pf->f * pf->bp1;
  503. hp1 = input - pf->lp1 - rez * pf->bp1;
  504. pf->bp1 = pf->f * hp1 + pf->bp1;
  505. lowpass = (lowpass + pf->lp1) * MULTI;
  506. highpass = (highpass + hp1) * MULTI;
  507. bandpass = (bandpass + pf->bp1) * MULTI;
  508. /*switch( pf->type )
  509. {
  510. case FILTER_LP:
  511. out = lowpass;
  512. break;
  513. case FILTER_HP:
  514. out = highpass;
  515. break;
  516. case FILTER_BP:
  517. out = bandpass;
  518. break;
  519. case FILTER_NT:
  520. out = lowpass + highpass;
  521. break;
  522. default:
  523. return;
  524. }*/
  525. *pIn = lowpass * AUDIO_MAX;
  526. }
  527. //-----------------------------------------------------
  528. // Procedure: processReverb
  529. //
  530. //-----------------------------------------------------
  531. void Dronez::processReverb( float In, float *pL, float *pR )
  532. {
  533. float fl = 0, fr = 0, rin;
  534. for( int i = 0; i < REV_TAPS; i++ )
  535. {
  536. rin = m_reverb.buf[ m_reverb.out[ i ]++ ] * 0.2f;
  537. m_reverb.out[ i ] &= REV_BUF_MAX;
  538. if( i < (REV_TAPS / 2) )
  539. fl += rin;
  540. else
  541. fr += rin;
  542. }
  543. m_reverb.buf[ m_reverb.in++ ] = In;
  544. m_reverb.in &= REV_BUF_MAX;
  545. *pL = (In * .3) + fl;
  546. *pR = (In * .3) + fr;
  547. }
  548. //-----------------------------------------------------
  549. // Procedure: step
  550. //
  551. //-----------------------------------------------------
  552. void Dronez::step()
  553. {
  554. float out = 0.0f, In =0.0f, outL = 0.0f, outR = 0.0f, fmorph[ nCHANNELS ], fcv=0.0f;
  555. int ch, i, wv;
  556. if( !m_bInitialized )
  557. return;
  558. // randomize trigger
  559. if( m_SchmitTrigRand.process( inputs[ IN_RANDTRIG ].normalize( 0.0f ) ) )
  560. {
  561. m_pButtonRand->Set( true );
  562. ChangeSeedPending( (int)randomu32() );
  563. }
  564. switch( m_FadeState )
  565. {
  566. case FADE_OUT:
  567. m_fFade -= 0.00005f;
  568. if( m_fFade <= 0.0f )
  569. {
  570. m_fFade = 0.0f;
  571. BuildDrone();
  572. m_FadeState = FADE_IN;
  573. }
  574. break;
  575. case FADE_IN:
  576. m_fFade += 0.00005f;
  577. if( m_fFade >= 1.0f )
  578. {
  579. m_fFade = 1.0f;
  580. m_FadeState = FADE_IDLE;
  581. }
  582. break;
  583. case FADE_IDLE:
  584. default:
  585. break;
  586. }
  587. for( i = 0; i < nGLOBALOSCS; i++ )
  588. {
  589. m_global[ i ].m_Clock.syncInc = m_GlobalOsc[ i ].finc * speeds[ (int)params[ PARAM_SPEED ].value ];
  590. m_GlobalOsc[ i ].fval = m_global[ i ].procStep( false, false );
  591. }
  592. // process oscillators
  593. for( ch = 0; ch < nCHANNELS; ch++ )
  594. {
  595. // process modulation waves
  596. for( i = 0; i < nMODS; i++ )
  597. {
  598. m_mod[ ch ][ i ].m_Clock.syncInc = m_finc[ ch ][ i ] * speeds[ (int)params[ PARAM_SPEED ].value ];
  599. m_osc[ ch ].fval[ i ] = m_mod[ ch ][ i ].procStep( false, false );
  600. }
  601. // wav morph modulation
  602. memset( fmorph, 0, sizeof(fmorph));
  603. fcv = m_osc[ ch ].fval[ MOD_MORPH ];
  604. fmorph[ 1 ] = 1.0 - fabs( fcv );
  605. // left wave
  606. if( fcv <= 0.0f )
  607. {
  608. fmorph[ 0 ] = -fcv;
  609. }
  610. else
  611. {
  612. fmorph[ 2 ] = fcv;
  613. }
  614. In= 0.0f;
  615. // get wave audio
  616. for( wv = 0; wv < nMORPH_WAVES; wv++ )
  617. {
  618. m_wav[ ch ][ wv ].m_Clock.syncInc = 32.7032f * clamp( powf( 2.0f, clamp( inputs[ IN_VOCT ].normalize( 3.0f ) + m_osc[ ch ].semi, 0.0f, VOCT_MAX ) ), 0.0f, 4186.01f );
  619. if( wv == 0 )
  620. {
  621. m_wav[ ch ][ wv ].m_Clock.syncInc += m_osc[ ch ].fval[ MOD_DET1 ];
  622. }
  623. else if( wv == 2 )
  624. {
  625. m_wav[ ch ][ wv ].m_Clock.syncInc += m_osc[ ch ].fval[ MOD_DET2 ];
  626. }
  627. In += m_wav[ ch ][ wv ].procStep( false, false ) * fmorph[ wv ];
  628. }
  629. if( wv != 1 )
  630. out += In * m_osc[ ch ].fval[ MOD_LEVEL ];
  631. else
  632. out += In;
  633. }
  634. if( frand_perc( 75.0f ) )
  635. out += frand_mm( -1.0f, 1.0f ) * m_GlobalOsc[ GOSC_NOISE ].fval;
  636. // filter
  637. ChangeFilterCutoff( &m_filter, m_cuttoff * m_GlobalOsc[ GOSC_FILTER ].fval );
  638. processFilter( &m_filter, &out );
  639. out *= m_fFade;
  640. processReverb( out, &outL, &outR );
  641. outputs[ OUT_L ].value = outL;
  642. outputs[ OUT_R ].value = outR;
  643. }
  644. } // namespace rack_plugin_mscHack
  645. using namespace rack_plugin_mscHack;
  646. RACK_PLUGIN_MODEL_INIT(mscHack, Dronez) {
  647. Model *modelDronez = Model::create<Dronez, Dronez_Widget>( "mscHack", "Dronez", "Dronez module", OSCILLATOR_TAG, MULTIPLE_TAG );
  648. return modelDronez;
  649. }