
<<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)
{
switch(note){
case 0:
midiPlay = !midiPlay;
break;
case 1:
triggerNormal();
break;
}
}
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;
/*
int major[] =
{253, 238, 212, 189, 179, 159, 141, 126, 119, 106, 94, 89, 79, 70, 63, 59, 53, 47, 44, 39, 35, 31, 29, 26, 23};
byte major[2][26] = {
{239, 213, 190, 160, 142, 127, 120, 107, 95, 89, 80, 71, 64, 60, 53, 47, 45, 40, 36, 32, 32, 30, 27, 24, 22, 20}, //C major
{213, 190, 169, 160, 142, 127, 113, 107, 95, 84, 80, 71, 64, 56, 53, 47, 42, 40, 36, 32, 28, 27, 24, 21, 22, 20} //D major
};
*/
byte major[3][25] = {
//{239, 213, 190, 160, 142, 127, 120, 107, 95, 89, 80, 71, 64, 60, 53, 47, 45, 40, 36, 32, 32, 30, 27, 24, 22}, //C major
{ 0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 35, 36, 38, 40, 41, 43}, //C major
//{213, 190, 169, 160, 142, 127, 113, 107, 95, 84, 80, 71, 64, 56, 53, 47, 42, 40, 36, 32, 28, 27, 24, 21, 22}, //D major
{ 2, 4, 6, 7, 9, 11, 14, 16, 18, 19, 21, 23, 26, 28, 30, 31, 33, 36, 39, 41, 43, 44, 46, 48, 48}, //D major
//{226, 201, 190, 169, 150, 134, 127, 113,100, 95, 84, 75, 67, 64, 56, 50, 47, 42, 38, 34, 32, 28, 25, 24, 21} //B major
{ 1, 3, 4, 6, 8, 10, 11, 13, 15, 16, 18, 20, 22, 23, 25, 27, 28, 30, 32, 33, 34, 35, 37, 38, 40} //B major
};
byte scale[49] = {
//0 1 2 3 4 5 6 7 8 9 10 11
239, 226, 213, 201, 190, 179, 169, 160, 150, 142, 134, 127,
//12 13 14 15 16 17 18 19 20 21 22 23
120, 113, 107, 100, 95, 89, 84, 80, 75, 71, 67, 64,
//24 25 26 27 28 29 30 31 32 33 34 35
60, 56, 53, 50, 47, 45, 42, 40, 38, 36, 34, 32,
//36 37 38 39 40 41 42 43 44 45 46 47
30, 28, 27, 25, 24, 22, 21, 19, 18, 17, 16, 16,
//48
15
};
//if OCR0A == 255
//6: c=15
//5: b=16 a#=17 a=18 g#=19 g=20 f#=21 f=22 e=24 d#=25 d=27 c#=28 c=30
//4: b=32 a#=34 a=36 g#=38 g=40 f#=42 f=45 e=47 d#=50 d=53 c#=56 c=60
//3: b=64 a#=67 a=71 g#=75 g=80 f#=84 f=89 e=95 d#=100 d=107 c#=113 c=120
//2: b=127 a#=134 a=142 g#=150 g=160 f#=169 f=179 e=190 d#=201 d=213 c#=226 c=239
byte ti = 0;
int out = 0;
volatile boolean inLoop = false;
byte sampleRate = 255;
void setup(){
//TIMER SETUP
cli();
TCCR1B = TCCR1B & B11111000 | B00000001;
TCCR2B = TCCR2B & B11111000 | B00000001;
//also check the datasheet!
TCCR0A = TCCR0A & B11111000 | B00000010;
TCCR0B = TCCR0B & B11111000 | B00000010;
TIMSK0 = TIMSK0 & B11111000 | B00000010; //Call ISR
//set sample rate/frequency
OCR0A = sampleRate;
pinMode(8, INPUT);
digitalWrite(8, HIGH);
delay(100);
typeSwitch = !digitalRead(8);
if(typeSwitch){
setupPWM(3);
}else{
setupPWM(0);
}
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, INPUT);
digitalWrite(12, HIGH);
pinMode(13, OUTPUT);
pinMode(3, OUTPUT);
readAnalogs();
pinMode(2, INPUT);
pinMode(3, INPUT);
//digitalWrite(2, HIGH);
//set to CHANGE to patch signal direct thrue..
//attachInterrupt(0, triggerOut, CHANGE);
//attachInterrupt(1, triggerOut, CHANGE);
attachInterrupt(0, triggerNormal, FALLING);
attachInterrupt(1, triggerOutB, FALLING);
midi.begin(1);
}
ISR(TIMER0_COMPA_vect) {
teknoI0();
}
void loop(){
midi.poll();
readAnalogs();
teknoL0();
}
inline void teknoI0(){
//techno
OCR0A = 255;
oscB = cup(oscB, ((1023-pot[4])<<1)+500);
if(!oscB && !externalTrigger || triggerActive){
triggerActive = false;
IRsync();
ta = true;
}
oscD2 = cup(oscD2, 3);//pot[2]>>5);
if(!oscD2){
//legato
if(tp < (scale[oscA2])){
tp++;
}else if(tp > (scale[oscA2])){
tp--;
}
}
//oscillators timer
oscA = cup(oscA, (tp ));
//decay
tvolb1++;
if(tvolb1 > pot[1]>>2 && tvolb2 > 0){
tvolb1 = 0;
tvolb2--;
}
//saw to square so volume stays sort of the same..
out = constrain((oscA<<1), 0, tvolb2);
audioOut(out);
}
inline void teknoL0(){
//nothing needed here (-:
byte visuals = (min(out << 3, 255));
analogWrite(5, visuals);
analogWrite(10, visuals);
setupPWM(3);
if(ta){
ta = false;
//selectpotmeter for next pitch
seqCount++;
seqCount %= ((pot[3]) >> 4)+1;
if(audioTrigger){
audioTrigger = false;
seqCount = 0;
}
if(!seqCount){
bank = 3*(pot[5]>>8);
}
static byte record;
byte bigBut = digitalRead(8);
byte smallBut = digitalRead(12);
if(!bigBut && smallBut){//record pitch
byte scaleSelect = pot[2] >> 8;
if(scaleSelect < 3){
byte selectedscale = map(pot[0] >> 2, 0, 255, 0, 22);
pitch = major[scaleSelect][selectedscale];//map(pot[0], 0, 1023, 0, 48);
}else{
pitch = map(pot[0] >> 2, 0, 255, 0, 48);
}
//record pitch
seqPitches[bank][seqCount] = pitch;
//record trigger for fade
seqPitches[bank+2][seqCount] = record;
record = false;
}else if(!bigBut && !smallBut){//record filter
seqPitches[bank+1][seqCount] = pot[0]>>2;
}else{
record = true;
}
static byte prevbank = 100;//random default value
if(bank != prevbank){
if(!smallBut){
for(byte i=0; i<64; i++){
seqPitches[bank][i] = seqPitches[prevbank][i];
seqPitches[bank+1][i] = seqPitches[prevbank+1][i];
seqPitches[bank+2][i] = seqPitches[prevbank+2][i];
}
}
prevbank = bank;
}
//send next pitch to ISR.
oscA2 = seqPitches[bank][seqCount];
//set filter
analogWrite(11, seqPitches[bank+1][seqCount]);
//reset to start volume.
//tvol = 70;
if(seqPitches[bank+2][seqCount]){
tvolb1 = 0;
tvolb2 = 120;
}
}
}
/////////
//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);
}
//setup PWMs: https://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559
void setupPWM(byte inp){
static byte prevstate = 255;
if(inp != prevstate){
prevstate = inp;
if(inp == 0){
cli();
TCCR0B = TCCR0B & 0b11111000 | 0x03;
sei();
}
else if(inp == 1){
cli();
TCCR0B = TCCR0B & 0b11111000 | 0x01;
sei();
}
else if(inp == 2){
cli();
TCCR0B = TCCR0B & 0b11111000 | 0x02;
sei();
}else if(inp == 3){
cli();
//also check the datasheet!
TCCR0A = TCCR0A & B11111000 | B00000010;
TCCR0B = TCCR0B & B11111000 | B00000010;
TIMSK0 = TIMSK0 & B11111000 | B00000010; //Call ISR
//set sample rate/frequency
OCR0A = 255;
sei();
}
}
}