diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2016-05-06 13:54:04 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2016-05-06 13:54:04 +0300 |
| commit | 485b8a3386fda17a9afb707302810664ccb2409c (patch) | |
| tree | 33058b5f9e2dde0390e1fed2e602d15c3a32cb44 /arduino-monosynth.ino | |
| parent | f4abcb2f16855ec7717e8970e17605e7f3d7ce2b (diff) | |
Fix idle buzz and loud feedback after 1 minute
Diffstat (limited to 'arduino-monosynth.ino')
| -rw-r--r-- | arduino-monosynth.ino | 128 |
1 files changed, 93 insertions, 35 deletions
diff --git a/arduino-monosynth.ino b/arduino-monosynth.ino index 87f99a2..df36f5c 100644 --- a/arduino-monosynth.ino +++ b/arduino-monosynth.ino @@ -26,7 +26,9 @@ #include <ADSR.h> #include <mozzi_fixmath.h> #include <Portamento.h> -#include <tables/cos2048_int8.h> // table for Oscils to play +#include <tables/cos512_int8.h> // table for Oscils to play +#include <tables/square_analogue512_int8.h> +#include <tables/triangle_analogue512_int8.h> #include <tables/saw_analogue512_int8.h> // table for Oscils to play // use #define for CONTROL_RATE, not a constant @@ -35,12 +37,18 @@ // Mozzi example uses COS waves for carrier and modulator // Shit gets brutal very fast if you use a saw/square carrier // Shit gets subtly more brutal if you use smaller wavetables (fewer samples per cycle) -Oscil<SAW_ANALOGUE512_NUM_CELLS, AUDIO_RATE> oscCarrierMaster(SAW_ANALOGUE512_DATA); -Oscil<SAW_ANALOGUE512_NUM_CELLS, AUDIO_RATE> oscCarrierSlave1(SAW_ANALOGUE512_DATA); -Oscil<SAW_ANALOGUE512_NUM_CELLS, AUDIO_RATE> oscCarrierSlave2(SAW_ANALOGUE512_DATA); +Oscil<SAW_ANALOGUE512_NUM_CELLS, AUDIO_RATE> oscils[3] = + {(SAW_ANALOGUE512_DATA), (SAW_ANALOGUE512_DATA), (SAW_ANALOGUE512_DATA)}; -Oscil<COS2048_NUM_CELLS, AUDIO_RATE> oscModulator(COS2048_DATA); -Oscil<COS2048_NUM_CELLS, AUDIO_RATE> oscLFO(COS2048_DATA); +Oscil<COS512_NUM_CELLS, AUDIO_RATE> oscModulator(COS512_DATA); +Oscil<COS512_NUM_CELLS, AUDIO_RATE> oscLFO(COS512_DATA); + +enum TableType { + Cosine, + Square, + Saw, + Triangle +} currentTable; // envelope generator ADSR <CONTROL_RATE, AUDIO_RATE> envelope; @@ -49,6 +57,7 @@ Portamento <CONTROL_RATE>aPortamento; MIDI_CREATE_DEFAULT_INSTANCE(); #define LED 13 // to see if MIDI is being recieved +#define TABLE_TOGGLE 10 unsigned long vibrato = 0; float carrierFreq = 10.f; @@ -57,7 +66,11 @@ float modDepth = 0.5; float amplitude = 0.f; float modOffset = 1; byte lastnote = 0; -int portSpeed = 100; +//int portSpeed = 100; +byte detuneCents = 0; + +byte tableToggleTimer = 0; +byte tableToggleTimerMax = 1000; float detuneCoefficient1 = 1; float detuneCoefficient2 = 1; @@ -73,18 +86,19 @@ float modOffsets[] = { void setup() { pinMode(LED, OUTPUT); - + pinMode(TABLE_TOGGLE, INPUT); + MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.setHandleNoteOn(HandleNoteOn); MIDI.setHandleNoteOff(HandleNoteOff); MIDI.setHandleControlChange(HandleControlChange); MIDI.setHandlePitchBend(HandlePitchBend); - MIDI.setHandleProgramChange(HandleProgramChange); - MIDI.setHandleContinue(HandleContinue); + MIDI.setHandleProgramChange(HandleProgramChange); envelope.setADLevels(255, 174); - envelope.setTimes(10, 50, 50, 1000); // 20000 is so the note will sustain 20 seconds unless a noteOff comes - aPortamento.setTime(50u); + envelope.setTimes(188, 345, 65000000, 345); // 20000 is so the note will sustain 20 seconds unless a noteOff comes + envelope.setSustainLevel(255); + //aPortamento.setTime(50u); oscLFO.setFreq(10); // default frequency startMozzi(CONTROL_RATE); @@ -99,26 +113,15 @@ void HandleProgramChange (byte channel, byte number) void HandleNoteOn(byte channel, byte note, byte velocity) { - aPortamento.start((byte)(((int) note) - 5)); + //aPortamento.start((byte)(((int) note) - 5)); lastnote = note; envelope.noteOn(); - + oscLFO.setPhase(0); + oscModulator.setPhase(0); digitalWrite(LED, HIGH); } -void HandleContinue () -{ - portSpeed += 100; - - if (portSpeed > 500) - { - portSpeed = 0; - } - - aPortamento.setTime(portSpeed); -} - void HandleNoteOff(byte channel, byte note, byte velocity) { if (note == lastnote) @@ -132,6 +135,7 @@ void HandlePitchBend (byte channel, int bend) { float shifted = float ((bend + 8500) / 2048.f) + 0.1f; oscLFO.setFreq(shifted); + } void HandleControlChange (byte channel, byte number, byte value) @@ -151,21 +155,65 @@ void HandleControlChange (byte channel, byte number, byte value) } } +void readPotsAndUpdate() { + if (tableToggleTimer > tableToggleTimerMax) { + byte toggled = digitalRead(TABLE_TOGGLE); + digitalWrite(LED, toggled); + if (toggled) { + currentTable = (TableType)(((byte)currentTable + 1) % 4); + tableToggleTimer = 0; + } + } else { + tableToggleTimer++; + } + + /* + int pot0 = mozziAnalogRead(0); + if (currentTable != Cosine && pot0 < 256) { + oscCarrierMaster.setTable(COS512_DATA); + oscCarrierSlave1.setTable(COS512_DATA); + oscCarrierSlave2.setTable(COS512_DATA); + currentTable = Cosine; + } else if (currentTable != Saw && pot0 < 512) { + oscCarrierMaster.setTable(SAW_ANALOGUE512_DATA); + oscCarrierSlave1.setTable(SAW_ANALOGUE512_DATA); + oscCarrierSlave2.setTable(SAW_ANALOGUE512_DATA); + currentTable = Saw; + } else if (currentTable != Square && pot0 < 768) { + oscCarrierMaster.setTable(SQUARE_ANALOGUE512_DATA); + oscCarrierSlave1.setTable(SQUARE_ANALOGUE512_DATA); + oscCarrierSlave2.setTable(SQUARE_ANALOGUE512_DATA); + currentTable = Square; + } else if (currentTable != Triangle && pot0 <= 1024) { + oscCarrierMaster.setTable(TRIANGLE_ANALOGUE512_DATA); + oscCarrierSlave1.setTable(TRIANGLE_ANALOGUE512_DATA); + oscCarrierSlave2.setTable(TRIANGLE_ANALOGUE512_DATA); + currentTable = Triangle; + } + */ + int pot1 = mozziAnalogRead(1); + detuneCents = map(pot1, 0, 1024, 0, 100); +} + void updateControl() { MIDI.read(); envelope.update(); - carrierFreq = Q16n16_to_float (aPortamento.next()); //NB presumably returns frequency as Q16n16 + carrierFreq = mtof(lastnote); modFreq = carrierFreq * modOffset; - const unsigned short cents = 40; - detuneCoefficient1 = 1 + 0.0005946 * cents; - detuneCoefficient2 = 1 - 0.0005946 * cents; + // update oscil types + readPotsAndUpdate(); + + detuneCoefficient1 = 1 + 0.0005946 * detuneCents; + detuneCoefficient2 = 1 - 0.0005946 * detuneCents; + + // set carrier frequencies - oscCarrierMaster.setFreq(carrierFreq); - oscCarrierSlave1.setFreq(carrierFreq * detuneCoefficient1); - oscCarrierSlave2.setFreq(carrierFreq * detuneCoefficient2); + oscils[0].setFreq(carrierFreq); + oscils[1].setFreq(carrierFreq * detuneCoefficient1); + oscils[2].setFreq(carrierFreq * detuneCoefficient2); oscModulator.setFreq(modFreq); } @@ -174,8 +222,18 @@ int updateAudio() { vibrato = (unsigned long) (oscLFO.next() * oscModulator.next()) >> 7; vibrato *= (unsigned long) (carrierFreq * modDepth) >> 3; - int carrierSum = (oscCarrierMaster.phMod(vibrato) + oscCarrierSlave1.phMod(vibrato) + oscCarrierSlave2.phMod(vibrato)) >> 3; - return (int) (carrierSum * (envelope.next())) >> 8; + //int carrierSum = (oscCarrierMaster.phMod(vibrato) >> 3) + (oscCarrierSlave1.phMod(vibrato) >> 3) + (oscCarrierSlave2.phMod(vibrato) >> 3); + + int carrierSum = 0; + for (int i = 0; i < sizeof(oscils)/sizeof(oscils[0]); i++) { + carrierSum += (oscils[i].next() >> 3); + } + + int total = (carrierSum * (envelope.next() >> 1)) >> 8; + if (abs(total) < 5) + return 0; + else + return total; } void loop() |
