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.driverandanalysisnodes are a report. They never change a solid, a cut list or a cache key;ww analyze FILEprints the response, the -3 dB point, port air speed and cone excursion, andww packwrites the same intoanalysis.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):
| Function | Arguments | Returns |
|---|---|---|
ac_sealed_fc(fs, vas, vb) | Hz, litres, litres | sealed-box resonance, Hz |
ac_sealed_qtc(qts, vas, vb) | none, litres, litres | sealed-box total Q |
ac_port_length(vb, fb, dv, np) | litres, Hz, mm, count | length of each port, mm, end correction (0.732 d) included |
ac_helmholtz_fb(vb, dv, lv, np) | litres, mm, mm, count | tuning, 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
fidelityobject (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_lengthcannot be derived fromac_port_lengthwhen the net volume depends on the port's own displacement: that is a cycle and a hard error. Keepport_lengthauthored and use the function in an advisory parameter, asexamples/speaker_ported.kdldoes.kind=transmission_lineis not built (not yetdiagnostic), nor are horns, passive radiators and band-pass boxes: this is why the file ispartial.volume=cannot name a metrics volume yet.- The inline
1.2 rend correction in an older file differs from the library's0.732 dby about 1 Hz on a 33 Hz tuning. - A function name is
ac_sealed_fc, neverac.sealed_fc: method calls are refused.
See also#
docs/KDL_AUTHORING.mdsection 18,docs/adr/0037-acoustic-functions-and-analysis.md.project-and-paramsfor 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