This is a simple audio and visualization program that deals mainly with interaction of the keypad with music and geometric visualization. To start the program, press enter and play around with timing of sounds and visualization by pressing keys such as “W”,”A”,”S”,”D”, “I”, “J”, “K”, “L” that will work with the background music. Last but not least, have fun and explore different combination of keys to create cool visualizations.
// Scarlet Tong
//sntong@andrew.cmu.edu
// Final Project
// incrementally increase the x, y parameter
var inc = 0.02;
// ze of each grid spacing
var scl = 48;
// rows and columns of the grid
var cols, rows;
// introducing a "time" parameter for the lines to move
var zoff = 0;
// variables the squares function will use
var topX;
var topY;
var topX1;
var topY1;
// difference variable that is used for the frames function below
var m = 0;
// declaring variables to store sound files
var backg;
var bass;
var chime;
var beat;
var popp;
// intializing variables that holds and stores Amplitude of the sound for
// the "sound wave" visualization
var amp;
var volhistory = [];
// to make sure sounds don't play and overlap with itself
var dJ = false;
// difference variable that the rings function uses
var step = 0;
// track click count to start the background music and other visualizations
var numClick = 0;
// difference variable used for the knitted function below
var column = 0;
function preload(){
backg = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/background-1.wav");
bass = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/bass.wav");
chime = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/chimes.wav");
beat = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/steady-beat.wav");
popp = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pop.wav");
}
function setup() {
createCanvas(480, 480);
// define grid spacing for field function below
cols = floor(width/scl);
rows = floor(height/scl);
// defining variables of for squares function
topX = width/2;
topY = height/2;
topX1 = width/2;
topY1 = height/2;
}
function draw() {
background(0);
// startup page for users before rest of the code runs
if (numClick == 0) {
// Ready? icon, press enter key to start
fill(255);
rect(200,200,80,80);
textAlign(CENTER);
fill(255,255,255,160);
text("READY?",width/2,height/2-40);
stroke(180,15,85,100);
rect(210,245,60,20);
text("PRESS",width/2,height/2);
text("ENTER",width/2,height/2+20);
}
if (keyIsDown(13) & numClick == 0) {
numClick +=1;
// play background music and loop it
backg.amp(0.5);
backg.play()
backg.loop();
// variable that stores the values of amplitude of the music playing
amp = new p5.Amplitude();
stroke(255);
} if (numClick == 1) {
// draw the graph that changes based on amplitude of the music
soundWave();
}
// if key "w" is pressed create a "random vector field" with low bass sound
if (keyIsDown(87)) {
field();
}
// if key "a" is pressed, separating squares with a drum sound
if (keyIsDown(65)) {
square();
} else {
topX= width/2;
topY=height/2;
topX1= width/2;
topY1=height/2;
}
// if "s" is presssed, a series of "rings" will display along with chime sound
if (keyIsDown(83)) {
rings();
}
// if "d" is pressed, pattern of yellow dots start to appear with pop sound
if (keyIsDown(68)) {
pattern();
}
// if "i" is pressed a vizualization of corners moving apart
if (keyIsDown(73)) {
frames();
}
// if "j" is pressed, bars of orange and pink strips start to extend and overlap
if (keyIsDown(74)) {
knitted();
}
// if "k" is pressed, a set of three rotating shapes appears
if (keyIsDown(75)) {
triangles();
}
// if "l" is pressed, a grid of pink dots appears
if (keyIsDown(76)) {
for (var x = 0; x < width; x+=48) {
for (var y = 0; y < height; y+=48) {
fill(180,15,85,100,20);
noStroke();
ellipse(x+24+random(1),y+24+random(1),10,10);
}
}
}
// small text to help prompt users to use the keys to add sound or visual effects
push();
fill(100);
noStroke();
text("W",30,450);
text("A S D",30,470);
text("I",440,450);
text("J K L",440,470);
pop();
}
// assign sound to each key
function keyPressed(){
// if key "w" is pressed, play the low bass sound
if (keyCode === 87) {
bass.play();
dJ = true;
}
// if key "s" is pressed, a small "chime" sound is played
if (keyCode === 83) {
chime.play();
dJ = true;
}
// if "a" is pressed play the short drum sound
if (keyCode === 65) {
beat.play();
dJ = true;
}
// if "d" is pressed, play pop sound
if (keyCode === 68) {
popp.play();
dJ = true;
}
}
// graph the Amplitude of the sound
function soundWave(){
// get Amplitude of sound and add it to the array
var vol = amp.getLevel();
volhistory.push(vol);
stroke(255,255,255,170);
noFill();
push();
// map the graph in the middle of the canvas
translate(0,-height/2+40);
beginShape();
for (var i = 0; i < volhistory.length; i++) {
// remap the values of the amplitude to fit within the canvas size
var y = map(volhistory[i],0,1,height,0);
strokeWeight(2);
vertex(i,y);
stroke(250,250,250,50);
strokeWeight(1);
// draw diagonal lines that help give a 3D sense
line(i,y,-i,-y);
}
endShape();
pop();
if (volhistory.length> width) {
// keep updating and shifting "old" graph backwards to draw new ones.
volhistory.splice(0,1);
}
}
//generate a vector field of swaying lines
function field (){
var yoff = 0;
// asgn a vector component to the grid that has x number of columns and y number of rows.
for (var y = 0; y < rows+1; y++) {
var xoff = 0;
for (var x = 0; x < cols+1; x++) {
// create random angle
var angle = noise(xoff, yoff,zoff)* 40;
// define angle as an vector to make the lines turn
var v = p5.Vector.fromAngle(angle);
xoff += inc;
stroke(255);
push();
// tranlate lines to each intersection of the grid and draw it
translate(x*scl+scl,y*scl);
rotate(v.heading());
strokeWeight(3);
stroke(180,15,85,100,50);
line(0,0,scl*2,0);
pop();
}
yoff += inc;
zoff += 0.00005;
}
}
// draw two separating squares that move apart until they reach the edge of the canva
// before going back to the center of the canvas.
function square(){
noStroke();
// light red color
fill(180,15,85,100);
rectMode(CENTER);
rect(topX1,topY1,200,200);
// light orange color
fill(215,122,97,100);
rect(topX,topY,200,200)
topX1+=1;
topY1+=1;
topX-=1;
topY-=1;
// reset squared to the middle of the canvas
if (topX <80) {
topX= width/2;
topY=height/2;
topX1= width/2;
topY1=height/2;
}
}
// make cirlces appear at a random rate to make a pattern
function pattern(){
push();
translate(width/2, height/2); // so that the curve is within the canvas
beginShape();
for(var i = 0; i < volhistory.length; i++){
var theta = map(i,0,100,0,500);
// give the randomly apparenting circles to make a pattern
var a = map(volhistory[i], 0,1,-10,10);
//Conchoid of de Sluze equation from Wolfram MathWorld
var x = (1/cos(theta)+(a*cos(theta)))*cos(theta);
var y = (1/cos(theta)+(a*cos(theta)))*sin(theta);
noStroke();
fill(215,122,97,100);
//"polar array" the Conchoid from the center
rotate(90);
ellipse(x*20+random(0,1),y*20+random(0,1),4,4);
}
endShape(CLOSE);
pop();
}
// draw spinning rings
function rings(){
push();
stroke(215,122,97);
strokeWeight(5);
strokeCap(SQUARE);
arc(width/2,height/2,100,100,0-step,HALF_PI-step);
strokeWeight(3);
arc(width/2,height/2,80,80,QUARTER_PI-step,PI+HALF_PI-step);
strokeWeight(2);
arc(width/2,height/2,150,150,HALF_PI+QUARTER_PI+step,PI+HALF_PI+step);
strokeWeight(1);
arc(width/2,height/2, 200,200,0+step,PI+HALF_PI+step);
// the variable makes each arc to change and rotate
step+=0.1;
pop();
}
function frames(){
// setting up variable that governs the rate of which the corners move away
if (m >= 0) {
m+=0.5;
} // if the displacement of the corners is more than 50 pixels, reset to 0
if(m == 50) {
m = 0;
}
// small frame
stroke(255,255,255,150);
strokeWeight(4);
// top left corner
line(190-m,190-m,190-m,240-m);
line(190-m,190-m,240-m,190-m);
// top right corner
line(240+m,190-m,290+m,190-m);
line(290+m,190-m,290+m,240-m);
// bottom right corner
line(290+m,240+m,290+m,290+m);
line(290+m,290+m,240+m,290+m);
// bottom left corner
line(240-m,290+m,190-m,290+m);
line(190-m,290+m,190-m,240+m);
}
function knitted(){
// setting up the x and y values to draw the colored columns and rows
for (var i = 0; i < 8; i++) {
if (column >= 0) {
column+=0.25;
} if(column == width) {
column = 0;
}
noStroke();
fill(215,122,97,100);
// yellow bars
rect(i*width/8,0,30,height/8+column);
fill(180,15,85,100);
// pink bars
rect(0,i*height/8,column,30);
}
}
function triangles (){
stroke(215,122,97,100);
strokeWeight(2);
push();
translate(width/2,height/2);
// set rotation of the triangles to increase with the frameCount
rotate(radians(frameCount));
triangle(-50,50,0,-50,50,50);
strokeWeight(4);
rotate(radians(frameCount*.5));
triangle(-60,60,0,-60,60,60);
strokeWeight(2);
rotate(radians(frameCount*2));
triangle(-65,65,0,-65,65,65);
pop();
}