I found a proprietary protocol that is used on ham radio bands. The author have published details,claiming that it's a version of DominoEX with slightly different baud rate and FEC.

I want to try to write a free demodulator for that mode beacuse i love radio in general. However I dont have any DSP related background, so I decided to use an already made library that has all the maths hidden. But it has parameters that I don't fully understand.

So, I have a wav file containing one transmisson. I want to get symbols, (processing them is another problem).

DominoEx is IFSK modulation, but liquid dsp does not have the IFSK demodulator, so I assumed that I can use regular MFSK modem and compute distance between symbols afterwards. (Is this right?)

But fskdem_demodulate takes complex float arrays, (I/Q stream probably), so I need to "convert" my wav file to a complex numbers. I found that I can use the Hilbert transform for that. However in the liquid dsp it is combined with some sort of filter, which make me thinking that i'm on a wrong track. So, here is the first sub-question: how to convert regular AF 12000 samples/s into a complex float array? And if i should use firhilbf then what "semi-length" and "stop band attenuation" - parameters of firhilbf_create - should I choose.

The next step is to feed the samples to the fskdem_demodulate, however it requires several parameters which I don't fully understand.

  • m (number of bits per symbol) - for DominoEx it's 4, however, its number of symbols is 18 which is 2 more than required for 4 bits. What number should i use?
  • k (samples per symbol). Filter samples per symbol? It should be 12000/1.55 (input file samplerate/bps) but 12000/1.66 = 7741, which is more than the maximum of 2048 that is set by the library. Even if I reduce the sample rate to 6000s/s (SSB bandwidth being 3 kHz) it is still too much.
  • bandwidth - i've found bandwidth for DominoEx standard rates, but first I'm dealing with a non-standard one (1.55 bd) and second liquid dsp requires not Hz, but some floating point value.

More questions:

Now I'm dealing with carefuly pre-recorded wav file (which I converted to 32bit float raw file (Should i've converted it into a 64 bit float if i'm running my code on x86_64 machine?)) But in reality i'll be taking audio from a soundcard where transmission can start at any time. And fskdem_demodulate assumes that "symbol timing is perfect". So I need to detect the first sample of a first symbol. How can I do that?

Small "samples per symbol" above and posibility of appearance of several signals in one SSB channel makes me think that I should add some sort of filter that will pass trought a small (<200 Hz) portion of input signal, reducing the number of "samples per symbol" required. Or a downconverter, because software such as Fldigi allows you to pick a spot on the waterfall.

I'm definetly asking too much questions here, so is there a well-documented picece of open souce software I can look at? I haven't found any "real world" examples of liquid dsp MFSK demodulation. There is liquidwolf but it doesn't seems to use liquid dsp (all demodulation done in its own code). Maybe there is a more popular library with more well-documented self-explanatory examples? I've tried to port wsprd (which is also using MFSK, but the 4FSK insteadof 18FSK) to android and suceeded, but with my full respect to the author its code is hard to understand, so I touched only "input" and "output" portions, removing the fortran section entirely as I saw in someone else's modification of the wsprd. It uses the DFT to split a wav file to I/Q and a different library (fftw3) - which has no useful-looking methods like fsk_demod.

If there's not enough text, there is modulation summary:

  • IFSK, based on DominoEx
  • 1.55 baud rate, 18 symbols, but 4 bits per symbol

My failed attempt:


int main(int argc, char*argv[]){
FILE *fin = fopen("input.raw","rb"); // 12000s/s 32bit float header-less

unsigned int m           =   4;     // number of bits/symbol
unsigned int k           =   0;     // filter samples/symbol
unsigned int M    = 1 << m;
float        bandwidth   = 0.20;
// initial value
if (k == 0)
    k = 2 << m; // set samples per symbol if not otherwise specified
// should be a correct value
k = 12000/1.55;

// create Hilbert transform object
float As=60.0f;                 // stop-band attenuation [dB]
firhilbf q = firhilbf_create(64,As);

// Hilbert filter semi-length
fskdem dem = fskdem_create(m,k,bandwidth);

float x[k];         // real input
float complex y[k];   // complex output

unsigned int sym=0;

    int red = fread(&x,sizeof(float),k,fin);
    firhilbf_decim_execute_block(q, x, k, y);
    sym = fskdem_demodulate(dem, y);
    printf("%d ",sym);

} ``


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.