/* by nick lally, with help from: Background Subtraction by Golan Levin. */ import processing.video.*; import rwmidi.*; // midiNote in C int [] midiNote = {21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 96, 98, 100, 101, 103, 105}; MidiInput input; MidiOutput output; //start with no music mode selected to avoid noise int musicMode = 0; // colorSensor coords int [] colorSensorX = new int[midiNote.length]; int [] colorSensorY = new int[midiNote.length]; int count = 0; int backgroundCount = 0; int midiCount = 0; int numPixels; int[] backgroundPixels; int[] backgroundPixels2; Capture video; Capture video2; void setup() { // Change size to 320 x 240 if too slow at 640 x 480 size(640, 480, P2D); String[] devices = Capture.list(); println(devices); video = new Capture(this, width, height, devices[0], 24); video2 = new Capture(this, width, height, devices[1], 24); numPixels = video.width * video.height; // Create array to store the background image backgroundPixels = new int[numPixels]; backgroundPixels2 = new int[numPixels]; // Make the pixels[] array available for direct manipulation loadPixels(); //populate colorsensor arrays for (int i = 0; i < colorSensorX.length; i++){ colorSensorX[i] = (i%28)*23 + 20; colorSensorY[i] = i/14*15 + 20; } output = RWMidi.getOutputDevices()[0].createOutput(); } void draw() { if (video.available()) { video.read(); // Read a new video frame video2.read(); // Read a new video frame video.loadPixels(); // Make the pixels of video available video2.loadPixels(); // Make the pixels of video available // Difference between the current frame and the stored background int presenceSum = 0; for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame... // Fetch the current color in that location, and also the color // of the background in that spot color currColor = video.pixels[i]; color currColor2 = video2.pixels[i]; color bkgdColor = backgroundPixels[i]; color bkgdColor2 = backgroundPixels2[i]; // Extract the red, green, and blue components of the current pixel’s color int currR = (currColor >> 16) & 0xFF; int currG = (currColor >> 8) & 0xFF; int currB = currColor & 0xFF; int currR2 = (currColor2 >> 16) & 0xFF; int currG2 = (currColor2 >> 8) & 0xFF; int currB2 = currColor2 & 0xFF; // Extract the red, green, and blue components of the background pixel’s color int bkgdR = (bkgdColor >> 16) & 0xFF; int bkgdG = (bkgdColor >> 8) & 0xFF; int bkgdB = bkgdColor & 0xFF; int bkgdR2 = (bkgdColor2 >> 16) & 0xFF; int bkgdG2 = (bkgdColor2 >> 8) & 0xFF; int bkgdB2 = bkgdColor2 & 0xFF; // Compute the difference of the red, green, and blue values int diffR = abs(currR - bkgdR); int diffG = abs(currG - bkgdG); int diffB = abs(currB - bkgdB); int diffR2 = abs(currR2 - bkgdR2); int diffG2 = abs(currG2 - bkgdG2); int diffB2 = abs(currB2 - bkgdB2); // Add these differences to the running tally presenceSum += diffR + diffG + diffB; //render difference to grey if(((diffR + diffG + diffB) > 150) || ((diffR2 + diffG2 + diffB2) > 150)){ pixels[i] = color(100); //if both are different, render red if(((diffR + diffG + diffB) > 150) && ((diffR2 + diffG2 + diffB2) > 150)){ pixels[i] = color(255, 0, 0); } } else { pixels[i] = color(255); } } //select music mode if (musicMode == 1){ musicMode1(); } else if (musicMode == 2){ musicMode2(); } else if (musicMode == 3){ musicMode3(); } else if (musicMode == 4){ musicMode4(); } updatePixels(); // Notify that the pixels[] array has changed //println(presenceSum); // Print out the total amount of movement } //println(midiNote.length); //image(video2, 0, 0); } // Check for pressed key. 1, 2, 3 change music mode, everything else runs backgroundCapture() void keyPressed() { if (key == '1') { musicMode = 1; output.sendNoteOn(6, 60, 100); }else if (key == '2') { musicMode = 2; output.sendNoteOn(6, 60, 100); }else if (key == '3'){ musicMode = 3; output.sendNoteOn(6, 60, 100); }else if (key == '4'){ musicMode = 4; output.sendNoteOn(6, 60, 100); }else{ backgroundCapture(); } //send off notes to all channels for (int i = 0; i< midiNote.length; i++) { output.sendNoteOff(0, midiNote[i], 100); output.sendNoteOff(1, midiNote[i], 100); output.sendNoteOff(2, midiNote[i], 100); output.sendNoteOff(3, midiNote[i], 100); output.sendNoteOff(4, midiNote[i], 100); output.sendNoteOff(5, midiNote[i], 100); } output.sendNoteOff(6, 60, 100); } void mousePressed() { backgroundCapture(); //send off notes to all channels for (int i = 0; i< midiNote.length; i++) { output.sendNoteOff(0, midiNote[i], 100); output.sendNoteOff(1, midiNote[i], 100); output.sendNoteOff(2, midiNote[i], 100); output.sendNoteOff(3, midiNote[i], 100); output.sendNoteOff(4, midiNote[i], 100); output.sendNoteOff(5, midiNote[i], 100); } } //capture the background image into the backgroundPixels // buffer, by copying each of the current frame’s pixels into it. void backgroundCapture(){ video.loadPixels(); arraycopy(video.pixels, backgroundPixels); video2.loadPixels(); arraycopy(video2.pixels, backgroundPixels2); } //music mode number 1 void musicMode1() { //colorsensor to send midinotes if pixel is red for (int i = 0; i< midiNote.length; i++) { //limit 10 note polyphony if (midiCount < 10){ color p = get(colorSensorX[i], colorSensorY[i]); float r = red(p); float g = green(p); float b = blue(p); if (r == 255 && g == 0 && b == 0){ output.sendNoteOn(0, midiNote[i], 100); //println("send note"); fill(0, 255, 0); //ellipse(colorSensorX[i], colorSensorY[i], 20,20); midiCount++; //println(midiCount); } if (r != 255){ output.sendNoteOff(0, midiNote[i], 100); } } } midiCount = 0; } void musicMode2() { //colorsensor to send midinotes if pixel is red for (int i = 0; i< midiNote.length; i++) { //limit 10 note polyphony if (midiCount < 5){ color p = get(colorSensorX[i], colorSensorY[i]); float r = red(p); float g = green(p); float b = blue(p); if (r == 255 && g == 0 && b == 0){ output.sendNoteOn(1, midiNote[i], 100); output.sendNoteOn(2, midiNote[i], 100); //println("send note"); fill(0, 255, 0); //ellipse(colorSensorX[i], colorSensorY[i], 20,20); midiCount++; //println(midiCount); } if (r != 255){ output.sendNoteOff(1, midiNote[i], 100); output.sendNoteOff(2, midiNote[i], 100); } } } midiCount = 0; } void musicMode3() { //colorsensor to send midinotes if pixel is red for (int i = 0; i< midiNote.length; i++) { //limit 10 note polyphony if (midiCount < 5){ color p = get(colorSensorX[i], colorSensorY[i]); float r = red(p); float g = green(p); float b = blue(p); if (r == 255 && g == 0 && b == 0){ output.sendNoteOn(3, midiNote[i], 100); output.sendNoteOn(4, midiNote[i], 100); //println("send note"); fill(0, 255, 0); //ellipse(colorSensorX[i], colorSensorY[i], 20,20); midiCount++; //println(midiCount); } if (r != 255){ output.sendNoteOff(3, midiNote[i], 100); output.sendNoteOff(4, midiNote[i], 100); } } } midiCount = 0; } void musicMode4() { //colorsensor to send midinotes if pixel is red for (int i = 0; i< midiNote.length; i++) { //limit 10 note polyphony if (midiCount < 5){ color p = get(colorSensorX[i], colorSensorY[i]); float r = red(p); float g = green(p); float b = blue(p); if (r == 255 && g == 0 && b == 0){ output.sendNoteOn(5, midiNote[i], 100); //println("send note"); fill(0, 255, 0); //ellipse(colorSensorX[i], colorSensorY[i], 20,20); midiCount++; //println(midiCount); } if (r != 255){ output.sendNoteOff(5, midiNote[i], 100); } } } midiCount = 0; }