When Propellers Meet Musical Mathematics
Picture this: your RC plane’s propeller creates a steady 440 Hz drone—a perfect A note. But as it flies toward you, the Doppler effect shifts that frequency higher, maybe to 465 Hz. Now you want your arpeggiator to stay in sync, but how do you track that shifting pitch?
The answer lies in beat frequency detection, a phenomenon that happens when two similar frequencies interfere. Play a 440 Hz tone alongside that 465 Hz propeller sound, and you’ll hear a “wah-wah-wah” beating at 25 Hz—the mathematical difference between them.
class BeatDetector
def detect_beat(freq1, freq2, samples, sample_rate)
beat_freq = (freq1 - freq2).abs
samples.each_with_index.map do |sample, i|
time = i.to_f / sample_rate
Math.cos(2 * Math.PI * beat_freq * time) * sample
end
end
end
detector = BeatDetector.new
beat_pattern = detector.detect_beat(440, 465, [1.0] * 1000, 44100)
puts "Beat frequency: #{(440-465).abs} Hz"
Ruby’s expressiveness lets us focus on the mathematical beauty—beat frequency as simple subtraction, then envelope detection through cosine modulation.
For real-time propeller tracking, C gives us the speed we need:
#include <math.h>
float detect_beat_amplitude(float freq1, float freq2, float time) {
float beat_freq = fabs(freq1 - freq2);
return 0.5 * (1 + cos(2 * M_PI * beat_freq * time));
}
int main() {
float propeller_hz = 465.0, target_hz = 440.0;
float beat_envelope = detect_beat_amplitude(propeller_hz, target_hz, 0.1);
printf("Beat amplitude at t=0.1s: %.3f\n", beat_envelope);
}
The C version strips away Ruby’s comfort to reveal the core: beat detection is just trigonometry racing against time. When that envelope peaks, your arpeggiator knows the propeller frequency has aligned with your target note.
This mathematical synchronization turns chaotic Doppler shifts into musical opportunities. Each beat becomes a timing signal, each frequency difference a chance to retune your arpeggio. The propeller doesn’t just make noise—it conducts the orchestra.