From 145c6041160749e7e79daf8f4da2ffa5f051f97b Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Sun, 21 Jul 2024 10:27:00 +0200 Subject: [PATCH] Docs: phase vocoder example (#3791) * Docs: phase vocoder example * Simplify code --- examples/phase-vocoder/index.js | 64 +++++++++++++++++++++ examples/phase-vocoder/phase-vocoder.min.js | 1 + 2 files changed, 65 insertions(+) create mode 100644 examples/phase-vocoder/index.js create mode 100644 examples/phase-vocoder/phase-vocoder.min.js diff --git a/examples/phase-vocoder/index.js b/examples/phase-vocoder/index.js new file mode 100644 index 000000000..8f0737aa7 --- /dev/null +++ b/examples/phase-vocoder/index.js @@ -0,0 +1,64 @@ +// WebAudio speed control with pitch preservation + +import WaveSurfer from 'wavesurfer.js' + +// Init wavesurfer +const wavesurfer = WaveSurfer.create({ + backend: 'WebAudio', + container: document.body, + waveColor: 'violet', + progressColor: 'purple', + url: '/examples/audio/librivox.mp3', +}) + +// Wait for the audio to be ready +wavesurfer.on('ready', async () => { + const webAudioPlayer = wavesurfer.getMediaElement() + const gainNode = webAudioPlayer.getGainNode() + const audioContext = gainNode.context + + // Load the phase vocoder audio worklet + await audioContext.audioWorklet.addModule('/examples/phase-vocoder/phase-vocoder.min.js') + const phaseVocoderNode = new AudioWorkletNode(audioContext, 'phase-vocoder-processor') + + // Connect the worklet to the wavesurfer audio + gainNode.disconnect() + gainNode.connect(phaseVocoderNode) + phaseVocoderNode.connect(audioContext.destination) + + // Speed slider + document.querySelector('input[type="range"]').addEventListener('input', (e) => { + const speed = e.target.valueAsNumber + document.querySelector('#rate').textContent = speed.toFixed(2) + wavesurfer.setPlaybackRate(speed) + const pitchFactorParam = phaseVocoderNode.parameters.get('pitchFactor') + pitchFactorParam.value = 1 / speed + }) + + // Play/pause button + document.querySelector('button').addEventListener('click', () => { + wavesurfer.playPause() + }) +}) + +/* + +
+ 📖 Based on github.com/olvb/phaze +
+ +*/ diff --git a/examples/phase-vocoder/phase-vocoder.min.js b/examples/phase-vocoder/phase-vocoder.min.js new file mode 100644 index 000000000..ee9da8459 --- /dev/null +++ b/examples/phase-vocoder/phase-vocoder.min.js @@ -0,0 +1 @@ +!function t(e,s,r){function i(o,f){if(!s[o]){if(!e[o]){var h="function"==typeof require&&require;if(!f&&h)return h(o,!0);if(n)return n(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var a=s[o]={exports:{}};e[o][0].call(a.exports,(function(t){return i(e[o][1][t]||t)}),a,a.exports,t,e,s,r)}return s[o].exports}for(var n="function"==typeof require&&require,o=0;o