Combining

This commit is contained in:
Benjamin Bädorf 2019-06-14 16:46:42 +02:00
parent add2c28363
commit 70a21d274f
4 changed files with 117 additions and 34 deletions

View file

@ -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;
export function draw(sketch) { baseHeight;
sketch.background(30); baseWidth;
sketch.noFill(); maxVolume = 0;
sketch.strokeWeight(2); maxPitch = 0;
sketch.stroke(230); minPitch = 0;
circles = [];
for (let c = 0; c < circles.length; c++) { averageSpectrum;
const circle = circles[c];
sketch.beginShape(); constructor(audioCtx) {
for (let i = 0; i < circle.spectrum.length; i++) { this.worker = new Worker();
const p = circle.spectrum[i]; this.analyser = new AnalyserNode(audioCtx);
sketch.curveVertex( this.analyser.fftSize = this.FFT_SIZE;
Math.cos((i / CIRCLE_POINTS) * 2 * Math.PI) * (CIRCLE_RADIUS + c * 15) + baseWidth + (maxVolume / 2 - circle.volume) + p, this.audioProcessor = audioCtx.createScriptProcessor(this.FFT_SIZE * 2, 1, 1);
Math.sin((i / CIRCLE_POINTS) * 2 * Math.PI) * (CIRCLE_RADIUS + c * 15) + baseHeight + (maxPitch / 2 - circle.pitch) - p, this.audioProcessor.onaudioprocess = () => this.audioProcess();
); this.analyser.connect(this.audioProcessor);
this.worker.onmessage = e => this.getAverageData(e.data);
}
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.noFill();
sketch.strokeWeight(2);
sketch.stroke(230);
for (let c = 0; c < this.circles.length; c++) {
const circle = this.circles[c];
sketch.beginShape();
for (let i = 0; i < circle.spectrum.length; i++) {
const p = circle.spectrum[i];
sketch.curveVertex(
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 / 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);
} }
} }

View file

@ -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() {

View file

@ -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 = () => {

View file

@ -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;
} }