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 p5 from 'p5';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const VOLUME_THRESHOLD = 0;
|
const FFT_SIZE = 256;
|
||||||
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})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRMS(spectrum) {
|
function getRMS(spectrum) {
|
||||||
let rms = 0;
|
let rms = 0;
|
||||||
|
@ -21,8 +13,14 @@ function getRMS(spectrum) {
|
||||||
return rms;
|
return rms;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWidth(volume) {
|
function getPitch(spectrum) {
|
||||||
return volume * VOLUME_NORMALIZATION;
|
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() {
|
function getRandomX() {
|
||||||
|
@ -38,28 +36,34 @@ async function main() {
|
||||||
const audioCtx = new AudioContext();
|
const audioCtx = new AudioContext();
|
||||||
const microphone = await navigator.mediaDevices.getUserMedia({ audio: true });
|
const microphone = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
const analyser = new AnalyserNode(audioCtx);
|
const analyser = new AnalyserNode(audioCtx);
|
||||||
|
|
||||||
let fresh = false;
|
|
||||||
let spectrum = [];
|
|
||||||
let volume = 0;
|
|
||||||
analyser.smoothingTimeConstant = 0.2;
|
analyser.smoothingTimeConstant = 0.2;
|
||||||
analyser.fftSize = FFT_SIZE;
|
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 = () => {
|
audioProcessor.onaudioprocess = () => {
|
||||||
fresh = true;
|
fresh = true;
|
||||||
// bitcount returns array which is half the FFT_SIZE
|
// bitcount returns array which is half the FFT_SIZE
|
||||||
spectrum = new Uint8Array(analyser.frequencyBinCount);
|
spectrum = new Uint8Array(analyser.frequencyBinCount);
|
||||||
|
|
||||||
// getByteFrequencyData returns amplitude for each bin
|
// getByteFrequencyData returns amplitude for each bin
|
||||||
// analyser.getByteFrequencyData(spectrum);
|
analyser.getByteFrequencyData(spectrum);
|
||||||
// getByteTimeDomainData gets volumes over the sample time
|
// getByteTimeDomainData gets volumes over the sample time
|
||||||
// analyser.getByteTimeDomainData(self.spectrum);
|
// analyser.getByteTimeDomainData(self.spectrum);
|
||||||
|
|
||||||
volume = getRMS(spectrum);
|
spectrum.reverse();
|
||||||
|
|
||||||
|
const currentVolume = getRMS(spectrum);
|
||||||
// get peak - a hack when our volumes are low
|
// get peak - a hack when our volumes are low
|
||||||
if (volume > VOLUME_THRESHOLD) VOLUME_THRESHOLD = volume;
|
if (currentVolume > volumeThreshold) volumeThreshold = currentVolume;
|
||||||
volume = self.vol;
|
volume = currentVolume;
|
||||||
|
pitch = getPitch(spectrum, volume, volumeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
const input = audioCtx.createMediaStreamSource(microphone);
|
const input = audioCtx.createMediaStreamSource(microphone);
|
||||||
|
@ -67,30 +71,37 @@ async function main() {
|
||||||
analyser.connect(audioProcessor);
|
analyser.connect(audioProcessor);
|
||||||
// audioProcessor.connect(audioCtx.destination);
|
// audioProcessor.connect(audioCtx.destination);
|
||||||
|
|
||||||
|
|
||||||
const instance = new p5(( sketch ) => {
|
const instance = new p5(( sketch ) => {
|
||||||
sketch.setup = () => {
|
sketch.setup = () => {
|
||||||
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
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 = () => {
|
sketch.draw = () => {
|
||||||
if (!fresh) {
|
if (!fresh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fresh = false;
|
fresh = false;
|
||||||
|
sketch.background(sketch.color(0, 0, 0));
|
||||||
|
|
||||||
sketch.background(0);
|
bars.push({
|
||||||
|
x: getRandomX(),
|
||||||
for (const pitch of spectrum) {
|
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: [
|
use: [
|
||||||
{ loader: "style-loader" },
|
{ loader: "style-loader" },
|
||||||
{ loader: "css-loader" },
|
{ loader: "css-loader" },
|
||||||
{
|
{ loader: "sass-loader" },
|
||||||
loader: "sass-loader",
|
|
||||||
options: {
|
|
||||||
includePaths: ["absolute/path/a", "absolute/path/b"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue