Spectrogram
Sonoscope provides an easy way to visualize audio using fast, flexible spectrograms.
When connected to navigation, dragging directly on the spectrogram pans across time and frequency, while scrolling or pinching zooms into harmonic detail.
The basics
Section titled “The basics”Spectrograms attach to standard HTML <canvas> elements. Calling createSpectrogram without options initializes a GPU-accelerated spectrogram with auto-resizing:
import { Sonoscope } from "@sonoscope/core";
const scope = await Sonoscope.fromUrl("/audio/sample.wav");
// Create a spectrogram using default optionsconst spectrogram = scope.createSpectrogram(spectrogramCanvas);
// Synchronize drag and zoom interactions across time and frequencyscope.attachNavigation(spectrogramCanvas);Example configurations
Section titled “Example configurations”1. Default spectrogram
Section titled “1. Default spectrogram”Renders with standard linear frequency scaling and the Viridis colormap:
scope.createSpectrogram(spectrogramCanvas);2. Inferno colormap & dynamic range
Section titled “2. Inferno colormap & dynamic range”Applies the Inferno palette with adjusted decibel floors for enhanced contrast:
scope.createSpectrogram(spectrogramCanvas, { colorMap: "inferno", minDb: -80, maxDb: 0,});3. Mel frequency scale
Section titled “3. Mel frequency scale”Compresses higher frequencies to match human pitch perception:
scope.createSpectrogram(spectrogramCanvas, { frequencyScale: "mel",});4. Logarithmic frequency scale
Section titled “4. Logarithmic frequency scale”Distributes octaves equally along the vertical frequency axis:
scope.createSpectrogram(spectrogramCanvas, { frequencyScale: "log",});5. High time-resolution STFT
Section titled “5. High time-resolution STFT”Uses a smaller window and hop size to emphasize rapid transient events:
scope.createSpectrogram(spectrogramCanvas, { windowSize: 512, hopSize: 128,});6. Narrow dynamic range
Section titled “6. Narrow dynamic range”Raises the noise floor to suppress quiet background and expose mid-level detail:
scope.createSpectrogram(spectrogramCanvas, { minDb: -60, maxDb: -10,});7. Plasma colormap
Section titled “7. Plasma colormap”Applies the perceptually uniform Plasma palette:
scope.createSpectrogram(spectrogramCanvas, { colorMap: "plasma", minDb: -85, maxDb: 0,});For stylized shader programs and alternative renderers (Halftone, 3D Terrain, Topographic, ASCII), see the Plugins section.
Configuration options
Section titled “Configuration options”Options accepted by scope.createSpectrogram(canvas, options). Full reference: SpectrogramConfig.
| Option | Type | Default | Description |
|---|---|---|---|
autoRenderopt | boolean | true | Whether to automatically re-render when viewport or configuration changes. |
showLoadingPlaceholdersopt | boolean | - | Whether to draw loading placeholders over tiles that are still computing. |
rendereropt | RendererMode | "auto" | Rendering engine: - "auto": Uses WebGL2 if supported, falling back to Canvas 2D. - "webgl" / "webgl2": Hardware-accelerated GPU shader renderer. - "canvas2d": CPU Canvas 2D fallback renderer. - Custom object with shader program (`{ type: "webgl", program: "normal" | "halftone" | "terrain" }`). |
backendopt | BackendMode | "auto" | STFT compute execution backend: - "auto": Prefers WebAssembly workers, falling back to main thread. - "wasm": Fast WebAssembly computation. - "worker": Web Worker background thread computation. - "main-thread": Synchronous main thread computation. |
channelopt | number | 0 | Audio channel index to analyze (0 for left/mono, 1 for right). |
windowSizeopt | number | 1024 | STFT analysis window length in audio samples. |
fftSizeopt | number | 1024 | FFT length in samples. Must be a power of two >= windowSize. Spectral magnitudes contain the first `fftSize / 2` bins, normalized by `fftSize`, without one-sided or window coherent-gain compensation. |
hopSizeopt | number | 256 | Hop size (step length) in samples between consecutive FFT frames. |
windowopt | WindowName | "hann" | Window function applied before FFT: "hann", "hamming", "blackman", or "rectangular". |
frequencyScaleopt | FrequencyScale | "linear" | Frequency scale mapping: "linear", "mel", or "log". |
valueModeopt | ValueMode | "db" | Intensity scale representation: "db" (decibels), "magnitude", or "power". dB values use `20 * log10(max(magnitude, 1e-12))`. |
minDbopt | number | -100 | Lower intensity limit mapped to the start of the colormap (always specified in dB; converted internally for non-dB value modes). |
maxDbopt | number | 0 | Upper intensity limit mapped to the end of the colormap (in dB when valueMode is "db"). |
valueGammaopt | number | 1.0 | Power-law gamma exponent for dynamic range contrast adjustment. |
clampValuesopt | boolean | true | Whether to clamp intensity values strictly within [minDb, maxDb]. |
tileMaxCellsopt | number | 131_072 | Maximum 2D STFT matrix cells (frameCount * binCount) budgeted per computation tile. |
maxCachedTilesopt | number | 64 | Maximum number of computed STFT tiles retained in memory cache. |
maxCachedBytesopt | number | - | Maximum estimated bytes retained by the computed tile cache. |
prefetchTilesopt | number | 8 | Number of tiles to prefetch and compute ahead of the visible viewport. |
autoResizeopt | boolean | true | Whether to automatically resize canvas pixel resolution when container dimensions change. |
devicePixelRatioopt | boolean | number | window.devicePixelRatio | Device pixel ratio scaling factor for HiDPI/Retina displays. |
colorMapopt | ColorMapConfig | "viridis" | Colormap palette name (such as "inferno", "viridis", "magma", "turbo") or custom palette object. |
transformsopt | SpectrogramTransform[] | undefined | Array of custom matrix transforms applied to STFT data before rendering. |
Navigation & interaction
Section titled “Navigation & interaction”Use scope.attachNavigation(canvas, options) to link panning and zooming across spectrograms, waveforms, and rulers:
- 2D navigation: By default, spectrogram navigation tracks both horizontal time and vertical frequency axes.
- Axis constraints: Pass
{ axis: 'time' }or{ axis: 'frequency' }to restrict navigation to a single dimension. - Drag & scroll: Dragging pans the visible window; scrolling or pinching zooms into the frequency band or time interval under the cursor.
- Synchronized views: Navigating on any attached canvas immediately updates all connected spectrograms, waveforms, and rulers.
Try it yourself!
Section titled “Try it yourself!”Play around with the code in the live sandbox below:
- Drag the spectrogram to pan across time and frequency.
- Scroll / Pinch over the canvas to zoom in and out.
- Edit the options in
index.tsto test different colormaps, frequency scales, STFT resolutions, or shader programs live.