//////////////////////////////////// // // // TVSLD1S02, Gijs Gieskes 2011 // // // //////////////////////////////////// #include #include "TVout.h" #define W 128 #define H 96 #define TBYTES W*H/8 #define ACTIV bitRead(PIND, 5) #define LENGR bitRead(PIND, 3) #define SPEER bitRead(PIND, 4) #define VOLUR bitRead(PINC, 0) #define COPYR bitRead(PINC, 1) #define SAVER bitRead(PIND, 2) #define BACKR bitRead(PINC, 4) #define FORWR bitRead(PINC, 5) TVout tv; //////////////////////////////// seq vars below char vol[3][16]; char prevol[3]; char length[3] = {15, 15, 15}; boolean mute[3] = {0, 0, 0}; byte position[3]; byte off[3] = {0, 30, 60}; byte dposition = 0; char modSelectX = 0; char modSelectY = 0; char bpmspeed = 10; byte butDelay = 0; byte pvs = 100; byte prevBut = 100; byte recTimer = 0; boolean external = false; void setup() { //pal/ntsc pinMode(3, INPUT); digitalWrite(3, HIGH); if(digitalRead(3)){ tv.begin(PAL, W, H); }else{ tv.begin(PAL, W, H); } tv.fill(0); //trigger out pinMode(10, OUTPUT); pinMode(11, OUTPUT); pinMode(12, OUTPUT); //controls pinMode(14, INPUT); pinMode(15, INPUT); pinMode(18, INPUT); pinMode(19, INPUT); pinMode(0, INPUT); pinMode(2, INPUT); pinMode(3, INPUT); pinMode(4, INPUT); pinMode(5, INPUT); digitalWrite(14, HIGH); digitalWrite(15, HIGH); digitalWrite(18, HIGH); digitalWrite(19, HIGH); //digitalWrite(0, HIGH); no pullup on t digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); //digitalWrite(5, HIGH); //initialize display settings updateLength(0, off[0]); updateLength(1, off[1]); updateLength(2, off[2]); updateSpeed(91); load(); } void loop() { //internal/external if(external){ digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); //update select/menus updateSelect(); tv.delay_frame(1); updateVolumeOut(0, off[0]); updateVolumeOut(1, off[1]); updateVolumeOut(2, off[2]); if(!ACTIV){ digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); //update sequencer position updatePosition(0, off[0]); updatePosition(1, off[1]); updatePosition(2, off[2]); //update sequencer volume updateVolume(0, off[0]); updateVolume(1, off[1]); updateVolume(2, off[2]); while(!ACTIV){} } digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); tv.delay_frame(1); updateVolumeOut(0, off[0]); updateVolumeOut(1, off[1]); updateVolumeOut(2, off[2]); if(!ACTIV){ //update sequencer position updatePosition(0, off[0]); updatePosition(1, off[1]); updatePosition(2, off[2]); //update sequencer volume updateVolume(0, off[0]); updateVolume(1, off[1]); updateVolume(2, off[2]); while(!ACTIV){} } }else{ //update sequencer position updatePosition(0, off[0]); updatePosition(1, off[1]); updatePosition(2, off[2]); updateVolume(0, off[0]); updateVolume(1, off[1]); updateVolume(2, off[2]); for(byte i=16-bpmspeed; i>0; i--){ digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); tv.delay_frame(1); updateVolumeOut(0, off[0]); updateVolumeOut(1, off[1]); updateVolumeOut(2, off[2]); tv.delay_frame(1); updateVolumeOut(0, off[0]); updateVolumeOut(1, off[1]); updateVolumeOut(2, off[2]); updateSelect(); } } } //draw sequence position inline void updatePosition(byte inp, byte offset){ if(position[inp] < length[inp]){ position[inp]++; }else{ position[inp] = 0; } if(dposition < 15){ dposition++; }else{ dposition = 0; } //clear old tv.draw_rect(0, 22+offset, 95, 2, 0, 0); //draw new tv.draw_rect(sizer(position[inp]), 22+offset, 3, 2, 1, 1); } //draw sequence volume on position inline void updateVolume(byte inp, byte offset){ //send trigger on pins D 10/11/12 if(!mute[inp]){ if(vol[inp][position[inp]] < 15){ //must be 14 because the signal is inverter, for visual reasons. digitalWrite(inp+10, HIGH); } } //clear old tv.draw_rect(sizer(dposition), offset, 3, 16, 1, 1); //draw new tv.draw_rect(sizer(dposition), offset, 3, vol[inp][dposition], 0, 0); } //draw sequence volume on position inline void updateVolumeOut(byte inp, byte offset){ if(!mute[inp]){ if(prevol[inp] > vol[inp][position[inp]]){ prevol[inp]--; } if(prevol[inp] > vol[inp][position[inp]]){ prevol[inp]--; } if(prevol[inp] < vol[inp][position[inp]]){ prevol[inp]++; } if(prevol[inp] < vol[inp][position[inp]]){ prevol[inp]++; } //clear old tv.draw_rect(96, offset, 27, 28, 1, 1); //draw new tv.draw_rect(96, offset, 27, prevol[inp]<<1, 0, 0); } } //lengte van de sequence inline void updateLength(byte inp, byte offset){ //clear tv.draw_rect(0, 26+offset, 95, 2, 0, 0); //draw new tv.draw_rect(0, 26+offset, (sizer(length[inp])+3), 2, 1, 1); } //lengte van de sequence inline void updateSpeed(byte offset){ //clear tv.draw_rect(0, offset, 95, 2, 0, 0); //draw new tv.draw_rect(0, offset, (sizer(bpmspeed)+3), 2, 1, 1); } //buttons enzo.. inline void updateSelect(){ //save only when you realy want to if(!SAVER){ if(recTimer < 21){ recTimer++; //clear old tv.draw_rect(96, 91, 21, 2, 0, 0); //draw new tv.draw_rect(96, 91, recTimer, 2, 1, 1); }else if(recTimer == 21){ recTimer++; store(); } }else{ //clear old tv.draw_rect(96, 91, 22, 2, 0, 0); recTimer = 0; } if(!SPEER){ prevBut = 1; //set speed if(!FORWR){ if(bpmspeed < 15){ bpmspeed++; } }else if(!BACKR){ if(bpmspeed > 0){ bpmspeed--; } }else if(!LENGR){ external = !external; if(external){ //external sync //clear old tv.draw_rect(120, 91, 3, 2, 0, 0); //draw new tv.draw_rect(120, 91, 3, 2, 1, 1); }else{ //clear old tv.draw_rect(120, 91, 3, 2, 1, 1); //draw new tv.draw_rect(120, 91, 3, 2, 0, 0); } }else if(!VOLUR){ //mute channel if(!butDelay){ butDelay = 8; mute[modSelectY] = !mute[modSelectY]; } if(mute[modSelectY]){ //clear old tv.draw_rect(126, off[modSelectY]+1, 1, 27, 0, 0); //draw new tv.draw_rect(126, off[modSelectY]+1, 1, 27, 1, 1); }else{ //clear old tv.draw_rect(126, off[modSelectY]+1, 1, 27, 1, 1); //draw new tv.draw_rect(126, off[modSelectY]+1, 1, 27, 0, 0); } }else if(!COPYR){ //goto last step position[modSelectY] = length[modSelectY]; } while(!LENGR){} updateSpeed(91); }else if(!COPYR){ if(prevBut != 3){ pvs = vol[modSelectY][modSelectX]; } prevBut = 3; if(!FORWR){ modSelectX++; if(modSelectX > 15){ modSelectX = 0; modSelectY++; if(modSelectY > 2){ modSelectY = 0; } } } if(!BACKR){ modSelectX--; if(modSelectX < 0){ modSelectX = 15; modSelectY--; if(modSelectY < 0){ modSelectY = 2; } } } vol[modSelectY][modSelectX] = pvs; //clear old volume at position tv.draw_rect(sizer(modSelectX), off[modSelectY], 3, 16, 1, 1); //draw new volume at position tv.draw_rect(sizer(modSelectX), off[modSelectY], 3, vol[modSelectY][modSelectX], 0, 0); }else if(!LENGR){ prevBut = 0; //set length if(!FORWR){ if(length[modSelectY] < 15){ length[modSelectY]++; } }else if(!BACKR){ if(length[modSelectY] > 0){ length[modSelectY]--; } } updateLength(modSelectY, off[modSelectY]); }else if(!VOLUR){ prevBut = 2; //set volume if(!BACKR){ if(vol[modSelectY][modSelectX] < 15){ vol[modSelectY][modSelectX]++; } }else if(!FORWR){ if(vol[modSelectY][modSelectX] > 0){ vol[modSelectY][modSelectX]--; } } //clear old volume at position tv.draw_rect(sizer(modSelectX), off[modSelectY], 3, 15, 1, 1); //draw new volume at position tv.draw_rect(sizer(modSelectX), off[modSelectY], 3, vol[modSelectY][modSelectX], 0, 0); }else{ //move cursor if(!FORWR){ modSelectX++; if(modSelectX > 15){ modSelectX = 0; modSelectY++; if(modSelectY > 2){ modSelectY = 0; } } } if(!BACKR){ modSelectX--; if(modSelectX < 0){ modSelectX = 15; modSelectY--; if(modSelectY < 0){ modSelectY = 2; } } } } if(butDelay){ butDelay--; } //clear old select tv.draw_rect(0, off[0]+18, 95, 2, 0, 0); tv.draw_rect(0, off[1]+18, 95, 2, 0, 0); tv.draw_rect(0, off[2]+18, 95, 2, 0, 0); //draw new tv.draw_rect(sizer(modSelectX), off[modSelectY]+18, 3, 2, 1, 1); } char sizer(char i){ return (i<<2)+(i<<1); } void store(){ int address = 0; //schrijf voor de zekerheid een var hier. EEPROM.write(address, 255); address++; for(byte i=0; i<3; i++){ for(byte j=0; j<16; j++){ EEPROM.write(address, vol[i][j]); address++; } } for(byte i=0; i<3; i++){ EEPROM.write(address, prevol[i]); address++; } for(byte i=0; i<3; i++){ EEPROM.write(address, length[i]); address++; } for(byte i=0; i<3; i++){ EEPROM.write(address, position[i]); address++; } EEPROM.write(address, bpmspeed); address++; EEPROM.write(address, external); } void load(){ int address = 0; if(EEPROM.read(0) == 255){ address++; for(byte i=0; i<3; i++){ for(byte j=0; j<16; j++){ vol[i][j] = constrain(EEPROM.read(address), 0, 17); address++; } } for(byte i=0; i<3; i++){ prevol[i] = constrain(EEPROM.read(address), 0, 17); address++; } for(byte i=0; i<3; i++){ length[i] = constrain(EEPROM.read(address), 0, 17); address++; } for(byte i=0; i<3; i++){ position[i] = constrain(EEPROM.read(address), 0, 17); address++; } bpmspeed = constrain(EEPROM.read(address), 0, 17); address++; external = constrain(EEPROM.read(address), 0, 1); updateLength(0, off[0]); updateLength(1, off[1]); updateLength(2, off[2]); updateSpeed(91); } }