diff --git a/software/apps/Processing/Music/Music_Controls/Controller_Functions.pde b/software/apps/Processing/Music/Music_Controls/Controller_Functions.pde new file mode 100644 index 0000000..006a66d --- /dev/null +++ b/software/apps/Processing/Music/Music_Controls/Controller_Functions.pde @@ -0,0 +1,330 @@ +String[] knobName = { "FREQ1", + "SEMI1", + "DETUNE1", + "GAIN1", + "WAVE1", + "FREQ2", + "SEMI2", + "DETUNE2", + "GAIN2", + "WAVE2", + "FREQ3", + "SEMI3", + "DETUNE3", + "GAIN3", + "WAVE3", + "ATTACK", + "DECAY", + "SUSTAIN", + "RELEASE", + "DETUNE_ALL", + "WAVE_ALL" + }; + +String[] controllerName = { "freq1", + "semi1", + "detune1", + "gain1", + "wave1", + "freq2", + "semi2", + "detune2", + "gain2", + "wave2", + "freq3", + "semi3", + "detune3", + "gain3", + "wave3", + "attack", + "decay", + "sustain", + "release" + }; + + + +String[] waveform = { "SINE", + "SQUARE", + "PULSE", + "TRIANGLE", + "SAW", + "FUZZ", + "DIGI1", + "DIGI2", + "DIGI3", + "DIGI4", + "NOISE", + "DIGI6", + "TAN1", + "TAN2", + "TAN3", + "TAN4" + }; + +int[] knobMidiCC = {10,11,12,13,14,20,21,22,23,24,30,31,32,33,34,114,115,116,117,4,5}; + + +void setupKnobs() { + + controlP5 = new ControlP5(this); + PFont p = createFont("Georgia",12); + controlP5.setControlFont(p,12); + controlP5.setColorLabel(color(255,128)); + + Textlabel labelFreq = controlP5.addTextlabel("freqLabel","FREQ",posX+posW*0,posY-20); + Textlabel labelSemi = controlP5.addTextlabel("semiLabel","SEMI",posX+posW*1,posY-20); + Textlabel labelDetune = controlP5.addTextlabel("detuneLabel","DETUNE",posX+posW*2,posY-20); + Textlabel labelGain = controlP5.addTextlabel("gainLabel","GAIN",posX+posW*3,posY-20); + Textlabel labelWave = controlP5.addTextlabel("waveLabel","WAVE",posX+posW*4,posY-20); + + Textlabel labelAttack = controlP5.addTextlabel("attackLabel","A",posX+16+posW*0,posY+posH*4-20); + Textlabel labelDecay = controlP5.addTextlabel("decayLabel","D",posX+16+posW*1,posY+posH*4-20); + Textlabel labelsustain = controlP5.addTextlabel("sustainLabel","S",posX+16+posW*2,posY+posH*4-20); + Textlabel labelReleasek = controlP5.addTextlabel("releaseLabel","R",posX+16+posW*3,posY+posH*4-20); + + Knob freq1 = controlP5.addKnob("freq1", 0,127,64, posX+posW*0,posY+posH*0,knobS); + Knob semi1 = controlP5.addKnob("semi1", -24,24,0, posX+posW*1,posY+posH*0,knobS); + Knob detune1 = controlP5.addKnob("detune1",0,127,64, posX+posW*2,posY+posH*0,knobS); + Knob gain1 = controlP5.addKnob("gain1", 0,127,127, posX+posW*3,posY+posH*0,knobS); + Knob wave1 = controlP5.addKnob("wave1", 0,15,0, posX+posW*4,posY+posH*0,knobS); + + Knob freq2 = controlP5.addKnob("freq2", 0,127,64, posX+posW*0,posY+posH*1,knobS); + Knob semi2 = controlP5.addKnob("semi2", -24,24,0, posX+posW*1,posY+posH*1,knobS); + Knob detune2 = controlP5.addKnob("detune2",0,127,64, posX+posW*2,posY+posH*1,knobS); + Knob gain2 = controlP5.addKnob("gain2", 0,127,127, posX+posW*3,posY+posH*1,knobS); + Knob wave2 = controlP5.addKnob("wave2", 0,15,0, posX+posW*4,posY+posH*1,knobS); + + Knob freq3 = controlP5.addKnob("freq3", 0,127,64, posX+posW*0,posY+posH*2,knobS); + Knob semi3 = controlP5.addKnob("semi3", -24,24,0, posX+posW*1,posY+posH*2,knobS); + Knob detune3 = controlP5.addKnob("detune3",0,127,64, posX+posW*2,posY+posH*2,knobS); + Knob gain3 = controlP5.addKnob("gain3", 0,127,127, posX+posW*3,posY+posH*2,knobS); + Knob wave3 = controlP5.addKnob("wave3", 0,15,0, posX+posW*4,posY+posH*2,knobS); + + Knob attack = controlP5.addKnob("attack", 0,127,0, posX+posW*0, posY+posH*4, knobS); + Knob decay = controlP5.addKnob("decay", 0,127,64, posX+posW*1, posY+posH*4, knobS); + Knob sustain = controlP5.addKnob("sustain",0,127,64, posX+posW*2, posY+posH*4, knobS); + Knob release = controlP5.addKnob("release",0,127,64, posX+posW*3, posY+posH*4, knobS); + +} + +void writeKnobValues() { + textAlign(CENTER); + fill(128); + text(knobValue[0],40,90); + text(knobValue[1],100,90); + text(knobValue[2],160,90); + text(knobValue[3],220,90); + text(waveform[knobValue[4]],280,90); + text(knobValue[5],40,150); + text(knobValue[6],100,150); + text(knobValue[7],160,150); + text(knobValue[8],220,150); + text(waveform[knobValue[9]],280,150); + text(knobValue[10],40,210); + text(knobValue[11],100,210); + text(knobValue[12],160,210); + text(knobValue[13],220,210); + text(waveform[knobValue[14]],280,210); + text(knobValue[15],40,330); + text(knobValue[16],100,330); + text(knobValue[17],160,330); + text(knobValue[18],220,330); +} + +void freq1(int val) +{ + int knob = 0; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz"); + //(2^((p-69)/12))*440 + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void semi1(int val) +{ + int knob = 1; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + int semi =(knobValue[knob]+24)*2+16; + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi); + } +} + +void detune1(int val) +{ + int knob = 2; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void gain1(int val) +{ + int knob = 3; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void wave1(int val) +{ + int knob = 4; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")"); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8)); + } +} + +void freq2(int val) +{ + int knob = 5; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz"); + //(2^((p-69)/12))*440 + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void semi2(int val) +{ + int knob = 6; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + int semi =(knobValue[knob]+24)*2+16; + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi); + } +} + +void detune2(int val) +{ + int knob = 7; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void gain2(int val) +{ + int knob = 8; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void wave2(int val) +{ + int knob = 9; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")"); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8)); + } +} + +void freq3(int val) +{ + int knob = 10; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz"); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void semi3(int val) +{ + int knob = 11; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + int semi =(knobValue[knob]+24)*2+16; + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi); + } +} + +void detune3(int val) +{ + int knob = 12; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void gain3(int val) +{ + int knob = 13; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void wave3(int val) +{ + int knob = 14; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")"); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8)); + } +} + +void attack(int val) +{ + int knob = 15; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void decay(int val) +{ + int knob = 16; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void sustain(int val) +{ + int knob = 17; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + +void release(int val) +{ + int knob = 18; + if(knobValue[knob] != val) { + knobValue[knob] = val; + if(printChange) println(knobName[knob] + " is: " + knobValue[knob]); + sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]); + } +} + + diff --git a/software/apps/Processing/Music/Music_Controls/Music_Controls.pde b/software/apps/Processing/Music/Music_Controls/Music_Controls.pde new file mode 100644 index 0000000..68d65ee --- /dev/null +++ b/software/apps/Processing/Music/Music_Controls/Music_Controls.pde @@ -0,0 +1,71 @@ +//import oscP5.*; +//import netP5.*; +import controlP5.*; +import rwmidi.*; // watch out for this +import processing.serial.*; + +ControlP5 controlP5; +MidiInput input; +Serial port0; + +boolean printChange = true; + +int backgroundColor = color(0,0,0); +int knobColor = color(235,103,295); + +int numKnobs = 19; +int[] knobValue = new int[numKnobs]; + +int posX = 20; +int posY = 40; +int posW = 60; +int posH = 60; +int knobS = 40; + +long time = 0; +long lastTime = 0; +long timePassed; +long timeAllowed = 10; + +int delayTime = 40; + +void setup() { + + size(400,400); + smooth(); + background(0); + + setupKnobs(); + + //println("print MIDI input devices:"); + //println(RWMidi.getInputDeviceNames()); + input = RWMidi.getInputDevices()[0].createInput(this); + + //println(Serial.list()); + port0 = new Serial(this, Serial.list()[0], 9600); +} + + +void draw() { + background(backgroundColor); + writeKnobValues(); +} + + +void keyPressed() { + if(key=='s' || key=='S') { + saveKnobValues(); + } + if(key=='l' || key=='L') { + loadKnobValues(); + } +} + + +void keyReleased() { + if(key=='l' || key=='L') { + sendMidiKnobs(); + } +} + + diff --git a/software/apps/Processing/Music/Music_Controls/knobValues.txt b/software/apps/Processing/Music/Music_Controls/knobValues.txt new file mode 100644 index 0000000..a60b1cb Binary files /dev/null and b/software/apps/Processing/Music/Music_Controls/knobValues.txt differ diff --git a/software/apps/Processing/Music/Music_Controls/midi_handling.pde b/software/apps/Processing/Music/Music_Controls/midi_handling.pde new file mode 100644 index 0000000..2a943ff --- /dev/null +++ b/software/apps/Processing/Music/Music_Controls/midi_handling.pde @@ -0,0 +1,66 @@ +void noteOnReceived(Note note) { + + byte channel = byte(note.getChannel()); + byte pitch = byte(note.getPitch()); + byte velocity = byte(note.getVelocity()); + + sendNoteOn(channel, pitch, velocity); + +} + +void noteOffReceived(Note note) { + + byte channel = byte(note.getChannel()); + byte pitch = byte(note.getPitch()); + byte velocity = byte(note.getVelocity()); + + sendNoteOff(channel, pitch, velocity); + +} + +void controllerChangeReceived(rwmidi.Controller controller) { + + byte channel = byte(controller.getChannel()); + byte CC = byte(controller.getCC()); + byte value = byte(controller.getValue()); + + sendControlChange(channel, CC, value); +} + + +void sendNoteOn(byte channel, byte pitch, byte velocity) { + + byte noteOn = byte(0x90 | channel); + + port0.write(noteOn); + port0.write(pitch); + port0.write(velocity); + //println('\n' + hex(noteOn) + " " + hex(pitch) + " " + hex(velocity)); + +} + +void sendNoteOff(byte channel, byte pitch, byte velocity) { + + byte noteOff = byte(0x80 | channel); + + port0.write(noteOff); + port0.write(pitch); + port0.write(velocity); + //println('\n' + hex(noteOff) + " " + hex(pitch) + " " + hex(velocity)); + +} + +void sendControlChange(byte channel, byte CC, byte value) { + time = millis(); + timePassed = time - lastTime; + if(timePassed > timeAllowed) { + lastTime = time; + + byte controlChange = byte(0xB0 | channel); + + port0.write(controlChange); + port0.write(CC); + port0.write(value); + //println('\n' + hex(controlChange) + " " + hex(CC) + " " + hex(value)); + } +} diff --git a/software/apps/Processing/Music/Music_Controls/saving_loading.pde b/software/apps/Processing/Music/Music_Controls/saving_loading.pde new file mode 100644 index 0000000..b4f53a6 --- /dev/null +++ b/software/apps/Processing/Music/Music_Controls/saving_loading.pde @@ -0,0 +1,112 @@ +byte[] savedKnobValues = new byte[numKnobs]; +byte[] loadedKnobValues = new byte[numKnobs]; + + +void loadKnobValues() { + + loadedKnobValues = loadBytes("knobValues.txt"); + + for(int i=0; i