SoundTouchJS

repository·master·Indexed 43 days ago

https://github.com/cutterbl/soundtouchjs

A real-time audio processing library for pitch shifting and playback speed control within the Web Audio API, providing a modernized port of the SoundTouch C++ library. It includes @soundtouchjs/audio-worklet for AudioWorklet-based processing and @soundtouchjs/core for custom audio pipelines and offline processing. Key features include support for Buffer and Element modes, independent pitch and tempo control via SoundTouchNode, and offline rendering using processOffline().

Tokens
59.9K
Snippets
183
Records
265
Agent score
52%

What's inside SoundTouchJS

  1. Overview of SoundTouchJS packages

    master

    SoundTouchJS is a monorepo containing several specialized packages for real-time audio processing. Depending on your needs, you might use different packages:

    • Core Processing: @soundtouchjs/core provides the main SoundTouch engine, buffers, and interpolation registry.
    • Web Audio Integration: @soundtouchjs/audio-worklet is the recommended implementation for Web Audio API users, providing AudioParam-based controls and offline rendering.
    • Advanced Time-Stretching: @soundtouchjs/stretch-phase-vocoder implements a phase vocoder algorithm for smoother extreme-ratio time-stretching.
    • Vocal Preservation: @soundtouchjs/formant-correction-worklet provides an AudioWorklet with LPC-based formant preservation for natural-sounding vocal pitch shifts.
    • Interpolation Strategies: Various plugins for different interpolation qualities (e.g., @soundtouchjs/interpolation-strategy-lanczos, @soundtouchjs/interpolation-strategy-linear, etc.).
    • Custom Worklets: @soundtouchjs/worklet-base provides an abstract base class for building your own custom AudioWorklet processors.
  2. Overview of SoundTouchJS packages and features

    master

    SoundTouchJS is a toolkit for real-time audio manipulation in the browser, including playback speed control (time stretching), pitch shifting, and key transposition.

    Core Components

    • @soundtouchjs/core: The main engine and building blocks for custom pipelines or offline processing.
    • @soundtouchjs/stretch-phase-vocoder: An alternative time-stretch algorithm (phase vocoder) for smoother results at extreme playback ratios. Can be used as a drop-in stage in SoundTouch or standalone.
    • Interpolation Plugins: Swappable modules for tuning the quality vs. CPU cost of sample-rate conversion. Available strategies include lanczos, linear, hann, blackman, and kaiser.
  3. What is SoundTouch and when to use it

    master

    The SoundTouch class is the core engine for real-time pitch and key manipulation. It functions by chaining RateTransposer and Stretch stages into a single processing pipeline.

    When to use it:

    • Use SoundTouch directly if you are building a custom, low-level audio pipeline.
    • Do NOT use it directly for browser playback. Instead, use SoundTouchNode from @soundtouchjs/audio-worklet, which is designed to manage the pipeline and Web Audio integration automatically.
  4. What is the Interpolation Strategy Registry?

    master

    The interpolation strategy registry is a process-wide lookup table managed by @soundtouchjs/core. It tracks which interpolation strategies are available for use in SoundTouch and RateTransposer.

    When to use it: While most developers simply pass a strategy ID when constructing SoundTouch or SoundTouchNode, you should use the registry directly when:

    • Building plugins that provide new interpolation kernels.
    • Testing if specific strategies are available in the current environment.
    • Changing the process-wide default strategy at runtime.
  5. Use FifoSampleBuffer for audio data processing

    master

    The FifoSampleBuffer is a resizable First-In-First-Out (FIFO) container optimized for interleaved stereo frame processing. It is designed to manage audio data as it moves through a processing pipeline, ensuring that the oldest data is handled first. This is particularly useful for audio effects that require historical context (memory of previous samples).

    import { FifoSampleBuffer } from '@soundtouchjs/core';
    
    // Initialize a buffer with an optional maximum number of frames
    const buffer = new FifoSampleBuffer(1024);
  6. Compare WSOLA vs Phase Vocoder for time-stretching

    master

    Choosing between the default WSOLA and the Phase Vocoder depends on your application's requirements:

    | Feature | WSOLA (Default) | Phase Vocoder | | :--- | :--- | : | | Quality at extreme ratios | Artifacts above 2× | Smooth at all ratios | | Transient preservation | Better (time-domain) | Worse (frequency smearing) | | Computation | Lower | Higher (FFT per hop) | | Startup latency | Lower | fftSize samples | | Artifacts | Clicks / repeats | "Phasiness" / smearing |

    Recommendation: Use WSOLA for most musical applications at moderate tempos (0.5–2×). Use the Phase Vocoder for very slow-motion or very fast playback, or when WSOLA artifacts are unacceptable.

  7. Compare SoundTouchNode vs FormantCorrectionNode

    master

    Choose between the standard SoundTouchNode and the FormantCorrectionNode based on your use case:

    FeatureSoundTouchNodeFormantCorrectionNode
    Formant shift with pitchYes (chipmunk/giant effect)Corrected — original timbre preserved
    ComputationLowerHigher (LPC per render block)
    Best use caseInstruments, musicVocals, speech
    formantStrength = 0 mode—Identical to SoundTouchNode
  8. Important notes for using Stretch in the browser

    master

    When working in a browser environment, keep the following in mind:

    1. Tempo Control: The tempo property on the Stretch class is an internal DSP control. It is not exposed as an AudioParam.
    2. AudioWorklet Integration: For browser-based audio processing, you should prefer calling SoundTouchNode.setStretchParameters(). This ensures that parameter updates are correctly queued on the render thread.
  9. Implement Buffer mode transport logic

    master

    Because AudioBufferSourceNode is a 'one-shot' node (it cannot be restarted once stopped), you must manage playback state manually to support pause/resume and tempo changes.

    To keep state coherent, track these three variables:

    1. playStartTime: The audioCtx.currentTime when playback started/resumed.
    2. pauseOffset: The source position in seconds where playback should start next.
    3. currentTempo: The current playback rate.

    Calculating the new offset when pausing or changing tempo: pauseOffset += (audioCtx.currentTime - playStartTime) * currentTempo

  10. Use RateTransposer to change audio speed

    master

    The RateTransposer class is a building block used to change the playback speed (rate) of audio by resampling. It performs sample-rate transposition and interpolation as a single stage in the SoundTouch processing pipeline. While most users will interact with the higher-level SoundTouch class (which uses RateTransposer internally), you should use RateTransposer directly if you are building a custom audio processing pipeline.

    import { RateTransposer } from '@soundtouchjs/core';
    
    // Example initialization
    const transposer = new RateTransposer();
  11. Understand Interpolation Strategies

    master

    When changing speed or pitch, SoundTouchJS uses interpolation strategies to estimate in-between audio samples. Choosing a strategy involves a trade-off between CPU cost, latency, and sound quality.

    Available Strategies

    StrategyTypeDescription
    lanczosBuilt-inHigh-quality windowed-sinc baseline; recommended for most music and voice.
    linearPluginLowest complexity and typically lowest latency.
    hannPluginGood general-purpose quality with moderate roll-off.
    blackmanPluginBetter stopband rejection with a slightly wider transition band.
    kaiserPluginTunable strategy with flexible quality/performance tradeoffs.