Fast Chunk Distortion — v1.11 User Guide

Fixed-size chunk processing with ten transformation modes, synchronized stereo structure, raised-cosine overlap-add, dry/wet mixing, and diagnostic visualization.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 1.11 (2026) License: MIT License Repo: GitHub
Contents:

What this does

Fast Chunk Distortion divides one selected Sound into fixed-duration time chunks and applies one of ten transformations: Stutter, Gaps, Reverse, Shuffle, Time Stretch, Time Compress, Pumping, Ring Modulator, Bitcrush, or Tremolo. Despite the legacy script filename, the processor does not detect wavesets or zero crossings; segmentation is based on a fixed time grid.

Chunks are assembled with Praat's Concatenate with overlap. The join is a raised-cosine complementary-power crossfade: the two amplitude weights sum to one through the overlap. It is not an equal-power crossfade, and it is not a pair of independent Hann fades to silence.

Current v1.11 behavior:
  • Exactly one Sound is required.
  • Stereo input keeps its real left and right channels. Mono input becomes a synthetic stereo pair; inputs with more than two channels are downmixed to mono first and then rendered to stereo.
  • Left and right use the same chunk grid and the same structural decisions, including repeat count, gap period, shuffle order, and varispeed factor.
  • Stereo_spread creates width without changing the structural timing between channels.
  • Dry/wet mixing pads the shorter side with silence instead of deleting the longer tail.
  • The final output is always stereo and is named <source>_FCD_<PresetName>.

Quick start

  1. In Praat, select exactly one Sound object.
  2. Run Fast_Waveset_Distortion.praat (the form itself is titled Fast Chunk Distortion v1.11).
  3. Choose a preset or leave Custom and select one of the ten modes.
  4. Set Amount, Chunk_ms, Fade_ms, Stereo_spread, and Mix.
  5. Choose whether to normalize, visualize, and play the result.
Important: Amount has a different mathematical meaning in each mode. The preset values below are useful starting points, but there is no single global "effect strength" interpretation.

The 10 presets (+ Custom)

PresetModeAmountChunkFadeSpreadWhat it configures
Glitch StutterStutter4.030 ms3 ms0.30Four repeats per source chunk, with repeat decay.
Rhythmic GapsGaps3.050 ms5 ms0.10Every third chunk is silenced.
Backwards ChunksReverse1.080 ms8 ms0.15Each chunk is reversed while chunk order is retained.
Random ShuffleShuffle1.060 ms6 ms0.25One random chunk permutation, shared by L and R.
Slow MotionTime Stretch4.0100 ms10 ms0.10Varispeed factor 2.0: chunks become longer and pitch drops.
Fast ForwardTime Compress3.050 ms5 ms0.10Varispeed factor 1.5: chunks become shorter and pitch rises.
Alternating PumpPumping4.0125 ms10 ms0.05Alternating high/low chunk gain; no sidechain detector is used.
Robot VoiceRing Modulator2.520 ms2 ms0.40Carrier request 250 Hz before Nyquist clamping.
Lo-Fi CrushBitcrush4.030 ms3 ms0.204 quantization steps per polarity (approximately 9 possible values including zero).
Wobble TremoloTremolo5.040 ms5 ms0.3017 Hz requested modulation rate with 0.75 depth, before Nyquist clamping.

Presets overwrite the mode and the listed processing parameters. Mix, Normalize_output, Show_visualization, and Play_result retain the values entered in the form.

Operation modes (10)

ModeAmount mappingImplemented operation
1. StutterR = clamp(round(amount), 2, 8)Each source chunk is copied R times. Repeat r is multiplied by 0.85^(r-1); the first repeat stays at unity.
2. GapsN = max(2, round(amount))Every Nth chunk is replaced by silence.
3. ReverseIgnoredEach chunk is reversed in time; the original chunk order is retained.
4. ShuffleIgnoredChunks are reordered by an ascending Fisher-Yates shuffle. The same random order is reused for L and R. No random seed is exposed.
5. Time Stretchfactor = max(1.1, amount/2)Varispeed stretch: resample to sr × factor, then override the sampling frequency back to the original rate. Duration increases and pitch falls. v1.11 clamps the effective factor if the intermediate rate would exceed 192 kHz.
6. Time Compressfactor = max(1.1, amount/2)Varispeed compression: resample to sr / factor, then override back to the original rate. Duration decreases and pitch rises. If the intermediate rate would fall below 100 Hz, that chunk is left uncompressed.
7. Pumpinggain_hi = max(0.05, 1 + (abs(amount)-1)×0.5); gain_lo = 1/gain_hiOdd chunks use gain_hi; even chunks use gain_lo. This is alternating gain, not sidechain compression.
8. Ring Modulatorf = clamp(50 + amount×80, 0, Nyquist)Each chunk is multiplied by sin(2πfx + phase). The right channel receives the spread-derived phase offset.
9. BitcrushL = max(2, round(16/abs(amount))); amount 0 uses 0.01round(sample × L) / L. L is steps per polarity, giving roughly 2L+1 possible values across negative, zero, and positive amplitudes.
10. Tremolof = clamp(2 + amount×3, 0, Nyquist); depth = clamp(amount×0.15, 0, 0.9)sample × [1 − depth × (0.5 + 0.5 sin(2πfx + phase))]. The right channel receives the spread-derived phase offset.

Parameters & validation

ParameterDefaultBehavior
PresetCustomLoads one of the ten preset configurations above.
ModeStutterSelects one of the ten processing branches.
Amount3.0Mode-dependent; see the mode table. Time Stretch may reduce the effective Amount to stay under the 192 kHz intermediate-rate ceiling.
Chunk_ms40 msBase source-chunk size. It is floored to at least two samples and may be raised automatically to keep the temporary-object count bounded.
Fade_ms5 msRequested overlap duration. Negative values become 0. It is first reduced to fit the effective base chunk and can be reduced again to at most 40% of the shortest member in the assembled sequence.
Stereo_spread0.2Clamped to −0.95…1.0. Controls right-channel gain offset, pre-delay, and Ring Mod/Tremolo phase offset; it does not change the L/R chunk grid or structural mode decisions.
Mix1.0Clamped to 0…1. Formula: wet×Mix + dry×(1−Mix).
Normalize_outputOnIf the final output is non-silent, Scale peak: 0.95 is applied. This can amplify or attenuate. Silent output is left unchanged.
Show_visualizationOnDraws the v1.11 diagnostic figure.
Play_resultOnPlays the final Sound after processing.
Trailing remainder rule: the initial chunk count is ceiling(duration / chunk_size). If the final remainder is shorter than half a base chunk, that remainder is absorbed into the preceding final chunk. The visualization uses the same rule.

Stereo processing

The output is always stereo, but input handling depends on channel count:

L and R share the same chunk grid, Stutter repeat count, Gaps period, Shuffle permutation, and Stretch/Compress factor. The right channel then receives:

phase_offset_R = Stereo_spread × π × 0.5 gain_R = 1 + Stereo_spread × 0.15 predelay_R = |Stereo_spread| × 0.004 seconds

The phase offset is used only by Ring Modulator and Tremolo. The gain offset and short pre-delay apply to every mode. The pre-delay is silence-padded: silence is added before R and an equal-duration silence tail is added after L, so the width mechanism does not intentionally discard content.

Spread = 0 means no added phase offset, gain offset, or pre-delay. For mono input this makes the two processed channels identical; for true stereo input it does not collapse the original stereo program to mono.

Chunk assembly, overlap, and duration

After the mode-specific transformation, the complete ordered sequence is selected and assembled in one operation. If the effective overlap is greater than zero, the script calls Concatenate with overlap; otherwise it uses ordinary Concatenate.

The effective overlap is:

effective_overlap = min(requested Fade_ms, 0.4 × shortest member duration)

If that second limit reduces the requested fade, the reduction is written to the Info window separately for L and R.

Output duration is not generally equal to input duration. Every overlap shortens the assembled sequence by the overlap duration at each boundary. Stutter and Stretch can still lengthen the result overall; Compress can shorten it more strongly. Even nominally duration-preserving modes such as Reverse, Bitcrush, or Tremolo become slightly shorter when overlap is non-zero.

Dry/wet length handling

When Mix < 1, the script does not trim the longer side to the shorter one. It pads whichever of dry or wet is shorter with trailing silence to the longer duration, reconciles any remaining one-sample mismatch, and then applies the mix formula. Consequently, Mix = 0 returns the dry program content, but if the wet path is longer it may be followed by silence out to the wet duration.

Visualization (Praat Picture)

When Show_visualization is enabled, v1.11 draws the following diagnostic layout:

Panel A and Panel D use their own amplitude scales; only the zoom overlay directly compares source and both output channels on a common vertical scale.

Limits & interpretation