Skip to content

Commit d6d2aac

Browse files
committed
Add documentation, recipe gallery, and case study
1 parent 06ba25a commit d6d2aac

20 files changed

Lines changed: 24917 additions & 0 deletions

docs/case-studies/triangle-br09.md

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
# Case study — voicing Triangle BR09 + SVS SB-2000 in Dirac Live
2+
3+
> ⚠️ **This curve is tuned for one specific system in one specific room.** Don't
4+
> copy the final YAML expecting it to sound right on your gear. **Copy the
5+
> process, not the curve.** The point of this doc is to show how to iterate
6+
> on a target curve using listening cues and measurements as your guide.
7+
8+
A walk-through of building a personal target curve over roughly ten
9+
listening sessions. Each section is structured as **complaint →
10+
diagnosis → fix → result**, which is approximately how the iteration
11+
actually unfolded.
12+
13+
## The system
14+
15+
| Component | Detail |
16+
|---|---|
17+
| **Mains** | Triangle Borea BR09 (3-way ported floor-stander, 1 × 25 mm silk dome tweeter with horn-flare waveguide + 1 × 16 cm midrange + 3 × 16 cm woofers) |
18+
| **Sub** | SVS SB-2000 (sealed, -3 dB at ~19 Hz anechoic) |
19+
| **Amp / DSP** | NAD C700 v1 with Dirac Live (BluOS) |
20+
| **Crossover** | 80 Hz, 18 dB/oct (NAD bass management) |
21+
| **Room** | Apartment living room, untreated, ~30 m² |
22+
| **Listening** | Moderate-to-loud SPL, mixed music and occasional film |
23+
24+
A few things to know about the BR09: Triangle voices its speakers for
25+
an energetic, forward presentation, with elevated upper-midrange
26+
emphasis — they "want" to sound forward. That matters because Dirac
27+
corrects toward whatever target curve you give it: if the target is
28+
flat in a band where the speaker is intentionally not flat, Dirac
29+
will treat that elevation as a room problem and cut it away, removing
30+
the voicing along with it.
31+
32+
## Starting point: Harman +8 dB
33+
34+
The community default. A first-order low-shelf at +8 dB — the most
35+
common starting point for music-focused Dirac calibrations, derived
36+
from Olive/Welti's Harman International listener-preference research.
37+
38+
![Stage 0 baseline curve](../img/case-study/stage-0-baseline.svg)
39+
40+
```yaml
41+
base:
42+
type: harman
43+
params: { shelf_level: 8 }
44+
```
45+
46+
**What was good**: solid bass weight, neutral mids, easy on the ears.
47+
**What was wrong**: deep bass (below ~30 Hz) felt missing on
48+
bass-heavy modern productions with significant sub-bass content —
49+
the lowest notes were audible but lacked physical impact. And the
50+
speakers felt "smoothed away" — less forward and articulate than they
51+
sound un-corrected.
52+
53+
We tackled the sub-bass shortfall first (clearer fix, less subjective),
54+
then the speaker-character problem (more nuanced).
55+
56+
## Stage 1 — Sub-bass immersion
57+
58+
**Complaint**: "I can hear the sub but the lowest notes don't have
59+
the visceral, physical-pressure quality I expect at this SPL.
60+
Sub-bass content (20–30 Hz) feels recessed."
61+
62+
**Diagnosis**: Harman-8 already plateaus at +8 dB down to 10 Hz, so
63+
the target itself isn't capping the level. The issue is the
64+
[equal-loudness contours](https://en.wikipedia.org/wiki/Equal-loudness_contour):
65+
the contours steepen sharply below ~30 Hz, so a given SPL is
66+
perceived as significantly quieter at 20 Hz than at 50 Hz. To make
67+
the sub-bass band feel proportionate at typical listening levels,
68+
the *target* needs extra energy in the 20–40 Hz band beyond the
69+
shelf — psychoacoustic compensation, not flat reproduction.
70+
71+
**Fix**: A wide PEQ centred at 30 Hz, +2.5 dB with Q 0.9, to lift
72+
the sub-bass band on top of the shelf.
73+
74+
```yaml
75+
transforms:
76+
- peq: { freq: 30, gain_db: 2.5, q: 0.9 }
77+
```
78+
79+
**Result**: sub-bass became physically perceptible on tracks with
80+
deep low-frequency content. The 20–40 Hz region is now the loudest
81+
band on the target — a deliberate over-flat shape that compensates
82+
for the steepening equal-loudness contours at low frequencies. (Not
83+
true isophonic compensation, which would require an SPL-dependent
84+
target; just a bump in the right place at one assumed listening
85+
level.) The fix exposed a secondary issue.
86+
87+
## Stage 2 — Boxiness fix
88+
89+
**Complaint**: "Now the 100 Hz region feels boxy — voices and
90+
upright bass have a 'cardboard tube' quality."
91+
92+
**Diagnosis**: with the sub-bass PEQ added, the 80–150 Hz band ended
93+
up at roughly +5 dB on the target. That's the classic "boxiness"
94+
zone, and the room's modal response was likely piling up there too.
95+
Two ways to address it: cut that band with a surgical `gain`
96+
transform, or tighten the Harman shelf corner so the shelf decays
97+
faster. Surgical band cuts leave non-natural shapes in the curve;
98+
adjusting the shelf corner is cleaner.
99+
100+
**Fix**: move `shelf_corner` from the default 105 Hz down to 85 Hz —
101+
the shelf falls off faster, cutting ~2 dB across the boxiness band.
102+
(Spoiler: 85 turned out to be slightly too tight once the warmth
103+
PEQ was added in Stage 5 — we relaxed it back to 95 in Stage 6.
104+
Iterative tuning.)
105+
106+
```yaml
107+
base:
108+
type: harman
109+
params: { shelf_level: 8, shelf_corner: 85 }
110+
```
111+
112+
**Lesson**: when a complaint maps to a band, the first reflex
113+
shouldn't always be a surgical PEQ. If the underlying shape is wrong,
114+
fix the shape. Surgical EQs leave kinks in the curve; shape
115+
adjustments don't.
116+
117+
![After Stage 2 — sub-bass lift + tighter shelf](../img/case-study/stage-2-cumulative.svg)
118+
119+
## Stage 3 — Sibilance from full-range correction
120+
121+
**Complaint**: "With the curtain at 16 kHz, female vocals and
122+
cymbals have audible sibilance and a harsh, glassy quality."
123+
124+
**Diagnosis**: with the curtain at 16 kHz and a flat target above
125+
400 Hz, Dirac is being asked to make the room measure *flat* all the
126+
way up. In a real listening room the in-room response naturally rolls
127+
off above ~8 kHz (off-axis directivity of the speakers + absorption
128+
by soft furnishings and carpet; atmospheric absorption contributes a
129+
smaller portion). Correcting toward a flat target through that
130+
naturally-rolled-off band lifts the 5–10 kHz region — exactly where
131+
sibilance lives.
132+
133+
**Fix attempts** (this took a few tries):
134+
- Switching to the `olive_welti_inroom` base with a -1 dB/oct tilt
135+
→ too dark; the entire top end was rolled off rather than just
136+
the sibilance band
137+
- A gentler -0.5 dB/oct tilt → still affected the bass (a downward
138+
tilt anchored at 1 kHz lifts everything below the anchor too,
139+
including the bass shelf)
140+
- High-shelf cut at 4 kHz, -2 dB → cleaner, but trimmed too much
141+
of the 4–7 kHz band that gives transients their "snap"
142+
143+
**Final**: high-shelf cut at **7 kHz, -3 dB**. The first-order shelf
144+
has a transition zone, so 4–6 kHz is lightly attenuated (about
145+
-0.6 to -1.0 dB) — enough to leave most of the presence/snap intact;
146+
above 7 kHz the cut deepens toward the full -3 dB, taming the
147+
sibilance band (5–9 kHz) and the lower portion of the air band
148+
(10+ kHz).
149+
150+
```yaml
151+
transforms:
152+
- shelf: { type: high, corner: 7000, gain_db: -3.0 }
153+
```
154+
155+
**Lesson**: a high-shelf is fundamentally different from a tilt.
156+
The shelf only affects frequencies above its corner; the rest of
157+
the curve is left alone. A linear tilt affects everything around
158+
its anchor — useful for overall warming, wrong tool for surgical
159+
treble-only adjustments.
160+
161+
## Stage 4 — Reading the L+R measurement to find speaker voicing
162+
163+
This was the breakthrough. After bass and treble were dialled in,
164+
the BR09s still felt "smoothed away" in the midrange — less forward
165+
and articulate than their natural character.
166+
167+
**Diagnostic move**: in the Dirac measurement view, switch to
168+
**left and right channels overlaid** (instead of the average).
169+
This separates two very different things:
170+
171+
- **Where L and R agree** = the speaker driver's intrinsic response,
172+
baked into the speaker.
173+
- **Where L and R disagree** = the room. Asymmetric placement,
174+
position-dependent modes, single-side reflections.
175+
176+
Looking at the BR09 overlay:
177+
178+
| Band | L+R behaviour | Diagnosis |
179+
|---|---|---|
180+
| 30–80 Hz | L and R diverge by 5–10 dB | Room modes (correct) |
181+
| 100–200 Hz | Some divergence | Mixed speaker + room |
182+
| **200–500 Hz** | **L and R agree, +2 dB above target** | Speaker (warmth region) |
183+
| **800 Hz–1.5 kHz** | **L and R agree, +4–5 dB above target** | Triangle's signature midrange forwardness |
184+
| 2–4 kHz | L and R close, +1–2 dB above target | Speaker (presence) |
185+
| Above 5 kHz | L and R tracking each other | Speaker rolloff + air |
186+
187+
The 200–2000 Hz elevation in both channels is the BR09's
188+
**intentional voicing**. Dirac was cutting it down to flat, removing
189+
the Triangle character entirely.
190+
191+
**Caveat**: L+R agreement isn't conclusive evidence of speaker
192+
voicing on its own. Symmetric room modes (e.g. low-frequency
193+
standing waves between parallel walls) also affect both channels.
194+
The *width and smoothness* of the feature matter as much as the L/R
195+
match: broad, smooth elevations across hundreds of Hz are
196+
characteristic of speaker voicing; sharp single-frequency peaks
197+
typically indicate modes.
198+
199+
**Lesson**: combine L+R overlap with shape — broad+smooth+matched
200+
≈ speaker; narrow+spiky ≈ room. Use this to decide whether to EQ a
201+
peak away or leave it alone.
202+
203+
## Stage 5 — Restoring the Triangle character
204+
205+
Two PEQs to lift the target back toward where the BR09 naturally
206+
plays. Dirac then cuts those measured peaks less, letting the
207+
speaker's voicing come through.
208+
209+
**The character lift** — 1 kHz, +2 dB, Q 0.6 (wide bell, roughly
210+
1.5 octaves):
211+
212+
```yaml
213+
transforms:
214+
- peq: { freq: 1000, gain_db: 2.0, q: 0.6 }
215+
```
216+
217+
This covers 400 Hz – 2.5 kHz with the peak centred at 1 kHz —
218+
matches the broad band where the BR09 naturally elevates the
219+
upper-midrange.
220+
221+
**The warmth lift** — 350 Hz, +1 dB, Q 1.0 (narrower, focused):
222+
223+
```yaml
224+
transforms:
225+
- peq: { freq: 350, gain_db: 1.0, q: 1.0 }
226+
```
227+
228+
Picks up the separate ~300 Hz Triangle warmth bump that the wider
229+
1 kHz PEQ doesn't fully reach.
230+
231+
![After Stage 5 — Triangle character lifts applied](../img/case-study/stage-5-character.svg)
232+
233+
**Result**: the BR09 character returned. Vocals more forward and
234+
present, acoustic guitars more articulate, snare attack more
235+
defined — without losing bass weight or re-introducing sibilance.
236+
237+
**Lesson**: if your speakers were chosen partly for their tonal
238+
character, don't let Dirac flatten that character away. Lift the
239+
target where the speaker naturally rises so Dirac cuts less there.
240+
241+
## Stage 6 — Restoring equilibrium
242+
243+
**Complaint**: "Adding the warmth PEQ at 350 Hz makes the curve
244+
feel disconnected — there's a gap between the bass shelf and the
245+
warmth lift."
246+
247+
**Diagnosis**: back in Stage 2 we tightened `shelf_corner` from
248+
105 Hz to 85 Hz to reduce boxiness. With the new warmth PEQ adding
249+
energy in 250–500 Hz, the over-tight shelf created a **valley** at
250+
around 150–200 Hz between the bass shelf and the warmth band. The
251+
curve fell into a hole, then climbed back out — visually weird, and
252+
audible as a disconnect between the bass region and the warmth.
253+
254+
**Fix**: loosen `shelf_corner` from 85 to **95** — a compromise
255+
between the default 105 and the over-tight 85. Lifts 100–200 Hz
256+
by ~1 dB so the bass shelf flows continuously into the warmth band.
257+
258+
```yaml
259+
base:
260+
type: harman
261+
params: { shelf_level: 8, shelf_corner: 95 }
262+
```
263+
264+
**Lesson**: every parameter interacts with every other parameter.
265+
A fix that solves a problem in isolation can create one elsewhere.
266+
Always re-check the *shape* after adding a new transform.
267+
268+
## The final curve
269+
270+
![Final voicing recipe](../img/case-study/final-curve.svg)
271+
272+
```yaml
273+
name: Living room (Triangle BR09 voicing)
274+
output:
275+
path: living-room.targetcurve
276+
device_name: Living Room
277+
low_limit_hz: 10
278+
high_limit_hz: 24000
279+
280+
base:
281+
type: harman
282+
params:
283+
shelf_level: 8
284+
shelf_corner: 95 # Stage 2 + 6: tightened from 105 → 85, then relaxed → 95
285+
286+
transforms:
287+
# Stage 1: sub-bass immersion bump (equal-loudness compensation)
288+
- peq: { freq: 30, gain_db: 2.5, q: 0.9 }
289+
290+
# Stage 5: Triangle warmth region (~300 Hz)
291+
- peq: { freq: 350, gain_db: 1.0, q: 1.0 }
292+
293+
# Stage 5: Triangle character lift — preserve the speaker's natural
294+
# upper-midrange forwardness rather than flattening it
295+
- peq: { freq: 1000, gain_db: 2.0, q: 0.6 }
296+
297+
# Stage 3: high-shelf cut to tame sibilance and air-band harshness
298+
- shelf: { type: high, corner: 7000, gain_db: -3.0 }
299+
300+
breakpoints:
301+
resolution: third_octave
302+
freq_range: [10, 20000]
303+
```
304+
305+
## The journey, one chart
306+
307+
![Progression overlay](../img/case-study/progression.svg)
308+
309+
Stage 0 has the plateau at +8 dB; the Stage 2 snapshot adds the
310+
+2.5 dB lift at 30 Hz (Stage 1) and tightens the bass shelf for
311+
boxiness (Stage 2); the final adds the Triangle warmth and character
312+
lifts (Stage 5) and the air-band high-shelf cut (Stage 3). Each step
313+
is small; the cumulative effect is decisive.
314+
315+
## What I'd do differently
316+
317+
- **Read the L+R overlay sooner**. I spent several iterations
318+
guessing at "is this voicing or is this the room?" before
319+
switching to the per-channel view. That single diagnostic is
320+
much faster than iterating blind.
321+
- **Use a high-shelf, not a tilt, for treble-only adjustments.**
322+
I initially reached for a downward tilt to tame HF harshness,
323+
thinking it was a "treble-only" tool. It isn't: a downward tilt
324+
anchored at 1 kHz also lifts everything below 1 kHz, which
325+
re-bloated the bass. A high-shelf only affects above its corner,
326+
so the rest of the curve stays untouched.
327+
- **Adjust shelves before reaching for PEQs**. When the warmth
328+
band felt off, the first reflex was to add another PEQ.
329+
Adjusting `shelf_corner` by 10 Hz was the cleaner move and
330+
didn't introduce a new transform.
331+
332+
## What's transferable
333+
334+
For *your* system, the process — not the curve — is the gift:
335+
336+
1. **Start with a known-good baseline** (Harman-8 is fine).
337+
2. **Listen on real music with sub-bass content**. Identify the
338+
biggest single complaint and frame it as a frequency band:
339+
- "Lacks impact" → 20–40 Hz
340+
- "Boxy" → 80–250 Hz
341+
- "Hollow" / "thin" → 200–500 Hz
342+
- "Sibilant" → 5–9 kHz
343+
- "Dull" → 10+ kHz
344+
- "Vocals smoothed away" → 200–2000 Hz
345+
3. **Use the L+R overlay** in Dirac before adjusting anything. If
346+
a peak appears in both channels at the same frequency, it's
347+
most likely speaker voicing — don't EQ it away.
348+
4. **Prefer shape adjustments over surgical EQ** when possible.
349+
Adjust the base curve's shelf or tilt parameters first; only
350+
reach for a PEQ when a surgical bump is truly needed.
351+
5. **Reload, listen, repeat**. Each `curveforge build` takes a
352+
few seconds; you can iterate dozens of times in an evening.
353+
6. **Keep the recipe in version control**. Diffing two YAML
354+
versions tells you exactly what changed between two listening
355+
states.
356+
357+
## Disclaimer (again)
358+
359+
The final YAML at the top of this doc will probably sound *wrong*
360+
on your system if your speakers aren't Triangle BR09s, your sub
361+
isn't an SB-2000, your room isn't a similar size and untreated, or
362+
your listening level isn't moderate-to-loud. The shape changes
363+
were targeted at a specific speaker's voicing and a specific
364+
room's modes. Use the methodology to find your own.

0 commit comments

Comments
 (0)