Combining
This commit is contained in:
parent
add2c28363
commit
70a21d274f
|
@ -1,30 +1,93 @@
|
||||||
const VOLUME_THRESHOLD = 20;
|
import Worker from './sound.worker.js';
|
||||||
const CIRCLE_RADIUS = 100;
|
import { getSpectrumData } from './util.js';
|
||||||
const CIRCLE_POINTS = 256;
|
|
||||||
const FFT_SIZE = CIRCLE_POINTS;
|
|
||||||
const MAX_CIRCLES = 20;
|
|
||||||
|
|
||||||
export function setup(sketch, analyser) {
|
export default class CirclesAnimation {
|
||||||
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
VOLUME_THRESHOLD = 20;
|
||||||
sketch.colorMode(sketch.HSL, 255);
|
CIRCLE_RADIUS = 100;
|
||||||
|
CIRCLE_POINTS = 256;
|
||||||
|
FFT_SIZE = 256;
|
||||||
|
MAX_CIRCLES = 20;
|
||||||
|
|
||||||
|
baseHeight;
|
||||||
|
baseWidth;
|
||||||
|
maxVolume = 0;
|
||||||
|
maxPitch = 0;
|
||||||
|
minPitch = 0;
|
||||||
|
circles = [];
|
||||||
|
|
||||||
|
averageSpectrum;
|
||||||
|
|
||||||
|
constructor(audioCtx) {
|
||||||
|
this.worker = new Worker();
|
||||||
|
this.analyser = new AnalyserNode(audioCtx);
|
||||||
|
this.analyser.fftSize = this.FFT_SIZE;
|
||||||
|
this.audioProcessor = audioCtx.createScriptProcessor(this.FFT_SIZE * 2, 1, 1);
|
||||||
|
this.audioProcessor.onaudioprocess = () => this.audioProcess();
|
||||||
|
this.analyser.connect(this.audioProcessor);
|
||||||
|
this.worker.onmessage = e => this.getAverageData(e.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function draw(sketch) {
|
setup(sketch) {
|
||||||
|
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
||||||
|
sketch.colorMode(sketch.HSL, 255);
|
||||||
|
this.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
resize() {
|
||||||
|
this.baseWidth = window.innerWidth / 2;
|
||||||
|
this.baseHeight = window.innerHeight / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAverageData(data) {
|
||||||
|
this.averageSpectrum = data.averageSpectrum;
|
||||||
|
}
|
||||||
|
|
||||||
|
audioProcess() {
|
||||||
|
const spectrum = new Uint8Array(this.analyser.frequencyBinCount);
|
||||||
|
this.analyser.getByteFrequencyData(spectrum);
|
||||||
|
|
||||||
|
spectrum.reverse();
|
||||||
|
|
||||||
|
const data = getSpectrumData(spectrum);
|
||||||
|
this.worker.postMessage(data);
|
||||||
|
const { volume, pitch } = data;
|
||||||
|
|
||||||
|
if (volume > this.maxVolume) {
|
||||||
|
this.maxVolume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pitch > this.maxPitch) {
|
||||||
|
this.maxPitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pitch < this.minPitch) {
|
||||||
|
this.minPitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.circles.unshift(data);
|
||||||
|
|
||||||
|
if (this.circles.length > this.MAX_CIRCLES) {
|
||||||
|
this.circles.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(sketch) {
|
||||||
sketch.background(30);
|
sketch.background(30);
|
||||||
sketch.noFill();
|
sketch.noFill();
|
||||||
sketch.strokeWeight(2);
|
sketch.strokeWeight(2);
|
||||||
sketch.stroke(230);
|
sketch.stroke(230);
|
||||||
|
|
||||||
for (let c = 0; c < circles.length; c++) {
|
for (let c = 0; c < this.circles.length; c++) {
|
||||||
const circle = circles[c];
|
const circle = this.circles[c];
|
||||||
sketch.beginShape();
|
sketch.beginShape();
|
||||||
for (let i = 0; i < circle.spectrum.length; i++) {
|
for (let i = 0; i < circle.spectrum.length; i++) {
|
||||||
const p = circle.spectrum[i];
|
const p = circle.spectrum[i];
|
||||||
sketch.curveVertex(
|
sketch.curveVertex(
|
||||||
Math.cos((i / CIRCLE_POINTS) * 2 * Math.PI) * (CIRCLE_RADIUS + c * 15) + baseWidth + (maxVolume / 2 - circle.volume) + p,
|
Math.cos((i / this.CIRCLE_POINTS) * 2 * Math.PI) * (this.CIRCLE_RADIUS + c * 15) + this.baseWidth + (this.maxVolume / 2 - circle.volume) + p,
|
||||||
Math.sin((i / CIRCLE_POINTS) * 2 * Math.PI) * (CIRCLE_RADIUS + c * 15) + baseHeight + (maxPitch / 2 - circle.pitch) - p,
|
Math.sin((i / this.CIRCLE_POINTS) * 2 * Math.PI) * (this.CIRCLE_RADIUS + c * 15) + this.baseHeight + (this.maxPitch / 2 - circle.pitch) - p,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
sketch.endShape(sketch.CLOSE);
|
sketch.endShape(sketch.CLOSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -42,8 +42,6 @@ export default class HorizontalLinesAnimation {
|
||||||
|
|
||||||
getAverageData(data) {
|
getAverageData(data) {
|
||||||
this.averageSpectrum = data.averageSpectrum;
|
this.averageSpectrum = data.averageSpectrum;
|
||||||
console.log('got average');
|
|
||||||
console.log(this.averageSpectrum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
audioProcess() {
|
audioProcess() {
|
||||||
|
|
26
src/index.js
26
src/index.js
|
@ -3,12 +3,25 @@ import './index.scss';
|
||||||
|
|
||||||
import HorizontalLinesAnimation from './horizontal-lines.js';
|
import HorizontalLinesAnimation from './horizontal-lines.js';
|
||||||
import SquaresAnimation from './squares.js';
|
import SquaresAnimation from './squares.js';
|
||||||
|
import CirclesAnimation from './circles.js';
|
||||||
|
|
||||||
async function main() {
|
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 input = audioCtx.createMediaStreamSource(microphone);
|
const input = audioCtx.createMediaStreamSource(microphone);
|
||||||
|
|
||||||
|
const horizontalLines = new HorizontalLinesAnimation(audioCtx);
|
||||||
|
const squares = new SquaresAnimation(audioCtx);
|
||||||
|
const circles = new CirclesAnimation(audioCtx);
|
||||||
|
|
||||||
|
const animations = [
|
||||||
|
horizontalLines,
|
||||||
|
squares,
|
||||||
|
circles,
|
||||||
|
];
|
||||||
|
|
||||||
|
let animationNum = 0;
|
||||||
|
|
||||||
const instance = new p5(( sketch ) => {
|
const instance = new p5(( sketch ) => {
|
||||||
let activeAnimation;
|
let activeAnimation;
|
||||||
|
|
||||||
|
@ -19,16 +32,23 @@ async function main() {
|
||||||
|
|
||||||
function activate(animation) {
|
function activate(animation) {
|
||||||
activeAnimation = animation;
|
activeAnimation = animation;
|
||||||
|
input.disconnect();
|
||||||
input.connect(animation.analyser);
|
input.connect(animation.analyser);
|
||||||
animation.setup(sketch);
|
animation.setup(sketch);
|
||||||
}
|
}
|
||||||
|
|
||||||
sketch.setup = () => {
|
sketch.setup = () => {
|
||||||
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
sketch.createCanvas(window.innerWidth, window.innerHeight);
|
||||||
|
activate(animations[animationNum]);
|
||||||
|
|
||||||
const horizontalLines = new HorizontalLinesAnimation(audioCtx);
|
setInterval(() => {
|
||||||
const squares = new SquaresAnimation(audioCtx);
|
animationNum++;
|
||||||
activate(horizontalLines);
|
if (animationNum > animations.length - 1) {
|
||||||
|
animationNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
activate(animations[animationNum]);
|
||||||
|
}, 10000);
|
||||||
};
|
};
|
||||||
|
|
||||||
sketch.draw = () => {
|
sketch.draw = () => {
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
const PERIOD = 20 * 1000;
|
const PERIOD = 1000;
|
||||||
|
const CAPTURE_PERIOD = 60 * 1000;
|
||||||
const data = [];
|
const data = [];
|
||||||
let firstRun = true;
|
|
||||||
|
let capture = true;
|
||||||
|
|
||||||
|
setTimeout(() => capture = false, CAPTURE_PERIOD);
|
||||||
|
|
||||||
function onDataPoint(event) {
|
function onDataPoint(event) {
|
||||||
if (!firstRun) {
|
if (!capture) {
|
||||||
data.shift();
|
data.shift();
|
||||||
}
|
}
|
||||||
data.push(event.data);
|
data.push(event.data);
|
||||||
|
@ -12,8 +16,6 @@ function onDataPoint(event) {
|
||||||
self.onmessage = onDataPoint;
|
self.onmessage = onDataPoint;
|
||||||
|
|
||||||
function calculateAndSend() {
|
function calculateAndSend() {
|
||||||
firstRun = false;
|
|
||||||
|
|
||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue