import arb.soundcipher.*; import arb.soundcipher.constants.*; //score.addNote(start beat, pitch, volume(1-100), length) import processing.video.*; float clipFrameRate = 30; //fps int numKeys = 88; int startFrame = 0; //use to skip intros int targetTempo = 120; String fileName = "megalovania"; int fileSizex = 640; int fileSizey = 360; int quantization = 128;// 1/quantization th note (i.e. 4-->quarter note, 8-->eighth note float beatLength = 60000/targetTempo; float frameLength = 1000/clipFrameRate; float keyWidth = float(fileSizex) / float(numKeys+1); int frame = 0; double timer = millis() + 2500; int[] checkPoints; int checkHeight = fileSizey - 60; color[] defaults; ArrayList data; //data.get(beat)[pitch] Movie clip; SCScore converted; void setup() { //fullScreen(); size(640, 360); data = new ArrayList(); checkPoints = new int[numKeys]; defaults = new color[numKeys]; clip = new Movie(this, fileName + ".mp4"); //clip.frameRate(20); converted = new SCScore(); converted.tempo(targetTempo); noStroke(); for (int i = 0; i < numKeys; i++) { checkPoints[i] = int(keyWidth * float(i+1)); } //incrementFrame(); clip.play(); delay(3000); image(clip, 0, 0); //delay(3000); loadPixels(); for (int i = 0; i < numKeys; i++) { int x = checkPoints[i]; int y = checkHeight; defaults[i] = pixels[y*fileSizex+x]; } //delay(2000); } void draw() { if (millis() - timer < 8000 && !(key == ' ') && !keyPressed && timer != -1) { image(clip, 0, 0); } else { //println("done"); clip.stop(); processVid(); converted.writeMidiFile("/Users/chinmay/Downloads/" + fileName + ".mid"); exit(); } } void movieEvent(Movie m) { //println("available"); m.read(); timer = millis(); loadPixels(); data.add(new Boolean[numKeys]); for (int i = 0; i < numKeys; i++) { int x = checkPoints[i]; int y = checkHeight; //println(i); //println(data); //println(red(pixels[y*fileSizex+x]) + " " + green(pixels[y*fileSizex+x]) + " " + blue(pixels[y*fileSizex+x])); //println(red(defaults[i]) + " " + green(defaults[i]) + " " + blue(defaults[i])); if (!sameColor(pixels[y*fileSizex+x], defaults[i], 30)) { data.get(frame)[i] = true; fill(50); } else { data.get(frame)[i] = false; fill(210); } //ellipse(checkPoints[i], fileSizey-keyWidth, 3, 3); } //println("running"); //printData(frame); frame++; } void incrementFrame() { clip.play(); delay(int(1000/clipFrameRate/2)); clip.pause(); frame++; } float quantize(int frame, int quan) { float q = quan/4; float a = frame * frameLength / beatLength; a = round(a * q) / q; return(a); } Boolean sameColor(color x, color y, float range) { Boolean r = abs(red(x) - red(y)) < range; Boolean g = abs(green(x) - green(y)) < range; Boolean b = abs(blue(x) - blue(y)) < range; return(r && g && b); } void processVid() { Boolean keyReleased; int pos = 0; for (int i = 0; i < numKeys; i++) { keyReleased = true; for (int j = 0; j < data.size(); j++) { if (data.get(j)[i] && keyReleased) { keyReleased = false; pos = j; } else if (!data.get(j)[i] && !keyReleased) { keyReleased = true; converted.addNote(quantize(pos, quantization), i+21, 75, quantize(j-pos, quantization)); } } } } void printData(int i) { for(int j = 0; j< numKeys; j++) { if(data.get(i)[j]) { print("1"); } else { print("0"); } //print(" "); } println(); }