I've trying to write this software as part of my amateur radio and SDR hobby for analyzing various two-level FSK signals. I'm very new to DSP but have been having a lot of fun so far learning more about this subject. My long-term idea is to try and automatically detect the mark and space frequencies, as well as the baud rate, in arbitrary signals (maybe this is incredibly naive -- I don't know).
Right now I'm trying to get this software working using a known signal, known mark and space frequencies, and known baud rate. I've tested it with samples from sources like the Emergency Alert System, Bell 103, and even a pure $2600\textrm{ Hz}$ sine wave just to make sure that my frequency detection algorithm (very basic zero-crossing detection) works correctly.
I get back a $2600\textrm{ Hz}$ frequency when I test against the pure $2600\textrm{ Hz}$ sine wave sample so I'm at least somewhat confident about my ability to detect one particular frequency. However, I can never extract the mark and space frequencies when I use two-level FSK samples.
What I'm using right now is a sliding window that starts at the beginning of a sample and moves along the sample, changing both the starting position of the window and the overall length of the window, in an effort to try and find a good fit. But no matter what, I never see the mark or space frequency (actually, sometimes I will get a somewhat near read on one of the two frequencies but never both).
The project is pretty small if you want to have a look for yourself and give me some pointers (no pun intended). Apologies for the amount of code in the Cli
project right now. I've put the code that I'm pretty confident about into their own classes and behind interfaces but my "work-in-progress" code is currently just living in the Main()
method of the command-line interface.
Here is my current "window algorithm" in a nutshell:
- Start with window positioned at $0\textrm{ ms}$ into the sample
- Start with window length of a fairly minimal value
- Count zero crossings across the current window to determine the frequency of the signal in that window
- Output various information about the window and the frequency it contains
- Increase the window length and repeat until the window length hits a maximum (maybe $1-10\textrm{ ms}$ in $0.25-1.0\textrm{ ms}$ increments -- all easily configured)
- Once the maximum window length is reached, reset to the minimum window length, increment the window position a little, and repeat the varying window length frequency samples again
- Repeat this until the maximum window position is reached
And here is a screenshot of the software running, where it was able to accurately detect one of the two FSK frequencies but not the other:
EDIT 1: Turns out I had a bad sample. When I looked at a frequency spectrum plot I only saw one frequency peak, whereas a 2-level FSK spectrum should have two peaks. I found another sample and now my window algorithm is working much better.
EDIT 2: Still using the same algorithm but now with the new sample and a few very minor tweaks to the software am successfully decoding at least the first non-trivial amount of this NWR/NOAA SAME signal. You can very clearly see the 1010 1011 preamble repeating at the beginning.
EDIT 3: Refactored a lot of the code and cleaned-up the Cli project so that it is actually just a Command-Line Interface.