• ### Mathematical equations for frequency modulation?

Hi all,

this might be slightly off topic but I need help with some simple sound-related math. I've been trying to do something as trivial as plotting the function of a wave modulated by another one.

At the moment i'm using this function:
 y = cos(Fc * x + M * cos(Fm * x))
Function plot on Wolfram Alpha

Where Fm is the frequency of the modulator, Fc frequency of the carrier and M the modulation index. In this way I can draw two sine waves modulating each other and - surprisingly enough - this also works when modulating the frequency of other waveshapes, like a [x - floor(x)] sawtooth:

 y = [Fc * x + M * cos(Fm * x)] - floor(Fc * x + M * cos(Fm * x))
Function plot on Wolfram Alpha

BUT I can't manage to do the opposite! If I want a sinewave to be frequency modulated by a sawtooth wave it just doesn't work. I see the phase going all crazy but no frequency modulation at all.

 y = cos(Fc * x + M * [(Fm * x) - floor(Fm * x)])
Function plot on Wolfram Alpha

Am I taking a completely wrong approach? What elementary mathematical principle am I missing here? Thanks!

• Posts 13 | Views 9852
• Hmm, how can the phase of a simple waveform go crazy without changing it's frequency?? Did you listen to it, maybe it's sounds good?!..

Well, this should be what you are looking for!?!

[phasor~ f_saw]
|
[*~ a]
|
[+~ f_sin]
|
[osc~]

Where one would use the inlets instead of the parameters f_saw, a and f_sin of course.

the thing is that i'm using these equations for visuals, not for sound, that's why i need to display a frequency modulated waveform.

i see your fm pd patch and if i try to do it using inline functions  it just doesn't work. i'm starting to understand that what i'm doing with equation  is more like [phasor~] -> [*~] -> [cos~] (clean sine wave) which for some reason is totally different from [phasor~] -> [*~] -> [osc~] (osc modulated by sawtooth).

does this make any sense?

• [phasor~]
|
[cos~]

is basically the same thing as:

[osc~]

so,

[phasor~]
|
[*~ ]
|
[osc~]

is basically the same as:

[phasor~]
|
[*~ ]
|
[phasor~]
|
[cos~]

• Well, let's break this down a bit. Starting with the simple FM equation:

y = cos(Fc * x + M * cos(Fm * x))

Both of those cos() represent the sinusoids, with the outside one being the carrier and the inner one being the modulator. x is the time increment, and Fn is the frequency, or the rate at which the phase changes for each increment of x. So, by having the modulator inside the carrier cos(), it is offsetting the phase.

If you were to just plot Fc*x and wrap it between 0 and 2*pi radians (because cos() repeats at 2*pi intervals), you just get a sawtooth wave. So what you are basically doing is taking that sawtooth wave and adding another sawtooth wave to that at a different frequency and amplitude. This just results in a sawtooth with occasional sudden jumps:

y = mod(Fc * x + M * [(Fm * x) - floor(Fm * x)], 2 * pi)

And you can see how those jumps affect  in your plot. So it is being modulated. It's just not particularly interesting.

• i had a go at doing fm with control signals. not sure how correct this is, but the graph 'looks' like it might be correct.

for sure there's probably some simple [expr] function that would make all this easier, but i just did it with basic objects.

http://www.pdpatchrepo.info/hurleur/controlFM.pd

• thanks everybody, i think i'm getting closer now.

mod: your patch with control messages was really useful. i made a new version (attached below) and it seems to work. just one thing: could you please elaborate a bit more the last counter in your patch? maelstorm: thanks, i think i understand now why the  wasn't working but still, how can i display the modulation i want? when modulating the frequency of a sine wave with a sawtooth i'm expecting its frequency to increase linearly and then drop, following the amplitude of the sawtooth wave. i still can't find the right equation for that.

http://www.pdpatchrepo.info/hurleur/controlFM.pd

• ok.

say you have a basic counter, [f ]x[+ 1] style.. but instead of [+ 1], if you use [+ 0.01] followed by [wrap]... what this does, is it will create a ramp from 0 to 1, over a period of 100 steps, and then wrap around to zero again. so basically, it is the control version of a [phasor~]

however, if you just use 0.01 all the time, then the frequency of that [phasor~] would stay the same. ie, for every step, you just advance 0.01
SO, what we do here, is with the [t b f] object, we take the output from the first 'oscillator', and use that to change the frequency of this 2nd oscillator.

does that make sense???

• @guido said:

maelstorm: thanks, i think i understand now why the  wasn't working but still, how can i display the modulation i want? when modulating the frequency of a sine wave with a sawtooth i'm expecting its frequency to increase linearly and then drop, following the amplitude of the sawtooth wave. i still can't find the right equation for that.

Ah, okay. So you're thinking more in terms of modulating the pitch with an LFO. To get a better understanding, let's take a step back and look at what a basic cosine oscillator looks like as an equation:

y(x) = cos(F*x + phi)

Where F is the radian frequency and phi is a phase offset, i.e. what the phase is at time x=0. Now, when you look at Chowning's Simple FM formula, you'll see that the modulator replaces phi:

y(x) = cos(Fc*x + M*cos(Fm*x))

In other words, it is actually phase modulation.

What you are looking to do is modulate Fc, in which case you would replace Fc with the sawtooth function instead of phi. To make the formula more clear, let's substitute the function saw(x) = Fm*x - floor(Fm*x). Fc should then be substituted by a scaled and offset saw(x):

y(x) = cos(((Fmax - Fmin)*saw(x) + Fmin)*x)

Where Fmin is the starting frequency of the ramp, and Fmax is the ending frequency. Try plugging that into Wolfram|Alpha and see if that works.

• mod: this makes sense thanks. in my final project i won't be able to store variables (it's for gpu stuff) so i think your dsp-like approach with phase accumulators will not work for me.

maelstorm:
@Maelstorm said:

y(x) = cos(((Fmax - Fmin)*saw(x) + Fmin)*x)

thanks, this works sometimes but still it's not working as expected [...] edit: i cleaned up all the mess down here.

• had some time to work again on this and finally came up with a solution. the problem was simple but my poor skills in maths led me to misunderstand the damn thing. chowning's fm formula is generalized like this: this means that the general equation for frequency modulation needs a time-integral of the modulating function (i'd say to get the actual amplitude of the modulating waveform).

that's why to modulate a cosine wave with a sine wave the resulting formula includes a cosine function &#8211; and not a sine &#8211; as modulator, the sine is integrated as a cosine.

starting from this, i just needed to figure out the indefinite integral of all the waveforms i wanted and, well, it worked. thanks everybody for the help in this mathematical madness.

• Nice! I realized after I posted that my equation didn't make sense, but couldn't figure it out. Once you start getting into integrals, I'm out of my league. Thanks for posting the solution.

• I'm a little late to the discussion, but I think these articles of SOS are well explained. They talk about FM and the math in simple terms.

Hope it helps!!

Posts 13 | Views 9852
Internal error.

Oops! Looks like something went wrong!