Light House – Interface

This is a version of the final UI we developed in processing to control Light House, and interactive light and sound installation commissioned by SONOS. 

The UI was created using processing. In this case the UI analyses sound from a microphone. For live performances the sound was taken from a line in and the value of each bulb was sent to a series of arduino boards that controlled the individual bulbs. You can download the processing code for the interface here: LightHouseUI

The code is also available in the rest of this post.

import controlP5.*;

import ddf.minim.*;

Minim minim;
AudioInput in;


ControlP5 cp5;
RadioButton r;

char oscTemp = 0;
byte currentPos = 0;

boolean Auto = false;
boolean Pulse = false;
boolean Spine = false;
boolean Random = false;
boolean Ring = false;
boolean X_Pulse = false;
boolean Test = false;
boolean Horizontal_Band = false;
int speed = 25;
int range = 25;
float sound_threshold = 0.10;
float threshold = 0.5;

int Random_Multiplier = 1;
int random_speed = 10;
int spinecount = 10;
int hcount = 10;
int Random_Num = 10;
int Random_Delay = 1;

float audiomag = 0;

float amplitude = 0.0;
float spacing = 2.5;

float volume = 1.0;

float Spine_Multiplier = 1.0;


int[][] lights = new int[30][20];

void setup() {
  
  frameRate(30);
  
  size(displayWidth, displayHeight);

  
   minim = new Minim(this);
 
  in = minim.getLineIn();
  
  
  for (int i = 0; i < 30; i++) {
  for (int j = 0; j < 20; j++) {
    lights[i][j] = 0;
    }
  }
  
  cp5 = new ControlP5(this);

   cp5.addToggle("Pulse")
     .setPosition(950,50)
     .setSize(20,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))

     ;
  cp5.getController("Pulse").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
   cp5.addToggle("Horizontal_Band")
   .setPosition(950,140)
   .setSize(20,20)
   .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))
   ;
   cp5.addToggle("Spine")
   .setPosition(950,170)
   .setSize(20,20)
   .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))
   ;
 cp5.getController("Spine").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
 
 cp5.addToggle("Ring")
   .setPosition(950,230)
   .setSize(20,20)
   .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))
   ;
 cp5.getController("Ring").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
  

    cp5.getController("Horizontal_Band").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
    
    cp5.addToggle("Random")
   .setPosition(950,260)
   .setSize(20,20)
   .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))
   ;
   cp5.getController("Random").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
   
   cp5.addSlider("Random_Num")
     .setPosition(770,290)
     .setRange(0,100)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     
     cp5.addSlider("Spine_Multiplier")
     .setPosition(770,200)
     .setRange(1,4)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     
     cp5.addSlider("Random_Delay")
     .setPosition(770,320)
     .setRange(0,80)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
  cp5.addToggle("X_Pulse")
   .setPosition(950,350)
   .setSize(20,20)
   .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(0xffff88ff)
     .setColorActive(color(200,200,200))
   ;
   cp5.getController("X_Pulse").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
 
 
  cp5.addSlider("speed")
     .setPosition(770,80)
     .setRange(0,100)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     //cp5.getController("X_pulse").getCaptionLabel().align(ControlP5.LEFT, ControlP5.RIGHT_OUTSIDE).setPadding(23,2);
 
  cp5.addSlider("range")
     .setPosition(770,110)
     .setRange(10,100)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     
     cp5.addSlider("volume")
     .setPosition(1080,320)
     .setRange(0,10)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;

     
  cp5.addSlider("threshold")
     .setPosition(1080,350)
     .setRange(0.0,1.0)
     .setSize(200,20)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     
     cp5.addSlider("amplitude")
     .setPosition(1080,90)
     .setRange(0.0,200.0)
     .setSize(60,200)
     .setColorForeground(color(20,20,20))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(200,200,200))
     ;
     
}



int[] audio01 = new int[60];
int count01 = 0;
int acount = 0;


int space = 10;
int count = 0;
int spcount = 0;
int ringcount = 0;

float[] randpointsx = new float[25];
float[] randpointsy = new float[25];

int vol = 0;

void draw(){
  ///GET SOUND/////////////
  background(0, 0, 0);
  float sd = in.mix.get(0);
  float s = 200 * abs(sd);
  float tnum = threshold * 200;
  sd = 0;
  for(int i = 0; i < in.bufferSize() - 1; i++)   {     if(abs(in.mix.get(i)) > sd){
      sd = abs(in.mix.get(i));
    }
  }
  sound_threshold = threshold;
  s = s * volume;
  ////////////////////////
  
  ///SOUND BAR VISUALISER////
  
  if(s > 200){
    s = 200;
  }
  if(s < 0){     s = 0;   }      cp5.getController("amplitude").setValue(s);   noStroke();   fill(color(70,70,70));   rect(1080, 280, 60, -200);   fill(color(20,20,20));   float rh = -1*s;   rect(1080, 280, 60, rh);   stroke(255);   strokeWeight(1);    line(1145,280-tnum,1160,280-tnum);   fill(255);   ////////////////////////////      audiomag = s/200;      if(Test == true){     audiomag = random(1);   }     spcount++;     if(spcount > (100-random_speed)){
          for (int i = 0; i < Random_Multiplier; i++) {
            randpointsx[i] = random(0, 600);
            randpointsy[i] = random(0, 900);
          }
          for (int i = Random_Multiplier; i < 25; i++) {
            randpointsx[i] = -100;
            randpointsy[i] = -100;
          }
          spcount = 0;
    }
  
    
    
    ////////////////////pulse//////////////////////////////
    if(Pulse == true){
      for (int i = 0; i < 30; i++) {
        for (int j = 0; j < 20; j++) {           float x = 20+i*space*spacing;           float y = 20+j*space*spacing;           int light = pulse(x,y);           if(light == 1){             lights[i][j] = 1;           }         }       }            }            radius = radius + speed;     if(radius > 1100){
      centerx = 8000;
      centery = 8000;
      radius = 0;
    }
    if(audiomag > sound_threshold){
      centerx = random(0, 600);
      centery = random(0, 900);
      radius = 0;
    }
   
  ////////////////////end pulse/////////////////////////////
  
   ////////////////////spine//////////////////////////////
    if(Spine == true){
      float limit = (audiomag * 15 - 2) * Spine_Multiplier;
      if (limit < 0){         limit = 0;       }       if(limit > 9){
        limit = 9;
      }
      if (vol < limit){             lights[spinecount][vol+10] = (vol)*(vol)+10;             lights[spinecount][9-vol] = (vol)*(vol/2)+10;             vol++;             lights[spinecount][vol+10] = (vol)*(vol)+10;             lights[spinecount][9-vol] = (vol)*(vol)+10;             vol++;        }else{          spinecount++;          vol = 0;        }     }          if(spinecount > 29){
      spinecount = 0;
    }
  ////////////////////end spine/////////////////////////////
  
   ////////////////////ring//////////////////////////////
    if(Ring == true){
      float limit = audiomag * 10 * 5;
      if(audiomag > sound_threshold){
        ringcount++;
      }

      if (audiomag > (sound_threshold/1.25)){
          for (int j = ringcount; j < (20-ringcount); j++) {
            lights[ringcount][j] = 3;
            lights[(29-ringcount)][j] = 3;
          }
          for (int j = ringcount; j < (29-ringcount); j++) {             lights[j][ringcount] = 3;             lights[j][(19-ringcount)] = 3;           }        }     }          if(ringcount > 9){
      ringcount = 0;
    }
  ////////////////////end ring/////////////////////////////
  
    ////////////////////wave//////////////////////////////
    if(Horizontal_Band == true){
      float limit = audiomag * 10 * 5;
      if(audiomag > sound_threshold){
        hcount = 0;
      }

      if (hcount < 30){
        for (int c = 0; c < 20; c++) {
           lights[hcount][c] = 3;
        }
        for (int c = 0; c < 20; c++) {            lights[29-hcount][c] = 3;         }       }     }     hcount++;   ////////////////////end wave/////////////////////////////      ////////////////////random//////////////////////////////     if(Random == true){         if(audiomag > sound_threshold){
        for (int j = 0; j < Random_Num; j++) {            int xran = round(random(29));            int yran = round(random(19));            lights[xran][yran] = 3 + round(random(Random_Delay));         }        }     }   ////////////////////random/////////////////////////////      ////////////////////xpulse//////////////////////////////     if(X_Pulse == true){       if(audiomag > sound_threshold){
        for (int j = 0; j < (audiomag * 30); j++) {
           int xpos = round(j * cos(radians(35)))+14;
           int ypos = round(j * sin(radians(35)))+9;
           if((xpos < 30) && (ypos < 20)){
             lights[xpos][ypos] = 3;
          }
        }
        for (int j = 0; j < (audiomag * 30); j++) {
           int xpos = round(j * cos(radians(-25)))+13;
           int ypos = round(j * sin(radians(-25)))+8;
           if((xpos < 30) && (ypos > -1)){
             lights[xpos][ypos] = 3;
          }
        }
        for (int j = 0; j < (audiomag * 30); j++) {            int xpos = round(j * cos(radians(145)))+14;            int ypos = round(j * sin(radians(145)))+9;            if((xpos >-1) && (ypos < 20)){
             lights[xpos][ypos] = 3;
          }
        }
        for (int j = 0; j < (audiomag * 30); j++) {            int xpos = round(j * cos(radians(-150)))+13;            int ypos = round(j * sin(radians(-150)))+8;            if((xpos > -1) && (ypos > -1)){
             lights[xpos][ypos] = 3;
          }
        }
      }
    }


  ////////////////////random/////////////////////////////
   
    
   //draw light grid

   currentPos = 0;
   for (int i = 0; i < 30; i++) {
      for (int j = 0; j < 20; j++) {         float x = 20+i*space*spacing;         float y = 20+j*space*spacing;         if (lights[i][j] > 0){
          fill(255);
          ellipse(x,y,(space*1.5),(space*1.5)); 
          lights[i][j] = lights[i][j] - 1;
          oscTemp |= (0x01<<currentPos);         }else{           fill(0, 0, 0);           stroke(255);           ellipse(x,y,space,space);             //myMessage.add(0);         }         currentPos++;         if(currentPos == 8 || j == 19){           currentPos = 0;           oscTemp = 0x00;         }       // For every column and row, a circle is drawn at an (x,y) location scaled and sized by videoScale.               }   }      count++;    } int radius = 0; float centerx = 0; float centery = 0; int pulse(float Xpos, float Ypos) {   int onoff;   float distance = dist(Xpos,Ypos,centerx,centery);   if((distance > (radius-range)) && (distance < (radius+range))){
    onoff = 1;
  }else{
    onoff = 0;
  }

  return onoff;
}

int randomp(float cx, float cy, float Xpos, float Ypos) {
  int onoff;

    float distance = dist(Xpos,Ypos,cx,cy);
    if(distance < range){
      onoff = 1;
    }else{
      onoff = 0;
    }

  return onoff;
}