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.

855 lines
23KB

  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 nCHANNELS 3
  7. #define CHANNEL_H 90
  8. #define CHANNEL_Y 65
  9. #define CHANNEL_X 10
  10. #define MAX_nWAVES 7
  11. #define MAX_DETUNE 20 //Hz
  12. #define freqMAX 300.0f
  13. #define ADS_MAX_TIME_SECONDS 0.5f
  14. #define WAVE_BUFFER_LEN ( 192000 / 20 ) // (9600) based on quality for 20Hz at max sample rate 192000
  15. typedef struct
  16. {
  17. int state;
  18. int a, d, r;
  19. int acount, dcount, rcount, fadecount;
  20. float fainc, frinc, fadeinc;
  21. float out;
  22. bool bTrig;
  23. }ADR_STRUCT;
  24. typedef struct
  25. {
  26. int wavetype;
  27. int filtertype;
  28. // wave
  29. float phase[ MAX_nWAVES ];
  30. float freq[ MAX_nWAVES ];
  31. //filter
  32. float q, f;
  33. float lp1[ 2 ] = {}, bp1[ 2 ] = {};
  34. // ads
  35. ADR_STRUCT adr_wave;
  36. }OSC_PARAM_STRUCT;
  37. //-----------------------------------------------------
  38. // Module Definition
  39. //
  40. //-----------------------------------------------------
  41. struct Osc_3Ch : Module
  42. {
  43. enum WaveTypes
  44. {
  45. WAVE_SIN,
  46. WAVE_TRI,
  47. WAVE_SQR,
  48. WAVE_SAW,
  49. WAVE_NOISE,
  50. nWAVEFORMS
  51. };
  52. enum ParamIds
  53. {
  54. PARAM_DELAY,
  55. PARAM_ATT = PARAM_DELAY + nCHANNELS,
  56. PARAM_REL = PARAM_ATT + nCHANNELS,
  57. PARAM_REZ = PARAM_REL + nCHANNELS,
  58. PARAM_WAVES = PARAM_REZ + nCHANNELS,
  59. PARAM_CUTOFF = PARAM_WAVES + (nWAVEFORMS * nCHANNELS),
  60. PARAM_RES = PARAM_CUTOFF + nCHANNELS,
  61. PARAM_OUTLVL = PARAM_RES + nCHANNELS,
  62. PARAM_FILTER_MODE = PARAM_OUTLVL + nCHANNELS,
  63. PARAM_nWAVES = PARAM_FILTER_MODE + nCHANNELS,
  64. PARAM_SPREAD = PARAM_nWAVES + nCHANNELS,
  65. PARAM_DETUNE = PARAM_SPREAD + nCHANNELS,
  66. nPARAMS = PARAM_DETUNE + nCHANNELS
  67. };
  68. enum InputIds
  69. {
  70. IN_VOCT,
  71. IN_TRIG = IN_VOCT + nCHANNELS,
  72. IN_FILTER = IN_TRIG + nCHANNELS,
  73. IN_REZ = IN_FILTER + nCHANNELS,
  74. IN_LEVEL = IN_REZ + nCHANNELS,
  75. nINPUTS = IN_LEVEL + nCHANNELS,
  76. };
  77. enum OutputIds
  78. {
  79. OUTPUT_AUDIO,
  80. nOUTPUTS = OUTPUT_AUDIO + (nCHANNELS * 2)
  81. };
  82. enum ADRSTATES
  83. {
  84. ADR_OFF,
  85. ADR_FADE,
  86. ADR_WAIT_PHASE,
  87. ADR_FADE_OUT,
  88. ADR_ATTACK,
  89. ADR_DELAY,
  90. ADR_RELEASE
  91. };
  92. enum FILTER_TYPES
  93. {
  94. FILTER_OFF,
  95. FILTER_LP,
  96. FILTER_HP,
  97. FILTER_BP,
  98. FILTER_NT
  99. };
  100. bool m_bInitialized = false;
  101. CLog lg;
  102. SchmittTrigger m_SchTrig[ nCHANNELS ];
  103. OSC_PARAM_STRUCT m_Wave[ nCHANNELS ] = {};
  104. // waveforms
  105. float m_BufferWave[ nWAVEFORMS ][ WAVE_BUFFER_LEN ] = {};
  106. float m_DetuneIn[ nCHANNELS ] = {};
  107. float m_Detune[ nCHANNELS ][ MAX_nWAVES ][ MAX_nWAVES ];
  108. float m_SpreadIn[ nCHANNELS ] = {};
  109. float m_Pan[ nCHANNELS ][ MAX_nWAVES ][ MAX_nWAVES ][ 2 ];
  110. int m_nWaves[ nCHANNELS ] = {};
  111. MyLEDButtonStrip *m_pButtonWaveSelect[ nCHANNELS ] = {};
  112. // Contructor
  113. Osc_3Ch() : Module( nPARAMS, nINPUTS, nOUTPUTS, 0 ){}
  114. //-----------------------------------------------------
  115. // MynWaves_Knob
  116. //-----------------------------------------------------
  117. struct MynWaves_Knob : Knob_Yellow3_20_Snap
  118. {
  119. Osc_3Ch *mymodule;
  120. int param;
  121. void onChange( EventChange &e ) override
  122. {
  123. mymodule = (Osc_3Ch*)module;
  124. if( mymodule )
  125. {
  126. param = paramId - Osc_3Ch::PARAM_nWAVES;
  127. mymodule->m_nWaves[ param ] = (int)( value );
  128. }
  129. RoundKnob::onChange( e );
  130. }
  131. };
  132. //-----------------------------------------------------
  133. // MyEQHi_Knob
  134. //-----------------------------------------------------
  135. struct MyDetune_Knob : Knob_Yellow3_20
  136. {
  137. Osc_3Ch *mymodule;
  138. int param;
  139. void onChange( EventChange &e ) override
  140. {
  141. mymodule = (Osc_3Ch*)module;
  142. if( mymodule )
  143. {
  144. param = paramId - Osc_3Ch::PARAM_DETUNE;
  145. mymodule->m_DetuneIn[ param ] = value;
  146. mymodule->CalcDetune( param );
  147. }
  148. RoundKnob::onChange( e );
  149. }
  150. };
  151. //-----------------------------------------------------
  152. // MyEQHi_Knob
  153. //-----------------------------------------------------
  154. struct MySpread_Knob : Knob_Yellow3_20
  155. {
  156. Osc_3Ch *mymodule;
  157. int param;
  158. void onChange( EventChange &e ) override
  159. {
  160. mymodule = (Osc_3Ch*)module;
  161. if( mymodule )
  162. {
  163. param = paramId - Osc_3Ch::PARAM_SPREAD;
  164. mymodule->m_SpreadIn[ param ] = value;
  165. mymodule->CalcSpread( param );
  166. }
  167. RoundKnob::onChange( e );
  168. }
  169. };
  170. // Overrides
  171. void step() override;
  172. json_t* toJson() override;
  173. void fromJson(json_t *rootJ) override;
  174. void onRandomize() override;
  175. void onReset() override;
  176. void CalcSpread( int ch );
  177. void CalcDetune( int ch );
  178. void SetWaveLights( void );
  179. void BuildWaves( void );
  180. void ChangeFilterCutoff( int ch, float cutfreq );
  181. void Filter( int ch, float *InL, float *InR );
  182. float GetWave( int type, float phase );
  183. float ProcessADR( int ch );
  184. void GetAudio( int ch, float *pOutL, float *pOutR, float flevel );
  185. };
  186. //-----------------------------------------------------
  187. // Osc_3Ch_WaveSelect
  188. //-----------------------------------------------------
  189. void Osc_3Ch_WaveSelect( void *pClass, int id, int nbutton, bool bOn )
  190. {
  191. Osc_3Ch *mymodule;
  192. mymodule = (Osc_3Ch*)pClass;
  193. mymodule->m_Wave[ id ].wavetype = nbutton;
  194. }
  195. //-----------------------------------------------------
  196. // Procedure: Widget
  197. //
  198. //-----------------------------------------------------
  199. struct Osc_3Ch_Widget : ModuleWidget {
  200. Osc_3Ch_Widget( Osc_3Ch *module );
  201. };
  202. Osc_3Ch_Widget::Osc_3Ch_Widget( Osc_3Ch *module ) : ModuleWidget(module)
  203. {
  204. int ch, x, y, x2, y2;
  205. box.size = Vec( 15*21, 380);
  206. {
  207. SVGPanel *panel = new SVGPanel();
  208. panel->box.size = box.size;
  209. panel->setBackground(SVG::load(assetPlugin(plugin, "res/OSC3Channel.svg")));
  210. addChild(panel);
  211. }
  212. //module->lg.Open("OSC3Channel.txt");
  213. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  214. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  215. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  216. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  217. y = CHANNEL_Y;
  218. x = CHANNEL_X;
  219. for( ch = 0; ch < nCHANNELS; ch++ )
  220. {
  221. x = CHANNEL_X;
  222. // inputs
  223. addInput(Port::create<MyPortInSmall>( Vec( x, y ), Port::INPUT, module, Osc_3Ch::IN_VOCT + ch ) );
  224. addInput(Port::create<MyPortInSmall>( Vec( x, y + 43 ), Port::INPUT, module, Osc_3Ch::IN_TRIG + ch ) );
  225. x2 = x + 32;
  226. y2 = y + 52;
  227. module->m_pButtonWaveSelect[ ch ] = new MyLEDButtonStrip( x2, y2, 11, 11, 5, 8.0, 5, false, DWRGB( 180, 180, 180 ), DWRGB( 255, 255, 0 ), MyLEDButtonStrip::TYPE_EXCLUSIVE, ch, module, Osc_3Ch_WaveSelect );
  228. addChild( module->m_pButtonWaveSelect[ ch ] );
  229. x2 = x + 24;
  230. y2 = y + 18;
  231. // params
  232. addParam(ParamWidget::create<Knob_Yellow2_26>( Vec( x2, y2 ), module, Osc_3Ch::PARAM_ATT + ch, 0.0, 1.0, 0.0 ) );
  233. x2 += 31;
  234. addParam(ParamWidget::create<Knob_Yellow2_26>( Vec( x2, y2 ), module, Osc_3Ch::PARAM_DELAY + ch, 0.0, 1.0, 0.0 ) );
  235. x2 += 31;
  236. addParam(ParamWidget::create<Knob_Yellow2_26>( Vec( x2, y2 ), module, Osc_3Ch::PARAM_REL + ch, 0.0, 1.0, 0.0 ) );
  237. // waves/detune/spread
  238. x2 = x + 149;
  239. y2 = y + 56;
  240. addParam(ParamWidget::create<Osc_3Ch::MynWaves_Knob>( Vec( x + 129, y + 11 ), module, Osc_3Ch::PARAM_nWAVES + ch, 0.0, 6.0, 0.0 ) );
  241. addParam(ParamWidget::create<Osc_3Ch::MyDetune_Knob>( Vec( x + 116, y + 48 ), module, Osc_3Ch::PARAM_DETUNE + ch, 0.0, 0.05, 0.0 ) );
  242. addParam(ParamWidget::create<Osc_3Ch::MySpread_Knob>( Vec( x + 116 + 28, y + 48 ), module, Osc_3Ch::PARAM_SPREAD + ch, 0.0, 1.0, 0.0 ) );
  243. // inputs
  244. x2 = x + 178;
  245. y2 = y + 51;
  246. addInput(Port::create<MyPortInSmall>( Vec( x2, y2 ), Port::INPUT, module, Osc_3Ch::IN_FILTER + ch ) );
  247. x2 += 36;
  248. addInput(Port::create<MyPortInSmall>( Vec( x2, y2 ), Port::INPUT, module, Osc_3Ch::IN_REZ + ch ) );
  249. x2 += 40;
  250. addInput(Port::create<MyPortInSmall>( Vec( x2, y2 ), Port::INPUT, module, Osc_3Ch::IN_LEVEL + ch ) );
  251. // filter
  252. y2 = y + 6;
  253. x2 = x + 167;
  254. addParam(ParamWidget::create<Knob_Green1_40>( Vec( x2, y2 ), module, Osc_3Ch::PARAM_CUTOFF + ch, 0.0, 0.1, 0.0 ) );
  255. addParam(ParamWidget::create<FilterSelectToggle>( Vec( x2 + 43, y2 + 2 ), module, Osc_3Ch::PARAM_FILTER_MODE + ch, 0.0, 4.0, 0.0 ) );
  256. addParam(ParamWidget::create<Knob_Purp1_20>( Vec( x2 + 46, y2 + 20 ), module, Osc_3Ch::PARAM_RES + ch, 0.0, 1.0, 0.0 ) );
  257. // main level
  258. addParam(ParamWidget::create<Knob_Blue2_40>( Vec( x2 + 76, y2 ), module, Osc_3Ch::PARAM_OUTLVL + ch, 0.0, 1.0, 0.0 ) );
  259. // outputs
  260. addOutput(Port::create<MyPortOutSmall>( Vec( x + 283, y + 4 ), Port::OUTPUT, module, Osc_3Ch::OUTPUT_AUDIO + (ch * 2) ) );
  261. addOutput(Port::create<MyPortOutSmall>( Vec( x + 283, y + 53 ), Port::OUTPUT, module, Osc_3Ch::OUTPUT_AUDIO + (ch * 2) + 1 ) );
  262. y += CHANNEL_H;
  263. module->m_nWaves[ ch ] = 0;
  264. }
  265. module->m_bInitialized = true;
  266. module->BuildWaves();
  267. module->SetWaveLights();
  268. }
  269. //-----------------------------------------------------
  270. // Procedure:
  271. //
  272. //-----------------------------------------------------
  273. json_t *Osc_3Ch::toJson()
  274. {
  275. json_t *gatesJ;
  276. json_t *rootJ = json_object();
  277. // wavetypes
  278. gatesJ = json_array();
  279. for (int i = 0; i < nCHANNELS; i++)
  280. {
  281. json_t *gateJ = json_integer( m_Wave[ i ].wavetype );
  282. json_array_append_new( gatesJ, gateJ );
  283. }
  284. json_object_set_new( rootJ, "wavetypes", gatesJ );
  285. return rootJ;
  286. }
  287. //-----------------------------------------------------
  288. // Procedure: fromJson
  289. //
  290. //-----------------------------------------------------
  291. void Osc_3Ch::fromJson(json_t *rootJ)
  292. {
  293. int i;
  294. json_t *StepsJ;
  295. // wave select
  296. StepsJ = json_object_get( rootJ, "wavetypes" );
  297. if (StepsJ)
  298. {
  299. for ( i = 0; i < nCHANNELS; i++)
  300. {
  301. json_t *gateJ = json_array_get(StepsJ, i);
  302. if (gateJ)
  303. m_Wave[ i ].wavetype = json_integer_value( gateJ );
  304. }
  305. }
  306. // set up parameters
  307. for ( i = 0; i < nCHANNELS; i++)
  308. {
  309. m_nWaves[ i ] = (int)( params[ PARAM_nWAVES + i ].value );
  310. m_SpreadIn[ i ] = params[ PARAM_SPREAD + i ].value;
  311. CalcSpread( i );
  312. m_DetuneIn[ i ] = params[ PARAM_DETUNE + i ].value;
  313. CalcDetune( i );
  314. }
  315. SetWaveLights();
  316. }
  317. //-----------------------------------------------------
  318. // Procedure: reset
  319. //
  320. //-----------------------------------------------------
  321. void Osc_3Ch::onReset()
  322. {
  323. }
  324. //-----------------------------------------------------
  325. // Procedure: randomize
  326. //
  327. //-----------------------------------------------------
  328. void Osc_3Ch::onRandomize()
  329. {
  330. int ch;
  331. for( ch = 0; ch < nCHANNELS; ch++ )
  332. {
  333. m_Wave[ ch ].wavetype = (int)( randomUniform() * (nWAVEFORMS-1) );
  334. }
  335. SetWaveLights();
  336. }
  337. //-----------------------------------------------------
  338. // Procedure: SetWaveLights
  339. //
  340. //-----------------------------------------------------
  341. void Osc_3Ch::SetWaveLights( void )
  342. {
  343. int ch;
  344. for( ch = 0; ch < nCHANNELS; ch++ )
  345. m_pButtonWaveSelect[ ch ]->Set( m_Wave[ ch ].wavetype, true );
  346. }
  347. //-----------------------------------------------------
  348. // Procedure: initialize
  349. //
  350. //-----------------------------------------------------
  351. //#define DEG2RAD( x ) ( ( x ) * ( 3.14159f / 180.0f ) )
  352. void Osc_3Ch::BuildWaves( void )
  353. {
  354. int i;
  355. float finc, pos, val;
  356. finc = 360.0 / WAVE_BUFFER_LEN;
  357. pos = 0;
  358. // create sin wave
  359. for( i = 0; i < WAVE_BUFFER_LEN; i++ )
  360. {
  361. m_BufferWave[ WAVE_SIN ][ i ] = sin( DEG2RAD( pos ) );
  362. pos += finc;
  363. }
  364. // create sqr wave
  365. for( i = 0; i < WAVE_BUFFER_LEN; i++ )
  366. {
  367. if( i < WAVE_BUFFER_LEN / 2 )
  368. m_BufferWave[ WAVE_SQR ][ i ] = 1.0;
  369. else
  370. m_BufferWave[ WAVE_SQR ][ i ] = -1.0;
  371. }
  372. finc = 2.0 / (float)WAVE_BUFFER_LEN;
  373. val = 1.0;
  374. // create saw wave
  375. for( i = 0; i < WAVE_BUFFER_LEN; i++ )
  376. {
  377. m_BufferWave[ WAVE_SAW ][ i ] = val;
  378. val -= finc;
  379. }
  380. finc = 4 / (float)WAVE_BUFFER_LEN;
  381. val = 0;
  382. // create tri wave
  383. for( i = 0; i < WAVE_BUFFER_LEN; i++ )
  384. {
  385. m_BufferWave[ WAVE_TRI ][ i ] = val;
  386. if( i < WAVE_BUFFER_LEN / 4 )
  387. val += finc;
  388. else if( i < (WAVE_BUFFER_LEN / 4) * 3 )
  389. val -= finc;
  390. else if( i < WAVE_BUFFER_LEN )
  391. val += finc;
  392. }
  393. }
  394. //-----------------------------------------------------
  395. // Procedure: GetAudio
  396. //
  397. //-----------------------------------------------------
  398. float Osc_3Ch::GetWave( int type, float phase )
  399. {
  400. float fval = 0.0;
  401. float ratio = (float)(WAVE_BUFFER_LEN-1) / engineGetSampleRate();
  402. switch( type )
  403. {
  404. case WAVE_SIN:
  405. case WAVE_TRI:
  406. case WAVE_SQR:
  407. case WAVE_SAW:
  408. fval = m_BufferWave[ type ][ int( ( phase * ratio ) + 0.5 ) ];
  409. break;
  410. case WAVE_NOISE:
  411. fval = ( randomUniform() > 0.5 ) ? (randomUniform() * -1.0) : randomUniform();
  412. break;
  413. default:
  414. break;
  415. }
  416. return fval;
  417. }
  418. //-----------------------------------------------------
  419. // Procedure: ProcessADS
  420. //
  421. //-----------------------------------------------------
  422. float Osc_3Ch::ProcessADR( int ch )
  423. {
  424. ADR_STRUCT *padr;
  425. padr = &m_Wave[ ch ].adr_wave;
  426. // retrig the adsr
  427. if( padr->bTrig )
  428. {
  429. padr->state = ADR_FADE;
  430. padr->fadecount = 900;
  431. padr->fadeinc = padr->out / (float)padr->fadecount;
  432. padr->acount = 40 + (int)( params[ PARAM_ATT + ch ].value * 2.0f * engineGetSampleRate() );
  433. padr->fainc = 1.0f / (float)padr->acount;
  434. padr->dcount = (int)( params[ PARAM_DELAY + ch ].value * 4.0f * engineGetSampleRate() );
  435. padr->rcount = 20 + (int)( params[ PARAM_REL + ch ].value * 10.0f * engineGetSampleRate() );
  436. padr->frinc = 1.0f / (float)padr->rcount;
  437. padr->bTrig = false;
  438. }
  439. // process
  440. switch( padr->state )
  441. {
  442. case ADR_FADE:
  443. if( --padr->fadecount <= 0 )
  444. {
  445. padr->state = ADR_ATTACK;
  446. padr->out = 0.0f;
  447. m_Wave[ ch ].phase[ 0 ] = 0.0f;
  448. m_Wave[ ch ].phase[ 1 ] = 0.0f;
  449. m_Wave[ ch ].phase[ 2 ] = 0.0f;
  450. m_Wave[ ch ].phase[ 3 ] = 0.0f;
  451. m_Wave[ ch ].phase[ 4 ] = 0.0f;
  452. m_Wave[ ch ].phase[ 5 ] = 0.0f;
  453. m_Wave[ ch ].phase[ 6 ] = 0.0f;
  454. }
  455. else
  456. {
  457. padr->out -= padr->fadeinc;
  458. }
  459. break;
  460. case ADR_OFF:
  461. padr->out = 0.0f;
  462. break;
  463. case ADR_ATTACK:
  464. if( --padr->acount <= 0 )
  465. {
  466. padr->state = ADR_DELAY;
  467. }
  468. else
  469. {
  470. padr->out += padr->fainc;
  471. }
  472. break;
  473. case ADR_DELAY:
  474. padr->out = 1.0f;
  475. if( --padr->dcount <= 0 )
  476. {
  477. padr->state = ADR_RELEASE;
  478. }
  479. break;
  480. case ADR_RELEASE:
  481. if( --padr->rcount <= 0 )
  482. {
  483. padr->state = ADR_OFF;
  484. padr->out = 0.0f;
  485. }
  486. else
  487. {
  488. padr->out -= padr->frinc;
  489. }
  490. break;
  491. }
  492. return clamp( padr->out, 0.0f, 1.0f );
  493. }
  494. //-----------------------------------------------------
  495. // Procedure: ChangeFilterCutoff
  496. //
  497. //-----------------------------------------------------
  498. void Osc_3Ch::ChangeFilterCutoff( int ch, float cutfreq )
  499. {
  500. float fx, fx2, fx3, fx5, fx7;
  501. // clamp at 1.0 and 20/samplerate
  502. cutfreq = fmax(cutfreq, 20 / engineGetSampleRate());
  503. cutfreq = fmin(cutfreq, 1.0);
  504. // calculate eq rez freq
  505. fx = 3.141592 * (cutfreq * 0.026315789473684210526315789473684) * 2 * 3.141592;
  506. fx2 = fx*fx;
  507. fx3 = fx2*fx;
  508. fx5 = fx3*fx2;
  509. fx7 = fx5*fx2;
  510. m_Wave[ ch ].f = 2.0 * (fx
  511. - (fx3 * 0.16666666666666666666666666666667)
  512. + (fx5 * 0.0083333333333333333333333333333333)
  513. - (fx7 * 0.0001984126984126984126984126984127));
  514. }
  515. //-----------------------------------------------------
  516. // Procedure: Filter
  517. //
  518. //-----------------------------------------------------
  519. #define MULTI (0.33333333333333333333333333333333f)
  520. void Osc_3Ch::Filter( int ch, float *InL, float *InR )
  521. {
  522. OSC_PARAM_STRUCT *p;
  523. float rez, hp1;
  524. float input[ 2 ], out[ 2 ], lowpass, bandpass, highpass;
  525. if( (int)params[ PARAM_FILTER_MODE + ch ].value == 0 )
  526. return;
  527. p = &m_Wave[ ch ];
  528. rez = 1.0 - params[ PARAM_RES + ch ].value;
  529. input[ 0 ] = *InL;
  530. input[ 1 ] = *InR;
  531. // do left and right channels
  532. for( int i = 0; i < 2; i++ )
  533. {
  534. input[ i ] = input[ i ] + 0.000000001;
  535. p->lp1[ i ] = p->lp1[ i ] + p->f * p->bp1[ i ];
  536. hp1 = input[ i ] - p->lp1[ i ] - rez * p->bp1[ i ];
  537. p->bp1[ i ] = p->f * hp1 + p->bp1[ i ];
  538. lowpass = p->lp1[ i ];
  539. highpass = hp1;
  540. bandpass = p->bp1[ i ];
  541. p->lp1[ i ] = p->lp1[ i ] + p->f * p->bp1[ i ];
  542. hp1 = input[ i ] - p->lp1[ i ] - rez * p->bp1[ i ];
  543. p->bp1[ i ] = p->f * hp1 + p->bp1[ i ];
  544. lowpass = lowpass + p->lp1[ i ];
  545. highpass = highpass + hp1;
  546. bandpass = bandpass + p->bp1[ i ];
  547. input[ i ] = input[ i ] - 0.000000001;
  548. p->lp1[ i ] = p->lp1[ i ] + p->f * p->bp1[ i ];
  549. hp1 = input[ i ] - p->lp1[ i ] - rez * p->bp1[ i ];
  550. p->bp1[ i ] = p->f * hp1 + p->bp1[ i ];
  551. lowpass = (lowpass + p->lp1[ i ]) * MULTI;
  552. highpass = (highpass + hp1) * MULTI;
  553. bandpass = (bandpass + p->bp1[ i ]) * MULTI;
  554. switch( (int)params[ PARAM_FILTER_MODE + ch ].value )
  555. {
  556. case FILTER_LP:
  557. out[ i ] = lowpass;
  558. break;
  559. case FILTER_HP:
  560. out[ i ] = highpass;
  561. break;
  562. case FILTER_BP:
  563. out[ i ] = bandpass;
  564. break;
  565. case FILTER_NT:
  566. out[ i ] = lowpass + highpass;
  567. break;
  568. default:
  569. break;
  570. }
  571. }
  572. *InL = out[ 0 ];
  573. *InR = out[ 1 ];
  574. }
  575. //-----------------------------------------------------
  576. // Procedure: CalcSpread
  577. //
  578. //-----------------------------------------------------
  579. typedef struct
  580. {
  581. float pan[ 2 ];
  582. float maxdetune;
  583. }PAN_DETUNE;
  584. PAN_DETUNE pandet[ 7 ][ 7 ] =
  585. {
  586. { { {1.0, 1.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 } },
  587. { { {1.0, 0.5}, 0.1 }, { {0.5, 1.0}, 0.2 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 } },
  588. { { {1.0, 0.5}, 0.3 }, { {1.0, 1.0}, 0.0 }, { {0.5, 1.0}, 0.2 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 } },
  589. { { {1.0, 0.3}, 0.4 }, { {1.0, 0.5}, 0.2 }, { {0.5, 1.0}, 0.2 }, { {0.3, 1.0}, 0.3 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 } },
  590. { { {1.0, 0.3}, 0.5 }, { {1.0, 0.5}, 0.4 }, { {1.0, 1.0}, 0.0 }, { {0.5, 1.0}, 0.3 }, { {0.3, 1.0}, 0.1 }, { {0.0, 0.0}, 0.0 }, { {0.0, 0.0}, 0.0 } },
  591. { { {1.0, 0.2}, 0.6 }, { {1.0, 0.3}, 0.4 }, { {1.0, 0.5}, 0.2 }, { {0.5, 1.0}, 0.3 }, { {0.3, 1.0}, 0.5 }, { {0.2, 1.0}, 0.8 }, { {0.0, 0.0}, 0.0 } },
  592. { { {1.0, 0.0}, 0.9 }, { {1.0, 0.2}, 0.7 }, { {1.0, 0.3}, 0.5 }, { {1.0, 1.0}, 0.0 }, { {0.3, 1.0}, 0.4 }, { {0.2, 1.0}, 0.8 }, { {0.0, 1.0}, 1.0 } },
  593. };
  594. void Osc_3Ch::CalcSpread( int ch )
  595. {
  596. int used; // number of waves being used by channel
  597. int wave; // values for each individual wave
  598. // calculate pans for each possible number of waves being used
  599. for( used = 0; used < MAX_nWAVES; used++ )
  600. {
  601. for( wave = 0; wave <= used; wave++ )
  602. {
  603. m_Pan[ ch ][ used ][ wave ][ 0 ] = ( 1.0 - m_SpreadIn[ ch ] ) + ( pandet[ used ][ wave ].pan[ 0 ] * m_SpreadIn[ ch ] );
  604. m_Pan[ ch ][ used ][ wave ][ 1 ] = ( 1.0 - m_SpreadIn[ ch ] ) + ( pandet[ used ][ wave ].pan[ 1 ] * m_SpreadIn[ ch ] );
  605. }
  606. }
  607. }
  608. void Osc_3Ch::CalcDetune( int ch )
  609. {
  610. int used; // number of waves being used by channel
  611. int wave; // values for each individual wave
  612. // calculate detunes for each possible number of waves being used
  613. for( used = 0; used < MAX_nWAVES; used++ )
  614. {
  615. for( wave = 0; wave <= used; wave++ )
  616. m_Detune[ ch ][ used ][ wave ] = pandet[ used ][ wave ].maxdetune * MAX_DETUNE * m_DetuneIn[ ch ];
  617. }
  618. }
  619. //-----------------------------------------------------
  620. // Procedure: GetAudio
  621. //
  622. //-----------------------------------------------------
  623. void Osc_3Ch::GetAudio( int ch, float *pOutL, float *pOutR, float flevel )
  624. {
  625. float foutL = 0, foutR = 0, cutoff, adr;
  626. int i;
  627. for( i = 0; i <= m_nWaves[ ch ]; i++ )
  628. {
  629. foutL = GetWave( m_Wave[ ch ].wavetype, m_Wave[ ch ].phase[ i ] ) / 2.0;
  630. foutR = foutL;
  631. foutL *= m_Pan[ ch ][ m_nWaves[ ch ] ][ i ][ 0 ];
  632. foutR *= m_Pan[ ch ][ m_nWaves[ ch ] ][ i ][ 1 ];
  633. // ( 32.7032 is C1 ) ( 4186.01 is C8)
  634. m_Wave[ ch ].phase[ i ] += 32.7032f * clamp( powf( 2.0f, clamp( inputs[ IN_VOCT + ch ].value, 0.0f, VOCT_MAX ) ) + m_Detune[ ch ][ m_nWaves[ ch ] ][ i ], 0.0f, 4186.01f );
  635. if( m_Wave[ ch ].phase[ i ] >= engineGetSampleRate() )
  636. m_Wave[ ch ].phase[ i ] = m_Wave[ ch ].phase[ i ] - engineGetSampleRate();
  637. *pOutL += foutL;
  638. *pOutR += foutR;
  639. }
  640. adr = ProcessADR( ch );
  641. *pOutL = *pOutL * adr * flevel;
  642. *pOutR = *pOutR * adr * flevel;
  643. cutoff = clamp( params[ PARAM_CUTOFF + ch ].value * ( inputs[ IN_FILTER + ch ].normalize( CV_MAX ) / CV_MAX ), 0.0f, 1.0f );
  644. ChangeFilterCutoff( ch, cutoff );
  645. Filter( ch, pOutL, pOutR );
  646. }
  647. //-----------------------------------------------------
  648. // Procedure: step
  649. //
  650. //-----------------------------------------------------
  651. void Osc_3Ch::step()
  652. {
  653. int ch;
  654. float outL, outR, flevel;
  655. if( !m_bInitialized )
  656. return;
  657. // check for triggers
  658. for( ch = 0; ch < nCHANNELS; ch++ )
  659. {
  660. outL = 0.0;
  661. outR = 0.0;
  662. if( inputs[ IN_TRIG + ch ].active )
  663. {
  664. if( m_SchTrig[ ch ].process( inputs[ IN_TRIG + ch ].value ) )
  665. {
  666. m_Wave[ ch ].adr_wave.bTrig = true;
  667. }
  668. }
  669. flevel = clamp( params[ PARAM_OUTLVL + ch ].value + ( inputs[ IN_LEVEL + ch ].normalize( 0.0 ) / 5.0f ), 0.0f, 1.0f );
  670. GetAudio( ch, &outL, &outR, flevel );
  671. //outL = clamp( ( outL * AUDIO_MAX ), -AUDIO_MAX, AUDIO_MAX );
  672. //outR = clamp( ( outR * AUDIO_MAX ), -AUDIO_MAX, AUDIO_MAX );
  673. outL = outL * AUDIO_MAX;
  674. outR = outR * AUDIO_MAX;
  675. outputs[ OUTPUT_AUDIO + (ch * 2 ) ].value = outL;
  676. outputs[ OUTPUT_AUDIO + (ch * 2 ) + 1 ].value = outR;
  677. }
  678. }
  679. } // namespace rack_plugin_mscHack
  680. using namespace rack_plugin_mscHack;
  681. RACK_PLUGIN_MODEL_INIT(mscHack, Osc_3Ch) {
  682. Model *modelOsc_3Ch = Model::create<Osc_3Ch, Osc_3Ch_Widget>( "mscHack", "Osc_3Ch_Widget", "OSC 3 Channel", SYNTH_VOICE_TAG, OSCILLATOR_TAG, MULTIPLE_TAG );
  683. return modelOsc_3Ch;
  684. }