From 041a98349b463b42ff6aab548ba85a8ce6a3d920 Mon Sep 17 00:00:00 2001 From: Jorge Marcos Date: Wed, 9 Feb 2022 13:16:03 +0100 Subject: [PATCH] use num keys 0-9 to play first 10 slices --- .../demos/onsets/src/core/audio-worker.js | 24 ++++++---- examples/demos/onsets/src/core/processing.js | 48 +++++++++++++------ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/examples/demos/onsets/src/core/audio-worker.js b/examples/demos/onsets/src/core/audio-worker.js index 8147b93..4408dd0 100644 --- a/examples/demos/onsets/src/core/audio-worker.js +++ b/examples/demos/onsets/src/core/audio-worker.js @@ -18,7 +18,6 @@ self.essentia = null; self.allowedParams = ['sampleRate', 'frameSize', 'hopSize', 'odfs', 'odfsWeights', 'sensitivity']; self.params = {}; // changing odfs should require changing odfsWeights (at least length), and viceversa -self.fftRecomputeNeeded = true; // global storage for slicing self.signal = null; @@ -37,10 +36,15 @@ onmessage = function listenToMainThread(msg) { log('received analyse cmd') // const signal = new Float32Array(msg.data.audio); self.signal = msg.data.audio; + log(self.signal); computeFFT(); self.onsetPositions = computeOnsets(); + const slices = sliceAudio(); - postMessage(self.onsetPositions); + postMessage({ + onsets: self.onsetPositions, + slices: slices + }); break; } case 'initParams': { @@ -67,18 +71,19 @@ onmessage = function listenToMainThread(msg) { if (self.polarFrames === null || self.polarFrames.length === 0) { // file hasn't been uploaded and analysed for 1st time, or it has been cleared - self.fftRecomputeNeeded = true; + computeFFT(); } if (suppliedParamList.includes('frameSize') || suppliedParamList.includes('hopSize')) { // re-compute FFT analysis if updated params affect it (frame or hop size changed) - self.fftRecomputeNeeded = true; + computeFFT(); } - if (self.fftRecomputeNeeded) { - computeFFT() - } self.onsetPositions = computeOnsets(); - postMessage(self.onsetPositions); + const slices = sliceAudio(); + postMessage({ + onsets: self.onsetPositions, + slices: slices + }); break; } case 'slice': { @@ -130,7 +135,6 @@ function computeFFT () { frames.delete(); PolarFFT.shutdown(); - self.fftRecomputeNeeded = false; } function computeOnsets () { @@ -160,7 +164,7 @@ function computeOnsets () { function sliceAudio () { // onsets: seconds to samples const onsetSamplePositions = Array.from(self.onsetPositions.map( (pos) => Math.round(pos * self.params.sampleRate) )); - // if onsetSamplePositions[index+1] == undefined, we've reached the last onset and slice will extract from samp till the end of the array + log(onsetSamplePositions); return onsetSamplePositions.map( (samp, index) => self.signal.slice(samp, onsetSamplePositions[index+1]) ); } diff --git a/examples/demos/onsets/src/core/processing.js b/examples/demos/onsets/src/core/processing.js index ff650c0..bc5541c 100644 --- a/examples/demos/onsets/src/core/processing.js +++ b/examples/demos/onsets/src/core/processing.js @@ -2,7 +2,6 @@ import EventBus from "./event-bus"; import JSZip from "jszip"; import audioEncoder from "audio-encoder"; import freesound from 'freesound'; -import apiKey from '../.env/key'; /* "Signal Processing Unit" for audio-only purposes (no views) @@ -19,21 +18,16 @@ export default class DSP { params: {sampleRate: this.audioCtx.sampleRate} }); this.audioWorker.onmessage = (msg) => { - if (msg.data instanceof Float32Array) { - if (msg.data.length == 0) { - EventBus.$emit("analysis-finished-empty"); - } else { - EventBus.$emit("analysis-finished-onsets", Array.from(msg.data)); - } - } else if (msg.data instanceof Array && msg.data[0] instanceof Float32Array) { - console.info('worker returned sliced audio', msg.data); - this.downloadSlicesAsZip(msg.data); + if (msg.data.onsets.length == 0) { + EventBus.$emit("analysis-finished-empty"); } else { - throw TypeError("Worker failed. Analysis results should be of type Float32Array"); + EventBus.$emit("analysis-finished-onsets", Array.from(msg.data.onsets)); + this.slices = msg.data.slices; } }; this.soundData = {}; + this.slices = []; this.fileSampleRate = this.audioCtx.sampleRate; // set up global event handlers @@ -52,10 +46,10 @@ export default class DSP { }) }); EventBus.$on("download-slices", () => { - this.audioWorker.postMessage({ - request: 'slice' - }) + this.downloadSlicesAsZip(this.slices); }); + + window.addEventListener("keydown", this.handleKeyDown.bind(this)); } async getAudioFile (url) { @@ -163,7 +157,31 @@ export default class DSP { offlineSource.start(); let resampled = await offlineCtx.startRendering(); return resampled; - } + } + + handleKeyDown (event) { + if (this.slices.length == 0) return; + + let pressedKeyAsNum = Number(event.key); + if ( Number.isNaN(pressedKeyAsNum) || event.key == ' ' ) return; + pressedKeyAsNum = pressedKeyAsNum == 0 ? 9 : pressedKeyAsNum - 1; + if ( !this.slices[pressedKeyAsNum] ) return; + + const slice = this.slices[pressedKeyAsNum]; + this.playSlice(slice); + } + + playSlice (slice) { + if (this.audioCtx.state == 'suspended') this.audioCtx.resume(); + + const buffer = this.audioCtx.createBuffer(1, slice.length, this.audioCtx.sampleRate); + buffer.copyToChannel(slice, 0, 0); + const source = this.audioCtx.createBufferSource(); + source.buffer = buffer; + + source.connect(this.audioCtx.destination); + source.start(this.audioCtx.currentTime); + } } async function freesoundGetById (id) {