An abstract video¬†made for Video Sculpture¬†that portrays the adjective “hidden”. I kind of went nuts on this one…
 
The source footage is simply skyscrapers, but the video was generated using the ofxFreeFrame addon for openFrameworks. Filters applied to the image include a mirror, a film strip, a pixelator, and a background substractor.
The sound was generated in Processing using the¬†Minim library. It is basically a sine wave with the frequency mapped to the amount of black pixels in the frame, and the pan mapped to the amount of white pixels in the frame. Yes, it’s annoying, but I like it.
Here’s the Processing code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | import ddf.minim.*; import ddf.minim.signals.*; //------------------------------------- AudioRecorder recorder; AudioPlayer player; AudioOutput out; SineWave sine; PImage img; int blackPx, whitePx; int processFrame = 1; int playbackFrame = 0; int numFrames = 1721; float[] dataBlack, dataWhite; boolean recording; //------------------------------------- void setup() { size(640, 480); stroke(255); smooth(); dataBlack = new float[numFrames]; dataWhite = new float[numFrames]; Minim.start(this); recording = false; } //------------------------------------- void draw() { if (processFrame <= numFrames) { print("Analyzing frame " + nf(currFrame, 4)); // load the next frame img = loadImage("hidden" + nf(currFrame, 4) + ".png"); // calculate the number of totally black and totally white pixels blackPx = whitePx = 0; for (int i=0; i < img.width*img.height; i++) { if ((img.pixels[i]) == 0xFF000000) { blackPx++; } else if ((img.pixels[i]) == 0xFFFFFFFF) { whitePx++; } } // save the data println(":: " + blackPx + " blackPx | " + whitePx + " whitePx"); dataBlack[currFrame-1] = blackPx; dataWhite[currFrame-1] = whitePx; // draw the frame on screen image(img, 0, 0); processFrame++; } else if (!recording) { print("Recording..."); recording = true; // open an output channel out = Minim.getLineOut(Minim.STEREO, numFrames); // generate a sine wave sine = new SineWave(440, 0.5, 44100); sine.portamento(200); // add it to the output out.addSignal(sine); // record the output recorder = Minim.createRecorder(out, "generated-sound.wav", true); recorder.beginRecord(); } else { // map the black pixel data to the sine frequency float freq = map(dataBlack[playbackFrame], 0, 640*480, 1500, 60); sine.setFreq(freq); // map the white pixel data to the sine pan float pan = map(dataWhite[playbackFrame], 0, 640*480, -1, 1); sine.setPan(pan); // draw the waveforms background(0); for(int i = 0; i < out.left.size()-1; i++) { line(i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50); line(i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50); } playbackFrame++; if (playbackFrame == numFrames) { println(" done!"); if (recorder.isRecording()) { // stop recording and save the sound to disk recorder.endRecord(); recorder.save(); } exit(); } } } //------------------------------------- void stop() { out.close(); if (player != null) player.close(); super.stop(); } |
Beautiful, unsettling, intricate.