Skip to content

Spectral Editing

spectralEdit(...) is libsonare's region-based STFT editor. Use it when you want to change a time and frequency rectangle inside a mono clip: attenuate a whistle, mute a short hum, boost a narrow band, or heal a small dropout from neighboring frames.

It is an offline transform. The output keeps the same sample rate and length as the input, and each region operation is applied in order to the same STFT buffer.

SPECTRAL EDIT · REGIONIDLE
Spectral editing — erase one region, leave the rest

A steady pad is given a narrow whistle over a middle time window (Artifact). One `spectralEdit` region op — the same time x frequency rectangle the whistle occupies — removes it (Edited), and the averaged spectra show the in-band spike collapse while everything outside the shaded band is untouched. Switch the mode to compare attenuate (turn the bins down by gainDb), mute (silence them) and heal (rebuild them from neighbouring frames), and flip Compare to audition each side. NOTCH is the in-band reduction in dB.

Compare
Mode

When To Use It

GoalMode
Turn a selected band up or down by an exact amountgain
Reduce a selected band — same formula as gain, conventionally passed a negative gainDbattenuate
Remove a selected rectangle completelymute
Fill a small artifact from nearby framesheal

gain and attenuate run the identical math; they exist as two names so your code reads by intent. Use gain when you mean to boost and attenuate (with a negative gainDb) when you mean to cut.

Use Editing DSP for pitch, time, note, and voice edits. Use Mastering Processors for whole-track tone, dynamics, repair, and delivery processing.

Usage

typescript
import { init, spectralEdit } from '@libraz/libsonare';

await init();

const repaired = spectralEdit(samples, sampleRate, [
  {
    startSample: Math.round(1.25 * sampleRate),
    endSample: Math.round(1.55 * sampleRate),
    lowHz: 7600,
    highHz: 8300,
    mode: 'attenuate',
    gainDb: -18,
  },
  {
    startSample: Math.round(2.1 * sampleRate),
    endSample: Math.round(2.18 * sampleRate),
    lowHz: 0,
    highHz: 400,
    mode: 'heal',
  },
], {
  nFft: 2048,
  hopLength: 512,
  window: 'hann',
  healRadiusFrames: 2,
});
python
import libsonare as sonare

repaired = sonare.spectral_edit(
    samples,
    sample_rate,
    [
        sonare.SpectralRegionOp(
            start_sample=int(1.25 * sample_rate),
            end_sample=int(1.55 * sample_rate),
            low_hz=7600,
            high_hz=8300,
            gain_db=-18,
            mode="attenuate",
        ),
        sonare.SpectralRegionOp(
            start_sample=int(2.1 * sample_rate),
            end_sample=int(2.18 * sample_rate),
            low_hz=0,
            high_hz=400,
            mode="heal",
        ),
    ],
    n_fft=2048,
    hop_length=512,
    window="hann",
    heal_radius_frames=2,
)

Options

FieldMeaning
startSample / endSampleTime rectangle in input samples. Omitting endSample (Python: leave end_sample at its default -1 sentinel) spans to the end of the signal. In Python, end_sample=0 is an empty region, not the full signal.
lowHz / highHzFrequency rectangle in Hz. Values are clamped to [0, Nyquist]; highHz <= 0 means Nyquist.
gainDbGain in dB. Applied identically by gain and attenuate as magnitude *= 10^(gainDb/20); pass a negative value to reduce. Ignored by mute/heal.
nFftPower-of-two FFT size, default 2048.
hopLengthSTFT hop, default 512; must satisfy 0 < hopLength <= nFft / 2.
windowhann, hamming, blackman, or rectangular.
healRadiusFramesNeighbor frames on each side used by heal, default 2; must be >= 1.

Small regions usually work best. Broad, long, or repeatedly healed regions can sound phasey because the edit happens in an STFT representation rather than a source-separated model.