Pitched random location bars
This commit is contained in:
parent
ede4449de8
commit
76c97155ce
73
src/index.js
73
src/index.js
|
@ -1,15 +1,7 @@
|
|||
import p5 from 'p5';
|
||||
import './index.scss';
|
||||
|
||||
const VOLUME_THRESHOLD = 0;
|
||||
const FFT_SIZE = 1024;
|
||||
|
||||
function getColorValue(volume) {
|
||||
const normalizedVolume = volume * VOLUME_NORMALIZATION;
|
||||
const color = Math.floor(normalizedVolume);
|
||||
const opacity = (normalizedVolume > VOLUME_MAX ? normalizedVolume : VOLUME_MAX) / 100;
|
||||
return `rgba(${color}, ${color}, ${color}, ${opacity})`;
|
||||
}
|
||||
const FFT_SIZE = 256;
|
||||
|
||||
function getRMS(spectrum) {
|
||||
let rms = 0;
|
||||
|
@ -21,8 +13,14 @@ function getRMS(spectrum) {
|
|||
return rms;
|
||||
}
|
||||
|
||||
function getWidth(volume) {
|
||||
return volume * VOLUME_NORMALIZATION;
|
||||
function getPitch(spectrum) {
|
||||
let cg = 0;
|
||||
let weight = 0;
|
||||
for (let i = 0; i < spectrum.length; i++) {
|
||||
cg += spectrum[i] * i;
|
||||
weight += spectrum[i];
|
||||
}
|
||||
return Math.floor(cg / weight);
|
||||
}
|
||||
|
||||
function getRandomX() {
|
||||
|
@ -38,28 +36,34 @@ async function main() {
|
|||
const audioCtx = new AudioContext();
|
||||
const microphone = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
const analyser = new AnalyserNode(audioCtx);
|
||||
|
||||
let fresh = false;
|
||||
let spectrum = [];
|
||||
let volume = 0;
|
||||
analyser.smoothingTimeConstant = 0.2;
|
||||
analyser.fftSize = FFT_SIZE;
|
||||
|
||||
const audioProcessor = audioCtx.createScriptProcessor(FFT_SIZE*2, 1, 1);
|
||||
let fresh = false;
|
||||
let spectrum = [];
|
||||
let pitch = 0;
|
||||
let volume = 0;
|
||||
let volumeThreshold = 0;
|
||||
let bars = [];
|
||||
|
||||
const audioProcessor = audioCtx.createScriptProcessor(FFT_SIZE * 2, 1, 1);
|
||||
audioProcessor.onaudioprocess = () => {
|
||||
fresh = true;
|
||||
// bitcount returns array which is half the FFT_SIZE
|
||||
spectrum = new Uint8Array(analyser.frequencyBinCount);
|
||||
|
||||
// getByteFrequencyData returns amplitude for each bin
|
||||
// analyser.getByteFrequencyData(spectrum);
|
||||
analyser.getByteFrequencyData(spectrum);
|
||||
// getByteTimeDomainData gets volumes over the sample time
|
||||
// analyser.getByteTimeDomainData(self.spectrum);
|
||||
|
||||
spectrum.reverse();
|
||||
|
||||
volume = getRMS(spectrum);
|
||||
const currentVolume = getRMS(spectrum);
|
||||
// get peak - a hack when our volumes are low
|
||||
if (volume > VOLUME_THRESHOLD) VOLUME_THRESHOLD = volume;
|
||||
volume = self.vol;
|
||||
if (currentVolume > volumeThreshold) volumeThreshold = currentVolume;
|
||||
volume = currentVolume;
|
||||
pitch = getPitch(spectrum, volume, volumeThreshold);
|
||||
}
|
||||
|
||||
const input = audioCtx.createMediaStreamSource(microphone);
|
||||
|
@ -67,30 +71,37 @@ async function main() {
|
|||
analyser.connect(audioProcessor);
|
||||
// audioProcessor.connect(audioCtx.destination);
|
||||
|
||||
|
||||
const instance = new p5(( sketch ) => {
|
||||
sketch.setup = () => {
|
||||
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
||||
sketch.colorMode(sketch.HSL, 255);
|
||||
};
|
||||
|
||||
function drawBar(bar) {
|
||||
sketch.fill(getColorValue(bar.volume));
|
||||
sketch.rect(bar.x, 0, getWidth(bar.volume), window.innerHeight);
|
||||
}
|
||||
|
||||
let bars = [];
|
||||
|
||||
sketch.draw = () => {
|
||||
if (!fresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
fresh = false;
|
||||
sketch.background(sketch.color(0, 0, 0));
|
||||
|
||||
sketch.background(0);
|
||||
|
||||
for (const pitch of spectrum) {
|
||||
bars.push({
|
||||
x: getRandomX(),
|
||||
volume,
|
||||
pitch,
|
||||
age: 1,
|
||||
});
|
||||
const newBars = [];
|
||||
for (const bar of bars) {
|
||||
sketch.fill(sketch.color(0, (bar.volume / volumeThreshold) * 255, 255));
|
||||
sketch.rect(bar.x, 0, bar.age * bar.volume * 2, window.innerHeight);
|
||||
bar.age /= 2;
|
||||
if (bar.age > 0.1) {
|
||||
newBars.push(bar);
|
||||
}
|
||||
}
|
||||
|
||||
bars = newBars;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,12 +14,7 @@ module.exports = {
|
|||
use: [
|
||||
{ loader: "style-loader" },
|
||||
{ loader: "css-loader" },
|
||||
{
|
||||
loader: "sass-loader",
|
||||
options: {
|
||||
includePaths: ["absolute/path/a", "absolute/path/b"],
|
||||
},
|
||||
},
|
||||
{ loader: "sass-loader" },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue