Python- FM Modulation

I am trying to Frequency modulate a sine signal using Python. I have written the following code that should do it:

def generateSignalFM(time_vector,data):
TWO_PI = 2 * np.pi
fc = 100
b = 15
data = np.sin(TWO_PI * 1 * time_vector)
fm = np.sin(TWO_PI * (fc + b * data) * time_vector)

plot_graph2d(time_vector,data,time_vector,fm)

def plot_graph2d(t1,data1,t2,data2):

plt.plot(t2,data2)
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.plot(t1,data1)
plt.legend(['FM Signal', 'Original Signal'])
plt.show()

However this is the result I'm getting back: As you can see it does work, but it is not synchronized, the lowest frequency of the sine wave does not appear below the lowest frequency of the FM signal.

Can anyone explain why this is happening?

Tying to FM an audio file: 1. Input to sine should be phase, not frequency
2. The * t is only to apply to fc per 1

Corrected: Code

import numpy as np
import matplotlib.pyplot as plt

#%% Generate #################################################################
t = np.linspace(0, 1, 2048, 0)
fc = 200
b = 15
data = -np.cos(2*np.pi * 1 * t)
phi = fc*t + b * data
fm = np.sin(2*np.pi * phi)

#%% Plot #####################################################################
plt.plot(t, fm)
plt.xlabel("Time(s)")
plt.ylabel("Amplitude")
plt.plot(t, data)
intended_freq_approx = np.hstack([0, *np.diff([data])])
intended_freq_approx *= np.abs(data).max() / np.abs(intended_freq_approx).max()
plt.plot(t, intended_freq_approx)
plt.legend(['FM Signal', 'Original Signal', '~Intended Freq'])
plt.show()

#%% Bonus ####################################################################
from ssqueezepy import ssq_stft
from ssqueezepy.visuals import imshow

Tx = ssq_stft(fm)[::-1]
imshow(Tx, abs=1, title="abs(SSQ_STFT)", ylabel="frequency", xlabel="time",
ticks=0)
• Thank you, I also tried loading a wav file and FM it, I added the results in the question, do you think it works?, FC=20KHz Jul 21 '21 at 15:19
• @yarinCohen You're using an audio signal as phase, this will not yield meaningful results (imagine time vs frequency looking like the audio signal). How to FM properly is its own question; I can imagine a multi-component approach. Jul 21 '21 at 16:17
• Dang I thought I can use the same formula for the audio signal as well, as it's just bunch of cos and sine waves, is there a special name for FM an audio signal? because I can't find anything on then web. Jul 21 '21 at 17:20
• @yarinCohen "How to frequency modulate an audio signal", is how I'd ask on this network. Can't just feed to sin since it blends multi-component phases and yields nonsense. Jul 21 '21 at 21:35
• Granted, it's not an unambiguous question, would need clarification on the precise goal. Jul 21 '21 at 21:58

This should really be a comment on the accepted answer, but I lack the reputation to do so.

@OverLordGoldDragon, what is the motivation behind multiplying the whole phi by $$2\pi$$, as opposed to only multiplying its first half (fc*t) by $$2\pi$$? It seems that this just boosts the modulation index b by a relatively arbitrary amount. This isn't too bad when b is just an uninterpretable control parameter for artistic applications (e.g. sound synthesis), but if your intention includes demodulation (e.g. FM radio transmission), the modulation index is not a free parameter, but depends on the modulator frequency and amplitude.

• This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
– MBaz
Jan 4 at 18:54
• I believe the first line of my answer indicates that I know this already. I'm also not asking for clarification from the asker, but from the answerer, because I think there's an error in the answer. Jan 4 at 19:09
• Johan: Indeed, unfortunately the moderation tools are not very nuanced. When a moderator turns your answer to a comment, they'll realize it should be attached to the existing answer. In the mean time, I've upvoted you so that you're nearer to being able to comment on others' posts.
– MBaz
Jan 4 at 21:14