This is the finished product for the first project in our Interactive Media Studio. I was in a group with Dean Zhu for this project.
Link to Video of Final Result
Recording of Project Testing
Link to Documentation Video
Dean’s Thoughts:
Plants and the like are definitely not my first choice of subject matter for a given project.. However, I enjoyed conceptualizing and attempting to add my own particular edge to leafy greens. I’m glad I was able to use many of the skills I already have to hold the arrangement together, though this experience has taught me that I still have quite a bit left to learn, as well as to remember to take into consideration for the next time.The fake plants were a bit unwieldy, though. I’d like to be able to work with something a bit more… flexible, next time. we shall see.
My thoughts:
This project is very intriguing, and I would love to be able to do something similar that is more ambitious. Our arrangement of leaves reacts based on the input sound intensity at a given frequency, and with Minim’s capabilities this was simple to accomplish in theory. In reality there were many limitations to the tweaks we could make to test the program, such as substituting existing audio files for microphone input with no microphone. I think if I had to do it again, I would want the user input to be done differently, because Minim’s capability to pick out more specific input data from a Mic In is limited.
The core program code is under the cut:
import codeanticode.syphon.*;
PGraphics canvas;
SyphonServer server;
/**
* This sketch demonstrates how to monitor the currently active audio input
* of the computer using an AudioInput. What you will actually
* be monitoring depends on the current settings of the machine the sketch is running on.
* Typically, you will be monitoring the built-in microphone, but if running on a desktop
* it’s feasible that the user may have the actual audio output of the computer
* as the active audio input, or something else entirely.
* <p>
* Press ‘m’ to toggle monitoring on and off.
* <p>
* When you run your sketch as an applet you will need to sign it in order to get an input.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
Minim minim;
AudioInput in;
int timer = 0;
int volume = 0;
boolean renew = false;
int level = 0;
float levelF = 0; //level de-generate variable
float levelG = 0; //level generate variable
float aa=-.5; // Kilter Left
float ab=.5; // Kilter Right
//Controllers
int maxVol = 10000; //
int maxgrowth = 8;
int fadeRate = 4; //lower rate = slower fade
float growRate = 0.2; //plant generation rate
float dieRate = 0.01; //plant de-generation rate
//Color Selection
int colorR = 240;
int colorG = 255;
int colorB = 240;
int Ink = 10; // Subtractive color editor. Apply to R, B sections.
int sqHeight = 100; //height of colorbox
int sqWidth = 8; //width of colorbox
int thd = 20; //amplification of color
int thr = 1; //ignores volume levels below this number
int samplePos = 205; //frequency to test, range may be from 0 to 1024
//======================
void form(float x,float y, float a, int c) {
canvas.line(x,y,(x+45*cos(a)),(y+45*sin(a)-(level/2)));
if (c>0) {
canvas.strokeWeight(5);
form((x+45*cos(a)),(y+45*sin(a)-(level/2)),a+aa,c-1);
form((x+45*cos(a)),(y+45*sin(a)-(level/2)),a+ab,c-1);
// canvas.stroke((255-(c*Ink)), 255, (255-(c*Ink)));
}
}
void fractal(int cR, int cG, int cB, int time){
//aa = 0.5;//random(-PI,PI);
// ab = -1;//random(-PI,PI);
if(renew == true){
renew = false;
timer = 0;
levelG = levelG + growRate;
level = int(levelG);
if(level > maxgrowth) level = maxgrowth;
levelF = 0;
//cR = cR * volume[time];
//cG = cG * volume[time];
//cB = cB * volume[time];
}
// canvas.stroke(cR – timer, cG – timer, cB – timer);
canvas.stroke((cR-(level*Ink)-timer), cG – timer, (cB-(level*Ink)-timer));
form(width/2,(height-height/5),-HALF_PI, level – 1);
timer = timer + fadeRate;
levelF = levelF + dieRate;
levelG = levelG – (timer/100);
if(levelG < 0) levelG = 0;
level = level – int(levelF);
if (level<1) level = 1;
//levelG = int(levelG);
}
void square(int Xpos, int Ypos, int cR, int cG, int cB, int time){
if(renew == true){
renew = false;
timer = volume;
//cR = cR * volume[time];
//cG = cG * volume[time];
//cB = cB * volume[time];
}
canvas.fill(cR – timer, cG – timer, cB – timer);
canvas.rect(Xpos,Ypos,sqWidth,sqHeight);
timer = timer + fadeRate;
}
//===================
void setup()
{
size(600, 500, P3D);
canvas = createGraphics(600,500,P3D);
// canvas.background(0);
server = new SyphonServer(this, “Psyphon”);
minim = new Minim(this);
timer = 0;
// canvas.strokeWeight(3);
//setup squares
//square(1,0, 0,0,255, 1); //blue
for(int i = 0; i < 1024; i++){
timer = 0;
renew = false;
}
// use the getLineIn method of the Minim object to get an AudioInput
in = minim.getLineIn();
// in = minim.getAK5370();
}
//=======================================================
void draw()
{
canvas.beginDraw();
canvas.background(0);
canvas.stroke(255);
int j = 0;
// draw the waveforms so we can see what we are monitoring
//bufferSize = 1024;
for(int i = 0; i < 1024; i++){
volume = int(((in.left.get(i)*thd) / maxVol) * 255);
if((in.left.get(i)*thd) > thr){
renew = true;
}
}
fractal(colorR,colorG,colorB, 1);
//for(int i = 0; i < in.bufferSize() – 1; i+=8){
for(int i = 0; i < 1024; i+=16){
volume = int(((in.left.get(i)*thd) / maxVol) * 255);
}//end of For Loop
if((in.left.get(samplePos)*thd) > thr){
renew = true;
}
// square(1,1, 0,0,255, 1);
canvas.endDraw();
image(canvas,0,0);
server.sendImage(canvas);
}