0e92d35Pizzicato standup bass: coupled string-body modal model, numbl MATLAB reference, and interactive web appJeremy Magland 1function body = bass_body(P)
2% BASS_BODY The parameterized modal body seen at the bridge.
3%
4% This is the empirical part of the model: the corpus of a double bass is
5% not solved from plates and ribs here, it is a table of measured-plausible
6% resonances, each reduced to what the string and the listener can see of
7% it. Per mode: the frequency, the Q, the effective mass at the bridge foot
8% (which sets the admittance the string is loaded by), the radiating area
9% (the net volume the body displaces per unit bridge displacement in that
10% mode), and whether it radiates as a monopole or a dipole. The first row
11% is A0, the f-hole Helmholtz resonance: the one mode that moves net volume
12% through the f-holes and therefore the one monopole; every corpus mode
13% above it displaces the top plate against the surrounding air with no net
14% flow and radiates as a dipole across the body. The table follows the
15% published admittance and radiativity measurements of orchestral basses in
16% shape (A0 near 60 Hz, the main wood resonances between 90 and 250 Hz, a
17% falling effective area above), with the absolute levels set by the trims
18% in bass_defaults.m. Modes above the table are NOT ignored: their
19% collective resistive load enters as residual_y in bass_basis.m and their
20% radiation as the direct term in bass_radiate.m.
21%
22% Mass-normalized amplitude at the bridge: a_j = sqrt(bridge_mobility/m_j),
23% so bridge_mobility scales the whole admittance without retuning the table.
25fb = [60.0 97.0 113.0 135.0 167.0 205.0 252.0 310.0 382.0 470.0 578.0 711.0];
26Qb = [25.0 28.0 30.0 30.0 28.0 26.0 24.0 22.0 20.0 19.0 18.0 17.0];
27mb = [2.2 1.6 1.3 1.1 0.95 0.85 0.80 0.80 0.85 0.95 1.1 1.3]; % kg at the bridge
28Sb = [0.040 0.032 0.028 0.024 0.020 0.016 0.013 0.011 0.009 0.0075 0.006 0.005]; % m^2
29mono = [1 0 0 0 0 0 0 0 0 0 0 0];
31nb = length(fb);
32f = reshape(fb, nb, 1);
33f(1) = P.a0_hz;
34f(2:nb) = f(2:nb) * P.body_trim;
36body.n = nb;
37body.f = f;
38body.omega = 2 * pi * f;
39body.zeta = reshape(0.5 ./ (Qb * P.body_q_scale), nb, 1);
40body.a = reshape(sqrt(P.bridge_mobility ./ mb), nb, 1); % 1/sqrt(kg)
41body.S = reshape(Sb * P.rad_area_scale, nb, 1); % m^2
42body.mono = reshape(mono, nb, 1);
43end