Input and Decoding Boundaries
This tool is a web application for loading user-selected audio files (such as MP3, WAV, AAC, and M4A) directly in the browser to adjust playback speed and musical pitch.
Audio loading uses the Web Audio API decodeAudioData method. Consequently, supported input formats depend heavily on browser version and underlying operating system media frameworks.
For example, proprietary compressed formats playable in one browser may fail to decode in another. To prevent excessive system load and client memory exhaustion, strict boundaries are enforced: maximum input file size is 50 MiB, duration must be greater than 0 seconds and up to 5 minutes (300 seconds), channel count is restricted to mono (1ch) or stereo (2ch), and processing immediately aborts with an error if decompressed Float32Array audio in browser memory exceeds 64 MiB.
For long recordings or high-resolution audio with elevated sample rates, split the file beforehand or downsample to standard 44.1 kHz or 48 kHz before importing.
Upon successful decoding, a visual waveform representation is rendered on screen. This display divides channel 0 audio into 48 segments and visualizes the peak amplitude of each segment.
It serves as an approximate guide for volume contours rather than a precision tool for acoustic evaluation, and it depicts original audio peaks rather than the processed output after parameter changes.
Independent Speed and Pitch Control
In standard audio playback, simply altering the playbackRate of an AudioBufferSourceNode changes speed and pitch proportionally at the same time: speeding up causes a higher chipmunk effect, while slowing down lowers the pitch.
This tool integrates the SoundTouchJS library under the Mozilla Public License 2.0 (MPL-2.0) to control these two properties independently.
The interface provides two sliders: Playback Speed (Tempo) and Pitch (Key). Playback speed can be set from 0.5x (slower) to 2.0x (faster) in 0.05 increments relative to 1.0x normal tempo.
Musical pitch can be adjusted in semitone increments from -12 semitones (one octave down) to +12 semitones (one octave up) as whole integers relative to 0.
Altering only pitch does not change audio duration from its original buffer length. These parameters are passed to SoundTouchJS algorithms to apply time-stretching and pitch-shifting DSP routines.
However, because processing relies on digital signal algorithms, transformations may introduce changes in timbre, minor waveform fluctuations, rounding artifacts, or slight truncation at the end of audio; complete preservation of original acoustic characteristics cannot be guaranteed.
Processing and Previewing Audio
Applying speed and pitch parameters to audio waveforms requires recomputing audio data whenever settings change. This tool adopts an approach where adjusting sliders immediately discards existing playback state and previously rendered buffers, recalculating the transformation when playback or export is initiated.
This helps minimize discrepancies between preview playback and the exported file. Waveform processing is executed via an AudioWorklet inside an OfflineAudioContext separate from the main UI thread using SoundTouchJS routines.
When tempo is 1.0x and pitch shift is 0 semitones, the Worklet processing can be bypassed. Specifically, the asynchronous processOffline function generates a newly processed AudioBuffer applying the specified playbackRate and pitchSemitones across the entire input AudioBuffer.
When playback is triggered, this transformed AudioBuffer is assigned to a newly created AudioBufferSourceNode and routed through a GainNode to the browser audio output (AudioContext.destination).
To help mitigate high memory consumption, two separate limits are enforced: if the transformed Float32 buffer exceeds 128 MiB, or if the resulting WAV PCM data exceeds 128 MiB, an exception is raised and processing halts immediately.
During preview, requestAnimationFrame calculates current playback time to update the progress bar smoothly based on the transformed duration.
Volume, Seeking, and File Reselection
The preview interface offers controls over the transformed audio buffer. The progress bar seek feature operates based on the duration *after* transformation.
For instance, setting playback speed to 2.0x halves physical duration, and the seek bar dynamically reconfigures its maximum value to match this halved length.
Moving the seek thumb behaves according to playback state: during active playback, the running source node is stopped immediately and a new AudioBufferSourceNode is created at the specified offset to resume playback; when paused or stopped, only the indicator moves without triggering playback.
Volume adjustment is managed via the gain.value property of a GainNode along the playback path. Gain can be set from 0.0 (silent) to 1.0 (original signal level), and clicking mute forces the gain value to 0.
A volume setting of 1.0 indicates a multiplier relative to the digital signal rather than guaranteeing absolute sound pressure levels in physical decibels (dB).
When a different audio file is selected via drag-and-drop or file dialog, active sources and old buffers are discarded and reset while reusing the existing AudioContext for subsequent operations; the AudioContext is closed and disposed only when the page session ends, such as closing the browser tab.
Exporting 16-bit PCM WAV Files
When saving transformed audio, this tool does not perform real-time recording such as capturing playback through the MediaRecorder API.
It calls the exact same offline processing function used for preview to construct binary data directly from the complete AudioBuffer in memory, avoiding reliance on real-time stream recording.
Exporting invokes the internal encodePcmWav function, which iterates through Float32Array channel samples (-1.0 to 1.0) and quantizes them into 16-bit signed integers (-32768 to 32767).
Concurrently, standard WAVE headers comprising RIFF, fmt, and data chunks are constructed at the byte level with appropriate endianness using DataView, combining PCM data into an audio/wav Blob.
The volume slider setting and mute state are applied as amplitude multipliers to each sample; exporting while muted results in a completely silent WAV file.
The generated Blob is converted into a temporary download link via URL.createObjectURL, triggering a file download with _processed.wav appended to the original filename.
Workload, Sound Quality, and Network Scope
Time-stretching and pitch-shifting involve computationally intensive digital signal processing that depends on client CPU resources.
Processing long files with extreme parameters requires noticeable computation time. Furthermore, extreme parameter settings (such as shifting +12 semitones or slowing down to 0.5x) accentuate artifacts like unnatural reverberation, warbling, or phase discrepancies due to overlap-add algorithmic characteristics, representing technical limits of browser JavaScript processing.
In terms of data handling and security, user audio files and converted binary data are never sent to external servers for storage, analysis, or machine learning; decoding, SoundTouchJS DSP transformations, and WAV encoding execute entirely within browser memory.
Site analytics or advertising requests remain separate from audio handling. Bundled library assets are loaded dynamically, and the AudioWorklet processor script (soundtouch-processor.js) is fetched when non-default pitch or tempo processing is required.
If necessary assets are not cached locally, an initial connection to the hosting site is needed to retrieve them.