//HSS3S01V38 for use with HSS3a, HSS3b, HSS3c, HSS3d, HSS3f hardware.
//gijs gieskes 2009/2010, http://gieskes.nl
//credits: http://gieskes.nl/instruments/files/hard-soft-synth-3/hss3-credits.html
byte prevSynth = 100;
byte triggerDecay = 0;
byte sinAc = 0;
byte sinAc2 = 0;
float tvol = 0.5;
float tvol2 = 0;
float kick = 0;
int BA = 0;
int BB = 0;
int tp = 0;
//oscs
byte oscA = 0;
byte oscB = 0;
byte oscC = 0;
byte oscD = 0;
byte oscA2 = 0;
byte oscB2 = 0;
byte oscC2 = 0;
byte oscD2 = 0;
boolean ta = LOW;
boolean tb = LOW;
boolean tc = LOW;
boolean td = LOW;
boolean te = LOW;
int oscL[8] = {
264,264,264,264,264,264,264,264};
//noise synth waveform holder
byte oscN[8] = {
1,1,1,1,1,1,1,1};
unsigned long pitcha = 4;
boolean noisebool = false;
int c = 0;
unsigned long noiselong = 0;
//pot array
int pot[8] = {
0,0,0,0,0,0,0,0};
float sinA[2][32] =
{
{0.6, 0.679, 0.755, 0.825, 0.886, 0.936, 0.972, 0.994, 1, 0.99, 0.965, 0.926, 0.874, 0.811, 0.739, 0.662, 0.583, 0.504, 0.429, 0.361, 0.303, 0.256, 0.222, 0.204, 0.201, 0.214, 0.242, 0.284, 0.339, 0.404, 0.477, 0.554},
{0.6, 0.679, 0.755, 0.825, 0.886, 0.936, 0.972, 0.994, 1, 0.99, 0.965, 0.926, 0.874, 0.811, 0.739, 0.662, 0.583, 0.504, 0.429, 0.361, 0.303, 0.256, 0.222, 0.204, 0.201, 0.214, 0.242, 0.284, 0.339, 0.404, 0.477, 0.554}
};
byte waveTable[260];
float sinC[41];
byte ti = 0;
int out = 0;
float fout = 0;
//extra outs
boolean Acounter = 0;
boolean Bcounter = 0;
byte selPitch = 0;
byte vibA = 0;
unsigned long mlong[4] = {0,0,0,0};
//trigger vars
boolean externalTrigger = false;
boolean triggerActive = false;
boolean inLoop = false;
#define FASTADC 0
//defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup(){
#if FASTADC
//set prescale to 16
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
cbi(ADCSRA,ADPS0);
#endif
//setup FAST PWM pin 9 & 10.
TCCR1B = TCCR1B & 0b11111000 | 0x01;
TCCR2B = TCCR2B & 0b11111000 | 0x01;
for(float f=0.5; f<1; f+=0.05){
sinC[ti] = f;
ti++;
}
for(float f=1; f>0.5; f-=0.05){
sinC[ti] = f;
ti++;
}
for(byte f=0; f<32; f++){
sinA[1][f] = f*0.032;
}
waveTable[0] = 0xaa;
waveTable[1] = 0x66;
setupPWM(0);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(13, OUTPUT);
pinMode(3, OUTPUT);
readAnalogs();
for(byte i=6; i<255; i++){
waveGenartor(pot[3], 0 , 0);
}
pinMode(2, INPUT);
digitalWrite(2, HIGH);
startupSound();
attachInterrupt(0, triggerNormal, FALLING);
}
void loop(){
//check if we are in the loop.. (for interupt, pullup resistors).
inLoop = true;
//read potmeters
readAnalogs();
//button vars
static byte butSel = 6;
//select synth (0 to 15).
butSel = pot[5] >> 6;
if(butSel == 0){
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
digitalWrite(11, HIGH);
}
setupPWM(1);
waveGenartor(pot[3], 0, 0);
oscA2 = max(pot[0] >> 2, 1);
//detunes oscillators
oscA++;
//extra pitch shift up to normal pitch
oscA += pot[4]>>6;
oscA %= max(oscA2, 1);
oscB++;
oscB %= max(oscA2+1, 2);
oscC++;
oscC %= max(oscA2+2, 3);
//mix oscillators
out = ((waveTable[oscA]*2)+(waveTable[oscB]*2)+(waveTable[oscC]*2))/6;
//add vibrato
if(millis() - mlong[0] > ((pot[2]*4)+512)){
mlong[0] = millis();
vibA++;
vibA %= ti;
fout = sinC[vibA]*((pot[1]*0.001)+0.9);
trigger((ti*2));
}
out *= fout;
out = constrain(out, 0, 127);
if(!oscA){
Acounter = !Acounter;
}
if(!oscA2){
Bcounter = !Bcounter;
}
analogWrite(5, 20);
analogWrite(6, 10);
if(oscD > out){
oscD++;
}else{
oscD--;
}
analogWrite(9, out);
analogWrite(10, out);
delayMicroseconds(oscA2);
}
else if(butSel == 1){
//reset vars
if(prevSynth != butSel){
//fader();
prevSynth = butSel;
}
setupPWM(1);
waveGenartor(pot[3], 0 , 0);
//detunes oscillators
oscA++;
oscA %= (pot[0] >> 4)+1;
oscB++;
oscB %= (pot[1] >> 4)+1;
oscC++;
oscC %= (pot[2] >> 4)+1;
//mix oscillators
out = ((waveTable[oscA]*2)+(waveTable[oscB]*2)+(waveTable[oscC]*2))/7;
analogWrite(11, (255 - (pot[4] >> 2)));
analogWrite(9, out);
analogWrite(10, out);
delayMicroseconds(1);
}
else if(butSel == 2){
//kick
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
}
setupPWM(0);
static unsigned int pitchDecay = 0;
waveGenartor(pot[3], 0, 0);
//detunes oscillators
oscA++;
//extra pitch shift up to normal pitch
oscA += ((pot[3]) >> 6);
oscA %= max(pot[0] >> 3, 1);
oscB++;
oscB %= max((pot[0] >> 3)+1, 1);
oscC++;
oscC %= max((pot[0] >> 3)+2, 1);
pitchDecay++;
pitchDecay %= (pot[2]);
//mix oscillators
out = ((waveTable[oscA]*2)+(waveTable[oscB]*2)+(waveTable[oscC]*2))/6;
byte tr0 = (pot[1]/6)+83;
out = constrain(out, 0, tr0);
if(!oscA){
Acounter = !Acounter;
}
if(!oscB){
Bcounter = !Bcounter;
}
static byte go = 0;
go++;
go %= 256;
if(!go){
Acounter = !Acounter;
}
if(Acounter){
analogWrite(6, out);
digitalWrite(10, LOW);
}
else{
analogWrite(10, out);
digitalWrite(6, LOW);
}
analogWrite(9, out);
if(256 % (pitchDecay + 20) == 0){
trigger(2);
}
if(!pitchDecay){
tvol = 255;
}
tvol*=0.992;
max(tvol, 0.1);
analogWrite(11, (byte(tvol)));
delayMicroseconds(pitchDecay+20);
}
else if(butSel == 3){
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
digitalWrite(11, HIGH);
}
setupPWM(0);
//detunes oscillators
oscA++;
oscA %= (pot[0] >> 4)+1;
oscB++;
oscB %= (pot[0] >> 4)+2;
oscC++;
oscC %= (pot[0] >> 4)+3;
oscD++;
oscD %= (pot[0] >> 4)+4;
//detunes oscillators
oscA2++;
oscA2 %= (pot[1] >> 4)+1;
oscB2++;
oscB2 %= (pot[1] >> 4)+2;
oscC2++;
oscC2 %= (pot[1] >> 4)+3;
oscD2++;
oscD2 %= (pot[1] >> 4)+4;
//mix oscillators
unsigned int outA = ((waveTable[oscA]*2)+(waveTable[oscB]*2)+(waveTable[oscC]*2)+(waveTable[oscD]*2));
unsigned int outB = ((waveTable[oscA2]*2)+(waveTable[oscB2]*2)+(waveTable[oscC2]*2)+(waveTable[oscD2]*2));
outA = (outA)*(((pot[2]+1)*0.0005));
outB = (outB)*(((pot[3]+1)*0.0005));
if(outA > 255){
outA -= (outA - 255);
trigger(32);
}
if(outB > 255){
outB -= (outB - 255);
trigger(32);
}
byte out = (outA+outB)/2;
//oscilloscope(Mout);
digitalWrite(5, out);
digitalWrite(6, out);
analogWrite(9, out);
analogWrite(10, out);
analogWrite(11, (pot[4] >> 2));
delayMicroseconds(1);
}
else if(butSel == 4){
//techno
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
oscA = 0;
selPitch = 0;
tvol = 0;
//resetWavetable();
}
//setup timers
setupPWM(0);
//legato
if(tp < pot[selPitch]){
tp++;
}
else if(tp > pot[selPitch]){
tp--;
}
//oscillators timer
oscA++;
oscA %= (tp >> 3)+20;
//display wave..
analogWrite(10, (tp >> 2));
analogWrite(11, (tp >> 2));
//interval
if(triggerME((pot[4] >> 1)+ 4, 0)){
//selectpotmeter for next pitch
selPitch++;
selPitch %= 4;
//render waveform
waveGenartor(1023, ta, ta);
//pwm sound, changes settings inside the waveGenerator
if(!(sinAc % 32)){
sinAc = 0;
ta = !ta;
}
//reset volume
tvol = 0.5;
tc = random(2);
//no display lines
digitalWrite(5, 0);
digitalWrite(6, 0);
//send trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
oscA2 = 30;
}
oscA2--;
oscA2 = max(oscA2, 0);
if(!oscA2){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//fade out
tvol -= 0.0002;
tvol = max(tvol, 0.0001);
out = (waveTable[oscA])*tvol;
analogWrite(9, out);
delayMicroseconds(20);
}
else if(butSel == 5){
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
oscD = 0;
oscA2 = 2;
oscB2 = 2;
oscC2 = 2;
oscD2 = 0;
oscL[0] = 0;
oscL[1] = 0;
oscL[2] = 0;
}
//setup timers
setupPWM(0);
oscA++;
oscA %= oscA2;
oscB++;
oscB %= oscB2;
oscC++;
oscC %= oscC2;
//pitch change
if(triggerME((pot[3] >> 3)+10, 0)){
waveGenartor(1023, 0, 0);
byte selMode = pot[4] >> 8;
if(selMode == 0){
oscA2 = max(pot[0] >> 4, 1);
oscB2 = max(pot[1] >> 4, 1);
oscC2 = max(pot[2] >> 4, 1);
}
else if(selMode == 1){
oscA2 = max(pot[1] >> 4, 1);
oscB2 = max(pot[2] >> 4, 1);
oscC2 = max(pot[0] >> 4, 1);
}
else if(selMode == 2){
oscA2 = max(pot[2] >> 4, 1);
oscB2 = max(pot[0] >> 4, 1);
oscC2 = max(pot[1] >> 4, 1);
}
oscL[0]++;
oscL[0] %= max((pot[0] >> 3)+1, 1);
oscL[1]++;
oscL[1] %= max((pot[1] >> 3)+1, 1);
oscL[2]++;
oscL[2] %= max((pot[2] >> 3)+1, 1);
//fade reset
oscD2 = 240;
}
//fade
oscD2 -= 0.01;
oscD2 = max(oscD2, 0.0001);
//reset out
out = 0;
//mix
if(!oscL[0]){
out += (sinA[1][oscA]*oscD2);
trigger(2);
}
if(!oscL[1]){
out += (sinA[1][oscB]*oscD2);
trigger(2);
}
if(!oscL[2]){
out += (sinA[1][oscC]*oscD2);
trigger(2);
//reset Effect LED
oscD = 255;
}
//fade Efect LED
oscD--;
oscD = max(oscD, 1);
analogWrite(11, oscD);
out = max(min((out/3), 255), 1);
analogWrite(9, max(min(out, 100), 1));
analogWrite(10, out);
delayMicroseconds(1);
}
else if(butSel == 6){
//noise
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
}
setupPWM(0);
//switch between up or down fade
if(triggerME(pot[2]+50, 0)){
for(byte i=0; i<255; i++){
waveTable[i] = random(32);
}
analogWrite(11, min((waveTable[0]*(pot[3] >> 5)), 255));
ta = !ta;
//visuals
analogWrite(5, waveTable[0]);
analogWrite(6, waveTable[1]);
digitalWrite(4, HIGH);
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//fade
if(ta == 0){
kick -= 0.0003;
if(kick < 0.001){
kick = 0.95;
}
}
else if(ta == 1){
kick += 0.0003;
if(kick > 0.95){
kick = 0.0001;
}
}
//play wave form..
oscA++;
oscA %= ((pot[1] >> 3)+2);
out = min(waveTable[oscA]*kick, 253)+1;
analogWrite(9, out);
analogWrite(10, out);
delayMicroseconds((pot[0] << 1)+1);
}
else if(butSel == 7){
//noise
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
}
setupPWM(0);
//analogWrite(11, pot[4] >> 3);
//add up and add new rand vars to array with delay..
oscA++;
oscA %= (pot[4] >> 4)+1;
if(!oscA){
oscB++;
oscB %= 8;
oscN[oscB] = random(90)*kick;
tc = !tc;
digitalWrite(7, tc);
}
//select active sounds
oscA2 = pot[1] >> 5;
//fade in
if(bitRead(oscA2, 0)){
kick += 0.01;
if(kick > 0.99){
kick = 0;
}
}
//fade out
if(bitRead(oscA2, 1)){
kick -= 0.01;
if(kick < 0.1){
kick = 1;
}
}
//oscilate
if(bitRead(oscA2, 2)){
for(int i = 100; i>1; i--){
ta = !ta;
if(ta){
analogWrite(9, limiter(pot[1] >> 6));
}
else{
analogWrite(9, 5);
}
delayMicroseconds((pot[0] >> 1)+1);
}
}
//add empty time..
if(bitRead(oscA2, 3)){
//read voor break..
readAnalogs();
readAnalogs();
readAnalogs();
readAnalogs();
readAnalogs();
readAnalogs();
delay(pot[3] >> 2);
}
for(int i=0; i<((pot[2] >> 4)+1); i++){
byte t = i % 8;
out = min((oscN[t]*kick), 128);
analogWrite(11, min((out*3), 255));
analogWrite(9, limiter(out));
tb = !tb;
digitalWrite(6, tb);
trigger(pot[2]+4);
delayMicroseconds((pot[0] >> 1)+1);
}
ta = !ta;
digitalWrite(5, ta);
digitalWrite(4, LOW);
digitalWrite(10, LOW);
}
else if(butSel == 8){
//hypnotoad
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
oscA2 = 0;
oscB2 = 0;
oscC2 = 0;
oscA = 0;
oscB = 0;
ta = false;
tb = false;
tc = false;
analogWrite(10, 0);
analogWrite(5, 0);
analogWrite(6, 0);
analogWrite(7, 0);
}
//setup timers
setupPWM(1);
if(millis() - mlong[1] > ((pot[2] >> 1)+2)){
mlong[1] = millis();
sinAc++;
sinAc %= max(pot[0] >> 2, 1);
waveTable[sinAc] = random(100);
tb = !tb;
}
if(millis() - mlong[0] > (pot[3]+128)){
mlong[0] = millis();
trigger(2);
oscC2++;
oscC2 %= ti;
}
ta = !ta;
//oscillators
oscA++;
oscA %= max(pot[0] >> 2, 2);
oscB++;
oscB %= max(pot[0] >> 2, 3);
out = (((waveTable[oscA])+(waveTable[oscB]))/3);
//Serial.println(oscC2, DEC);
analogWrite(11, (pot[4] >> 2));
analogWrite(10, oscC2*12);
analogWrite(5, sinAc);
analogWrite(6, (255 - sinAc));
digitalWrite(7, tc);
analogWrite(9, out);
delayMicroseconds((((pot[1])+1)*sinC[oscC2])+1);
}
else if(butSel == 9){
//melody bin seq
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
BA = 0;
BB = 0;
tvol = 0;
tb = true;
}
//setup timers
setupPWM(0);
if(triggerME(pot[4]+20, 1)){
BA = pot[2] >> 2;
BB = pot[3] >> 2;
waveGenartor(1023, ta, ta);
oscA2++;
oscA2 %= 8;
oscB2++;
oscB2 %= 8;
if(!(sinAc % 32)){
sinAc = 0;
ta = !ta;
}
//no extra visuals
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
//tvol = 0.5;
tb = true;
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
oscC2 = 30;
}
//countdwon trigger and set low..
oscC2--;
oscC2 = max(oscC2, 0);
if(!oscC2){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//pitch
oscA++;
oscA %= (pot[0] >> 3)+2;
oscB++;
oscB %= (pot[1] >> 3)+2;
if(bitRead(BA, oscA2) && bitRead(BB, oscB2)){
out = ((waveTable[oscA]*2)+(waveTable[oscB]*2))*(tvol/3);
oscD--;
}
else if(bitRead(BA, oscA2)){
out = waveTable[oscA]*tvol;
oscD++;
}
else if(bitRead(BB, oscB2)){
out = waveTable[oscB]*tvol;
oscD++;
}
//oscD %= 255;
oscD = max(min(oscD, 254), 1);
analogWrite(11, oscD);
//short attack..
if(tb){
if(tvol > 0.8){
tb = false;
}
tvol += (pot[4]+1)*0.00001;//0.005;
}
else{
tvol -= (pot[4]+1)*0.00001;//0.005;
tvol = max(tvol, 0.0001);
}
analogWrite(9, out);
analogWrite(10, out);
}
else if(butSel == 10){
//4/4 chipy attempt..
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
digitalWrite(11, HIGH);
}
//setup timers
setupPWM(0);
if(triggerME(pot[4]+20, 1)){
//if(millis() - mlong[1] > (pot[4]+20)){
// mlong[1] = millis();
BA = pot[2] >> 2;
BB = pot[3] >> 2;
//waveGenartor(1023, ta, ta);
waveGenartor(1023, 0, 0);
//reset volume decay
tvol = 0.5;
//bit read counters (probably only need one of these..).
oscA2++;
oscA2 %= 8;
oscB2++;
oscB2 %= 8;
//change volume with length of long pitch change..
tvol2 = ((byte) (pot[1]))*0.0035;
//add some delay (4/4 type) because the analog reads are to unstable..
oscD2++;
oscD2 %= 8 << (pot[1] >> 8);
if(!oscD2){
for(byte i=0; i<8; i++){
//multiply and make into byte... melody generation..
oscL[i] = (byte) (pot[0]*(i+1));
oscL[i] += 1;
}
//melody change
oscC2++;
oscC2 %= 8;
}
//phasing..
if(!(sinAc % 32)){
sinAc = 0;
ta = !ta;
}
//no extra visuals
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
//attack time change..
kick = (oscL[oscA2] >> 2)+1;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//kick pitch down speed
kick += 0.05;
kick = min(kick, 255);
//pitch
oscA++;
oscA %= (byte) (kick); //convert from float to byte
oscB++;
oscB %= max((oscL[oscA2] >> 1), 2);
if(bitRead(BA, oscA2) && bitRead(BB, oscB2)){
fout = ((waveTable[oscA]*1.3)+(waveTable[oscB]*2))*(tvol/2);
}
else if(bitRead(BA, oscA2)){
fout = waveTable[oscA]*tvol;
}
else if(bitRead(BB, oscB2)){
fout = waveTable[oscB]*tvol;
}
tvol -= 0.0003;
tvol = max(tvol, 0.0001);
oscD++;
oscD %= 128;
if(!oscD){
tb = !tb;
}
oscC++;
oscC %= oscL[oscC2];
//mix in with limiter
out = (byte) min(((fout*2)+(waveTable[oscC]*tvol2))*0.5, 255);
analogWrite(9, out);
analogWrite(10, out);
}
else if(butSel == 11){
//clicks
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
}
//setup timers
setupPWM(0);
if(triggerME(pot[4]+20, 1)){
//add some delay (4/4 type) because the analog reads are to unstable..
oscA2++;
oscA2 %= 16;
if(!oscA2){
for(byte i=0; i<8; i++){
//multiply and make into byte... melody generation..
oscL[i] = max(((oscL[i]+((byte) (pot[2]*(i+1))))/2), 1);
oscN[i] = max(((oscN[i]+((byte) (pot[3]*(i+1))))/2), 1);
}
}
//select pitch
oscB2++;
oscB2 %= pot[0] >> 7;
oscC2++;
oscC2 %= pot[1] >> 7;
//no extra visuals
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
tvol = 2;
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//pitch
oscA++;
oscA %= (oscL[oscB2] >> 2)+1;
oscB++;
oscB %= (oscN[oscC2] >> 2)+1;
//fade out
tvol *= 0.9;
tvol = max(tvol, 0.0001);
tvol = min(tvol, 2);
if(!oscA || !oscB){
tc = !tc;
if(tc){
out = 100*tvol;
analogWrite(11, (out % 255));
}
else{
out = 0;
}
}
analogWrite(9, out);
analogWrite(10, out);
}
else if(butSel == 12){
//2 voice arpegiator with fade
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
digitalWrite(11, HIGH);
}
//setup timers
setupPWM(0);
if(triggerME(pot[4]+20, 1)){
waveGenartor(pot[1], 0, 0);
//add some delay (4/4 type) because the analog reads are to unstable..
oscA2++;
oscA2 %= 8;
if(!oscA2){
for(byte i=0; i<8; i++){
//multiply and make into byte... melody generation..
oscL[i] = max(((oscL[i]+((byte) (pot[2]*(i+1))))/2), 1);
oscN[i] = max(((oscN[i]+((byte) (pot[3]*(i+1))))/2), 1);
}
}
//select pitch
oscB2++;
oscB2 %= pot[0] >> 7;
oscC2++;
oscC2 %= pot[1] >> 7;
//no extra visuals
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
//phasing..
if(!(sinAc % 32)){
sinAc = 0;
ta = !ta;
}
//tvol = 2;
tb = true;
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//short attack..
if(tb){
if(tvol >= 2){
tb = false;
}
tvol += 0.03;
}
else{
tvol -= 0.0009;
tvol = max(tvol, 0.0001);
}
//pitch
oscA++;
oscA %= max((oscL[oscB2]>>1), 2);
oscB++;
oscB %= max((oscN[oscC2]>>1), 2);
//mix
out = min(((waveTable[oscA]*tvol)+(waveTable[oscB]*tvol))/4, 255);
analogWrite(9, out);
//visuals
analogWrite(10, min((out*2), 255));
if(out > 50){
digitalWrite(5, HIGH);
}else{
digitalWrite(5, LOW);
}
}
else if(butSel == 13){
//setup timers
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
//digitalWrite(11, HIGH);
triggerDecay = 1;
}
setupPWM(0);
//extra reads
readAnalogs();
readAnalogs();
readAnalogs();
readAnalogs();
readAnalogs();
oscA++;
oscA %= 8;
oscL[oscA] = max(((oscL[oscA]+((byte) (pot[0]*(oscA+1))))/2), 1);
//select sounds
byte tpot = pot[1] >> 8;
byte tpot2 = pot[2] >> 8;
//set random or not
if(pot[3] >> 9){
tpot = random(4);
tpot2 = random(4);
}
//effect led
analogWrite(11, (255 - (pot[4] >> 2)));
oscD2 = (pot[4] >> 6)+1;
//send trigger
triggerDecay = !triggerDecay;
digitalWrite(3, triggerDecay);
digitalWrite(4, triggerDecay);
if(tpot == 0){
//1st one empty
}
else if(tpot == 1){
//no fade, 8 pitches
for(byte j=0; j<8; j++){
for(byte i=0; i<255; i++){
ta = !ta;
delayMicroseconds((oscL[j]+1)*oscD2);
if(ta){
analogWrite(9, 25);
}
else{
analogWrite(9, 0);
}
}
}
}
else if(tpot == 2){
//no fade, 8 pitches
for(byte j=0; j<8; j++){
for(byte i=0; i<255; i++){
ta = !ta;
oscB++;
oscB %= 35;
delayMicroseconds((oscL[j]+1)*oscD2);
if(ta){
analogWrite(9, oscB);
}
else{
analogWrite(9, (35-oscB));
}
}
}
}
else if(tpot == 3){
//fade in and out, 8 pitches
for(byte j=0; j<4; j++){
tvol = 0;
for(byte i=0; i<255; i++){
ta = !ta;
tvol += 0.0025;
delayMicroseconds((oscL[j+4]+1)*oscD2);
if(ta){
analogWrite(9, 40*tvol);
}
else{
analogWrite(9, 0);
}
}
for(byte i=0; i<255; i++){
ta = !ta;
tvol -= 0.0025;
tvol = max(tvol, 0.001);
delayMicroseconds((oscL[j]+1)*oscD2);
if(ta){
analogWrite(9, 40*tvol);
}
else{
analogWrite(9, 0);
}
}
}
}
//send trigger
triggerDecay = !triggerDecay;
digitalWrite(3, triggerDecay);
digitalWrite(4, triggerDecay);
if(tpot2 == 0){
//1st one empty
}
else if(tpot2 == 1){
//just a pitch
for(byte j=0; j<8; j++){
for(byte i=0; i<((byte)(oscL[oscA]/4)); i++){
ta = !ta;
delayMicroseconds((oscL[oscA]+1)*oscD2);
if(ta){
analogWrite(9, 16);
}
else{
analogWrite(9, 0);
}
}
}
}
else if(tpot2 == 2){
//
for(byte j=0; j<8; j++){
tvol = 0;
for(byte i=0; i<255; i++){
tvol += 0.0025;
ta = !ta;
oscC++;
oscC %= 3;
oscB++;
oscB %= 35;
delayMicroseconds((oscL[oscA]+1)*oscD2);
if(ta){
analogWrite(9, ((oscB*tvol)*oscC));
}
else{
analogWrite(9, 0);
}
}
}
}
else if(tpot2 == 3){
for(byte j=0; j<8; j++){
for(byte i=0; i<255; i++){
ta = !ta;
delayMicroseconds((oscL[oscA]+1)*oscD2);
if(ta){
analogWrite(9, random(40));
}
else{
analogWrite(9, 0);
}
}
}
}
}
else if(butSel == 14){
//bas kick and hh noise..
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(11, HIGH);
}
//setup timers
setupPWM(0);
if(triggerME(pot[4]+20, 1)){
BA = pot[2] >> 2;
BB = pot[3] >> 2;
//waveGenartor(1023, ta, ta);
waveGenartor(1023, ta, ta);
//crosfade volume..
tvol = min(pot[1]*0.001, 0.6);
tvol2 = min((1023-pot[1])*0.001, 0.6);
//bit read counters (probably only need one of these..).
oscA2++;
oscA2 %= 8;
oscB2++;
oscB2 %= 8;
//phasing..
if(!(sinAc % 32)){
sinAc = 0;
ta = !ta;
}
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
//attack time change..
kick = (pot[0] >> 2)+1;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
//kick pitch down speed
kick += 0.05;
kick = min(kick, 255);
//volume
tvol -= 0.001;
tvol = max(tvol, 0.0001);
tvol2 -= 0.003;
tvol2 = max(tvol2, 0.0001);
//pitch
oscA++;
oscA %= (byte) (kick); //convert from float to byte
oscB++;
oscB %= (byte) (tvol2); //convert from float to byte
//reset volume if no beat A
if(!bitRead(BA, oscA2)){
tvol = 0.001;
//analogWrite(11, random(255));
oscD += (random(10) - 5);
oscD %= 256;
analogWrite(11, oscD);
}
//reset volume if no beat B
if(!bitRead(BB, oscA2)){
tvol2 = 0.001;
digitalWrite(11, LOW);
}
//mix
out = (waveTable[oscA]*tvol)+(random(240)*tvol2)/2;
analogWrite(9, out);
analogWrite(10, min((out*8), 255));
}
else if(butSel == 15){
//square wave synth..
//reset vars
if(prevSynth != butSel){
prevSynth = butSel;
oscA2 = 10;
oscB2 = 10;
oscC2 = 10;
analogWrite(10, 0);
}
setupPWM(0);
//oscillators
oscA++;
oscA %= (pot[0]>>4)+8;
oscB++;
oscB %= (pot[0]>>4)+9;
oscC++;
oscC %= (pot[0]>>4)+10;
//inverse cycle
if(!oscA){
ta = !ta;
}
if(!oscB){
tb = !tb;
}
if(!oscC){
tc = !tc;
}
//reset output volume
out = 0;
//make wave form, lower volume on low pitch
if(ta){
out += 28;
}
if(tb){
out += 28;
}
if(tc){
out += 28;
}
if(triggerME(pot[4]+10, 1)){
oscA2++;
oscA2 %= (pot[2]>>7)+1;
for(byte i=0; i<8; i++){
//multiply and make into byte... melody generation.. reverse for low pitch on no arp..
oscL[i] = 255 - ((byte) ((pot[1]>>2)*((i+1))));
}
//start trigger
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
triggerDecay = 30;
}
//countdwon trigger and set low..
triggerDecay--;
triggerDecay = max(triggerDecay, 0);
if(!triggerDecay){
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
out += pot[3]>>4;
out = constrain(out, 1, 100);
analogWrite(9, out);
//visuals
digitalWrite(7, ta);
digitalWrite(6, tb);
digitalWrite(5, tc);
analogWrite(11, oscL[oscA2]);
//overall pitch
delayMicroseconds(max(oscL[oscA2], 1));
}
}
//read pots, 1 at a time
void readAnalogs(){
static byte potc = 0;
potc++;
potc %= 6;
pot[potc] = analogRead(potc);
}
//setup PWMs: http://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();
}
}
}
//send trigger
void trigger(byte inp){
static unsigned int tCount = 0;
tCount++;
tCount %= inp;
if(!tCount){
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
}
else{
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
}
void startupSound(){
//wait tone
for(int i=10000; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*16;
analogWrite(9, out);
delayMicroseconds(68);
}
//dial
for(int j=8; j>0; j--){
byte rpitch = random(1, 50);
int rpitcC = (50 - rpitch)*50;
for(unsigned int i=rpitcC; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*35;
analogWrite(9, out);
delayMicroseconds(rpitch);
}
delay(100);
}
delay(1000);
//part 2..
oscA = 0;
for(int i=20000; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*2;
analogWrite(9, out);
delayMicroseconds(1);
}
for(int i=2000; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*2;
analogWrite(9, out);
delayMicroseconds(70);
}
oscA = 0;
for(int j=7; j>0; j--){
for(int i=96; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*12;
analogWrite(9, out);
delayMicroseconds(1);
}
delay(6);
}
for(int i=200; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*20;
analogWrite(9, out);
delayMicroseconds(1);
}
for(int j=10; j>0; j--){
byte tv = random(4, 20);
for(int k=20; k>0; k--){
for(int i=96; i>0; i--){
oscA++;
oscA %= 32;
out = sinA[0][oscA]*tv;
analogWrite(9, out);
delayMicroseconds(1);
}
}
}
//noise
for(unsigned int i=3000; i>0; i--){
analogWrite(9, random(14));
delayMicroseconds(1);
}
tvol = 20;
for(unsigned int i=3000; i>0; i--){
tvol += 0.005;
oscA++;
oscA %= 8;
out = (sinA[1][oscA]*30)+random(tvol)/2;
analogWrite(9, out);
delayMicroseconds(1);
}
tvol /= 2;
for(unsigned int i=600; i>0; i--){
oscA++;
oscA %= 8;
out = (sinA[1][oscA]*30)+random(tvol)/2;
analogWrite(9, out);
delayMicroseconds(1);
}
tvol = 0;
for(unsigned int i=1000; i>0; i--){
tvol += 0.002;
analogWrite(9, (random(20)*tvol));
delayMicroseconds(1);
}
}
//if trigger use trigger, otherwise use millis..
boolean triggerME(int mil, byte arr){
boolean retVal = false;
if(!externalTrigger){
if(millis() - mlong[arr] > mil){
mlong[arr] = millis();
retVal = true;
}
else{
retVal = false;
}
}
else if(triggerActive){
//reset trigger status, for trigger below
triggerActive = false;
retVal = true;
}
return retVal;
}
void triggerNormal(){
if(inLoop){
//set external trigger to true if there is a trigger signal..
externalTrigger = true;
//set trigger to active, see above
triggerActive = true;
}
}
void resetWavetable(){
for(byte i=0; i<100; i++){
waveTable[i] = 20;
}
}
byte limiter(byte inp){
return constrain(inp, 0, 60);
}
void waveGenartor(int inpA, byte inpB, byte inpC){
static byte decayA = 0;
sinAc++;
sinAc %= 256;
sinAc2++;
sinAc2 %= 32;
decayA++;
//decayA %= (inpA >> 5);
decayA %= (inpA >> 5)+1;
waveTable[sinAc] = (255*sinA[inpB][decayA])*sinA[inpC][sinAc2];
}