Skip to main content

Build Dirac Live target curves from research-grounded base curves and composable transforms.

Project description

curveforge

Build Dirac Live target curves from research-grounded recipes.

Shipped target curves overview

curveforge is a small CLI that turns a YAML recipe into a .targetcurve file ready to load into Dirac Live 2/3. It ships with a curated library of in-room target curves (Harman, Olive-Welti, B&K, Toole, Welti-sub, flat) — each parameterised so you can sweep, compare, and tune them rather than being stuck with whatever shelf level a preset shipped with.

Install

pip install curveforge            # or: uvx curveforge
pip install 'curveforge[plot]'    # adds matplotlib for the `plot` command

Requires Python ≥ 3.11.

Quick start

A recipe is a YAML file describing a base curve, an ordered list of transforms, and where to write the result.

# my-living-room.yml
output:
  path: living-room.targetcurve
  device_name: Living Room
  low_limit_hz: 10
  high_limit_hz: 24000

base:
  type: harman
  params:
    shelf_level: 8

transforms:
  - peq: { freq: 22, gain_db: 4, q: 1.5 }
  - rolloff: { freq: 15, order: 2 }
curveforge build my-living-room.yml
# wrote living-room.targetcurve

Drop the file into Dirac Live → Custom Target Curve → load.

Cookbook

Worked recipes for common situations. Each one builds cleanly with curveforge build <yaml>; the full versions live in gallery/.

Critical listening (Harman +6)

A lean, balanced Harman shelf for accurate mixing-style playback. Light bass weight — the right baseline if you want clarity over physical impact.

Critical listening curve

base:
  type: harman
  params: { shelf_level: 6 }

Cinema / bass-heavy

Harman +10 with the shelf extended into mid-bass (shelf_corner: 150), plus a +4 dB peak at 25 Hz for visceral sub impact. Compensates for the steepening equal-loudness contours at low listening levels.

Cinema curve

base:
  type: harman
  params: { shelf_level: 10, shelf_corner: 150 }
transforms:
  - peq: { freq: 25, gain_db: 4, q: 1.0 }

Classical / vocal-forward (B&K 1974)

Modest bass plateau, smooth 0.83 dB/oct treble taper. Anchored without being bloated; smooth without being dark. The closest thing to a "natural room" target.

B&K curve

base:
  type: b_and_k
  params: { bass_level: 3, bass_corner: 200, treble_slope: -0.83 }

Sub-only calibration

Low-shelf with corner at the sub-to-mains crossover. Use this for independent sub-channel correction in Dirac; set Dirac's HIGHLIMITHZ to match the crossover_hz value.

Sub-only curve

base:
  type: welti_sub
  params: { shelf_level: 8, crossover_hz: 80 }

Comparing curves at a glance

One YAML knob sweeps Harman from lean to cinema — curveforge plot overlays several recipes side-by-side so you can see exactly what each parameter does.

Shelf level comparison

curveforge plot harman-4.yml harman-6.yml harman-8.yml harman-10.yml \
    -o comparison.svg

Case study: real-world iteration

Want to see how to use these tools to actually voice a system? The Triangle BR09 + SVS SB-2000 case study walks through ~10 listening iterations: each one frames a complaint as a frequency band, diagnoses speaker-voicing-vs-room with the Dirac L+R overlay, applies a targeted recipe change, and reflects on what worked. The point isn't to copy the curve — it's to copy the process.

Curves shipped

Name Shape Best for
harman First-order bass shelf, flat treble Music; the community default. shelf_level 4–14 sweeps from lean to cinema.
olive_welti_inroom Bass shelf + downward treble tilt Bright rooms, near-field, or "finished mix" sound.
b_and_k Modest bass plateau + linear treble taper Classical, jazz, vocals. Smooth, natural-room character.
toole_inroom Flat below 500 Hz + gentle tilt above Directionally well-behaved speakers in treated rooms. The "preserve what good speakers do" target.
welti_sub Sub-band low-shelf at the crossover Sub-only calibration runs (mains corrected separately).
flat 0 dB everywhere Baseline before transforms; measurement reference.
breakpoints User-supplied (Hz, dB) pairs Hand-drawn curves; imports from other tools.

curveforge list curves and curveforge info <name> print parameters and citations from the CLI. Detailed background on each curve is in the References section at the bottom.

Transforms shipped

Name What it does
gain Boost or cut a frequency band by a fixed dB, with cosine-tapered edges
peq Parametric peaking EQ (RBJ analog biquad — freq + gain + Q)
shelf First-order low- or high-shelf added on top of the current curve
rolloff Butterworth high-pass attenuation (Nth-order) for sub protection
tilt Linear dB/octave slope across the spectrum, anchored to a chosen Hz

Transforms apply in the order they appear in the recipe.

Python library

from curveforge import build_curve, write_targetcurve

curve = build_curve(
    base="harman",
    base_params={"shelf_level": 8, "shelf_corner": 105},
    transforms=[
        ("peq", {"freq": 25, "gain_db": 4, "q": 1.0}),
        ("rolloff", {"freq": 15, "order": 2}),
    ],
)

write_targetcurve(
    path="living-room.targetcurve",
    curve=curve,
    name="My target",
    device_name="Living Room",
    low_limit_hz=10,
    high_limit_hz=24000,
)

Useful for batch jobs, notebooks, or wrapping curveforge in your own tools.

Other commands

curveforge list curves|transforms|all
curveforge info <curve_or_transform_name>
curveforge validate path/to/file.targetcurve
curveforge diff a.targetcurve b.targetcurve
curveforge render recipe.yml --stdout --format csv
curveforge plot recipe.yml [-o curve.svg]      # needs [plot] extra; format inferred from extension
curveforge plot a.yml b.yml -o overlay.svg     # overlay multiple recipes
curveforge tweak input.targetcurve tweak.yml   # apply transforms to an existing curve

Why this exists

Existing Dirac target-curve resources (the GUI editor, hand-curated target-curve files shared on audio forums) force you to choose between a small set of fixed shapes or hand-edit breakpoints. curveforge gives you the parametric model behind each research target, so you can:

  • Sweep a Harman shelf from +4 to +14 dB by changing one number
  • Layer a sub-bass peak or a protective rolloff on top of any base curve
  • Compare scientific targets at equivalent settings (e.g. Harman vs B&K vs Toole at +6 dB bass)
  • Treat target curves as code: version-controlled, diffable, reproducible

References

Each curve module ships with full citations accessible via curveforge info <name>. The condensed sources:

  • harman — Olive, S. E. & Welti, T. — multiple AES papers on listener preference for in-room loudspeaker response (Harman International). See also Toole, F. E., Sound Reproduction (3rd ed., 2017), Routledge / AES Presents.
  • olive_welti_inroom — Olive, S. E., Welti, T., & McMullin, E. (2013). "Listener Preferences for In-Room Loudspeaker and Headphone Target Responses." AES 135th Convention, paper 8994. (See also paper 8867 at the 134th Convention, which introduces the RR1_G reference curve.)
  • b_and_k — Brüel & Kjær Application Note 17-197 (1974), "Relevant loudspeaker tests in studios, in Hi-Fi dealers' demo rooms, in the home, etc., using 1/3 octave, pink-weighted, random noise."
  • toole_inroom — Toole, F. E. (2017). Sound Reproduction: The Acoustics and Psychoacoustics of Loudspeakers and Rooms (3rd ed.). Routledge / AES Presents.
  • welti_sub — Welti, T. & Devantier, A. (2006). "Low-Frequency Optimization Using Multiple Subwoofers." J. AES 54(5), pp. 347–364. See also Welti, Subwoofers: Optimum Number and Locations (Harman).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

curveforge-0.1.0.post1.tar.gz (187.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

curveforge-0.1.0.post1-py3-none-any.whl (41.0 kB view details)

Uploaded Python 3

File details

Details for the file curveforge-0.1.0.post1.tar.gz.

File metadata

  • Download URL: curveforge-0.1.0.post1.tar.gz
  • Upload date:
  • Size: 187.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for curveforge-0.1.0.post1.tar.gz
Algorithm Hash digest
SHA256 3322ab653d5bab6a18bc3594828d65767b27d883c675c400a5928c4ad0c90741
MD5 708a6b8daf2923e0c980e23894662b17
BLAKE2b-256 43d7ebc743fc97a548de04acd82533820249b48fb0de23d89893c3c8d44515c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for curveforge-0.1.0.post1.tar.gz:

Publisher: release.yml on teolbb/curveforge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file curveforge-0.1.0.post1-py3-none-any.whl.

File metadata

File hashes

Hashes for curveforge-0.1.0.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 658f190c097ec94f14b7d0026230d775c6ab906e6c8905337d1b9ffaf540f965
MD5 1724ce18576b3d98aafb12d800ac6a2f
BLAKE2b-256 0d8e7945b6a8dd6bb24917e3fbaa507c304e71b4ab0b0246c0941d8d85ed6e5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for curveforge-0.1.0.post1-py3-none-any.whl:

Publisher: release.yml on teolbb/curveforge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page