I am trying to comprehend GMSK modulation/demodulation. IQ samples are being phase keying is such a way that after multiplying them by complex carrier and sum both I and Q together, there is FM modulation. I don't understand how its being done. I guess it must be trigonometry but can someone explain me how phase changes in IQ result in frequency changes in HF signal?
Thanks in advance I and Q samples in time domain
carrier in time domain

  • 1
    $\begingroup$ no, there's no FM modulation, in general. Only if the Baseband (which is what IQ are, together) contained an FM-modulated signal to begin with. I think you'll really want to understand complex baseband first before diving into GMSK/OQPSK terrain, so: Marc Lichtman runs pysdr.org, and you're exactly the kind of person he'd like to educate :) Start with chapter 1, chapter 2 and 3 will explain exactly how this IQ stuff gives you a way to define the HF signal, and chapter 4 is what you need to know to understand GMSK! $\endgroup$ Commented Feb 25, 2021 at 9:09
  • $\begingroup$ (it doesn't cover GMSK itself, since that is a bit hardish to understand on a useful level if you're not yet used to both linear modulation schemes like QPSK as well as FSK, and is kind of a special case of both.) I'll say that your question is good, but it's very broad: It takes our students multiple lectures to "get there", so pointing you to a nice-to-read-and-understand resource is probably better than trying to boil down that amount of knowledge to an answer. $\endgroup$ Commented Feb 25, 2021 at 9:11
  • $\begingroup$ @MarcusMüller GMSK is an FM modulation as a form of FSK $\endgroup$ Commented Feb 25, 2021 at 13:13

2 Answers 2


The solution to this is realizing the relationship between frequency and phase:

$$\omega(t) = \frac{d\phi(t)}{dt}$$

Where $\omega(t)= 2\pi f(t)$ is the instantaneous frequency in radians/sec as a function of time ($f(t)$ is the frequency in Hz), and $\phi(t)$ is the instantaneous phase in radians as a function of time. So by such definition, a linear change in phase represents a step change in frequency. This is exactly how we can use vector modulators as frequency translators (and equivalently single-sideband modulators). A rotating phasor on the IQ plane, if rotating at a constant rate represents either a positive or negative frequency depending on the direction of rotation. So with FSK using two frequency symbols we get positive and negative rotating phasors. The frequency realized is the rate of that rotation (cycles/sec).

Starting with MSK, which is a subset of FSK, and specifically the minimum frequency shift between the two FSK tones such that the two signals are orthogonal, for this we rotate the phase 90° over one symbol duration, such that the direction of rotation determines if a one or zero was transmitted. The reason for 90° is this results in the minimum spacing of the two frequency tones as first described (hence MSK). If we rotated further within the same time of a symbol period this would result in a higher frequency and thus increase the spacing between the tones (as in generalized FSK). Below shows the phase diagram of rotation versus symbol "1" or "0". If we continued to send a long series of either symbol, it is quite clear that we are transmitting either a positive or negative frequency (relative to a central carrier frequency, so basically one of two possible tones: FSK).


When we transmit a series of symbols the frequency shift keying that is occurring is clear from the relationship between phase and frequency:


The sharp transition in frequency as a step is what creates a high spectral occupancy (sharp edges create high frequencies, consider all the spectral components of a square wave). By rounding these edges we minimize the spectral occupancy, and Gaussian Minimum Shift Keying specifically replaces the straight phase slopes with a Gaussian filtered transition (see diagram below). So the phase starts out slowly at the beginning of the symbol, reaches maximum rate mid way and then terminates slowly at the end where a possible otherwise abrupt direction change could occur. You can make a very simple (no multipliers so can be done in a micro-controller) GMSK modulator using a Gaussian Filter on the Frequency Control Word input to an NCO which is otherwise connected to the data stream (and similarly with a VCO in the analog world). (This is actually what I was getting at with this question: Simplest All Digital GMSK Modulator which can be combined with this solution for the simple no-multiplier Gaussian filter: Gaussian FIR filter with no multipliers?). The GMSK phase and frequency diagrams below further and most immediately shows how this is a form of FM modulation.


GMSK is also commonly implemented as partial response signals where we overlap consecutive pulses with intentional inter-symbol interference which can later be completely undone (with Viterbi decoding for example), and thus further improves spectral efficiency since we can send more data in the same amount of time (at the expense of receiver complexity). The strategic use of the Laurent Decompositions significantly simplifies those receivers by decomposing the GMSK waveform into Pulse-Amplitude Modulated (PAM) components.

Further FSK, MSK, GMSK are all constant envelope modulations so have the noted advantage that we can run the transmitter power amplifier into saturation which offers significant power efficiency and, without regard to immunity against intentional jammers, we can hard limit the receiver input instead of using an AGC (both of particular interest to low cost battery operated devices).

  • 1
    $\begingroup$ Nice (+1), always good with your visual illustrations. $\endgroup$
    – Gilles
    Commented Feb 25, 2021 at 20:54
  • $\begingroup$ Very thank you for this comprehensive explanation. I wish there were books which explain such a things. Can I also ask for some advise how to recover signal captured from GSM system? Is there any chance I can demodulate (without decoding) the symbols? I heard about Viterbi algorithm but isn't it data aided? Any suggestion will be highly appreciated. Thanks! $\endgroup$ Commented Feb 28, 2021 at 17:18

As @Dan_Boschen points out, the key relation is that frequency, $f(t)$, is the time derivative of phase, $\phi(t)$. To generate a final FM waveform, once actually integrates the frequency variation to produce the time varying phase used in the final waveform.

If $f_{msg}(t)$ is your Gaussian pulse shaped series of bipolar message bits (expressing the message as a normalized frequency deviation function in $[-1.0, 1.0]$), at a bit rate of $R_b$, then for MSK (modulation index of $\frac{1}{2}$), the I/Q for GMSK centered at a "carrier" frequency of 0 Hz is

$$ s(t) = Ae^{j2\pi\int_0^t \frac{R_b/2}{2}f_{msg}(\tau) d\tau} =Ae^{j\phi(t)}$$

Modulated up to a carrier of $f_c$ Hz, the expression becomes

$$ s(t) = Ae^{j\left(2\pi f_ct + 2\pi\int_0^t \frac{R_b/2}{2}f_{msg}(\tau) d\tau\right)}= Ae^{j\left(\omega_ct + \phi(t)\right)}$$

The following Octave (MatLab clone) script, walks through the steps for the digital modulation of bits to a GMSK signal at IF:

% Keep Octave happy
pkg load signal;

% Bit rate
Rb = 9600;

% Modulation index; 1/2 is Minimum Shift Keying.
modulation_index = 1/2;

% GMSK specific parameters
BT = 0.4;
L = 3; % duration of pulse in symbols

% Optional frequency shift for demonstration of modulation on a
% carrier within -Fs/2 to +Fs/2
freq_shift_hz = 12.5e3;

% Samples per symbol and sample rate out of the modulation process
sps = 10;
Fs = Rb * sps;

% pulse filter taps
% Build Gaussian pulse filter
Ls = round(L*sps); % FIXME, code assumes even.
alpha = sqrt(2/log(2)) * pi * BT;
k = [(-Ls/2+1):1:(Ls/2-1)];
taps_pf = (erf(alpha*(k/sps + 0.5)) - erf(alpha*(k/sps - 0.5)))*0.5/sps;
K_pf = length(taps_pf);
if (mod(K_pf,2) == 0)
   delay_pf = K_pf/2;
   delay_pf = (K_pf-1)/2;

% Create a random bit string
nbits = 50;
message_bits = round(rand(nbits,1));
nrz_message_bits = (message_bits - 0.5)*2;

% Upsample and pulse shape the packet
% N.B. Octave's filter function sets up a history of 0's for us.
x = sps*[upsample(nrz_message_bits, sps); zeros(delay_pf+sps*3/2, 1)];
packet_baseband = filter(taps_pf, [1], x);

% Frequency modulate the baseband packet
fm_gain = pi/(Fs/2) * Rb/2 * modulation_index;
x = packet_baseband * fm_gain;
phase = cumsum(x); % phase is integral of frequency
packet_modulated = exp(1i*mod(phase, 2*pi));

% Perform a frequency shift (using a time varying complex exponential) 
radian_phase_inc = pi/(Fs/2) .* freq_shift_hz;
rotator = exp(1i*mod(radian_phase_inc * [0:(length(packet_modulated)-1)],2*pi));
packet_modulated_if = packet_modulated .* rotator.';

title('Message Bits');
xlabel('Bit number');
grid on;

N1 = length(packet_baseband);
t1 = [0:N1-1]/Fs;
plot(t1, packet_baseband * Rb/2 * modulation_index, 'x-');
title('Upsampled, Pulse Shaped, Scaled, and Level Shifted NRZ Bits');
xlabel('Time (seconds)');
ylabel('Frequency Deviation (Hz)');
grid on;

N2 = length(phase);
t2 = [0:N2-1]/Fs;
plot(t2, phase, '.-');
title('Accumulated Phase');
xlabel('Time (seconds)');
ylabel('Accumulated Phase (radians)');
grid on;

N = length(packet_modulated);
t = [0:N-1]/Fs;
plot(t, real(packet_modulated), t, imag(packet_modulated));
title('I & Q of GMSK Modulated Signal');
xlabel('Time (seconds)');
grid on;

N_if = length(packet_modulated_if);
t_if = [0:N_if-1]/Fs;
plot(t_if, real(packet_modulated_if), t_if, imag(packet_modulated_if));
title('I & Q of GMSK Modulated Signal at IF');
xlabel('Time (seconds)');
grid on;
  • $\begingroup$ Thank you very much for this code! It helped me a lot! :) $\endgroup$ Commented Mar 2, 2021 at 7:36
  • $\begingroup$ if I increse Rb, I will increase fm_gain . could you explain what fm_gain means? How is it important for phase calculation? $\endgroup$
    – FrimHart64
    Commented Apr 26, 2022 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.