xxxxxxxxxx
295
/*
Brian (Hyunje) Park
IML 300
Project 1
Credits:
Inspired by 2D Audio Visualizer from Colorful Coding Project #17: https://www.youtube.com/watch?v=uk96O7N1Yo0
WebGL and Spherical Coordinates tutorial from Kazuki Umeda: https://www.youtube.com/@kazukiumeda4903
Statement:
What does sound look like? Such a question might seem nonsensical as it might feel the same as asking what smell a certain color has. Looking at waveforms, however, gives a clear answer to the question. As sounds are longitudinal waves that travel through the air, there is always a way in which we can visualize them. If you spread sand or pour water on top of a speaker, beautiful patterns based on sound waves appear depending on the sound you play. But how can we imagine sound in shapes and forms we've never seen before? By utilizing WebGL, this project visualizes sounds in various spherical forms which the user can manipulate. From regular spheres to bumpy ones, this visualizer helps reveal beautiful patterns that lie in sound.
*INSTRUCTIONS*
Press Return/Enter to play/pause the song
Press '1' to play TAKE A CHANCE
Press '2' to play Moanin'
Press '3' to play The Wave
Press through q, w, e, r to switch between different spherical forms
Use the sliders at the bottom of the screen to control various elements of the 3D objects
*/
let music = 1;
let fft;
let angle = 0;
let offset = 0;
let ptDensSlide;
let multSlide;
let mult2Slide;
function preload() {
music1 = loadSound("takeAChance.mp3");
music2 = loadSound("moanin.mp3");
music3 = loadSound("theWave.mp3");
font = loadFont("bdrMedium.otf");
}
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
textFont(font);
textSize(15);
angleMode(DEGREES);
fft = new p5.FFT();
ptDensSlide = createSlider(15, 90, 40, 1);
ptDensSlide.position(0, windowHeight);
multSlide = createSlider(2, 30, 6, 1);
multSlide.position(windowWidth / 4, windowHeight);
mult2Slide = createSlider(2, 20, 6, 1);
mult2Slide.position(windowWidth / 2, windowHeight);
}
function keyTyped() {
if (key === "1") {
music = 1;
music2.stop();
music3.stop();
} else if (key === "2") {
music = 2;
music1.stop();
music3.stop();
} else if (key === "3") {
music = 3;
music1.stop();
music2.stop();
}
}
function musicInfo() {
push();
translate((-1 * windowWidth) / 2.2, (-1 * windowHeight) / 2.2);
text("now playing:", 0, 0);
pop();
push();
translate((-1 * windowWidth) / 2.2, (-1 * windowHeight) / 2.3);
if (music === 1) {
text("DOMi & JD BECK, Anderson .Paak - TAKE A CHANCE", 0, 0);
} else if (music === 2) {
text("Sakamichi no Apollon OST - Moanin'", 0, 0);
} else if (music === 3) {
text("SE SO NEON - The Wave", 0, 0);
}
pop();
}
function sphereControl() {
rotateX(angle);
rotateY(angle);
rotateZ(angle);
angle += 0.1;
offset += 0.5;
}
function draw() {
background(0);
stroke(255, 255, 255);
strokeWeight(0.7);
fill(255);
musicInfo();
bumpySphere();
if (key === "q") {
clear();
musicInfo();
sphereControl();
regularSphere();
} else if (key === "w") {
clear();
musicInfo();
sphereControl();
tanSphere();
} else if (key === "e") {
clear();
musicInfo();
sphereControl();
bumpySphere();
} else if (key === "r") {
clear();
musicInfo();
sphereControl();
galaxySphere();
} else {
musicInfo();
sphereControl();
bumpySphere();
}
fft.analyze();
bass = fft.getEnergy(20, 200);
push();
if (bass > 230) {
angle += 0.8;
}
pop();
}
function regularSphere() {
let wave = fft.waveform();
for (let phi = 0; phi < 180; phi += 180 / ptDensSlide.value()) {
beginShape(POINTS);
for (let theta = 0; theta < 360; theta += 360 / ptDensSlide.value()) {
let index = floor(map(theta, 0, 360, 0, wave.length));
let r = map(wave[index], -1, 1, 75, 200);
let x = r * cos(phi + offset);
let y = r * sin(phi + offset) * sin(theta);
let z = r * sin(phi + offset) * cos(theta);
vertex(x, y, z);
}
endShape(CLOSE);
}
}
function tanSphere() {
let wave = fft.waveform();
for (let phi = 0; phi < 180; phi += 180 / ptDensSlide.value()) {
beginShape(POINTS);
for (let theta = 0; theta < 360; theta += 360 / ptDensSlide.value()) {
let index = floor(map(theta, 0, 360, 0, wave.length));
let r = map(wave[index], -1, 1, 75, 200);
let x =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
tan((phi + offset) * mult2Slide.value())) *
cos(phi);
let y =
r *
(1 +
-0.2 *
sin(theta * multSlide.value()) *
tan((phi + offset) * mult2Slide.value())) *
sin(phi) *
sin(theta);
let z =
r *
(1 +
-0.2 *
sin(theta * multSlide.value()) *
tan((phi + offset) * mult2Slide.value())) *
sin(phi) *
cos(theta);
vertex(x, y, z);
}
endShape();
}
}
function bumpySphere() {
let wave = fft.waveform();
for (let phi = 0; phi < 180; phi += 180 / ptDensSlide.value()) {
beginShape(POINTS);
for (let theta = 0; theta < 360; theta += 360 / ptDensSlide.value()) {
let index = floor(map(theta, 0, 360, 0, wave.length));
let r = map(wave[index], -1, 1, 75, 130);
let x =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
cos(phi);
let y =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
sin(phi) *
sin(theta);
let z =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
sin(phi) *
cos(theta);
vertex(x, y, z);
}
endShape();
}
}
function galaxySphere() {
let wave = fft.waveform();
for (let phi = 0; phi < 180; phi += 180 / ptDensSlide.value()) {
beginShape(POINTS);
for (let theta = 0; theta < 360; theta += 360 / ptDensSlide.value()) {
let index = floor(map(theta, 0, 360, 0, wave.length));
let r = map(wave[index], -1, 1, 75, 130);
let x =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
cos(phi);
let y =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
tan(phi) *
sin(theta);
let z =
r *
(1 +
0.2 *
sin(theta * multSlide.value()) *
sin((phi + offset) * mult2Slide.value())) *
tan(phi) *
cos(theta);
vertex(x, y, z);
}
endShape();
}
}
function keyPressed() {
if (keyCode === RETURN) {
if (music === 1) {
if (music1.isPlaying()) {
music1.pause();
noLoop();
} else {
music1.play();
loop();
}
}
if (music === 2) {
if (music2.isPlaying()) {
music2.pause();
noLoop();
} else {
music2.play();
loop();
}
}
if (music === 3) {
if (music3.isPlaying()) {
music3.pause();
noLoop();
} else {
music3.play();
loop();
}
}
}
}