I'm trying to send some text over sound. For example, I try to send the words "Hello John". I do it this way: Every char is converted into its binary ascii code. Then I construct a wav file with no gaps by NAudio library in this manner:

    StartDelimiter = 12KHz, 
    1's = 13kHz,
    0's = 14kHz(for the message),
    End Delimiter = 10kHz. 
    The durations of whole beeps are similar: 100ms.

I'm only at the beginning of my work and I Record the series of beeps and after recording I analyze the record(in the future I want it to be near Real Time) by:

  1. Find the start delimiter's index with Goertzel filter(max power along the recorded buffer).
  2. Skipping a known duration(100ms) in a buffer to decode the 1 OR 0 by using another 2 Goertzel filters. If the End delimiter is found I break the search and show the decoded message to a box.

My problem that I've encountered so are:

  1. After sending more than 5 chars I get for example: "Hello Pohny". The first chars are fine but then it start to rubbish.
  2. Some noise defects the series.

Are there some strategies which I can use to improve the skills of my the above algorithm? Thanks I work with C# on WPF


You can't simply skip ahead some amount of time, and won't be able to skip ahead when decoding in real time.

You need to simply decode as the values come in, and switch your output depending on what comes in. Change states only on input changes. So, like this:

  1. Feed input signal into the bank of goertzel filters, the detected tone is the filter output that goes over a defined limit.
  2. When detected tone changes to 12kHz, set message start flag
  3. When detected tone changes to 13khz, send output bit 1
  4. When detected tone changes to 14kHz, send output bit 0
  5. When detected tone changes to 10kHz, end of message.
  6. Repeat from step 1 until end of message.

Working that way, you should stay synchronized and have fewer errors. You should also be able to shorten the beep lengths, though you may need to work with the length of the Goertzel filters to make it work with shorter beeps.

You will find that you will have to make a compromise between the length of the beeps, the length of the goertzel filter, and the separation between the individual tones in order to get fast, reliable communication.

To get faster communication, you will need shorter filters which in turn require larger separation between the tones to get reliable detection.

What you are doing is called frequency shift keying (FSK,) and has been used to transmit data over audio paths for a long time.

Noise will always be a problem. There are two ways to fight it, and you might have to use them both. First, you make your goertzel filters as long as possible, but still short enough to react within your desired bit rate. Second, most systems encode the data with checksums. Checksum codes can be used that allow you to recover from bit errors - they don't just say "bad data," they can also say "bad data, bit X should be value Z." There are of course limits. The better the checksum and error correction, the more extra information you have to send, so the slower your effective data rate.

A third thing you could do is to lower the data rate and extend the length of the goertzel filters, but you are already running a very low rate.

  • $\begingroup$ Thanks, my beeps are 75msec duration so is represents 3307 samples for the Goertzel filter. Is that good enough?In addition, I've thought about FIR filter before the Goertzel to reduce some noise. Is that fine? $\endgroup$ May 26 '15 at 11:00
  • $\begingroup$ Hello @JRE , I use now a goertzel for detecting a 35ms duration of 19.5Khz. I get some problems because I don't understand why as my beep duration is smaller and the freq is higer the returned magnitude of the goertzel is so small that I can't the determine if the signal is '1' or '0'. Why is it happening? $\endgroup$ Jun 11 '15 at 13:50

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.