Crystal-Xue-Final-Project

sketch-134js


var imgPhone;
var imgLogo;
var imgAlb;
var imgBg;
var imgLike;
var song;
var amp;
var fft;
var volhistory = [];
var scrWid = 270; // width of the iphone screen

function preload(){
    //preloading images and sound source
    imgPhone = loadImage("https://i.imgur.com/Mb4yoMB.jpg?2");
    imgLogo = loadImage("https://i.imgur.com/sFAzrlV.jpg?3");
    imgAlb = loadImage("https://i.imgur.com/EAsdXzG.png?1");
    imgBg = loadImage("https://i.imgur.com/Ztd0x2o.jpg")
    imgLike = loadImage("https://i.imgur.com/vX1cA55.jpg?1");
    song = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/instagram.wav");
    song.setVolume(0.5);
}

function setup() {
    createCanvas(323, 635);
    song.play();
    amp = new p5.Amplitude();
    fft = new p5.FFT(0.9, 256);
    angleMode(DEGREES);

}

function draw() {
    background(255);

    var vol = amp.getLevel();
    volhistory.push(vol);

    //setup constrains for bountries
    var topWall = scrWid / 2 + 130;
    var botWall = height - scrWid / 2 - 100;
    var yc = constrain(mouseY, topWall, botWall);

    //draw iphne and instagram logo
    image(imgPhone, 0, 0);
    image(imgLogo, width / 2 - 50, 47);

    drawPost();

    push();
    translate((width - scrWid) / 2, yc-height + scrWid - 40);
    drawfft();
    pop();

    push();
    translate((width - scrWid) / 2, -height + scrWid / 2 + yc);
    drawAmp();
    pop();

    push();
    translate(width / 2, yc);
    drawCir();
    pop();


}

function drawfft(){
    //setup colors
    var colorvar = frameCount;
    if (colorvar >= 255) {
        colorvar = 0;
    } else {colorvar = frameCount;}
    var rC = map(colorvar, 0, width, random(255), 255);
    var g = map(colorvar, 0, width, random(255), 100);
    var b = map(colorvar, 0, height, random(255), 255);
    strokeWeight(2);
    stroke(rC, g, b, 90);

    var spectrum = fft.analyze();
    for (var i = 0; i < spectrum.length; i++) {
        var y = map(spectrum[i], 0, 250, 0, scrWid);
        //spacings
        var w = scrWid/64;
        line((i)*w, scrWid, (i)*w , y+scrWid);
    }
}

function drawAmp(){
    //setup colors
    var colorvar = frameCount;
    if (colorvar >= 255) {
        colorvar = 0;
    } else {colorvar = frameCount;}
    var rC = map(colorvar, 0, width, random(255), 255);
    var g = map(colorvar, 0, width, random(255), 100);
    var b = map(colorvar, 0, height, random(255), 255);

    noStroke();
    fill(rC, g, b, 90);
    //draw amplitutes
    beginShape();
    vertex(0, height);
    for (var i = 0; i < volhistory.length; i++) {
        var y = map(volhistory[i], 0, 1, height, 0);
        vertex(i, y);
    }
    vertex(scrWid, height);
    endShape();

    //make sure the graphs stays inside the width of the screen
    if (volhistory.length > scrWid) {
        volhistory.splice(0, 1);
    }
}

function drawPost(){
    rectMode(CENTER);
    stroke(255);
    //setup constrains
    var topWall = scrWid / 2 + 130;
    var botWall = height - scrWid / 2 - 100;
    var yc = constrain(mouseY, topWall, botWall);

    //draw post images
    fill(100);
    rect(width/2, yc, scrWid, scrWid);
    //draw album profile image
    image(imgAlb, 35, yc - scrWid / 2 - 60, 45, 45);
    //draw background image
    image(imgBg, width / 2 - scrWid / 2, yc - scrWid / 2, scrWid, scrWid);
    //draw like image
    image(imgLike, 250, yc, 40 + random(0, 5) ,32 + random(0, 5));

    //draw post texts
    textSize(14);
    text("DEAN", 100,  yc-scrWid / 2 - 30);
    textSize(12);
    text(frameCount, 30, yc + scrWid / 2 + 30);
    text("likes", 70, yc + scrWid / 2 + 30);
    text("#dean #instagram #soundvisualization", 30, yc + scrWid / 2 + 45);
    text("All night just wasting time like this", 30, yc + scrWid / 2 + 60);
    text("Inside your Instagram", 30, yc + scrWid / 2 + 75);
}

function drawCir(){
    noFill();
    stroke(255);
    strokeWeight(1.5);
    beginShape();
    for (var i = 0; i < 360; i++) {
        var r = map(volhistory[i], 0, 1, 10, 300);
        var x = r*cos(i);
        var y = r*sin(i);
        vertex(x,y);
    }
    endShape();
    //make sure that the the lines don't overlap
    if (volhistory.length > 360) {
        volhistory.splice(0, 1);
    }
}

This Project is about visualization of the song “Instagram”. The main theme is to deliver the message of social media anxiety among teenagers that everything is about the obsession of “likes” and how to gain popularity through posts. I mimicked the Instagram app page to set the base of this project. And as the progression of the song is represented by the intensity of the graphics. The anxiety also levels up when the “like” number goes up over time.

STAGE 1
STAGE 2
STAGE 3

Crystal-Xue-Project-12-Proposal

For my final proposal, I want to create a sound interactive project. There will be sound visualization for the main piece and mouse interactive parts that can control the pitch/volume etc. I will also make the changes to be perceivable in the visualization part. The geometry is not fully designed yet. I’ll have to experiment with the sound itself to decide the best way to deliver my project (possibly use the z-coordinate)

final project proposal

Crystal Xue-LookingOutwards-12

For my final project, I want to do sound visualization. And here are two projects that I found particularly interesting.

This first project is called WAVES is created by students from OPENLIGHT: the creative lab of Intelligent Lighting Institute of the TU Eindhoven. Using a “sound camera”, a device with 1024 microphones which can very precisely locate a sound in space, students place it in an industrial place and visualized waves. People can interact with the device by making sounds, whistles, stomping their feet etc.

The next project is VOICE ARRAY. by Rafael Lozano-Hemmer. The LED light blinking gives a visual representation of the recorded sound

Rafael Lozano-Hemmer, “Voice Array, Subsculpture 13”, 2011. “Recorders”, Museum of Contemporary Art, Sydney, 2011. Photo by: Antimodular Research
Rafael Lozano-Hemmer, “Voice Array, Subsculpture 13”, 2011. “Recorders”, Museum of Contemporary Art, Sydney, 2011. Photo by: Antimodular Research

Both of them showed different techniques and interactions that might happen in sound visualization. And I hope my project can have similar achievement like them.

Crystal Xue-LookingOutwards-11

Geraldline Juarez is a Mexican and Swedish visual artist. She likes to use time-based media, sculpture and performance to consider the materials, histories, technics, politics and economics shaping the dominant narratives and contexts in contemporary media culture.

I am intrigued by one of her 2019 “collection”, here are 4 of the pieces she created known as “non-functional jewelry” mainly made with porcelain, silver clay re-materialized from photographic waste and broken screens from smartphones. The ironic property allows us to reflect upon the durability and add-values of jewelry.

“Jewels are ornaments but also markers of time, what kind of memories will these jewels evoke in the future?” – Geraldline Juarez

Screenware is a method for glazing ceramics using refuse from smartphones and computer LCD’s screens as glass former.

Ice Blue Ring
Bisque black Porcelain and screenglaze
Screenware
Mineral Black Ring
Black Porcelain and screenglaze
Screenware
Silver Pearl Ring
Silver clay and screen pearl
Screenware
Screen pearls

Crystal-Xue-Project-11

sketch-237.js

//Crystal Xue
//15104-section B
//luyaox@andrew.cmu.edu
//Project-11

var terrainSpeed;
var terrainDetail;
var c1, c2;
var cacti = [];
var cWidth = 50; //cactus Width
var cLeft = - 20 - cWidth; //left point of cactus drawn

function setup() {
    createCanvas(480, 240);
    // create an initial collection of cacti
    for (var i = 0; i < 4; i++){
        var xLocation = random(width);
        var yLocation = random(150, 170);
        cacti[i] = makeCacti(xLocation, yLocation);
    }

    frameRate(20);
    //two end colors of the gradient backgound
    c1 = color(134, 162, 148);
    c2 = color(245, 193, 140);
}

function draw() {
    setGradient(c1, c2);
    terrain();
    //addCacti();
    updateCacti();

}

function drawCacti() {
    noStroke();
    fill(255, 230, 238);
    push();
    translate(this.x2, this.y2);
    scale(this.cactiSize);
    stroke(61,73,49);
    strokeWeight(10);
    line(0, 0, 0,60);

    noFill();
    stroke(61,73,49);
    strokeWeight(10);
    beginShape();
    curveVertex(-20,20);
    curveVertex(-20,20);
    curveVertex(-15,30);
    curveVertex(0,30);
    curveVertex(20,25);
    curveVertex(25,-10);
    curveVertex(25,-10);
    endShape();

    stroke(100,100,89);
    strokeWeight(0.5);
    line(0, -2, 0,62);
    line(2, -2, 2,62);
    line(-2, -2, -2,62);

    //draw cacti spines
    fill(0);
    noStroke();
    ellipse(0,2,2,2);
    ellipse(5,20,3,3);
    ellipse(20,30,2,2);
    ellipse(30,10,2,2);
    ellipse(-15,17,3,3);
    ellipse(-10,27,2,2);
    ellipse(5,45,2,2);
    pop();
}


function makeCacti(xlocation, ylocation) {
    //Cacti objects
    var makeCactus = {x2: xlocation,
                      y2: ylocation,
                      cactiSize: random(0.8,1.5),
                      speed: -2.0,
                      move: moveCacti,
                      draw: drawCacti}
    return makeCactus;
}

function moveCacti() {
    //make cacti move
    this.x2 += this.speed;
    if (this.x2 <= cLeft) {
        this.x2 += width - cLeft;
    }
}

function updateCacti() {
    for(i = 0; i < cacti.length; i++) {
        cacti[i].move();
        cacti[i].draw();
    }
}

function setGradient(c1, c2) {
    //gradient color background
    noFill();
    for (var y = 0; y < height; y++) {
        var inter = map(y, 0, height, 0, 1);
        var c = lerpColor(c1, c2, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

function terrain(){
    terrainSpeed = 0.0002;
    terrainDetail = 0.006;

    //draw dessert mountain 1
    fill(225, 184, 139);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y1 = map(noise(t1), 0, 1, 80, height);
        vertex(x, y1);
    }
    vertex(width, height);
    endShape();

    //draw dessert mountain 2
    terrainDetail = 0.007;
    fill(225, 164, 109);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y1 = map(noise(t1), 0, 1, 100, height);
        vertex(x, y1);
    }
    vertex(width, height);
    endShape();

    //draw ground
    terrainDetail = 0.0005;
    fill(160, 96, 69);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t2 = (x * terrainDetail) + (millis() * terrainSpeed);
        var y2 = map(noise(t2), 0, 1, 180, height);
        vertex(x, y2);
    }
    vertex(width, height);
    endShape();
}

This is a landscape of a desert with different sized cactus along the road and different depth of the scenery.

Crystal-Xue-Project-10

sketch-152.js

//Crystal Xue
//15104-section B
//luyaox@andrew.cmu.edu
//project-10

//size of the vinyl
var size1 = 300;
//size of the label
var size2 = 100;

function preload(){
    jazz1 = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/475409__sandib__bass2.wav");
    jazz2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/49658__sub-d__more-jazz-guitar.wav");
    jazz3 = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/233699__gulyas25__acid-jazz-loop-music-bed.wav");
    jazz4 = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/187099__simondsouza__alto-sax-90bpm-cm-4-solo.wav");
    jazz4.setVolumn(0.1);
}


function setup() {
    createCanvas(500, 500);
}

function draw() {
    background(250);
    drawRecord();
}
function drawRecord(){
    fill(0);
    ellipse(width/2, width/2, size1, size1);

    for (var i = 0; i < 8; i++) {
        noFill();
        stroke(105);
        strokeCap(SQUARE);
        strokeWeight(0.4);
        arc(width/2, width/2, i * 20 + 140, i * 20 + 140, PI, 0.8 * PI);
    }

    for (var i = 0; i < 8; i++) {
        noFill();
        stroke(255);
        strokeCap(SQUARE);
        strokeWeight(1);
        arc(width/2, width/2, i * 20 + 140, i * 20 + 140, 0.8 * PI, PI);
    }
    for (var i = 0; i < 8; i++) {
        noFill();
        stroke(105);
        strokeCap(SQUARE);
        strokeWeight(0.4);
        arc(width/2, width/2, i * 20 + 140, i * 20 + 140, PI, 1.8 * PI);
    }
    for (var i = 0; i < 8; i++) {
        noFill();
        stroke(255);
        strokeCap(SQUARE);
        strokeWeight(1);
        arc(width/2, width/2, i * 20 + 140, i * 20 + 140, 1.8 * PI, 2 * PI);
    }

    fill(250,50);
    arc(width/2, width/2, i * 20 + 140, i * 20 + 140, 0.8 * PI, PI);
    fill(250,50);
    arc(width/2, width/2, i * 20 + 140, i * 20 + 140, 1.8 * PI, 2 * PI)

    //drawing red label
    fill(255, 0, 0);
    noStroke();
    ellipse(width/2, width/2, size2, size2);

    //drawing controls
    var yc = constrain(mouseY,350, 470);

    fill(100);
    rect(410, 350, 10, 120);
    fill(0);
    rect(400, yc, 30, 15);

    fill(100);
    rect(450, 350, 10, 120);
    fill(0);
    rect(440, yc, 30, 15);

    fill(100);
    ellipse(430, 100, 60, 60);
    fill(0);
    ellipse(430, 100, 40, 40);

    fill(100);
    ellipse(450, 160, 45, 45);
    fill(0);
    ellipse(450, 160, 30, 30);

}

function mousePressed() {
    //setting mousepresed location
    if (dist(mouseX,mouseY, width / 2, height/ 2) <= size1 ) {
        jazz1.play();
        } else {
        jazz1.pause();
        }
    if (dist(mouseX, mouseY, 430, 100) <= 60) {
        jazz2.play();
        } else {
        jazz2.pause();
        }
    if (dist(mouseX, mouseY, 450, 160) <= 45) {
        jazz3.play();
        } else {
        jazz3.pause();
        }
}

function mouseMoved(){
    if (mouseX <= 450 & mouseX >= 410 && mouseY <= 470 && mouseY >= 350) {
        jazz4.play();
        } else {
        jazz4.pause();
        }
}

It is inspired by jazz mixtapes. there are 3 different jazz tracks that can be started and paused by pressing the buttons and the record player. The fouth is controlled by the moving control which is more interesting to play with.

Crystal Xue-LookingOutwards-10

Christine Sun Kim, deaf since birth, explores her subjective experiences with sound in her work. She investigates the operations o sound and various aspects of deaf culture in her performances, videos, and drawings. She uses a lot of elements like body language, ASL(Amerian Sign Language) and so as her interpretation to expand the traditional scope of communication.

This particular project shown above is called “game of skill 2.0” is displayed in MoMA PS1. Audiences are invited to listen to a reading of a text about the future. Pathways are created in concert with the game’s console, causes the device to emit sound at a pace proportional to the participant’s movement. The physical scrubbing process is the direct interaction with the sound.

Crystal-Xue-Project-09

sketch-231.js

//Crystal Xue
//15104-section B
//luyaox@andrew.cmu.edu
//Project-09

var underlyingImage;
var xarray = [];
var yarray = [];

function preload() {
    var myImageURL = "https://i.imgur.com/Z0zPb5S.jpg?2";
    underlyingImage = loadImage(myImageURL);
}

function setup() {
    createCanvas(500, 500);
    background(0);
    underlyingImage.loadPixels();
    frameRate(20);
}

function draw() {
    var px = random(width);
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    var theColorAtLocationXY = underlyingImage.get(ix, iy);

    stroke(theColorAtLocationXY);
    strokeWeight(random(1,5));
    var size1 = random(5,15);
    //brush strokes from bottom left to top right diagnal direction
    line(px, py, px - size1, py + size1);

    var theColorAtTheMouse = underlyingImage.get(mouseX, mouseY);
    var size2 = random(1,8);
    for (var i = 0; i < xarray.length; i++) {
        stroke(theColorAtTheMouse);
        strokeWeight(random(1,5));
        //an array of brush strokes from top left to bottom right diagnal direction controlled by mouse
        line(xarray[i], yarray[i],xarray[i]-size2,yarray[i]-size2);
        size2 = size2 + 1;
        if (i > 10) {
            xarray.shift();
            yarray.shift();
        }
    }
}

function mouseMoved(){
    xarray.push(mouseX);
    yarray.push(mouseY);
}

phase-1
phase-2
phase-3
original picture

This is a weaving portrait of my friend Fallon. The color pixels will be concentrated on the cross between strokes of two directions

Crystal Xue-LookingOutwards-09

Fallon Creech’s LookingOutwards-05 is particularly interesting to me when I was looking through some of my peer’s posts. The generative artist Thomas Lin Pedersen created this series of art pieces by programming and using visualization techniques.

He believes “the process of generative art is dual,” meaning both system development and visualization method are required. I think that computational generative art is about developing a system that assists the delivery of an idea and its artistic value. I understand the artist thinks that the techniques should be focused less than the art itself. However, even without programming code being shared, I would love to see the generative progress of the artwork, and how the piece comes up together.

“genesis338” belongs to Pedersen’s Generative Art collection.
“genesis4321” belongs to Pedersen’s Generative Art collection.

Crystal Xue-LookingOutwards-08

Speaker: Jake Barton

Jake Barton is a Brooklyn born and raised designer. He is the founder of the Local Projects that focuses on expression of emotions in technology in all ranges of projects such as museums, education, architecture, and memorials, etc.

In the Eyeo Festival 2012 video, he mentioned the Cleveland Museum of Art project which is very intriguing. Breaking the traditional way of how visitors engage in an art museum, Jake successfully turned presentations into experiences. People make active interactions with the exhibit instead of being passively receiving the information.

The team made very different interfaces using technology like face recognition to experiment with a whole different way of learning. At the end of the day, a museum is all about story telling. Instead of reading a tedious paragraph of words, museum visitors enjoy and learn more with interactive processes.