Gauss Minimum-Shift Keying Modulator/Demodulator (gmskmodem)

Keywords: gmskmodem gmskmod gmskdem GMSK Gauss minimum shift keying MSK

The two objects gmksmod and gmskdem implement the Gauss minimum-shift keying (GMSK) modem in liquid . Notice that unlike the linear modem objects, the GMSK modulator and demodulator are split into separate objects. Because GMSK is a nonlinear modulation scheme, the data are tied directly to the modulated waveform, resulting in separate modulator and demodulator objects.

Modulation is performed by interpolating the input data symbols with a transmit filter to provide an instantaneous frequency. This frequency is then integrated to provide an instantaneous phase, the resulting signal is used to generate the complex sinusoid for transmission.

Demodulation is performed by differentiating the instantaneous received frequency and running the resulting time-varying phase through a matched filter . By design, the GMSK transmit filter imparts inter-symbol interference (by nature of the pulse shape). To mitigate symbol errors, the receive filter is initially designed to remove as much ISI as possible

Listed below is an example to interfacing with the gmskmod and gmskdem modulator/demodulator objects. Notice that in the example, the output data symbols match the input only when accounting for the delay in the modulator/demodulator filters.

#include <liquid/liquid.h>

int main() {
    // options
    unsigned int k     =    10; // filter samples/symbol
    unsigned int m     =     7; // filter delay (symbols)
    float        BT    = 0.25f; // bandwidth-time product
    unsigned int nsyms =    30; // number of symbols

    // create modulator/demodulator objects
    gmskmod mod   = gmskmod_create(k, m, BT);
    gmskdem demod = gmskdem_create(k, m, BT);

    // derived values
    unsigned int  delay = 2 * m;    // delay between mod/demod
    unsigned int  syms_in [nsyms];  // input data symbol
    unsigned int  syms_out[nsyms];  // input data symbol
    float complex buf[k];           // modulated samples

    // pre-generate symbols
    unsigned int i;
    for (i=0; i<nsyms; i++)
        syms_in[i] = rand() & 1;

    // run through modulator/demodulator
    for (i=0; i<nsyms; i++)
    {
        // modulate symbol and store samples into buffer
        gmskmod_modulate(mod, syms_in[i], buf);

        // demodulate
        gmskdem_demodulate(demod, buf, syms_out+i);

        // print result *accounting for delay*
        printf("[%2u] out=%1u", i, syms_out[i]);
        if (i >= delay)
            printf(" : in=%1u\n", syms_in[i-delay]);
        else
            printf("\n");
    }

    // destroy modem objects
    gmskmod_destroy(mod);
    gmskdem_destroy(demod);
    return 0;
}

Here is a time series and spectral estimate of the resulting signal:

doc/gmskmodem/gmskmod_example.png

Figure [fig-gmskmodem-psd]. GMSK modem time series for first 50 symbols and power spectral density with an excess bandwidth factor BT=0.25