jgaeddert / liquid-dsp

digital signal processing library for software-defined radios
http://liquidsdr.org
MIT License
1.87k stars 439 forks source link

Is GMSK example really just MSK, and filter execution is up to the user? #291

Closed marnett2 closed 2 years ago

marnett2 commented 2 years ago

Hi, Thanks for this excellent library, it is really helping with my research on communication theory.

I am curious about the code in examples/gmskmodem_example.c: it appears that the Gaussian filter is created, but not actually used. Is it up to the user to run the filter before calling gmskmod_modulate()? Would it be fair to say that the example code demonstrates minimum-shift keying (GMSK without the "G")?

jgaeddert commented 2 years ago

Hi, @marnett2. The example does indeed demonstrate GMSK and not just MSK. There are actually several ways to demodulate GMSK. The three main was are:

  1. Estimate the transmitted bits using a maximum-likelihood sequence estimator (MLSE). This is optimal, but computationally complex. It generally involves instantiating a Viterbi decoder, and requires phase-coherent reception
  2. Apply a pseudo-matched filter to the I/Q samples. This has nearly as good a performance characteristic as the MLSE, but runs much faster. The downside is that is also requires phase-coherent reception
  3. Perform frequency demodulation, and pass the real-valued result through a matched filter. This is what's being shown in the example. This has the worst performance but is the simplest to implement and does not require phase coherence

I hope that helps

marnett2 commented 2 years ago

Thanks for the excellent demodulation tips, I will definitely be exploring these methods!

But I am interested in the modulation side -- I still don't see where the Gaussian filter is used. In src/modem/src/gmskmod.c:

The Gaussian filter coeffecients are created (line 78): liquid_firdes_gmsktx(q->k, q->m, q->BT, 0.0f, q->h);

The interpolator is created (line 81): q->interp_tx = firinterp_rrrf_create_prototype(LIQUID_FIRFILT_GMSKTX, q->k, q->m, q->BT, 0);

Later, I see the interpolator is used, but the Gaussian filter (q->h) is never used (only freed). Would I need to add some code in gmskmod_modulate(), for example, that executes the filter q->h, e.g. with firfilt_rrrf_push() and firfilt_rrrf_execute() using a filter created with q->h?

Or is the interpolator actually doing the Gaussian filtering?

Thanks for your help!

jgaeddert commented 2 years ago

Ah good point. I believe the coefficients were used in a previous version directly. Now there is a special filter type that's used in the interpolator. I can probably get rid of the filter coefficients in the modulator itself (aside from the print() method)

marnett2 commented 2 years ago

Ok, that makes sense. A side question -- if I wanted to demonstrate MSK, would I simply bypass the interpolator (or use a non-Gaussian form)?

jgaeddert commented 2 years ago

MSK uses a different interpolator; you cannot just bypass it. You can use the cpfskmodem family for a whole range of continuous-phase frequency shift keying (CPFSK) modem types.

marnett2 commented 2 years ago

I will check out cpfskmodem, I had read that setting modulation index to .5 and using CPFSK would result in MSK. Thanks for your help!