From 9715bb0ef8b88285bc9d23bf20b06a500650b189 Mon Sep 17 00:00:00 2001 From: Eric Dauenhauer Date: Thu, 8 Dec 2022 21:39:27 -0600 Subject: [PATCH] Allow recording over a track --- roadmap.md | 2 +- src/Metronome/controls/TempoControl.tsx | 2 +- src/Track/index.tsx | 8 +++++--- src/workers/recorder.js | 8 ++++++++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/roadmap.md b/roadmap.md index f00ec1d..ebf4c00 100644 --- a/roadmap.md +++ b/roadmap.md @@ -52,7 +52,7 @@ A `Track` is a single mono or stereo audio buffer that contains audio data. A `T - [x] Component can remove itself from scene https://github.com/ericyd/loop-supreme/pull/5 - [x] Component has arm toggle button https://github.com/ericyd/loop-supreme/pull/8 - [x] ~audio data can be cleared from component without deleting it (to preserve track name)~ just mute, and then re-record if desired -- [ ] `regression` allow re-recording audio over a track [regression introduced here](https://github.com/ericyd/loop-supreme/pull/27) +- [x] `regression` allow re-recording audio over a track [regression introduced here](https://github.com/ericyd/loop-supreme/pull/27) https://github.com/ericyd/loop-supreme/pull/34 - [x] deleting a track stops playback https://github.com/ericyd/loop-supreme/pull/13 - [x] Component can record data from user device https://github.com/ericyd/loop-supreme/pull/8 - [x] Component shows waveform of recorded audio https://github.com/ericyd/loop-supreme/pull/20 diff --git a/src/Metronome/controls/TempoControl.tsx b/src/Metronome/controls/TempoControl.tsx index d316d78..bcac6ca 100644 --- a/src/Metronome/controls/TempoControl.tsx +++ b/src/Metronome/controls/TempoControl.tsx @@ -36,7 +36,7 @@ export function TempoControl({ onChange, defaultValue }: TempoProps) { } else { setTaps((taps) => [...taps, now]) } - if (taps.length > 2) { + if (taps.length >= 2) { const averageMs = averageBetween(taps.slice(-3)) const bpm = 60 / (averageMs / 1000) debouncedOnChange(bpm) diff --git a/src/Track/index.tsx b/src/Track/index.tsx index 50e2b5c..e38b36e 100644 --- a/src/Track/index.tsx +++ b/src/Track/index.tsx @@ -154,8 +154,8 @@ export const Track: React.FC = ({ /** * Both of these are instantiated on mount */ - const recorderWorklet = useRef() - const bufferSource = useRef() + const recorderWorklet = useRef(null) + const bufferSource = useRef(null) /** * Builds a callback that handles the messages from the recorder worker. @@ -271,7 +271,7 @@ export const Track: React.FC = ({ if (recorderWorklet.current) { recorderWorklet.current.disconnect() recorderWorklet.current.port.onmessage = null - recorderWorklet.current = undefined + recorderWorklet.current = null } bufferSource.current?.stop() mediaSource.disconnect() @@ -290,9 +290,11 @@ export const Track: React.FC = ({ if (armed) { setRecording(true) setArmed(false) + bufferSource.current = null recorderWorklet.current?.port?.postMessage({ message: 'UPDATE_RECORDING_STATE', recording: true, + reset: true, }) waveformWorker.postMessage({ message: 'RESET_FRAMES', diff --git a/src/workers/recorder.js b/src/workers/recorder.js index ac439c9..fa278d6 100644 --- a/src/workers/recorder.js +++ b/src/workers/recorder.js @@ -87,6 +87,14 @@ class RecordingProcessor extends AudioWorkletProcessor { this.port.onmessage = (event) => { if (event.data.message === 'UPDATE_RECORDING_STATE') { this.recording = event.data.recording + if (event.data.reset) { + this.channelsData = new Array(this.numberOfChannels).fill( + new Float32Array(this.maxRecordingSamples) + ) + this.recordedSamples = 0 + this.samplesSinceLastPublish = 0 + this.gainSum = 0 + } // When the recording ends, send the buffer back to the Track if (this.recording === false) {