### Quick Start with AudioWorklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/navigation.mdx Demonstrates the basic setup for using SoundTouchNode with the AudioWorklet API. Ensure processorModuleUrl is correctly resolved for your build setup. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; const audioCtx = new AudioContext(); // See Getting Started for processorModuleUrl details await SoundTouchNode.register(audioCtx, processorModuleUrl); const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(audioCtx.destination); ``` -------------------------------- ### Install @soundtouchjs/core Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md Install the core audio processing library using npm. ```sh npm install @soundtouchjs/core ``` -------------------------------- ### Install @soundtouchjs/stretch-phase-vocoder Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/stretch-phase-vocoder/README.md Install the package using npm. ```sh npm install @soundtouchjs/stretch-phase-vocoder ``` -------------------------------- ### Install @soundtouchjs/audio-worklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md Install the package using npm. ```sh npm install @soundtouchjs/audio-worklet ``` -------------------------------- ### Install @soundtouchjs/worklet-base Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Install the package using npm. ```sh npm install @soundtouchjs/worklet-base ``` -------------------------------- ### Run Nx Command with Package Manager Prefix Source: https://github.com/cutterbl/soundtouchjs/blob/master/AGENTS.md Example of running an Nx command, such as 'build', prefixed with the workspace's package manager ('pnpm'). This ensures that the locally installed Nx CLI is used. ```sh pnpm nx build ``` -------------------------------- ### Basic SoundTouchNode Usage Example Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Demonstrates registering the processor, creating a SoundTouchNode, connecting it in an audio graph, and adjusting playback rate and pitch. Ensure the processor script is correctly located. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; const audioCtx = new AudioContext(); await SoundTouchNode.register(audioCtx, '/soundtouch-processor.js'); const gainNode = audioCtx.createGain(); const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(gainNode); gainNode.connect(audioCtx.destination); const source = audioCtx.createBufferSource(); source.buffer = audioBuffer; source.connect(stNode); const tempo = 1.2; source.playbackRate.value = tempo; // speed up source stNode.playbackRate.value = tempo; // compensate pitch stNode.pitch.value = 1.0; // no additional pitch change stNode.pitchSemitones.value = -2; // shift down 2 semitones await audioCtx.resume(); source.start(); ``` -------------------------------- ### Start Demo Development Server Source: https://github.com/cutterbl/soundtouchjs/blob/master/AGENTS.md Starts the development server for the demo application using Vite. This command enables hot module replacement (HMR) and typically runs on port 8080. ```sh pnpm dev ``` -------------------------------- ### Full Example: AudioBuffer with SoundTouchNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md This example demonstrates how to use SoundTouchNode with a decoded AudioBuffer. Ensure the SoundTouch processor is registered and connect the source, SoundTouchNode, and gain node. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; const audioCtx = new AudioContext(); const gainNode = audioCtx.createGain(); gainNode.connect(audioCtx.destination); await SoundTouchNode.register(audioCtx, '/soundtouch-processor.js'); const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(gainNode); const response = await fetch('/audio.mp3'); const buffer = await response.arrayBuffer(); const audioBuffer = await audioCtx.decodeAudioData(buffer); const source = audioCtx.createBufferSource(); source.buffer = audioBuffer; source.playbackRate.value = 1.2; // 1.2x tempo source.connect(stNode); stNode.playbackRate.value = 1.2; // tell processor the source rate stNode.pitch.value = 0.9; // desired pitch (auto-compensated) stNode.pitchSemitones.value = -2; gainNode.gain.value = 0.8; source.start(); ``` -------------------------------- ### Start Demo App Development Server with HMR Source: https://github.com/cutterbl/soundtouchjs/blob/master/AGENTS.md Starts the Vite development server for the demo application, enabling hot module replacement for a faster development feedback loop. ```sh pnpm nx dev demo ``` -------------------------------- ### Register and Use Blackman Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/blackman-strategy.mdx This example shows how to register the Blackman strategy and then instantiate SoundTouch with it. Tune `zeroCrossings` if transition width causes softening during large edits. ```typescript import { SoundTouch, registerInterpolationStrategy } from '@soundtouchjs/core'; import { registerBlackmanStrategy } from '@soundtouchjs/interpolation-strategy-blackman'; registerBlackmanStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: { id: 'blackman', params: { zeroCrossings: 6 } }, }); ``` -------------------------------- ### Install Workspace Dependencies Source: https://github.com/cutterbl/soundtouchjs/blob/master/AGENTS.md Installs all dependencies required for the monorepo. This should be run after cloning the repository. ```sh pnpm install ``` -------------------------------- ### Full Example: HTML Audio Element with SoundTouchNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md This example shows how to integrate SoundTouchNode with an HTML audio element. It connects the media element source to the SoundTouchNode and configures playback and pitch settings. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; const audioEl = document.querySelector('audio')!; const audioCtx = new AudioContext(); const gainNode = audioCtx.createGain(); gainNode.connect(audioCtx.destination); await SoundTouchNode.register(audioCtx, '/soundtouch-processor.js'); const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(gainNode); const source = audioCtx.createMediaElementSource(audioEl); source.connect(stNode); audioEl.preservesPitch = false; audioEl.playbackRate = 1.2; // 1.2x tempo stNode.playbackRate.value = 1.2; // tell processor the source rate stNode.pitch.value = 0.9; // desired pitch (auto-compensated) stNode.pitchSemitones.value = -2; gainNode.gain.value = 0.8; ``` -------------------------------- ### Install Phase Vocoder Worklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/phase-vocoder-worklet/README.md Install the phase vocoder worklet and its core dependency using npm. ```sh npm install @soundtouchjs/phase-vocoder-worklet @soundtouchjs/stretch-phase-vocoder ``` -------------------------------- ### Extend SoundTouchProcessorBase Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Extend the base class and implement the required `onProcessComplete` hook to create a custom AudioWorklet processor. This example shows basic setup and message posting for metrics. ```typescript import { SoundTouchProcessorBase, STANDARD_PARAMETER_DESCRIPTORS } from '@soundtouchjs/worklet-base'; import type { ProcessCoreResult } from '@soundtouchjs/worklet-base'; class MyProcessor extends SoundTouchProcessorBase { static get parameterDescriptors() { return STANDARD_PARAMETER_DESCRIPTORS; } constructor() { super('[MyProcessor]', {}); } onProcessComplete(result: ProcessCoreResult): void { // called after each block; post metrics, trigger side-effects, etc. this.port.postMessage({ type: 'metrics', ...result }); } } registerProcessor('my-processor', MyProcessor); ``` -------------------------------- ### Blackman Strategy Parameters Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/blackman-strategy.mdx Examples demonstrating how to configure the Blackman strategy parameters. Adjust `zeroCrossings` for kernel width and `normalize` for output scaling. Custom window coefficients can also be specified. ```typescript // Default params: { zeroCrossings: 4 } ``` ```typescript // Wider kernel params: { zeroCrossings: 6 } ``` ```typescript // Enable normalization params: { zeroCrossings: 4, normalize: true } ``` ```typescript // Custom window coefficients params: { zeroCrossings: 4, alpha: 0.5, beta: 0.6, gamma: 0.7 } ``` -------------------------------- ### Initialize and Use FormantCorrectionNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/formant-correction-worklet/README.md This example demonstrates how to register the worklet processor, create an instance of FormantCorrectionNode, set its parameters, and connect it within an AudioContext. ```typescript import { FormantCorrectionNode } from '@soundtouchjs/formant-correction-worklet'; const audioCtx = new AudioContext(); await FormantCorrectionNode.register(audioCtx, processorUrl); const node = new FormantCorrectionNode({ context: audioCtx }); node.pitchSemitones.value = 7; // shift up a perfect fifth node.formantStrength.value = 1; // keep original timbre (default) node.connect(audioCtx.destination); sourceNode.connect(node); ``` -------------------------------- ### Registering the Processor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/phase-vocoder-worklet.mdx Before using the PhaseVocoderNode, you need to register its processor with the AudioContext. This example shows how to do it, including a note for Vite users. ```APIDOC ## Registering the Processor ```ts import { PhaseVocoderNode } from '@soundtouchjs/phase-vocoder-worklet'; const audioCtx = new AudioContext(); // Vite: import processorUrl from '@soundtouchjs/phase-vocoder-worklet/processor?url'; await PhaseVocoderNode.register(audioCtx, processorUrl); ``` See [Getting Started](./getting-started) for Vite, webpack, and static setups. ``` -------------------------------- ### Initialize SoundTouch with Lanczos Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/lanczos-strategy.mdx Instantiate SoundTouchJS and specify the Lanczos interpolation strategy with default or custom parameters. The `zeroCrossings` parameter defaults to 4, which is often a good starting point. ```typescript import { SoundTouch } from '@soundtouchjs/core'; const soundTouch = new SoundTouch({ interpolationStrategy: { id: 'lanczos', params: { zeroCrossings: 4 }, // 4 is a good default }, }); ``` -------------------------------- ### Example Usage of processOffline Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/process-offline.mdx Demonstrates how to use processOffline to process an AudioBuffer with specified pitch and playback rate adjustments. The processed audio can then be played back or exported. ```typescript import { processOffline } from '@soundtouchjs/audio-worklet'; // Fetch and decode a source file const response = await fetch('/audio.mp3'); const arrayBuffer = await response.arrayBuffer(); const audioCtx = new AudioContext(); const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer); // Process offline — no audio device needed const processed = await processOffline({ input: audioBuffer, processorUrl: '/soundtouch-processor.js', pitchSemitones: -3, playbackRate: 1.2, }); // Play the result or export it const source = audioCtx.createBufferSource(); source.buffer = processed; source.connect(audioCtx.destination); source.start(); ``` -------------------------------- ### Register and Use Kaiser Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/kaiser-strategy.mdx Register the Kaiser strategy with SoundTouch.js and instantiate SoundTouch with it. Start with default or recommended parameter values and tune based on artifact tolerance and CPU budget. ```typescript import { SoundTouch, registerInterpolationStrategy } from '@soundtouchjs/core'; import { registerKaiserStrategy } from '@soundtouchjs/interpolation-strategy-kaiser'; registerKaiserStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: { id: 'kaiser', params: { zeroCrossings: 8, beta: 10 }, }, }); ``` -------------------------------- ### AudioWorklet Quick Start with SoundTouchNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/README.md Integrates SoundTouchNode for audio processing using AudioWorklet. Ensure the '/soundtouch-processor.js' path is correct. Control playback speed and pitch using the exposed AudioParams. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; const audioCtx = new AudioContext(); await SoundTouchNode.register(audioCtx, '/soundtouch-processor.js'); const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(audioCtx.destination); const source = audioCtx.createBufferSource(); source.buffer = audioBuffer; source.connect(stNode); // To change playback speed, set both source and stNode to the same value source.playbackRate.value = 1.2; stNode.playbackRate.value = 1.2; stNode.pitch.value = 0.9; source.start(); ``` -------------------------------- ### SoundTouch Initialization and Basic Usage Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md Demonstrates how to initialize the SoundTouch engine, set pitch, and use both default circular and FIFO sample buffers for processing audio. ```APIDOC ## SoundTouch Initialization and Basic Usage ### Description Instantiate the `SoundTouch` engine, configure pitch, and process audio using either the default `CircularSampleBuffer` or a `FifoSampleBuffer`. ### Method `new SoundTouch(options?: SoundTouchOptions)` ### Parameters #### Options - `sampleRate` (number) - Optional: The sample rate of the audio. - `sampleBufferType` ('circular' | 'fifo') - Optional: Specifies the type of sample buffer to use. Defaults to 'circular'. - `stretchFactory` (StretchFactory) - Optional: A factory function to provide a custom stretch stage. ### Usage Examples #### Default Circular Buffer ```ts import { SoundTouch } from '@soundtouchjs/core'; const st = new SoundTouch({}); st.pitch = 1.5; // Feed samples manually and pull processed output const inputSamples = new Float32Array(4096 * 2); // interleaved stereo st.inputBuffer.putSamples(inputSamples); st.process(); const outputBuffer = new Float32Array(4096 * 2); st.outputBuffer.extract(outputBuffer, 0, 4096); ``` #### FIFO Sample Buffer ```ts import { SoundTouch } from '@soundtouchjs/core'; const stFifo = new SoundTouch({ sampleRate: 44100, sampleBufferType: 'fifo', }); // ... (similar sample feeding and processing as above) ``` ``` -------------------------------- ### Initialize and Process Audio with SoundTouch Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md Demonstrates initializing SoundTouch with default or FIFO sample buffers and manually feeding and processing audio samples. Use this for custom pipeline work or when direct control over sample buffers is needed. ```typescript import { CircularSampleBuffer, SoundTouch, FifoSampleBuffer, registerInterpolationStrategy, setActiveInterpolationStrategy, } from '@soundtouchjs/core'; const st = new SoundTouch({}); st.pitch = 1.5; // Optional FIFO buffer override const stFifo = new SoundTouch({ sampleRate: 44100, sampleBufferType: 'fifo', }); // Feed samples manually and pull processed output const inputSamples = new Float32Array(4096 * 2); // interleaved stereo st.inputBuffer.putSamples(inputSamples); st.process(); const outputBuffer = new Float32Array(4096 * 2); st.outputBuffer.extract(outputBuffer, 0, 4096); ``` -------------------------------- ### Build Demo Application Source: https://github.com/cutterbl/soundtouchjs/blob/master/AGENTS.md Builds the demo application using Vite. The output is placed in `apps/demo/dist/`. ```sh pnpm nx build demo ``` -------------------------------- ### Install Formant Correction Worklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/formant-correction-worklet/README.md Install the package using npm. This command adds the necessary files to your project for using the formant correction AudioWorklet. ```sh npm install @soundtouchjs/formant-correction-worklet ``` -------------------------------- ### Static Hosting: Copy and Register Processor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/getting-started.mdx Copy the pre-bundled processor file to your static assets directory and reference it by its public path. Ensure the processor script is served from the same origin or with appropriate CORS headers. ```bash cp node_modules/@soundtouchjs/audio-worklet/.dist/soundtouch-processor.js public/ ``` ```typescript await SoundTouchNode.register(audioCtx, '/soundtouch-processor.js'); ``` -------------------------------- ### Instantiate SoundTouch Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/SoundTouch.mdx Create a new SoundTouch instance with optional configuration. ```typescript new SoundTouch({ sampleRate?: number, sampleBufferType?: 'fifo' | 'circular', sampleBufferFactory?: SampleBufferFactory, interpolationStrategy?: RateTransposerInterpolationStrategy, stretchFactory?: StretchFactory, }) ``` -------------------------------- ### Registering the Worklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/formant-correction-worklet.mdx Before using the FormantCorrectionNode, you need to register it with the AudioContext. This example shows how to do it using Vite. ```APIDOC ## Setup ```ts import { FormantCorrectionNode } from '@soundtouchjs/formant-correction-worklet'; // Vite: import processorUrl from '@soundtouchjs/formant-correction-worklet/processor?url'; const audioCtx = new AudioContext(); await FormantCorrectionNode.register(audioCtx, processorUrl); ``` See [Getting Started](./getting-started) for Vite, webpack, and static setups. ``` -------------------------------- ### SoundTouchProcessorBase Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Initializes the SoundTouchProcessorBase with a processor label for logging and SoundTouch pipe options. ```APIDOC ## new SoundTouchProcessorBase(processorLabel, pipeOptions) ### Description Initializes the SoundTouchProcessorBase with a processor label for logging and SoundTouch pipe options. ### Parameters #### Path Parameters - **processorLabel** (string) - Required - Label used in log messages (e.g. '[MyProcessor]'). - **pipeOptions** (SoundTouchOptions) - Required - Options forwarded to SoundTouch (interpolation strategy, stretch parameters, etc.). ``` -------------------------------- ### SoundTouchNode.registerStrategyModule Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Loads an interpolation strategy installer module into the AudioWorkletGlobalScope. Call this after register if you want to use plugin strategies. ```APIDOC ## registerStrategyModule(context, strategyModuleUrl) ### Description Loads an interpolation strategy installer module into the `AudioWorkletGlobalScope`. Call this after `register` if you want to use plugin strategies (`hann`, `blackman`, `kaiser`). ### Method Signature `static registerStrategyModule(context: AudioContext, strategyModuleUrl: string): Promise` ### Parameters #### Path Parameters - **context** (AudioContext) - Required - The AudioContext. - **strategyModuleUrl** (string) - Required - The URL of the strategy module to load. ### Request Example ```javascript await SoundTouchNode.registerStrategyModule(context, strategyModuleUrl); ``` ``` -------------------------------- ### AudioWorklet Test Setup Stubbing Source: https://github.com/cutterbl/soundtouchjs/blob/master/CLAUDE.md Global stubbing of AudioWorkletNode using vi.stubGlobal for running AudioWorklet tests in Node.js or jsdom environments. ```typescript import { vi } from 'vitest'; vi.stubGlobal('AudioWorkletNode', class AudioWorkletNode { // ... stub implementation }); ``` -------------------------------- ### Register and Use Blackman Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/interpolation-strategy-blackman/README.md Import and register the Blackman strategy, then instantiate SoundTouch with it. You can also set specific parameters for the strategy. ```typescript import { registerInterpolationStrategy, SoundTouch } from '@soundtouchjs/core'; import { registerBlackmanStrategy } from '@soundtouchjs/interpolation-strategy-blackman'; registerBlackmanStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: 'blackman', }); st.setInterpolationStrategyParams({ zeroCrossings: 6 }); ``` -------------------------------- ### Register SoundTouch Strategy Module Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Loads an interpolation strategy installer module into the AudioWorkletGlobalScope. Call this after register if you want to use plugin strategies. ```typescript await SoundTouchNode.registerStrategyModule(context, strategyModuleUrl); ``` -------------------------------- ### Initialize SoundTouchNode with AudioWorklet Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/interpolation-strategies.mdx Set up the AudioContext, register necessary modules for SoundTouchNode and interpolation strategies, and then instantiate the SoundTouchNode with a chosen strategy. You can also dynamically change the strategy and its parameters. ```typescript import { SoundTouchNode } from '@soundtouchjs/audio-worklet'; import strategyInstallerModuleUrl from '../worklet/interpolation-strategies.installers.ts?url'; const context = new AudioContext(); await SoundTouchNode.register(context, processorModuleUrl); await SoundTouchNode.registerStrategyModule( context, strategyInstallerModuleUrl, ); const node = new SoundTouchNode({ context, interpolationStrategy: { id: 'hann', params: { zeroCrossings: 6 } }, }); node.setInterpolationStrategy({ id: 'kaiser', params: { zeroCrossings: 6, beta: 12 }, }); node.setInterpolationStrategyParams({ beta: 10 }); ``` -------------------------------- ### Normalize Interpolation Strategy ID Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/interpolation-strategy-registry.mdx Validates and normalizes a strategy ID. Accepts a string ID or a descriptor object. Call with no arguments to get the default ID. ```typescript const id = normalizeInterpolationStrategyId('lanczos'); // 'lanczos' const id2 = normalizeInterpolationStrategyId({ id: 'hann' }); // 'hann' const id3 = normalizeInterpolationStrategyId(); // active default ``` -------------------------------- ### Build and Test Commands Source: https://github.com/cutterbl/soundtouchjs/blob/master/CLAUDE.md Commands for building, testing, and typechecking all packages in the monorepo using pnpm and Nx. ```sh # Build all packages pnpm build # nx run-many -t build # Run all tests pnpm test # nx run-many -t test # Typecheck all packages pnpm typecheck # nx run-many -t typecheck ``` ```sh # Single-package commands (use Nx project name) pnpm nx build core pnpm nx test core pnpm nx typecheck audio-worklet ``` ```sh # Run a single test file pnpm nx test core -- --reporter=verbose --testPathPattern=Stretch ``` ```sh # Generate consolidated coverage report (branches ≥ 80%, functions ≥ 90%) pnpm coverage:summary ``` ```sh # Start Storybook dev server pnpm nx storybook storybook ``` ```sh # Start demo app dev server pnpm dev # nx dev demo (Vite on port 8080) ``` ```sh # Format all files pnpm prettier ``` ```sh # Release (from master only) pnpm release # nx release ``` -------------------------------- ### Control Tempo with Playback Rate (Buffer Source) Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Demonstrates how to control tempo by setting the playbackRate on both the audio source and the SoundTouchNode. The processor automatically compensates for pitch. ```javascript const tempo = 1.2; // 1.2× speed // Buffer source source.playbackRate.value = tempo; stNode.playbackRate.value = tempo; // processor compensates pitch automatically ``` -------------------------------- ### SoundTouch Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md The SoundTouch constructor now accepts a named options object for configuration. This is a breaking change from previous versions. ```APIDOC ## Constructor API (breaking) `@soundtouchjs/core` constructors now use named options objects instead of positional arguments. Example: ```ts new SoundTouch({ sampleRate: 44100, sampleBufferType: 'fifo' }); ``` ``` -------------------------------- ### SoundTouch Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/SoundTouch.mdx Initializes the SoundTouch engine with optional configuration for sample rate, buffer type, interpolation, and stretch factory. ```APIDOC ## Constructor ```ts new SoundTouch({ sampleRate?: number, sampleBufferType?: 'fifo' | 'circular', sampleBufferFactory?: SampleBufferFactory, interpolationStrategy?: RateTransposerInterpolationStrategy, stretchFactory?: StretchFactory, }) ``` ### Parameters - **sampleRate** (number) - Optional - Processing sample rate in Hz. Defaults to `44100`. - **sampleBufferType** ('fifo' | 'circular') - Optional - Buffer strategy for all chain buffers. Defaults to `'circular'`. - **sampleBufferFactory** (SampleBufferFactory) - Optional - Custom factory; overrides `sampleBufferType`. - **interpolationStrategy** (RateTransposerInterpolationStrategy) - Optional - Rate transposer interpolation kernel. Defaults to `'lanczos'`. - **stretchFactory** (StretchFactory) - Optional - Factory for a custom time-stretch stage; when provided, the default WSOLA `Stretch` is not created. ``` -------------------------------- ### Initialize SoundTouch with Named Options Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md The SoundTouch constructor now requires a named options object. Specify sample rate and buffer type during initialization. ```typescript new SoundTouch({ sampleRate: 44100, sampleBufferType: 'fifo' }); ``` -------------------------------- ### Observing Processor Metrics Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/formant-correction-worklet.mdx Listen for the 'metrics' event on the worklet node to get insights into its internal state. This includes buffer status and processing counts. Requires a 'CustomEvent' with 'ProcessorMetrics' detail. ```typescript node.addEventListener('metrics', (e) => { const { framesBuffered, underrunCount, blockCount } = (e as CustomEvent).detail; }); ``` -------------------------------- ### Initialize SoundTouch with Hann Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/hann-strategy.mdx Register the Hann strategy and initialize SoundTouch with custom parameters, such as a wider kernel for smoother output. ```typescript import { SoundTouch, registerInterpolationStrategy } from '@soundtouchjs/core'; import { registerHannStrategy } from '@soundtouchjs/interpolation-strategy-hann'; registerHannStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: { id: 'hann', params: { zeroCrossings: 6 } }, }); ``` -------------------------------- ### SoundTouchProcessorBase Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Instantiate `SoundTouchProcessorBase` with a processor label for logging and SoundTouch pipe options. ```typescript new SoundTouchProcessorBase(processorLabel: string, pipeOptions: SoundTouchOptions) ``` -------------------------------- ### Get Active Interpolation Strategy ID Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/interpolation-strategy-registry.mdx Fetches the ID of the current process-wide default interpolation strategy. This strategy is used by default for new SoundTouch or RateTransposer instances if no specific strategy is provided. ```typescript const id = getActiveInterpolationStrategyId(); // 'lanczos' by default ``` -------------------------------- ### Create SoundTouchNode with AudioBufferSourceNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md Instantiate SoundTouchNode and connect it to the audio context destination. Demonstrates optional FIFO override, linear interpolation, and mono output configurations. Connect an AudioBufferSourceNode to the SoundTouchNode, setting its playback rate and the node's playbackRate and pitch. ```typescript const stNode = new SoundTouchNode({ context: audioCtx }); stNode.connect(audioCtx.destination); // Optional FIFO override const stNodeFifo = new SoundTouchNode({ context: audioCtx, sampleBufferType: 'fifo', }); // Optional interpolation override (requires registering the linear strategy module) const stNodeLinear = new SoundTouchNode({ context: audioCtx, interpolationStrategy: 'linear', }); // Mono output (e.g. connecting to a mono destination) const stNodeMono = new SoundTouchNode({ context: audioCtx, outputChannelCount: 1, }); const source = audioCtx.createBufferSource(); source.buffer = audioBuffer; source.playbackRate.value = tempo; // tempo via playback rate source.connect(stNode); stNode.playbackRate.value = tempo; // tell processor the source rate stNode.pitch.value = pitch; // desired pitch (auto-compensated) source.start(); ``` -------------------------------- ### Configure SoundTouchNode with FIFO Sample Buffer Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md Instantiate `SoundTouchNode` and specify 'fifo' for the `sampleBufferType` to use a First-In, First-Out buffer. This is an alternative to the default circular buffer. ```typescript const stNode = new SoundTouchNode({ context: audioCtx, sampleBufferType: 'fifo', }); ``` -------------------------------- ### Import AbstractSamplePipe Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/abstract-sample-pipe.mdx Import the base class for creating custom audio processing pipes. ```typescript import { AbstractSamplePipe } from '@soundtouchjs/core'; ``` -------------------------------- ### SoundTouchNode Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/audio-worklet/README.md The SoundTouchNode constructor now accepts a named options object for initialization. This allows for specifying options like the audio context and sample buffer type. ```APIDOC ## Constructor `SoundTouchNode` now uses a named options object constructor: ```ts new SoundTouchNode({ context: audioCtx }); new SoundTouchNode({ context: audioCtx, sampleBufferType: 'fifo' }); ``` ``` -------------------------------- ### Configure Interpolation Strategy with Parameters Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/README.md Configure SoundTouch with specific interpolation strategy parameters, such as 'lanczos' with 'zeroCrossings'. Strategies can also be updated at runtime. ```ts const st = new SoundTouch({ interpolationStrategy: { id: 'lanczos', params: { zeroCrossings: 4 }, }, }); st.setInterpolationStrategy('linear'); st.setInterpolationStrategyParams({ edgeHoldFrames: 4 }); ``` -------------------------------- ### Register and Use Lanczos Interpolation Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/interpolation-strategy-lanczos/README.md Import and register the Lanczos strategy, then instantiate SoundTouch with it. You can also set specific parameters for the Lanczos kernel. ```typescript import { registerInterpolationStrategy, SoundTouch } from '@soundtouchjs/core'; import { registerLanczosStrategy } from '@soundtouchjs/interpolation-strategy-lanczos'; registerLanczosStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: 'lanczos', }); st.setInterpolationStrategyParams({ zeroCrossings: 6 }); ``` -------------------------------- ### Instantiate SoundTouchNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Create a new SoundTouchNode instance, providing the audio context and optional configuration for sample buffer type, interpolation strategy, and output channels. ```typescript new SoundTouchNode({ context, processorUrl?, sampleBufferType?, interpolationStrategy?, }) ``` -------------------------------- ### PhaseVocoderNode Constructor Options Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/phase-vocoder-worklet.mdx Instantiate the PhaseVocoderNode with various configuration options. Defaults are provided for most parameters. ```typescript new PhaseVocoderNode({ context: audioCtx, fftSize?: 512 | 1024 | 2048 | 4096, // default: 2048 overlapFactor?: 2 | 4 | 8, // default: 4 outputChannelCount?: 1 | 2, // default: 2 sampleBufferType?: 'circular' | 'fifo', interpolationStrategy?: RateTransposerInterpolationStrategy, }) ``` -------------------------------- ### Register Plugin Strategies and Initialize SoundTouch Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/interpolation-strategies.mdx Register plugin interpolation strategies like Hann, Blackman, and Kaiser, then initialize SoundTouch with a specific strategy and its parameters. You can also dynamically change the strategy and its parameters after initialization. ```typescript import { SoundTouch, registerInterpolationStrategy } from '@soundtouchjs/core'; import { registerHannStrategy } from '@soundtouchjs/interpolation-strategy-hann'; import { registerBlackmanStrategy } from '@soundtouchjs/interpolation-strategy-blackman'; import { registerKaiserStrategy } from '@soundtouchjs/interpolation-strategy-kaiser'; registerHannStrategy({ registerInterpolationStrategy }); registerBlackmanStrategy({ registerInterpolationStrategy }); registerKaiserStrategy({ registerInterpolationStrategy }); const soundTouch = new SoundTouch({ interpolationStrategy: { id: 'kaiser', params: { zeroCrossings: 6, beta: 10 }, }, }); soundTouch.setInterpolationStrategy({ id: 'blackman', params: { zeroCrossings: 5 }, }); soundTouch.setInterpolationStrategyParams({ zeroCrossings: 4 }); ``` -------------------------------- ### AbstractSamplePipe Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/abstract-sample-pipe.mdx Instantiates an AbstractSamplePipe. Optionally accepts factories for input and output buffers. If createBuffers is true, both factories must be provided. ```APIDOC ## Constructor ```ts new AbstractSamplePipe({ createBuffers?: boolean, inputBufferFactory?: () => TInputBuffer, outputBufferFactory?: () => TOutputBuffer, }) ``` When `createBuffers` is `true`, both factories are required. ``` -------------------------------- ### Common Development Commands with pnpm Source: https://github.com/cutterbl/soundtouchjs/blob/master/README.md Executes common development tasks such as building, testing, and formatting. Use these commands for maintaining the project. ```sh pnpm build # Build all projects pnpm test # Run all tests pnpm coverage:summary # Run package coverage and write consolidated report to .coverage-reports/ pnpm typecheck # Typecheck all projects pnpm dev # Start demo dev server (Vite on port 8080) pnpm prettier # Format all files pnpm nx storybook storybook # Start Storybook docs server ``` -------------------------------- ### Import Processor URL with Static/CDN Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/formant-correction-worklet/README.md When using static files or a CDN, copy the processor script to your public directory and reference it directly. ```typescript const processorUrl = '/formant-correction-processor.js'; ``` -------------------------------- ### Import FFT Primitives Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/stretch-phase-vocoder/README.md Import and utilize the internal FFT, IFFT, and Hann window functions for custom signal processing tasks. ```ts import { fft, ifft, makeHannWindow } from '@soundtouchjs/stretch-phase-vocoder'; ``` -------------------------------- ### Basic Usage of PhaseVocoderNode Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/phase-vocoder-worklet.mdx Instantiate and configure the PhaseVocoderNode. You can set parameters like `fftSize`, `overlapFactor`, `pitch`, `pitchSemitones`, and `playbackRate` to control the audio processing. ```APIDOC ## Basic Usage ```ts const node = new PhaseVocoderNode({ context: audioCtx, fftSize: 2048, // default overlapFactor: 4, // default }); node.pitch.value = 1.5; // 50 % pitch up node.pitchSemitones.value = 3; // shift by semitones node.playbackRate.value = 0.25; // extreme slow-down — smooth with phase vocoder node.connect(audioCtx.destination); sourceNode.connect(node); ``` ``` -------------------------------- ### Phase Vocoder Constructor Options Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/stretch-phase-vocoder.mdx Instantiate the PhaseVocoder directly with options for FFT size and overlap factor. Larger FFT sizes improve frequency resolution but increase startup latency. ```typescript new PhaseVocoder({ fftSize?: 512 | 1024 | 2048 | 4096, // default: 2048 overlapFactor?: 2 | 4 | 8, // default: 4 }) ``` -------------------------------- ### SoundTouchNode Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/sound-touch-node.mdx Initializes a new SoundTouchNode instance. This node is responsible for processing audio for pitch and tempo changes in real-time. ```APIDOC ## Constructor ```ts new SoundTouchNode({ context, processorUrl?, sampleBufferType?, interpolationStrategy?, outputChannelCount? }) ``` ### Options - **context**: `BaseAudioContext` (required) - The audio context to which the node will be connected. - **processorUrl**: `string` (optional) - A convenience field for the processor URL, though registration is typically done separately. - **sampleBufferType**: `'circular' | 'fifo'` (optional) - Specifies the type of sample buffer to use. Defaults to a package constant. - **interpolationStrategy**: `string` (optional) - The ID of the interpolation strategy to use, understood by `@soundtouchjs/core`. Built-in default is `'lanczos'`. Additional IDs like `'linear'`, `'hann'`, `'blackman'`, `'kaiser'` can be registered. - **outputChannelCount**: `1 | 2` (optional) - The number of output channels for the node. Defaults to `2`. Set to `1` for mono destinations. ``` -------------------------------- ### FFT Primitives for Custom Use Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/core/stretch-phase-vocoder.mdx Import and utilize the internal FFT and windowing functions for custom audio processing tasks. Ensure you have the necessary samples loaded into Float32Array buffers. ```typescript import { fft, ifft, makeHannWindow } from '@soundtouchjs/stretch-phase-vocoder'; const N = 1024; const re = new Float32Array(N); const im = new Float32Array(N); // Fill re with samples... fft(re, im); // in-place forward FFT ifft(re, im); // in-place inverse FFT const win = makeHannWindow(N); // symmetric Hann window ``` -------------------------------- ### Individual Project Commands with pnpm nx Source: https://github.com/cutterbl/soundtouchjs/blob/master/README.md Builds or tests specific packages within the SoundTouchJS monorepo using pnpm and Nx. Useful for targeted development or testing. ```sh pnpm nx build core # Build @soundtouchjs/core pnpm nx build audio-worklet # Build @soundtouchjs/audio-worklet pnpm nx build @soundtouchjs/interpolation-strategy-lanczos pnpm nx build @soundtouchjs/interpolation-strategy-linear pnpm nx build @soundtouchjs/interpolation-strategy-hann pnpm nx build @soundtouchjs/interpolation-strategy-blackman pnpm nx build @soundtouchjs/interpolation-strategy-kaiser pnpm nx test core # Run core tests pnpm nx test audio-worklet # Run audio-worklet tests pnpm nx dev demo # Dev server with HMR ``` -------------------------------- ### Constructor Options Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/formant-correction-worklet.mdx Details the available options for the FormantCorrectionNode constructor, including context, output channel count, sample buffer type, and interpolation strategy. ```APIDOC ## Constructor options ```ts new FormantCorrectionNode({ context: audioCtx, outputChannelCount?: 1 | 2, // default: 2 sampleBufferType?: 'circular' | 'fifo', interpolationStrategy?: RateTransposerInterpolationStrategy, }) ```
OptionDefaultDescription
contextrequiredAudioContext or OfflineAudioContext
outputChannelCount21 for mono destinations; input is always processed as stereo
sampleBufferType'circular'Internal buffer strategy
interpolationStrategy'lanczos'Rate-transposer interpolation kernel
``` -------------------------------- ### Register and Use Hann Interpolation Strategy Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/interpolation-strategy-hann/README.md Import and register the Hann strategy, then instantiate SoundTouch with it. You can also set specific parameters for the Hann strategy. ```typescript import { registerInterpolationStrategy, SoundTouch } from '@soundtouchjs/core'; import { registerHannStrategy } from '@soundtouchjs/interpolation-strategy-hann'; registerHannStrategy({ registerInterpolationStrategy }); const st = new SoundTouch({ interpolationStrategy: 'hann', }); st.setInterpolationStrategyParams({ zeroCrossings: 6 }); ``` -------------------------------- ### Import SoundTouch Core Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/SoundTouch.mdx Import the SoundTouch class from the core library. ```typescript import { SoundTouch } from '@soundtouchjs/core'; ``` -------------------------------- ### A/B Comparison Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/formant-correction-worklet.mdx Demonstrates how to adjust the formant strength to achieve different effects, from raw pitch shifting to fully formant-corrected sound. ```APIDOC ## A/B comparison ```ts // Raw pitch shift (chipmunk/giant effect) node.formantStrength.value = 0; // Formant-corrected node.formantStrength.value = 1; // Or blend node.formantStrength.value = 0.5; ``` ``` -------------------------------- ### Basic PhaseVocoderNode Usage Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/phase-vocoder-worklet/README.md Instantiate and connect a PhaseVocoderNode to the audio context. Adjust pitch and playback rate as needed. Ensure the processor is registered before creating the node. ```ts import { PhaseVocoderNode } from '@soundtouchjs/phase-vocoder-worklet'; const audioCtx = new AudioContext(); await PhaseVocoderNode.register(audioCtx, processorUrl); const node = new PhaseVocoderNode({ context: audioCtx, fftSize: 2048, // optional, default 2048 overlapFactor: 4, // optional, default 4 }); node.pitch.value = 1.5; // pitch up 50 % node.pitchSemitones.value = 3; // or shift by semitones node.playbackRate.value = 0.5; // slow down 2× node.connect(audioCtx.destination); // Connect your source: sourceNode.connect(node); ``` -------------------------------- ### Signal Chain Overview Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/core/AGENTS.md Illustrates the data flow through the audio processing pipeline, from source to output, including optional filters and the core SoundTouch engine. ```plaintext WebAudioBufferSource → SimpleFilter → SoundTouch → getWebAudioNode → ScriptProcessorNode ├─ Stretch (time-stretch via WSOLA) └─ RateTransposer (sample rate transposition) ``` -------------------------------- ### SoundTouchProcessorBase Abstract Method: onProcessComplete Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Implement this abstract method to execute code after each successfully processed audio block. The `result` object contains output metrics. ```typescript abstract onProcessComplete(result: ProcessCoreResult): void ``` -------------------------------- ### PhaseVocoderNode Constructor Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/audio-worklet/phase-vocoder-worklet.mdx Instantiates a new PhaseVocoderNode with specified options. The constructor accepts an options object to configure various aspects of the node's behavior. ```APIDOC ## new PhaseVocoderNode(options) ### Description Creates a new PhaseVocoderNode instance. ### Parameters #### Options Object - **context** (AudioContext | OfflineAudioContext) - Required - The audio context to associate with this node. - **fftSize** (512 | 1024 | 2048 | 4096) - Optional - The FFT frame size. Larger values provide better frequency resolution at the cost of higher latency. Defaults to 2048. - **overlapFactor** (2 | 4 | 8) - Optional - The overlap factor for the FFT frames. A higher factor (e.g., 8 for 87.5% overlap) results in smoother audio but doubles the computational cost compared to a lower factor (e.g., 4 for 75% overlap). Defaults to 4. - **outputChannelCount** (1 | 2) - Optional - The number of output channels. Set to 1 for mono destinations. The input is always processed as stereo. Defaults to 2. - **sampleBufferType** ('circular' | 'fifo') - Optional - The internal buffer strategy used for sample processing. Defaults to 'circular'. - **interpolationStrategy** (RateTransposerInterpolationStrategy) - Optional - The interpolation kernel used by the rate transposer. Defaults to 'lanczos'. ### Example ```javascript const audioCtx = new AudioContext(); const vocoder = new PhaseVocoderNode({ context: audioCtx, fftSize: 1024, overlapFactor: 8, outputChannelCount: 1 }); ``` ``` -------------------------------- ### SoundTouchProcessorBase.onProcessComplete Source: https://github.com/cutterbl/soundtouchjs/blob/master/packages/worklet-base/README.md Abstract method to be implemented by subclasses. It is called after each successfully processed audio block. ```APIDOC ## abstract onProcessComplete(result: ProcessCoreResult): void ### Description Abstract method to be implemented by subclasses. It is called after each successfully processed audio block. `result` contains `{ outputRms, outputPeak }` unless `extractSamples` is overridden to return different values. ### Parameters #### Path Parameters - **result** (ProcessCoreResult) - Required - An object containing processing results like `outputRms` and `outputPeak`. ``` -------------------------------- ### Import Stretch Class Source: https://github.com/cutterbl/soundtouchjs/blob/master/storybook/src/docs/Stretch.mdx Import the Stretch class from the core SoundTouchJS library. ```typescript import { Stretch } from '@soundtouchjs/core'; ```