Skip to content

Repairing Clipping, Clicks, and Crackle ​

Clipping, clicks, and crackle are all short-time defects, but their evidence is different. Clipping creates runs at or near a ceiling, a click is an isolated discontinuity, and crackle is a dense set of sample-scale deviations. Detect each defect before choosing its reconstruction method.

Terms on this page

  • Run: a stretch of consecutive samples a detector marks as damaged. Clip runs sit at one level; click runs stand out from their neighbors.
  • LPC / AR model (linear prediction, autoregressive): a model that predicts each sample from the few dozen before it. Declick and declip fit one to the undamaged audio around a run and use it to fill the run with a waveform that continues the surrounding signal (lpcOrder is how many past samples it uses).
  • Interpolation fallback: a run too long for the model is filled with a smooth curve between its edges instead.
  • Median criterion: decrackle compares each sample with the median of its neighbors and replaces the ones that depart too far.
  • Wavelet shrinkage: the other decrackle mode splits the signal into detail levels (levels) and shrinks the small detail coefficients where crackle lives, rather than replacing individual samples.

Select a detector ​

DefectDetectorRepair stageWhat to inspect
A flat-topped or over-threshold peakmasteringRepairDetectClippingmasteringRepairDeclipsampleCount, runCount, and longestRunSamples for samples at or past clipThreshold; long runs use an interpolation fallback. For audio clipped before a later gain change, read flatRunCount, longestFlatRunSamples, flatSampleCount, and flatLevel instead.
An isolated impulse-like discontinuitymasteringRepairDetectClicksmasteringRepairDeclickcount, rejected, longestRunSamples, and perSecond.
Dense sample-scale surface damagemasteringRepairDetectCracklemasteringRepairDecracklesampleCount, sampleFraction, and perSecond.

Detection is source-dependent. A square wave, pulse train, or fully limited signal can look like a flat top, while downmixing, resampling, or lossy coding can erase a real flat top. Inspect each original channel before any downmix. Percussion is not read as damage: crackle samples and click runs are counted only where they stand above the local transient level, so a clean kick loop reports none. The repair stages still act inside transients, so replacedSamples and repairedRuns can exceed the detected counts.

Detect in repair order ​

The following mono workflow detects again after each selected stage, so later measurements see the waveform that the previous repair produced.

ts
import {
  init,
  masteringRepairDeclick,
  masteringRepairDeclip,
  masteringRepairDecrackle,
  masteringRepairDetectClicks,
  masteringRepairDetectClipping,
  masteringRepairDetectCrackle,
} from '@libraz/libsonare';

await init();

let repaired = samples;
const clipping = masteringRepairDetectClipping(repaired, sampleRate);
if (clipping.sampleCount > 0 || clipping.flatRunCount > 0) {
  repaired = masteringRepairDeclip({
    samples: repaired,
    sampleRate,
    clipThreshold: clipping.sampleCount > 0 ? 0.98 : clipping.flatLevel,
  });
}

const clicks = masteringRepairDetectClicks(repaired, sampleRate);
if (clicks.count > 0) {
  repaired = masteringRepairDeclick(repaired, sampleRate);
}

const crackle = masteringRepairDetectCrackle(repaired, sampleRate);
if (crackle.sampleCount > 0) {
  repaired = masteringRepairDecrackle(repaired, sampleRate);
}

sampleCount only sees samples at or past the threshold (0.98 by default). Audio that was clipped and then turned down has its flat tops at a lower level, so sampleCount reads 0 and a default declip changes nothing; the flat-run fields find those tops, and flatLevel is the threshold to pass. masteringRepairAnalyze chooses this threshold for you and withholds declip when a louder unclipped passage would be rewritten.

The positive-count checks are only a starting point. Review the waveform and audition each change; a detector cannot know whether a clipped-looking waveform was intentional.

Listen to a transient-repair A/B ​

A/B PROCESS · DECLICKIDLE
Click repair — compare before and after

The declicker detects short impulsive defects and reconstructs their samples from the surrounding signal. This clip also contains hum, hiss and crackle; this demo runs only declick, so those defects can remain. Compare the original and processed signal without extra loudness matching. Musical attacks can also be affected: inspect the result rather than assuming every detected impulse is damage.

Compare

This A/B uses the real WASM declicker on a damaged vinyl-style clip. It does not inject noise, match loudness, or run declip/decrackle/dehum. The source still contains hum, hiss, crackle, and musical attacks, so use it to hear the local click repair rather than as a promise that every defect is removed.

Preserve a stereo image ​

For stereo, pass both channels to the paired functions. Calling the mono function on each side independently can repair one channel while leaving a matching event in the other channel untouched.

ts
import {
  masteringRepairDeclickStereo,
  masteringRepairDeclipStereo,
  masteringRepairDecrackleStereo,
} from '@libraz/libsonare';

const declipped = masteringRepairDeclipStereo({
  left,
  right,
  sampleRate,
});
const declicked = masteringRepairDeclickStereo({
  left: declipped.left,
  right: declipped.right,
  sampleRate,
});
const decrackled = masteringRepairDecrackleStereo({
  left: declicked.left,
  right: declicked.right,
  sampleRate,
});
console.log(decrackled.leftReport, decrackled.rightReport);

declipStereo takes the union of both channels' clipped runs. A channel with no clipped sample in a union run is left untouched there; each channel still gets its own reconstruction and report. declickStereo repairs a run selected by either channel in both channels, while each fill uses that channel's own samples and LPC model. decrackleStereo processes each channel independently because surface scratches do not form a shared event.

Read the reports ​

The mono calls return only the samples. For these report fields, call the *Stereo form (which returns leftReport and rightReport) or masteringRepairApply.

StageUseful report fieldsInterpretation
DecliplpcReconstructedRuns, interpolatedRuns, repairedSamplesA run longer than 512 samples uses cubic or linear interpolation; LPC options do not change that fallback.
Declickdetected.rejected, repairedRuns, linkedRuns, lpcModelUsedA large rejected count usually means maxClickSamples or neighborRatio is too tight, not that the recording is clean.
DecracklereplacedSamples or shrunkCoefficientsThe detector always uses the median criterion. Wavelet mode removes detail coefficients without declaring each removed sample to be crackle.

The detector and repair use signal-level thresholds, not a promise that every damaged sample can be restored. Clipping discards information; reconstruction estimates the missing shape from nearby samples. Keep the original and compare the result at a controlled playback gain.

In a chain config or override, repair.decrackle.mode takes median (0) or waveletShrinkage (1); any other value is refused with unknown decrackle mode.

A/B PROCESS · DECRACKLEIDLE
Decrackle repair — surface pops before and after

About eighty short pops per second are added to a clean chord. The decrackler replaces samples that deviate from their local median by more than the threshold. At the default 0.4 it leaves most of the pops, and each lower threshold removes more of them. The chord itself is returned unchanged at every setting here. FLOOR shows the high-band reduction in dB.

Compare
Threshold

Settings and accepted ranges ​

Each option has an upper bound. A value above it throws InvalidParameter on every surface, including the named-processor path.

StageOptionDefaultAccepted
Declickthreshold0.8(0, 10]
DeclickneighborRatio4(0, 100]
DeclickmaxClickSamples8[1, 512]; 512 is the longest gap the AR fill solves
DeclicklpcOrder20[0, 2048]
DeclickresidualRatio8(0, 1000]
DeclipclipThreshold0.98(0, 1]
DecliplpcOrder36[0, 2048]
Declipiterations2[1, 8]
DecliplpcBlend0.65[0, 1]
Decracklethreshold0.4(0, 1000]
Decracklelevels4[1, 24]

Declick fills every selected run linearly between its two anchoring samples before any run is solved with the AR model, so the context an AR solve reads never contains a click that has not been repaired yet. Runs that touch or overlap, including those selected by different channels in the stereo form, are joined into one region, because a neighboring click cannot anchor the fill.

The causal stages, decrackle in median mode among them, also run as realtime inserts; declick and declip do not. See Audio Repair Workflow.

Limits and the shared order ​

The complete repair order is declip → declick → decrackle → dehum → denoise → dereverb. Clipping is first because a flat region can hide a click; the remaining impulsive stages run before spectral noise and reverb estimation. The functions here are offline whole-buffer operations (decrackle also exists as a realtime insert) and do not perform LUFS matching. For the broader decision flow, see Audio Repair Workflow, and for exact option types see the JavaScript mastering API.