Synthesizing Sounds with the Wave Equation

Simulating the motion of a string to make cool sounds! Headphones recommended.

If you’ve ever tried to get a computer to play a song, you might start with a sine generator. The problem is, a straight-up sine wave doesn’t sound like music:

Even though a violin and a piano can both generate 440 Hz, the A above middle C, our ears can tell apart a violin and a piano. How do they do that? Well, the dominant frequency for the As on both instruments may be 440 Hz, but both those signals come with additional harmonics, other frequencies which are excited on the string or in a resonant cavity. These harmonics give instruments their unique timbre. To go about faking harmonics, we can experiment with adding together frequencies from the harmonic series. We can even take the Fourier transform of a real instrument and use it to inform which harmonics we choose for our synthesizer.

What if, instead, we synthesize a string? What would it sound like if we started a string in some wacky shape, gave it a kick, and listened to it? To do this, we need to solve the wave equation. If u describes the displacement of a string along x, then the wave equation boils down to: \frac{\partial^2 u}{\partial t^2} = c^{2} \frac{\partial^2 u}{\partial x^2}.

In words, this means: the acceleration of a point of the string depends on how bendy the string is at that point. Graphically:

The math details can be found here. To solve for the string’s motion at any time, we need the initial position of the string along all points, the initial velocity of the string along all points, and the condition that the ends of the string are stationary. Now it’s time to come up with some shapes!

A V-shaped velocity profile and its equivalent in the frequency domain.

First, we’ll try to simulate a simple pluck. Let’s say the string is initially flat, but we’ll give it a velocity profile that’s fastest in the middle and is zero at the edges. To figure out what will happen to this string over time, we first write this velocity profile as a sum of sines which have zeros at the string ends (our condition of stationary ends bans all other solutions!). Each sine in that sum then goes on to wiggle with a frequency related to its number of humps. Let’s animate what this solution looks like:

To turn this into sound, we can keep track of a point or two along the string and listen to it as audio. We’ll make it decay exponentially so it doesn’t go on forever like the annoying sine wave. (This one is really soft.)

Sounds like a gentle, warm bass, right? We can try a more square audio velocity profile for an initially stationary string. Slap bass, perhaps?

Now let’s try something with a little more going on. Let’s add together a few harmonics to create a pretty wiggle for the initial position and give it no additional kick. Notice how in the frequency domain, this complicated wiggle looks extremely simple since it’s just the sum of a few different sines!

If we sample this string once at the middle, it sounds kind of like those plastic Boomwhacker tubes:

With two samples averaged, we get a nice marimba sound:

What happens when we force our string into more jagged shapes? Let’s try a triangular wave with no kick:

Sounds like a tinny bell, far sharper and less warm. Why? Well, edges in signals represent high frequencies. By introducing gnarly angles, we are incorporating the high frequencies necessary to make the pointy features in the string. Stare at the gif for a bit. I was shocked to see the way the tips of the triangles get folded away and then inverted so neatly. Wrap your head around the fact that every frame of that animation is made from summing sinusoids.

Then I just tried to make the nastiest shape I could think of.

Isn’t the way it moves horrible and beautiful? Kind of sounds like a bass pluck and a bell at the same time.

We’ve only just begun to scratch the surface of the sounds (and hypnotic gifs) we can create with this method. What if we try envelopes besides exponential decay: swells, staccato, the whole sforzando-into-a-crescendo-big-band thing? What if we use envelopes that are frequency dependent? What if we learn some new math and bounce the string sound around in a chamber with a funky shape?

Until next time!

Code available here.