TorchDSP / torchsig

TorchSig is an open-source signal processing machine learning toolkit based on the PyTorch data handling pipeline.
MIT License
153 stars 36 forks source link

FSK generation issues #12

Closed daltoncass closed 1 year ago

daltoncass commented 1 year ago

There are a couple of issues with the FSK signal generation:

  1. The low pass filter applied to non gaussian FSKs does not take the number of tones into accountwhen calculating the bandwidth. The LPF is randomly chosen between 1.25 and 3.75 times the symbol rate, but the 3dB bandwidth of an FSK is (num_tones - 1) tone_spacing where tone_spacing is modulation_index symbol_rate. So the 3dB bandwidth of 16 tone FSK with mod index of 1 is 15 symbol_rate but the LPF filter for this signal is between 1.25 and 3.75 symbol_rate. This means that all but the 2 level FSKs are always over filtered
  2. The modulation index is not correct for anything larger than the 2FSKs. This is because the "constellation" of the FSKs (the frequency list) is normalized between -1 and 1 and then multiplied by the mod_index when passed to the FM modulation. This normalizes the total frequency excursion to 2 which happens to actually be an excursion of 1 since the argument to the FM modulation has a pi instead of a 2pi. So for the 2FSKs, a modulation index of 1 results in the correct tone spacing. But when you pack more than 2 tones between -1 and 1, the tone spacing gets scaled by a factor of num_tones/2. For example, packing 4 tones onto [-1, 1] means that the normalized tone spacing (accounting for the pi vs 2pi in the modulator) is 0.5 not 1, so the 4FSK has an effective modualtion index of 0.5 and the 4MSK has an effective modulation index of 0.25.
gvanhoy commented 1 year ago

@daltoncass Thank you for the issue and the detailed explanation. This seems like a relatively simple fix and we're actively working on it.

MattCarrickPL commented 1 year ago

Thank you @daltoncass , wanted to follow up with an explanation on how the fixes were made.

An overarching problem was the use of iq_samples_per_symbol as a bandwidth measure, which works for QAM/PSK but does not work for FSK as you mentioned. Within the FSKDataset() class in datasets/synthetic.py, I reassign iq_samples_per_symbol variable into the variable "oversampling_rate" and then re-calculate the actual samples per symbol as based on the oversampling rate and the modulation order. This is part of the solution to problems 1 and 2 you identified.

To finish problem 2, I also redefined the freq_map variable for FSK/MSK/GMSK/GFSK such that the modulation index is consistent for all higher order modulations.

Prior fixes solved the randomized LPF applied to both FSK and MSK, but in reviewing the code I discovered that the GFSK/GMSK modulations were not low-pass filtered and resampled. A merge request has been submitted which corrects for this and closes out this issue.