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).

    • 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.
    • Apr 30 2013 | 6:12 am
      Same patch as previous post, cleaned up a bit and labelled.
    • Apr 30 2013 | 3:28 pm
      Steve, 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.
    • Apr 30 2013 | 9:23 pm
      And here's a comparison to phase mod:
    • 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.