Forums > MaxMSP

FM in C and in Max

Apr 30 2013 | 4:20 am


I’ve implemented a simple FM function in both C and in Max: f(t) = G * cos(2pi * fc * t + pd * cos(2pi * fm * t)) [the max code is pasted below].

However, the two sound quite different from one another (of course, using the same values for fm, fc and pd). The C code version sounds much "brighter".

What might be the reason for the difference? Does Max use a lower sampling rate, and so doesn’t (by default) reproduce the higher frequencies? (The sampling rate for the C code was 44100).



-- Pasted Max Patch, click to expand. --

Apr 30 2013 | 5:14 am

Lack of anti-aliasing in cycle~? But I don’t see how the C code oscillators could be anti-alised either with only the basic sine wave equation invoked, but I don’t know C (yet).

Apr 30 2013 | 5:35 am

Here’s another take on FM – implementing the standard algorithm as per Dodge/Jerse, Roads, etc. Plenty of brightness.

-- Pasted Max Patch, click to expand. --

Apr 30 2013 | 6:12 am

Same patch as previous post, cleaned up a bit and labelled.

-- Pasted Max Patch, click to expand. --

Apr 30 2013 | 3:28 pm

Thanks for your model, and yes, it does preserve the "brightness" of the C code.
I’m new to Max, and I’m trying to understand how and why it works the way it does.

Two Questions:

1) why does Max require the use of the sig~ object, as you’ve used in your code? Is this a hangover from csound, and is delivering a number at the "control" rate?

2) In your "FM-control" object, why do you need to use both the "f" object and the "t" object? Why can’t numbers (Fc and C:M for example) be simply multiplied with each other, and the result simply sent to two different outputs?

Thanks in advance,


Apr 30 2013 | 4:10 pm

not sure, but the differences might be to do with modulating frequency vs modulating phase

Apr 30 2013 | 5:22 pm

Arun, from what I can tell all the [f ] objects can be removed, but the [t b f] objects are there to ensure that the values re-calculated when either input is altered – the trigger object is very very important in max, especially due to the way most objects only trigger on the left-most input.

Apr 30 2013 | 6:27 pm

In your Max version, the mod osc swings between -1.0 and 1.0, and then you add that to the frequency of the carrier. I don’t think that this is what you want. See the SimpleFM~ abstraction for another implementation.

-- Pasted Max Patch, click to expand. --

Apr 30 2013 | 9:23 pm

And here’s a comparison to phase mod:

-- Pasted Max Patch, click to expand. --

May 01 2013 | 12:55 am

The [sig~] objects convert a float or int into a signal of that value (i.e. a signal of that magnitude, or DC offset, if you will). In this application they are not strictly necessary, but they come in handy if making certain extensions/expansions by keeping the math for the dynamic oscillator frequency and amplitude values in the signal domain.

The [f] (float variable) objects are there to store the incoming value so that I can ‘bang’ it when values arrive in the other inlets, causing it to output its stored value. Because of Max’s right-left order and the fact that typically only the left-most inlet of any object triggers that object’s action/behavior, I make sure that a value coming into the right inlet of a math operator also triggers reloading the value for the left inlet – thereby making sure that updating either value triggers the math calculation.

Viewing 10 posts - 1 through 10 (of 10 total)

Forums > MaxMSP