Chapter 27
22 min read
Section 232 of 353

Applications: Musical Instruments

The Wave Equation

Learning Objectives

By the end of this section, you will be able to:

  1. Derive the formula fn=n2LT/μf_n = \frac{n}{2L}\sqrt{T/\mu} for the natural frequencies of a vibrating string directly from the 1D wave equation
  2. Predict how a guitarist's fingers, a violinist's bow pressure, and a piano tuner's wrench each change pitch
  3. Distinguish open–open and closed–open pipe modes and explain why a clarinet plays an octave lower than a flute of the same length
  4. Compute drum-head frequencies using Bessel-function zeros and prove that drums are inharmonic
  5. Relate Fourier coefficients of the pluck shape to the timbre (the "color") of an instrument's sound
  6. Implement all three instrument families in plain Python, then use PyTorch's autograd to solve the inverse problem: what tension produces a given pitch?

The Big Picture: How Music Lives Inside the Wave Equation

"Every musical instrument is a boundary-value problem with a pretty face. The boundary conditions decide the scale; the shape decides the timbre."

For the last five sections we have built a deep theory of waves — the wave equation utt=c22uu_{tt} = c^2 \nabla^2 u, d'Alembert's traveling-wave solution, separation of variables for standing waves, Bessel functions for circular geometry, finite-difference schemes for numerical experiments. We have been climbing a tall ladder. This section is the view from the top.

Everything you have heard in your life — every guitar, every flute, every drum, the sound of your own voice — is a particular solution of the wave equation, sculpted by the geometry of the instrument. Pitch comes from the eigenvalues. Loudness comes from the amplitudes. Timbre comes from the relative weights of the modes. Even the difference between an oboe and a clarinet — both wooden tubes — is nothing more than a difference in boundary conditions.

Analogy: an instrument is a calculator with strings

Pressing a fret on a guitar is short-handing LL in the formula f1=12LT/μf_1 = \tfrac{1}{2L}\sqrt{T/\mu}. Tightening a tuning peg is dialing up TT. Blowing harder into a recorder is increasing the amplitude of the excitation, not the frequency. Every musical action maps to one symbol in a calculus formula. Once you see this, instruments stop being magic and start being experiments you can run.


Why a Whole Section on Instruments?

Three reasons. First, instruments are the most honest teachers of the wave equation: their boundary conditions are physically visible, their eigenmodes audible, their inharmonicities measurable in cents on a tuner app. Second, the same three problem types — string, pipe, drum — generalize to every wave application you will meet later: antennas (electromagnetic strings), waveguides (electromagnetic pipes), and quantum confinement (probability-amplitude membranes). Third, every one of these problems can be solved forward (geometry → pitch) and inverse (desired pitch → geometry), and the inverse direction is exactly where modern ML and physics meet.


The Vibrating String: Guitars, Violins, and Pianos

Consider a string of length LL, tension TT, and linear mass density μ\mu (kilograms per metre). Both ends are clamped — the bridge at x=0x = 0 and the nut (or your finger on the fret) at x=Lx = L. The vertical displacement y(x,t)y(x, t) obeys the 1D wave equation

2yt2=c22yx2,c=T/μ\dfrac{\partial^2 y}{\partial t^2} = c^2 \dfrac{\partial^2 y}{\partial x^2}, \quad c = \sqrt{T/\mu}

with boundary conditions y(0,t)=y(L,t)=0y(0,t) = y(L,t) = 0. We derived this in Section 1 of this chapter from Newton's second law applied to a tiny segment of string. We solved it in Sections 2–3. Now we read off the consequences for music.

The intuition before the algebra

Pluck the string and let it go. The string wants to return to its straight rest shape; tension pulls it down, but its inertia overshoots, and a wave bounces back and forth between the bridge and the nut. Because both ends are pinned, only shapes that vanish at both ends can persist — the same way only certain notes fit between two walls. Those allowed shapes are the eigenfunctions sin(nπx/L)\sin(n\pi x / L). The time they take to complete one oscillation is the period, and its reciprocal is the frequency you hear.


From the Wave Equation to Pitch in Three Steps

Step 1. Separate the variables

Write y(x,t)=X(x)Θ(t)y(x, t) = X(x)\,\Theta(t) and plug into the wave equation. Dividing by c2XΘc^2 X \Theta:

Θ(t)c2Θ(t)=X(x)X(x)=λ\dfrac{\Theta''(t)}{c^2 \Theta(t)} = \dfrac{X''(x)}{X(x)} = -\lambda

The left side depends only on tt, the right only on xx. They can be equal only if both equal a constant; we write the constant as λ-\lambda (negative, so the time solution oscillates rather than blows up).

Step 2. Apply the boundary conditions

The spatial ODE X+λX=0X'' + \lambda X = 0 withX(0)=X(L)=0X(0) = X(L) = 0 only has nonzero solutions when

λn=(nπL)2,Xn(x)=sin(nπxL),n=1,2,3,\lambda_n = \left(\dfrac{n\pi}{L}\right)^2, \quad X_n(x) = \sin\left(\dfrac{n\pi x}{L}\right), \quad n = 1, 2, 3, \dots

Those are the standing waves. Any other value of λ\lambda forces X(x)0X(x) \equiv 0 — silence.

Step 3. Read the frequency off the time equation

With λn\lambda_n known, the time equation Θ+c2λnΘ=0\Theta'' + c^2 \lambda_n \Theta = 0 has angular frequency

ωn=cλn=nπcL=nπLT/μ\omega_n = c\sqrt{\lambda_n} = \dfrac{n\pi c}{L} = \dfrac{n\pi}{L}\sqrt{T/\mu}

Converting to hertz, fn=ωn/2πf_n = \omega_n / 2\pi, we get the master formula for stringed instruments:

fn=n2LT/μ,n=1,2,3,f_n = \dfrac{n}{2L}\sqrt{T/\mu}, \quad n = 1, 2, 3, \dots

Read the formula like a sentence

To make a note higher: shorten LL (press a fret), or raise TT (tune up), or choose a lighter string (smaller μ\mu).

To make it lower: the opposite. A bass guitar uses thick strings exactly because μ\mu is in the denominator and we can't make the body absurdly long.


Interactive Guitar String Lab

Move the sliders below to feel the formula. Watch the composite vibration (white) and the individual harmonics (colored). The bar chart is the harmonic spectrum — the recipe of the sound.

Things to try

  • Pull the length slider down by half. The fundamental f1f_1 doubles. That is one octave higher. Halving the length on any string raises the pitch by exactly an octave — the simplest fact in music.
  • Quadruple the tension. c=T/μc = \sqrt{T/\mu} doubles → pitch doubles → one octave again. That is what a tuning peg does on every guitar.
  • Raise the density 4×. Pitch drops by one octave — why bass strings are wound with extra metal.

Worked Example: Tuning a Guitar's High-E String

Let's do one full calculation by hand. A standard tuned high-E guitar string vibrates at f1=329.63f_1 = 329.63 Hz. A typical scale length is L=0.65L = 0.65 m and a typical mass density is μ=0.00040\mu = 0.00040 kg/m (a 0.010-inch steel string). What tension do we need?

▶ Click to expand the full step-by-step solution

Step 1. Solve the master formula for TT:

f1=12LT/μT=μ(2Lf1)2f_1 = \dfrac{1}{2L}\sqrt{T/\mu} \quad\Longrightarrow\quad T = \mu (2L f_1)^2

Step 2. Compute 2Lf12L f_1:

2 · 0.65 · 329.63 = 428.52 m/s

That number is the wave speed cc we need on the string.

Step 3. Square and multiply by μ\mu:

T = 0.00040 · (428.52)² ≈ 0.00040 · 183 629 ≈ 73.45 N

Step 4. Sanity-check. 73 N ≈ 7.5 kgf — about the weight of a backpack. That is exactly the order of magnitude that a tuning peg can supply. The guitar would be unplayable at 1 N (too slack to vibrate) or 1000 N (the bridge would tear off). The formula has correctly told us the engineering tolerance.

Step 5. Predict the other harmonics. Because fn=nf1f_n = n f_1:

nFrequencyMusical name
1329.63 HzE4 (fundamental)
2659.26 HzE5 (one octave up)
3988.88 HzB5 (octave + fifth)
41318.5 HzE6 (two octaves up)
51648.1 HzG♯6 (two octaves + major third)
61977.7 HzB6 (two octaves + fifth)

What we just did: we used pure calculus to predict the entire harmonic content of a real guitar string and inferred the tension a luthier would need to apply. No tuner needed.


The Harmonic Series and Timbre

Why does a violin sound different from a piano playing the same note? Both have a fundamental at, say, 440 Hz. The difference is in the amplitudes of the higher harmonics — the Fourier coefficients bnb_n in

y(x,t)=n=1bnsin ⁣(nπxL)cos(ωnt)y(x, t) = \sum_{n=1}^{\infty} b_n \sin\!\left(\dfrac{n \pi x}{L}\right) \cos(\omega_n t)

For a triangular pluck at position x=pLx = pL, bnsin(nπp)/n2b_n \propto \sin(n\pi p) / n^2. Two facts follow immediately:

  1. The 1/n21/n^2 decay means high harmonics are quiet — exactly why a pluck sounds rich but not screechy.
  2. If p=1/np = 1/n for some integer nn, then sin(nπp)=0\sin(n\pi p) = 0 and the nn-th harmonic is silent. Pluck a string exactly in the middle (p=1/2p = 1/2) and the 2nd, 4th, 6th harmonics all vanish — the sound becomes hollow and flute-like. This is why guitarists pluck near the bridge for a bright sound and over the fretboard for a mellow one.

Why this matters far beyond music

The fact that where you excite a system controls which modes you see is the same idea behind Fourier image compression, mode-selective laser excitation, and even certain attention patterns in deep networks. Pluck position is a one-dimensional version of an input-feature engineering choice.


Wind Instruments: Sound in a Tube of Air

Replace the transverse displacement of a string with the longitudinal pressure of air inside a tube and you get a wind instrument. Air is compressible; the wave equation now governs pressure fluctuationsp(x,t)p(x, t):

2pt2=c22px2,c343 m/s\dfrac{\partial^2 p}{\partial t^2} = c^2 \dfrac{\partial^2 p}{\partial x^2}, \quad c \approx 343 \text{ m/s}

The wave speed cc is no longer T/μ\sqrt{T/\mu} — it's the speed of sound in air, set by temperature, not by the instrument. The geometry only enters through boundary conditions:

  • Open end (the bell of a flute, the open tone hole): pressure equals atmospheric pressure outside, so the standing-wave pressure has a node there.
  • Closed end (the player's lips on a clarinet mouthpiece, the cap on an organ pipe): air cannot move past the cap, so the velocity is zero and the pressure swings maximally — a pressure antinode.

Open vs. Closed Pipes — Why a Clarinet Sounds Different

Open–open pipe (flute, recorder, open organ pipe)

Pressure node at both ends. The allowed spatial pattern is pn(x)=sin(nπx/L)p_n(x) = \sin(n\pi x / L) — identical to the string! So the frequencies are

fn=nc2L,n=1,2,3,f_n = \dfrac{n c}{2L}, \quad n = 1, 2, 3, \dots

Every integer multiple of the fundamental is allowed. The full harmonic series is present — flutes sound bright and full.

Closed–open pipe (clarinet, panpipe, stopped organ pipe)

Now we have an antinode at x=0x = 0 (the mouthpiece) and a node at x=Lx = L (the open bell). The allowed pattern is pn(x)=cos((2n1)πx/(2L))p_n(x) = \cos((2n-1)\pi x / (2L)) and the frequencies are

fn=(2n1)c4L,n=1,2,3,f_n = \dfrac{(2n-1)c}{4L}, \quad n = 1, 2, 3, \dots

Only odd multiples of the fundamental. This has three consequences musicians know in their bones:

  1. A closed–open pipe of length LL plays half the fundamental frequency of an open–open pipe of the same length — one octave lower. A clarinet body the same length as a flute body plays an octave deeper.
  2. The lowest overtone of a clarinet is the third harmonic (twelfth above the fundamental, not an octave). Clarinetists have a technique called "overblowing the twelfth" for exactly this reason.
  3. Missing even harmonics gives the "hollow, reedy" clarinet timbre. Open–open pipes have a rounder, more vocal sound because every harmonic is present.

Interactive Pipe Acoustics Lab

Switch between flute (open–open) and clarinet (closed–open), drag the length slider, and step through the mode index. Pink curve = pressure standing wave; cyan dots = air particles displaced by the wave.

Things to try

  • Set the same length on both pipe kinds with mode = 1. Note the closed-open frequency is exactly half the open-open frequency.
  • On a closed–open pipe, step the mode slider from 1 → 5. The harmonic numbers go 1, 3, 5, 7, 9 — the even ones never appear.
  • Shrink the length. The pitch goes up — exactly what happens when you close a tone hole on a recorder.

Worked Example: Tuning a Clarinet to Middle C

How long must a clarinet (closed–open pipe) be to sound middle C (f1=261.63f_1 = 261.63 Hz) at room temperature (c=343c = 343 m/s)?

▶ Click to expand the full step-by-step solution

Step 1. Solve the closed–open formula for LL:

f1=c4LL=c4f1f_1 = \dfrac{c}{4L} \quad\Longrightarrow\quad L = \dfrac{c}{4 f_1}

Step 2. Plug in numbers:

L = 343 / (4 · 261.63) ≈ 0.328 m

That is about 33 cm. A real B♭ clarinet is closer to 60 cm because it is built to sound a tone lower (D below middle C is its written C) and because end corrections at the bell shift the effective length. The formula is the first-order picture; the missing 5–10% is what makes instrument design an art.

Step 3. Tabulate the audible overtones.

Mode nHarmonic #FrequencyMusical interval
11261.6 HzC4 (fundamental)
23784.9 HzG5 (twelfth)
351308.1 HzE6 (two octaves + third)
471831.4 HzA♯6 (≈ 7:4 natural seventh)
592354.7 HzD7 (three octaves + tone)

Step 4. Compare with a flute (open–open) of the same 33 cm length:

f₁_flute = 343 / (2 · 0.328) ≈ 523.3 Hz = C5

Exactly one octave above the clarinet. The boundary condition shifted the entire instrument by an octave. Two pieces of identical wood, one open at both ends and one closed at one end, are heard as fundamentally different instruments. This is the wave equation telling us, with no fudging, what music will sound like before the carpenter has cut a single hole.


Drums: When Calculus Goes Inharmonic

For a circular drumhead of radius aa, surface tension TT (N/m), and areal density σ\sigma (kg/m²), the 2D wave equation in polar coordinates gives modes

umn(r,θ,t)=Jm ⁣(jmnra)cos(mθ)cos(ωmnt)u_{mn}(r, \theta, t) = J_m\!\left(\dfrac{j_{mn}\, r}{a}\right) \cos(m \theta) \cos(\omega_{mn} t)

with frequencies

ωmn=cjmna,c=T/σ\omega_{mn} = \dfrac{c\, j_{mn}}{a}, \quad c = \sqrt{T/\sigma}

Here jmnj_{mn} is the nn-th positive zero of the Bessel function JmJ_m. The crucial thing about these zeros is that they are not equally spaced.

Mode (m, n)j_{mn}Ratio to fundamental
(0, 1) fundamental2.4051.000
(1, 1)3.8321.594
(2, 1)5.1362.136
(0, 2)5.5202.296
(3, 1)6.3802.653
(1, 2)7.0162.917
(0, 3)8.6543.598

Compare with a string, whose ratios are 1, 2, 3, 4, 5, … — every integer. The drum's ratios are 1, 1.594, 2.136, 2.296, … — irrational and clustered. That single fact is why drums have indefinite pitch. Your ear can't lock onto a fundamental because the overtones don't reinforce it. Drums are tones with body, not pitches.

The timpani trick

Concert timpani sound "tuned" despite being drums because orchestral designers exploit air-coupling and head loading to suppress the (0, 1) mode and let (1, 1), (2, 1), (3, 1) — which form an approximate harmonic series 2 : 3 : 4 : 5 — dominate. The (0, 1) mode is too low and too fat to set pitch; the (m, 1) family does the job. Pure mathematics on top, careful engineering on the bottom.


Interactive Drum Membrane Lab

Step through the modes and watch the nodal lines appear. Dashed white circles and lines are zero-displacement curves — sprinkle sand on a real drumhead vibrating in this mode and it will settle along exactly these lines.


Worked Example: A Timpani Tuned to A₂

A concert timpani has radius a=0.30a = 0.30 m and an areal density of about σ=0.25\sigma = 0.25 kg/m². The orchestra needs it tuned to A₂ ≈ 110 Hz. What surface tension TT do we need on the (1, 1) mode, which dominates the perceived pitch?

▶ Click to expand the full step-by-step solution

Step 1. Look up j11j_{11}.

j₁₁ = 3.8317 (the first zero of the Bessel function J₁)

Step 2. Solve ω11=cj11/a\omega_{11} = c j_{11}/a for cc, then for TT:

ω11=2πf11    c=2πf11aj11    T=σc2\omega_{11} = 2 \pi f_{11} \;\Rightarrow\; c = \dfrac{2\pi f_{11}\, a}{j_{11}} \;\Rightarrow\; T = \sigma c^2

Step 3. Plug in numbers:

c = 2π · 110 · 0.30 / 3.8317 ≈ 54.13 m/s
T = 0.25 · 54.13² ≈ 732.5 N/m

A real timpani head sits at roughly 1500–3000 N/m surface tension, so 732 N/m is plausible for a softer A₂ — the player tightens lugs around the rim to step through pitches, and our formula tells them exactly how the pitch will respond.

Step 4. Once cc is fixed, predict every other mode for free.

Mode (m, n)j_{mn}FrequencyRatio to (1,1)
(0, 1)2.40569.1 Hz0.628 (suppressed in practice)
(1, 1)3.832110.0 Hz1.000 (perceived pitch)
(2, 1)5.136147.4 Hz1.340 ≈ a fourth
(0, 2)5.520158.5 Hz1.440
(3, 1)6.380183.1 Hz1.665 ≈ a sixth
(1, 2)7.016201.4 Hz1.831 ≈ a minor seventh

The dominant (m,1)(m, 1) family at 110, 147, 183 Hz forms ratios 1:1.340:1.6651 : 1.340 : 1.665 — close to 1:4/3:5/31 : 4/3 : 5/3, which the ear interprets as a recognizable chord-like pitch. That is why a tuned timpani sings a note while a snare drum just goes thwack.


Python and PyTorch Implementation

Putting everything together: closed-form formulas for the three instrument families, plus a PyTorch routine that inverts the string equation to solve a tuning problem. Plain Python first to build intuition, then PyTorch to show how the same idea scales to learnable systems.

Three Instruments in One Module
🐍musical_instruments.py
1Numerical workhorses

NumPy provides arrays and vectorized math for the closed-form formulas. PyTorch provides autograd so we can ask 'what tension gives this pitch?' and let gradient descent solve it. Two libraries, two complementary jobs.

EXAMPLE
np.sqrt(80 / 0.0007)  → 338.06   # wave speed in m/s
6string_frequency — the function under analysis

Real job: given the physical knobs of a string (length L, tension T, linear mass density μ) and a mode number n, return the natural frequency in hertz. This is the closed-form solution of the 1D wave equation we derived earlier — every fact about plucked strings hides inside this one formula.

EXAMPLE
string_frequency(1, L=0.65, T=80, mu=0.0007) → 260.05 Hz (about middle C)
8Wave speed c = √(T/μ)

Before any frequency exists, transverse disturbances must travel at some speed. That speed comes from Newton's second law applied to a small piece of string: tension is the restoring force, mass-per-length is the inertia. Larger tension → faster wave. Heavier string → slower wave.

EXAMPLE
Steel guitar string:  c = √(80 / 0.0007) ≈ 338 m/s
Nylon classical:      c = √(80 / 0.005)  ≈ 126 m/s
9Angular frequency ω_n = n π c / L

Boundary conditions (both ends pinned) force the spatial part of the standing wave to be sin(n π x / L). Plugging this into the wave equation gives ω_n = n π c / L. The fundamental (n = 1) is the lowest pitch; n = 2, 3, … are octave, perfect fifth above the octave, second octave, etc.

EXAMPLE
n = 1: ω₁ = π · 338 / 0.65 ≈ 1633 rad/s
10Hertz from angular frequency

Convert ω (radians per second) to f (cycles per second) by dividing by 2π. Hertz is what tuners and microphones measure; ω is what calculus likes.

EXAMPLE
f = 1633 / (2π) ≈ 260 Hz
13string_motion — Fourier reconstruction of the plucked shape

A real string isn't just one mode — when you pluck it, you excite many modes at once. This function sums the first n_modes modes with coefficients b_n that match the initial triangular shape of a pluck.

17b_n for a triangular pluck

Closed form of bₙ = (2/L) ∫₀ᴸ f(x) sin(nπx/L) dx when f is the triangular tent peaked at x = pluck·L. The 1/n² decay is why a string sounds richer than a tuning fork: high harmonics are present but quieter.

EXAMPLE
Pluck at x = 0.2 L → b₁ ≈ 0.81, b₂ ≈ 0.20, b₃ ≈ 0.09, …
(amplitudes fall like 1/n²)
21Each mode oscillates independently

Once the initial shape is decomposed, every mode evolves on its own as sin(nπx/L) · cos(ωₙ t). Their sum is the visible motion of the string. This is the principle of superposition, which the wave equation guarantees because it is linear.

29pipe_frequencies — air-column resonances

Real job: list the first n_modes resonant frequencies of a pipe of length L, choosing the boundary rule that matches the instrument. The formula uses the speed of sound in air, c ≈ 343 m/s at room temperature.

EXAMPLE
pipe_frequencies(0.6, 'open-open')  → [285.8, 571.7, 857.5, 1143.3, 1429.2]
pipe_frequencies(0.6, 'closed-open') → [142.9, 428.8, 714.6, 1000.4, 1286.3]
31Open–open pipe: fₙ = n c / (2 L)

Pressure vanishes at both open ends (a node), so the standing-pressure wave fits an integer number of half-wavelengths in the pipe. Same boundary algebra as the vibrating string — only here the wave is longitudinal pressure, not transverse displacement.

33Closed–open pipe: fₙ = (2n − 1) c / (4 L)

Closed end forces a pressure antinode; open end forces a pressure node. Only quarter-wavelength fits with this asymmetry, and only odd multiples of the fundamental are allowed. That single sign change in the boundary condition is the entire reason a clarinet sounds darker than a flute.

EXAMPLE
n=1 → harmonic # 1
n=2 → harmonic # 3
n=3 → harmonic # 5
(even harmonics missing)
44scipy.special.jn_zeros — zeros of the Bessel function

Bessel functions Jₘ(x) are the radial counterpart of sin/cos for cylindrical geometry. Their zeros j_{m,n} play the same role for circular membranes that nπ/L plays for strings. They are not equally spaced — and that single fact is why drums are inharmonic.

EXAMPLE
jn_zeros(0, 3) → [2.4048, 5.5201, 8.6537]
jn_zeros(1, 3) → [3.8317, 7.0156, 10.1735]
46drum_frequency — the membrane analogue of string_frequency

Real job: given the physical knobs of a drumhead (radius a, surface tension T, areal density σ) and the angular/radial mode indices (m, n), return the natural frequency in hertz. Same recipe as the string, just with 2D wave equation and Bessel boundary conditions.

EXAMPLE
drum_frequency(0, 1, a=0.30, T=2500, sigma=0.25) ≈ 40.4 Hz (a deep timpani)
48Membrane wave speed c = √(T/σ)

Same square-root law as the string, but now σ is mass per unit area (kg/m²) instead of mass per length (kg/m). A tighter, lighter head = a higher pitch. Drummers tighten lugs around the rim to raise the pitch; this formula tells them how much it changes.

50ω_{mn} = c j_{mn} / a

Combining the 2D wave equation with circular boundary conditions yields this clean answer. m counts diameters (nodes that cut the drum across), n counts circles (nodes that ring around). Drag the mode slider in the visualization above to see m diameters and n − 1 interior circles in real time.

EXAMPLE
Mode (0,1): j ≈ 2.405,  ratio = 1.000 (fundamental)
Mode (1,1): j ≈ 3.832,  ratio = 1.594
Mode (2,1): j ≈ 5.136,  ratio = 2.136
56fit_tension_to_pitch — turn calculus into a tuning machine

Real job: instead of solving f₁ = c/(2L) for T by hand, hand the equation to PyTorch's autograd engine and let gradient descent find the tension that hits target_hz exactly. This is the same technique used to train neural networks — only here the 'network' has a single parameter T.

58requires_grad=True

Marks the tension T as a variable PyTorch should differentiate with respect to. Without this flag, the graph that connects T to the loss is not recorded, and .backward() raises a runtime error.

EXAMPLE
T = torch.tensor(50.0, requires_grad=True)
f1 = torch.sqrt(T / mu) / (2 * L)
f1.requires_grad   # → True (gradient flowed through sqrt and division)
59Adam optimizer

Adam is overkill for a one-parameter problem but it converges robustly without manual learning-rate tuning. A plain torch.optim.SGD would also work — every gradient-descent step shrinks (f₁ − target)² by moving T in the direction of −∂loss/∂T.

62Differentiable forward pass

Each operation (sqrt, division) builds a node in the autograd graph. When we call loss.backward(), PyTorch walks the graph in reverse and computes ∂loss/∂T using the chain rule — automatically and exactly.

EXAMPLE
f1 = √(T/μ) / (2L)
loss = (f1 − target)²
∂loss/∂T = 2(f1 − target) · ∂f1/∂T
         = 2(f1 − target) · 1 / (4Lμ · √(T/μ))
64loss.backward()

Triggers reverse-mode automatic differentiation. After this line, T.grad contains the partial derivative ∂loss/∂T evaluated at the current value of T. Adam then uses T.grad to update T.

65optim.step()

Applies the update rule T ← T − lr · adam_adjusted_gradient. After enough iterations the loss is essentially zero and T is the tension your tuner needs.

67.detach().item()

.detach() removes the tensor from the autograd graph (we don't need gradients anymore). .item() pulls the value out as a plain Python float, ready to be printed or handed to a hardware tuner.

71End-to-end demo

The four print statements together solve four classical problems in one block: forward formula for the string, inverse problem solved by autograd, formula for a clarinet, formula for a timpani. The same pipeline scales up to entire orchestras.

69 lines without explanation
1import numpy as np
2import torch
3
4# ---------------------------------------------------------------
5# 1. Vibrating string  -- y_n(x, t) = A_n sin(n*pi*x/L) cos(omega_n t)
6#    omega_n = n * pi / L * sqrt(T / mu)
7# ---------------------------------------------------------------
8def string_frequency(n, L, T, mu):
9    """Return the n-th natural frequency (Hz) of a vibrating string."""
10    c = np.sqrt(T / mu)        # wave speed
11    omega_n = n * np.pi * c / L
12    return omega_n / (2 * np.pi)
13
14
15def string_motion(x, t, L, T, mu, n_modes=10, pluck=0.2):
16    """Time evolution of a plucked string using Fourier series."""
17    c = np.sqrt(T / mu)
18    y = np.zeros_like(x)
19    for n in range(1, n_modes + 1):
20        # Fourier coefficient for triangular pluck at x = pluck * L
21        b_n = (2.0 / (n * np.pi) ** 2) * np.sin(n * np.pi * pluck) / (
22            pluck * (1.0 - pluck)
23        )
24        omega_n = n * np.pi * c / L
25        y += b_n * np.sin(n * np.pi * x / L) * np.cos(omega_n * t)
26    return y
27
28
29# ---------------------------------------------------------------
30# 2. Pipes  --  open-open:  f_n = n*c/(2L)
31#               closed-open: f_n = (2n-1)*c/(4L)
32# ---------------------------------------------------------------
33def pipe_frequencies(L, kind="open-open", n_modes=5, c=343.0):
34    """Return the first n_modes resonant frequencies (Hz) of a pipe."""
35    if kind == "open-open":
36        return np.array([n * c / (2 * L) for n in range(1, n_modes + 1)])
37    elif kind == "closed-open":
38        return np.array([(2 * n - 1) * c / (4 * L) for n in range(1, n_modes + 1)])
39    else:
40        raise ValueError(f"Unknown pipe kind: {kind}")
41
42
43# ---------------------------------------------------------------
44# 3. Circular membrane -- u_mn = J_m(j_mn r/a) cos(m*theta) cos(omega_mn t)
45#    omega_mn = c * j_mn / a, where j_mn = n-th zero of J_m.
46# ---------------------------------------------------------------
47from scipy.special import jn_zeros
48
49def drum_frequency(m, n, a, T, sigma):
50    """Return the (m, n) mode frequency (Hz) of a circular drum."""
51    c = np.sqrt(T / sigma)        # wave speed on the membrane
52    j_mn = jn_zeros(m, n)[-1]     # n-th zero of J_m
53    omega_mn = c * j_mn / a
54    return omega_mn / (2 * np.pi)
55
56
57# ---------------------------------------------------------------
58# 4. PyTorch demo: fit string tension to a target pitch
59# ---------------------------------------------------------------
60def fit_tension_to_pitch(target_hz, L, mu, lr=1.0, steps=400):
61    """Use autograd to find the tension T that produces target_hz on mode 1."""
62    # Start with a guess; require_grad lets PyTorch track derivatives.
63    T = torch.tensor(50.0, requires_grad=True)
64    optim = torch.optim.Adam([T], lr=lr)
65    for step in range(steps):
66        optim.zero_grad()
67        c = torch.sqrt(T / mu)
68        f1 = c / (2 * L)
69        loss = (f1 - target_hz) ** 2
70        loss.backward()
71        optim.step()
72    return T.detach().item()
73
74
75if __name__ == "__main__":
76    # Guitar high E (frequency ~ 329.63 Hz)
77    L, mu = 0.65, 0.0007
78    f1 = string_frequency(1, L=L, T=80.0, mu=mu)
79    print(f"Guitar E1 with T=80 N : {f1:6.2f} Hz")
80
81    # Find tension that hits exactly 329.63 Hz
82    T_best = fit_tension_to_pitch(329.63, L, mu)
83    print(f"Tension to hit 329.63 Hz: {T_best:6.2f} N")
84
85    # Clarinet length to play middle C (f1 ~ 261.63 Hz, closed-open pipe)
86    L_clarinet = 343.0 / (4 * 261.63)
87    print(f"Closed-open pipe length : {L_clarinet:6.3f} m")
88    print(f"Overtones:               {pipe_frequencies(L_clarinet, 'closed-open')}")
89
90    # Timpani (drum) fundamental for a 30 cm radius head
91    f_drum = drum_frequency(m=0, n=1, a=0.30, T=2500.0, sigma=0.25)
92    print(f"Timpani fundamental f01 : {f_drum:6.2f} Hz")

Common Pitfalls

Confusing wave speed c with the speed of sound

On a string, c=T/μc = \sqrt{T/\mu} — usually a few hundred m/s, but depends entirely on the string. In a pipe, c343c \approx 343 m/s — the speed of sound in air, almost independent of the pipe. Mixing them up gives nonsensical frequencies. The wave equation only knows about its own medium.

Forgetting the end correction

Real pipes don't end exactly at the geometric opening — a small column of air outside the pipe also vibrates, making the effective length slightly longer. For a tube of radius rr, add roughly 0.6r0.6 r at each open end. The textbook formula f1=c/(2L)f_1 = c/(2L) is an idealization; instrument makers always tune by ear after calculation.

Assuming drums have harmonics

Tempting, because every other instrument we've studied does. But the zeros of Bessel functions are irrational, so drum overtones are not integer multiples of the fundamental. Designing a sound synthesizer that uses fn=nf1f_n = n f_1 for percussion will produce something that sounds like a bell, not a drum.

Reading sin(nπp)/n² as 'always nonzero'

When the pluck position p=k/np = k/n for any integers kk and nn, the corresponding Fourier coefficient is exactly zero and the harmonic is missing. Plucking at L/3 silences every 3rd, 6th, 9th harmonic. Plucking at L/7 silences every 7th. This is a feature, not a bug — guitarists use it deliberately to shape timbre.


Summary

The three classical instrument families — strings, pipes, drums — are the wave equation looked at through three different boundary windows. One PDE, three geometries, an entire orchestra.

Key formulas

Instrument familyFrequency formulaAllowed harmonics
String (both ends pinned)f_n = (n / 2L) √(T/μ)1, 2, 3, 4, 5, … (full series)
Open–open pipe (flute)f_n = n c / (2L)1, 2, 3, 4, 5, … (full series)
Closed–open pipe (clarinet)f_n = (2n − 1) c / (4L)1, 3, 5, 7, 9 (odd only)
Circular drumf_{mn} = c j_{mn} / (2π a)1, 1.594, 2.136, 2.296, … (inharmonic)

Key takeaways

  1. Pitch is an eigenvalue. The geometry of the instrument decides which eigenvalues are allowed; everything else is consequence.
  2. Timbre is a Fourier coefficient. The way you excite the instrument (pluck, strike, bow, blow) decides the relative amplitudes of the modes — and that decides what the note sounds like.
  3. Boundary conditions matter more than material. A flute and a clarinet of the same length play an octave apart purely because one end is closed.
  4. Drums are mathematical proof that not every wave is harmonic. Bessel-zero ratios are irrational, which is why percussion exists as a separate musical category.
  5. Inverse problems are the future. PyTorch's autograd lets us pose questions like "what tension produces this pitch?" without a closed-form inverse — the same trick used for shape optimization, antenna design, and acoustic metamaterials.
The Essence of Musical Acoustics:
"Every instrument is a different way of asking the wave equation a question — and pitch, loudness, and timbre are the three numbers calculus gives back as an answer."
Coming Next: In Section 27.7 we leave the orchestra for the laboratory and apply the same machinery to electromagnetic waves — Maxwell's equations reduce to a vector wave equation whose boundary problems describe antennas, waveguides, and the colors of light.
Loading comments...