added WIP Acid
This commit is contained in:
238
Acid/Acid.ino
Normal file
238
Acid/Acid.ino
Normal file
@ -0,0 +1,238 @@
|
||||
// Acid synth firmware for Sitka Instruments WS-1.0
|
||||
// by Oleksiy Hrachov
|
||||
//
|
||||
// Although the code designed to work on Sitka Instruments WS-1.0 synth, it should
|
||||
// be pretty easy to adapt to run on other arduino/mozzi-based setups
|
||||
//
|
||||
// This code is licenced under GPL v3 or later
|
||||
|
||||
#include <Mozzi.h>
|
||||
#include <MIDI.h>
|
||||
#include <Oscil.h>
|
||||
#include <MetaOscil.h>
|
||||
#include <StateVariable.h>
|
||||
#include <ADSR.h>
|
||||
#include <mozzi_midi.h>
|
||||
#include <IntMap.h>
|
||||
#include <FixMath.h>
|
||||
#include "config.h"
|
||||
|
||||
//Band limited SQUARE oscilator tables
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_90_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_101_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_122_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_138_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_154_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_174_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_210_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_264_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_327_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_431_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_546_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_744_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_910_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_1170_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_1638_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_2730_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SQUARE/512/square_max_8192_at_16384_512_int8.h>
|
||||
Oscil <SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq90(SQUARE_MAX_90_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_101_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq101(SQUARE_MAX_101_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_122_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq122(SQUARE_MAX_122_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_138_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq138(SQUARE_MAX_138_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_154_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq154(SQUARE_MAX_154_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_174_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq174(SQUARE_MAX_174_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_210_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq210(SQUARE_MAX_210_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_264_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq264(SQUARE_MAX_264_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_327_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq327(SQUARE_MAX_327_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_431_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq431(SQUARE_MAX_431_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_546_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq546(SQUARE_MAX_546_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_744_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq744(SQUARE_MAX_744_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_910_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq910(SQUARE_MAX_910_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_1170_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1170(SQUARE_MAX_1170_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_1638_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq1638(SQUARE_MAX_1638_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_2730_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq2730(SQUARE_MAX_2730_AT_16384_512_DATA);
|
||||
Oscil <SQUARE_MAX_8192_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSq8192(SQUARE_MAX_8192_AT_16384_512_DATA);
|
||||
MetaOscil<SQUARE_MAX_90_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE, 16> aSquare {&aSq90, &aSq101, &aSq122, &aSq138, &aSq154, &aSq174, &aSq210, &aSq264, &aSq327, &aSq431, &aSq546, &aSq744, &aSq1170, &aSq1638, &aSq2730, &aSq8192};
|
||||
|
||||
//Band limited SAW oscilator tables
|
||||
#include <tables/BandLimited_SAW/512/saw_max_138_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_154_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_182_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_240_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_292_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_341_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_390_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_431_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_512_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_630_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_744_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_910_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_1170_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_1638_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_2730_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_4096_at_16384_512_int8.h>
|
||||
#include <tables/BandLimited_SAW/512/saw_max_8192_at_16384_512_int8.h>
|
||||
Oscil <SAW_MAX_138_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw138(SAW_MAX_138_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_154_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw154(SAW_MAX_154_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_182_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw182(SAW_MAX_182_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_240_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw240(SAW_MAX_240_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_292_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw292(SAW_MAX_292_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_341_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw341(SAW_MAX_341_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_390_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw390(SAW_MAX_390_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_431_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw431(SAW_MAX_431_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_512_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw512(SAW_MAX_512_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_630_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw630(SAW_MAX_630_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_744_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw744(SAW_MAX_744_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_910_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw910(SAW_MAX_910_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_1170_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw1170(SAW_MAX_1170_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_1638_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw1638(SAW_MAX_1638_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_2730_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw2730(SAW_MAX_2730_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_4096_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw4096(SAW_MAX_4096_AT_16384_512_DATA);
|
||||
Oscil <SAW_MAX_8192_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE> aSaw8192(SAW_MAX_8192_AT_16384_512_DATA);
|
||||
MetaOscil<SAW_MAX_138_AT_16384_512_NUM_CELLS, MOZZI_AUDIO_RATE, 16> aSaw {&aSaw138, &aSaw154, &aSaw182, &aSaw240, &aSaw292, &aSaw341, &aSaw390, &aSaw431, &aSaw512, &aSaw630, &aSaw744, &aSaw1170, &aSaw1638, &aSaw2730, &aSaw4096, &aSaw8192};
|
||||
|
||||
IntMap kMapNote( 0, 4095, 24 * pitchSubSteps, 84 * pitchSubSteps );
|
||||
IntMap kMapLFOSpeed( 0, 1023, 500, 20000 );
|
||||
IntMap kMapFreqMod( 0, 1023, 0, 1023 );
|
||||
IntMap kMapResonance( 0, 1023, 200, 1 );
|
||||
IntMap kMapCutoff( 0, 1023, 60, 3600 );
|
||||
IntMap kMapAttack( 0, 1023, 0, 80 );
|
||||
IntMap kMapDecayRelease( 0, 1023, 8, 160 );
|
||||
IntMap kMapSustain( 0, 1023, 0, 255 );
|
||||
|
||||
ADSR <MOZZI_CONTROL_RATE, MOZZI_CONTROL_RATE> envelope;
|
||||
StateVariable <LOWPASS> lpf;
|
||||
|
||||
//Global variables
|
||||
byte gain;
|
||||
bool MIDINotePlaying;
|
||||
bool gateIsHigh = false;
|
||||
float noteFreq;
|
||||
bool envSwitchVal;
|
||||
|
||||
void MIDINoteOn(byte channel, byte note, byte velocity) {
|
||||
noteFreq = mtof((int) note);
|
||||
envelope.noteOn();
|
||||
MIDINotePlaying = true;
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
|
||||
void MIDINoteOff(byte channel, byte note, byte velocity) {
|
||||
envelope.noteOff();
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
|
||||
long softClip(long input) {
|
||||
int threshold = 2048;
|
||||
if (input < -threshold) {
|
||||
return -threshold + (input + threshold) / 4;
|
||||
} else if (input > threshold) {
|
||||
return threshold + (input - threshold) / 4;
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
void setup(){
|
||||
pinMode(LED, OUTPUT);
|
||||
pinMode(GateIn, INPUT_PULLUP);
|
||||
pinMode(EnvSwitch, INPUT_PULLUP);
|
||||
pinMode(DroneSwitch, INPUT_PULLUP);
|
||||
|
||||
MIDI.setHandleNoteOn(MIDINoteOn);
|
||||
MIDI.setHandleNoteOff(MIDINoteOff);
|
||||
MIDI.begin(MIDI_CHANNEL);
|
||||
|
||||
aSquare.setCutoffFreqs(90, 101, 122, 138, 154, 174, 210, 264, 327, 431, 546, 744, 1170, 1638, 2730, 8192);
|
||||
aSaw.setCutoffFreqs(138, 154, 182, 240, 292, 341, 390, 431, 512, 630, 744, 1170, 1638, 2730, 4096, 8192);
|
||||
|
||||
startMozzi();
|
||||
|
||||
envelope.setAttackLevel(255);
|
||||
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
|
||||
void updateControl(){
|
||||
|
||||
for(int i=0; i<10; i++) { // Hacky way to drain the buffer faster
|
||||
MIDI.read();
|
||||
}
|
||||
|
||||
//Get Control Values
|
||||
int knob1Val = mozziAnalogRead(Knob1);
|
||||
int knob2Val = mozziAnalogRead(Knob2);
|
||||
int knob3Val = mozziAnalogRead(Knob3);
|
||||
int knob4Val = mozziAnalogRead(Knob4);
|
||||
int knobAVal = mozziAnalogRead(KnobA);
|
||||
int knobDRVal = mozziAnalogRead(KnobDR);
|
||||
int knobSVal = mozziAnalogRead(KnobS);
|
||||
bool droneSwitchVal = digitalRead(DroneSwitch);
|
||||
envSwitchVal = digitalRead(EnvSwitch);
|
||||
bool gateInVal = !digitalRead(GateIn);
|
||||
int CVInVal = mozziAnalogRead(CVIn);
|
||||
|
||||
//Remap the values and assign to parameter
|
||||
int resonance = kMapResonance(knob3Val);
|
||||
int cutoff = kMapCutoff(knob4Val);
|
||||
|
||||
//Set pitch and play notes on trigger
|
||||
if (!MIDINotePlaying) {
|
||||
noteFreq = mtof((float) kMapNote(CVInVal << 2) / pitchSubSteps);
|
||||
digitalWrite(LED, !gateInVal);
|
||||
if (gateInVal && !gateIsHigh) {
|
||||
gateIsHigh = true;
|
||||
envelope.noteOn();
|
||||
} else if (!gateInVal && gateIsHigh) {
|
||||
gateIsHigh = false;
|
||||
envelope.noteOff();
|
||||
}
|
||||
} else if (MIDINotePlaying && !envelope.playing()) {
|
||||
MIDINotePlaying = false;
|
||||
}
|
||||
|
||||
//Update Filter settings
|
||||
lpf.setResonance(resonance);
|
||||
//lpf.setCentreFreq(cutoff);
|
||||
|
||||
//Update Envelope Settings
|
||||
int attackTime = kMapAttack(knobAVal);
|
||||
int decayReleaseTime = kMapDecayRelease(knobDRVal);
|
||||
int sustainLevel = kMapSustain(knobSVal);
|
||||
envelope.setDecayLevel(sustainLevel);
|
||||
envelope.setTimes(attackTime, decayReleaseTime, 30000, decayReleaseTime); //30000 is so the note will sustain 30 seconds unless a noteOff comes
|
||||
|
||||
//Set Oscilator Frequency
|
||||
float oscFreq = noteFreq;
|
||||
aSquare.setFreq(oscFreq);
|
||||
aSaw.setFreq(oscFreq);
|
||||
|
||||
envelope.update();
|
||||
|
||||
int env = envelope.next();
|
||||
|
||||
if(!droneSwitchVal) {
|
||||
gain = env;
|
||||
} else {
|
||||
gain = 255;
|
||||
}
|
||||
lpf.setCentreFreq(60 + env * 14);
|
||||
|
||||
}
|
||||
|
||||
AudioOutput updateAudio(){
|
||||
long signal;
|
||||
if(envSwitchVal) {
|
||||
signal = aSquare.next() * 0.3;
|
||||
} else {
|
||||
signal = aSaw.next() * 1.2;
|
||||
}
|
||||
signal = lpf.next(signal); //filter
|
||||
signal = (signal * gain); //envelope
|
||||
//signal = softClip((signal * (127 + driveAmount)) >> 8); //overdrive
|
||||
return MonoOutput::fromNBit(17, signal).clip();
|
||||
}
|
||||
|
||||
void loop(){
|
||||
audioHook();
|
||||
}
|
||||
Reference in New Issue
Block a user