How to demodulate an AFSK signal in software I am trying to transmit binary data from one device to another over an audio channel (speaker/mic). I use AFSK (Audio Frequency Shift Keying) as in Packet Radio, with $1200 \text{ Baud}$ and two frequencies $f_{mark} = 1200 \text{ Hz}$ and $f_{space} = 2200 \text{ Hz}$. I played around a bit in Ruby and my first implementation simply imitates a classic incoherent demodulator, which works fine, so far.

The problem is, i am trying to port this to a mobile platform where performance is a concern and my current solution is too slow. I have found numerous ways to demodulate AFSK in software:


Sliding DFT (FFT)
Sliding Görtzel Filter
Phase Locked Loop
Zero Crossing


What would be the way to go? There are just too many options to choose from. I am sure there are even more options available. Perhaps there exist even better solutions than the ones i named above? Does someone even have a code examples for me? I am concerned with


Performance (should run on mobile Platform, say an iOS or Android device)
Stability (should be able to handle some noise)


Any suggestions and hints are greatly appreciated!
I think that you could get the best performance in terms of demodulator bit-error rate (BER) with a phase-locked loop.  You need it to be fast, though.  I think your best bet for a fast algorithm that still performs reasonably well is zero crossing.

On a side note, I would like to suggest that you change the 2200 Hz to 2400 Hz.  A naive implementation of the 1200/2200 Hz scheme would yield discontinuities, as seen about two thirds into the plot below, where the 2200 Hz transitions to 1200 Hz.



In order to minimize the bandwidth that you're using and avoid discontinuities that will distort the signal you'll need to make the phase continuous.  Even if you make the transmitter phase continuous, though, there will still be the issue that the 2200 Hz symbols will not always have the same number of zero crossings due to the different phases.   Usually they will have four zero crossings, but sometimes they will have three.  The 1200 Hz symbols on the other hand, will always have two zero crossings because the baud rate divides evenly into the FSK frequency.

You can solve both of these problems by changing the 2200 Hz to 2400 Hz.  Then the symbols will always start and end at 0 degrees (thus automatically making them phase continuous), and they will always have the same number of zero crossings- two and four.