/ tutorials / wave-acoustics
Sign in
tutorials / wave-acoustics
wave-acoustics / src / chapters / ch01 / pluck.m
49 lines · 1.9 KBBlameHistoryRaw
1% Modal synthesis of a plucked string.
2%
3% An ideal string of length 1, fixed at both ends and released from rest in
4% the shape of a triangle with its apex at x = beta, moves as
5%
6% u(x, t) = sum_n A_n sin(n pi x) cos(2 pi n f0 t),
7% A_n = 2 sin(n pi beta) / (n^2 pi^2 beta (1 - beta)),
8%
9% which is exact: it is the Fourier sine series of the initial shape, and each
10% term is a standing wave that solves the wave equation on its own. What the
11% listener hears is not u itself but something it drives, and this script
12% offers two choices:
14% 'bridge' the force on the bridge, proportional to the slope u_x(0, t),
15% whose partials fall off like 1/n. This is what an acoustic
16% instrument's body is shaken by, and it sounds bright.
17% 'pickup' the displacement at x = xp, whose partials fall off like 1/n^2
18% and are notched wherever sin(n pi xp) vanishes. This is what a
19% magnetic pickup reports, and it sounds darker.
21% Only partials below fmax are summed. With fmax at the Nyquist frequency the
22% result is the band-limited signal, which is the right thing to play; see the
23% driver for what happens otherwise.
25% T60 sets a loss for listening: each partial decays by 60 dB in
26% T60 / (1 + (f/2000)^2) seconds, so that high partials die first, as they do
27% on a real string. With T60 = Inf the synthesis is lossless and is compared
28% exactly against d'Alembert's solution.
30function y = pluck(t, f0, beta, where, xp, fmax, T60)
31t = t(:);
32y = zeros(size(t));
33nmax = floor(fmax / f0);
34for n = 1:nmax
35 A = 2 * sin(n * pi * beta) / (n ^ 2 * pi ^ 2 * beta * (1 - beta));
36 if strcmp(where, 'bridge')
37 c = n * pi * A;
38 else
39 c = A * sin(n * pi * xp);
40 end
41 f = n * f0;
42 if isinf(T60)
43 y = y + c * cos(2 * pi * f * t);
44 else
45 s = 6.908 * (1 + (f / 2000) ^ 2) / T60;
46 y = y + c * exp(-s * t) .* cos(2 * pi * f * t);
47 end
48end
49end
↑↓ move↵openescclose