Skip to content

Commit a00a5fe

Browse files
committed
refactor: implement DS201-inspired frequency-conscious gating
Introduces a Drawmer DS201-inspired gate implementation with: - Replaces highpass/bandreject/agate with DS201-based composite filters - Adds DS201HighPass (HP + hum notch) and DS201LowPass for frequency-conscious filtering - Implements DS201Gate with ultra-fast attack (0.5ms) for transient preservation - Adds comprehensive documentation explaining the DS201 design philosophy - Uses soft expander approach rather than hard gating for natural speech transitions This approach provides better gate behavior with frequency-aware noise rejection while preserving natural speech dynamics.
1 parent ebe527f commit a00a5fe

9 files changed

Lines changed: 1269 additions & 795 deletions

File tree

docs/DS201-INSPIRED-GATE.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# DS201-Inspired Frequency-Conscious Gate
2+
3+
This document describes Jivetalking's gate implementation, inspired by the legendary **Drawmer DS201 Dual Noise Gate**—the industry-standard hardware gate since 1982.
4+
5+
## The Drawmer DS201
6+
7+
The DS201 pioneered several innovations that became standard in professional gating:
8+
9+
### Key DS201 Characteristics
10+
11+
| Parameter | DS201 Range | Notes |
12+
|-----------|-------------|-------|
13+
| **Attack** | 10µs – 1 sec | Microsecond-level attack preserves natural transients |
14+
| **Hold** | 2ms – 2 sec | Keeps gate open after signal drops below threshold |
15+
| **Decay** | 2ms – 4 sec | Smooth fade-out rate after hold expires |
16+
| **Threshold** | +20dB to -54dB | Wide range for various signal levels |
17+
| **Range** | Up to 90dB | Full mute capability |
18+
| **HP Filter** | 25Hz – 4kHz | Side-chain high-pass for frequency-conscious gating |
19+
| **LP Filter** | 250Hz – 35kHz | Side-chain low-pass for frequency-conscious gating |
20+
21+
### DS201 Innovations
22+
23+
1. **Frequency-conscious gating** — Variable HP/LP filters on the side-chain allow the gate to respond only to specific frequency ranges, preventing false triggers from bleed or rumble.
24+
25+
2. **Ultra-fast attack** — Opens in microseconds to preserve the natural attack of transients, crucial for drums and percussive speech consonants.
26+
27+
3. **Four-stage envelope** — Attack, Hold, Decay, Range provides precise control over gate behaviour.
28+
29+
4. **Key Listen** — Monitor the filtered side-chain to tune filter settings.
30+
31+
## Jivetalking's DS201-Inspired Implementation
32+
33+
We implement the DS201's philosophy using FFmpeg's filters, with adaptations optimised for spoken word.
34+
35+
### Architecture: Frequency-Conscious Filtering
36+
37+
Rather than side-chain filtering (which FFmpeg doesn't support), we apply frequency filtering to the audio path before gating:
38+
39+
```
40+
DS201HighPass → DS201LowPass → [denoise] → DS201Gate
41+
↓ ↓ ↓
42+
HP + Hum LP filter Soft expander
43+
notch (adaptive) (speech-optimised)
44+
```
45+
46+
This achieves the same goal: the gate sees a frequency-filtered signal, preventing false triggers from:
47+
- **Low-frequency rumble** (handled by high-pass)
48+
- **Mains hum** (handled by notch filters at 50/60Hz harmonics)
49+
- **Ultrasonic noise** (handled by low-pass)
50+
51+
### DS201HighPass: Combined HP + Hum Rejection
52+
53+
Bundles two DS201-inspired filters:
54+
55+
1. **High-pass filter** — Removes subsonic rumble that could hold the gate open
56+
- Adaptive frequency: 60–120Hz based on voice character
57+
- Protects warm voices with gentler slopes and mix blending
58+
59+
2. **Mains hum notch** — Surgical removal of tonal hum
60+
- 50Hz (UK/EU) or 60Hz (US) fundamental
61+
- Up to 4 harmonics with 0.3–2Hz notch width
62+
- Enabled adaptively when silence entropy indicates tonal noise
63+
64+
### DS201LowPass: Ultrasonic Rejection
65+
66+
Removes high-frequency content that could cause false triggers:
67+
68+
- **Adaptive tuning** based on SpectralRolloff:
69+
- Rolloff < 8kHz → disabled (voice already dark)
70+
- Rolloff > 14kHz → enabled at rolloff + 2kHz
71+
- High ZCR + low centroid → possible HF noise, enable at 12kHz
72+
- **Conservative approach** — never cuts below 8kHz to preserve sibilance and air
73+
- **Default: disabled** — only activates when measurements indicate benefit
74+
75+
### DS201Gate: Soft Expander
76+
77+
Here we intentionally depart from the DS201's hard gate behaviour.
78+
79+
#### Why a Soft Expander?
80+
81+
The DS201 offers two modes:
82+
- **Hard gate** — Ultra-fast, clean cut, ideal for drums
83+
- **Soft gate** — Gentler expansion for vocals and mixes
84+
85+
For podcast speech, we exclusively use a soft expander approach:
86+
87+
| Aspect | DS201 Hard Gate | Jivetalking DS201Gate |
88+
|--------|-----------------|----------------------|
89+
| **Ratio** | ∞:1 (complete mute) | 1.5:1 – 2.5:1 (gentle reduction) |
90+
| **Knee** | Sharp | Soft (2–5 dB) |
91+
| **Range** | Up to 90dB | -12dB to -36dB |
92+
| **Character** | Absolute silence | Natural fade |
93+
94+
**Rationale:** Hard gating on speech creates unnatural "pumping" artifacts. A soft expander reduces noise between phrases while maintaining the natural room tone that listeners expect.
95+
96+
#### Adaptive Attack Timing
97+
98+
The DS201's microsecond attack is legendary for preserving transients. We implement adaptive attack based on measured transient characteristics:
99+
100+
| Condition | Attack Time | Use Case |
101+
|-----------|-------------|----------|
102+
| MaxDifference > 40% OR SpectralCrest > 40dB | 0.5ms | Extreme transients (plosives) |
103+
| MaxDifference > 25% OR SpectralCrest > 30dB | 3ms | Sharp consonants |
104+
| MaxDifference > 10% | 7ms | Normal speech |
105+
| Soft delivery | 15ms | Gentle fade-in |
106+
107+
**Measurements used:**
108+
- `MaxDifference` — Sample-to-sample change, catches plosives ("P", "T", "K")
109+
- `SpectralCrest` — Spectral peak-to-RMS ratio, indicates transient energy
110+
- `SpectralFlux` — Frame-to-frame spectral change, biases toward faster attack
111+
112+
#### Hold Compensation
113+
114+
The DS201 has a dedicated Hold parameter; FFmpeg's `agate` does not. We compensate by:
115+
- Adding 50ms to the release time as baseline hold compensation
116+
- Adding 75ms extra for tonal noise (hides pumping artifacts)
117+
- Release range: 150–500ms (vs DS201's 2ms–4s decay)
118+
119+
#### Adaptive Parameters
120+
121+
All gate parameters adapt to Pass 1 measurements:
122+
123+
| Parameter | Adaptation Logic |
124+
|-----------|------------------|
125+
| **Threshold** | Based on noise floor + silence peak, with headroom for noise severity |
126+
| **Ratio** | Based on LRA (wide dynamics → gentle ratio to preserve expression) |
127+
| **Attack** | Based on MaxDifference + SpectralCrest + SpectralFlux |
128+
| **Release** | Based on SpectralFlux + ZCR + noise character |
129+
| **Range** | Based on silence entropy (tonal → gentle, broadband → aggressive) |
130+
| **Knee** | Based on SpectralCrest (dynamic → soft knee) |
131+
| **Detection** | RMS for tonal bleed, peak for clean recordings |
132+
133+
## Comparison Summary
134+
135+
| Feature | DS201 | Jivetalking |
136+
|---------|-------|-------------|
137+
| **Frequency-conscious filtering** | ✅ HP/LP on side-chain | ✅ HP/LP on audio path |
138+
| **Ultra-fast attack** | ✅ 10µs minimum | ✅ 500µs minimum |
139+
| **Hold parameter** | ✅ 2ms–2s | ⚠️ Compensated via release |
140+
| **Hard gate mode** || ❌ (soft expander only) |
141+
| **Soft gate mode** || ✅ (always) |
142+
| **Adaptive parameters** | ❌ (manual) | ✅ (measurement-driven) |
143+
| **Detection modes** | Not specified | ✅ RMS/Peak adaptive |
144+
145+
## References
146+
147+
- [Drawmer DS201 Product Page](https://drawmer.com/products/pro-series/ds201.php)
148+
- [Drawmer DS201 Operator's Manual](https://drawmer.com/uploads/manuals/ds201_operators_manual.pdf)
149+
- FFmpeg [agate filter documentation](https://ffmpeg.org/ffmpeg-filters.html#agate)
150+
- FFmpeg [highpass](https://ffmpeg.org/ffmpeg-filters.html#highpass) / [lowpass](https://ffmpeg.org/ffmpeg-filters.html#lowpass) / [bandreject](https://ffmpeg.org/ffmpeg-filters.html#bandreject) filter documentation

0 commit comments

Comments
 (0)