Music and Tech Progress Update 4

Implementing piano mode by tuning the string to play specific harmonics for each key


Piano Mode Implementation

Skip the nerd bs and try it here!

The string simulator now has a piano mode that lets you play individual notes by exciting specific harmonics.

The Problem

The original string simulation had a fundamental frequency of ~243 Hz. With harmonics spaced 243 Hz apart, I could only hit 2 distinct frequencies in the piano octave (C4-B4: 262-494 Hz). I needed more harmonics packed into that range.

The Solution

I lowered the string's fundamental frequency to ~15 Hz by reducing tension and increasing density. Now harmonics are spaced only 15 Hz apart, and the 17th through 32nd harmonics fall within the piano octave. Each semitone maps to a different harmonic.

Physics

To excite a specific harmonic, you must force the string at one of its antinodes (points of maximum displacement). For harmonic n, the first antinode is at position L/(2n) from the left end.

So when you press a piano key:

  1. The code finds which harmonic n best matches that note's frequency
  2. It moves the forcing position to x = L/(2n)
  3. It sets the forcing frequency to n × f₁

String Parameters

ModeTensionDensityWave SpeedFundamental
Normal100 N0.001 kg/m316 m/s243 Hz
Piano4 N0.01 kg/m20 m/s15.4 Hz

Harmonic to Note Mapping

The 12 piano keys map to harmonics 17-32:

  • C4 → n=17 (261 Hz)
  • C#4 → n=18 (277 Hz)
  • D4 → n=19 (292 Hz)
  • D#4 → n=20 (308 Hz)
  • E4 → n=21 (323 Hz)
  • F4 → n=22 (339 Hz)
  • F#4 → n=23 (354 Hz)
  • G4 → n=24 (369 Hz)
  • G#4 → n=25 (385 Hz)
  • A4 → n=26 (400 Hz)
  • A#4 → n=27 (416 Hz)
  • B4 → n=32 (492 Hz)

Something interesting I'm running into: it sounds out of tune because of equal temperament. The harmonic series produces notes at integer multiples of the fundamental, but equal temperament divides the octave into 12 equal logarithmic steps. These don't line up exactly, so the "natural" harmonics sound slightly off compared to what we expect from a piano.

Audio Improvements

I'm now using trapezoidal integration to calculate the string displacement, which gives a more accurate model of the sound. One consequence of this: I needed to scale the forcing function as the harmonic increases because higher harmonics require more energy to excite.

The amplitude still decreases as I go up though. I scale it proportional to omega squared, which I thought was reflected in the physics, but I'll have to revisit why this is happening.