443,907 Members | 1,932 Online Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

# FM synthesis using Numpy

 P: n/a Hello fellow Python coders, I'm trying to build a simple FM synthesizer in Python. As a beginner, I take 'FM synthesizer' to mean: "using a sine wave to control the frequency of another sine wave." I tried to generate a tone of 1000 Hz that deviates 15 Hz six times a second. The start of the resulting wave file sounds right, i.e., a vibrato effect can be heard. After a second or so, the vibrato becomes more and more extreme, as if the modulating oscillator's amplitude is rising over time. I suspect that I am misunderstanding the math. I tried a couple of things: - removing the factor 2 * num.pi from either of the oscillators does not fix it, besides, doing so is even more wrong because numpy.sin works with radians - using a higher sampling frequency makes no difference - making t run from 0 to 1 each second (t %= 1) causes a clipping of the sound, so this seems wrong too - the problem is not related to Numpy, because the effect also happens in pure-Python implementations of my bug As you can see, I'm at a loss and am even trying incorrect bugfixes. Any help would be very welcome. Thanks for your time, Joost Molenaar [I left out a writewavheader function to aid brevity] ------------------------------------------------------------------- import numpy as num def oscillator(x, freq=1, amp=1, base=0, phase=0): return base + amp * num.sin(2 * num.pi * freq * x + phase) def writewav(filename, data): wave = open(filename, 'wb') # .wav header: 30 s at 44100 Hz, 1 channel of 16 bit signed samples wave.write('RIFF\x14`(\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D' '\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\xf0 _(\x00') # write float64 data as signed int16 (32767 * data).astype(num.int16).tofile(wave) wave.close() t = num.arange(0, 30, 1./44100) freq = oscillator(t, freq=6, amp=15, base=1000) tone = oscillator(t, freq=freq, amp=0.1) writewav('spam.wav', tone) ------------------------------------------------------------------- Aug 14 '07 #1 