|
|
Line 20: |
Line 20: |
| font-family: "bebas"; | | font-family: "bebas"; |
| } | | } |
− | #BMG h5 { | + | h5 { |
| font-size: 28px; | | font-size: 28px; |
| color: white; | | color: white; |
| font-family: "bebasneue"; | | font-family: "bebasneue"; |
| } | | } |
− | #BMG p { | + | p { |
| color: white; | | color: white; |
| font-family: "helveticaNL"; | | font-family: "helveticaNL"; |
Line 45: |
Line 45: |
| document.getElementById("BMGText").style.display = "none"; | | document.getElementById("BMGText").style.display = "none"; |
| document.getElementById("BMG").className = "collapsed"; | | document.getElementById("BMG").className = "collapsed"; |
| + | }; |
| + | } |
| + | function expandButton() { |
| + | if (document.getElementById("Button").className === "collapsed") { |
| + | document.getElementById("Button").style.color = "goldenrod"; |
| + | document.getElementById("ButtonText").style.display = "inline-block"; |
| + | document.getElementById("Button").className = "expanded"; |
| + | } else{ |
| + | document.getElementById("Button").style.color = "white"; |
| + | document.getElementById("ButtonText").style.display = "none"; |
| + | document.getElementById("Button").className = "collapsed"; |
| }; | | }; |
| } | | } |
Line 56: |
Line 67: |
| <br> | | <br> |
| <p id="BMGText" style="display:none"> | | <p id="BMGText" style="display:none"> |
− | //main | + | Something |
− | <br>import processing.video.*;
| + | </p> |
− | <br>import arb.soundcipher.*;
| + | </div> |
− | <br>import blobDetection.*;
| + | <div id="Button"class="collapsed" onclick="expandButton()"> |
− | | + | <h5 style="display:inline-block"><span class="noselect">Button Control</span></h5> |
− | <br><br>Capture video_sequencer, video_rack;
| + | <br> |
− | <br>SoundCipher sc = new SoundCipher(this);
| + | <p id="ButtonText" style="display:none"> |
− | | + | Something |
− | <br><br>int grid_size=20;
| + | |
− | <br>int grid_num=16;
| + | |
− | <br>int window_size;
| + | |
− | <br>int window_height;
| + | |
− | <br>int block_number=3;
| + | |
− | | + | |
− | <br><br>int interval=4;
| + | |
− | <br>int margin;
| + | |
− | <br>int n=0;//iterator for play()
| + | |
− | | + | |
− | <br><br>boolean[] camera= new boolean[block_number];
| + | |
− | <br>boolean[] music=new boolean[block_number];
| + | |
− | <br>boolean tube=false;
| + | |
− | <br>int[] volume=new int[block_number];
| + | |
− | | + | |
− | <br><br>Sequencer[] sequencer= new Sequencer[block_number];
| + | |
− | <br>Sequencer_video sequencer_video;
| + | |
− | <br>Rack rack;
| + | |
− | | + | |
− | <br><br>void setup() {
| + | |
− | <br>volume[0]=0; | + | |
− | <br>volume[1]=0;
| + | |
− | <br>volume[2]=0;
| + | |
− | <br>window_size=displayWidth;
| + | |
− | <br>window_height=displayHeight;
| + | |
− | | + | |
− | <br><br>margin=(window_size-(grid_num*(grid_size+interval)+interval)
| + | |
− | <br>*block_number)/(block_number+1);
| + | |
− | | + | |
− | <br>size(window_size, window_height);
| + | |
− | | + | |
− | <br><br>//empty tracks
| + | |
− | <br>for (int i=0; i<block_number; i++) {
| + | |
− | <br>camera[i]=false;
| + | |
− | <br>music[i]=false;
| + | |
− | }
| + | |
− | | + | |
− | <br><br>make_empty();
| + | |
− | | + | |
− | <br><br>String[] cameras = Capture.list();
| + | |
− |
| + | |
− | <br><br>video_sequencer = new Capture(this, cameras[0]);
| + | |
− | <br>video_sequencer.start();
| + | |
− | <br>sequencer_video=new Sequencer_video(video_sequencer, sc, grid_num, grid_size, interval);
| + | |
− | | + | |
− | <br><br>video_rack = new Capture(this, cameras[15]);
| + | |
− | <br>video_rack.start();
| + | |
− | <br>rack=new Rack(video_rack, sc, window_size, window_height,
| + | |
− | <br>window_height-margin-grid_num*(grid_size+interval));
| + | |
− | | + | |
− | <br><br>frameRate(4);
| + | |
− | }
| + | |
− | | + | |
− | <br><br>void draw() {
| + | |
− | <br>background(0);
| + | |
− | <br>if (tube) {
| + | |
− | <br>rack.get_color();
| + | |
− | <br>rack.draw_rack();
| + | |
− | <br>rack.glow(n);
| + | |
− | <br>rack.play_sounds(n);
| + | |
− | }
| + | |
− | | + | |
− | <br><br>for (int i=0; i<block_number; i++) {
| + | |
− | <br>sequencer[i].draw_grid();
| + | |
− | <br>if (camera[i]&&!music[i]) {
| + | |
− | <br>sequencer_video.position(pos_x(i), margin);
| + | |
− | <br>sequencer_video.grid_off();
| + | |
− | <br>sequencer_video.bd();
| + | |
− | <br>sequencer_video.bd_draw(n);
| + | |
− | <br>} else if (camera[i]&&music[i]) {
| + | |
− | <br>sequencer_video.position(pos_x(i), margin);
| + | |
− | <br>sequencer_video.grid_on();
| + | |
− | <br>sequencer_video.bd();
| + | |
− | <br>sequencer_video.bd_draw(n);
| + | |
− | <br>} else if (!camera[i]&&music[i]) {
| + | |
− | <br>sequencer[i].set_volume(volume[i]);
| + | |
− | <br>sequencer[i].play_sounds(n);
| + | |
− | <br>sequencer[i].glow(n);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>n++;
| + | |
− | <br>if (n>=grid_num) {
| + | |
− | <br>n=0;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | | + | |
− | <br><br>void keyPressed() {
| + | |
− | <br>//track 1
| + | |
− | <br>if (key=='q'||key=='Q') {
| + | |
− | <br>if (camera[0]==false &&camera[1]==false &&camera[2]==false) {
| + | |
− | camera[0]=true;
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='w'||key=='W') {
| + | |
− | <br>camera[0]=false;
| + | |
− | <br>if (music[0]) {
| + | |
− | <br>sequencer[0].get_sequence(sequencer_video.sequence());
| + | |
− | <br>sequencer[0].get_color(sequencer_video.grid_color());
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='e'||key=='E') {
| + | |
− | <br>music[0]=true;
| + | |
− | <br>} else if (key=='r'||key=='R') {
| + | |
− | <br>music[0]=false;
| + | |
− | <br>sequencer[0].delete();
| + | |
− | <br>} else if (key=='t'||key=='T') {
| + | |
− | <br>if (music[0]) {
| + | |
− | | + | |
− | <br><br>if (camera[0]) {
| + | |
− | <br>sequencer_video.set_volume(volume[0]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[0].set_volume(volume[0]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='y'||key=='Y') {
| + | |
− | <br>if (music[0]) {
| + | |
− | <br>volume[0]=constrain(volume[0]+5, 0, 127);
| + | |
− | <br>if (camera[0]) {
| + | |
− | <br>.set_volume(volume[0]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[0].set_volume(volume[0]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>//track 2
| + | |
− | <br>else if (key=='a'||key=='A') {
| + | |
− | <br>if (camera[0]==false &&camera[1]==false &&camera[2]==false) {
| + | |
− | camera[1]=true;
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='s'||key=='S') {
| + | |
− | <br>camera[1]=false;
| + | |
− | <br>if (music[1]) {
| + | |
− | <br>sequencer[1].get_sequence(sequencer_video.sequence());
| + | |
− | <br>sequencer[1].get_color(sequencer_video.grid_color());
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='d'||key=='D') {
| + | |
− | <br>music[1]=true;
| + | |
− | <br>} else if (key=='f'||key=='F') {
| + | |
− | <br>music[1]=false;
| + | |
− | <br>sequencer[1].delete();
| + | |
− | <br>} else if (key=='g'||key=='G') {
| + | |
− | <br>if (music[1]) {
| + | |
− | <br>volume[1]=constrain(volume[1]-5, 0, 127);
| + | |
− | <br>if (camera[1]) {
| + | |
− | <br>sequencer_video.set_volume(volume[1]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[1].set_volume(volume[1]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='h'||key=='H') {
| + | |
− | <br>if (music[1]) {
| + | |
− | <br>volume[1]=constrain(volume[1]+5, 0, 127);
| + | |
− | <br>if (camera[1]) {
| + | |
− | <br>sequencer_video.set_volume(volume[1]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[1].set_volume(volume[1]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>//track 3
| + | |
− | <br>else if (key=='z'||key=='Z') {
| + | |
− | <br>if (camera[0]==false &&camera[1]==false &&camera[2]==false) {
| + | |
− | <br>camera[2]=true;
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='x'||key=='X') {
| + | |
− | <br>camera[2]=false;
| + | |
− | <br>if (music[2]) {
| + | |
− | <br>sequencer[2].get_sequence(sequencer_video.sequence());
| + | |
− | <br>sequencer[2].get_color(sequencer_video.grid_color());
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='c'||key=='C') {
| + | |
− | <br>music[2]=true;
| + | |
− | <br>} else if (key=='v'||key=='V') {
| + | |
− | <br>music[2]=false;
| + | |
− | <br>sequencer[2].delete();
| + | |
− | <br>} else if (key=='b'||key=='B') {
| + | |
− | <br>if (music[2]) {
| + | |
− | <br>volume[2]=constrain(volume[2]-5, 0, 127);
| + | |
− | <br>if (camera[2]) {
| + | |
− | <br>sequencer_video.set_volume(volume[2]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[2].set_volume(volume[2]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='n'||key=='N') {
| + | |
− | <br>if (music[2]) {
| + | |
− | <br>volume[2]=constrain(volume[2]+5, 0, 127);
| + | |
− | <br>if (camera[2]) {
| + | |
− | <br>sequencer_video.set_volume(volume[2]);
| + | |
− | <br>} else {
| + | |
− | <br>sequencer[2].set_volume(volume[2]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>} else if (key=='o'||key=='O') {
| + | |
− | <br>tube=true;
| + | |
− | <br>} else if (key=='p'||key=='P') {
| + | |
− | <br>tube=false;
| + | |
− | <br>} else if (key==CODED) {
| + | |
− | <br>if (keyCode==LEFT) {
| + | |
− | <br>sequencer_video.threshold_down();
| + | |
− | <br>} else if (keyCode==RIGHT) {
| + | |
− | <br>sequencer_video.threshold_up();
| + | |
− | <br>} else if (keyCode==UP) {
| + | |
− | <br>rack.volume_up();
| + | |
− | <br>} else if (keyCode==DOWN) {
| + | |
− | <br>rack.volume_down();
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | | + | |
− | <br><br>void make_empty() {
| + | |
− | <br>for (int i=0; i<block_number; i++) {
| + | |
− | <br>int x= pos_x(i);
| + | |
− | <br>int y=margin;
| + | |
− | <br>sequencer[i]=new Sequencer(sc, grid_num, grid_size, interval, x, y);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>int pos_x(int i) {
| + | |
− | <br>int x=margin+(grid_num*(grid_size+interval)+interval+margin)*i;
| + | |
− | <br>return x;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>//tube rack
| + | |
− | <br>class Rack {
| + | |
− | <br>Capture video;
| + | |
− | <br>int tube_number=8;
| + | |
− | <br>int space_height;
| + | |
− | <br>float[][] colors;
| + | |
− | <br>SoundCipher sc;
| + | |
− | <br>int white=150;
| + | |
− | <br>float bright=1.5;
| + | |
− | <br>int volume=100;
| + | |
− | <br>int rack_width;
| + | |
− | <br>int rack_height;
| + | |
− | <br>int window_size;
| + | |
− | <br>int window_height;
| + | |
− | <br>int tube_height;
| + | |
− | <br>int tube_width;
| + | |
− | <br>int rack_x;
| + | |
− | <br>int rack_y;
| + | |
− | <br>int margin;
| + | |
− | | + | |
− | <br><br>Rack(Capture _video, SoundCipher _sc, int _window_size,
| + | |
− | <br>int _window_height, int _space_height) {
| + | |
− | <br>video=_video;
| + | |
− | <br>window_size=_window_size;
| + | |
− | <br>window_height=_window_height;
| + | |
− | <br>space_height=_space_height;
| + | |
− | <br>sc=_sc;
| + | |
− | <br>rack_width=int(window_size*0.75);
| + | |
− | <br>rack_height=space_height/2;
| + | |
− | <br>tube_height=int(space_height*0.6);
| + | |
− | <br>tube_width=int(rack_width/(tube_number*3));
| + | |
− | <br>rack_x=(window_size-rack_width)/2;
| + | |
− | <br>rack_y=int(space_height*0.3);
| + | |
− | <br>margin=(rack_width-tube_number*tube_width)/(tube_number+1);
| + | |
− | <br>} | + | |
− | | + | |
− | <br><br>void play(int n) {
| + | |
− | <br>get_color();
| + | |
− | <br>draw_rack();
| + | |
− | <br>glow(n);
| + | |
− | <br>play_sounds(n);
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>void get_color() {
| + | |
− | <br>if (video.available()) {
| + | |
− | <br>video.read();
| + | |
− | <br>video.loadPixels();
| + | |
− | <br>colors=new float[tube_number][3];
| + | |
− | <br>float[] loc_x = {0.1,0.215,0.333,0.45,0.569,0.705,0.823,0.941};
| + | |
− | <br>for (int i = 0; i < tube_number; i++) {
| + | |
− | <br>// Begin loop for rows
| + | |
− | | + | |
− | <br><br>// Where are we, pixel-wise?
| + | |
− | <br>int x = int(width*loc_x[i]) ;
| + | |
− | <br><br>int y = int(video.height*0.7);
| + | |
− | <br>int loc = x + y*video.width;
| + | |
− | | + | |
− | <br><br>colors[i][0] = red(video.pixels[loc]);
| + | |
− | <br>colors[i][1]= green(video.pixels[loc]);
| + | |
− | <br>colors[i][2]= blue(video.pixels[loc]);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− |
| + | |
− |
| + | |
− | <br><br>void draw_rack() {
| + | |
− | <br>if (colors!=null) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(0, window_height-space_height);
| + | |
− | <br>noFill();
| + | |
− | <br>stroke(255);
| + | |
− | <br>strokeWeight(3);
| + | |
− | <br>rect(rack_x, rack_y,
| + | |
− | <br>rack_width, rack_height, rack_height/10);
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(rack_x, rack_y);
| + | |
− | <br>for (int i = 0; i < tube_number; i++) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(margin*(i+1)+tube_width*i, -rack_y*0.6);
| + | |
− | <br>if ((colors[i][0]+colors[i][1]+colors[i][2])/3<white) {
| + | |
− | <br>noStroke();
| + | |
− | <br>fill(constrain(colors[i][0]*1.1,0,255),
| + | |
− | <br>constrain(colors[i][1]*1.1,0,255),
| + | |
− | <br>constrain(colors[i][2]*1.1,0,255));
| + | |
− | <br>rect(0, 0, tube_width, tube_height,tube_width/2);
| + | |
− | <br>} else {
| + | |
− | <br>noFill();
| + | |
− | <br>stroke(255);
| + | |
− | <br>strokeWeight(3);
| + | |
− | <br>rect(0, 0, tube_width, tube_height,tube_width/2);
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>popMatrix();
| + | |
− | <br>}
| + | |
− | <br>popMatrix();
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void glow(int n) {
| + | |
− | <br>n=n%tube_number;
| + | |
− | <br>if (colors!=null) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(0, window_height-space_height);
| + | |
− | <br>if ((colors[n][0]+colors[n][1]+colors[n][2])/3<white) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(rack_x, rack_y);
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(margin*(n+1)+tube_width*n, -rack_y*0.6);
| + | |
− | <br>fill(255, 255, 255, 40);
| + | |
− | <br>noStroke();
| + | |
− | <br>rect(0, 0, tube_width, tube_height,tube_width/2);
| + | |
− | <br>popMatrix();
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void play_sounds(int n) {
| + | |
− | <br>n=n%tube_number;
| + | |
− | <br>if (colors!=null) {
| + | |
− | <br>float noteVal;
| + | |
− | <br>float[] noteVals=new float[0];
| + | |
− | <br>boolean play;
| + | |
− | <br>if ((colors[n%tube_number][0]+colors[n%tube_number][1]
| + | |
− | <br>+colors[n%tube_number][2])/3<white) {
| + | |
− | <br>play=true;
| + | |
− | <br>} else {
| + | |
− | <br>play=false;
| + | |
− | <br>}
| + | |
− | <br>if (play) {
| + | |
− | <br>noteVal = noteVal(n);
| + | |
− | <br>noteVals=append(noteVals, noteVal);
| + | |
− | <br>}
| + | |
− | <br>sc.instrument(instrument(n));
| + | |
− | <br>println(instrument(n));
| + | |
− | <br>sc.playChord(noteVals, volume, 0.25);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>int instrument(int n){
| + | |
− | <br>int h=int(hue(color(colors[n][0],colors[n][1],
| + | |
− | <br><br>colors[n][2]))%6);
| + | |
− | <br>if (h==0){return 38;}
| + | |
− | <br>else if (h==1){return 103;}
| + | |
− | <br>else if (h==2){return 112;}
| + | |
− | <br>else if (h==3){return 113;}
| + | |
− | <br>else if (h==4){return 117;}
| + | |
− | <br>else {return 124;}
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>int noteVal(int n){
| + | |
− | <br>int h=int(hue(color(colors[n][0],colors[n][1],
| + | |
− | <br>colors[n][2]))%6);
| + | |
− | <br>if (h==0){return 14;}
| + | |
− | <br>else if (h==1){return 20;}
| + | |
− | <br>else if (h==2){return 24;}
| + | |
− | <br>else if (h==3){return 60;}
| + | |
− | <br>else if (h==4){return 96;}
| + | |
− | <br>else {return 60;}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void volume_up() {
| + | |
− | <br>volume=constrain(volume+5, 0, 127);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void volume_down() {
| + | |
− | <br>volume=constrain(volume-5, 0, 127);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>//step sequencer
| + | |
− | <br>class Sequencer {
| + | |
− | | + | |
− | <br><br>boolean[] empty;
| + | |
− | <br>float[] rgb_list;
| + | |
− | <br>int grid_num;
| + | |
− | <br>int grid_size;
| + | |
− | <br>int interval;
| + | |
− | | + | |
− | <br><br>SoundCipher sc;
| + | |
− | <br>boolean select=false;
| + | |
− | <br>int a, b;
| + | |
− | <br>int volume=0;
| + | |
− | <br>boolean on=true;
| + | |
− | <br>float red=0;
| + | |
− | <br>float green=0;
| + | |
− | <br>float blue=0;
| + | |
− | <br>int[] notes = {
| + | |
− | <br>96, 93, 91, 89, 86, 84, 81, 79, 77, 74, 72, 69, 67, 65, 62, 60
| + | |
− | <br>};
| + | |
− | <br>boolean[] sequence;
| + | |
− | | + | |
− | <br><br>Sequencer(SoundCipher _sc,
| + | |
− | <br>int _grid_num, int _grid_size, int _interval, int _a, int _b) {
| + | |
− | <br>sc=_sc;
| + | |
− | <br>grid_num=_grid_num;
| + | |
− | <br>grid_size=_grid_size;
| + | |
− | <br>interval=_interval;
| + | |
− | | + | |
− | <br><br>a=_a;
| + | |
− | <br>b=_b;
| + | |
− | | + | |
− | | + | |
− | <br><br>sequence=new boolean[grid_num*grid_num];
| + | |
− | <br>for (int i=0; i<sequence.length; i++) {
| + | |
− | <br>sequence[i]=false;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>empty=new boolean[grid_num*grid_num];
| + | |
− | <br>for (int i=0; i<sequence.length; i++) {
| + | |
− | <br>empty[i]=false;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void get_sequence(boolean[] _sequence) {
| + | |
− | <br>sequence=_sequence;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void get_color(float[] _rgb_list) {
| + | |
− | <br>rgb_list=_rgb_list;
| + | |
− | <br>red=rgb_list[0];
| + | |
− | <br>green=rgb_list[1];
| + | |
− | <br>blue=rgb_list[2];
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void draw_grid() {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(a, b);
| + | |
− | <br>rectMode(CORNER);
| + | |
− | <br>int x=0;
| + | |
− | <br>int y=0;
| + | |
− |
| + | |
− | <br><br>//black background
| + | |
− | <br>noStroke();
| + | |
− | <br>fill(0);
| + | |
− | <br>rect(-interval, -interval, (grid_size+interval)*grid_num+interval*2,
| + | |
− | <br>(grid_size+interval)*grid_num+interval*2);
| + | |
− |
| + | |
− | <br><br>for (int i=0; i<sequence.length; i++) {
| + | |
− | <br>x=(grid_size+interval)*(i%grid_num);
| + | |
− | <br>y=(grid_size+interval)*(i/grid_num);
| + | |
− | <br>if (sequence[i]) {
| + | |
− | <br>fill(red, green, blue);
| + | |
− | <br>} else {
| + | |
− | <br>if (select){fill(100);}
| + | |
− | <br>else {fill(70);}
| + | |
− | <br>}
| + | |
− | <br>rect(x, y, grid_size, grid_size);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>popMatrix();
| + | |
− | <br>} | + | |
− | | + | |
− | <br><br>void glow(int n) { | + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(a, b);
| + | |
− | <br><br>rectMode(CORNER);
| + | |
− | <br>for (int m=0; m<grid_num; m++) {
| + | |
− | <br>if (sequence[m*grid_num+n]) {
| + | |
− | <br>for (int p=-1; p<2; p++) {
| + | |
− | <br>for (int q=-1; q<2; q++) {
| + | |
− | <br>if (n+p>=0&&n+p<grid_num&&m+q>=0&&
| + | |
− | <br>m+q<grid_num) {
| + | |
− | <br>noStroke();
| + | |
− | <br>fill(255, 255, 255, 20);
| + | |
− | <br>rect((n+p)*(interval+grid_size), (m+q)*(interval+grid_size),
| + | |
− | <br>grid_size, grid_size);
| + | |
− | <br>}
| + | |
− | <br>if (p==0&&q==0){
| + | |
− | <br>fill(red, green, blue);
| + | |
− | <br>rect(n*(interval+grid_size)-interval/2, m*(interval+grid_size)-interval/2,
| + | |
− | <br>grid_size+interval, grid_size+interval);
| + | |
− | <br>fill(255, 255, 255, 30);
| + | |
− | <br>rect(n*(interval+grid_size)-interval/2, m*(interval+grid_size)-interval/2,
| + | |
− | <br>grid_size+interval, grid_size+interval);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | | + | |
− | | + | |
− | <br><br>void play_sounds(int n) {
| + | |
− | <br>float noteVal;
| + | |
− | <br>float[] noteVals=new float[0];
| + | |
− | | + | |
− | <br><br>for (int i=0; i<grid_num; i++) {
| + | |
− | | + | |
− | <br><br>// if the data text file has a "1" play note
| + | |
− | <br>if (sequence[i*grid_num+n]) {
| + | |
− | <br>noteVal = float(notes[i]);
| + | |
− | <br>noteVals=append(noteVals, noteVal);
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>}
| + | |
− | <br>sc.instrument(instrument());
| + | |
− | <br>sc.playChord(noteVals, volume, 0.25);
| + | |
− | <br>} | + | |
− |
| + | |
− | <br><br>int instrument(){
| + | |
− | <br>int h=int(hue(color(red,green,blue))%8);
| + | |
− | <br>if (h==0){return 2;}
| + | |
− | <br>else if (h==1){return 3;}
| + | |
− | <br>else if (h==2){return 38;}
| + | |
− | <br>else if (h==3){return 46;}
| + | |
− | <br>else if (h==4){return 47;}
| + | |
− | <br>else if (h==5){return 55;}
| + | |
− | <br>else if (h==6){return 116;}
| + | |
− | <br>else {return 120;}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void select(boolean _select) {
| + | |
− | <br>select=_select;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void set_volume(int _volume) {
| + | |
− | <br>volume=constrain(_volume, 0, 127);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void delete() {
| + | |
− | <br>sequence=empty;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>//step sequencer video
| + | |
− | <br>class Sequencer_video {
| + | |
− | <br>Capture video;
| + | |
− | <br>SoundCipher sc;
| + | |
− | <br>BlobDetection theBlobDetection;
| + | |
− | <br>boolean newFrame=false;
| + | |
− | <br>PImage img;
| + | |
− | <br>int a, b;
| + | |
− | <br>int grid_size;
| + | |
− | <br>int grid_num;
| + | |
− | <br>int interval;
| + | |
− | <br>int block_size;
| + | |
− | <br>int volume=0;
| + | |
− | <br>float[][] blob_color;
| + | |
− | <br>float[] avg_color=new float[3];
| + | |
− | <br>float[][] blobs;
| + | |
− | <br>float[][][] raw_color;
| + | |
− | <br>float threshold=0.5;
| + | |
− | <br>boolean draw_grid=false;
| + | |
− | <br>boolean[] sequence;
| + | |
− | <br>int[] notes = {
| + | |
− | <br>, 93, 91, 89, 86, 84, 81, 79, 77, 74, 72, 69, 67, 65, 62, 60
| + | |
− | <br>};
| + | |
− | <br>int radius=180;
| + | |
− | | + | |
− | <br><br>Sequencer_video(Capture _video, SoundCipher _sc, int _grid_num,
| + | |
− | <br>int _grid_size,int _interval) {
| + | |
− | <br>colorMode(RGB, 255, 255, 255, 100);
| + | |
− | <br>video=_video;
| + | |
− | <br>sc=_sc;
| + | |
− | <br>grid_num=_grid_num;
| + | |
− | <br>grid_size=_grid_size;
| + | |
− | <br>interval=_interval;
| + | |
− | <br>block_size=(interval+grid_size)*grid_num;
| + | |
− |
| + | |
− | <br>sequence=new boolean[grid_num*grid_num];
| + | |
− | <br>img = new PImage(grid_num*(grid_size+interval)-interval,
| + | |
− | <br>grid_num*(grid_size+interval)-interval);
| + | |
− | <br>theBlobDetection = new BlobDetection(img.width, img.height);
| + | |
− | <br>theBlobDetection.setPosDiscrimination(true);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void threshold_up() {
| + | |
− | <br>threshold=constrain(threshold+0.02, 0, 1);
| + | |
− | <br>println(threshold);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void threshold_down() {
| + | |
− | <br>threshold=constrain(threshold-0.02, 0, 1);
| + | |
− | <br>println(threshold);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void position(int _a, int _b) {
| + | |
− | <br>a=_a;
| + | |
− | <br>b=_b;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void grid_on() {
| + | |
− | <br>draw_grid=true;
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>void grid_off(){
| + | |
− | <br>draw_grid=false;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void bd() {
| + | |
− | <br>if (video.available()) {
| + | |
− | <br>theBlobDetection.setThreshold(threshold);
| + | |
− | <br>video.read();
| + | |
− | <br>img.copy(video, (video.width-video.height)/2, 0, video.height,
| + | |
− | <br>video.height, 0, 0, img.width, img.height);
| + | |
− | <br>image(img, a, b, img.width+interval, img.height+interval);
| + | |
− | <br>fastblur(img, 2);
| + | |
− | <br>theBlobDetection.computeBlobs(img.pixels);
| + | |
− | <br>save_blob();
| + | |
− | <br>blob_color();
| + | |
− | <br>convert();
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br>void bd_draw(int n) {
| + | |
− | <br>if (draw_grid) {
| + | |
− |
| + | |
− | <br>draw_grid();
| + | |
− | <br>glow(n);
| + | |
− | <br>play_sounds(n);
| + | |
− | <br>} else {
| + | |
− | <br>drawBlobsAndEdges(true, false);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void blob_color() {
| + | |
− | <br>float red=0;
| + | |
− | <br>float blue=0;
| + | |
− | <br>float green=0;
| + | |
− | <br>int total=theBlobDetection.getBlobNb ();
| + | |
− | <br>for (int n=0; n<total; n++) {
| + | |
− | | + | |
− | <br><br>//get the color
| + | |
− | <br><br><br>blob_color=new float[total][3];
| + | |
− | <br><br><br><br>int centerX = int(blobs[n][0]+0.5*blobs[n][2]);
| + | |
− | <br>int centerY = int(blobs[n][1]+0.5*blobs[n][3]);
| + | |
− | | + | |
− | <br><br>color c = get(centerX+a, centerY+b);
| + | |
− | <br>blob_color[n][0] = red(c);
| + | |
− | <br><br>blob_color[n][1] = green(c);
| + | |
− | <br>blob_color[n][2] = blue(c);
| + | |
− |
| + | |
− | <br><br>red+=blob_color[n][0];
| + | |
− | <br>green+=blob_color[n][1];
| + | |
− | <br>blue+=blob_color[n][2];
| + | |
− |
| + | |
− | | + | |
− | <br>}
| + | |
− | <br>avg_color[0]=constrain(red/total*1.2,0,255);
| + | |
− | <br>avg_color[1]=constrain(green/total*1.2,0,255);
| + | |
− | <br>avg_color[2]=constrain(blue/total*1.2,0,255);
| + | |
− | | + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void drawBlobsAndEdges(boolean drawBlobs, boolean drawEdges) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br><br>translate(a, b);
| + | |
− | <br><br><br>noFill();
| + | |
− | <br><br><br><br>rectMode(CORNER);
| + | |
− | <br>Blob b;
| + | |
− | <br>EdgeVertex eA, eB;
| + | |
− |
| + | |
− | <br><br>for (int n=0; n<theBlobDetection.getBlobNb (); n++)
| + | |
− | <br>{
| + | |
− | <br>b=theBlobDetection.getBlob(n);
| + | |
− | <br>if (b!=null)
| + | |
− | <br>{
| + | |
− | <br>// Edges
| + | |
− | <br>if (drawEdges)
| + | |
− | <br>{
| + | |
− | <br>strokeWeight(3);
| + | |
− | <br><br>stroke(0, 255, 0);
| + | |
− | <br>for (int m=0; m<b.getEdgeNb (); m++)
| + | |
− | <br>{
| + | |
− | <br>eA = b.getEdgeVertexA(m);
| + | |
− | <br>eB = b.getEdgeVertexB(m);
| + | |
− | <br>if (eA !=null && eB !=null)
| + | |
− | <br>line(
| + | |
− | <br><br>eA.x*block_size, eA.y*block_size,
| + | |
− | <br><br><br>eB.x*block_size, eB.y*block_size
| + | |
− | <br>);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>// Blobs
| + | |
− | <br>if (dist(block_size/2,block_size/2,b.xMin*block_size,
| + | |
− | <br>b.yMin*block_size)<radius
| + | |
− | <br>&&drawBlobs&&b.w*block_size>5&&b.w*block_size<25&&
| + | |
− | <br>b.h*block_size>5&&b.h*block_size<25)
| + | |
− | <br>{
| + | |
− | <br>strokeWeight(3);
| + | |
− | <br>stroke(255, 0, 0);
| + | |
− |
| + | |
− | <br><br>rect(
| + | |
− | <br><br><br>b.xMin*block_size, b.yMin*block_size,
| + | |
− | <br><br><br><br>b.w*block_size, b.h*block_size
| + | |
− | <br>);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br> popMatrix();
| + | |
− | <br><br>}
| + | |
− | | + | |
− | <br><br>void fastblur(PImage img, int radius)
| + | |
− | <br>{
| + | |
− | <br>if (radius<1) {
| + | |
− | <br>return;
| + | |
− | <br>}
| + | |
− | <br>int w=img.width;
| + | |
− | <br>int h=img.height;
| + | |
− | <br>int wm=w-1;
| + | |
− | <br>int hm=h-1;
| + | |
− | <br>int wh=w*h;
| + | |
− | <br>int div=radius+radius+1;
| + | |
− | <br>int r[]=new int[wh];
| + | |
− | <br>int g[]=new int[wh];
| + | |
− | <br>int b[]=new int[wh];
| + | |
− | <br>int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw;
| + | |
− | <br>int vmin[] = new int[max(w, h)];
| + | |
− | <br>int vmax[] = new int[max(w, h)];
| + | |
− | <br>int[] pix=img.pixels;
| + | |
− | <br>int dv[]=new int[256*div];
| + | |
− | <br>for (i=0; i<256*div; i++) {
| + | |
− | <br>dv[i]=(i/div);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>yw=yi=0;
| + | |
− | | + | |
− | <br><br>for (y=0; y<h; y++) {
| + | |
− | <br>rsum=gsum=bsum=0;
| + | |
− | <br>for (i=-radius; i<=radius; i++) {
| + | |
− | <br>p=pix[yi+min(wm, max(i, 0))];
| + | |
− | <br>rsum+=(p & 0xff0000)>>16;
| + | |
− | <br>gsum+=(p & 0x00ff00)>>8;
| + | |
− | <br>bsum+= p & 0x0000ff;
| + | |
− | <br>}
| + | |
− | <br>for (x=0; x<w; x++) {
| + | |
− | | + | |
− | <br><br>r[yi]=dv[rsum];
| + | |
− | <br>g[yi]=dv[gsum];
| + | |
− | <br>b[yi]=dv[bsum];
| + | |
− | | + | |
− | <br><br>if (y==0) {
| + | |
− | <br>vmin[x]=min(x+radius+1, wm);
| + | |
− | <br>vmax[x]=max(x-radius, 0);
| + | |
− | <br>}
| + | |
− | <br>p1=pix[yw+vmin[x]];
| + | |
− | <br><br>p2=pix[yw+vmax[x]];
| + | |
− | | + | |
− | <br><br>rsum+=((p1 & 0xff0000)-(p2 & 0xff0000))>>16;
| + | |
− | <br>gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8;
| + | |
− | <br><br><br>bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff);
| + | |
− | <br>yi++;
| + | |
− | <br>}
| + | |
− | <br>yw+=w;
| + | |
− | <br> }
| + | |
− | | + | |
− | <br><br>for (x=0; x<w; x++) {
| + | |
− | <br>rsum=gsum=bsum=0;
| + | |
− | <br>yp=-radius*w;
| + | |
− | <br>for (i=-radius; i<=radius; i++) {
| + | |
− | <br>yi=max(0, yp)+x;
| + | |
− | <br>rsum+=r[yi];
| + | |
− | <br>gsum+=g[yi];
| + | |
− | <br>bsum+=b[yi];
| + | |
− | <br>yp+=w;
| + | |
− | <br>}
| + | |
− | <br>yi=x;
| + | |
− | <br>for (y=0; y<h; y++) {
| + | |
− | <br>pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
| + | |
− | <br>if (x==0) {
| + | |
− | <br>vmin[y]=min(y+radius+1, hm)*w;
| + | |
− | <br>vmax[y]=max(y-radius, 0)*w;
| + | |
− | <br>}
| + | |
− | <br>p1=x+vmin[y];
| + | |
− | <br>p2=x+vmax[y];
| + | |
− | | + | |
− | <br><br>rsum+=r[p1]-r[p2];
| + | |
− | <br>gsum+=g[p1]-g[p2];
| + | |
− | <br>bsum+=b[p1]-b[p2];
| + | |
− | | + | |
− | <br><br>yi+=w;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void save_blob() {
| + | |
− | | + | |
− | <br><br>Blob b;
| + | |
− | <br>blobs=new float[theBlobDetection.getBlobNb ()][4];
| + | |
− | <br>for (int n=0; n<theBlobDetection.getBlobNb (); n++)
| + | |
− | <br>{
| + | |
− | <br>b=theBlobDetection.getBlob(n);
| + | |
− | <br>if (dist(block_size/2,block_size/2,b.xMin*block_size,
| + | |
− | <br>b.yMin*block_size)<radius
| + | |
− | <br>&&b.w*block_size>5&&b.w*block_size<25&&
| + | |
− | <br>b.h*block_size>5&&b.h*block_size<25){
| + | |
− | <br>blobs[n][0]=b.xMin*block_size;
| + | |
− | <br>blobs[n][1]=b.yMin*block_size;
| + | |
− | <br>blobs[n][2]=b.w*block_size;
| + | |
− | <br>blobs[n][3]=b.h*block_size;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void convert() {
| + | |
− | <br>int row, col, i;
| + | |
− | <br>for (int n=0; n<sequence.length; n++) {
| + | |
− | <br>sequence[n]=false;
| + | |
− | <br>}
| + | |
− | <br>for (int n=0; n<blobs.length; n++) {
| + | |
− | <br>row=int(blobs[n][0]+blobs[n][2]*0.5)/grid_size;
| + | |
− | <br>col=int(blobs[n][1]+blobs[n][3]*0.5)/grid_size;
| + | |
− | <br>i=row+col*grid_num;
| + | |
− | <br>if (i>0&&i<grid_num*grid_num) {
| + | |
− | <br>sequence[i]=true;
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void draw_grid() {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(a, b);
| + | |
− | <br>rectMode(CORNER);
| + | |
− | <br>int x=0;
| + | |
− | <br>int y=0;
| + | |
− | <br>noStroke();
| + | |
− | <br>fill(0);
| + | |
− | <br>rect(-interval,-interval,(grid_size+interval)*grid_num+interval*2,
| + | |
− | <br>(grid_size+interval)*grid_num+interval*2);
| + | |
− | <br>for (int i=0; i<sequence.length; i++) {
| + | |
− | <br>x=(grid_size+interval)*(i%grid_num);
| + | |
− | <br>y=(grid_size+interval)*(i/grid_num);
| + | |
− | | + | |
− | <br><br>noStroke();
| + | |
− |
| + | |
− | <br><br>if (sequence[i]) {
| + | |
− | <br>fill(avg_color[0], avg_color[1], avg_color[2]);
| + | |
− | <br>} else {
| + | |
− | <br>fill(70);
| + | |
− | <br>}
| + | |
− | <br>rect(x, y, grid_size, grid_size);
| + | |
− | <br>}
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>void glow(int n) {
| + | |
− | <br>pushMatrix();
| + | |
− | <br>translate(a, b);
| + | |
− | <br>rectMode(CORNER);
| + | |
− | <br>for (int m=0; m<grid_num; m++) {
| + | |
− | <br>if (sequence[m*grid_num+n]) {
| + | |
− | <br>for (int p=-1; p<2; p++) {
| + | |
− | <br>for (int q=-1; q<2; q++) {
| + | |
− | <br>if (n+p>=0&&n+p<grid_num&&m+q>=0&&
| + | |
− | <br>m+q<grid_num) {
| + | |
− | <br>noStroke();
| + | |
− | <br><br>fill(255, 255, 255, 20);
| + | |
− | <br>rect((n+p)*(interval+grid_size), (m+q)*(interval+grid_size),
| + | |
− | <br><br>grid_size, grid_size);
| + | |
− | <br>}
| + | |
− | <br>if (p==0&&q==0){
| + | |
− | <br>fill(255, 255, 255, 30);
| + | |
− | <br>rect(n*(interval+grid_size), m*(interval+grid_size),
| + | |
− | <br>grid_size, grid_size);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>popMatrix();
| + | |
− | <br>}
| + | |
− | | + | |
− | <br> void play_sounds(int n) {
| + | |
− | <br>float noteVal;
| + | |
− | <br>float[] noteVals=new float[0];
| + | |
− | <br>for (int i=0; i<grid_num; i++) {
| + | |
− | <br>if (sequence[i*grid_num+n]) {
| + | |
− | <br>noteVal = float(notes[i]);
| + | |
− | <br>noteVals=append(noteVals, noteVal);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | <br>sc.instrument(instrument());
| + | |
− | <br>sc.playChord(noteVals, volume, 0.25);
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>float[] grid_color() {
| + | |
− | <br>float[] color_return=new float[3];
| + | |
− | <br>arrayCopy(avg_color, color_return);
| + | |
− | <br>return color_return;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>boolean[] sequence() {
| + | |
− | <br>boolean[] to_return=new boolean[sequence.length];
| + | |
− | <br>arrayCopy(sequence, to_return);
| + | |
− | <br>return to_return;
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br><br>int instrument(){
| + | |
− | <br>int h=int(hue(color(avg_color[0],avg_color[1],
| + | |
− | <br>avg_color[2]))%8);
| + | |
− | <br>if (h==0){return 2;}
| + | |
− | <br>else if (h==1){return 3;}
| + | |
− | <br>else if (h==2){return 38;}
| + | |
− | <br>else if (h==3){return 46;}
| + | |
− | <br>else if (h==4){return 47;}
| + | |
− | <br>else if (h==5){return 55;}
| + | |
− | <br>else if (h==6){return 116;}
| + | |
− | <br>else {return 120;}
| + | |
− | <br>}
| + | |
− |
| + | |
− | <br><br>void set_volume(int _volume) {
| + | |
− | <br>volume=constrain(_volume, 0, 127);
| + | |
− | <br>}
| + | |
− | <br>}
| + | |
− | | + | |
− | <br><br>Source: blob detection
| + | |
− | http://www.v3ga.net/processing/BlobDetection/
| + | |
− | | + | |
− | <br><br>soundcipher
| + | |
− | http://explodingart.com/soundcipher/
| + | |
− | | + | |
− | | + | |
| </p> | | </p> |
| </div> | | </div> |
| | | |
| </html> | | </html> |