
<<3);
break;
case 21:
midibools[1] = true;
pot[1] = 1023-(value<<3);
break;
case 22:
midibools[2] = true;
pot[2] = 1023-(value<<3);
break;
case 23:
midibools[3] = true;
pot[3] = 1023-(value<<3);
break;
case 24:
midibools[4] = true;
pot[4] = 1023-(value<<3);
break;
case 25:
midibools[5] = true;
pot[5] = 1023-(value<<3);
break;
case 26:
pot[6] = 1023-(value<<3);
break;
}
}
void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity)
{
midiActive = true;
midiHandler(channel, note, true);
}
void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity)
{
midiHandler(channel, note, false);
}
void handleSync(){
if(midiPlay){
if(!midiCounter){
triggerActive = true;
}
midiCounter = cupb(midiCounter, 6);
}
}
void handleStop(){
midiPlay = false;
}
void handleStart(){
seqCount = 0; //reset sequencer so it starts at 0
oscD = 0; //reset sequencer so it starts at 0
midiCounter = 0;
midiPlay = true;
externalTrigger = true;
}
void handleContinue(){
midiCounter = 0;
midiPlay = true;
}
};
MyMidi midi(Serial);
byte midichannel = 1;
byte scaleSelect = 1;
boolean typeSwitch = 0;
//wave generator values
static int octaver = 0;
byte butSel = 0;
byte triggerDecay = 0;
float tvol = 0.5;
float tvol2 = 0;
float kick = 0;
byte tvolb1 = 0;
byte tvolb2 = 0;
int BA = 0;
int BB = 0;
int tp = 0;
boolean ta = LOW;
boolean tb = LOW;
boolean tc = LOW;
byte scale[33] = {
239, 226, 213, 201, 190, 179, 169, 160, 150, 142, 134, 126,
119, 112, 106, 100, 94, 89, 84, 79, 75, 71, 67, 63,
59, 56, 53, 50, 47, 44, 42, 39, 37
};
byte wave[256];
byte ti = 0;
int out = 0;
volatile boolean inLoop = false;
byte sampleRate = 255;
void setup(){
cli();
TCCR1B = TCCR1B & B11111000 | B00000001;
TCCR2A = TCCR2A & B11111000 | B00000010;
TCCR2B = TCCR2B & B11111000 | B00000010;
TIMSK2 = TIMSK2 & B11111000 | B00000010;
OCR2A = frequency;
sei();
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(8, INPUT);
digitalWrite(8, HIGH);
pinMode(12, INPUT);
digitalWrite(12, HIGH);
pinMode(13, OUTPUT);
pinMode(3, OUTPUT);
readAnalogs();
pinMode(2, INPUT);
pinMode(3, INPUT);
attachInterrupt(0, triggerNormal, FALLING);
attachInterrupt(1, triggerOutB, FALLING);
midi.begin(1);
}
ISR(TIMER2_COMPA_vect) {
oscA++;
if(oscA >= oscA2){oscA = 0;}
oscB++;
if(oscB >= oscB2){oscB = 0;}
oscF = cup(oscF, ((1023 - pot[3])<<3)+50);
if(!oscF && pot[3] > 10 && !externalTrigger || triggerActive){
triggerActive = false;
tc = !tc;
IRsync();
bitWrite(PORTB, 3, tc);
}
if(midiActive){
oscC2 = cup(oscC2, ((1023-pot[0])<<3)+10);
if(!oscC2){
//arpegio
for(byte i=0; i<24; i++){
if(audioTrigger){
audioTrigger = false;
activeCount = 0;
}
activeCount = cup(activeCount, 24);
//if active note is found use it and break.
if(activeNotes[activeCount] > 0){
frequency = activeNotes[activeCount];
break;
}
}
}
}
oscC = cup(oscC, ((1023-pot[4])>>1)+20);
if(!oscC){
oscD = cup(oscD, 255);
//select waveform to fill wavetable.
byte psel = pot[5] >> 6;
if(psel == 0){ //noise
wave[oscD] = min((byte) rand(), (pot[1]>>3));
}else{//triangle
if(tb){
oscE += psel+1;
if(oscE >= pot[1]>>2){
oscE = pot[1]>>2;
tb = false;
}
}else{
oscE -= psel+1;
if(oscE < 1){
oscE = 0;
tb = true;
}
}
wave[oscD] = oscE;
}
ta = true;
}
OCR2A = frequency;
analogWrite(9, wave[oscA]+wave[oscB]>>1);
}
void loop(){
midi.poll();
readAnalogs();
oscB2 = (1023-pot[2]) >> 2;
if(digitalRead(8) && !midiActive){
byte selNote = map((pot[0] >
3), 0, 127, 0, 24);
frequency = scale[selNote];
}else if(!digitalRead(8)){
midiDisable = true;
}else{
midiDisable = false;
}
if(!digitalRead(12)){
externalTrigger = false;
midiActive = false;
}
static byte oscZ;
oscZ = cup(oscZ, 255);
byte visuals = (min(wave[oscZ], 255));
digitalWrite(5, tb);
digitalWrite(6, tb);
digitalWrite(7, tb);
analogWrite(10, visuals);
}
/////////
//other//
/////////
//read pots, 1 at a time
inline void readAnalogs(){
static byte potc = 0;
potc = cup(potc, 6);
int av = analogRead(potc);
if(midibools[potc] == false){
//pot[potc] = analogRead(potc);
pot[potc] = av;
}
}
//send trigger
void trigger(byte inp){
volatile static int tCount = 0;
if(!externalTrigger){
tCount = cup(tCount, inp);
IRsync();
}
}
void triggerNormal(){
//set external trigger to true if there is a trigger signal..
externalTrigger = true;
//set trigger to active, see above
triggerActive = true;
}
void triggerOutB(){
audioTrigger = true;
}
void triggerOut(){
if(triggerSignal){
triggerNormal();
}
triggerSignal = !triggerSignal;
IRsync();
}
inline static int cup(int a, int b){
a++;
if(a >= b){
a = 0;
}
return a;
}
inline static byte cupb(byte a, byte b){
a++;
if(a >= b){
a = 0;
}
return a;
}
inline byte audioOut(byte signal){
if(butSelVolDel > 1){
butSelVolDel--;
analogWrite(9, constrain(signal>>(pot[6]>>7), 10, 170));
}else{
analogWrite(9, min(signal>>(pot[6]>>7), 220));
}
analogWrite(10, min(signal << 2, 255));
}
inline void audioOut2(){
if(butSelVolDel > 1){
butSelVolDel--;
analogWrite(9, constrain(out>>(pot[6]>>7), 10, 170));
}else{
analogWrite(9, min(out>>(pot[6]>>7), 220));
}
analogWrite(10, min(out << 2, 255));
}
void IRsync(){
static boolean irflip;
irflip = !irflip;
bitWrite(PORTB, 5, irflip);
bitWrite(PORTD, 4, irflip);
}
void midiHandler(byte channel, byte note, boolean onOff){
byte noteIn = note % 24;
//some keyboards don't send note off..
if(!onOff){
//scale over array, and reset note value.
if(!midiDisable){
activeNotes[noteIn] = 0;
}
}else{
//set emediatly so there are no missing notes when arp is slow
checkIfActiveNote(scale[noteIn]);
//scale over array, and set note value.
activeNotes[noteIn] = scale[noteIn];
}
}
void checkIfActiveNote(int input){
byte count = 0;
//check for active notes
for(byte i=0; i<25; i++){
if(activeNotes[i]){
count++;
}
}
//if little active notes are found set freq emediatly
if(count < 2){
frequency = input;
}
}