0% found this document useful (0 votes)
156 views11 pages

Three.js Audio Spectrum Visualizer

This document describes the implementation of a Three.js based audio spectrum visualizer. It discusses creating different geometric objects like circles and diamonds to visualize the audio spectrum retrieved from an audio file or live microphone input. Code snippets show how the scene is set up with these geometric objects and how the audio data is analyzed to update the visualization in real-time based on amplitude of different frequencies. Problems faced include not being able to get live microphone input working and making the visualization more minimalistic and complex.

Uploaded by

Samuel Putra
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
156 views11 pages

Three.js Audio Spectrum Visualizer

This document describes the implementation of a Three.js based audio spectrum visualizer. It discusses creating different geometric objects like circles and diamonds to visualize the audio spectrum retrieved from an audio file or live microphone input. Code snippets show how the scene is set up with these geometric objects and how the audio data is analyzed to update the visualization in real-time based on amplitude of different frequencies. Problems faced include not being able to get live microphone input working and making the visualization more minimalistic and complex.

Uploaded by

Samuel Putra
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1

[Link] Based Audio Spectrum Visualizer

Stefan Liemawan (2101694690), Asoka Wotulo (2101693611), Samuel Putra (2101693630)

BINUS University International


2

Background

Music visualization was popularized by the existence of windows media player. At that

time, it was considered a replacement for video. It was interactive and was default in every PC

out there. It generates a certain animated imagery or illustration based on the audio source

provided, in this case music. It usually is generated in real time, syncs, rendered and reacts with

the music as we’re hearing them live. There are various techniques that can be used to visualize

the music. It ranges from simple ones, to composite effects. Composite effects are audio

visualization effects that are combines various simple visualization algorithms to create a

visualization that is much more complex. Most of the time though, the music’s frequency (pitch)

and amplitude (loudness) are the two main determining factors. Since music is a subjective

matter, to us an effective music visualization is one that attains a high degree of correlation

between the music’s frequency and amplitude. The music needs to correlate and make sense to

the music.

In this computer graphics project, we were asked to create something that uses JavaScript

and WebGL to produce a visualization on browsers. We then decided to create a web-based

music visualization based on [Link]. Early on, we learned [Link], we found that [Link]

even though it has a lot o easy sources to learn from, and is still actively developed, for our uses

[Link] was much more convenient. It is much more feature rich ranging from effects, scenes,

cameras, animations, lights, materials, shaders, objects, geometry, data loaders, utility, and much

more. To add to that, it is better documented than [Link], but our pivoting reason was that it

could support most industry standard file formats, this proved useful as we needed to import

audio files and we wanted to minimalize the off chance of a troubleshoot happening.
3

Problems

There were some problems that we had encounter during the creation of this project. Our

aesthetic was black and white, we wanted to make a minimalist visualization with a higher

complexity to it. We didn’t think of adding various colors to aid the visualization. Another

problem is with a live microphone feed to the computer. At first, we wanted to be able to

visualize a live microphone feed to the computer, however we didn’t manage to get it to work.

Adding the camera shake proved to be tricky as well, but we managed to figure that out.

Related Work

To our best knowledge, there are [Link] based audio visualizer projects. One of them is

a project created by Janine, a student of Fullstack Academy on September 29, 2017. She created

the project using the JavaScript library, [Link], as well as the Web Audio API. In this project

users can choose four songs that exemplify the different average frequencies and can also decide

how wide the visualization will appear on screen. The height of each cube is directly mapped to

an array of frequency data available at every moment, and the color changes based on the

average frequency. The following link, redirects to her project;

[Link]

The difference between her projects and ours, is the way the music was visualized. It was

visualized as a wave spectrum comprised of smaller cubes. Our project visualizes the music

using arrayed circles.


4

Implementation
5

Code Snippet

<html>

<head>
<title>Audio</title>
<style>
body {
margin: 0;
color: black;
}
canvas {
width: 100%;
height: 100%;
}
#audio {
position: absolute;
bottom: 2%;
left: 50%;
transform: translateX(-50%);
width: 50%;
height: 5%;
outline: none;
}
#file {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>

<body>

<input type="file" id="file" accept="audio/*" />


<audio id="audio" controls></audio>

<script src="/node_modules/three/build/[Link]"></script>
<script
src="/node_modules/three/examples/js/controls/[Link]"></script>
<script>
6

var id = null;
var white = new [Link]('white');
var color = new [Link]('black');
var renderer = new [Link]();
[Link]([Link], [Link]);
[Link]([Link]);
// create scene
var scene = new [Link]();
[Link] = new [Link](white);
var camera = new [Link](100, [Link] /
[Link], 0.1, 2000);
[Link](0, 0, 600);
[Link]();

var controls = new [Link](camera, [Link]);


[Link] = 700;
[Link] = 900;
[Link]();
var file = [Link]("file");
var audio = [Link]("audio");
[Link] = function () {
if (id !== null) cancelAnimationFrame(id);
var files = [Link];
[Link] = [Link](files[0]);
[Link]();
[Link]();
render();
}
var context = new AudioContext();
var src = [Link](audio);
var analyser = [Link]();
[Link](analyser);
[Link]([Link]);
[Link] = 1024;
var bufferLength = [Link];
var data = new Uint8Array(bufferLength);
//------------------------------------------------------GEOMETRY----------
----------------------------------------------
//group1 circle spectrum
var geometry = new [Link](10, 0.03, 16, 100);
var material = new [Link]({ color: color });
var group = new THREE.Object3D();
[Link](group);
7

for (var i = 0; i < [Link]; i++) {


var mesh = new [Link](geometry, material);
if (i % 2 == 0) [Link](0, 0, i);
else [Link](0, 0, -i);
[Link](mesh);
}

//group2 outer diamond


var geometry2 = new [Link](20, 0);
var material2 = new [Link]({ color: color });
var group2 = new THREE.Object3D();
[Link](group2);
for (var i=0; i<4; i++) {
var mesh2 = new [Link](geometry2, material2);
[Link](mesh2);
}
[Link][0].[Link](500, 0, 0);
[Link][1].[Link](-500, 0, 0);
[Link][2].[Link](0, 500, 0);
[Link][3].[Link](0, -500, 0);
//group3 inner diamond
var geometry3 = new [Link](12, 0);
var material3 = new [Link]({ color: color });
var group3 = new THREE.Object3D();
[Link](group3);
for (var i = 0; i < 4; i++) {
var mesh3 = new [Link](geometry3, material3);
[Link](mesh3);
}
[Link][0].[Link](250, 0, 0);
[Link][1].[Link](-250, 0, 0);
[Link][2].[Link](0, 250, 0);
[Link][3].[Link](0, -250, 0);
//group 4 line background
var group4 = new THREE.Object3D();
[Link](group4);
var parameters = [[3.5, 0xaaaaaa, 0.25], [4.0, 0xaaaaaa, 0.5], [4.5,
0xaaaaaa, 0.75]];
var geometry4 = createGeometry();
for (var i = 0; i < [Link]; ++i) {
var p = parameters[i];
var material4 = new [Link]({ color: p[1], opacity:
p[2] });
8

var line = new [Link](geometry4, material4);


[Link].x = [Link].y = [Link].z = p[0];
[Link] = p[0];
[Link].y = [Link]() * [Link];
[Link]();
[Link](line);
}
// line sphere geometry from
[Link]
function createGeometry() {
var geometry = new [Link]();
var vertices = [];
var vertex = new THREE.Vector3();
for (var i = 0; i < 1500; i++) {
vertex.x = [Link]() * 2 - 1;
vertex.y = [Link]() * 2 - 1;
vertex.z = [Link]() * 2 - 1;
[Link]();
[Link](200);
[Link](vertex.x, vertex.y, vertex.z);
[Link]([Link]() * 0.09 + 1);
[Link](vertex.x, vertex.y, vertex.z);
}
[Link]('position', new
THREE.Float32BufferAttribute(vertices, 3));
return geometry;
}
[Link] = false;
[Link](scene, camera);
//------------------------------------------------------------------------
--------------------------------------------

function render() {
// get the frequency of the sound
[Link] = true;
[Link](data);
var avgdata = avg(data);
var lowerHalfArray = [Link](0, ([Link] / 2) - 1);
var upperHalfArray = [Link](([Link] / 2) - 1, [Link] -
1);
var lowerAvg = avg(lowerHalfArray);
var upperAvg = avg(upperHalfArray);
9

// color = new [Link](parseInt(lowerAvg) % 255,


parseInt(upperAvg) % 255, parseInt(avgdata) % 255);
// [Link](color);
for (var i = 0; i < [Link]; i++) {
[Link][i].scale.x = (data[i] * 0.1) + 0.001;
[Link][i].scale.y = (data[i] * 0.1) + 0.001;
// [Link][i].[Link]([Link]() *
0xffffff );
}
var speed2 = upperAvg * 0.002;
[Link](speed2);
var range2 = upperAvg * 6 + 500;
[Link][0].[Link](range2, 0, 0);
[Link][1].[Link](-range2, 0, 0);
[Link][2].[Link](0, range2, 0);
[Link][3].[Link](0, -range2, 0);
// for (var i = 0; i < 4; i++)
[Link][i].[Link]([Link]() * 0xffffff );
var speed3 = lowerAvg * -0.0002;
[Link](speed3);
var range3 = lowerAvg * 1.5 + 250;
[Link][0].[Link](range3, 0, 0);
[Link][1].[Link](-range3, 0, 0);
[Link][2].[Link](0, range3, 0);
[Link][3].[Link](0, -range3, 0);
// for (var i = 0; i < 4; i++)
[Link][i].[Link]([Link]() * 0xffffff );
[Link](avgdata * 0.0004);
if (lowerAvg / upperAvg < avgdata) {
[Link] = 15;
[Link] = 3;
}
// camera shake from [Link]
[Link]
if ([Link] > 0) {
var value1 = [Link]() * 2 * [Link] -
[Link];
var value2 = [Link]() * 2 * [Link] -
[Link];
var value3 = [Link]() * 2 * [Link] -
[Link];
[Link].x += value1;
[Link].y += value2;
10

[Link].z += value3;
[Link] -= [Link];
}
id = requestAnimationFrame(render);
[Link]();
[Link](scene, camera);
}
function max(params) {
return [Link](Math, params);
}
function avg(params) {
var sum = 0;
for (var i = 0; i < [Link]; i++) sum += params[i];
return sum / [Link];
}

</script>
</body>

</html>
11

Links & References

[Link]

[Link]

[Link]

[Link]

You might also like