Sara Frankel – Final Project

sketch

// Sara Frankel
// Final Project
// sfrankel
// Section A

var liftYourself;
var shostyTen;
var liftArray;
var fft;
var greatestWave;
var isPlaying;
var greatestOverall = 0;
var isLiftYourself;

function preload() {
    shostyTen = loadSound("https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/shostakovich-symphony-no-10-mvt-2-gianandrea-noseda-london-symphony-orchestra.mp3");
    liftYourself = loadSound("https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/Lift-Yourself.mp3"); 
}

function setup(){
    var cnv = createCanvas(400, 400);
    cnv.mouseClicked(togglePlay); //plays the canvas when clicked
    fft = new p5.FFT();
    liftYourself.amp(0.2);
    shostyTen.amp(1);
    isPlaying = false;
    isLiftYourself = true;
}

function draw(){
    background(0);
    var spectrum = fft.analyze(); //uses FFT to use the "spectrum" of sound (i.e. the eyebrows)
    var waveform = fft.waveform(); //uses FFT to use the waveform of the sound (i.e. the squiggled hair)
    noStroke();
    
    //draw variable to keep track of the greatest wave to give the "pulse" effect
    greatestWave = 0;
    for (i = 0; i < waveform.length; i++) {
        if(waveform[i] > greatestWave) {
            greatestWave = waveform[i];
        }   
    }
    //takes greatest overal wave value and stores it as greatest wave
    if(greatestWave > greatestOverall){
        greatestOverall = greatestWave;
    }

  
    //uses map use the value of the greatest wave of the sound and put it on a scale for color
    fill(map(greatestWave, 0, greatestOverall, 255, 0), map(greatestWave, 0, greatestOverall, 0, 255), map(greatestWave, 0, greatestOverall, 0, 0));
    

    //draws the "hair" of the eyebrow when turned on
    //left eyebrow
    for (var i = 0; i < spectrum.length; i++){
        var x = map(i, 0, spectrum.length, 0, width / 3); //maps i on the length of the spectrum variable
        var h = -height + map(spectrum[i], 0, 255, height, 0); //maps position in the spectrum array to allow height
        rect(x + width * 0.75 - 50, height / 4 + 35, width / spectrum.length, h / 4);
    }
    //right eyebrow
    for (var i = 0; i < spectrum.length; i++){
        var x = map(i, 0, spectrum.length, width / 3, 0);
        var h = -height + map(spectrum[i], 0, 255, height, 0);
        rect(x + 15, height / 4 + 20, width / spectrum.length, h / 4);
    }

    //draws base of eyebrows
    stroke(255);
    line(width / 4, height / 4 + 20, width / 4 + 50, height / 4 + 20);
    line(width * 0.75 - 50, height / 4 + 35, width * 0.75, height / 4 + 35);

    noFill();
    //draw eyeballs
    var y = map(greatestWave, -1, 1, 0, height); //allows for the eyes and head to pulse
    ellipse(width / 4 + 20, height / 4 + 60, y / 3, y / 3);
    ellipse(width * 0.75 - 20, height * 0.25 + 60, y / 6, y / 6);
    //draws head
    ellipse(width / 2, height / 2, y * 1.5, y * 1.5); 

    //calls that if the audio is playing, the color of hair and eyes change to the music
    if(isPlaying) {
        fill(map(greatestWave, 0, greatestOverall, 0, 255), map(greatestWave, 0, greatestOverall, 255, 0), map(greatestWave, 0, greatestOverall, 255, 0));
        stroke(map(greatestWave, 0, greatestOverall, 0, 255), map(greatestWave, 0, greatestOverall, 255, 0), map(greatestWave, 0, greatestOverall, 255, 0));
    } else {
        noFill();
        stroke(255);
    }

    //uses drawHairAtAngle function to draw the hair on the head that follows the pulse of the head (stays in spot with music)
    drawHairAtAngle(-14 * PI / 18, y * 0.75, waveform);
    drawHairAtAngle(-12 * PI / 18, y * 0.75, waveform);
    drawHairAtAngle(-10 * PI / 18, y * 0.75, waveform);
    drawHairAtAngle(-8 * PI / 18, y * 0.75, waveform);
    drawHairAtAngle(-6 * PI / 18, y * 0.75, waveform);
    drawHairAtAngle(-4 * PI / 18, y * 0.75, waveform);

    //allows eyes to follow mouse, drawing eyeballs
    var eX = map(mouseX, 0, y, -1, 1); 
    var eY = map(mouseY, 0, y, -1, 1);
    ellipse(eX + width / 4 + 20, eY + height / 4 + 60, 40, 40);
    ellipse(eX / 2 + width * 0.75 - 20, eY / 2 + height * 0.25 + 60, 20, 20);

    //states that if playing, the color of the mouth and eyebrows change color
    if(isPlaying) {
        stroke(map(greatestWave, 0, greatestOverall, 255, 0), map(greatestWave, 0, greatestOverall, 0, 255), map(greatestWave, 0, greatestOverall, 0, 0));
    } else {
        stroke(255);
    }

    //draws mouth
    for (var i = 0; i < waveform.length; i++){
        var x = map(i, 0, waveform.length, width/4, width * 0.75);
        var y = map(waveform[i], -1, 1, 0, height);
        line(width / 2, y + 50, x, height / 2 + 50);
    }

    //displays instructions of the canvas and which song is playing
    stroke(255);
    noFill();
    text('Click to play or pause - Press space to change song', 60, 15);
    if(isLiftYourself) {
        text("Kanye West - Lift Yourself", width - 150, height - 10);
    } else {
        text('Dmitri Shostakovich - Symphony No. 10 Second Movement', width - 360, height - 10);
    }
}


// fade liftYourself if mouse is over canvas
function togglePlay() {
    //if statement that allows for each song to play and not overlap another and still alows for the click to play/stop to work
    if(isLiftYourself){
        if (liftYourself.isPlaying()) {
        liftYourself.pause();
        isPlaying = false;
        } else {
            shostyTen.pause();
            liftYourself.loop();
            isPlaying = true;
        }
    } else {
        if (shostyTen.isPlaying()) {
            shostyTen.pause();
            isPlaying = false;
        } else {
            liftYourself.pause();
            shostyTen.loop();
            isPlaying = true;
        }
    }
}

//object that helps to draw the hair along the head
function drawHairAtAngle(angle, rad, waveform) {
    beginShape();
    for (var i = 0; i < waveform.length; i++) {
        //uses map to place the hairs along the radius of the circle evenly spaced
        var hairY = map(i, 0, waveform.length, sin(angle) * rad + height / 2, sin(angle) * (rad) + height / 2 - 25);
        var hairX = map(waveform[i], -0.5, 0.5, cos(angle) * (rad - 25) + width / 2, cos(angle) * (rad + 25) + width / 2); 
        vertex(hairX, hairY);
    }
    endShape();
}

//function to switch songs if space bar is clicked
function keyTyped() {
    if(key === ' ') {
        isLiftYourself = !isLiftYourself;
        togglePlay();
    }
 }


For this project, I decided to visualize music. My first vision at this project was something more abstract, but as I was creating the project I felt it to be more fun to have a face. This face visualizes music in the sense that all aspects of it “dance” to the music. The eyebrows raise, the hair squiggles, and the mouth draws lines to give the effect of singing. What I wanted to prove in this project is that not only is Kanye West “boppable” to, but so can classical music. The image posted below is a screen shot taken from the Shostakovich.

The instructions for this project are:
To play click the canvas
To change the song click space
To dance along (with the eyes) move the mouse!

Hope you enjoy!

if code does not work correctly, here is the zip.file for it!
https://drive.google.com/file/d/1O-X48r1iUjrtR_PWghS4f_l9hLtnG8Vf/view?usp=sharing

Leave a Reply