check my oscillators for doing selfFM,
there are a few things that you need to take care off:
-linear FM should often use an index: multiply it with the current frequency so it stays in the same ratio, whatever the frequency is. Then add this value to the phase together with the base frequency.
FMW = __SMMUL(paramFMW<<3,freq<<3);
phase += freq + ___SMMUL(modsignal<<3,FMW<<2)
(ps. this code isn't working as the __ before SMMUL should be 3x "" and the editor here removes one in the FMW function..)
-exponential FM doesn't need an indexing, as the modulation-width is automatically wider at higher octaves.
-I always implement a HP-filter on the modulating signal. This is needed as frequency modulation tends to modulate the signal such that it gets a DC-offset, offsetting the base-pitch. By implementing a HP-filter, you can remove this DC-offset, so the base-pitch of the modulated oscillator doesn't change too much.
This HP filter also helps to prevent the oscillator to get "stuck" if the self-modulation makes the frequency to be zero hertz. As this only happens when the modulation is exactly the negative version of the "base-pitch"( when the multiplication of the frequency is -1), the HP filter will force the modulator-multiplication back to zero, allowing the oscillator to go above zero hertz again and move on.