hss3jwithscripthss3s05v01withmidikeyboard

hss3jwithscripthss3s05v01withmidikeyboard

hss3jwithscripthss3s05v02withmidikeyboard

hss3s05v01pde
hss3s05v02pde
hss3s05v03pde

hss3s05v02gijsgieskes2012httpgieskesnlforusewithhss3jhardwarehttpgieskesnlinstruments filehardsoftsynth3howtouploadhttpgieskesnlundefinedtutorials fhss3softwareupdateuploadusingarduinoversion21onlymanualnormalmodepot0select1ofthe24notespicthespot0bigbuttonselect1ofthe24notespicthesonreleaseofthebuttonpot1setspitchofthetrianglewavethatfillsthewavtablepot2oscillator2detunepot3filterledsequencialonoffspeedallthewaytotheleftisholdpot4setsspeedofhowfastthewavetableisbeingfilledwiththetrianglewaveinrelationtopot1pot5allthewaytotheleftaddsnosietowavtableclockwisewilladdtrianglewavetowavetableleftishighpitchrightislowpitchmanualmidikeyboardmodewhenamidinoteissendtothethehss3itwillgointomidikeyboardmodeyoucangocangooutofmidimodebypressingthesmallbuttonpot0playbackspeedofmidinotebufferbugbuttonwhenpressedmidinotesthatarebeingplayedwillnotbestoppedwhenanoteoffmessageisrecievedallotherpotskeepthesamefuntionasmentionedabovebutwillbereplacedwhenccmessagesarerecievedthatareconnectedtothepotinquestionthatis20to25volatilebytefrequency255volatilebyteframe255volatilebytewtl255volatilebooleantriggersignalfalsevolatilebooleanaudioinactivetruevolatilebytebutselp255volatileunsignedintbutselvoldel0volatilebyteslidespeedvolatilebytedecayspeedbytepitch48oscsunsignedintosca0unsignedintoscb0unsignedintoscc0unsignedintoscd0intosce0unsignedintoscf0unsignedintosca2255unsignedintoscb2254unsignedintoscd20unsignedintoscc20byteoscdiv0byteseqcount0byteseqpitches1264bytebank0potarrayvolatileintpot800000000triggervarsvolatilebooleanexternaltriggerfalsevolatilebooleantriggeractivefalsevolatilebooleanaudiotriggerfalsemidilibraryhttptimothytwillmancomitpblog pageid240includemidihmidisequencingvarsbytemidicounterbooleanmidiplayfalsebooleanmididisablefalsebooleanmidiboolfalsebooleanmidiactivefalsebooleanmidibools6000000byteactivenotes25byteactivecount1classmymidipublicmidipublicneedthistocompileitjusthandsthingsofftothemidiclassmymidihardwareserialsmidisvoidhandlecontrolchangeunsignedintchannelunsignedintcontrollerunsignedintvalueifcontroller20212223242526midibooltrueswitchcontrollercase20midibools0truepot01023value<<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; } }