Chaos Distortion — User Guide
A configurable multi-stage lo-fi processor combining drive, reflection-pass wave folding, two quantizer designs, two rate-reduction methods, positionable noise, and an explicit output-level stage.
What this does
Chaos Distortion processes one selected Sound through a serial degradation chain. The fixed backbone is Drive → Fold → Bit Crush → Rate Reduction; optional uniform noise can be inserted before the bit crusher, before rate reduction, or after the other processing. A final output-level stage can preserve the rendered level, attenuate only when the peak exceeds 0.9, or normalize the peak to 0.9.
The script preserves the input duration and channel structure. Stereo and multichannel Sounds are not converted to mono. The processed object is named <source>_chaos_<preset>.
Key features:
- Five named presets plus Custom.
- Two fold algorithms: one reflection per pass, or the v0.2 two-reflection legacy behavior.
- Two quantizers: the legacy unbounded step quantizer or a true
2^N-level quantizer over −1…+1. - Anti-aliased band-limiting or alias-producing sample & hold.
- Positionable uniform noise with optional reproducible random seed.
- Three explicit output-level modes.
- Suite-standard visualization showing the deterministic transfer, the actual processing order, a 50 ms comparison, the output waveform, and summary statistics.
Quick start
- Select exactly one Sound in Praat.
- Run
Chaos_Distortion.praat. - Choose a preset or Custom.
- Choose the fold algorithm, quantizer, rate-reduction method, noise position/seed, and output-level mode.
- Run the script. The Info window reports the resolved settings, including the effective sample rate used by the rate-reduction stage.
Fold_algorithm, Quantizer, Rate_reduction, Noise_position, Random_seed, or Output_level. The same named preset can therefore sound different when those mode choices change.
Processing pipeline
Noise is added at one of the three selected positions, not at all three. Its position matters: noise placed before the crusher is itself quantized; noise placed before band-limited rate reduction is filtered by that stage; noise added last remains full-rate and full-resolution.
Parameters & presets
Form parameters
| Parameter | Default | Meaning |
|---|---|---|
| Preset | Default (balanced) | Five named presets plus Custom. |
| Drive | 3.0 | Positive pre-gain applied before folding. |
| Fold_count | 3 | Integer number of reflection passes. 0 disables folding; negative values are rejected. |
| Fold_threshold | 0.7 | Positive amplitude threshold used by each reflection pass. |
| Fold_algorithm | Single reflection per pass | One sign branch per pass, or the v0.2 legacy double-reflection behavior. |
| Bit_crush | 6 | Natural-number resolution parameter; higher values give finer quantization. Exact mapping depends on Quantizer. |
| Quantizer | Step 1/2^N, unbounded | Legacy step quantizer or true 2^N levels over −1…+1. |
| Sample_rate_percent | 30 | Requested percentage of the original sample rate. Values above 100 are treated as 100%; effective rates below 1000 Hz are floored at 1000 Hz. |
| Rate_reduction | Band-limit | Anti-aliased resampling or sample & hold with true aliasing. |
| Add_noise | Yes | Enable uniform random noise. |
| Noise_amount | 0.03 | Noise is drawn independently in [−amount,+amount]. |
| Noise_position | After processing | Before bit crush, before rate reduction, or after processing. |
| Random_seed | 0 | 0 = unpredictable; positive = reproducible noise realization. |
| Output_level | Normalize to 0.9 | Preserve; attenuate only if peak > 0.9; or normalize to 0.9. |
| Draw_visualization | Yes | Draw the diagnostic page. |
| Play_result | Yes | Play the processed Sound after rendering. |
Named presets
| Preset | Drive | Folds | Threshold | Bits | SR request | Noise |
|---|---|---|---|---|---|---|
| Default (balanced) | 3.0 | 3 | 0.7 | 6 | 30% | On, 0.03 |
| Gentle Grit | 1.6 | 1 | 0.7 | 8 | 85% | Off |
| Heavy Crush | 4.5 | 5 | 0.7 | 4 | 40% | On, 0.05 |
| Lo-Fi Glitch | 2.2 | 2 | 0.7 | 3 | 20% | On, 0.04 |
| Mild Boost/Crush | 1.25 | 0 | 0.7 | 12 | 100% | Off |
Algorithm details
Drive and reflection-pass folding
Drive is a simple multiplication. It does not clip by itself. Folding is then applied for Fold_count passes. This is not an infinite or periodic triangular wavefolder: with high Drive and too few passes, a sample can finish outside ±Fold_threshold.
For the transfer visualization, the first fold starts when the input magnitude reaches approximately T / Drive. The graph therefore marks vertical first-fold input thresholds at ±Fold_threshold/Drive.
Bit crushing: two mappings
round(x × 2^N) / 2^NThis sets a quantization step of
1/2^N but does not clamp the signal. Across −1…+1 it produces 2×2^N+1 possible values, not 2^N; values outside that range remain possible.First clamps to −1…+1, then maps that interval to exactly
2^N uniformly spaced levels.This behaves more like a conventional fixed-range N-bit amplitude quantizer.
Rate reduction
The Sound is resampled down with Praat precision 50 and then back to the original sampling frequency. Anti-alias filtering removes content above the new Nyquist frequency. This produces bandwidth reduction, not intentional alias folding.
The script repeats each block leader for an integer number of samples. The achievable rate is therefore
sr/N for whole-number N. The Info window reports the nearest actual rate and warns when it differs materially from the requested percentage.The requested reduced rate is never allowed below 1000 Hz. If the requested percentage is 100% or higher, the stage is off. For sample & hold, the percentage displayed in the report and visualization is the effective percentage after resolving the integer hold factor.
Noise and random seed
When enabled, the script adds independent uniform random values from −Noise_amount to +Noise_amount to each sample. Random_seed = 0 initializes unpredictably; a positive seed reproduces the same random sequence. After a seeded render, the script restores the generator to an unpredictable state so it does not determine later random operations in the Praat session.
Output level
- Preserve: no peak scaling. If the peak exceeds 1.0, the Info window warns that playback/export may clip.
- Attenuate to 0.9 only if peak > 0.9: global peak scaling is applied only when needed. This is attenuation, not a dynamic limiter.
- Normalize to 0.9: scales any non-silent render to peak 0.9. If the rendered peak is zero, normalization is skipped safely and the output remains silent.
Visualization
The optional 8-inch diagnostic page contains five components:
- Transfer (drive + fold + crush): deterministic static mapping for these three stages only. It follows the selected fold algorithm and quantizer, and marks the first-fold input thresholds. It does not include noise, rate reduction, or the final output-level scaling.
- Processing chain: five boxes whose order reflects the selected Noise position. Disabled Fold or SR stages are shown as off.
- 50 ms zoom: overlays original Ch 1 in gray and processed Ch 1 in orange, making quantization and time-stepping changes easier to see.
- Output waveform: mono output directly, or Ch 1 and Ch 2 for multichannel output. For more than two channels the title states that only Ch 1–2 are shown and that all channels are preserved.
- Summary strip: preset, Drive, Fold count, quantizer description, effective SR, Noise setting, output-level state, duration, and final peak.
Notes & limitations
- The effect is offline and destructive only in the sense that the new Sound contains the processed samples; the original selected Sound remains unchanged because the script processes a copy.
- There is no wet/dry control.
- There is no oversampling around the nonlinear Drive/Fold/quantization stages. Those stages can create high-frequency components that may alias at the original sampling rate.
- Band-limit mode intentionally suppresses aliases during rate reduction; choose Sample & hold when aliasing from temporal decimation is the desired effect.
Fold_count = 0disables folding only. Drive and the later stages still operate.- A high
Bit_crushvalue is finer, but the legacy quantizer is not equivalent to a conventional signed PCM word length because it is an unbounded step mapping. - Named presets do not lock the secondary algorithm choices; document those choices when reproducibility matters.
- For noise-based renders, use a positive Random seed when exact repeatability is required.
Applications
Gentle Grit with Band-limit mode for reduced bandwidth and quantization without deliberate sample-rate aliasing.
Heavy Crush or Lo-Fi Glitch with low-bit quantization and Sample & hold for stepped, aliased textures.
Place noise before Bit Crush or before Rate Reduction so the noise itself is quantized or rate-reduced.
Keep Noise position After processing when the noise should sit above the degraded signal rather than pass through the degradation stages.