New Project

Speaker Analysis#

Loudspeaker enclosure functions (ac_) and the report-only analysis node*

Names: driver analysis ac_sealed_fc ac_sealed_qtc ac_port_length ac_helmholtz_fb fs qts vas sd xmax re sensitivity_db tolerance drive_watts port_diameter ports tuning range points

When to use#

You are modelling a speaker cabinet and want its tuning or its response to follow the box. Two separate things:

  • ac_* functions are CEL builtins. They run before geometry, so a result may feed a dimension: a port length for a target tuning, the Fc of a sealed box.
  • driver and analysis nodes are a report. They never change a solid, a cut list or a cache key; ww analyze FILE prints the response, the -3 dB point, port air speed and cone excursion, and ww pack writes the same into analysis.json.

Units are fixed and never written next to the number: volumes in litres, frequencies in Hz, port lengths and diameters in mm. A bare number elsewhere in the file is still millimetres, so a volume in a litre argument is the one place to check twice.

Syntax#

Functions (every argument finite and positive; np a whole number 1 to 16):

FunctionArgumentsReturns
ac_sealed_fc(fs, vas, vb)Hz, litres, litressealed-box resonance, Hz
ac_sealed_qtc(qts, vas, vb)none, litres, litressealed-box total Q
ac_port_length(vb, fb, dv, np)litres, Hz, mm, countlength of each port, mm, end correction (0.732 d) included
ac_helmholtz_fb(vb, dv, lv, np)litres, mm, mm, counttuning, Hz

driver Name { ... } (top level; values are children, a number or a CEL expression): fs Hz, qts, vas litres, sd cm2, xmax mm, re ohms, sensitivity_db dB at 1 W 1 m, tolerance a fraction 0 to under 1 (default none). There is no unit=.

analysis Name kind=sealed|ported driver=Name volume=<litres> [drive_watts=W] { range LO HI; points N }. kind=ported also needs port_diameter= (mm) and exactly one of port_length= (mm, reports the tuning it makes) or tuning= (Hz, reports the length it needs), plus optional ports= (count, default 1). points is at most 512 (default 256); more is an error, not clamped. range defaults to 20 to 2000 Hz.

Example#

project name="Sealed monitor" units=mm schema_version=1 {
    params {
        net_litres 20.0 min=5.0 max=80.0 step=1.0 label="Net volume" category="Acoustics"
        qtc "ac_sealed_qtc(0.35, 45.0, net_litres)"
    }
    materials {
        material mdf type=sheet
    }
    driver Woofer {
        fs 32.0
        qts 0.35
        vas 45.0
        sd 132.0
        xmax 6.0
        re 5.5
        sensitivity_db 88.0
        tolerance 0.15
    }
    analysis Response kind=sealed driver=Woofer volume=net_litres {
        range 20.0 2000.0
        points 128
    }
    component Panel role=side {
        stock mdf 300.0 400.0 18.0
    }
    assembly Root {
        part Side instance=Panel {
            by top_sw
            pos x=0.0 y=0.0 z=0.0
        }
    }
}

Pitfalls and diagnostics#

  • It is an estimate. Every report has a fidelity object (grade: "estimate") listing what is modelled and not: baffle step, diffraction, room, port compression, cabinet resonances, crossover, and leakage beyond an assumed Ql of 7. Say so when you quote a figure. The tolerance band is the min and max over the 2^3 corners of fs, qts and vas.
  • f3 is the half-power point, -3.0103 dB, not -3 dB.
  • port_length cannot be derived from ac_port_length when the net volume depends on the port's own displacement: that is a cycle and a hard error. Keep port_length authored and use the function in an advisory parameter, as examples/speaker_ported.kdl does.
  • kind=transmission_line is not built (not yet diagnostic), nor are horns, passive radiators and band-pass boxes: this is why the file is partial. volume= cannot name a metrics volume yet.
  • The inline 1.2 r end correction in an older file differs from the library's 0.732 d by about 1 Hz on a 33 Hz tuning.
  • A function name is ac_sealed_fc, never ac.sealed_fc: method calls are refused.

See also#

  • docs/KDL_AUTHORING.md section 18, docs/adr/0037-acoustic-functions-and-analysis.md.
  • project-and-params for CEL and the function table.
  • examples/speaker_sealed.kdl, examples/speaker_ported.kdl.

Names#

Every name this page declares, how the example library uses it, and the shortest real use.

driver#

project-level node, word-valued property; node in 2 of 116 examples (2 uses); property in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

driver Woofer {
    fs   "driver_fs"
    qts  "driver_qts"
    vas  "driver_vas"
    sd   132.0           // cm^2: a 6.5 in cone's effective piston area
    xmax 6.0             // mm, one-way linear excursion
    re   5.5             // ohms, DC resistance
    sensitivity_db 88.0  // dB SPL, 1 W / 1 m
    tolerance 0.15       // +/-15 % on Fs, Qts and Vas
}

analysis#

project-level node; node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_sealed.kdl:

analysis Response kind=sealed driver=Woofer volume=vb_net_liters drive_watts=5.0 {
    range 20.0 2000.0
    points 256
}

ac_sealed_fc#

expression function; not used by any example yet.

ac_sealed_qtc#

expression function; not used by any example yet.

ac_port_length#

expression function; not used by any example yet.

ac_helmholtz_fb#

expression function; not used by any example yet.

fs#

node in 4 of 116 examples (4 uses).

Shortest real use, from speaker_ported.kdl:

fs   "driver_fs"

qts#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

qts  "driver_qts"

vas#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

vas  "driver_vas"

sd#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

sd   132.0

xmax#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

xmax 6.0

re#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

re   5.5

sensitivity_db#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

sensitivity_db 88.0

tolerance#

property; node in 2 of 116 examples (2 uses); property in 3 of 116 examples (36 uses).

Shortest real use, from speaker_ported.kdl:

tolerance 0.15

drive_watts#

property; property in 2 of 116 examples (2 uses).

Shortest real use, from speaker_sealed.kdl:

analysis Response kind=sealed driver=Woofer volume=vb_net_liters drive_watts=5.0 {
    range 20.0 2000.0
    points 256
}

port_diameter#

property; property in 1 of 116 examples (1 uses).

Shortest real use, from speaker_ported.kdl:

analysis Response kind=ported driver=Woofer volume=vb_net_liters \
    port_diameter="2.0 * port_radius" port_length=port_length drive_watts=5.0 {
    range 15.0 2000.0
    points 256
}

ports#

not used by any example yet.

tuning#

not used by any example yet.

range#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

range 15.0 2000.0

points#

node in 2 of 116 examples (2 uses).

Shortest real use, from speaker_ported.kdl:

points 256

Settings

Region

A region picks sensible defaults; change any of these separately.

Units

In inches, type lengths the way you say them: 34 1/2, 3/4", 1'-2" or 12.7mm. A length that can't be read is flagged, never rounded to something else.

Paper
Date order
Clock