This is now part of gnuradio-core as of version 2.5 (or cvs after March 30, 2005.)
The following python script implements both GMSK modulation and demodulation for GNU Radio. Details were derived from the 3GPP TS 45.004 document at http://www.3gpp.org/specs/numbering.htm and from the GMSK in a nutshell paper found at http://citeseer.ist.psu.edu/turletti96gmsk.html. It was very easy to implement GMSK with existing GNU Radio primitives.
There are three files. The first is the base module, gmsk.py, and the other two, gmsk-test.py and ggmsk-test.py, are programs to test the module. An archive with all three files is available here: gmsk-v0.0.tar.bz2.
gmsk_mod(fg, sps, symbol_rate, bt, p_size)
It then takes the output of simple_framer, separates the bytes into individual bits and turns those bits into polar bits using bytes_to_syms. This output is oversampled sps times with an interpolator and then sent through a Gaussian filter. (Note that with the current version of simple_correlator, cvs current 3/3/2005, the sps value must always be 8.) The output of the filter is then frequency modulated using a frequency_modulator. The frequency_modulator output is the complex GMSK signal at baseband.
The GNU Radio hier_block code is initialized with the head of the module set to the simple_framer and the tail to the frequency_modulator.
The simple_correlator block implements a fairly simple method to find the transmitted data. Basically it bit-slices the data into 0 and 1 and places each bit into one of sps unsigned integers. It calculates the Hamming distance between each of the unsigned integers and the sync word 0x40952416. The code remembers when the Hamming distance between any of the integers and the sync word falls below three and then when it rises over three. It thus has a window where the correct 32-bit sync value was recognized. It estimates the best place to sample the bit as the center of the window.
The GNU Radio hier_block code is initialized with the head of the module set to the quadrature_demod and the tail to the simple_correlator.
There are many options to the program to alter its behavior. One option, --air, mixes the modulated signal to an intermediate frequency and simulates transmission by adding in AWGN before mixing it back down to baseband for demodulation.
One must keep in mind that the entire file will not be received. Filters in GNU Radio do not produce output unless they are entirely filled. That is, if a filter has N taps, it will not produce data unless there is at least N samples to work with. Because there are filters being used in the test program, some amount of data at the end of the file will never be transmitted.
jl@secfoo:~/src/adc/gmsk/python/gmsk> dd if=/dev/urandom of=./payload.dat bs=8192 count=4 4+0 records in 4+0 records out jl@secfoo:~/src/adc/gmsk/python/gmsk> ./gmsk-test.py --packet-size=8192 sps: 8 symbol_rate: 270833.333333 sample_rate: 2166666.66667 p_size: 8192 seqno 0 seqno 1 seqno 2 tx data: 32768 elapsed time: 0.374880 seconds, 699kb/s jl@secfoo:~/src/adc/gmsk/python/gmsk> ./gmsk-test.py --packet-size=8192 --air --noise=0.1 sps: 8 symbol_rate: 270833.333333 sample_rate: 2166666.66667 p_size: 8192 lo_freq: 750000.0 lp_cutoff: 250000.0 lp_tw: 500000.0 noise_mag: 0.1 seqno 0 seqno 1 seqno 2 tx data: 32768 elapsed time: 0.943866 seconds, 277kb/s
The program displays:
jl@secfoo:~/src/adc/gmsk/python/gmsk> ./ggmsk-test.py sps: 8 symbol_rate: 270833.333333 sample_rate: 2166666.66667 p_size: 1024 lo_freq: 750000.0 lp_cutoff: 250000.0 lp_tw: 500000.0 noise_mag: 0.0 filename: ./payload.dat seqno 0 seqno 1 seqno 2 [...]
Last modified: April 2, 2005