├── .gitattributes ├── .gitignore ├── DueTimer.cpp ├── DueTimer.h ├── EquationBank.cpp ├── EquationBank.h ├── EquationBankKhepri.cpp ├── EquationBankKhepri.h ├── EquationBankPtah.cpp ├── EquationBankPtah.h ├── EquationBankSobek.cpp ├── EquationBankSobek.h ├── EquationComposer.ino ├── FixedPointMath.cpp ├── FixedPointMath.h ├── GlobalChords.cpp ├── GlobalChords.h ├── GlobalFilterTables.cpp ├── GlobalFilterTables.h ├── GlobalFixedPointMathTables.cpp ├── GlobalFixedPointMathTables.h ├── GlobalIncrements.cpp ├── GlobalIncrements.h ├── GlobalLoops.cpp ├── GlobalLoops.h ├── GlobalRingBuffer.cpp ├── GlobalRingBuffer.h ├── GlobalSamples.cpp ├── GlobalSamples.h ├── GlobalScales.cpp ├── GlobalScales.h ├── GlobalSlopes.cpp ├── GlobalSlopes.h ├── GlobalSpeechTables.cpp ├── GlobalSpeechTables.h ├── GlobalWaveshaperTables.cpp ├── GlobalWaveshaperTables.h ├── GlobalWavetables.cpp ├── GlobalWavetables.h ├── Inputs.cpp ├── Inputs.h ├── Module.cpp ├── Module.h ├── ModuleAdd.cpp ├── ModuleAdd.h ├── ModuleAnalogInput.cpp ├── ModuleAnalogInput.h ├── ModuleArpeggio.cpp ├── ModuleArpeggio.h ├── ModuleBitReducer.cpp ├── ModuleBitReducer.h ├── ModuleChords.cpp ├── ModuleChords.h ├── ModuleClock.cpp ├── ModuleClock.h ├── ModuleClockDivider.cpp ├── ModuleClockDivider.h ├── ModuleClockedRandom.cpp ├── ModuleClockedRandom.h ├── ModuleConstant.cpp ├── ModuleConstant.h ├── ModuleCounter.cpp ├── ModuleCounter.h ├── ModuleDelay.cpp ├── ModuleDelay.h ├── ModuleDigitalInput.cpp ├── ModuleDigitalInput.h ├── ModuleDrumSequencer.cpp ├── ModuleDrumSequencer.h ├── ModuleDrumSequencer32.cpp ├── ModuleDrumSequencer32.h ├── ModuleENV.cpp ├── ModuleENV.h ├── ModuleEqDrum.cpp ├── ModuleEqDrum.h ├── ModuleEquationLooper.cpp ├── ModuleEquationLooper.h ├── ModuleEquationPlayer.cpp ├── ModuleEquationPlayer.h ├── ModuleExtClock.cpp ├── ModuleExtClock.h ├── ModuleFreeze.cpp ├── ModuleFreeze.h ├── ModuleInput.cpp ├── ModuleInput.h ├── ModuleInputSmooth.cpp ├── ModuleInputSmooth.h ├── ModuleKitSelect.cpp ├── ModuleKitSelect.h ├── ModuleLFO.cpp ├── ModuleLFO.h ├── ModuleLooper.cpp ├── ModuleLooper.h ├── ModuleLowpassFilter.cpp ├── ModuleLowpassFilter.h ├── ModuleMap.cpp ├── ModuleMap.h ├── ModuleMixer2.cpp ├── ModuleMixer2.h ├── ModuleMixer3.cpp ├── ModuleMixer3.h ├── ModuleMultiply.cpp ├── ModuleMultiply.h ├── ModuleOscParam.cpp ├── ModuleOscParam.h ├── ModuleOutput.cpp ├── ModuleOutput.h ├── ModulePatternGenerator.cpp ├── ModulePatternGenerator.h ├── ModuleQuantizer.cpp ├── ModuleQuantizer.h ├── ModuleRotatingRouter3.cpp ├── ModuleRotatingRouter3.h ├── ModuleSampleAndHold.cpp ├── ModuleSampleAndHold.h ├── ModuleSamplePlayer.cpp ├── ModuleSamplePlayer.h ├── ModuleSequencer.cpp ├── ModuleSequencer.h ├── ModuleSmooth.cpp ├── ModuleSmooth.h ├── ModuleSpeechSound.cpp ├── ModuleSpeechSound.h ├── ModuleSwitch.cpp ├── ModuleSwitch.h ├── ModuleVCA.cpp ├── ModuleVCA.h ├── ModuleWaveFolder.cpp ├── ModuleWaveFolder.h ├── ModuleWaveshaper.cpp ├── ModuleWaveshaper.h ├── ModuleWavetableOsc.cpp ├── ModuleWavetableOsc.h ├── Modules.h ├── README.md ├── Rand.cpp ├── Rand.h ├── Synth.cpp ├── Synth.h ├── Synth3Osc.cpp ├── Synth3Osc.h ├── SynthArpeggio1.cpp ├── SynthArpeggio1.h ├── SynthAutoDrum.cpp ├── SynthAutoDrum.h ├── SynthChords.cpp ├── SynthChords.h ├── SynthClickers.cpp ├── SynthClickers.h ├── SynthDrumPlayer.cpp ├── SynthDrumPlayer.h ├── SynthDrumSelektor.cpp ├── SynthDrumSelektor.h ├── SynthEquationLooper.cpp ├── SynthEquationLooper.h ├── SynthEquationPlayer.cpp ├── SynthEquationPlayer.h ├── SynthLooper.cpp ├── SynthLooper.h ├── SynthMini.cpp ├── SynthMini.h ├── SynthMumbler.cpp ├── SynthMumbler.h ├── SynthPatterns.cpp ├── SynthPatterns.h ├── SynthTutorial1.cpp ├── SynthTutorial1.h ├── SynthTutorial10.cpp ├── SynthTutorial10.h ├── SynthTutorial11.cpp ├── SynthTutorial11.h ├── SynthTutorial12.cpp ├── SynthTutorial12.h ├── SynthTutorial13.cpp ├── SynthTutorial13.h ├── SynthTutorial14.cpp ├── SynthTutorial14.h ├── SynthTutorial15.cpp ├── SynthTutorial15.h ├── SynthTutorial16.cpp ├── SynthTutorial16.h ├── SynthTutorial2.cpp ├── SynthTutorial2.h ├── SynthTutorial3.cpp ├── SynthTutorial3.h ├── SynthTutorial4.cpp ├── SynthTutorial4.h ├── SynthTutorial5.cpp ├── SynthTutorial5.h ├── SynthTutorial6.cpp ├── SynthTutorial6.h ├── SynthTutorial7.cpp ├── SynthTutorial7.h ├── SynthTutorial8.cpp ├── SynthTutorial8.h ├── SynthTutorial9.cpp ├── SynthTutorial9.h ├── SynthWavetable.cpp ├── SynthWavetable.h ├── SynthWavetableDelay.cpp ├── SynthWavetableDelay.h ├── SynthWavetableFolder.cpp ├── SynthWavetableFolder.h ├── defines.h ├── experimental ├── Macro.cpp ├── Macro.h ├── MacroGatedLPF.cpp ├── MacroGatedLPF.h ├── ModuleADSR.cpp.older ├── ModuleADSR.h.older ├── ModuleAudioEFX.cpp ├── ModuleAudioEFX.h ├── ModuleCAOsc.cpp ├── ModuleCAOsc.h ├── ModuleChatBot.cpp ├── ModuleChatBot.h ├── ModuleChords.cpp ├── ModuleDrum.cpp ├── ModuleDrum.h ├── ModuleEqWaveOsc.cpp ├── ModuleEqWaveOsc.h ├── ModuleEquationShot.cpp ├── ModuleEquationShot.h ├── ModuleHighpassFilter.cpp ├── ModuleHighpassFilter.h ├── ModuleLowpassFilter.cpp ├── ModuleLowpassFilter.h ├── ModuleReverb.cpp ├── ModuleReverb.h ├── ModuleRingMod.cpp ├── ModuleRingMod.h ├── ModuleSoundToy.cpp ├── ModuleSoundToy.h ├── ModuleSpeechSound.cpp ├── ModuleSpeechSound.h ├── ModuleVocalizer.cpp ├── ModuleVocalizer.h ├── ModuleWalkSequencer.cpp ├── ModuleWalkSequencer.h ├── ModuleWaveshaper.cpp ├── ModuleWaveshaper.h ├── ModuleWavetable.cpp ├── ModuleWavetable.h ├── ModuleWords.cpp ├── ModuleWords.h ├── SynthArp1.cpp ├── SynthArp1.h ├── SynthAudioMath.cpp ├── SynthAudioMath.h ├── SynthChatterbox.cpp ├── SynthChatterbox.h ├── SynthDCOffsetTest.cpp ├── SynthDCOffsetTest.h ├── SynthEqWave.cpp ├── SynthEqWave.h ├── SynthMumbler.cpp ├── SynthMumbler.h ├── SynthPassthroughTest.cpp ├── SynthPassthroughTest.h ├── SynthPatternsFX.cpp ├── SynthPatternsFX.h ├── SynthPhonetics.cpp ├── SynthPhonetics.h ├── SynthSoundToy.cpp ├── SynthSoundToy.h ├── SynthTutorial14.cpp ├── SynthTutorial14.h ├── SynthVerbalizer.cpp └── SynthVerbalizer.h └── old ├── Equations.cpp └── Equations.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /DueTimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | DueTimer.h - DueTimer header file, definition of methods and attributes... 3 | For instructions, go to https://github.com/ivanseidel/DueTimer 4 | 5 | Created by Ivan Seidel Gomes, March, 2013. 6 | Modified by Philipp Klaus, June 2013. 7 | Released into the public domain. 8 | */ 9 | 10 | #ifdef __arm__ 11 | 12 | #ifndef DueTimer_h 13 | #define DueTimer_h 14 | 15 | #include "Arduino.h" 16 | 17 | #include 18 | 19 | class DueTimer 20 | { 21 | protected: 22 | 23 | // Represents the timer id (index for the array of Timer structs) 24 | int timer; 25 | 26 | // Stores the object timer frequency 27 | // (allows to access current timer period and frequency): 28 | static double _frequency[9]; 29 | 30 | // Picks the best clock to lower the error 31 | static uint8_t bestClock(double frequency, uint32_t& retRC); 32 | 33 | public: 34 | struct Timer 35 | { 36 | Tc *tc; 37 | uint32_t channel; 38 | IRQn_Type irq; 39 | }; 40 | 41 | static DueTimer getAvailable(); 42 | 43 | // Store timer configuration (static, as it's fix for every object) 44 | static const Timer Timers[9]; 45 | 46 | // Needs to be public, because the handlers are outside class: 47 | static void (*callbacks[9])(); 48 | 49 | DueTimer(int _timer); 50 | DueTimer attachInterrupt(void (*isr)()); 51 | DueTimer detachInterrupt(); 52 | DueTimer start(long microseconds = -1); 53 | DueTimer stop(); 54 | DueTimer setFrequency(double frequency); 55 | DueTimer setPeriod(long microseconds); 56 | 57 | 58 | double getFrequency(); 59 | long getPeriod(); 60 | }; 61 | 62 | // Just to call Timer.getAvailable instead of Timer::getAvailable() : 63 | extern DueTimer Timer; 64 | 65 | extern DueTimer Timer0; 66 | extern DueTimer Timer1; 67 | extern DueTimer Timer2; 68 | extern DueTimer Timer3; 69 | extern DueTimer Timer4; 70 | extern DueTimer Timer5; 71 | extern DueTimer Timer6; 72 | extern DueTimer Timer7; 73 | extern DueTimer Timer8; 74 | 75 | #endif 76 | 77 | #else 78 | #error Oops! Trying to include DueTimer on another device? 79 | #endif 80 | -------------------------------------------------------------------------------- /EquationBank.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "EquationBank.h" 4 | 5 | EquationBank::EquationBank() 6 | { 7 | w = 0; 8 | } -------------------------------------------------------------------------------- /EquationBank.h: -------------------------------------------------------------------------------- 1 | #ifndef EquationBank_h 2 | #define EquationBank_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | #include "FixedPointMath.h" 7 | 8 | class EquationBank 9 | { 10 | public: 11 | 12 | EquationBank(); 13 | virtual uint32_t compute(int equation_number, uint32_t t, uint32_t p1, uint32_t p2, uint32_t p3) = 0; 14 | 15 | FixedPointMath fixed_point_math; 16 | uint8_t number_of_equations; 17 | 18 | int value; 19 | 20 | uint32_t p; // Temporary variable for use in equations 21 | uint32_t q; // Temporary variable for use in equations 22 | uint16_t w; // The final output of the equation 23 | 24 | uint32_t p1; // parameters used in equations to modify the soudn 25 | uint32_t p2; 26 | uint32_t p3; 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /EquationBankKhepri.h: -------------------------------------------------------------------------------- 1 | #ifndef EquationBankKhepri_h 2 | #define EquationBankKhepri_h 3 | 4 | #include "EquationBank.h" 5 | 6 | class EquationBankKhepri : public EquationBank 7 | { 8 | public: 9 | EquationBankKhepri(); 10 | uint32_t compute(int equation_number, uint32_t t, uint32_t p1, uint32_t p2, uint32_t p3); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /EquationBankPtah.h: -------------------------------------------------------------------------------- 1 | #ifndef EquationBankPtah_h 2 | #define EquationBankPtah_h 3 | 4 | #include "EquationBank.h" 5 | 6 | class EquationBankPtah : public EquationBank 7 | { 8 | public: 9 | EquationBankPtah(); 10 | uint32_t compute(int equation_number, uint32_t t, uint32_t p1, uint32_t p2, uint32_t p3); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /EquationBankSobek.h: -------------------------------------------------------------------------------- 1 | #ifndef EquationBankSobek_h 2 | #define EquationBankSobek_h 3 | 4 | #include "EquationBank.h" 5 | 6 | class EquationBankSobek : public EquationBank 7 | { 8 | public: 9 | EquationBankSobek(); 10 | uint32_t compute(int equation_number, uint32_t t, uint32_t p1, uint32_t p2, uint32_t p3); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /FixedPointMath.h: -------------------------------------------------------------------------------- 1 | #ifndef FixedPointMath_h 2 | #define FixedPointMath_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | 7 | class FixedPointMath 8 | { 9 | public: 10 | 11 | uint32_t SquareRoot(uint32_t a_nInput); 12 | uint32_t exp_fix0912(uint32_t in); 13 | uint32_t sin_fix1212(uint32_t in); 14 | uint32_t cos_fix1212(uint32_t in); 15 | uint32_t square_fix1212(uint32_t in); 16 | uint32_t saw_fix1212(uint32_t x, uint32_t a); 17 | }; 18 | 19 | #endif -------------------------------------------------------------------------------- /GlobalChords.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "GlobalChords.h" 3 | 4 | const uint8_t CHORDS[][3] = 5 | { 6 | 7 | {0, 4, 7}, // 0: "major" 8 | {4, 7, 12}, // 1: 9 | {7, 12, 16}, // 2: 10 | 11 | {0, 4, 8}, // 3: "augmented" 12 | {4, 8, 12}, // 4: 13 | {8,12,16}, // 5: 14 | 15 | {0, 4, 9}, // 6: "6th" 16 | {4, 9, 12}, // 7: 17 | {9, 12, 16}, // 8: 18 | 19 | {0, 4, 10}, // 9: "7th" 20 | {4, 10, 12}, // 10: 21 | {10, 12, 16}, // 11: 22 | 23 | {0, 5, 7}, // 12: "sus4" 24 | {5, 7, 12}, // 13: 25 | 26 | {0, 5, 8}, // 14: "sus4 aug5" 27 | {5, 8, 12}, // 15: 28 | 29 | {0, 5, 9}, // 16: "sus4 6" 30 | {5, 9, 12}, // 17: 31 | {9, 12, 17}, // 18: 32 | 33 | {0, 3, 9}, // 19: "m6th" 34 | {3, 9, 12}, // 20: 35 | {9, 12, 15}, // 21: 36 | 37 | {0, 3, 8}, // 22: "mAug 5" 38 | {3, 8, 12}, // 23: 39 | {8, 12, 15}, // 24: 40 | 41 | {0, 3, 7}, // 25: "minor" 42 | {3, 7, 12}, // 26: 43 | {7, 12, 15}, // 27: 44 | 45 | {0, 3, 6}, // 28: "diminished" 46 | {3, 6, 12}, // 29: 47 | {6, 12, 15}, // 30: 48 | 49 | {0, 7, 12} // 31: 5ths 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /GlobalChords.h: -------------------------------------------------------------------------------- 1 | #ifndef Chords_h 2 | #define Chords_h 3 | 4 | extern const uint8_t CHORDS[][3]; 5 | 6 | #endif -------------------------------------------------------------------------------- /GlobalFilterTables.h: -------------------------------------------------------------------------------- 1 | #ifndef FILTER_TABLES 2 | #define FILTER_TABLES 3 | 4 | extern const uint16_t LPF_P_TABLE[]; 5 | extern const uint16_t LPF_T4_TABLE[]; 6 | #endif -------------------------------------------------------------------------------- /GlobalFixedPointMathTables.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | #ifndef FIXED_POINT_MATH_TABLES 4 | extern const uint16_t fixed_point_sin[]; 5 | extern const uint16_t fixed_point_exp[]; 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /GlobalIncrements.h: -------------------------------------------------------------------------------- 1 | #ifndef Increments_h 2 | #define Increments_h 3 | 4 | extern const uint32_t INCREMENTS[]; 5 | 6 | #endif -------------------------------------------------------------------------------- /GlobalLoops.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | #ifndef GOBAL_LOOPS 4 | #define GOBAL_LOOPS 5 | 6 | // Loops by Richard Devine 7 | 8 | #define DEVINE_BEAT1_LENGTH 29669 9 | #define DEVINE_BEAT2_LENGTH 29730 10 | #define TRUCHAN_BEAT1_LENGTH 36873 11 | 12 | extern const uint8_t DEVINE_BEAT1[]; 13 | extern const uint8_t DEVINE_BEAT2[]; 14 | extern const uint8_t TRUCHAN_BEAT1[]; 15 | 16 | #endif -------------------------------------------------------------------------------- /GlobalRingBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | uint16_t RING_BUFFER[4096]; 4 | -------------------------------------------------------------------------------- /GlobalRingBuffer.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | #ifndef RingBuffer_h 4 | #define RingBuffer_h 5 | 6 | extern uint16_t RING_BUFFER[4096]; 7 | 8 | #endif -------------------------------------------------------------------------------- /GlobalSamples.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | #ifndef SAMPLES 4 | #define SAMPLES 5 | 6 | #define SAMPLE_KICK_LENGTH 6199 7 | #define SAMPLE_SNARE_LENGTH 5222 8 | #define SAMPLE_HIHAT_LENGTH 2131 9 | 10 | #define SAMPLE_KICK2_LENGTH 8394 11 | #define SAMPLE_SNARE2_LENGTH 1026 12 | #define SAMPLE_HIHAT2_LENGTH 1243 13 | 14 | #define SAMPLE_KICK3_LENGTH 7288 15 | #define SAMPLE_SNARE3_LENGTH 6988 16 | #define SAMPLE_HIHAT3_LENGTH 1128 17 | 18 | extern const uint16_t SAMPLE_KICK[]; 19 | extern const uint16_t SAMPLE_SNARE[]; 20 | extern const uint16_t SAMPLE_HIHAT[]; 21 | 22 | extern const uint16_t SAMPLE_KICK2[]; 23 | extern const uint16_t SAMPLE_SNARE2[]; 24 | extern const uint16_t SAMPLE_HIHAT2[]; 25 | 26 | extern const uint16_t SAMPLE_KICK3[]; 27 | extern const uint16_t SAMPLE_SNARE3[]; 28 | extern const uint16_t SAMPLE_HIHAT3[]; 29 | 30 | #endif -------------------------------------------------------------------------------- /GlobalScales.h: -------------------------------------------------------------------------------- 1 | #ifndef Scales_h 2 | #define Scales_h 3 | 4 | extern const uint8_t CHROMATIC[]; 5 | extern const uint8_t IONIAN[]; 6 | extern const uint8_t DORIAN[]; 7 | extern const uint8_t LYDIAN[]; 8 | extern const uint8_t PHRYGIAN[]; 9 | 10 | extern const uint8_t MIXOLYDIAN[]; 11 | extern const uint8_t AEOLIAN[]; 12 | extern const uint8_t LOCRIAN[]; 13 | extern const uint8_t MAJOR_PENTATONIC[]; 14 | extern const uint8_t MINOR_PENTATONIC[]; 15 | extern const uint8_t BLUES[]; 16 | extern const uint8_t DIMINISHED[]; 17 | extern const uint8_t ARABIAN[]; 18 | 19 | extern const uint8_t MAJOR[]; 20 | extern const uint8_t MINOR[]; 21 | extern const uint8_t PRISM[]; 22 | extern const uint16_t NOTES[]; 23 | 24 | #endif -------------------------------------------------------------------------------- /GlobalSlopes.h: -------------------------------------------------------------------------------- 1 | #ifndef Slopes_h 2 | #define Slopes_h 3 | 4 | extern const uint8_t SLOPES[][512]; 5 | 6 | #endif -------------------------------------------------------------------------------- /GlobalSpeechTables.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | 3 | #ifndef SPEECH_TABLES 4 | #define SPEECH_TABLES 5 | 6 | extern const uint16_t speechPitchTable[]; 7 | extern const int8_t speechSinCalc[]; 8 | extern const int8_t speechSqrCalc[]; 9 | extern const uint8_t speechFormantTable[]; 10 | extern const uint8_t speechWordTable[]; 11 | 12 | #endif -------------------------------------------------------------------------------- /GlobalWaveshaperTables.h: -------------------------------------------------------------------------------- 1 | #ifndef WaveshaperTables_h 2 | #define WaveshaperTables_h 3 | 4 | extern const uint8_t WAVE_SHAPER_TABLES[][4096]; 5 | 6 | #endif -------------------------------------------------------------------------------- /GlobalWavetables.h: -------------------------------------------------------------------------------- 1 | #ifndef Wavetables_h 2 | #define Wavetables_h 3 | 4 | extern const uint8_t WAVETABLES[][512]; 5 | 6 | #endif -------------------------------------------------------------------------------- /Inputs.cpp: -------------------------------------------------------------------------------- 1 | #include "Inputs.h" 2 | #include "defines.h" 3 | 4 | Inputs::Inputs() 5 | { 6 | prg = new ModuleAnalogInput(PIN_PRG); 7 | sr = new ModuleAnalogInput(PIN_SR); 8 | mod = new ModuleAnalogInput(PIN_MOD); 9 | param1 = new ModuleAnalogInput(PIN_PARAM_1); 10 | param2 = new ModuleAnalogInput(PIN_PARAM_2); 11 | param3 = new ModuleAnalogInput(PIN_PARAM_3); 12 | gate = new ModuleDigitalInput(PIN_GATE); 13 | } 14 | 15 | void Inputs::read() 16 | { 17 | prg->read(); 18 | sr->read(); 19 | mod->read(); 20 | param1->read(); 21 | param2->read(); 22 | param3->read(); 23 | gate->read(); 24 | } -------------------------------------------------------------------------------- /Inputs.h: -------------------------------------------------------------------------------- 1 | #ifndef Inputs_h 2 | #define Inputs_h 3 | 4 | #include "defines.h" 5 | #include "ModuleAnalogInput.h" 6 | #include "ModuleDigitalInput.h" 7 | 8 | 9 | class Inputs 10 | { 11 | public: 12 | 13 | // Methods 14 | Inputs(); // Constructor 15 | 16 | void read(); 17 | 18 | // Individual input modules 19 | // 20 | // It might seem strange to use a "module" just for an input, but it's necessary because of the way 21 | // modules are strung together. Each module can have inputs, and these inputs -must be- pointers 22 | // to other modules. That's also why there's such thing as a ModuleConstant, since we can't set a 23 | // module's input to a number, like 43. A pointer to a global instance of the Inputs class is passed 24 | // into each Synth via the constructor. From inside a synth, you can read one of the inputs with 25 | // code like: 26 | // 27 | // some_module->some_input = inputs->param2; 28 | // 29 | 30 | ModuleAnalogInput *prg; 31 | ModuleAnalogInput *sr; 32 | ModuleAnalogInput *mod; 33 | ModuleAnalogInput *param1; 34 | ModuleAnalogInput *param2; 35 | ModuleAnalogInput *param3; 36 | ModuleDigitalInput *gate; 37 | 38 | }; 39 | 40 | #endif -------------------------------------------------------------------------------- /Module.h: -------------------------------------------------------------------------------- 1 | #ifndef Module_h 2 | #define Module_h 3 | 4 | #include "Arduino.h" 5 | 6 | class Module 7 | { 8 | public: 9 | 10 | // Methods 11 | Module(); 12 | 13 | // run(cycle) 14 | // 15 | // The run() method uses the cycle iterator to ensure that it isn't being 16 | // run twice in a single interrupt cycle. Then run() calls the module's 17 | // compute() method and returns the results. No need to override this 18 | // method. 19 | 20 | uint16_t run(uint8_t cycle); 21 | 22 | // readInput(..) 23 | // 24 | // The readInput(..) methods take a module * as a parameter, calls the 25 | // run() method on that module, then returns the results. An input to a 26 | // module is really just a pointer to another module. 27 | 28 | uint16_t readInput(Module *); // Read one of this module's inputs. This is implemented in Module.cpp 29 | uint16_t readInput(Module *, int conversion); // See defines.h for a list of conversions 30 | uint16_t readInput(Module *, uint32_t map_low, uint32_t map_high); // Read input and map the results 31 | 32 | // compute() 33 | // 34 | // Compute the output of the module. Pure virtual function. This is the 35 | // method of a module that actually -does stuff- and must be implemented 36 | // in the derived class. 37 | 38 | virtual uint16_t compute() = 0; 39 | 40 | // Variables 41 | uint8_t cycle; // Current interrupt cycle 42 | uint16_t output; // Instance variable to store the module's output 43 | boolean no_output_conversion; // Set this to true in the derived class in order to skip any output scaling 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ModuleAdd.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleAdd.h" 2 | #include "defines.h" 3 | 4 | ModuleAdd::ModuleAdd() 5 | { 6 | this->input_1 = NULL; 7 | this->input_2 = NULL; 8 | } 9 | 10 | uint16_t ModuleAdd::compute() 11 | { 12 | // Read inputs 13 | uint32_t value_1 = this->readInput(input_1); 14 | uint32_t value_2 = this->readInput(input_2); 15 | 16 | uint32_t sum = value_1 + value_2; 17 | 18 | if(sum > MAX_CV) 19 | { 20 | return(sum >> 12); 21 | } 22 | else 23 | { 24 | return(sum); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ModuleAdd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleAdd | 4 | * |----------------------| 5 | * > input_1 | 6 | * > input_2 | 7 | * | | 8 | * | output > 9 | * +----------------------+ 10 | */ 11 | // ============================================================================= 12 | // 13 | // Adds the values at input_1 and input_2 and outputs the sum. For audio 14 | // signals, consider using ModuleMixer2 instead. 15 | // 16 | 17 | 18 | #ifndef ModuleAdd_h 19 | #define ModuleAdd_h 20 | 21 | #include "Module.h" 22 | 23 | class ModuleAdd : public Module 24 | { 25 | public: 26 | ModuleAdd(); 27 | uint16_t compute(); 28 | 29 | // Inputs 30 | Module *input_1; 31 | Module *input_2; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /ModuleAnalogInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleAnalogInput | 4 | * |----------------------| 5 | * | | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | */ 10 | // ============================================================================= 11 | // 12 | // ModuleAnalogInput is used for reading one of the analog inputs of the Arduino. 13 | // The pin number of the input to be read is passed in the constructor. Pin 14 | // numbers are defined in defines.h. Outputs a value ranging from 0 to 4095. 15 | // 16 | // You should never need to instantiate a ModuleAnalogInput yourself. All of 17 | // the Equation Composer's input modules are created for you and stored in the 18 | // Inputs (see Inputs.h/Inputs.cpp) object. 19 | 20 | #ifndef ModuleAnalogInput_h 21 | #define ModuleAnalogInput_h 22 | 23 | #include "ModuleInput.h" 24 | 25 | class ModuleAnalogInput : public ModuleInput 26 | { 27 | private: 28 | uint16_t compute(); 29 | 30 | public: 31 | 32 | ModuleAnalogInput(int input_pin); 33 | uint32_t read(); 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /ModuleArpeggio.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleArpeggio.h" 3 | #include "defines.h" 4 | 5 | ModuleArpeggio::ModuleArpeggio() 6 | { 7 | this->clocked = false; 8 | this->step = 0; 9 | this->my_output = 0; 10 | 11 | // Initialize all inputs 12 | this->root_note_input = NULL; 13 | this->pattern_input = NULL; 14 | this->clock_input = NULL; 15 | } 16 | 17 | uint16_t ModuleArpeggio::compute() 18 | { 19 | uint32_t clock = this->readInput(clock_input); 20 | 21 | if((clock < MID_CV) && clocked) clocked = false; 22 | 23 | if((clock >= MID_CV) && !clocked) 24 | { 25 | clocked = true; 26 | 27 | // Read scale input. 28 | // Convert the standard 12 bit CV value to a 3-bit value, which ranges from 0 to 7 29 | uint32_t pattern = this->readInput(pattern_input, CONVERT_TO_3_BIT); 30 | 31 | // Read root note 32 | uint32_t root_note = this->readInput(root_note_input); 33 | 34 | my_output = (arpeggiations[pattern][step] * 4096/60) + root_note; 35 | 36 | step++; 37 | if(step == 8) step = 0; 38 | } 39 | 40 | return(my_output); 41 | } 42 | -------------------------------------------------------------------------------- /ModuleArpeggio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleArpeggio | 4 | * |----------------------| 5 | * > root_note | 6 | * > pattern | 7 | * > clock | 8 | * | | 9 | * | output > 10 | * +----------------------+ 11 | * 12 | */ 13 | // ============================================================================= 14 | // 15 | // ModuleArpeggio is a clocked arpeggiation generator with variable pattern 16 | // and root note. Arpeggiations are defined in ModuleArpeggio.cpp. 17 | // 18 | // 19 | // Example usage: 20 | // 21 | // ModuleArpeggio *arp = new ModuleArpeggio(); 22 | // ModuleWavetable *wavetable_osc = new ModuleWavetable(equations); 23 | // 24 | // arp->clock_input = inputs->gate; 25 | // arp->root_note_input = inputs->sr; 26 | // arp->pattern_input = inputs->param1; 27 | // 28 | // wavetable_osc->frequency_input = arp; 29 | // wavetable_osc->equation_input = inputs->param2; 30 | // 31 | // this->last_module = wavetable_osc; 32 | // 33 | 34 | #ifndef ModuleArpeggio_h 35 | #define ModuleArpeggio_h 36 | 37 | #include "Arduino.h" 38 | #include "Module.h" 39 | 40 | class ModuleArpeggio : public Module 41 | { 42 | 43 | public: 44 | 45 | ModuleArpeggio(); 46 | uint16_t compute(); 47 | 48 | // Inputs 49 | Module *root_note_input; 50 | Module *pattern_input; 51 | Module *clock_input; 52 | 53 | private: 54 | 55 | int step; 56 | 57 | // 8 scales, 8 notes per scale 58 | int8_t arpeggiations[8][8] = { 59 | {0,12,0,12,0,12,0,12}, 60 | {0,12,0,12,0,12,-2,10}, 61 | {0,10,12,0,10,12,0,0}, 62 | {0,3,7,10,0,3,7,10}, 63 | {0,3,7,10,12,10,7,3}, 64 | {0,-2,0,3,0,-2,-5,-2}, 65 | {0,0,12,0,0,0,12,0}, 66 | {0,1,4,5,7,5,4,1} 67 | }; 68 | 69 | boolean clocked; 70 | uint32_t my_output; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /ModuleBitReducer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleBitReducer.h" 3 | #include "defines.h" 4 | 5 | ModuleBitReducer::ModuleBitReducer() 6 | { 7 | audio_input = NULL; 8 | bit_input = NULL; 9 | } 10 | 11 | uint16_t ModuleBitReducer::compute() 12 | { 13 | uint16_t audio = this->readInput(audio_input); 14 | uint16_t bits = this->readInput(bit_input, 0, 12); 15 | 16 | audio = audio >> bits; // Shave off bits for the effect 17 | audio = audio << bits; // Restore to a 12 bit number 18 | 19 | return(audio); 20 | } 21 | -------------------------------------------------------------------------------- /ModuleBitReducer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleBitReducer | 4 | * |----------------------| 5 | * > audio_input | 6 | * > bit_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleBitReducer is an audio effect for reducing the number of bits used 14 | // to represent the audio information, which results in a low-fi, crunchy, 15 | // digital distortion. 16 | // 17 | // Example usage: 18 | // 19 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 20 | // ModuleBitReducer *bit_reducer = new ModuleBitReducer(); 21 | // 22 | // wavetable_osc->wavetable_input = inputs->mod; 23 | // wavetable_osc->frequency_input = inputs->sr; 24 | // 25 | // bit_reducer->audio_input = wavetable_osc; 26 | // bit_reducer->bit_input = inputs->param1; 27 | // 28 | // this->last_module = bit_reducer; 29 | 30 | #ifndef ModuleBitReducer_h 31 | #define ModuleBitReducer_h 32 | 33 | #include "Arduino.h" 34 | #include "Module.h" 35 | 36 | class ModuleBitReducer : public Module 37 | { 38 | 39 | public: 40 | ModuleBitReducer(); 41 | uint16_t compute(); 42 | 43 | // Inputs 44 | Module *audio_input; 45 | Module *bit_input; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /ModuleChords.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleChords.h" 3 | #include "defines.h" 4 | #include "GlobalScales.h" 5 | #include "GlobalChords.h" 6 | 7 | ModuleChords::ModuleChords() 8 | { 9 | // Initialize all inputs 10 | this->root_note_input = NULL; 11 | this->chord_input = NULL; 12 | 13 | // Instantiate all outputs 14 | this->note_1_output = new ModuleOutput(this); 15 | this->note_2_output = new ModuleOutput(this); 16 | this->note_3_output = new ModuleOutput(this); 17 | } 18 | 19 | uint16_t ModuleChords::compute() 20 | { 21 | uint16_t root_note_input = this->readInput(this->root_note_input, 0, 60); 22 | uint16_t chord_input = this->readInput(this->chord_input, CONVERT_TO_5_BIT); // 0 - 31 23 | 24 | this->note_1_output->value = NOTES[CHROMATIC[(uint8_t) min((root_note_input + CHORDS[chord_input][0]),60)]]; 25 | this->note_2_output->value = NOTES[CHROMATIC[(uint8_t) min((root_note_input + CHORDS[chord_input][1]),60)]]; 26 | this->note_3_output->value = NOTES[CHROMATIC[(uint8_t) min((root_note_input + CHORDS[chord_input][2]),60)]]; 27 | 28 | return(this->note_3_output->value); 29 | } -------------------------------------------------------------------------------- /ModuleClock.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleClock.h" 3 | #include "defines.h" 4 | 5 | ModuleClock::ModuleClock(uint16_t bpm, int clock_division) 6 | { 7 | this->counter = 0; 8 | this->bpm = constrain(bpm, 0, 254); 9 | 10 | for(uint8_t bpm_i=0; bpm_i < 255; bpm_i++) 11 | { 12 | bpm_ppqn[bpm_i] = ((float)(60.0 * SAMPLE_RATE_FLOAT * clock_division)/((float)bpm_i * 96.0)); 13 | bpm_half_ppqn[bpm_i] = bpm_ppqn[bpm_i] / 2; 14 | } 15 | } 16 | 17 | ModuleClock::ModuleClock(uint16_t bpm) 18 | { 19 | this->counter = 0; 20 | this->bpm = constrain(bpm, 0, 254); 21 | 22 | for(uint8_t bpm_i=0; bpm_i < 255; bpm_i++) 23 | { 24 | bpm_ppqn[bpm_i] = ((float)(60.0 * SAMPLE_RATE_FLOAT)/((float)bpm_i * 96.0)); 25 | bpm_half_ppqn[bpm_i] = bpm_ppqn[bpm_i] / 2; 26 | } 27 | } 28 | 29 | 30 | uint16_t ModuleClock::compute() 31 | { 32 | this->counter = this->counter + 1; 33 | 34 | // If we're at the end of the clock duty, 35 | // then reset the counter back to 0 and return 0 36 | // 37 | // _____↓ 38 | // | | 39 | // _____| | 40 | 41 | if(this->counter == this->bpm_ppqn[bpm]) 42 | { 43 | this->counter = 0; 44 | return(0); 45 | } 46 | 47 | // If we're 1/2 way (or more) through the clock duty, 48 | // then output the MAX_CV 49 | // 50 | // ↓_____ 51 | // | | 52 | // _____| | 53 | 54 | if (this->counter >= this->bpm_half_ppqn[bpm]) 55 | { 56 | return(MAX_CV); 57 | } 58 | 59 | // If neither of the two conditions above it true, 60 | // then we're at the first phase of the clock duty, 61 | // so return 0. 62 | // 63 | // _____ 64 | // | | 65 | // __↓__| | 66 | 67 | else 68 | { 69 | return(0); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /ModuleClock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleClock | 4 | * |----------------------| 5 | * | | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | * 10 | * The clock module produces a square wave with a 50% duty cycle starting low. 11 | * _____ _____ 12 | * | | | | 13 | * _____| |_____| | etc... 14 | * 15 | * The clock speed is controlled via a BPM (beats per minute) value supplied during 16 | * instantiation, like: 17 | * 18 | * int beats_per_minute = 120; 19 | * ModuleClock *module_clock = new ModuleClock(beats_per_minute); 20 | * 21 | * The output is 96 pulses per quarter note. A second parameter can be supplied 22 | * in the constructor to act as a clock divider. To have the clock output 23 | * quarter note pulses, we divide the 96 pulses-per-quarter-note by 96: 24 | * 25 | * ModuleClock *module_clock = new ModuleClock(120, 96); 26 | * 27 | * Helpful clock divisions have been defined in defines.h. Here are some examples: 28 | * 29 | * ModuleClock *module_clock = new ModuleClock(120, 48); // produce 1/8th note gates at 120 BPM 30 | * ModuleClock *module_clock = new ModuleClock(120, EIGHTH_NOTE_CLOCK_DIVISION); // produce 1/8th note gates at 120 BPM 31 | * ModuleClock *module_clock = new ModuleClock(100, QUARTER_NOTE_CLOCK_DIVISION); // produce 1/4th note gates at 100 BPM 32 | * ModuleClock *module_clock = new ModuleClock(100, WHOLE_NOTE_CLOCK_DIVISION); // produce whole note gates at 100 BPM 33 | * 34 | */ 35 | 36 | #ifndef ModuleClock_h 37 | #define ModuleClock_h 38 | 39 | #include "Arduino.h" 40 | #include "Module.h" 41 | 42 | class ModuleClock : public Module 43 | { 44 | public: 45 | ModuleClock(uint16_t bpm); 46 | ModuleClock(uint16_t bpm, int clock_division); 47 | uint16_t compute(); 48 | 49 | private: 50 | uint32_t rate; 51 | uint32_t counter; 52 | uint32_t bpm; 53 | uint16_t bpm_ppqn[255]; 54 | uint16_t bpm_half_ppqn[255]; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /ModuleClockDivider.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleClockDivider.h" 2 | #include "defines.h" 3 | 4 | ModuleClockDivider::ModuleClockDivider() 5 | { 6 | this->counter = 0; 7 | this->clock_division = 0; 8 | this->clocked = false; 9 | this->my_output = 0; 10 | 11 | this->clock_input = NULL; 12 | } 13 | 14 | uint16_t ModuleClockDivider::compute() 15 | { 16 | uint32_t clock = this->readInput(clock_input); 17 | uint32_t clock_division = this->readInput(division_input); 18 | 19 | if((clock < MID_CV) && clocked) clocked = false; 20 | 21 | if((clock >= MID_CV) && !clocked) 22 | { 23 | clocked = true; 24 | 25 | counter = counter + 1; 26 | 27 | if(counter >= clock_division) 28 | { 29 | counter = 0; 30 | 31 | if(my_output == 0) 32 | { 33 | my_output = MAX_CV; 34 | } 35 | else 36 | { 37 | my_output = 0; 38 | } 39 | } 40 | } 41 | 42 | return(my_output); 43 | } 44 | -------------------------------------------------------------------------------- /ModuleClockDivider.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleClockDivider | 4 | * |----------------------| 5 | * > clock_input | 6 | * > division_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | * 11 | * The clock module divides a clock signal. 12 | * 13 | * For example, with a clock_division of 2... 14 | * 15 | * Input: 16 | * 17 | * 18 | * _____ _____ _____ _____ _____ _____ 19 | * | | | | | | | | | | | | 20 | * _____| |_____| |_____| |_____| |_____| |_____| |_____ 21 | * 22 | * 23 | * Output: 24 | * 25 | * _______________________ __________ 26 | * | | | 27 | * _________________| |________________________| 28 | * 29 | * 30 | * Example usage: 31 | * 32 | * ModuleClock *clock = new ModuleClock(120); 33 | * ModuleClockDivider *clock_divider = new ModuleClockDivider(); 34 | * clock_divider->clock_input = clock; 35 | * clock_divider->division_input = new ModuleConstant(96); 36 | * 37 | * For Whole Notes, divide by 96 38 | * For Half Notes, divide by 48 39 | * For Quarter Notes, divide by 24 40 | * For 8th notes, divide by 12 41 | * For 16th Notes, divide by 6 42 | * For 32nd Notes, divide by 3 43 | * For 64th Notes, divide by 1 (although this is the default output of the clock module) 44 | */ 45 | 46 | #ifndef ModuleClockDivider_h 47 | #define ModuleClockDivider_h 48 | 49 | #include "Module.h" 50 | 51 | class ModuleClockDivider : public Module 52 | { 53 | public: 54 | ModuleClockDivider(); 55 | uint16_t compute(); 56 | 57 | // inputs 58 | Module *clock_input; 59 | Module *division_input; 60 | 61 | private: 62 | uint32_t counter; 63 | uint32_t my_output; 64 | int clock_division; 65 | boolean clocked; 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /ModuleClockedRandom.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleClockedRandom.h" 3 | #include "defines.h" 4 | 5 | ModuleClockedRandom::ModuleClockedRandom() 6 | { 7 | this->old_clock = 0; 8 | this->latched_output = 0; 9 | 10 | // Initialize all inputs 11 | this->clock_input = NULL; 12 | 13 | rand.seed(1); 14 | } 15 | 16 | uint16_t ModuleClockedRandom::compute() 17 | { 18 | uint32_t clock = this->readInput(clock_input); 19 | 20 | // Step the sequencer on the rising edge 21 | if((clock > MID_CV) && (old_clock < MID_CV)) latched_output = rand.random(); 22 | 23 | old_clock = clock; 24 | 25 | return(latched_output); 26 | } -------------------------------------------------------------------------------- /ModuleClockedRandom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +-------------------------+ 3 | * | ModuleClockedRandom | 4 | * |-------------------------| 5 | * > clock_input | 6 | * | | 7 | * | output > 8 | * +-------------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleClockedRandom is a clocked random number generator. The output ranges 14 | // from 0 to 4095. 15 | // 16 | // Example usage: 17 | // 18 | // ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 19 | // ModuleClockedRandom *clocked_random = new ModuleClockedRandom(); 20 | // ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 21 | // 22 | // ext_clock->clock_input = inputs->gate; 23 | // 24 | // clocked_random->clock_input = ext_clock; 25 | // 26 | // osc->frequency_input = clocked_random; 27 | // 28 | // this->last_module = osc; 29 | // 30 | 31 | #ifndef ModuleClockedRandom_h 32 | #define ModuleClockedRandom_h 33 | 34 | #include "Arduino.h" 35 | #include "Module.h" 36 | #include "Rand.h" 37 | 38 | class ModuleClockedRandom : public Module 39 | { 40 | 41 | public: 42 | 43 | ModuleClockedRandom(); 44 | uint16_t compute(); 45 | 46 | // Inputs 47 | Module *clock_input; 48 | 49 | private: 50 | 51 | boolean clocked; 52 | uint32_t old_clock; 53 | uint32_t latched_output; 54 | 55 | Rand rand; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ModuleConstant.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleConstant.h" 3 | #include "defines.h" 4 | 5 | ModuleConstant::ModuleConstant(int value) 6 | { 7 | this->value = value; 8 | this->no_output_conversion = true; 9 | } 10 | 11 | uint16_t ModuleConstant::compute() 12 | { 13 | return(this->value); 14 | } 15 | 16 | void ModuleConstant::setValue(uint32_t new_value) 17 | { 18 | this->value = new_value; 19 | } 20 | 21 | uint32_t ModuleConstant::getValue() 22 | { 23 | return(this->value); 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /ModuleConstant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleConstant | 4 | * |----------------------| 5 | * | | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | */ 10 | // ============================================================================= 11 | // 12 | // ModuleConstant is used to supply constant values to the inputs of other 13 | // modules. 14 | // 15 | // Example usage: 16 | // 17 | // ModuleWavetable *wavetable = new ModuleWavetable(equations_wavetable); 18 | // 19 | // wavetable->equation_input = new ModuleConstant(3); 20 | // wavetable->frequency_input = sequencer; 21 | // 22 | // this->last_module = wavetable; 23 | // 24 | 25 | #ifndef ModuleConstant_h 26 | #define ModuleConstant_h 27 | 28 | #include "Arduino.h" 29 | #include "Module.h" 30 | 31 | class ModuleConstant : public Module 32 | { 33 | 34 | public: 35 | 36 | // Methods 37 | ModuleConstant(int value); 38 | uint16_t compute(); 39 | 40 | void setValue(uint32_t value); 41 | uint32_t getValue(); 42 | 43 | // Variables 44 | uint32_t value; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /ModuleCounter.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleCounter.h" 3 | #include "defines.h" 4 | 5 | ModuleCounter::ModuleCounter(int target) 6 | { 7 | this->value = 0; 8 | this->target = target; 9 | this->clocked = false; 10 | this->my_output = 0; 11 | this->no_output_conversion = true; 12 | 13 | this->clock_input = NULL; 14 | } 15 | 16 | uint16_t ModuleCounter::compute() 17 | { 18 | uint32_t clock = this->readInput(clock_input); 19 | 20 | if((clock < MID_CV) && clocked) clocked = false; 21 | 22 | if((clock >= MID_CV) && !clocked) 23 | { 24 | clocked = true; 25 | my_output = value; 26 | value = value + 1; 27 | if(value > target) value = 0; 28 | } 29 | 30 | return(my_output); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ModuleCounter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleCounter | 4 | * |----------------------| 5 | * > clock_input | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | */ 10 | // ============================================================================= 11 | // 12 | // ModuleCounter is used for counting up from 0 to a target number (inclusive). 13 | // Once the target number has been reached, the output loops back to 0. 14 | // The target number is passed into ModuleCounter's constructor. The counter 15 | // is incremented in response to a positive clock pulse at the clock input. 16 | // 17 | // Here's an example which uses a counter to cycle through the first 6 18 | // equations of the wavetable module: 19 | // 20 | // ModuleCounter *counter = new ModuleCounter(5); // count from 0 to 5 21 | // ModuleClock *bpm_clock = new ModuleClock(120, EIGHTH_NOTE_CLOCK_DIVISION); // clock at 120BPM 22 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 23 | // 24 | // counter->clock_input = bpm_clock; 25 | // wavetable_osc->wavetable_input = counter; 26 | // wavetable_osc->frequency_input = inputs->sr; 27 | // 28 | // this->last_module = wavetable_osc; 29 | 30 | 31 | #ifndef ModuleCounter_h 32 | #define ModuleCounter_h 33 | 34 | // #include "Arduino.h" 35 | #include "Module.h" 36 | 37 | class ModuleCounter : public Module 38 | { 39 | public: 40 | ModuleCounter(int target); 41 | uint16_t compute(); 42 | 43 | // Inputs 44 | Module *clock_input; 45 | 46 | private: 47 | int value; 48 | int target; 49 | uint32_t my_output; 50 | boolean clocked; 51 | 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /ModuleDelay.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleDelay.h" 3 | #include "defines.h" 4 | #include "GlobalRingBuffer.h" 5 | 6 | ModuleDelay::ModuleDelay() 7 | { 8 | buffer_index = 0; 9 | delay_output = 0; 10 | 11 | audio_input = NULL; 12 | mix_input = NULL; 13 | feedback_input = NULL; 14 | length_input = NULL; 15 | } 16 | 17 | uint16_t ModuleDelay::compute() 18 | { 19 | uint32_t audio = this->readInput(audio_input); 20 | uint32_t wet_mix = this->readInput(mix_input); 21 | uint32_t feedback = this->readInput(feedback_input); 22 | uint16_t buffer_length = this->readInput(length_input); 23 | 24 | uint32_t dry_mix = 4095 - wet_mix; 25 | 26 | buffer_index++; 27 | if(buffer_index >= buffer_length) buffer_index = 0; 28 | 29 | delay_output = RING_BUFFER[buffer_index]; 30 | RING_BUFFER[buffer_index] = ((audio * (4095 - feedback)) >> 12) + ((delay_output * feedback) >> 12); 31 | 32 | if(wet_mix == 0) 33 | { 34 | return(audio); 35 | } 36 | else 37 | { 38 | return(((delay_output * wet_mix) >> 12) + ((audio * dry_mix) >> 12)); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ModuleDelay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleDelay | 4 | * |----------------------| 5 | * > audio_input | 6 | * > mix_input | 7 | * > feedback_input | 8 | * > length_input | 9 | * | output > 10 | * +----------------------+ 11 | * 12 | */ 13 | // ============================================================================= 14 | // 15 | // ModuleDelay is an extremely short audio delay effect with control over 16 | // mix, feedback, and buffer length. All inputs should range from 0 to 4095. 17 | // 18 | // Example usage: 19 | // 20 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 21 | // ModuleDelay *delay = new ModuleDelay(); 22 | // 23 | // wavetable_osc->wavetable_input = inputs->mod; 24 | // wavetable_osc->frequency_input = inputs->sr; 25 | // 26 | // delay->audio_input = wavetable_osc; 27 | // delay->mix_input = inputs->param1; 28 | // delay->feedback_input = inputs->param2; 29 | // delay->length_input = inputs->param3; 30 | // 31 | // this->last_module = delay; 32 | // 33 | 34 | #ifndef ModuleDelay_h 35 | #define ModuleDelay_h 36 | 37 | #include "Arduino.h" 38 | #include "Module.h" 39 | 40 | class ModuleDelay : public Module 41 | { 42 | 43 | public: 44 | ModuleDelay(); 45 | uint16_t compute(); 46 | 47 | // Inputs 48 | Module *audio_input; 49 | Module *mix_input; 50 | Module *feedback_input; 51 | Module *length_input; 52 | 53 | private: 54 | 55 | uint16_t buffer_index; 56 | uint32_t delay_output; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /ModuleDigitalInput.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleDigitalInput.h" 2 | #include "defines.h" 3 | 4 | ModuleDigitalInput::ModuleDigitalInput(int input_pin) 5 | { 6 | this->value = 0; 7 | this->pin = input_pin; 8 | } 9 | 10 | uint32_t ModuleDigitalInput::read() 11 | { 12 | this->value = (digitalRead(this->pin) * MAX_CV); 13 | return(this->value); 14 | } 15 | 16 | uint16_t ModuleDigitalInput::compute() 17 | { 18 | return(this->value); 19 | } 20 | -------------------------------------------------------------------------------- /ModuleDigitalInput.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleDigitalInput | 4 | * |----------------------| 5 | * | | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | */ 10 | // ============================================================================= 11 | // 12 | // ModuleDigitalInput is used for reading one of the digital inputs of the Arduino. 13 | // The pin number of the input to be read is passed in the constructor. Pin 14 | // numbers are defined in defines.h. Outputs "0" for low and "4095" for high. 15 | // 16 | // Unlike analog pins, the pinMode for digital pins must be set in the Arduino's 17 | // setup() routine, liks so: 18 | // 19 | // pinMode([pin number], INPUT); 20 | // 21 | // You should never need to instantiate a ModuleDigitalInput yourself. All of 22 | // the Equation Composer's input modules are created for you and stored in the 23 | // Inputs (see Inputs.h/Inputs.cpp) object. 24 | 25 | #ifndef ModuleDigitalInput_h 26 | #define ModuleDigitalInput_h 27 | 28 | #include "ModuleInput.h" 29 | 30 | class ModuleDigitalInput : public ModuleInput 31 | { 32 | 33 | public: 34 | ModuleDigitalInput(int pin); 35 | uint32_t read(); 36 | uint16_t compute(); 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /ModuleDrumSequencer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleDrumSequencer.h" 3 | #include "defines.h" 4 | 5 | ModuleDrumSequencer::ModuleDrumSequencer() 6 | { 7 | this->clocked = false; 8 | this->step = 0; 9 | 10 | // Initialize all inputs 11 | this->clock_input = NULL; 12 | this->kick_pattern_input = NULL; 13 | this->snare_pattern_input = NULL; 14 | this->hihat_pattern_input = NULL; 15 | 16 | // Instantiate all outputs 17 | kick_output = new ModuleOutput(this); 18 | snare_output = new ModuleOutput(this); 19 | hihat_output = new ModuleOutput(this); 20 | } 21 | 22 | uint16_t ModuleDrumSequencer::compute() 23 | { 24 | uint32_t clock = this->readInput(clock_input); 25 | 26 | if((clock < MID_CV) && clocked) 27 | { 28 | clocked = false; 29 | kick_output->value = 0; 30 | snare_output->value = 0; 31 | hihat_output->value = 0; 32 | } 33 | 34 | if((clock >= MID_CV) && !clocked) 35 | { 36 | clocked = true; 37 | 38 | uint8_t kick_pattern = this->readInput(kick_pattern_input, CONVERT_TO_3_BIT); 39 | uint8_t snare_pattern = this->readInput(snare_pattern_input, CONVERT_TO_3_BIT); 40 | uint8_t hihat_pattern = this->readInput(hihat_pattern_input, CONVERT_TO_3_BIT); 41 | 42 | kick_output->value = bitRead(patterns[0][kick_pattern], step) * MAX_CV; 43 | snare_output->value = bitRead(patterns[1][snare_pattern], step) * MAX_CV; 44 | hihat_output->value = bitRead(patterns[2][hihat_pattern], step) * MAX_CV; 45 | 46 | step++; 47 | if(step == 16) step = 0; 48 | } 49 | 50 | return(kick_output->value); 51 | } 52 | -------------------------------------------------------------------------------- /ModuleDrumSequencer32.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleDrumSequencer32.h" 3 | #include "defines.h" 4 | 5 | ModuleDrumSequencer32::ModuleDrumSequencer32() 6 | { 7 | this->clocked = false; 8 | this->step = 0; 9 | 10 | // Initialize all inputs 11 | this->clock_input = NULL; 12 | this->kick_pattern_input = NULL; 13 | this->snare_pattern_input = NULL; 14 | this->hihat_pattern_input = NULL; 15 | 16 | // Instantiate all outputs 17 | kick_output = new ModuleOutput(this); 18 | snare_output = new ModuleOutput(this); 19 | hihat_output = new ModuleOutput(this); 20 | } 21 | 22 | uint16_t ModuleDrumSequencer32::compute() 23 | { 24 | uint32_t clock = this->readInput(clock_input); 25 | 26 | if((clock < MID_CV) && clocked) 27 | { 28 | clocked = false; 29 | kick_output->value = 0; 30 | snare_output->value = 0; 31 | hihat_output->value = 0; 32 | } 33 | 34 | if((clock >= MID_CV) && !clocked) 35 | { 36 | clocked = true; 37 | 38 | uint8_t kick_pattern = this->readInput(kick_pattern_input, CONVERT_TO_4_BIT); 39 | uint8_t snare_pattern = this->readInput(snare_pattern_input, CONVERT_TO_4_BIT); 40 | uint8_t hihat_pattern = this->readInput(hihat_pattern_input, CONVERT_TO_4_BIT); 41 | 42 | kick_output->value = bitRead(patterns[0][kick_pattern], step) * MAX_CV; 43 | snare_output->value = bitRead(patterns[1][snare_pattern], step) * MAX_CV; 44 | hihat_output->value = bitRead(patterns[2][hihat_pattern], step) * MAX_CV; 45 | 46 | step++; 47 | if(step == 32) step = 0; 48 | } 49 | 50 | return(kick_output->value); 51 | } 52 | -------------------------------------------------------------------------------- /ModuleEquationLooper.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleEquationLooper.h" 3 | #include "defines.h" 4 | 5 | ModuleEquationLooper::ModuleEquationLooper(EquationBank *equation_bank) 6 | { 7 | fixed_point_20_12_index = 0; 8 | this->equation_bank = equation_bank; 9 | 10 | // Initialize all inputs 11 | this->sample_rate_input = NULL; 12 | this->loop_start_input = NULL; 13 | this->loop_length_input = NULL; 14 | this->equation_input = NULL; 15 | this->param3_input = NULL; 16 | this->gate_input = NULL; 17 | } 18 | 19 | uint16_t ModuleEquationLooper::compute() 20 | { 21 | // Read inputs 22 | // For loop_start and loop_length, I'm dropping some of the least significant 23 | // bits in order to remove any noise from the incoming signal. 24 | 25 | equation = this->readInput(equation_input, 0, equation_bank->number_of_equations); 26 | increment_by = this->readInput(sample_rate_input) << 1; // range: 0 - 4095 27 | loop_length = (this->readInput(loop_length_input, CONVERT_TO_9_BIT)+1) * 120; // range: (1 - 512) * 120 28 | loop_start = this->readInput(loop_start_input, CONVERT_TO_9_BIT) * 800; // range: (0 - 511) * 800 29 | p3 = this->readInput(param3_input, CONVERT_TO_8_BIT); 30 | gate = this->readInput(gate_input); 31 | 32 | fixed_point_20_12_index += increment_by; 33 | 34 | // shift off th 12 bits used for fractional numbers, which leaves us with a 20 bit number 35 | playback_position = loop_start + (fixed_point_20_12_index >> 12); 36 | 37 | if(gate < MID_CV) // Gating the module disables looping 38 | { 39 | // If the playback position is at the loop end, then restart playback 40 | if(playback_position >= (loop_start + loop_length)) 41 | { 42 | playback_position = 0; 43 | fixed_point_20_12_index = 0; 44 | } 45 | } 46 | 47 | // Play the selected equation 48 | return(this->equation_bank->compute(equation, playback_position, 1, 1, p3)); 49 | 50 | } -------------------------------------------------------------------------------- /ModuleEquationPlayer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleEquationPlayer.h" 3 | #include "defines.h" 4 | 5 | ModuleEquationPlayer::ModuleEquationPlayer(EquationBank *equation_bank) 6 | { 7 | t = 0; // Set the counter to 0 8 | p1 = 0; 9 | p2 = 0; 10 | p3 = 0; 11 | old_reset = false; 12 | reset = 0; 13 | fixed_point_32_32_index = 0; 14 | 15 | this->equation_bank = equation_bank; 16 | 17 | // Initialize all inputs 18 | this->equation_input = NULL; 19 | this->sample_rate_input = NULL; 20 | this->param1_input = NULL; 21 | this->param2_input = NULL; 22 | this->param3_input = NULL; 23 | this->reset_input = NULL; 24 | } 25 | 26 | uint16_t ModuleEquationPlayer::compute() 27 | { 28 | 29 | // Read inputs 30 | equation = this->readInput(equation_input, 0, equation_bank->number_of_equations); 31 | increment_by = this->readInput(sample_rate_input); // range: 0 - 4095 32 | p1 = this->readInput(param1_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 33 | p2 = this->readInput(param2_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 34 | p3 = this->readInput(param3_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 35 | reset = this->readInput(reset_input); 36 | 37 | increment_by = increment_by << 21; 38 | 39 | // If the reset input transitions from low to high, then reset fixed_point_20_12_index 40 | // to 0, which effectively restarts the sound. MID_CV is defined in defines.h 41 | if((reset >= MID_CV) && !old_reset) 42 | { 43 | old_reset = true; 44 | fixed_point_32_32_index = 0; 45 | } 46 | 47 | if(reset < MID_CV) old_reset = false; 48 | 49 | 50 | fixed_point_32_32_index += increment_by; 51 | 52 | // Shift off the 32 bits used for the fractional part, which leaves us with a 32 bit number 53 | // for 't', which is used as the main counter used in the equations. 54 | t = fixed_point_32_32_index >> 32; 55 | 56 | // Play the selected equation 57 | return(this->equation_bank->compute(equation, t, p1, p2, p3)); 58 | } -------------------------------------------------------------------------------- /ModuleFreeze.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleFreeze.h" 3 | #include "defines.h" 4 | #include "GlobalRingBuffer.h" 5 | 6 | ModuleFreeze::ModuleFreeze() 7 | { 8 | buffer_index = 0; 9 | buffer_output = 0; 10 | 11 | audio_input = NULL; 12 | length_input = NULL; 13 | } 14 | 15 | uint16_t ModuleFreeze::compute() 16 | { 17 | uint16_t audio = this->readInput(audio_input); 18 | uint16_t buffer_length = this->readInput(length_input); 19 | 20 | uint16_t inverted_buffer_length = 4095 - buffer_length; 21 | 22 | buffer_index++; 23 | if(buffer_index >= inverted_buffer_length) buffer_index = 0; 24 | 25 | buffer_output = RING_BUFFER[buffer_index]; 26 | 27 | if(buffer_length > 100) 28 | { 29 | return(buffer_output); 30 | } 31 | else 32 | { 33 | RING_BUFFER[buffer_index] = audio; 34 | return(audio); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ModuleFreeze.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleFreeze | 4 | * |----------------------| 5 | * > audio_input | 6 | * > length_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleFreeze is an audio effect for "freezing audio" by capturing a slice of 14 | // audio and looping it. The code for ModuleFreeze is based on the ModuleDelay 15 | // code and shares the same audio buffer. As a side effect, using both a 16 | // ModuleDelay and ModuleFreeze in the same synth may cause strange behavior. 17 | // 18 | // The length_input controls the slice length of the frozen audio. When the 19 | // length input is less than 100, the freeze effect is turned off. This allows 20 | // full control over the freeze effect with one input. 21 | // 22 | // Example usage: 23 | // 24 | // ModuleEqDrum *drum_sound = new ModuleEqDrum(); 25 | // ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 26 | // ModuleFreeze *freeze = new ModuleFreeze(); 27 | // 28 | // ext_clock->clock_input = inputs->gate; 29 | // 30 | // drum_sound->sample_rate_input = inputs->sr; 31 | // drum_sound->drum_selection_input = inputs->mod; 32 | // drum_sound->trigger_input = ext_clock; 33 | // 34 | // freeze->audio_input = drum_sound; 35 | // freeze->length_input = inputs->param1; 36 | // 37 | // this->last_module = freeze; 38 | // 39 | 40 | #ifndef ModuleFreeze_h 41 | #define ModuleFreeze_h 42 | 43 | #include "Arduino.h" 44 | #include "Module.h" 45 | 46 | class ModuleFreeze : public Module 47 | { 48 | 49 | public: 50 | ModuleFreeze(); 51 | uint16_t compute(); 52 | 53 | // Inputs 54 | Module *audio_input; 55 | Module *length_input; 56 | 57 | private: 58 | 59 | int buffer_index; 60 | uint16_t buffer_output; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /ModuleInput.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleInput.h" 3 | #include "defines.h" 4 | 5 | ModuleInput::ModuleInput() 6 | { 7 | this->value = 0; 8 | smooth = new ModuleInputSmooth(this); 9 | } 10 | 11 | uint32_t ModuleInput::run() 12 | { 13 | return(this->value); 14 | } 15 | 16 | void ModuleInput::setValue(uint32_t new_value) 17 | { 18 | this->value = new_value; 19 | } 20 | 21 | uint32_t ModuleInput::getValue() 22 | { 23 | return(this->value); 24 | } 25 | -------------------------------------------------------------------------------- /ModuleInputSmooth.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleInputSmooth.h" 3 | #include "defines.h" 4 | 5 | ModuleInputSmooth::ModuleInputSmooth(Module *parent_module) 6 | { 7 | this->parent_module = parent_module; 8 | this->value = 0; 9 | 10 | index = 0; // the index of the current reading 11 | total = 0; // the running total 12 | average = 0; // the average 13 | 14 | for (int i = 0; i < 8; i++) 15 | { 16 | readings[i] = 0; 17 | } 18 | } 19 | 20 | uint16_t ModuleInputSmooth::compute() 21 | { 22 | // subtract the last reading: 23 | total = total - readings[index]; 24 | 25 | // read from the input 26 | readings[index] = parent_module->compute(); 27 | 28 | // add the reading to the total: 29 | total = total + readings[index]; 30 | 31 | // advance to the next position in the array: 32 | index = index + 1; 33 | 34 | // if we're at the end of the array, then wrap around to the beginning 35 | if (index >= 8) index = 0; 36 | 37 | // calculate the average: 38 | // average = total / 8; 39 | average = total >> 3; 40 | 41 | return(average); 42 | } -------------------------------------------------------------------------------- /ModuleInputSmooth.h: -------------------------------------------------------------------------------- 1 | 2 | // ============================================================================= 3 | // 4 | // This is not a module that you use to build a synth. It gives you the 5 | // ability to smooth inputs: 6 | // 7 | // Before: 8 | // equation_player->equation_input = inputs->mod; 9 | // 10 | // After 11 | // equation_player->equation_input = inputs->mod->smooth; 12 | // 13 | 14 | #ifndef ModuleInputSmooth_h 15 | #define ModuleInputSmooth_h 16 | 17 | #include "Module.h" 18 | 19 | class ModuleInputSmooth : public Module 20 | { 21 | private: 22 | uint16_t compute(); 23 | 24 | public: 25 | ModuleInputSmooth(Module *parent_module); 26 | 27 | // Variables 28 | Module *parent_module; 29 | uint32_t value; // The value of the input 30 | 31 | // Smoothing variables 32 | uint16_t readings[8]; // the readings from the analog input 33 | uint16_t index; // the index of the current reading 34 | uint16_t total; // the running total 35 | uint16_t average; // the average 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /ModuleKitSelect.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleKitSelect.h" 3 | #include "Defines.h" 4 | 5 | 6 | ModuleKitSelect::ModuleKitSelect() 7 | { 8 | 9 | // Initialize all inputs 10 | this->kit_selection_input = NULL; 11 | 12 | // Instantiate all outputs 13 | kick_output = new ModuleOutput(this); 14 | snare_output = new ModuleOutput(this); 15 | hihat_output = new ModuleOutput(this); 16 | 17 | // The outputs of ModuleKitSelect should not 18 | // be mapped by the receiving module, which is 19 | // usually ModuleSamplePlayer 20 | 21 | kick_output->no_output_conversion = true; 22 | snare_output->no_output_conversion = true; 23 | hihat_output->no_output_conversion = true; 24 | } 25 | 26 | uint16_t ModuleKitSelect::compute() 27 | { 28 | 29 | // Read inputs 30 | uint8_t kit_selection = this->readInput(kit_selection_input, 0, 3); 31 | 32 | this->kick_output->value = kits[kit_selection][0]; 33 | this->snare_output->value = kits[kit_selection][1]; 34 | this->hihat_output->value = kits[kit_selection][2]; 35 | 36 | return(0); 37 | } -------------------------------------------------------------------------------- /ModuleKitSelect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleKitSelect | 4 | * |----------------------| 5 | * > kit_selection_input | 6 | * | | 7 | * | kick_output> 8 | * | snare_output> 9 | * | hihat_output> 10 | * +----------------------+ 11 | * 12 | */ 13 | // ============================================================================= 14 | // 15 | // ModuleKitSelect is a helper module for SynthDrumPlayer that outputs three 16 | // values depending on the kit selection input. 17 | // 18 | 19 | #ifndef ModuleKitSelect_h 20 | #define ModuleKitSelect_h 21 | 22 | #include "Arduino.h" 23 | #include "Module.h" 24 | #include "ModuleOutput.h" 25 | 26 | class ModuleKitSelect : public Module 27 | { 28 | 29 | public: 30 | ModuleKitSelect(); 31 | uint16_t compute(); 32 | 33 | // The number in the kits array are the indexes of 34 | // the sounds in ModuleSamplePlayer.php 35 | 36 | uint8_t kits[3][3] = { 37 | { 38 | 0,1,2 39 | }, 40 | { 41 | 3,4,5 42 | }, 43 | { 44 | 6,7,8 45 | } 46 | }; 47 | 48 | 49 | // Inputs 50 | Module *kit_selection_input; 51 | 52 | // Outputs 53 | ModuleOutput *kick_output; 54 | ModuleOutput *snare_output; 55 | ModuleOutput *hihat_output; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ModuleLFO.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleLFO.h" 3 | #include "defines.h" 4 | #include "GlobalWavetables.h" 5 | #include "GlobalIncrements.h" 6 | 7 | ModuleLFO::ModuleLFO() 8 | { 9 | fixed_point_10_22_index = 0; 10 | 11 | // Initialize all module inputs to NULL 12 | this->frequency_input = NULL; 13 | this->wavetable_input = NULL; 14 | } 15 | 16 | uint16_t ModuleLFO::compute() 17 | { 18 | // Read frequency input. 19 | frequency = this->readInput(frequency_input); 20 | 21 | // Read the wavetable input and map it to the appropriate range 22 | wavetable = this->readInput(wavetable_input, 0, NUMBER_OF_WAVETABLES); 23 | wavetable = constrain(wavetable, 0, NUMBER_OF_WAVETABLES - 1); 24 | 25 | // Calculate the index into the wavetable 26 | fixed_point_10_22_index += ((INCREMENTS[frequency] - 3100000) >> 4); 27 | if(fixed_point_10_22_index > WAVE_SAMPLES_SHIFTED_22) fixed_point_10_22_index -= WAVE_SAMPLES_SHIFTED_22; 28 | 29 | wavetable_index = fixed_point_10_22_index >> 22; 30 | 31 | return(WAVETABLES[wavetable][wavetable_index] << 4); 32 | } 33 | -------------------------------------------------------------------------------- /ModuleLooper.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleLooper.h" 3 | #include "Defines.h" 4 | #include "GlobalLoops.h" 5 | #include "GlobalIncrements.h" 6 | 7 | ModuleLooper::ModuleLooper() 8 | { 9 | t = 0; // Sample index 10 | w = 0; // Final output 11 | fixed_point_20_12_index = 0; 12 | triggered = false; 13 | 14 | // Initialize all inputs 15 | this->sample_input = NULL; 16 | this->trigger_input = NULL; 17 | this->sample_rate_input = NULL; 18 | this->slice_input = NULL; 19 | } 20 | 21 | uint16_t ModuleLooper::compute() 22 | { 23 | 24 | // Read inputs 25 | uint16_t sample = this->readInput(sample_input, CONVERT_TO_1_BIT); 26 | uint16_t trigger = this->readInput(trigger_input); 27 | uint16_t frequency = this->readInput(sample_rate_input) << 1; 28 | uint16_t slice = this->readInput(slice_input, CONVERT_TO_4_BIT); // ranges from 0 to 16 29 | 30 | uint16_t sample_length; 31 | 32 | // Select sample 33 | 34 | switch(sample) 35 | { 36 | case 0: 37 | sample_length = DEVINE_BEAT1_LENGTH; 38 | break; 39 | 40 | case 1: 41 | sample_length = DEVINE_BEAT2_LENGTH; 42 | break; 43 | } 44 | 45 | // Handle trigger events 46 | 47 | if((trigger >= MID_CV) && !triggered) 48 | { 49 | triggered = true; 50 | fixed_point_20_12_index = (slice * (sample_length/16)) << 12; 51 | } 52 | 53 | if((trigger < MID_CV) && triggered) 54 | { 55 | triggered = false; 56 | } 57 | 58 | // Playback selected sample 59 | 60 | t = fixed_point_20_12_index >> 12; 61 | 62 | if(t >= sample_length) 63 | { 64 | t = t - sample_length; 65 | fixed_point_20_12_index = t << 12; 66 | } 67 | 68 | switch(sample) 69 | { 70 | case 0: 71 | w = DEVINE_BEAT1[t]; 72 | break; 73 | 74 | case 1: 75 | w = DEVINE_BEAT2[t]; 76 | break; 77 | } 78 | 79 | 80 | fixed_point_20_12_index += frequency; 81 | 82 | 83 | return(w<<4); 84 | } 85 | -------------------------------------------------------------------------------- /ModuleLooper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +------------------------+ 3 | * | ModuleLooper | 4 | * |------------------------| 5 | * > trigger_input | 6 | * > sample_rate_input | 7 | * | output > 8 | * +------------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // 14 | 15 | #ifndef ModuleLooper_h 16 | #define ModuleLooper_h 17 | 18 | #include "Arduino.h" 19 | #include "Module.h" 20 | 21 | class ModuleLooper : public Module 22 | { 23 | 24 | public: 25 | ModuleLooper(); 26 | uint16_t compute(); 27 | 28 | // Inputs 29 | Module *sample_input; 30 | Module *sample_rate_input; 31 | Module *slice_input; 32 | Module *trigger_input; 33 | 34 | private: 35 | boolean triggered; 36 | boolean playing; 37 | 38 | uint32_t t; // Accumulator used in equations 39 | uint32_t w; // The final output 40 | 41 | uint32_t fixed_point_20_12_index; 42 | 43 | void stop_playback(); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ModuleLowpassFilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleLowpassFilter | 4 | * |----------------------| 5 | * > audio_input | 6 | * > cutoff_input | 7 | * > resonance_input | 8 | * | | 9 | * | output > 10 | * +----------------------+ 11 | */ 12 | // ============================================================================= 13 | // 14 | // ModuleLowpassFilter is a 24db resonant lowpass (Moog style) with control over 15 | // cutoff and resonance. 16 | // 17 | // Example usage: 18 | // 19 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 20 | // ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 21 | // 22 | // // Patch up ocillator 23 | // wavetable_osc->frequency_input = inputs->sr; 24 | // wavetable_osc->wavetable_input = inputs->mod; 25 | // 26 | // // Patch up filter 27 | // lowpass_filter->audio_input = wavetable_osc; 28 | // lowpass_filter->cutoff_input = inputs->param1; 29 | // lowpass_filter->resonance_input = inputs->param2; 30 | // 31 | // this->last_module = lowpass_filter; 32 | // 33 | 34 | 35 | #ifndef ModuleLowpassFilter_h 36 | #define ModuleLowpassFilter_h 37 | 38 | #include "Arduino.h" 39 | #include "Module.h" 40 | 41 | class ModuleLowpassFilter : public Module 42 | { 43 | 44 | public: 45 | 46 | // Methods 47 | ModuleLowpassFilter(); 48 | uint16_t compute(); 49 | 50 | // Inputs 51 | Module *audio_input; 52 | Module *cutoff_input; 53 | Module *resonance_input; 54 | 55 | long y1,y2,y3,y4,oldx,oldy1,oldy2,oldy3; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /ModuleMap.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleMap.h" 3 | #include "defines.h" 4 | 5 | ModuleMap::ModuleMap(uint32_t low, uint32_t high) 6 | { 7 | this->no_output_conversion = true; 8 | this->low = low; 9 | this->high = high; 10 | } 11 | 12 | uint16_t ModuleMap::compute() 13 | { 14 | return(map(this->readInput(input), 0, 4095, low, high)); 15 | } -------------------------------------------------------------------------------- /ModuleMap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleMap | 4 | * |----------------------| 5 | * > input | 6 | * | output > 7 | * +----------------------+ 8 | * 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // Maps an incoming signal to a range. The range is passed into this module's 14 | // constructor. For example, to map a value between 0 and 4 (inclusive), 15 | // you would instantiate a ModuleMap like: 16 | // 17 | // ModuleMap *map_0_4 = new ModuleMap(0,4); 18 | // 19 | // You use a ModuleMap module if you need to adjust the output of one module to 20 | // be compatible with the input of another module. Module's are constructed such 21 | // that this conversion is normally unnecessary. But, for example, if you want 22 | // the output of an LFO to select from the first 5 wavetables in the 23 | // ModuleWavetableOsc, then you'll need to use a ModuleMap (see example below). 24 | // 25 | // Example usage: 26 | // 27 | // ModuleMap *map_0_5 = new ModuleMap(0,5); 28 | // ModuleLFO *lfo = new LFO(); 29 | // ModuleWavetableOsc *wavetable_osc = new WavetableOsc(); 30 | // 31 | // lfo->frequency_input = 500; 32 | // map_0_5->input = lfo; 33 | // wavetable_osc->wavetable_input = map_0_5; 34 | // 35 | 36 | 37 | #ifndef ModuleMap_h 38 | #define ModuleMap_h 39 | 40 | #include "Module.h" 41 | 42 | class ModuleMap : public Module 43 | { 44 | public: 45 | ModuleMap(uint32_t low, uint32_t high); 46 | uint16_t compute(); 47 | 48 | // Inputs 49 | Module *input; 50 | 51 | uint32_t low; 52 | uint32_t high; 53 | }; 54 | 55 | #endif -------------------------------------------------------------------------------- /ModuleMixer2.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleMixer2.h" 2 | #include "defines.h" 3 | 4 | ModuleMixer2::ModuleMixer2() 5 | { 6 | this->input_1 = NULL; 7 | this->input_2 = NULL; 8 | } 9 | 10 | uint16_t ModuleMixer2::compute() 11 | { 12 | // Read inputs 13 | uint32_t value_1 = this->readInput(input_1); 14 | uint32_t value_2 = this->readInput(input_2); 15 | 16 | return((value_1 + value_2)>>1); 17 | } 18 | -------------------------------------------------------------------------------- /ModuleMixer2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleMixer2 | 4 | * |----------------------| 5 | * > input_1 | 6 | * > input_2 | 7 | * | | 8 | * | output > 9 | * +----------------------+ 10 | */ 11 | // ============================================================================= 12 | // 13 | // 2 input mixer. 14 | // 15 | // Example usage: 16 | // 17 | // ModuleWavetableOsc *wavetable_osc1 = new WavetableOsc(); 18 | // ModuleWavetableOsc *wavetable_osc2 = new WavetableOsc(); 19 | // ModuleMixer2 *mixer = new ModuleMixer2(); 20 | // 21 | // wavetable_osc1->frequency_input = inputs->sr; 22 | // wavetable_osc2->frequency_input = inputs->sr; 23 | // 24 | // wavetable_osc1->wavetable_input = inputs->param1; 25 | // wavetable_osc2->wavetable_input = inputs->param2; 26 | // 27 | // mixer->input_1 = wavetable_osc1; 28 | // mixer->input_2 = wavetable_osc2; 29 | // 30 | // this->last_module = mixer; 31 | // 32 | 33 | #ifndef ModuleMixer2_h 34 | #define ModuleMixer2_h 35 | 36 | #include "Module.h" 37 | 38 | class ModuleMixer2 : public Module 39 | { 40 | public: 41 | ModuleMixer2(); 42 | uint16_t compute(); 43 | 44 | // Inputs 45 | Module *input_1; 46 | Module *input_2; 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /ModuleMixer3.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleMixer3.h" 2 | #include "defines.h" 3 | 4 | ModuleMixer3::ModuleMixer3() 5 | { 6 | this->input_1 = NULL; 7 | this->input_2 = NULL; 8 | this->input_3 = NULL; 9 | } 10 | 11 | uint16_t ModuleMixer3::compute() 12 | { 13 | // Read inputs 14 | uint32_t value_1 = this->readInput(input_1); 15 | uint32_t value_2 = this->readInput(input_2); 16 | uint32_t value_3 = this->readInput(input_3); 17 | 18 | return((value_1 + value_2 + value_3)/3); 19 | } 20 | -------------------------------------------------------------------------------- /ModuleMixer3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleMixer3 | 4 | * |----------------------| 5 | * > input1 | 6 | * > input2 | 7 | * > input3 | 8 | * | | 9 | * | output > 10 | * +----------------------+ 11 | */ 12 | // ============================================================================= 13 | // 14 | // 3 input mixer. 15 | // 16 | // Example usage: 17 | // 18 | // ModuleDrumSequencer *drum_sequencer = new ModuleDrumSequencer(); 19 | // 20 | // ModuleEqDrum *kick = new ModuleEqDrum(); 21 | // ModuleEqDrum *snare = new ModuleEqDrum(); 22 | // ModuleEqDrum *hihat = new ModuleEqDrum(); 23 | // ModuleMixer3 *mixer = new ModuleMixer3(); 24 | // 25 | // drum_sequencer->clock_input = inputs->gate; 26 | // 27 | // drum_sequencer->kick_pattern_input = inputs->param1; 28 | // drum_sequencer->snare_pattern_input = inputs->param2; 29 | // drum_sequencer->hihat_pattern_input = inputs->param3; 30 | // 31 | // kick->trigger_input = drum_sequencer->kick_output; 32 | // kick->sample_rate_input = inputs->sr; 33 | // kick->drum_selection_input = new ModuleConstant(0); 34 | // 35 | // snare->trigger_input = drum_sequencer->snare_output; 36 | // snare->sample_rate_input = inputs->sr; 37 | // snare->drum_selection_input = new ModuleConstant(3); 38 | // 39 | // hihat->trigger_input = drum_sequencer->hihat_output;; 40 | // hihat->sample_rate_input = inputs->sr; 41 | // hihat->drum_selection_input = new ModuleConstant(7); 42 | // 43 | // mixer->input_1 = kick; 44 | // mixer->input_2 = snare; 45 | // mixer->input_3 = hihat; 46 | // 47 | // 48 | // this->last_module = mixer; 49 | 50 | 51 | #ifndef ModuleMixer3_h 52 | #define ModuleMixer3_h 53 | 54 | #include "Module.h" 55 | 56 | class ModuleMixer3 : public Module 57 | { 58 | public: 59 | ModuleMixer3(); 60 | uint16_t compute(); 61 | 62 | // Inputs 63 | Module *input_1; 64 | Module *input_2; 65 | Module *input_3; 66 | }; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /ModuleMultiply.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleMultiply.h" 2 | #include "defines.h" 3 | 4 | ModuleMultiply::ModuleMultiply() 5 | { 6 | this->input_1 = NULL; 7 | this->input_2 = NULL; 8 | } 9 | 10 | uint16_t ModuleMultiply::compute() 11 | { 12 | // Read inputs 13 | uint32_t value_1 = this->readInput(input_1); 14 | uint32_t value_2 = this->readInput(input_2); 15 | 16 | uint32_t product = value_1 * value_2; 17 | 18 | if(product > MAX_CV) 19 | { 20 | return(product >> 12); 21 | } 22 | else 23 | { 24 | return(product); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ModuleMultiply.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleMultiply | 4 | * |----------------------| 5 | * > input_1 | 6 | * > input_2 | 7 | * | | 8 | * | output > 9 | * +----------------------+ 10 | */ 11 | // ============================================================================= 12 | // 13 | // Multiplies the values at input_1 and input_2 and outputs the product. 14 | // 15 | // Example usage: 16 | // 17 | // ModuleWavetableOsc *wavetable_osc1 = new ModuleWavetableOsc(); 18 | // ModuleWavetableOsc *wavetable_osc2 = new ModuleWavetableOsc(); 19 | // ModuleMultiply *multiply = new ModuleMultiply(); 20 | // 21 | // wavetable_osc1->wavetable_input = inputs->param1; 22 | // wavetable_osc2->wavetable_input = inputs->param2; 23 | // 24 | // wavetable_osc1->frequency_input = inputs->sr; 25 | // wavetable_osc2->frequency_input = inputs->sr; 26 | // 27 | // wavetable_osc2->phase_input = inputs->mod; 28 | // 29 | // multiply->input_1 = wavetable_osc1; 30 | // multiply->input_2 = wavetable_osc2; 31 | // 32 | // this->last_module = multiply; 33 | 34 | 35 | #ifndef ModuleMultiply_h 36 | #define ModuleMultiply_h 37 | 38 | #include "Module.h" 39 | 40 | class ModuleMultiply : public Module 41 | { 42 | public: 43 | ModuleMultiply(); 44 | uint16_t compute(); 45 | 46 | // Inputs 47 | Module *input_1; 48 | Module *input_2; 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /ModuleOscParam.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +------------------------+ 3 | * | ModuleOscParam | 4 | * |------------------------| 5 | * > waveform_input | 6 | * > pitch_input | 7 | * > fine_input | 8 | * | | 9 | * > osc1_waveform > 10 | * > osc2_waveform > 11 | * > osc3_waveform > 12 | * > osc1_pitch > 13 | * > osc2_pitch > 14 | * > osc3_pitch > 15 | * > vca1_volume > 16 | * > vca2_volume > 17 | * > vca3_volume > 18 | * | | 19 | * +------------------------+ 20 | * 21 | */ 22 | // ============================================================================= 23 | // 24 | // ModuleOscParam takes 3 inputs and routes them to 9 outputs, in order to send 25 | // parameters to a 3 osc synth. This module is very specific to Synth3Osc. 26 | // 27 | 28 | 29 | #ifndef ModuleOscParam_h 30 | #define ModuleOscParam_h 31 | 32 | #include "Module.h" 33 | #include "ModuleOutput.h" 34 | 35 | class ModuleOscParam : public Module 36 | { 37 | public: 38 | ModuleOscParam(); 39 | uint16_t compute(); 40 | 41 | // Inputs 42 | Module *waveform_input; 43 | Module *pitch_input; 44 | Module *fine_input; 45 | 46 | // Outputs 47 | ModuleOutput *osc1_waveform; 48 | ModuleOutput *osc2_waveform; 49 | ModuleOutput *osc3_waveform; 50 | ModuleOutput *osc1_pitch; 51 | ModuleOutput *osc2_pitch; 52 | ModuleOutput *osc3_pitch; 53 | ModuleOutput *vca1_volume; 54 | ModuleOutput *vca2_volume; 55 | ModuleOutput *vca3_volume; 56 | }; 57 | 58 | #endif -------------------------------------------------------------------------------- /ModuleOutput.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleOutput.h" 3 | #include "defines.h" 4 | 5 | ModuleOutput::ModuleOutput(Module *parent_module) 6 | { 7 | this->value = 0; 8 | this->parent_module = parent_module; 9 | } 10 | 11 | uint16_t ModuleOutput::compute() 12 | { 13 | // Call the parent module's run method. Notice that the return results from 14 | // the run method are ignored. That's becuase, in this case, it's assumed that 15 | // the parent module will set this->value explicitely for this output module. 16 | this->parent_module->run(this->cycle); 17 | 18 | // this->value is the value at this output node 19 | return(this->value); 20 | } 21 | -------------------------------------------------------------------------------- /ModuleOutput.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleOutput | 4 | * |----------------------| 5 | * | output > 6 | * +----------------------+ 7 | */ 8 | // ============================================================================= 9 | // 10 | // Unlike most other modules, the ModuleOutput is NOT created inside of a synth. 11 | // Instead, it is created inside another module if that module requires multiple 12 | // outputs. 13 | // 14 | // If you're only creating synths and not building your own modules, you don't 15 | // have to worry about creating output modules. If you are building your own 16 | // modules which have mutiple outputs, see the tutorial in the online documentation 17 | // for creating modules. 18 | // 19 | // Typically, when creating a synth's code, you can wire together modules 20 | // like so: 21 | // 22 | // some_module.some_input = some_other_module 23 | // 24 | // But if some_other_module has multiple outputs, you can specify the output like: 25 | // 26 | // some_module.some_intput = some_other_module.specific_output 27 | // 28 | 29 | 30 | #ifndef ModuleOutput_h 31 | #define ModuleOutput_h 32 | 33 | #include "Module.h" 34 | 35 | class ModuleOutput : public Module 36 | { 37 | public: 38 | ModuleOutput(Module *parent_module); 39 | uint16_t compute(); 40 | uint16_t value; 41 | 42 | private: 43 | Module *parent_module; 44 | 45 | }; 46 | 47 | #endif -------------------------------------------------------------------------------- /ModuleQuantizer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleQuantizer.h" 3 | #include "defines.h" 4 | #include "GlobalScales.h" 5 | 6 | uint16_t ModuleQuantizer::compute() 7 | { 8 | uint32_t cv; 9 | uint32_t scale = this->readInput(this->scale_input, 0, 15); 10 | 11 | // The NOTES array and scale arrays are defined in Scales.h/Scales.cpp 12 | 13 | switch(scale) { 14 | case 0: 15 | cv = this->readInput(this->cv_input, 0, 60); 16 | return(NOTES[CHROMATIC[cv]]); 17 | case 1: 18 | cv = this->readInput(this->cv_input, 0, 36); 19 | return(NOTES[IONIAN[cv]]); 20 | case 2: 21 | cv = this->readInput(this->cv_input, 0, 35); 22 | return(NOTES[DORIAN[cv]]); 23 | case 3: 24 | cv = this->readInput(this->cv_input, 0, 35); 25 | return(NOTES[LYDIAN[cv]]); 26 | case 4: 27 | cv = this->readInput(this->cv_input, 0, 35); 28 | return(NOTES[PHRYGIAN[cv]]); 29 | case 5: 30 | cv = this->readInput(this->cv_input, 0, 35); 31 | return(NOTES[MIXOLYDIAN[cv]]); 32 | case 6: 33 | cv = this->readInput(this->cv_input, 0, 35); 34 | return(NOTES[AEOLIAN[cv]]); 35 | case 7: 36 | cv = this->readInput(this->cv_input, 0, 35); 37 | return(NOTES[LOCRIAN[cv]]); 38 | case 8: 39 | cv = this->readInput(this->cv_input, 0, 25); 40 | return(NOTES[MAJOR_PENTATONIC[cv]]); 41 | case 9: 42 | cv = this->readInput(this->cv_input, 0, 25); 43 | return(NOTES[MINOR_PENTATONIC[cv]]); 44 | case 10: 45 | cv = this->readInput(this->cv_input, 0, 30); 46 | return(NOTES[BLUES[cv]]); 47 | case 11: 48 | cv = this->readInput(this->cv_input, 0, 40); 49 | return(NOTES[DIMINISHED[cv]]); 50 | case 12: 51 | cv = this->readInput(this->cv_input, 0, 40); 52 | return(NOTES[ARABIAN[cv]]); 53 | case 13: 54 | cv = this->readInput(this->cv_input, 0, 15); 55 | return(NOTES[MAJOR[cv]]); 56 | case 14: 57 | cv = this->readInput(this->cv_input, 0, 15); 58 | return(NOTES[MINOR[cv]]); 59 | case 15: 60 | cv = this->readInput(this->cv_input, 0, 42); 61 | return(NOTES[PRISM[cv]]); 62 | } 63 | } -------------------------------------------------------------------------------- /ModuleQuantizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleQuantizer | 4 | * |----------------------| 5 | * > cv_input | 6 | * > scale_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleQuantizer is a simple note quantizer based on scales. 14 | // 15 | // There are two inputs to the ModuleQuantizer: 16 | // 17 | // cv_input: The signal to quantize 18 | // scale_input: Selects the scale for quantization 19 | // 20 | // The scales themselves are defined in GlobalScales.cpp: 21 | // 22 | // 0: CHROMATIC 23 | // 1: IONIAN 24 | // 2: DORIAN 25 | // 3: LYDIAN 26 | // 4: PHRYGIAN 27 | // 5: MIXOLYDIAN 28 | // 6: AEOLIAN 29 | // 7: LOCRIAN 30 | // 8: MAJOR_PENTATONIC 31 | // 9: MINOR_PENTATONIC 32 | // 10: BLUES 33 | // 11: DIMINISHED 34 | // 12: ARABIAN 35 | // 13: MAJOR 36 | // 14: MINOR 37 | // 15: PRISM 38 | // 39 | // Example usage: 40 | // 41 | // ModuleQuantizer *quantizer = new ModuleQuantizer(); 42 | // ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 43 | // 44 | // osc->wavetable_input = inputs->mod; 45 | // osc->frequency_input = inputs->sr; 46 | // 47 | // quantizer->cv_input = osc; 48 | // quantizer->scale_input = inputs->param1; 49 | // 50 | // this->last_module = quantizer; 51 | // 52 | // Also see: SynthPatterns.cpp 53 | 54 | #ifndef ModuleQuantizer_h 55 | #define ModuleQuantizer_h 56 | 57 | #include "Arduino.h" 58 | #include "Module.h" 59 | 60 | class ModuleQuantizer : public Module 61 | { 62 | 63 | public: 64 | uint16_t compute(); 65 | 66 | // Inputs 67 | Module *cv_input; 68 | Module *scale_input; 69 | 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /ModuleRotatingRouter3.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleRotatingRouter3.h" 3 | #include "defines.h" 4 | 5 | ModuleRotatingRouter3::ModuleRotatingRouter3() 6 | { 7 | this->triggered = false; 8 | this->trigger = 0; 9 | this->rotation = 0; 10 | 11 | // Initialize all module inputs to NULL 12 | this->rotate_input = NULL; 13 | this->input_1 = NULL; 14 | this->input_2 = NULL; 15 | this->input_3 = NULL; 16 | 17 | // Instantiate all outputs 18 | this->output_1 = new ModuleOutput(this); 19 | this->output_2 = new ModuleOutput(this); 20 | this->output_3 = new ModuleOutput(this); 21 | } 22 | 23 | uint16_t ModuleRotatingRouter3::compute() 24 | { 25 | uint32_t trigger = readInput(this->rotate_input); 26 | 27 | if((trigger >= MID_CV) && !triggered) 28 | { 29 | triggered = true; 30 | rotation ++; 31 | if (rotation == 3) rotation = 0; 32 | } 33 | 34 | if(trigger < MID_CV) 35 | { 36 | triggered = false; 37 | } 38 | 39 | switch(rotation) 40 | { 41 | case 0: 42 | this->output_1->value = this->readInput(this->input_1); 43 | this->output_2->value = this->readInput(this->input_2); 44 | this->output_3->value = this->readInput(this->input_3); 45 | break; 46 | case 1: 47 | this->output_1->value = this->readInput(this->input_2); 48 | this->output_2->value = this->readInput(this->input_3); 49 | this->output_3->value = this->readInput(this->input_1); 50 | break; 51 | case 2: 52 | this->output_1->value = this->readInput(this->input_3); 53 | this->output_2->value = this->readInput(this->input_1); 54 | this->output_3->value = this->readInput(this->input_2); 55 | break; 56 | } 57 | 58 | return(this->output_1->value); 59 | } -------------------------------------------------------------------------------- /ModuleRotatingRouter3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +------------------------+ 3 | * | ModuleRotatingRouter3 | 4 | * |------------------------| 5 | * > rotate_input | 6 | * | | 7 | * > input_1 output_1 > 8 | * > input_2 output_2 > 9 | * > input_3 output_3 > 10 | * | | 11 | * +------------------------+ 12 | * 13 | */ 14 | // ============================================================================= 15 | // 16 | // ModuleRotatingRouter3 takes 3 inputs and routes them to 3 outputs. For 17 | // example: 18 | // 19 | // input_1 => output_1 20 | // input_2 => output_2 21 | // input_3 => output_3 22 | // 23 | // When the rotation input is triggered, the output "rotates". 24 | // 25 | // The first rotation is: 26 | // 27 | // input_1 => output_2 28 | // input_2 => output_3 29 | // input_3 => output_1 30 | // 31 | // The second rotation is: 32 | // 33 | // input_1 => output_3 34 | // input_2 => output_1 35 | // input_3 => output_2 36 | // 37 | 38 | #ifndef ModuleRotatingRouter3_h 39 | #define ModuleRotatingRouter3_h 40 | 41 | #include "Module.h" 42 | #include "ModuleOutput.h" 43 | 44 | class ModuleRotatingRouter3 : public Module 45 | { 46 | public: 47 | ModuleRotatingRouter3(); 48 | uint16_t compute(); 49 | 50 | uint8_t rotation; 51 | uint16_t trigger; 52 | boolean triggered; 53 | 54 | // Inputs 55 | Module *rotate_input; 56 | Module *input_1; 57 | Module *input_2; 58 | Module *input_3; 59 | 60 | // Outputs 61 | ModuleOutput *output_1; 62 | ModuleOutput *output_2; 63 | ModuleOutput *output_3; 64 | }; 65 | 66 | #endif -------------------------------------------------------------------------------- /ModuleSampleAndHold.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleSampleAndHold.h" 3 | #include "defines.h" 4 | 5 | ModuleSampleAndHold::ModuleSampleAndHold() 6 | { 7 | this->triggered = false; 8 | this->sampled_value = 0; 9 | } 10 | 11 | uint16_t ModuleSampleAndHold::compute() 12 | { 13 | uint16_t clock = this->readInput(trigger_input); 14 | 15 | if((clock < MID_CV) && triggered) triggered = false; 16 | 17 | if((clock >= MID_CV) && !triggered) 18 | { 19 | sampled_value = this->readInput(sample_input); 20 | triggered = true; 21 | } 22 | 23 | return(sampled_value); 24 | } 25 | -------------------------------------------------------------------------------- /ModuleSampleAndHold.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleSampleAndHold | 4 | * |----------------------| 5 | * > trigger_input | 6 | * > sample_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | * 11 | */ 12 | // ============================================================================= 13 | // 14 | // ModuleSampleAndHold acts like a traditional analog Sample&Hold module. 15 | // A rising clock signal at trigger_input samples the value at sample_input and 16 | // outputs it. 17 | // 18 | // Example usage: 19 | // 20 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 21 | // ModulePatternGenerator *pattern_generator = new ModulePatternGenerator(); 22 | // ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 23 | // ModuleSampleAndHold *sample_and_hold = new ModuleSampleAndHold(); 24 | // 25 | // ext_clock->clock_input = inputs->gate; 26 | // 27 | // pattern_generator->cv_pattern_input = inputs->param1; 28 | // pattern_generator->gate_pattern_input = inputs->param2; 29 | // pattern_generator->gate_density_input = inputs->param3; 30 | // pattern_generator->clock_input = ext_clock; 31 | // pattern_generator->length_input = new ModuleConstant(16); 32 | // 33 | // sample_and_hold->sample_input = pattern_generator->cv_output; 34 | // sample_and_hold->trigger_input = pattern_generator->gate_output; 35 | // 36 | // wavetable_osc->wavetable_input = inputs->mod; 37 | // wavetable_osc->frequency_input = pattern_generator; 38 | // 39 | // this->last_module = wavetable_osc; 40 | 41 | 42 | #ifndef ModuleSampleAndHold_h 43 | #define ModuleSampleAndHold_h 44 | 45 | #include "Module.h" 46 | 47 | class ModuleSampleAndHold : public Module 48 | { 49 | public: 50 | ModuleSampleAndHold(); 51 | uint16_t compute(); 52 | 53 | // Inputs 54 | Module *trigger_input; 55 | Module *sample_input; 56 | 57 | private: 58 | uint16_t sampled_value; 59 | boolean triggered; 60 | }; 61 | 62 | #endif -------------------------------------------------------------------------------- /ModuleSequencer.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleSequencer.h" 3 | #include "defines.h" 4 | 5 | ModuleSequencer::ModuleSequencer(int values[]) 6 | { 7 | this->step = 0; 8 | this->old_clock = 0; 9 | 10 | for(int i=0; i < 8; i++) 11 | { 12 | this->sequence[i] = values[i]; 13 | } 14 | 15 | // Initialize all inputs 16 | this->clock_input = NULL; 17 | } 18 | 19 | uint16_t ModuleSequencer::compute() 20 | { 21 | uint16_t clock = this->readInput(clock_input); 22 | 23 | // Step the sequencer on the rising edge 24 | if((clock > MID_CV) && (old_clock < MID_CV)) 25 | { 26 | step++; 27 | if(step >= 8) step = 0; 28 | } 29 | 30 | old_clock = clock; 31 | 32 | // Serial.println(sequence[step]); 33 | 34 | return(sequence[step]); 35 | } 36 | -------------------------------------------------------------------------------- /ModuleSequencer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleSequencer | 4 | * |----------------------| 5 | * > clock_input | 6 | * | | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | * 11 | */ 12 | // ============================================================================= 13 | // 14 | // ModuleSequencer is a simple 8 step CV sequencer. Clocking the sequencer 15 | // steps through the 8 steps. The sequence itself is passed into the module's 16 | // constructor. 17 | // 18 | // Example usage: 19 | // 20 | // int sequence[] = { 0, 100, 2300, 4000, 1400, 500, 70, 4092 }; 21 | // 22 | // ModuleSequencer *sequencer = new ModuleSequencer(sequence); 23 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 24 | // 25 | // sequencer->clock_input = inputs->gate; 26 | // 27 | // wavetable_osc->equation_input = inputs->mod; 28 | // wavetable_osc->frequency_input = sequencer; 29 | // 30 | // this->last_module = wavetable_osc; 31 | // 32 | 33 | #ifndef ModuleSequencer_h 34 | #define ModuleSequencer_h 35 | 36 | #include "Arduino.h" 37 | #include "Module.h" 38 | 39 | class ModuleSequencer : public Module 40 | { 41 | 42 | public: 43 | ModuleSequencer(int values[]); 44 | uint16_t compute(); 45 | 46 | // Inputs 47 | Module *clock_input; 48 | 49 | private: 50 | int step; 51 | int sequence[8]; 52 | uint16_t old_clock; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ModuleSmooth.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleSmooth.h" 3 | #include "defines.h" 4 | 5 | ModuleSmooth::ModuleSmooth() 6 | { 7 | mix = 819; // .2 * 4096 (20% wet, 80% dry) 8 | smooth_output = 0; 9 | 10 | for(int i=0; i++; i<6) 11 | { 12 | buffer[i] = 0; 13 | } 14 | 15 | // Initialize all inputs 16 | this->audio_input = NULL; 17 | this->mix_input = NULL; 18 | } 19 | 20 | // 21 | // haystack smooth using coefficients 1 3 6 7 6 3 1 22 | // See: http://terpconnect.umd.edu/~toh/spectrum/Smoothing.html 23 | // 24 | uint16_t ModuleSmooth::compute() 25 | { 26 | uint16_t audio = this->readInput(audio_input); 27 | uint16_t mix = this->readInput(mix_input); 28 | uint16_t wet_mix = 4095 - mix; 29 | 30 | buffer[0] = buffer[1]; 31 | buffer[1] = buffer[2]; 32 | buffer[2] = buffer[3]; 33 | buffer[3] = buffer[4]; 34 | buffer[4] = buffer[5]; 35 | buffer[5] = buffer[6]; 36 | buffer[6] = audio; 37 | 38 | smooth_output = ((buffer[0] + (3*buffer[1]) + (6*buffer[2]) + (7*buffer[3]) + (6*buffer[4]) + (3*buffer[5]) + buffer[6]) / 27.0); 39 | 40 | if(mix == 0) 41 | { 42 | return(audio); 43 | } 44 | else 45 | { 46 | return(((smooth_output * mix) >> 12) + ((audio * wet_mix) >> 12)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ModuleSmooth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleSmooth | 4 | * |----------------------| 5 | * > audio_input | 6 | * > mix_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleSmooth is used for smoothing audio. Does it work? Mayyybbeee.. 14 | // It actually seems to add some overtones to audio input. So, perhaps there's 15 | // a bug in my implementation, but I'm keeping it around because it's interesting. 16 | // 17 | // I think that the original implementation of this algorithm was for reducing 18 | // noise in a signal. If you're trying to reduce noise on CV inputs, don't 19 | // use this module. Instead, add '->smooth' when reading an analog input. 20 | // For example: 21 | // 22 | // lfo->frequency_input = inputs->param1->smooth; 23 | // 24 | // Smoothing algorithm based on: http://terpconnect.umd.edu/~toh/spectrum/Smoothing.html 25 | // 26 | // Example usage: 27 | // 28 | // ModuleWavetable *wavetable = new ModuleWavetable(equations); 29 | // ModuleSmooth *smooth = new ModuleSmooth(); 30 | // 31 | // wavetable->equation_input = inputs->mod; 32 | // wavetable->frequency_input = inputs->sr; 33 | // 34 | // smooth->audio_input = wavetable; 35 | // smooth->mix_input = inputs->param1; 36 | // 37 | // this->last_module = smooth; 38 | // 39 | 40 | #ifndef ModuleSmooth_h 41 | #define ModuleSmooth_h 42 | 43 | #include "Arduino.h" 44 | #include "Module.h" 45 | 46 | class ModuleSmooth : public Module 47 | { 48 | 49 | public: 50 | ModuleSmooth(); 51 | uint16_t compute(); 52 | 53 | // Inputs 54 | Module *audio_input; 55 | Module *mix_input; 56 | 57 | private: 58 | 59 | uint16_t buffer[6]; 60 | uint16_t mix; // ranged from 0 to 4095, where 0 == dry, 4095 == wet 61 | uint16_t smooth_output; 62 | }; 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /ModuleSpeechSound.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleSpeechSound.h" 3 | #include "Defines.h" 4 | #include "GlobalSpeechTables.h" 5 | 6 | uint16_t ModuleSpeechSound::compute() 7 | { 8 | uint8_t phase1_input = readInput(this->phase1_input, CONVERT_TO_6_BIT)+8; 9 | uint8_t phase2_input = readInput(this->phase2_input, CONVERT_TO_6_BIT)+20; 10 | uint8_t phase3_input = readInput(this->phase3_input, CONVERT_TO_7_BIT); 11 | uint8_t formant_scale = readInput(this->formant_scale_input, CONVERT_TO_7_BIT)+8; 12 | uint8_t pitch_input = readInput(this->pitch_input, CONVERT_TO_6_BIT); 13 | 14 | int16_t value; 15 | 16 | pitchPhaseInc = speechPitchTable[pitch_input]; 17 | form1PhaseInc = phase1_input * formant_scale; 18 | form2PhaseInc = phase2_input * formant_scale; 19 | form3PhaseInc = phase3_input * formant_scale; 20 | 21 | form1Amp = 14; 22 | form2Amp = 14; 23 | form3Amp = 15; 24 | 25 | form1Phase += form1PhaseInc; 26 | value = speechSinCalc[(int)(((form1Phase>>8) & 0xf0) | form1Amp)]; 27 | form2Phase += form2PhaseInc; 28 | value += speechSinCalc[(int)(((form2Phase>>8) & 0xf0) | form2Amp)]; 29 | form3Phase += form3PhaseInc; 30 | value += speechSqrCalc[(int)(((form3Phase>>8) & 0xf0) | form3Amp)]; 31 | 32 | value = (value * (0xff^(pitchPhase>>8)))>>8; 33 | pitchPhase += pitchPhaseInc; 34 | 35 | if (pitchPhase < pitchPhaseInc) 36 | { 37 | form1Phase = 0; 38 | form2Phase = 0; 39 | form3Phase = 0; 40 | } 41 | 42 | value = value << 4; 43 | value += 2047; 44 | 45 | return(value); 46 | } 47 | -------------------------------------------------------------------------------- /ModuleSpeechSound.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleSpeechSound | 4 | * |----------------------| 5 | * > phase1_input | 6 | * > phase2_input | 7 | * > phase3_input | 8 | * > pitch_input | 9 | * > formant_scale_input | 10 | * | | 11 | * | output > 12 | * +----------------------+ 13 | * 14 | */ 15 | // ============================================================================= 16 | // 17 | // ModuleSpeechSound is a Formant synthesizer that makes sounds similar to vowel 18 | // sounds. 19 | // 20 | 21 | #ifndef ModuleSpeechSound_h 22 | #define ModuleSpeechSound_h 23 | 24 | #include "Module.h" 25 | 26 | #define FORMANT_SZ 7 27 | 28 | class ModuleSpeechSound : public Module 29 | { 30 | public: 31 | uint16_t compute(); 32 | 33 | // Inputs 34 | Module *phase1_input; 35 | Module *phase2_input; 36 | Module *phase3_input; 37 | Module *pitch_input; 38 | Module *formant_scale_input; 39 | 40 | private: 41 | 42 | uint16_t pitchPhase, form1Phase, form2Phase, form3Phase; 43 | uint16_t pitchPhaseInc, form1PhaseInc, form2PhaseInc, form3PhaseInc; 44 | uint8_t form1Amp, form2Amp, form3Amp; 45 | 46 | int frameTime; 47 | uint16_t basePitch; 48 | int formantScale; 49 | }; 50 | 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /ModuleSwitch.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleSwitch.h" 3 | #include "defines.h" 4 | 5 | uint16_t ModuleSwitch::compute() 6 | { 7 | if(this->readInput(select_input) >= MID_CV) 8 | { 9 | return(this->readInput(b_input)); 10 | } 11 | else 12 | { 13 | return(this->readInput(a_input)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ModuleSwitch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleSwitch | 4 | * |----------------------| 5 | * > select_input | 6 | * > a_input | 7 | * > b_input | 8 | * | output > 9 | * +----------------------+ 10 | * 11 | */ 12 | // ============================================================================= 13 | // 14 | // ModuleSwitch routes either a_input or b_input to the output depending on the 15 | // value at select_input. If select_input is greater than MID_CV, intput_b 16 | // is routed to the output. Otherwise input_a is routed to the output. 17 | // 18 | // Example usage: 19 | // 20 | // ModuleWavetableOsc *osc1 = new ModuleWavetableOsc(); 21 | // osc1->wavetable_input = inputs->param2; 22 | // osc1->frequency_input = inputs->param3; 23 | // 24 | // ModuleWavetableOsc *osc2 = new ModuleWavetableOsc(); 25 | // osc2->wavetable_input = new ModuleConstant(6); 26 | // osc2->frequency_input = inputs->sr; 27 | // 28 | // ModuleWavetableOsc *osc3 = new ModuleWavetableOsc(); 29 | // osc3->wavetable_input = inputs->mod; 30 | // osc3->frequency_input = inputs->param1; 31 | // 32 | // ModuleSwitch *switchAB = new ModuleSwitch(); 33 | // switchAB->a_input = osc1; 34 | // switchAB->b_input = osc2; 35 | // switchAB->select_input = osc3; 36 | // 37 | // this->last_module = switchAB; 38 | 39 | 40 | #ifndef ModuleSwitch_h 41 | #define ModuleSwitch_h 42 | 43 | #include "Module.h" 44 | 45 | class ModuleSwitch : public Module 46 | { 47 | public: 48 | uint16_t compute(); 49 | 50 | // Inputs 51 | Module *select_input; 52 | Module *a_input; 53 | Module *b_input; 54 | }; 55 | 56 | #endif -------------------------------------------------------------------------------- /ModuleVCA.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleVCA.h" 2 | #include "defines.h" 3 | 4 | ModuleVCA::ModuleVCA() 5 | { 6 | this->audio_input = NULL; 7 | this->cv_input = NULL; 8 | } 9 | 10 | uint16_t ModuleVCA::compute() 11 | { 12 | // Read inputs 13 | uint32_t audio = this->readInput(audio_input); 14 | uint32_t cv = this->readInput(cv_input) ; 15 | 16 | return((audio * cv) >> 12 ); 17 | } 18 | -------------------------------------------------------------------------------- /ModuleVCA.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleVCA | 4 | * |----------------------| 5 | * > audio_input | 6 | * > cv_input | 7 | * | output > 8 | * +----------------------+ 9 | */ 10 | // ============================================================================= 11 | // 12 | // ModuleVCA is an audio amplifier. The volume of the output is controlled via 13 | // the cv_input. See http://synthesizeracademy.com/voltage-controlled-amplifier-vca/ 14 | // 15 | // Example usage: 16 | // 17 | // ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 18 | // ModuleVCA *vca = new ModuleVCA(); 19 | // ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 20 | // 21 | // // Patch up ocillator 22 | // osc->frequency_input = inputs->sr; 23 | // osc->wavetable_input = inputs->mod; 24 | // 25 | // // Patch up lowpass filter 26 | // lowpass_filter->audio_input = osc; 27 | // lowpass_filter->cutoff_input = inputs->param1; 28 | // lowpass_filter->resonance_input = inputs->param2; 29 | // 30 | // // Patch up VCA 31 | // vca->cv_input = inputs->param3; 32 | // vca->audio_input = lowpass_filter; 33 | // 34 | // this->last_module = vca; 35 | 36 | #ifndef ModuleVCA_h 37 | #define ModuleVCA_h 38 | 39 | #include "Module.h" 40 | 41 | class ModuleVCA : public Module 42 | { 43 | public: 44 | ModuleVCA(); 45 | uint16_t compute(); 46 | 47 | // Inputs 48 | Module *audio_input; 49 | Module *cv_input; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /ModuleWaveFolder.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuleWaveFolder.h" 2 | #include "defines.h" 3 | 4 | ModuleWaveFolder::ModuleWaveFolder() 5 | { 6 | this->audio_input = NULL; 7 | this->lower_clipping_level_input = NULL; 8 | this->upper_clipping_level_input = NULL; 9 | } 10 | 11 | uint16_t ModuleWaveFolder::compute() 12 | { 13 | // Read inputs 14 | uint16_t audio = this->readInput(this->audio_input); 15 | uint16_t lower_clipping_level = this->readInput(this->lower_clipping_level_input, 0, 1792); 16 | uint16_t upper_clipping_level = this->readInput(this->upper_clipping_level_input, 4095, 2304); 17 | 18 | // Allow up to 4 folds 19 | for(int i=0; i<4; i++) 20 | { 21 | if(audio > upper_clipping_level) 22 | { 23 | audio = upper_clipping_level - (audio - upper_clipping_level); 24 | } 25 | 26 | if(audio < lower_clipping_level) 27 | { 28 | audio = lower_clipping_level + (lower_clipping_level - audio); 29 | } 30 | } 31 | 32 | // Clip any remaining audio that doesn't fit withing the clipping range 33 | if(audio > upper_clipping_level) audio = upper_clipping_level; 34 | if(audio < lower_clipping_level) audio = lower_clipping_level; 35 | 36 | // Adjust gain based on clipping levels 37 | float gain = 4095.0 / (float)(upper_clipping_level - lower_clipping_level); 38 | 39 | return((audio - lower_clipping_level) * gain); 40 | } 41 | -------------------------------------------------------------------------------- /ModuleWaveshaper.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "defines.h" 3 | #include "ModuleWaveshaper.h" 4 | #include "GlobalWaveshaperTables.h" 5 | 6 | ModuleWaveshaper::ModuleWaveshaper() 7 | { 8 | // Initialize all inputs 9 | this->audio_input = NULL; 10 | this->mix_input = NULL; 11 | this->waveshaper_input = NULL; 12 | } 13 | 14 | uint16_t ModuleWaveshaper::compute() 15 | { 16 | // Read inputs 17 | uint16_t audio = this->readInput(audio_input); 18 | uint16_t waveshaper = this->readInput(waveshaper_input,0,4); 19 | uint16_t wet_mix = this->readInput(mix_input); 20 | 21 | uint16_t dry_mix = 4095 - wet_mix; 22 | 23 | uint16_t shaped_output = WAVE_SHAPER_TABLES[waveshaper][audio]; 24 | 25 | if(wet_mix == 0) 26 | { 27 | return(audio); 28 | } 29 | else 30 | { 31 | return(((shaped_output * wet_mix) >> 12) + ((audio * dry_mix) >> 12)); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /ModuleWaveshaper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleWaveshaper | 4 | * |----------------------| 5 | * > audio_input | 6 | * | | 7 | * | output > 8 | * +----------------------+ 9 | 10 | !!!!!!! This module doesn't work at all yet !!!!!!!!!!!!!!! 11 | 12 | */ 13 | 14 | 15 | #ifndef ModuleWaveshaper_h 16 | #define ModuleWaveshaper_h 17 | 18 | #include "Module.h" 19 | 20 | class ModuleWaveshaper : public Module 21 | { 22 | 23 | public: 24 | 25 | // Methods 26 | ModuleWaveshaper(); 27 | uint16_t compute(); 28 | 29 | // Inputs 30 | Module *audio_input; 31 | Module *mix_input; 32 | Module *waveshaper_input; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /ModuleWavetableOsc.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleWavetableOsc.h" 3 | #include "defines.h" 4 | #include "GlobalWavetables.h" 5 | #include "GlobalIncrements.h" 6 | 7 | ModuleWavetableOsc::ModuleWavetableOsc() 8 | { 9 | fixed_point_10_22_index = 0; 10 | 11 | // Initialize all inputs 12 | this->frequency_input = NULL; 13 | this->wavetable_input = NULL; 14 | } 15 | 16 | uint16_t ModuleWavetableOsc::compute() 17 | { 18 | // Read the frequency 19 | frequency = this->readInput(frequency_input); 20 | 21 | // Read the wavetable input and map it to the appropriate range 22 | wavetable = this->readInput(wavetable_input, 0, NUMBER_OF_WAVETABLES); 23 | 24 | // Calculate the index into the wavetable 25 | fixed_point_10_22_index += INCREMENTS[frequency]; 26 | if(fixed_point_10_22_index > WAVE_SAMPLES_SHIFTED_22) fixed_point_10_22_index -= WAVE_SAMPLES_SHIFTED_22; 27 | 28 | wavetable_index = fixed_point_10_22_index >> 22; // This should yeald a value between 0 and WAVE_SAMPLES (512) 29 | 30 | // This output will range from 0 to 4080 (which is a 12-bit value) 31 | return(WAVETABLES[wavetable][wavetable_index] << 4); 32 | } 33 | -------------------------------------------------------------------------------- /ModuleWavetableOsc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleWavetableOsc | 4 | * |----------------------| 5 | * > frequency_input | 6 | * > wavetable_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleWavetableOsc is a wavetable oscillator with control over frequency and 14 | // wavetable. The wavetables are defined in GlobalWavetables.cpp. 15 | // 16 | // Example usage: 17 | // 18 | // ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 19 | // wavetable_osc->frequency_input = inputs->sr_input; 20 | // wavetable_osc->wavetable_input = inputs->mod_input; 21 | // this->last_module = wavetable_osc; 22 | // 23 | // Also see: SynthWavetable.cpp and SynthChords.cpp 24 | 25 | #ifndef ModuleWavetableOsc_h 26 | #define ModuleWavetableOsc_h 27 | 28 | #include "Arduino.h" 29 | #include "Module.h" 30 | #include "ModuleOutput.h" 31 | 32 | class ModuleWavetableOsc : public Module 33 | { 34 | 35 | public: 36 | ModuleWavetableOsc(); 37 | uint16_t compute(); 38 | 39 | // Inputs 40 | Module *frequency_input; // Input module for controlling frequency 41 | Module *wavetable_input; // Input module for controlling wavetable selection 42 | 43 | private: 44 | uint32_t wavetable_index; // An index into the wavetables array 45 | uint8_t wavetable; // Which wavetable is currently selected 46 | uint16_t frequency; // An index into the increments table 47 | 48 | // 10.22 fixed point number (using the upper 10 bits for addressing the indexes 49 | // up to 1024 (we only need 600), and an additional 22 bits (0-4194304) for simulating fractional values for 50 | // use when incrementing the variable fractional values 51 | uint32_t fixed_point_10_22_index; 52 | uint32_t increment_by; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /Modules.h: -------------------------------------------------------------------------------- 1 | // Each module in the Equation Composer should be included here. 2 | // This file is included in Synths.h 3 | 4 | #include "Module.h" 5 | #include "ModuleOutput.h" 6 | 7 | #include "ModuleAdd.h" 8 | #include "ModuleArpeggio.h" 9 | #include "ModuleBitReducer.h" 10 | #include "ModuleChords.h" 11 | #include "ModuleClock.h" 12 | #include "ModuleClockedRandom.h" 13 | #include "ModuleClockDivider.h" 14 | #include "ModuleConstant.h" 15 | #include "ModuleCounter.h" 16 | #include "ModuleDelay.h" 17 | #include "ModuleDrumSequencer.h" 18 | #include "ModuleDrumSequencer32.h" 19 | #include "ModuleENV.h" 20 | #include "ModuleEqDrum.h" 21 | #include "ModuleEquationLooper.h" 22 | #include "ModuleEquationPlayer.h" 23 | #include "ModuleExtClock.h" 24 | #include "ModuleFreeze.h" 25 | #include "ModuleKitSelect.h" 26 | #include "ModuleLFO.h" 27 | #include "ModuleLooper.h" 28 | #include "ModuleLowpassFilter.h" 29 | #include "ModuleMap.h" 30 | #include "ModuleMixer2.h" 31 | #include "ModuleMixer3.h" 32 | #include "ModuleMultiply.h" 33 | #include "ModuleOscParam.h" 34 | #include "ModulePatternGenerator.h" 35 | #include "ModuleQuantizer.h" 36 | #include "ModuleRotatingRouter3.h" 37 | #include "ModuleSampleAndHold.h" 38 | #include "ModuleSamplePlayer.h" 39 | #include "ModuleSequencer.h" 40 | #include "ModuleSmooth.h" 41 | #include "ModuleSpeechSound.h" 42 | #include "ModuleSwitch.h" 43 | #include "ModuleVCA.h" 44 | #include "ModuleWaveFolder.h" 45 | #include "ModuleWavetableOsc.h" 46 | #include "ModuleWaveshaper.h" -------------------------------------------------------------------------------- /Rand.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Rand.h" 3 | 4 | Rand::Rand() 5 | { 6 | x = 132456789; 7 | y = 362436069; 8 | z = 521288629; 9 | } 10 | 11 | uint32_t Rand::xorshift96() 12 | { 13 | 14 | uint32_t t; 15 | 16 | x ^= x << 16; 17 | x ^= x >> 5; 18 | x ^= x << 1; 19 | 20 | t = x; 21 | x = y; 22 | y = z; 23 | z = t ^ x ^ y; 24 | 25 | return z; 26 | } 27 | 28 | void Rand::seed(uint32_t seed) 29 | { 30 | x = seed; 31 | y = 362436069; 32 | z = 521288629; 33 | } 34 | 35 | uint32_t Rand::random(uint32_t min, uint32_t max) 36 | { 37 | return (uint32_t) ((((xorshift96() & 0xFFFF) * (max-min))>>16) + min); 38 | } 39 | 40 | // Return a random number between 0 and max-1, inclusive 41 | uint32_t Rand::random(uint32_t max) 42 | { 43 | return (uint32_t) (((xorshift96() & 0xFFFF) * max)>>16); 44 | } 45 | 46 | // Return a random number between 0 and 4095, inclusive 47 | uint32_t Rand::random() 48 | { 49 | // Version #1: return (uint32_t) (((xorshift96() & 0xFFFF) * 4096)>>16); 50 | // Version #2: return (uint32_t) (((xorshift96() & 0xFFFF)<<12)>>16); 51 | 52 | // Version #3: 53 | return (uint32_t) ((xorshift96() & 0xFFFF)>>4); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Rand.h: -------------------------------------------------------------------------------- 1 | #ifndef Rand_h 2 | #define Rand_h 3 | 4 | // 5 | // Based on the Mozzy (http://sensorium.github.io/Mozzi/) random number code, which in 6 | // turn is based on George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf 7 | // 8 | 9 | class Rand 10 | { 11 | public: 12 | Rand(); 13 | 14 | uint32_t xorshift96(); 15 | void seed(uint32_t seed); 16 | uint32_t random(uint32_t min, uint32_t max); 17 | uint32_t random(uint32_t max); 18 | uint32_t random(); 19 | 20 | private: 21 | unsigned long x,y,z; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /Synth.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "Synth.h" 4 | 5 | uint16_t Synth::run(uint8_t cycle) 6 | { 7 | return(this->last_module->run(cycle)); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /Synth.h: -------------------------------------------------------------------------------- 1 | #ifndef Synth_h 2 | #define Synth_h 3 | 4 | #include "Arduino.h" 5 | #include "Inputs.h" 6 | #include "Modules.h" 7 | 8 | class Synth 9 | { 10 | public: 11 | 12 | // Methods 13 | uint16_t run(uint8_t cycle); 14 | 15 | 16 | // 'last_module' is the last module in the synth. 17 | // This module's run() method will be called by the synth. 18 | Module *last_module; 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Synth3Osc.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Defines.h" 3 | #include "Synth3Osc.h" 4 | 5 | Synth3Osc::Synth3Osc(Inputs* inputs) 6 | { 7 | ModuleOscParam *osc_param = new ModuleOscParam(); 8 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 9 | ModuleWavetableOsc *osc1 = new ModuleWavetableOsc(); 10 | ModuleWavetableOsc *osc2 = new ModuleWavetableOsc(); 11 | ModuleWavetableOsc *osc3 = new ModuleWavetableOsc(); 12 | ModuleVCA *vca1 = new ModuleVCA(); 13 | ModuleVCA *vca2 = new ModuleVCA(); 14 | ModuleVCA *vca3 = new ModuleVCA(); 15 | ModuleMixer3 *mixer = new ModuleMixer3(); 16 | 17 | osc_param->waveform_input = inputs->mod; 18 | osc_param->pitch_input = inputs->sr; 19 | osc_param->fine_input = inputs->param1; 20 | 21 | osc1->wavetable_input = osc_param->osc1_waveform; 22 | osc2->wavetable_input = osc_param->osc2_waveform; 23 | osc3->wavetable_input = osc_param->osc3_waveform; 24 | 25 | osc1->frequency_input = osc_param->osc1_pitch; 26 | osc2->frequency_input = osc_param->osc2_pitch; 27 | osc3->frequency_input = osc_param->osc3_pitch; 28 | 29 | vca1->audio_input = osc1; 30 | vca2->audio_input = osc2; 31 | vca3->audio_input = osc3; 32 | vca1->cv_input = osc_param->vca1_volume; 33 | vca2->cv_input = osc_param->vca2_volume; 34 | vca3->cv_input = osc_param->vca3_volume; 35 | 36 | mixer->input_1 = vca1; 37 | mixer->input_2 = vca2; 38 | mixer->input_3 = vca3; 39 | 40 | // Patch up lowpass filter 41 | lowpass_filter->audio_input = mixer; 42 | lowpass_filter->cutoff_input = inputs->param2; 43 | lowpass_filter->resonance_input = inputs->param3; 44 | 45 | this->last_module = lowpass_filter; 46 | } 47 | -------------------------------------------------------------------------------- /Synth3Osc.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: Synth3Osc 4 | // Type: Audio 5 | // Written by: Gaetan Ro, 2014 6 | // 7 | // Description: Synth3Osc is a 3 osc synth with 2 main oscillators which can be 8 | // detuned a sub oscillator, and a low-pass filter. 9 | // 10 | // The MOD input controls the oscillator configuration. There are 16 configurations. 11 | // For example, the first 4 configurations are: 12 | // 13 | // MOD osc1 osc2 sub osc 14 | // ---------------------------------------- 15 | // 0 sine sine sine (50% vol) 16 | // 1 sine sawtooth sine (50% vol) 17 | // 2 sawtooth sawtooth sine (50% vol) 18 | // 3 sawtooth square sine (50% vol) 19 | // 20 | // Param1 is the detuning between the first 2 oscillators. In the middle of the 21 | // potentiometer there is no detune, in the far right, the second oscillator is 22 | // a quarter tone higher, and far left is a quarter tone lower. 23 | // 24 | // Param2 is the cutoff for the lowpass filter 25 | // 26 | // Param3 is the resonance for the lowpass filter 27 | // 28 | // Input summary: 29 | // 30 | // SR - Sample Rate (pitch) 31 | // MOD - Selects the oscillator configuraton 32 | // [1] - Detune 33 | // [2] - Lowpass Cutoff 34 | // [3] - Lowpass Resonance 35 | // GATE - Not used 36 | // 37 | // ============================================================================= 38 | 39 | #ifndef Synth3Osc_h 40 | #define Synth3Osc_h 41 | 42 | #include "Arduino.h" 43 | #include "Synth.h" 44 | 45 | class Synth3Osc : public Synth 46 | { 47 | public: 48 | 49 | Synth3Osc(Inputs* inputs); 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /SynthArpeggio1.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "SynthArpeggio1.h" 4 | 5 | SynthArpeggio1::SynthArpeggio1(Inputs* inputs) 6 | { 7 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 8 | ModuleVCA *vca = new ModuleVCA(); 9 | ModuleArpeggio *arpeggio = new ModuleArpeggio(); 10 | ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 11 | ModuleENV *env = new ModuleENV(); 12 | ModuleDelay *delay = new ModuleDelay(); 13 | 14 | // The ext_clock input will use the gate input if there is 15 | // one, otherwise default to an internal 120 BPM clock. 16 | ext_clock->clock_input = inputs->gate; 17 | 18 | arpeggio->clock_input = ext_clock; 19 | arpeggio->root_note_input = inputs->sr; 20 | arpeggio->pattern_input = inputs->param1; 21 | 22 | // Patch up ocillator 23 | osc->frequency_input = arpeggio; 24 | osc->wavetable_input = inputs->mod; 25 | 26 | // Envelope for VCA 27 | env->trigger_input = ext_clock; 28 | env->frequency_input = inputs->param2; 29 | env->slope_input = new ModuleConstant(2); 30 | 31 | // Patch up VCA 32 | vca->cv_input = env->output; 33 | vca->audio_input = osc; 34 | 35 | // Patch delay 36 | delay->audio_input = vca; 37 | delay->mix_input = inputs->param3; 38 | delay->feedback_input = new ModuleConstant(2048); 39 | delay->length_input = inputs->param1; 40 | 41 | this->last_module = delay; 42 | } 43 | -------------------------------------------------------------------------------- /SynthArpeggio1.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthArpeggio1 4 | // Type: Audio 5 | // Written by: Gaétan ROELENS, 2014 6 | // 7 | // Description: 8 | // 9 | // SR - Root note 10 | // MOD - Wavetable 11 | // [1] - Arpeggiation pattern 12 | // [2] - VCA decay time 13 | // [3] - Delay mix 14 | // GATE - (optional) Clocks the arpeggiator and triggers the envelope generator 15 | // that feeds the VCA 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthArpeggio1_h 20 | #define SynthArpeggio1_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthArpeggio1 : public Synth 25 | { 26 | public: 27 | SynthArpeggio1(Inputs *inputs); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /SynthAutoDrum.cpp: -------------------------------------------------------------------------------- 1 | #include "defines.h" 2 | #include "SynthAutoDrum.h" 3 | 4 | SynthAutoDrum::SynthAutoDrum(Inputs* inputs) 5 | { 6 | ModuleClock *clock = new ModuleClock(90, QUARTER_NOTE_CLOCK_DIVISION); 7 | ModuleDrumSequencer *drum_sequencer = new ModuleDrumSequencer(); 8 | 9 | drum_sequencer->clock_input = clock; 10 | drum_sequencer->kick_pattern_input = inputs->param1->smooth; 11 | drum_sequencer->snare_pattern_input = inputs->param2->smooth; 12 | drum_sequencer->hihat_pattern_input = inputs->param3->smooth; 13 | 14 | ModuleEqDrum *kick = new ModuleEqDrum(); 15 | kick->trigger_input = drum_sequencer->kick_output; 16 | kick->sample_rate_input = inputs->sr; 17 | kick->drum_selection_input = new ModuleConstant(0); 18 | 19 | ModuleEqDrum *snare = new ModuleEqDrum(); 20 | snare->trigger_input = drum_sequencer->snare_output; 21 | snare->sample_rate_input = inputs->sr; 22 | snare->drum_selection_input = new ModuleConstant(3); 23 | 24 | ModuleEqDrum *hihat = new ModuleEqDrum(); 25 | hihat->trigger_input = drum_sequencer->hihat_output; 26 | hihat->sample_rate_input = inputs->sr; 27 | hihat->drum_selection_input = new ModuleConstant(6); 28 | 29 | ModuleMixer3 *mixer = new ModuleMixer3(); 30 | mixer->input_1 = kick; 31 | mixer->input_2 = snare; 32 | mixer->input_3 = hihat; 33 | 34 | this->last_module = mixer; 35 | } 36 | -------------------------------------------------------------------------------- /SynthAutoDrum.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthAutoDrum_h 2 | #define SynthAutoDrum_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthAutoDrum : public Synth 7 | { 8 | public: 9 | SynthAutoDrum(Inputs *inputs); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /SynthChords.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthChords 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: A wavetable based chord generator. See GlobalChords.php 8 | // for a list of included chords. 9 | // 10 | // SR - Base note of the chord 11 | // MOD - Chord selection 12 | // [1] - Scale Selection 13 | // [2] - Wavetable #2 selection 14 | // [3] - Wavetable #3 selection 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthChords_h 20 | #define SynthChords_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthChords : public Synth 25 | { 26 | public: 27 | SynthChords(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthClickers.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthClickers.h" 2 | 3 | SynthClickers::SynthClickers(Inputs* inputs) 4 | { 5 | 6 | ModuleExtClock *ext_clock = new ModuleExtClock(120); 7 | ModuleClockDivider *clock_divider = new ModuleClockDivider(); 8 | ModuleLFO *lfo = new ModuleLFO(); 9 | ModuleEqDrum *drum_sound = new ModuleEqDrum(); 10 | ModuleMap *map_0_24 = new ModuleMap(0,24); 11 | ModuleMap *map_0_8 = new ModuleMap(0,8); 12 | ModuleAdd *add = new ModuleAdd(); 13 | 14 | ext_clock->clock_input = inputs->gate; 15 | 16 | // Read parameter 3 and scale it between 0 - 5 17 | map_0_8->input = inputs->param3; 18 | 19 | // Generate an LFO and scale the output to 0 - 24 20 | lfo->frequency_input = inputs->param1; 21 | lfo->wavetable_input = inputs->param2; 22 | map_0_24->input = lfo; 23 | 24 | // Add the scaled LFO value to the scaled param3 value 25 | add->input_1 = map_0_24; 26 | add->input_2 = map_0_8; 27 | 28 | // Feed a clock and the LFO + Param3 into the clock divider 29 | clock_divider->clock_input = ext_clock; 30 | clock_divider->division_input = add; 31 | 32 | // Trigger the drums 33 | drum_sound->drum_selection_input = inputs->mod; 34 | drum_sound->sample_rate_input = inputs->sr; 35 | drum_sound->trigger_input = clock_divider; 36 | 37 | this->last_module = drum_sound; 38 | 39 | } -------------------------------------------------------------------------------- /SynthClickers.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthClickers 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: LFO driven clock divider fed into a drum player. The output 8 | // sounds a bit like a bouncing ball. 9 | // 10 | // SR - sample rate of the drum sound 11 | // MOD - drum selection input 12 | // [1] - LFO frequency 13 | // [2] - LFO wavetable 14 | // [3] - Minimum gate density 15 | // GATE - (optional) supplies clock signal to the clock divider 16 | // 17 | // ============================================================================= 18 | 19 | 20 | #ifndef SynthClickers_h 21 | #define SynthClickers_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthClickers : public Synth 26 | { 27 | public: 28 | SynthClickers(Inputs *inputs); 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /SynthDrumPlayer.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthDrumPlayer 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Plays sequenced drum patterns using three different drum 8 | // sequencers driving three equation based drum sounds. 9 | // The parameter [1], [2], and [3] inputs select the drum pattern. 10 | // 11 | // 12 | // SR - controls the sample rate of the equation playback 13 | // MOD - not used 14 | // [1] - selects the pattern used for the kick drum's sequencer 15 | // [2] - selects the pattern used for the snare drum's sequencer 16 | // [3] - selects the pattern used for the hihat's sequencer 17 | // GATE - steps each of the drum sequencers 18 | // 19 | // ============================================================================= 20 | 21 | #ifndef SynthDrumPlayer_h 22 | #define SynthDrumPlayer_h 23 | 24 | #include "Synth.h" 25 | 26 | class SynthDrumPlayer : public Synth 27 | { 28 | public: 29 | SynthDrumPlayer(Inputs *inputs); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /SynthDrumSelektor.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthDrumSelektor.h" 2 | 3 | SynthDrumSelektor::SynthDrumSelektor(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleEqDrum *drum_sound = new ModuleEqDrum(); 7 | ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 8 | ModuleFreeze *freeze = new ModuleFreeze(); 9 | ModuleWaveFolder *wave_folder = new ModuleWaveFolder(); 10 | 11 | // Allow the GATE input to override the internal clock 12 | ext_clock->clock_input = inputs->gate; 13 | 14 | // Wire up the drum player. Trigger the drum player 15 | // with either the internal or external clock 16 | drum_sound->sample_rate_input = inputs->sr; 17 | drum_sound->drum_selection_input = inputs->mod; 18 | drum_sound->trigger_input = ext_clock; 19 | 20 | // Send the drum sounds through a freeze effect 21 | freeze->audio_input = drum_sound; 22 | freeze->length_input = inputs->param1; 23 | 24 | // Apply wave folding 25 | wave_folder->audio_input = freeze; 26 | wave_folder->lower_clipping_level_input = inputs->param2; 27 | wave_folder->upper_clipping_level_input = inputs->param2; 28 | 29 | // Output the audio of the wave folder 30 | this->last_module = wave_folder; 31 | } -------------------------------------------------------------------------------- /SynthDrumSelektor.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthDrumSelektor 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: CV selectable drum pattern player simliar to the Analogue 8 | // Solution SP-8, but using equation generated drum sounds. 9 | // 10 | // SR - Controls sample rate of drum sound 11 | // MOD - CV selection of drum sound 12 | // [1] - Freeze trigger input 13 | // [2] - Freeze length input 14 | // [3] - Controls wave folding level 15 | // GATE - Triggers drum sound 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthDrumSelektor_h 20 | #define SynthDrumSelektor_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthDrumSelektor : public Synth 25 | { 26 | public: 27 | SynthDrumSelektor(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthEquationLooper.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthEquationLooper.h" 2 | 3 | SynthEquationLooper::SynthEquationLooper(Inputs *inputs, EquationBank *equation_bank) 4 | { 5 | ModuleEquationLooper *equation_looper = new ModuleEquationLooper(equation_bank); 6 | 7 | equation_looper->equation_input = inputs->mod->smooth; 8 | equation_looper->sample_rate_input = inputs->sr; 9 | equation_looper->loop_start_input = inputs->param1->smooth; 10 | equation_looper->loop_length_input = inputs->param2->smooth; 11 | equation_looper->param3_input = inputs->param3->smooth; 12 | equation_looper->gate_input = inputs->gate; 13 | 14 | this->last_module = equation_looper; 15 | } 16 | -------------------------------------------------------------------------------- /SynthEquationLooper.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthEquationLooper 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Plays 'bytebeat' equations as audio. This synth offers less 8 | // control over the equation parameters, but allows you to control 9 | // playback_position and loop_length 10 | // 11 | // SR - controls the sample rate of the equation playback 12 | // MOD - selects equation to playback 13 | // [1] - controls the loop playback position 14 | // [2] - controls the loop length 15 | // [3] - modifies the equation parameter p1, which variates the sound 16 | // GATE - disables looping (meaning, the equation will playback continuously) 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthEquationLooper_h 21 | #define SynthEquationLooper_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthEquationLooper : public Synth 26 | { 27 | public: 28 | SynthEquationLooper(Inputs *inputs, EquationBank *equation_bank); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /SynthEquationPlayer.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthEquationPlayer.h" 2 | 3 | SynthEquationPlayer::SynthEquationPlayer(Inputs *inputs, EquationBank *equation_bank) 4 | { 5 | ModuleEquationPlayer *equation_player = new ModuleEquationPlayer(equation_bank); 6 | 7 | equation_player->equation_input = inputs->mod->smooth; 8 | equation_player->sample_rate_input = inputs->sr->smooth; 9 | equation_player->param1_input = inputs->param1->smooth; 10 | equation_player->param2_input = inputs->param2->smooth; 11 | equation_player->param3_input = inputs->param3->smooth; 12 | equation_player->reset_input = inputs->gate; 13 | 14 | this->last_module = equation_player; 15 | } 16 | -------------------------------------------------------------------------------- /SynthEquationPlayer.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthEquationPlayer 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Plays 'bytebeat' equations as audio. Three parameters of each 8 | // equation can be tweaked to variate the output. 9 | // 10 | // SR - controls the sample rate of the equation playback 11 | // MOD - selects equation to playback 12 | // [1] - modifies the equation parameter p1 13 | // [2] - modifies the equation parameter p2 14 | // [3] - modifies the equation parameter p3 15 | // GATE - resets the playback position 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthEquationPlayer_h 20 | #define SynthEquationPlayer_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthEquationPlayer : public Synth 25 | { 26 | public: 27 | SynthEquationPlayer(Inputs *inputs, EquationBank *equation_bank); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /SynthLooper.cpp: -------------------------------------------------------------------------------- 1 | #include "defines.h" 2 | #include "SynthLooper.h" 3 | 4 | SynthLooper::SynthLooper(Inputs* inputs) 5 | { 6 | ModuleLooper *looper = new ModuleLooper(); 7 | ModuleFreeze *freeze = new ModuleFreeze(); 8 | ModuleWaveFolder *wave_folder = new ModuleWaveFolder(); 9 | 10 | // Wire up looper inputs 11 | looper->sample_input = inputs->mod; 12 | looper->sample_rate_input = inputs->sr; 13 | looper->slice_input = inputs->param3; 14 | looper->trigger_input = inputs->gate; 15 | 16 | // Send the looper through a freeze effect 17 | freeze->audio_input = looper; 18 | freeze->length_input = inputs->param1; 19 | 20 | // Wire the output of the freeze effect into a wave folder 21 | wave_folder->audio_input = freeze; 22 | wave_folder->lower_clipping_level_input = inputs->param2; 23 | wave_folder->upper_clipping_level_input = inputs->param2; 24 | 25 | this->last_module = wave_folder; 26 | } -------------------------------------------------------------------------------- /SynthLooper.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthLooper 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // 8 | // ============================================================================= 9 | 10 | #ifndef SynthLooper_h 11 | #define SynthLooper_h 12 | 13 | #include "Synth.h" 14 | 15 | class SynthLooper : public Synth 16 | { 17 | public: 18 | SynthLooper(Inputs *inputs); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /SynthMini.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "SynthMini.h" 4 | 5 | SynthMini::SynthMini(Inputs* inputs) 6 | { 7 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 8 | ModuleVCA *vca = new ModuleVCA(); 9 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 10 | 11 | // Patch up ocillator 12 | osc->frequency_input = inputs->sr; 13 | osc->wavetable_input = inputs->mod; 14 | 15 | // Patch up lowpass filter 16 | lowpass_filter->audio_input = osc; 17 | lowpass_filter->cutoff_input = inputs->param1; 18 | lowpass_filter->resonance_input = inputs->param2; 19 | 20 | // Patch up VCA 21 | vca->cv_input = inputs->param3; 22 | vca->audio_input = lowpass_filter; 23 | 24 | this->last_module = vca; 25 | } -------------------------------------------------------------------------------- /SynthMini.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthMini 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Simple wavetable mini single voice synth. External control over 8 | // wavetable selection, sample rate, low-pass filter cutoff and resonance, 9 | // and amplitude. 10 | // 11 | // SR - sample rate 12 | // MOD - wavetable selecation 13 | // [1] - Lowpass Filter cutoff 14 | // [2] - Lowpass Filter resonance 15 | // [3] - Amplitude 16 | // GATE - not used 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthMini_h 21 | #define SynthMini_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthMini : public Synth 26 | { 27 | public: 28 | SynthMini(Inputs *inputs); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /SynthMumbler.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "Defines.h" 3 | #include "SynthMumbler.h" 4 | 5 | SynthMumbler::SynthMumbler(Inputs* inputs) 6 | { 7 | ModuleSpeechSound *speech_sound = new ModuleSpeechSound(); 8 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 9 | ModuleRotatingRouter3 *rotating_router_3 = new ModuleRotatingRouter3(); 10 | 11 | speech_sound->formant_scale_input = inputs->mod; 12 | 13 | rotating_router_3->rotate_input = inputs->gate; 14 | rotating_router_3->input_1 = inputs->param1; 15 | rotating_router_3->input_2 = new ModuleConstant(1000); 16 | rotating_router_3->input_3 = new ModuleConstant(15); 17 | 18 | speech_sound->phase1_input = rotating_router_3->output_1; 19 | speech_sound->phase2_input = rotating_router_3->output_2; 20 | speech_sound->phase3_input = rotating_router_3->output_3; 21 | 22 | speech_sound->pitch_input = inputs->sr; 23 | 24 | // Patch up lowpass filter 25 | lowpass_filter->audio_input = speech_sound; 26 | lowpass_filter->cutoff_input = inputs->param3; 27 | lowpass_filter->resonance_input = inputs->param2; 28 | 29 | this->last_module = lowpass_filter; 30 | } 31 | -------------------------------------------------------------------------------- /SynthMumbler.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthMumbler 4 | // Type: Audio 5 | // Written by: Gaetan Ro, 2014 6 | // 7 | // Description: Mumbler is a Formant Synthesizer with a built-in lowpass filter 8 | // that makes sounds similar to vowel sounds. 9 | // 10 | // SR - Sample Rate (pitch) 11 | // MOD - Formant scale input 12 | // [1] - Phase input 13 | // [2] - Lowpass Filter Resonance input 14 | // [3] - Lowpass Filter Cutoff Input 15 | // GATE - Not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthMumbler_h 20 | #define SynthMumbler_h 21 | 22 | #include "Arduino.h" 23 | #include "Synth.h" 24 | 25 | class SynthMumbler : public Synth 26 | { 27 | public: 28 | 29 | SynthMumbler(Inputs* inputs); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /SynthPatterns.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthPatterns 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: 8 | // 9 | // SR - delay effects mix 10 | // MOD - wavetable selecation 11 | // [1] - CV Pattern Select 12 | // [2] - Gate Pattern Select 13 | // [3] - Gate Density 14 | // GATE - (optional) clock control 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthPatterns_h 19 | #define SynthPatterns_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthPatterns : public Synth 24 | { 25 | public: 26 | SynthPatterns(Inputs *inputs); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /SynthTutorial1.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial1.h" 2 | 3 | // Note: 4 | // A description, including input assignments, can be found in 5 | // the tutorial's .h file. In this case, SynthTutorial1.h. 6 | 7 | SynthTutorial1::SynthTutorial1(Inputs* inputs) 8 | { 9 | // Create a wavetable oscillator 10 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 11 | 12 | // Select the second wavetable (0=first, 1=second, 2=third, etc..) 13 | wavetable_osc->wavetable_input = new ModuleConstant(1); 14 | 15 | // If you instead wanted to control the wavetable selection 16 | // using the mod input, the code would look like: 17 | // 18 | // wavetable_osc->wavetable_input = inputs->mod; 19 | // 20 | 21 | // Control the frequency using the SR input 22 | wavetable_osc->frequency_input = inputs->sr; 23 | 24 | // Output the value of the wavetable oscillator 25 | this->last_module = wavetable_osc; 26 | } -------------------------------------------------------------------------------- /SynthTutorial1.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial1 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Simple triangle wave oscillator. The implementation of this 8 | // synth can be seen in SynthTutorial1.cpp. 9 | // 10 | // SR - controls the sample rate of the oscillator 11 | // MOD - not used 12 | // [1] - not used 13 | // [2] - not used 14 | // [3] - not used 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthTutorial1_h 20 | #define SynthTutorial1_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthTutorial1 : public Synth 25 | { 26 | public: 27 | SynthTutorial1(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthTutorial10.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial10.h" 2 | 3 | SynthTutorial10::SynthTutorial10(Inputs* inputs) 4 | { 5 | // Create the modules. There are two different clocked 6 | // random number generators: One for the note selection 7 | // and the other for the wavetable selection 8 | ModuleQuantizer *quantizer = new ModuleQuantizer(); 9 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 10 | ModuleClockedRandom *clocked_random1 = new ModuleClockedRandom(); 11 | ModuleClockedRandom *clocked_random2 = new ModuleClockedRandom(); 12 | ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 13 | 14 | // Either use an external gate or an internal 120BPM clock 15 | ext_clock->clock_input = inputs->gate; 16 | 17 | // Wire the clock to both of the clocked random number generators 18 | clocked_random1->clock_input = ext_clock; 19 | clocked_random2->clock_input = ext_clock; 20 | 21 | // Wire up a quantizer 22 | quantizer->scale_input = inputs->param1; 23 | quantizer->cv_input = clocked_random1; 24 | 25 | // Route the quantizer into the wavetable oscillator 26 | osc->wavetable_input = clocked_random2; 27 | osc->frequency_input = quantizer; 28 | 29 | this->last_module = osc; 30 | } -------------------------------------------------------------------------------- /SynthTutorial10.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial10 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of the clocked random module. Uses two clocked 8 | // random number generators to control the note and wavetable selection of 9 | // a wavetable oscillator. 10 | // 11 | // SR - not used 12 | // MOD - not used 13 | // [1] - scale selection 14 | // [2] - not used 15 | // [3] - not used 16 | // GATE - (optional) clocks the pattern generator 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthTutorial10_h 21 | #define SynthTutorial10_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthTutorial10 : public Synth 26 | { 27 | public: 28 | SynthTutorial10(Inputs *inputs); 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /SynthTutorial11.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial11.h" 2 | 3 | SynthTutorial11::SynthTutorial11(Inputs* inputs) 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /SynthTutorial11.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial11 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Currently blank 8 | // 9 | // SR - 10 | // MOD - 11 | // [1] - 12 | // [2] - 13 | // [3] - 14 | // GATE - 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthTutorial11_h 19 | #define SynthTutorial11_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthTutorial11 : public Synth 24 | { 25 | public: 26 | SynthTutorial11(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthTutorial12.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial12.h" 2 | 3 | SynthTutorial12::SynthTutorial12(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleCounter *counter = new ModuleCounter(5); // count from 0 to 5 7 | ModuleClock *bpm_clock = new ModuleClock(120, EIGHTH_NOTE_CLOCK_DIVISION); // clock at 120BPM 8 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 9 | 10 | // Use the clock to increment the counter 11 | counter->clock_input = bpm_clock; 12 | 13 | // Wire the counter to the wavetable selection 14 | wavetable_osc->wavetable_input = counter; 15 | wavetable_osc->frequency_input = inputs->sr; 16 | 17 | // Output the wavetable oscillator 18 | this->last_module = wavetable_osc; 19 | } -------------------------------------------------------------------------------- /SynthTutorial12.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial12 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of the counter module. The output of a counter 8 | // module is used to step through wavetables in a wavetable oscillator. 9 | // 10 | // SR - controls the sample rate of the wavetable oscillator 11 | // MOD - not used 12 | // [1] - not used 13 | // [2] - not used 14 | // [3] - not used 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthTutorial12_h 20 | #define SynthTutorial12_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthTutorial12 : public Synth 25 | { 26 | public: 27 | SynthTutorial12(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthTutorial13.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial13.h" 2 | 3 | SynthTutorial13::SynthTutorial13(Inputs* inputs) 4 | { 5 | // Create wavetable and bit reducer modules 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleBitReducer *bit_reducer = new ModuleBitReducer(); 8 | 9 | // Control the wavetable selection using MOD 10 | // Control the frequency using SR 11 | wavetable_osc->wavetable_input = inputs->mod; 12 | wavetable_osc->frequency_input = inputs->sr; 13 | 14 | // Bit reduce the output of the wavetable oscillator 15 | // Use param1 to control the bit rate 16 | bit_reducer->audio_input = wavetable_osc; 17 | bit_reducer->bit_input = inputs->param1; 18 | 19 | // Output the audio from the bit reducer 20 | this->last_module = bit_reducer; 21 | } -------------------------------------------------------------------------------- /SynthTutorial13.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial13 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of ModuleBitReducer. A wavetable oscillator's 8 | // output is bit-reduced. 9 | // 10 | // The bit reducer module hasn't turned out to be very useful. I may eventually 11 | // rewrite it to get better "low-fi" effects. 12 | // 13 | // SR - Sample rate of the wavetable oscillator 14 | // MOD - Wavetable selection 15 | // [1] - Bit rate of the bit reducer 16 | // [2] - not used 17 | // [3] - not used 18 | // GATE - not used 19 | // 20 | // ============================================================================= 21 | 22 | #ifndef SynthTutorial13_h 23 | #define SynthTutorial13_h 24 | 25 | #include "Synth.h" 26 | 27 | class SynthTutorial13 : public Synth 28 | { 29 | public: 30 | SynthTutorial13(Inputs *inputs); 31 | }; 32 | 33 | #endif -------------------------------------------------------------------------------- /SynthTutorial14.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial14.h" 2 | 3 | SynthTutorial14::SynthTutorial14(Inputs* inputs) 4 | { 5 | // Crate a wavetable oscillator and a rotating router 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleRotatingRouter3 *rotating_router = new ModuleRotatingRouter3(); 8 | 9 | // Hook up param1, param2, and param3 inputs to the rotating router 10 | // When the router is gated, the outputs will rotate 11 | rotating_router->input_1 = inputs->param1->smooth; 12 | rotating_router->input_2 = inputs->param2->smooth; 13 | rotating_router->input_3 = inputs->param3->smooth; 14 | rotating_router->rotate_input = inputs->gate; 15 | 16 | // Wire the output of the rotating router to the wavetable selection 17 | // input of the wavetable oscillator 18 | wavetable_osc->wavetable_input = rotating_router; 19 | // \_The above line could have also been: 20 | // wavetable_osc->wavetable_input = rotating_router->output_1; 21 | 22 | // Use the SR input to control the frequency 23 | wavetable_osc->frequency_input = inputs->sr; 24 | 25 | // Output the audio from the wavetable oscillator 26 | this->last_module = wavetable_osc; 27 | } -------------------------------------------------------------------------------- /SynthTutorial14.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial14 4 | // Type: CV Output 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of the ModuleRotatingRouter3 8 | // 9 | // SR - Sample rate input 10 | // MOD - not used 11 | // [1] - Wavetable #1 selection 12 | // [2] - Wavetable #2 selection 13 | // [3] - Wavetable #3 selection 14 | // GATE - Rotates the router to cycle through the wavetable selections 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthTutorial14_h 19 | #define SynthTutorial14_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthTutorial14 : public Synth 24 | { 25 | public: 26 | SynthTutorial14(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthTutorial15.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial15.h" 2 | 3 | SynthTutorial15::SynthTutorial15(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleWaveFolder *wave_folder = new ModuleWaveFolder(); 8 | 9 | // Wire up wavetable oscillator 10 | wavetable_osc->wavetable_input = inputs->mod; 11 | wavetable_osc->frequency_input = inputs->sr; 12 | 13 | // Wave fold the output of the wavetable oscillator 14 | wave_folder->audio_input = wavetable_osc; 15 | wave_folder->lower_clipping_level_input = inputs->param1; 16 | wave_folder->upper_clipping_level_input = inputs->param2; 17 | 18 | // Output the audio of the wave folder 19 | this->last_module = wave_folder; 20 | } -------------------------------------------------------------------------------- /SynthTutorial15.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial15 4 | // Type: CV Output 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of ModuleWaveFolder. A wavetable oscillator is 8 | // wired into a wave folder. (see also SynthWavetableFolder.cpp) 9 | // 10 | // SR - Sample rate input 11 | // MOD - Wavetable selection 12 | // [1] - Folding Upper Level 13 | // [2] - Folding Lower Level 14 | // [3] - not used 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthTutorial15_h 20 | #define SynthTutorial15_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthTutorial15 : public Synth 25 | { 26 | public: 27 | SynthTutorial15(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthTutorial16.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial16.h" 2 | 3 | SynthTutorial16::SynthTutorial16(Inputs* inputs) 4 | { 5 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 6 | ModuleWaveshaper *wave_shaper = new ModuleWaveshaper(); 7 | 8 | wavetable_osc->wavetable_input = inputs->mod; 9 | wavetable_osc->frequency_input = inputs->sr; 10 | 11 | wave_shaper->audio_input = wavetable_osc; 12 | wave_shaper->mix_input = inputs->param1; 13 | wave_shaper->waveshaper_input = inputs->param2; 14 | 15 | this->last_module = wave_shaper; 16 | } -------------------------------------------------------------------------------- /SynthTutorial16.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial16 4 | // Written by: Bret Truchan, 2014 5 | // 6 | // Description: Demonstration of ModuleWaveShaper. The waveshaper is still 7 | // experimental. 8 | // 9 | // SR - Sample rate input 10 | // MOD - Wavetable selection 11 | // [1] - Wet/Dry mix for waveshaper 12 | // [2] - not used 13 | // [3] - not used 14 | // GATE - not used 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthTutorial16_h 19 | #define SynthTutorial16_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthTutorial16 : public Synth 24 | { 25 | public: 26 | SynthTutorial16(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthTutorial2.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial2.h" 2 | 3 | SynthTutorial2::SynthTutorial2(Inputs* inputs) 4 | { 5 | // Create a sequence for the sequencer module 6 | int sequence[] = { 0, 100, 2300, 4000, 1400, 500, 70, 4092 }; 7 | 8 | // Create the modules 9 | ModuleSequencer *sequencer = new ModuleSequencer(sequence); 10 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 11 | 12 | // Step the sequencer when the GATE input it triggered 13 | sequencer->clock_input = inputs->gate; 14 | 15 | // Control the wavetable selection using the MOD input 16 | wavetable_osc->wavetable_input = inputs->mod; 17 | 18 | // Control the wavetable frequency using the sequencer's output 19 | wavetable_osc->frequency_input = sequencer; 20 | 21 | // Output the value of the wavetable oscillator 22 | this->last_module = wavetable_osc; 23 | } -------------------------------------------------------------------------------- /SynthTutorial2.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial2 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Sequencer driving a wavetable oscillator 8 | // 9 | // SR - controls the sample rate of the oscillator 10 | // MOD - not used 11 | // [1] - not used 12 | // [2] - not used 13 | // [3] - not used 14 | // GATE - not used 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthTutorial2_h 19 | #define SynthTutorial2_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthTutorial2 : public Synth 24 | { 25 | public: 26 | SynthTutorial2(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthTutorial3.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial3.h" 2 | 3 | SynthTutorial3::SynthTutorial3(Inputs* inputs) 4 | { 5 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 6 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 7 | 8 | // Patch up ocillator 9 | wavetable_osc->frequency_input = inputs->sr; 10 | wavetable_osc->wavetable_input = inputs->mod; 11 | 12 | // Patch up filter 13 | lowpass_filter->audio_input = wavetable_osc; 14 | lowpass_filter->cutoff_input = inputs->param1; 15 | lowpass_filter->resonance_input = inputs->param2; 16 | 17 | this->last_module = lowpass_filter; 18 | } -------------------------------------------------------------------------------- /SynthTutorial3.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial3 4 | // Type: CV Output 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of the lowpass filter. This synth is a simple 8 | // wavetable oscillator with controllable pitch, wavetable, filter cutoff, 9 | // and filter resonance. 10 | // 11 | // SR - Wavetable Oscillator sample rate (aka pitch) 12 | // MOD - Wavetable selection 13 | // [1] - Filter cutoff 14 | // [2] - Filter resonance 15 | // [3] - not used 16 | // GATE - not used 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthTutorial3_h 21 | #define SynthTutorial3_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthTutorial3 : public Synth 26 | { 27 | public: 28 | SynthTutorial3(Inputs *inputs); 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /SynthTutorial4.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial4.h" 2 | 3 | SynthTutorial4::SynthTutorial4(Inputs* inputs) 4 | { 5 | // Create the modules 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 8 | ModuleENV *envelope_generator = new ModuleENV(); 9 | 10 | // Patch up envelope generator 11 | envelope_generator->slope_input = inputs->param1; 12 | envelope_generator->trigger_input = inputs->gate; 13 | envelope_generator->frequency_input = inputs->param2; 14 | 15 | // Patch up oscillator 16 | wavetable_osc->frequency_input = inputs->sr; 17 | wavetable_osc->wavetable_input = inputs->mod; 18 | 19 | // Patch up filter 20 | lowpass_filter->audio_input = wavetable_osc; 21 | lowpass_filter->cutoff_input = envelope_generator; 22 | lowpass_filter->resonance_input = inputs->param3; 23 | 24 | // Output the value of the lowpass filter (the final module in the patch) 25 | this->last_module = lowpass_filter; 26 | } -------------------------------------------------------------------------------- /SynthTutorial4.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial4 4 | // Type: CV Output 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of ModuleENV. A wavetable oscillator is passed 8 | // through a lowpass filter. The filter's cutoff is controlled by the output 9 | // of an envelope generator (ModuleENV). The shape of the envelope is selectable. 10 | // The envelope generator is triggered by the GATE input. 11 | // 12 | // SR - Wavetable Oscillator sample rate (aka pitch) 13 | // MOD - Wavetable selection 14 | // [1] - Slope selection input (see GlobalSlopes.cpp) 15 | // [2] - Filter cutoff 16 | // [3] - Filter resonance 17 | // GATE - Triggers the ModuleENV 18 | // 19 | // ============================================================================= 20 | 21 | #ifndef SynthTutorial4_h 22 | #define SynthTutorial4_h 23 | 24 | #include "Synth.h" 25 | 26 | class SynthTutorial4 : public Synth 27 | { 28 | public: 29 | SynthTutorial4(Inputs *inputs); 30 | }; 31 | 32 | #endif -------------------------------------------------------------------------------- /SynthTutorial5.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial5.h" 2 | 3 | SynthTutorial5::SynthTutorial5(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleWavetableOsc *osc1 = new ModuleWavetableOsc(); 7 | ModuleWavetableOsc *osc2 = new ModuleWavetableOsc(); 8 | ModuleWavetableOsc *osc3 = new ModuleWavetableOsc(); 9 | ModuleSwitch *switchAB = new ModuleSwitch(); 10 | 11 | // Wire up oscillator #1 12 | osc1->wavetable_input = inputs->param2; 13 | osc1->frequency_input = inputs->param3; 14 | 15 | // Wire up oscillator #2 16 | osc2->wavetable_input = new ModuleConstant(6); 17 | osc2->frequency_input = inputs->sr; 18 | 19 | // Wire up oscillator #3 20 | osc3->wavetable_input = inputs->mod; 21 | osc3->frequency_input = inputs->param1; 22 | 23 | // Wire the output of oscillator #3 into the switching 24 | // mechanism of switchAB, and rapidly switch between 25 | // the output from oscillator #1 and #2. 26 | switchAB->a_input = osc1; 27 | switchAB->b_input = osc2; 28 | switchAB->select_input = osc3; 29 | 30 | this->last_module = switchAB; 31 | } -------------------------------------------------------------------------------- /SynthTutorial5.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial5 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration using ModuleSwitch. This is an unusual example 8 | // where the output of two wavetable oscillators are rapidly switched between 9 | // using the output of a third wavetable oscillator. 10 | // 11 | // A more traditional usage might be to switch between control voltages, 12 | // like LFOs or sequencer output. 13 | // 14 | // SR - Frequency input of oscillator #2 15 | // MOD - Oscillator #3 wavetable selection 16 | // [1] - Frequency output of oscillator #3, which controls the switching 17 | // [2] - Wavetable selection of oscillator #1 18 | // [3] - Frequency of oscillator #2 19 | // GATE - Wavetable selection of oscillator #3 20 | // 21 | // ============================================================================= 22 | 23 | #ifndef SynthTutorial5_h 24 | #define SynthTutorial5_h 25 | 26 | #include "Synth.h" 27 | 28 | class SynthTutorial5 : public Synth 29 | { 30 | public: 31 | SynthTutorial5(Inputs *inputs); 32 | }; 33 | 34 | #endif -------------------------------------------------------------------------------- /SynthTutorial6.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial6.h" 2 | 3 | SynthTutorial6::SynthTutorial6(Inputs* inputs) 4 | { 5 | // Create the modules 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 8 | ModuleLFO *lfo = new ModuleLFO(); 9 | 10 | // Patch up oscillator 11 | wavetable_osc->frequency_input = inputs->sr; 12 | wavetable_osc->wavetable_input = inputs->mod; 13 | 14 | // Path up LFO 15 | lfo->wavetable_input = inputs->param1; 16 | lfo->frequency_input = inputs->param2; 17 | 18 | // Wire the oscillator into the lowpass filter 19 | // Use the LFO to modulate the LPF's cutoff 20 | lowpass_filter->audio_input = wavetable_osc; 21 | lowpass_filter->cutoff_input = lfo; 22 | lowpass_filter->resonance_input = inputs->param3; 23 | 24 | // Output the audio of the lowpass filter 25 | this->last_module = lowpass_filter; 26 | } -------------------------------------------------------------------------------- /SynthTutorial6.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial6 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Simple LFO example. A wavetable oscillator is being filtered 8 | // by a lowpass filter. The filter's cutoff is being modulated by the LFO. 9 | // 10 | // 11 | // SR - Wavetable Oscillator sample rate (pitch) 12 | // MOD - Wavetable selection 13 | // [1] - LFO wavetable selection 14 | // [2] - LFO frequency 15 | // [3] - Lowpass filter resonance input 16 | // GATE - not used 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthTutorial6_h 21 | #define SynthTutorial6_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthTutorial6 : public Synth 26 | { 27 | public: 28 | SynthTutorial6(Inputs *inputs); 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /SynthTutorial7.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial7.h" 2 | 3 | SynthTutorial7::SynthTutorial7(Inputs* inputs) 4 | { 5 | // Create a clock, clock divider, lfo, map, and drum sound module 6 | ModuleExtClock *ext_clock = new ModuleExtClock(120); 7 | ModuleClockDivider *clock_divider = new ModuleClockDivider(); 8 | ModuleLFO *lfo = new ModuleLFO(); 9 | ModuleEqDrum *drum_sound= new ModuleEqDrum(); 10 | ModuleMap *map_0_24 = new ModuleMap(0,24); 11 | 12 | // Allow the GATE input to override the internal clock 13 | ext_clock->clock_input = inputs->gate; 14 | 15 | // Control the LFO's frequency and wavetable using 16 | // the param1 and param2 inputs 17 | lfo->frequency_input = inputs->param1; 18 | lfo->wavetable_input = inputs->param2; 19 | 20 | // Map the LFO's output to 0 - 24 21 | map_0_24->input = lfo; 22 | 23 | // Wire up the clock divider 24 | clock_divider->clock_input = ext_clock; 25 | clock_divider->division_input = map_0_24; 26 | 27 | // Wire up the drum sound. The drum sound 28 | // is triggered by the clock divider. 29 | drum_sound->drum_selection_input = inputs->mod; 30 | drum_sound->sample_rate_input = inputs->sr; 31 | drum_sound->trigger_input = clock_divider; 32 | 33 | // Output the sound of the drum 34 | this->last_module = drum_sound; 35 | } -------------------------------------------------------------------------------- /SynthTutorial7.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial7 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstrates the usage of the map module, which is used to 8 | // reduce the range of an LFO so that it can modulate a clock divider's 9 | // clock division input. The final clock division output is used to trigger 10 | // a drum sound. 11 | // 12 | // The basic idea is: 13 | // clock ---> map(0-24) ---> clock divider ---> drum sound ---> output 14 | // 15 | // SR - Drum sound frequency 16 | // MOD - Drum sound selection (from ModuleEqDrum) 17 | // [1] - LFO frequency 18 | // [2] - LFO wavetable 19 | // [3] - not used 20 | // GATE - (optional) Clock input to the clock divider 21 | // 22 | // ============================================================================= 23 | 24 | #ifndef SynthTutorial7_h 25 | #define SynthTutorial7_h 26 | 27 | #include "Synth.h" 28 | 29 | class SynthTutorial7 : public Synth 30 | { 31 | public: 32 | SynthTutorial7(Inputs *inputs); 33 | }; 34 | 35 | #endif -------------------------------------------------------------------------------- /SynthTutorial8.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial8.h" 2 | 3 | SynthTutorial8::SynthTutorial8(Inputs* inputs) 4 | { 5 | // Create an lfo, quantizer, and oscillator 6 | // They're going to be patched together like: 7 | // 8 | // lfo ---> quantizer ---> oscillator 9 | // 10 | ModuleLFO *lfo = new ModuleLFO(); 11 | ModuleQuantizer *quantizer = new ModuleQuantizer(); 12 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 13 | 14 | // Control the LFO rate and waveform via inputs 15 | lfo->frequency_input = inputs->sr; 16 | lfo->wavetable_input = inputs->param2; 17 | 18 | // Wire the output of the lfo to the input of the quantizer 19 | quantizer->scale_input = inputs->param1; 20 | quantizer->cv_input = lfo; 21 | 22 | // Wire the output of the quantizer to the frequency 23 | // input of the oscillator. 24 | osc->wavetable_input = inputs->mod; 25 | osc->frequency_input = quantizer; 26 | 27 | this->last_module = osc; 28 | } -------------------------------------------------------------------------------- /SynthTutorial8.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial8 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Example usage of the Quantizer module. The output of an LFO 8 | // is used to control the pitch of a wavetable oscillator. 9 | // 10 | // SR - Controls the speed of the LFO 11 | // MOD - Wavetable selection 12 | // [1] - Selects the scale for quantization 13 | // [2] - Selects the wavetable for the LFO 14 | // [3] - not used 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthTutorial8_h 20 | #define SynthTutorial8_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthTutorial8 : public Synth 25 | { 26 | public: 27 | SynthTutorial8(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /SynthTutorial9.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial9.h" 2 | 3 | SynthTutorial9::SynthTutorial9(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleQuantizer *quantizer = new ModuleQuantizer(); 7 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 8 | ModulePatternGenerator *pattern_generator = new ModulePatternGenerator(); 9 | ModuleExtClock *ext_clock = new ModuleExtClock(120, EIGHTH_NOTE_CLOCK_DIVISION); 10 | 11 | // Allow the GATE input to override the internal clock 12 | ext_clock->clock_input = inputs->gate; 13 | 14 | // Wire up the pattern generator 15 | pattern_generator->cv_pattern_input = inputs->param2; 16 | pattern_generator->clock_input = ext_clock; 17 | pattern_generator->length_input = new ModuleConstant(16); 18 | 19 | // Quantize the output of the pattern generator 20 | quantizer->scale_input = inputs->param1; 21 | quantizer->cv_input = pattern_generator; 22 | 23 | // Use the quantized output of the pattern generator to 24 | // control the frequency of a wavetable oscillator. 25 | osc->wavetable_input = inputs->mod; 26 | osc->frequency_input = quantizer; 27 | 28 | // Output the audio of the wavetable oscillator 29 | this->last_module = osc; 30 | } -------------------------------------------------------------------------------- /SynthTutorial9.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthTutorial9 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Demonstration of the pattern generator module 8 | // 9 | // SR - not used 10 | // MOD - wavetable sound selection 11 | // [1] - scale selection 12 | // [2] - pattern selection 13 | // [3] - not used 14 | // GATE - (optional) clocks the pattern generator 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthTutorial9_h 19 | #define SynthTutorial9_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthTutorial9 : public Synth 24 | { 25 | public: 26 | SynthTutorial9(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthWavetable.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthWavetable.h" 2 | 3 | SynthWavetable::SynthWavetable(Inputs *inputs) 4 | { 5 | ModuleWavetableOsc *osc = new ModuleWavetableOsc(); 6 | 7 | osc->wavetable_input = inputs->mod; 8 | osc->frequency_input = inputs->sr; 9 | 10 | this->last_module = osc; 11 | } 12 | -------------------------------------------------------------------------------- /SynthWavetable.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthWavetable 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | 8 | // 9 | // ============================================================================= 10 | 11 | #ifndef SynthWavetable_h 12 | #define SynthWavetable_h 13 | 14 | #include "Synth.h" 15 | 16 | class SynthWavetable : public Synth 17 | { 18 | public: 19 | SynthWavetable(Inputs *inputs); 20 | }; 21 | 22 | #endif -------------------------------------------------------------------------------- /SynthWavetableDelay.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthWavetableDelay.h" 2 | 3 | SynthWavetableDelay::SynthWavetableDelay(Inputs* inputs) 4 | { 5 | // Create modules 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | ModuleDelay *delay = new ModuleDelay(); 8 | 9 | // Wire up the wavetable oscillator 10 | wavetable_osc->wavetable_input = inputs->mod; 11 | wavetable_osc->frequency_input = inputs->sr; 12 | 13 | // Put the wavetable oscillator through a delay 14 | delay->audio_input = wavetable_osc; 15 | delay->mix_input = inputs->param1; 16 | delay->feedback_input = inputs->param2; 17 | delay->length_input = inputs->param3; 18 | 19 | // Output the audio of the delay 20 | this->last_module = delay; 21 | } -------------------------------------------------------------------------------- /SynthWavetableDelay.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthWavetableDelay 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: A wavetable oscillator put through a short audio delay. 8 | // 9 | // SR - Sample rate of the wavetable oscillator 10 | // MOD - Wavetable selection 11 | // [1] - Mix (dry/wet) of the delay effect 12 | // [2] - Delay feedback 13 | // [3] - Delay buffer length 14 | // GATE - not used 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthWavetableDelay_h 19 | #define SynthWavetableDelay_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthWavetableDelay : public Synth 24 | { 25 | public: 26 | SynthWavetableDelay(Inputs *inputs); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /SynthWavetableFolder.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthWavetableFolder.h" 2 | 3 | SynthWavetableFolder::SynthWavetableFolder(Inputs* inputs) 4 | { 5 | 6 | // Create the modules 7 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 8 | ModuleBitReducer *bit_reducer = new ModuleBitReducer(); 9 | ModuleWaveFolder *wave_folder = new ModuleWaveFolder(); 10 | ModuleLowpassFilter *lowpass_filter = new ModuleLowpassFilter(); 11 | 12 | // Wire up the wavetable oscillator 13 | wavetable_osc->wavetable_input = inputs->mod; 14 | wavetable_osc->frequency_input = inputs->sr; 15 | 16 | // Put the wavetable oscillator through a lowpass filter 17 | lowpass_filter->audio_input = wavetable_osc; 18 | lowpass_filter->cutoff_input = inputs->param2; 19 | lowpass_filter->resonance_input = inputs->param3; 20 | 21 | // Wire the output of the lowpass filter into a wave folder 22 | wave_folder->audio_input = lowpass_filter; 23 | wave_folder->lower_clipping_level_input = inputs->param1; 24 | wave_folder->upper_clipping_level_input = inputs->param1; 25 | 26 | // Output the audio of the wave folder 27 | this->last_module = wave_folder; 28 | 29 | } -------------------------------------------------------------------------------- /SynthWavetableFolder.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthWavetableFolder 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: A wavetable oscillator routed through a lowpass filter, 8 | // followed by a wave folder. 9 | // 10 | // SR - Sample rate of the wavetable oscillator 11 | // MOD - Wavetable selection 12 | // [1] - Wave folding level 13 | // [2] - Lowpass filter cutoff 14 | // [3] - Lowpass filter resonance 15 | // GATE - not used 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthWavetableFolder_h 20 | #define SynthWavetableFolder_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthWavetableFolder : public Synth 25 | { 26 | public: 27 | SynthWavetableFolder(Inputs *inputs); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /experimental/Macro.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clone45/EquationComposer/cf437b10f68dfc8d4b69935cb974d46fd5b2f49a/experimental/Macro.cpp -------------------------------------------------------------------------------- /experimental/Macro.h: -------------------------------------------------------------------------------- 1 | #ifndef Macro_h 2 | #define Macro_h 3 | 4 | #include "Module.h" 5 | 6 | class Macro : public Module 7 | { 8 | }; 9 | 10 | #endif -------------------------------------------------------------------------------- /experimental/MacroGatedLPF.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "MacroGatedLPF.h" 3 | #include "defines.h" 4 | 5 | // Include the modules 6 | #include "ModuleLowpassFilter.h" 7 | #include "ModuleENV.h" 8 | 9 | MacroGatedLPF::MacroGatedLPF() 10 | { 11 | // Initialize all inputs 12 | // this->audio_input = NULL; 13 | // this->trigger_input = NULL; 14 | 15 | // Instantiate all modules 16 | lowpass_filter = new ModuleLowpassFilter(); 17 | envelope_generator = new ModuleENV(); 18 | 19 | // 20 | // Wire together the macro 21 | // 22 | 23 | envelope_generator->trigger_input = NULL; 24 | envelope_generator->frequency_input = new ModuleConstant(1000); 25 | envelope_generator->slope_input = new ModuleConstant(0); 26 | 27 | lowpass_filter->audio_input = NULL; 28 | // lowpass_filter->cutoff_input = envelope_generator; 29 | lowpass_filter->cutoff_input = new ModuleConstant(2000); 30 | lowpass_filter->resonance_input = new ModuleConstant(0); 31 | } 32 | 33 | uint16_t MacroGatedLPF::compute() 34 | { 35 | return(this->lowpass_filter->compute()); 36 | } -------------------------------------------------------------------------------- /experimental/MacroGatedLPF.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | MacroGatedLPF.h | 4 | * |----------------------| 5 | * +----------------------+ 6 | * 7 | */ 8 | 9 | 10 | #ifndef MacroGatedLPF_h 11 | #define MacroGatedLPF_h 12 | 13 | #include "Arduino.h" 14 | #include "Macro.h" 15 | 16 | #include "ModuleLowpassFilter.h" 17 | #include "ModuleENV.h" 18 | #include "ModuleConstant.h" 19 | 20 | class MacroGatedLPF : public Macro 21 | { 22 | 23 | public: 24 | MacroGatedLPF(); 25 | uint16_t compute(); 26 | 27 | // Modules 28 | ModuleLowpassFilter *lowpass_filter; 29 | ModuleENV *envelope_generator; 30 | 31 | // Inputs 32 | //Module *audio_input; 33 | //Module *trigger_input; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /experimental/ModuleAudioEFX.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleAudioEFX.h" 3 | #include "defines.h" 4 | 5 | ModuleAudioEFX::ModuleAudioEFX(Equations *equations) 6 | { 7 | audio = 0; // Set the counter to 0 8 | p1 = 0; 9 | p2 = 0; 10 | p3 = 0; 11 | 12 | this->equations = equations; 13 | 14 | // Initialize all inputs 15 | this->equation_input = NULL; 16 | this->audio_input = NULL; 17 | this->param1_input = NULL; 18 | this->param2_input = NULL; 19 | this->param3_input = NULL; 20 | this->reset_input = NULL; 21 | this->mod_input = NULL; 22 | } 23 | 24 | uint32_t ModuleAudioEFX::compute() 25 | { 26 | 27 | // Read inputs 28 | equation = this->readInput(equation_input); 29 | audio = this->readInput(audio_input); 30 | p1 = this->readInput(param1_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 31 | p2 = this->readInput(param2_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 32 | p3 = this->readInput(param3_input, CONVERT_TO_8_BIT); // range: 0 - 255 (2^8) 33 | 34 | // Play the selected equation 35 | return(this->equations->compute(equation, audio, p1, p2, p3)); 36 | } -------------------------------------------------------------------------------- /experimental/ModuleAudioEFX.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleAudioEFX_h 2 | #define ModuleAudioEFX_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | #include "Equations.h" 7 | 8 | class ModuleAudioEFX : public Module 9 | { 10 | 11 | public: 12 | ModuleAudioEFX(Equations *equations); 13 | uint32_t compute(); 14 | 15 | // Inputs 16 | Module *equation_input; 17 | Module *audio_input; 18 | Module *param1_input; 19 | Module *param2_input; 20 | Module *param3_input; 21 | Module *reset_input; 22 | Module *mod_input; 23 | 24 | private: 25 | int equation; 26 | uint32_t audio; 27 | 28 | uint32_t p1; 29 | uint32_t p2; 30 | uint32_t p3; 31 | 32 | Equations *equations; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /experimental/ModuleCAOsc.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleCAOsc.h" 3 | #include "defines.h" 4 | 5 | ModuleCAOsc::ModuleCAOsc() 6 | { 7 | output = 32768; 8 | last_output = 32768; 9 | 10 | ca_rules = { 0, 1, 1, 0, 1, 0, 0, 1 }; 11 | } 12 | 13 | uint16_t ModuleCAOsc::compute() 14 | { 15 | // Calculate next output 16 | for(uint8_t i=0; i<16; i++) 17 | { 18 | uint8_t a = ((i-1)%16); 19 | uint8_t b = i; 20 | uint8_t c = ((i+1)%16); 21 | 22 | uint8_t mask = (bitRead(last_output,c) << 2) + (bitRead(last_output,b) << 1) + bitRead(last_output,a); 23 | 24 | bitWrite(output, i, ca_rules[mask]); 25 | } 26 | 27 | last_output = output; 28 | 29 | return(output); 30 | } 31 | -------------------------------------------------------------------------------- /experimental/ModuleCAOsc.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleCAOsc_h 2 | #define ModuleCAOsc_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | 7 | class ModuleCAOsc : public Module 8 | { 9 | 10 | public: 11 | 12 | ModuleCAOsc(); 13 | uint16_t compute(); 14 | 15 | // Inputs 16 | 17 | 18 | private: 19 | 20 | uint16_t output; 21 | uint16_t last_output; 22 | 23 | uint16_t ca_rules[8]; 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /experimental/ModuleChords.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleChords.h" 3 | #include "defines.h" 4 | #include "Scales.h" 5 | 6 | ModuleChords::ModuleChords() 7 | { 8 | // Initialize all inputs 9 | this->root_note_input = NULL; 10 | this->chord_input = NULL; 11 | 12 | // Instantiate all outputs 13 | this->note_1_output = new ModuleOutput(this); 14 | this->note_2_output = new ModuleOutput(this); 15 | this->note_3_output = new ModuleOutput(this); 16 | } 17 | 18 | uint32_t ModuleChords::compute() 19 | { 20 | uint32_t root_note_input = this->readInput(this->root_note_input, 0, 60); 21 | uint32_t chord_input = this->readInput(this->chord_input, CONVERT_TO_5_BIT); // 0 - 31 22 | 23 | this->note_1_output->value = NOTES[CHROMATIC[min((root_note_input + CHORDS[chord_input][0]),60)]]; 24 | this->note_2_output->value = NOTES[CHROMATIC[min((root_note_input + CHORDS[chord_input][1]),60)]]; 25 | this->note_3_output->value = NOTES[CHROMATIC[min((root_note_input + CHORDS[chord_input][2]),60)]]; 26 | 27 | return(this->note_3_output->value); 28 | } -------------------------------------------------------------------------------- /experimental/ModuleDrum.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleDrum_h 2 | #define ModuleDrum_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | 7 | #define KICK_SAMPLE_LENGTH 4342 8 | #define SNARE_SAMPLE_LENGTH 5222 9 | #define HIHAT_SAMPLE_LENGTH 183 10 | 11 | class ModuleDrum : public Module 12 | { 13 | 14 | public: 15 | ModuleDrum(); 16 | uint32_t compute(); 17 | 18 | // Inputs 19 | Module *drum_selection_input; 20 | Module *trigger_input; 21 | Module *sample_rate_input; 22 | 23 | private: 24 | int drum_selection; 25 | boolean triggered; 26 | boolean playing; 27 | 28 | uint32_t t; // Accumulator used in equations 29 | uint32_t w; // The final output 30 | 31 | // Arrays to hold the sample data 32 | int kick_sample[KICK_SAMPLE_LENGTH]; 33 | int snare_sample[SNARE_SAMPLE_LENGTH]; 34 | int hihat_sample[HIHAT_SAMPLE_LENGTH]; 35 | 36 | 37 | // 19.13 fixed point number (using the upper 19 bits for holding the usable 38 | // numbers and an additional 13 bits (0-8192) for simulating fractional values for 39 | // use when incrementing the variable fractional values 40 | uint32_t fixed_point_20_12_index; 41 | uint32_t increment_by; 42 | 43 | void stop_playback(); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /experimental/ModuleEquationShot.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleEquationShot.h" 3 | #include "defines.h" 4 | 5 | ModuleEquationShot::ModuleEquationShot(Equations *equations) 6 | { 7 | fixed_point_20_12_index = 0; 8 | this->equations = equations; 9 | 10 | // Initialize all inputs 11 | this->sample_rate_input = NULL; 12 | this->equation_input = NULL; 13 | this->start_position_input = NULL; 14 | this->param3_input = NULL; 15 | this->reset_input = NULL; 16 | } 17 | 18 | uint16_t ModuleEquationShot::compute() 19 | { 20 | // Read inputs 21 | // For loop_start and loop_length, I'm dropping some of the least significant 22 | // bits in order to remove any noise from the incoming signal. 23 | 24 | equation = this->readInput(equation_input, 0, NUMBER_OF_EQUATIONS); 25 | increment_by = this->readInput(sample_rate_input) << 1; 26 | position = this->readInput(start_position_input) << 2; 27 | p3 = this->readInput(param3_input, CONVERT_TO_8_BIT); 28 | reset = this->readInput(reset_input); 29 | 30 | fixed_point_20_12_index += increment_by; 31 | 32 | // shift off th 12 bits used for fractional numbers, which leaves us with a 20 bit number 33 | playback_position = position + (fixed_point_20_12_index >> 12); 34 | 35 | if((reset >= MID_CV) && (old_reset < MID_CV)) 36 | { 37 | playback_position = 0; 38 | fixed_point_20_12_index = 0; 39 | } 40 | 41 | old_reset = reset; 42 | 43 | // Play the selected equation 44 | return(this->equations->compute(equation, playback_position, 1, 1, p3)); 45 | 46 | } -------------------------------------------------------------------------------- /experimental/ModuleEquationShot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleEquationShot | 4 | * |----------------------| 5 | * > sample_rate_input | 6 | * > equation_input | 7 | * > position_input | 8 | * > param3_input | 9 | * > reset_input | 10 | * | output> 11 | * +----------------------+ 12 | * 13 | */ 14 | // ============================================================================= 15 | // 16 | // 17 | 18 | 19 | #ifndef ModuleEquationShot_h 20 | #define ModuleEquationShot_h 21 | 22 | #include "Arduino.h" 23 | #include "Module.h" 24 | #include "Equations.h" 25 | 26 | class ModuleEquationShot : public Module 27 | { 28 | 29 | public: 30 | ModuleEquationShot(Equations *equations); 31 | uint16_t compute(); 32 | 33 | // Inputs 34 | Module *sample_rate_input; 35 | Module *equation_input; 36 | Module *start_position_input; 37 | Module *param3_input; 38 | Module *reset_input; 39 | 40 | private: 41 | 42 | uint16_t equation; 43 | uint16_t rate; 44 | uint16_t position; 45 | uint16_t p3; 46 | uint16_t reset; 47 | uint16_t old_reset; 48 | 49 | Equations *equations; 50 | 51 | // 20.12 fixed point number (using the upper 20 bits for holding the usable 52 | // numbers and an additional 12 bits for simulating fractional values for 53 | // use when incrementing the variable fractional values 54 | uint32_t fixed_point_20_12_index; 55 | uint32_t increment_by; 56 | uint32_t playback_position; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /experimental/ModuleHighpassFilter.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleHighpassFilter.h" 3 | #include "defines.h" 4 | 5 | ModuleHighpassFilter::ModuleHighpassFilter() 6 | { 7 | // Set cutoff and resonance to 0 to start with. 8 | // For some reason, if you don't do this, the lowpass filter 9 | // can generate noise until the cutoff reaches 0, then it starts sounding OK. 10 | hpf.setCutoffFreq(0); 11 | hpf.setResonance(0); 12 | 13 | // Initialize all inputs 14 | this->audio_input = NULL; 15 | this->cutoff_input = NULL; 16 | this->resonance_input = NULL; 17 | } 18 | 19 | uint16_t ModuleHighpassFilter::compute() 20 | { 21 | // Read inputs 22 | uint32_t audio = this->readInput(audio_input); // audio range: 0 to 4095 23 | uint32_t cutoff = this->readInput(cutoff_input, CONVERT_TO_8_BIT); // cutoff range: 0 to 255 24 | uint32_t resonance = this->readInput(resonance_input, CONVERT_TO_8_BIT); // resonance range: 0 to 255 25 | 26 | hpf.setCutoffFreq(cutoff); 27 | hpf.setResonance(resonance); 28 | 29 | return(hpf.next(audio) >> 1); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /experimental/ModuleHighpassFilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleHighpassFilter | 4 | * |----------------------| 5 | * > audio_input | 6 | * > cutoff_input | 7 | * > resonance_input | 8 | * | | 9 | * | output > 10 | * +----------------------+ 11 | */ 12 | 13 | #ifndef ModuleHighpassFilter_h 14 | #define ModuleHighpassFilter_h 15 | 16 | #include "Arduino.h" 17 | #include "Module.h" 18 | #include "HighPassFilter.h" 19 | 20 | class ModuleHighpassFilter : public Module 21 | { 22 | 23 | public: 24 | 25 | // Methods 26 | ModuleHighpassFilter(); 27 | uint16_t compute(); 28 | 29 | // Inputs 30 | Module *audio_input; 31 | Module *cutoff_input; 32 | Module *resonance_input; 33 | 34 | // Public variables 35 | 36 | // A high pass filter object from HighPassFilter.h, not to be 37 | // confused with the ModuleLowpassFilter type. 38 | HighPassFilter hpf; 39 | 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /experimental/ModuleLowpassFilter.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleLowpassFilter.h" 3 | #include "defines.h" 4 | 5 | ModuleLowpassFilter::ModuleLowpassFilter() 6 | { 7 | // Initialize all inputs 8 | this->audio_input = NULL; 9 | this->cutoff_input = NULL; 10 | this->resonance_input = NULL; 11 | 12 | b0=b1=b2=b3=b4=t1=t2=0; 13 | } 14 | 15 | uint16_t ModuleLowpassFilter::compute() 16 | { 17 | // Read inputs 18 | long audio = this->readInput(audio_input) - 2048; 19 | uint32_t cutoff = this->readInput(cutoff_input, CONVERT_TO_8_BIT); 20 | uint32_t resonance = this->readInput(resonance_input, CONVERT_TO_7_BIT); 21 | 22 | q = 256 - cutoff; 23 | p = cutoff + ((((205 * cutoff)>>8) * q)>>8); 24 | f = ((int)p<<1) - 256; 25 | long temp1 = (q * q)>>8; 26 | temp1 = (1434 * temp1)>>8; 27 | temp1 = temp1 + 256 - q; 28 | temp1 = (temp1*q)>>8; 29 | temp1 = temp1>>1; 30 | temp1 += 256; 31 | q = (temp1*resonance)>>8; 32 | 33 | audio -= (q * b4)>>8; //feedback 34 | t1 = b1; 35 | b1 = (((audio + b0) * p)>>8) - ((b1 * f)>>8); 36 | 37 | t2 = b2; 38 | b2 = (((b1 + t1) * p)>>8) - ((b2 * f)>>8); 39 | t1 = b3; 40 | b3 = (((b2 + t2) * p)>>8) - ((b3 * f)>>8); 41 | b4 = (((b3 + t1) * p)>>8) - ((b4 * f)>>8); 42 | b0 = audio; 43 | return((uint32_t) (b4 + 2048)); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /experimental/ModuleLowpassFilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleLowpassFilter | 4 | * |----------------------| 5 | * > audio_input | 6 | * > cutoff_input | 7 | * > resonance_input | 8 | * | | 9 | * | output > 10 | * +----------------------+ 11 | */ 12 | 13 | #ifndef ModuleLowpassFilter_h 14 | #define ModuleLowpassFilter_h 15 | 16 | #include "Arduino.h" 17 | #include "Module.h" 18 | #include "LowPassFilter_test.h" 19 | 20 | class ModuleLowpassFilter : public Module 21 | { 22 | 23 | public: 24 | 25 | // Methods 26 | ModuleLowpassFilter(); 27 | uint16_t compute(); 28 | 29 | // Inputs 30 | Module *audio_input; 31 | Module *cutoff_input; 32 | Module *resonance_input; 33 | 34 | long q,p,f; 35 | long b0,b1,b2,b3,b4,t1,t2; 36 | 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /experimental/ModuleReverb.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleReverb.h" 3 | #include "defines.h" 4 | #include "GlobalRingBuffer.h" 5 | 6 | ModuleReverb::ModuleReverb() 7 | { 8 | buffer_index = 0; 9 | reverb_output = 0; 10 | 11 | audio_input = NULL; 12 | mix_input = NULL; 13 | feedback_input = NULL; 14 | } 15 | 16 | uint16_t ModuleReverb::compute() 17 | { 18 | uint32_t audio = this->readInput(audio_input); 19 | uint32_t wet_mix = this->readInput(mix_input); 20 | uint32_t feedback = this->readInput(feedback_input); 21 | uint16_t buffer_length = 4095; 22 | uint16_t buffer_index_2; 23 | uint16_t buffer_index_3; 24 | 25 | uint32_t dry_mix = 4095 - wet_mix; 26 | 27 | buffer_index++; 28 | if(buffer_index >= buffer_length) buffer_index = 0; 29 | 30 | buffer_index_2 = (buffer_index + 64) % 4095; 31 | buffer_index_3 = (buffer_index + 128) % 4095; 32 | 33 | reverb_output = RING_BUFFER[buffer_index]; 34 | 35 | // RING_BUFFER[buffer_index] = ((audio * (4095 - feedback)) >> 12) + ((reverb_output * feedback) >> 12); 36 | RING_BUFFER[buffer_index_2] = ((audio * (4095 - (feedback >> 0))) >> 12) + ((RING_BUFFER[buffer_index_2] * (feedback >> 0)) >> 12); 37 | RING_BUFFER[buffer_index_3] = ((audio * (4095 - (feedback >> 1))) >> 12) + ((RING_BUFFER[buffer_index_3] * (feedback >> 1)) >> 12); 38 | 39 | if(wet_mix == 0) 40 | { 41 | return(audio); 42 | } 43 | else 44 | { 45 | return(((reverb_output * wet_mix) >> 12) + ((audio * dry_mix) >> 12)); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /experimental/ModuleReverb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleReverb | 4 | * |----------------------| 5 | * > audio_input | 6 | * > mix_input | 7 | * > feedback_input | 8 | * > length_input | 9 | * | output > 10 | * +----------------------+ 11 | * 12 | */ 13 | // ============================================================================= 14 | // 15 | // 16 | 17 | #ifndef ModuleReverb_h 18 | #define ModuleReverb_h 19 | 20 | #include "Arduino.h" 21 | #include "Module.h" 22 | 23 | class ModuleReverb : public Module 24 | { 25 | 26 | public: 27 | ModuleReverb(); 28 | uint16_t compute(); 29 | 30 | // Inputs 31 | Module *audio_input; 32 | Module *mix_input; 33 | Module *feedback_input; 34 | 35 | private: 36 | 37 | uint16_t buffer_index; 38 | uint32_t reverb_output; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /experimental/ModuleRingMod.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleRingMod.h" 3 | #include "defines.h" 4 | #include "GlobalWavetables.h" 5 | #include "GlobalIncrements.h" 6 | 7 | ModuleRingMod::ModuleRingMod() 8 | { 9 | fixed_point_10_22_index = 0; 10 | 11 | // Initialize all module inputs to NULL 12 | this->audio_input = NULL; 13 | this->frequency_input = NULL; 14 | } 15 | 16 | uint16_t ModuleRingMod::compute() 17 | { 18 | uint16_t audio = this->readInput(audio_input); 19 | uint16_t frequency = this->readInput(frequency_input); 20 | uint16_t wavetable = 0; 21 | 22 | fixed_point_10_22_index += ((INCREMENTS[frequency] - 3100000)); 23 | if(fixed_point_10_22_index > WAVE_SAMPLES_SHIFTED_22) fixed_point_10_22_index -= WAVE_SAMPLES_SHIFTED_22; 24 | 25 | wavetable_index = fixed_point_10_22_index >> 22; 26 | 27 | return(((uint32_t)audio * (uint32_t)WAVETABLES[wavetable][wavetable_index]) >> 1); 28 | } -------------------------------------------------------------------------------- /experimental/ModuleRingMod.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleRingMod | 4 | * |----------------------| 5 | * > audio_input | 6 | * > frequency_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | 14 | 15 | #ifndef ModuleRingMod_h 16 | #define ModuleRingMod_h 17 | 18 | #include "Arduino.h" 19 | #include "Module.h" 20 | 21 | class ModuleRingMod : public Module 22 | { 23 | 24 | public: 25 | ModuleRingMod(); 26 | uint16_t compute(); 27 | 28 | // Inputs 29 | Module *audio_input; 30 | Module *frequency_input; 31 | 32 | // 10.22 fixed point number (using the upper 10 bits for addressing the indexes 33 | // up to 1024 (we only need 600), and an additional 22 bits (0-4194304) for simulating fractional values for 34 | // use when incrementing the variable fractional values 35 | uint32_t fixed_point_10_22_index; 36 | uint32_t wavetable_index; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /experimental/ModuleSoundToy.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleSoundToy_h 2 | #define ModuleSoundToy_h 3 | 4 | #include "Module.h" 5 | #include "FixedPointMath.h" 6 | #include "Rand.h" 7 | 8 | class ModuleSoundToy : public Module 9 | { 10 | public: 11 | ModuleSoundToy(); 12 | uint32_t compute(); 13 | 14 | FixedPointMath fixed_point_math; 15 | Rand rand; 16 | 17 | Module *trigger_input; 18 | Module *frequency_input; 19 | Module *sound_input; 20 | 21 | private: 22 | 23 | float y; 24 | uint32_t output; 25 | uint32_t t; 26 | uint32_t trigger; 27 | uint32_t old_trigger; 28 | uint32_t sound; 29 | 30 | uint32_t frequency; // = 440; 31 | uint32_t value; 32 | 33 | // 20.12 fixed point number (using the upper 20 bits for holding the usable 34 | // numbers and an additional 12 bits (0-4095) for simulating fractional values for 35 | // use when incrementing the variable fractional values 36 | uint32_t fixed_point_20_12_index; 37 | uint32_t increment_by; 38 | }; 39 | 40 | #endif 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /experimental/ModuleSpeechSound.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleSpeechSound_h 2 | #define ModuleSpeechSound_h 3 | 4 | #include "Module.h" 5 | 6 | #if defined(__SAM3X8E__) 7 | #define PROGMEM 8 | #define pgm_read_byte(x) (*((char *)x)) 9 | #define pgm_read_word(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) 10 | #define pgm_read_byte_near(x) (*((char *)x)) 11 | #define pgm_read_byte_far(x) (*((char *)x)) 12 | #define pgm_read_word_near(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) 13 | #define pgm_read_word_far(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x)))) 14 | #define PSTR(x) x 15 | #if defined F 16 | #undef F 17 | #endif 18 | #define F(X) (X) 19 | #endif 20 | 21 | #define FORMANT_SZ 7 22 | 23 | /* 24 | enum { 25 | _SP,_DOT,_QM,_COM,_HYP,_IY,_IH,_EH,_AE,_AA, 26 | _AH,_AO,_UH,_AX,_IX,_ER,_UX,_OH,_RX,_LX, 27 | _WX,_YX,_WH,_RR,_LL,_WW,_YY,_MM,_NN,_NX, 28 | _DX,_QQ,_SS,_SH,_F,_TH,__H,__X,_ZZ,_ZH, 29 | _V,_DH,_CHa,_CHb,_Ja,_Jb,_Jc,_Jd,_EY,_AY, 30 | _OY,_AW,_OW,_UW,_Ba,_Bb,_Bc,_Da,_Db,_Dc, 31 | _Ga,_Gb,_Gc,_GXa,_GXb,_GXc,_Pa,_Pb,_Pc,_Ta, 32 | _Tb,_Tc,_Ka,_Kb,_Kc,_KXa,_KXb,_KXc 33 | }; 34 | */ 35 | 36 | class ModuleSpeechSound : public Module 37 | { 38 | public: 39 | ModuleSpeechSound(); 40 | uint32_t compute(); 41 | 42 | // Inputs 43 | Module *sound_input; 44 | Module *pitch_input; 45 | Module *formant_scale_input; 46 | 47 | private: 48 | 49 | uint32_t output; 50 | 51 | uint16_t pitchPhase, form1Phase,form2Phase,form3Phase; 52 | uint16_t pitchPhaseInc,form1PhaseInc,form2PhaseInc,form3PhaseInc; 53 | uint8_t form1Amp,form2Amp,form3Amp; 54 | uint8_t noiseMod; 55 | 56 | int8_t sinCalc[256]; 57 | int8_t sqrCalc[256]; 58 | uint8_t formantTable[546]; 59 | uint16_t pitchTable[64]; 60 | int frameTime; 61 | uint16_t basePitch; 62 | int formantScale; 63 | 64 | int8_t noise; 65 | }; 66 | 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /experimental/ModuleVocalizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +-------------------------+ 3 | * | ModuleVocalizer | 4 | * |-------------------------| 5 | * > pitch_input | 6 | * > param1_input | 7 | * > param2_input | 8 | * > param3_input | 9 | * > formant_scale_input | 10 | * | | 11 | * | output > 12 | * +-------------------------+ 13 | * 14 | */ 15 | // ============================================================================= 16 | // 17 | // ModuleVocalizer is a human speech vowel emulator. Output sounds like someone 18 | // saying "oooo", "whaaa", "uuuuu". 19 | // 20 | // Example usage: 21 | // 22 | // ModuleWords *words = new ModuleWords(); 23 | // 24 | // words->sound_input = inputs->mod; 25 | // words->param1_input = inputs->param1; 26 | // words->param2_input = inputs->param2; 27 | // words->param3_input = inputs->param3; 28 | // words->pitch_input = inputs->sr; 29 | // 30 | // this->last_module = words; 31 | // 32 | 33 | #ifndef ModuleVocalizer_h 34 | #define ModuleVocalizer_h 35 | 36 | #include "Module.h" 37 | 38 | #define FORMANT_SZ 7 39 | 40 | 41 | class ModuleVocalizer : public Module 42 | { 43 | public: 44 | ModuleVocalizer(); 45 | uint32_t compute(); 46 | 47 | // Inputs 48 | Module *param1_input; 49 | Module *param2_input; 50 | Module *param3_input; 51 | Module *pitch_input; 52 | Module *formant_scale_input; 53 | 54 | private: 55 | 56 | uint32_t output; 57 | 58 | uint16_t pitchPhase, form1Phase,form2Phase,form3Phase; 59 | uint16_t pitchPhaseInc,form1PhaseInc,form2PhaseInc,form3PhaseInc; 60 | uint8_t form1Amp,form2Amp,form3Amp; 61 | uint8_t noiseMod; 62 | 63 | int8_t sinCalc[256]; 64 | int8_t sqrCalc[256]; 65 | uint8_t formantTable[546]; 66 | uint16_t pitchTable[64]; 67 | int frameTime; 68 | uint16_t basePitch; 69 | int formantScale; 70 | 71 | int8_t noise; 72 | }; 73 | 74 | 75 | #endif -------------------------------------------------------------------------------- /experimental/ModuleWalkSequencer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | #include "Arduino.h" 3 | #include "ModuleWalkSequencer.h" 4 | #include "defines.h" 5 | 6 | ModuleWalkSequencer::ModuleWalkSequencer() 7 | { 8 | this->step = 0; 9 | this->old_clock = 0; 10 | 11 | this->patterns = { 12 | { 13 | 32896, 32932, 41506, 45714, 41120, 41504, 33058, 41508 14 | }, 15 | { 16 | // Bank #2 = snare patterns 17 | 2056, // 0000100000001000 18 | 2393, // 0000100101011001 19 | 2190, // 0000100010001110 20 | 2057, // 0000100000001001 21 | 128, // 0000000010000000 22 | 6144, // 0001100000000000 23 | 6152, // 0001100000001000 24 | 2230 // 0000100010110110 25 | }, 26 | { 27 | // Bank #3 = hihat patterns 28 | 65535, // 1111111111111111 29 | 43690, // 1010101010101010 30 | 47031, // 1011011110110111 31 | 47086, // 1011011111101110 32 | 41535, // 1010001000111111 33 | 33808, // 1000010000010000 34 | 33510, // 1000001011100110 35 | 21847 // 0101010101010111 36 | } 37 | }; 38 | } 39 | 40 | uint32_t ModuleSequencer::compute() 41 | { 42 | uint32_t clock = this->readInput(clock_input); 43 | 44 | // Step the sequencer on the rising edge 45 | if((clock > MID_CV) && (old_clock < MID_CV)) 46 | { 47 | step++; 48 | if(step >= 8) step = 0; 49 | } 50 | 51 | old_clock = clock; 52 | 53 | // Serial.println(sequence[step]); 54 | 55 | return(sequence[step]); 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /experimental/ModuleWalkSequencer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clone45/EquationComposer/cf437b10f68dfc8d4b69935cb974d46fd5b2f49a/experimental/ModuleWalkSequencer.h -------------------------------------------------------------------------------- /experimental/ModuleWaveshaper.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "defines.h" 3 | #include "ModuleWaveshaper.h" 4 | 5 | ModuleWaveshaper::ModuleWaveshaper() 6 | { 7 | // Initialize all inputs 8 | this->audio_input = NULL; 9 | this->amount_input = NULL; 10 | } 11 | 12 | uint32_t ModuleWaveshaper::compute() 13 | { 14 | // Read inputs 15 | uint32_t audio = this->readInput(audio_input); 16 | uint32_t amount = this->readInput(amount_input); 17 | 18 | uint32_t my_output = 0; 19 | 20 | if(amount < 3) 21 | { 22 | my_output = audio; 23 | } 24 | else 25 | { 26 | float f_amount = (float)amount / (float)2048; 27 | 28 | float x = ((audio + 1.0) / 2048.0) - 1.0; 29 | float k = 2.0 * f_amount / (1.0 - f_amount); 30 | float y = (1.0 + k) * x / (1+k*abs(x)); 31 | 32 | my_output = (((y + 1.0) * 2048.0) - 1); 33 | } 34 | 35 | return(my_output); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /experimental/ModuleWaveshaper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleWaveshaper | 4 | * |----------------------| 5 | * > audio_input | 6 | * | | 7 | * | output > 8 | * +----------------------+ 9 | 10 | !!!!!!! This module doesn't work at all yet !!!!!!!!!!!!!!! 11 | 12 | */ 13 | 14 | 15 | #ifndef ModuleWaveshaper_h 16 | #define ModuleWaveshaper_h 17 | 18 | #include "Module.h" 19 | 20 | class ModuleWaveshaper : public Module 21 | { 22 | 23 | public: 24 | 25 | // Methods 26 | ModuleWaveshaper(); 27 | uint32_t compute(); 28 | 29 | // Inputs 30 | Module *audio_input; 31 | Module *amount_input; 32 | 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /experimental/ModuleWavetable.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ModuleWavetable.h" 3 | #include "defines.h" 4 | 5 | #define WAVETABLE_LENGTH 512 6 | 7 | ModuleWavetable::ModuleWavetable(EquationsWavetable *equations) 8 | { 9 | fixed_point_10_22_index = 0; 10 | 11 | // Create frequency increments table 12 | for(uint32_t i=0; i < 128; i++) 13 | { 14 | float frequency = ((pow(2.0,(i-69.0)/12.0)) * 440.0); 15 | increments[i] = frequency * (float)((float)(WAVETABLE_LENGTH<<20)/(float)44100.0); 16 | } 17 | 18 | this->equations = equations; 19 | 20 | // Initialize all inputs 21 | this->frequency_input = NULL; 22 | this->equation_input = NULL; 23 | } 24 | 25 | uint32_t ModuleWavetable::compute() 26 | { 27 | // Read the frequency 28 | uint32_t frequency = this->readInput(frequency_input, CONVERT_TO_10_BIT); 29 | 30 | // Select equation 31 | int equation = this->readInput(equation_input, 0, NUMBER_OF_WAVETABLE_EQUATIONS); 32 | 33 | // Calculate the index into the wavetable 34 | fixed_point_10_22_index += increments[((frequency*60)>>10) + 24]; 35 | 36 | // If at the end of the wavetable 37 | if(fixed_point_10_22_index > (WAVETABLE_LENGTH << 22)) 38 | { 39 | // Set the index back to the start 40 | fixed_point_10_22_index -= (WAVETABLE_LENGTH << 22); 41 | } 42 | 43 | uint32_t t = (fixed_point_10_22_index >> 22); 44 | 45 | // Play the selected equation 46 | return(this->equations->compute(equation, t)); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /experimental/ModuleWavetable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * +----------------------+ 3 | * | ModuleWavetable | 4 | * |----------------------| 5 | * > frequency_input | 6 | * > wavetable_input | 7 | * | output > 8 | * +----------------------+ 9 | * 10 | */ 11 | // ============================================================================= 12 | // 13 | // ModuleWavetable is pseudo-wavetable generator. Instead of using actual 14 | // wavetables, it outputs audio using bytebeat equations that mimic wavetables. 15 | // 16 | // Example usage: 17 | // 18 | // ModuleWavetable *wavetable = new ModuleWavetable(equations); 19 | // 20 | // wavetable->equation_input = inputs->mod; 21 | // wavetable->frequency_input = inputs->sr; 22 | // 23 | // this->last_module = wavetable; 24 | // 25 | 26 | #ifndef ModuleWavetable_h 27 | #define ModuleWavetable_h 28 | 29 | #include "Arduino.h" 30 | #include "Module.h" 31 | #include "EquationsWavetable.h" 32 | 33 | class ModuleWavetable : public Module 34 | { 35 | 36 | public: 37 | ModuleWavetable(EquationsWavetable *equations); 38 | uint32_t compute(); 39 | 40 | // Inputs 41 | Module *frequency_input; 42 | Module *equation_input; 43 | 44 | private: 45 | uint32_t increments[128]; 46 | EquationsWavetable *equations; 47 | 48 | // 10.22 fixed point number (using the upper 10 bits for addressing the indexes 49 | // up to 1024 (we only need 600), and an additional 22 bits (0-4194304) for simulating fractional values for 50 | // use when incrementing the variable fractional values 51 | uint32_t fixed_point_10_22_index; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /experimental/ModuleWords.h: -------------------------------------------------------------------------------- 1 | #ifndef ModuleWords_h 2 | #define ModuleWords_h 3 | 4 | #include "Module.h" 5 | 6 | #if defined(__SAM3X8E__) 7 | #define PROGMEM 8 | #define pgm_read_byte(x) (*((char *)x)) 9 | #define pgm_read_word(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) 10 | #define pgm_read_byte_near(x) (*((char *)x)) 11 | #define pgm_read_byte_far(x) (*((char *)x)) 12 | #define pgm_read_word_near(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) 13 | #define pgm_read_word_far(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x)))) 14 | #define PSTR(x) x 15 | #if defined F 16 | #undef F 17 | #endif 18 | #define F(X) (X) 19 | #endif 20 | 21 | #define FORMANT_SZ 7 22 | 23 | 24 | class ModuleWords : public Module 25 | { 26 | public: 27 | ModuleWords(); 28 | uint32_t compute(); 29 | 30 | // Inputs 31 | Module *sound_input; 32 | Module *param1_input; 33 | Module *param2_input; 34 | Module *param3_input; 35 | Module *pitch_input; 36 | 37 | private: 38 | 39 | uint32_t output; 40 | 41 | uint16_t pitchPhase, form1Phase,form2Phase,form3Phase; 42 | uint16_t pitchPhaseInc,form1PhaseInc,form2PhaseInc,form3PhaseInc; 43 | uint8_t form1Amp,form2Amp,form3Amp; 44 | uint8_t noiseMod; 45 | 46 | int8_t sinCalc[256]; 47 | int8_t sqrCalc[256]; 48 | uint8_t formantTable[546]; 49 | uint16_t pitchTable[64]; 50 | int8_t word[72]; 51 | int frameTime; 52 | uint16_t basePitch; 53 | int formantScale; 54 | 55 | int8_t noise; 56 | }; 57 | 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /experimental/SynthArp1.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthArp1.h" 2 | 3 | SynthArp1::SynthArp1(Inputs* inputs) 4 | { 5 | ModuleArpeggio *arp = new ModuleArpeggio(); 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | 8 | arp->clock_input = inputs->gate; 9 | arp->root_note_input = inputs->sr; 10 | arp->pattern_input = inputs->param1; 11 | 12 | wavetable_osc->frequency_input = arp; 13 | wavetable_osc->wavetable_input = inputs->param2; 14 | 15 | this->last_module = wavetable_osc; 16 | } 17 | -------------------------------------------------------------------------------- /experimental/SynthArp1.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthArppegiator 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Plays arppegiating notes based on an internal clock which is 8 | // modulated by an LFO. The wavetable used for playback is also modulated 9 | // at the rate of the clock output. 10 | // 11 | // SR - selects the root note 12 | // MOD - 13 | // [1] - selects the arpeggiation pattern 14 | // [2] - controls the speed of the LFO 15 | // [3] - 16 | // GATE - 17 | // 18 | // ============================================================================= 19 | 20 | #ifndef SynthArp1_h 21 | #define SynthArp1_h 22 | 23 | #include "Synth.h" 24 | 25 | class SynthArp1 : public Synth 26 | { 27 | public: 28 | SynthArp1(Inputs *inputs); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /experimental/SynthAudioMath.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthAudioMath.h" 2 | 3 | SynthAudioMath::SynthAudioMath(Inputs *inputs, Equations *equations) 4 | { 5 | ModuleAudioEFX *audio_efx = new ModuleAudioEFX(equations); 6 | 7 | audio_efx->equation_input = inputs->mod; 8 | audio_efx->audio_input = inputs->sr; 9 | audio_efx->param1_input = inputs->param1; 10 | audio_efx->param2_input = inputs->param2; 11 | audio_efx->param3_input = inputs->param3; 12 | audio_efx->reset_input = inputs->gate; 13 | 14 | this->last_module = audio_efx; 15 | } -------------------------------------------------------------------------------- /experimental/SynthAudioMath.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthEquationLooper 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: Routes audio into equations, where the audio replaces the usual 8 | // 't' incrementing variable. This was an experiment to see if the equations 9 | // could act as effects units for the audio. On some patches you could hear 10 | // the audio, but it was extrordinarily distorted. Running waveforms into 11 | // the audio input also didn't sound good. I'm moving this module into the 12 | // 'experimental' folder. 13 | // 14 | // SR - plug an audio signal into the SR inputs 15 | // MOD - selects equation to playback 16 | // [1] - modifies the equation parameter p1 17 | // [2] - modifies the equation parameter p2 18 | // [3] - modifies the equation parameter p3 19 | // 20 | // ============================================================================= 21 | 22 | #ifndef SynthAudioMath_h 23 | #define SynthAudioMath_h 24 | 25 | #include "Synth.h" 26 | 27 | class SynthAudioMath : public Synth 28 | { 29 | public: 30 | SynthAudioMath(Inputs *inputs, Equations *equations); 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /experimental/SynthChatterbox.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "SynthChatterbox.h" 4 | 5 | SynthChatterbox::SynthChatterbox(Module* inputs[]) 6 | { 7 | ModuleChatBot *chat_bot = new ModuleChatBot(); 8 | 9 | chat_bot->word_input = inputs[PARAM1_INPUT]; 10 | chat_bot->formant_scale_input = inputs[PARAM2_INPUT]; 11 | chat_bot->pitch_input = inputs[SR_INPUT]; 12 | chat_bot->trigger_input = inputs[RESET_INPUT]; 13 | 14 | this->last_module = chat_bot; 15 | } 16 | -------------------------------------------------------------------------------- /experimental/SynthChatterbox.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthChatterbox_h 2 | #define SynthChatterbox_h 3 | 4 | #include "Arduino.h" 5 | #include "Synth.h" 6 | 7 | class SynthChatterbox : public Synth 8 | { 9 | public: 10 | 11 | SynthChatterbox(Module *inputs[]); 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /experimental/SynthDCOffsetTest.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "defines.h" 3 | #include "SynthDCOffsetTest.h" 4 | 5 | SynthDCOffsetTest::SynthDCOffsetTest(Module* inputs[]) 6 | { 7 | ModuleArpeggio *arpeggio = new ModuleArpeggio(); 8 | arpeggio->root_note_input = new ModuleConstant(20); 9 | arpeggio->pattern_input = new ModuleConstant(4); 10 | arpeggio->clock_input = new ModuleClock(10,8); 11 | 12 | this->last_module = arpeggio; 13 | } -------------------------------------------------------------------------------- /experimental/SynthDCOffsetTest.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthDCOffsetTest_h 2 | #define SynthDCOffsetTest_h 3 | 4 | #include "Arduino.h" 5 | #include "Synth.h" 6 | 7 | class SynthDCOffsetTest : public Synth 8 | { 9 | public: 10 | SynthDCOffsetTest(Module *inputs[]); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /experimental/SynthEqWave.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthEqWave.h" 2 | 3 | SynthEqWave::SynthEqWave(Inputs *inputs, Equations *equations) 4 | { 5 | ModuleEqWaveOsc *equation_wave_osc = new ModuleEqWaveOsc(equations); 6 | 7 | equation_wave_osc->equation_input = inputs->mod; 8 | equation_wave_osc->frequency_input = inputs->sr; 9 | equation_wave_osc->offset_input = inputs->param1; 10 | equation_wave_osc->x_input = inputs->param2; 11 | equation_wave_osc->y_input = inputs->param3; 12 | 13 | this->last_module = equation_wave_osc; 14 | } 15 | -------------------------------------------------------------------------------- /experimental/SynthEqWave.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthEqWave 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: A wavetable synth, where the wavetables are small slices of 8 | // bytebeat equations. 9 | // 10 | // SR - controls the sample rate of the wavetable playback 11 | // MOD - selects equation to playback 12 | // [1] - sets the position in the equation where the wavetable begins 13 | // [2] - modifies the equation parameter p1, which variates the sound 14 | // [3] - modifies the equation parameter p2, which variates the sound 15 | // GATE - no function (yet) 16 | // 17 | // ============================================================================= 18 | 19 | #ifndef SynthEqWave_h 20 | #define SynthEqWave_h 21 | 22 | #include "Synth.h" 23 | 24 | class SynthEqWave : public Synth 25 | { 26 | public: 27 | SynthEqWave(Inputs *inputs, Equations *equations); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /experimental/SynthMumbler.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthMumbler.h" 2 | 3 | SynthMumbler::SynthMumbler(Inputs *inputs) 4 | { 5 | ModuleSpeechSound *speech_sound = new ModuleSpeechSound(); 6 | 7 | speech_sound->pitch_input = inputs->sr; 8 | speech_sound->sound_input = inputs->mod; 9 | speech_sound->formant_scale_input = inputs->param2; 10 | 11 | this->last_module = speech_sound; 12 | } 13 | -------------------------------------------------------------------------------- /experimental/SynthMumbler.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthMumbler_h 2 | #define SynthMumbler_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthMumbler : public Synth 7 | { 8 | public: 9 | SynthMumbler(Inputs *inputs); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /experimental/SynthPassthroughTest.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthPassthroughTest.h" 2 | 3 | SynthPassthroughTest::SynthPassthroughTest(Inputs* inputs) 4 | { 5 | this->last_module = inputs->mod; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /experimental/SynthPassthroughTest.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthPassthroughTest_h 2 | #define SynthPassthroughTest_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthPassthroughTest : public Synth 7 | { 8 | public: 9 | SynthPassthroughTest(Inputs *inputs); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /experimental/SynthPatternsFX.h: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // 3 | // Name: SynthPatternsFX 4 | // Type: Audio 5 | // Written by: Bret Truchan, 2014 6 | // 7 | // Description: 8 | // 9 | // SR - delay effects mix 10 | // MOD - wavetable selecation 11 | // [1] - CV Pattern Select 12 | // [2] - Gate Pattern Select 13 | // [3] - Gate Density 14 | // GATE - (optional) clock control 15 | // 16 | // ============================================================================= 17 | 18 | #ifndef SynthPatternsFX_h 19 | #define SynthPatternsFX_h 20 | 21 | #include "Synth.h" 22 | 23 | class SynthPatternsFX : public Synth 24 | { 25 | public: 26 | SynthPatternsFX(Inputs *inputs); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /experimental/SynthPhonetics.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthPhonetics.h" 2 | 3 | SynthPhonetics::SynthPhonetics(Inputs *inputs) 4 | { 5 | ModuleVocalizer *vocalizer = new ModuleVocalizer(); 6 | 7 | vocalizer->pitch_input = inputs->sr; 8 | vocalizer->formant_scale_input = inputs->mod; 9 | vocalizer->param1_input = inputs->param1; 10 | vocalizer->param2_input = inputs->param2; 11 | vocalizer->param3_input = inputs->param3; 12 | 13 | this->last_module = vocalizer; 14 | } -------------------------------------------------------------------------------- /experimental/SynthPhonetics.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthPhonetics_h 2 | #define SynthPhonetics_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthPhonetics : public Synth 7 | { 8 | public: 9 | SynthPhonetics(Inputs *inputs); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /experimental/SynthSoundToy.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthSoundToy.h" 2 | 3 | SynthSoundToy::SynthSoundToy(Inputs* inputs) 4 | { 5 | ModuleSoundToy *sound_toy = new ModuleSoundToy(); 6 | 7 | sound_toy->sound_input = inputs->mod; 8 | sound_toy->frequency_input = inputs->sr; 9 | sound_toy->trigger_input = inputs->gate; 10 | 11 | this->last_module = sound_toy; 12 | } 13 | -------------------------------------------------------------------------------- /experimental/SynthSoundToy.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthSoundToy_h 2 | #define SynthSoundToy_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthSoundToy : public Synth 7 | { 8 | public: 9 | SynthSoundToy(Inputs *inputs); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /experimental/SynthTutorial14.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthTutorial14.h" 2 | 3 | SynthTutorial14::SynthTutorial14(Inputs* inputs) 4 | { 5 | // Create the modules/macros 6 | ModuleWavetableOsc *wavetable_osc = new ModuleWavetableOsc(); 7 | MacroGatedLPF *macro_gated_lpf = new MacroGatedLPF(); 8 | 9 | // Patch up ocillator 10 | wavetable_osc->frequency_input = inputs->sr; 11 | wavetable_osc->wavetable_input = inputs->mod; 12 | 13 | // Patch up macro for a gated Lowpass Filter 14 | macro_gated_lpf->envelope_generator->trigger_input = inputs->gate; 15 | macro_gated_lpf->lowpass_filter->audio_input = wavetable_osc; 16 | 17 | this->last_module = macro_gated_lpf; 18 | } -------------------------------------------------------------------------------- /experimental/SynthTutorial14.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthTutorial14_h 2 | #define SynthTutorial14_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthTutorial14 : public Synth 7 | { 8 | public: 9 | SynthTutorial14(Inputs *inputs); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /experimental/SynthVerbalizer.cpp: -------------------------------------------------------------------------------- 1 | #include "SynthVerbalizer.h" 2 | 3 | SynthVerbalizer::SynthVerbalizer(Inputs *inputs) 4 | { 5 | ModuleWords *words = new ModuleWords(); 6 | 7 | words->sound_input = inputs->mod; 8 | words->param1_input = inputs->param1; 9 | words->param2_input = inputs->param2; 10 | words->param3_input = inputs->param3; 11 | words->pitch_input = inputs->sr; 12 | 13 | this->last_module = words; 14 | } -------------------------------------------------------------------------------- /experimental/SynthVerbalizer.h: -------------------------------------------------------------------------------- 1 | #ifndef SynthVerbalizer_h 2 | #define SynthVerbalizer_h 3 | 4 | #include "Synth.h" 5 | 6 | class SynthVerbalizer : public Synth 7 | { 8 | public: 9 | SynthVerbalizer(Inputs *inputs); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /old/Equations.h: -------------------------------------------------------------------------------- 1 | #ifndef Equations_h 2 | #define Equations_h 3 | 4 | #include "Arduino.h" 5 | #include "Module.h" 6 | #include "FixedPointMath.h" 7 | 8 | class Equations 9 | { 10 | public: 11 | Equations(); // Constructor 12 | 13 | uint32_t compute(int equation_number, uint32_t t, uint32_t p1, uint32_t p2, uint32_t p3); 14 | 15 | FixedPointMath fixed_point_math; 16 | 17 | private: 18 | int value; 19 | uint32_t p; // Temporary variable for use in equations 20 | uint32_t q; // Temporary variable for use in equations 21 | uint16_t w; // The final output of the equation 22 | 23 | uint32_t p1; // parameters used in equations to modify the soudn 24 | uint32_t p2; 25 | uint32_t p3; 26 | 27 | uint16_t Sine[1024]; 28 | uint16_t Exp[4095]; 29 | 30 | }; 31 | 32 | #endif --------------------------------------------------------------------------------