//Image Scan Sequencer, by: Gijs Gieskes 2008 //Copyleft: This is a free work, you can copy, distribute, and modify it //under the terms of the Free Art License: //http://artlibre.org/licence/lal/en/ //MIDI byte setNoteOn = 0x90; byte setNoteOff= 0x80; byte pitch = 65; int velocity = 0; int arpegiator = 0; long prevMillis = 0; byte stateArrCounter = 0; byte arpCounter = 0; byte prevPitch = 0; boolean enableNoteOff = true; boolean rearangeYesNo = false; boolean arpegiatorYesNo = false; boolean read11 = HIGH; int noteOnRange = 0; //multiplex variables int multiArray[3][8] = { {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0} }; byte stateArray[3][24]= { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; void setup() { DDRB = DDRB | B00000111; // 10, 9, 8 zijn outputs pinMode(11, INPUT); digitalWrite(11, HIGH); //baut reet: Serial.begin(31250); //Serial.begin(9600); } void loop() { //read multiplexor inputs readAnalogs(); switcher(); //bepaalt de hoeveelheid noten die gespeelt worden in de arpegio. stateArrCounter = 0; //modify/organize recieved data for(byte i=0; i<3; i++){ for(byte j=0; j<8; j++){ int avals = multiArray[i][j]; velocity = (noteOnRange - avals); //inverse velocity = map(velocity, 0, noteOnRange, 0, 127); //bazeer de velocity op de noteOnRange. velocity = constrain(velocity, 0, 127); //voor de zekerheid.. if(avals <= noteOnRange){ stateArray[0][stateArrCounter] = setNoteOn; stateArray[1][stateArrCounter] = pitch; stateArray[2][stateArrCounter] = velocity; stateArrCounter++; }else{ stateArray[0][stateArrCounter] = setNoteOff; } pitch++; } } //als er weinig noten zijn word de arpegiator speed hoger. if(arpegiatorYesNo == true){ arpegiator = (stateArrCounter*16)+10; } //re-organize and send data as arpegio if(millis() - prevMillis > arpegiator) { prevMillis = millis(); if(rearangeYesNo == true){ rearangeToVel(); //reanrange notes to velocity } arpCounter++; if(arpCounter >= stateArrCounter){arpCounter = 0;} byte arpOnOff = stateArray[0][arpCounter]; byte arpInPitch = stateArray[1][arpCounter]; byte arpInVel = stateArray[2][arpCounter]; if(arpInPitch != prevPitch){ sendMIDI(setNoteOn, arpInPitch, arpInVel); } if(arpCounter == 0 && arpOnOff == setNoteOff && enableNoteOff == true){ sendMIDI(setNoteOff, arpInPitch, 0); enableNoteOff = false; //set note off once } if(arpInPitch != prevPitch){ //turn off the last played note sendMIDI(setNoteOff, prevPitch, 0); enableNoteOff = true; //set note off once } prevPitch = arpInPitch; } //just some delay delay(8); } //http://itp.nyu.edu/physcomp/Labs/MIDIOutput void sendMIDI(char sb, char data1, char data2) { Serial.print(sb, BYTE); Serial.print(data1, BYTE); Serial.print(data2, BYTE); } //lees de multiplex LDRs in void readAnalogs(){ for(byte i=0; i<8; i++){ PORTB &= B11111000; PORTB |= i; //schijf naar poort 10,9,8 delayMicroseconds(3); //geef de multiplexor de teid om te schakelen.. multiArray[0][i] = analogRead(0); multiArray[1][i] = analogRead(1); multiArray[2][i] = analogRead(2); } } //http://www.arduino.cc/playground/Main/DigitalSmooth void rearangeToVel(){ boolean done = 0; // flag to know when were done sorting byte temp0 = 0; byte temp1 = 0; byte temp2 = 0; while(done != 1){ // simple swap sort, sorts numbers from lowest to highest done = 1; for (byte j = 0; j < (stateArrCounter - 1); j++){ if (stateArray[2][j] > stateArray[2][j + 1]){ // numbers are out of order - swap temp0 = stateArray[0][j + 1]; temp1 = stateArray[1][j + 1]; temp2 = stateArray[2][j + 1]; stateArray[0][j+1] = stateArray[0][j] ; stateArray[1][j+1] = stateArray[1][j] ; stateArray[2][j+1] = stateArray[2][j] ; stateArray[0][j] = temp0; stateArray[1][j] = temp1; stateArray[2][j] = temp2; done = 0; } } } } void switcher(){ read11 = digitalRead(11); int Aread4T = analogRead(4); int Aread5T = analogRead(5); if(read11 == LOW){ if(Aread4T < 512){ noteOnRange = Aread5T/2; pitch = 65; }else{ //switch to select different types of playback (rearange to vel and vel dendant speed). if(Aread5T < 255){ rearangeYesNo = true; arpegiatorYesNo = false; }else if(Aread5T < 512 && Aread5T >= 255){ rearangeYesNo = false; arpegiatorYesNo = true; }else if(Aread5T < 765 && Aread5T >= 512){ rearangeYesNo = false; arpegiatorYesNo = false; }else{ rearangeYesNo = true; arpegiatorYesNo = true; } pitch = 65; } }else{ pitch = (Aread5T/10)+1; arpegiator = ((1023 - Aread4T)/2)+1; } }