【This is not a duplicate. Similar questions apply to scenarios in which people control the source data. I dont know.】
In Japan, there is something called the “Emergency Warning Broadcasting System”. When activated, it looks like this: http://www.youtube.com/watch?v=9hjlYvp9Pxs
In the above video, at about 2:37, an FSK modulated signal is sent. I want to parse this signal; that is, given the WAV file that contains the signal, I want to get a StringBuilder that contains 0 and 1 for further processing. I have a specification for binary data and everything, but the problem is that I don't know anything about sound programming. :(
This is only for the hobby of the project, but I became connected. Televisions and radios can pick up this signal and make their devices do something in response to this, so it can't be that hard, can it ?: (
Signal Facts:
- The marking mark is 1024 Hz, and the stop signal is 640 Hz
- Each tone lasts 15.625 m.
- 2-second pause before and after the signal (possibly for detection purposes)
What i have done so far:
- Write a simple RIFF parser that accepts 8-bit mono-WAV files and allows me to get samples from them. I tested it and it works.
- A cycle that takes 15.625 ms samples and:
- Using RMS to find two seconds of silence.
- Uses the Goertzel algorithm to determine if a signal is 1024 Hz or 640 Hz
The problems that I have are:
- 0s and 1s are swallowed during the cycle depending on the test data.
- Given the clarity of the signal (playback on YouTube-MP3), this should not be.
- If I create a repeating sequence 01 in Audacity 30 times, my program will collect about 10 from pairs 01 instead of 30
- Sometimes 0s and 1s change places (side effect higher?)
- If I configure the code to work with one test sound file, the other test sound files stop working.
My questions:
- Can someone give me a high level review on how FSK decoding will work correctly in software?
- Do I need to apply some kind of filter that limits the signal to 640 Hz + 1024 Hz and turns off everything else?
- What is the best approach for choosing the right time? Maybe I'm doing it wrong?
- Any links to budding literature on this type of sound processing? I would really like to study and get this job.
Code that reads samples (simplified):
StringBuilder ews_bits = new StringBuilder(); double[] samples = new double[(int)(samplesPerMs * 16.625D)]; int index = 0, readTo = /* current offset + RIFF subChunk2Size */; BinaryReader br = /* at start of PCM data */; while (br.BaseStream.Position < readTo) { switch (bitsPerSample / 8) { case 1: // 8bit samples[index++] = ((double)br.ReadByte() - 127.5D) / 256D; break; case 2: // 16bit samples[index++] = (double)br.ReadInt16() / 32768D; break; } if (index != samples.Length) continue; /****** The sample buffer is full and we must process it. ******/ if (AudioProcessor.IsSilence(ref samples)) { silence_count++; if (state == ParserState.Decoding && silence_count > 150) { // End of EWS broadcast reached. EwsSignalParser.Parse(ews_bits.ToString()); /* ... reset state; go back looking for silence... */ } goto Done; } /****** The signal was not silence. ******/ if (silence_count > 120 && state == ParserState.SearchingSilence) state = ParserState.Decoding; if (state == ParserState.Decoding) { AudioProcessor.Decode(ref samples, sampleRate, ref ews_bits); bool continue_decoding = /* check first 20 bits for signature */; if (continue_decoding) goto Done; // If we get here, we were decoding a junk signal. state = ParserState.SearchingSilence; } /* Not enough silence yet */ silence_count = 0; Done: index = 0; }
An audio processor is just a class with:
public static void Decode(ref double[] samples, int sampleRate, ref StringBuilder bitHolder) { double freq_640 = GoertzelMagnitude(ref samples, 640, sampleRate); double freq_1024 = GoertzelMagnitude(ref samples, 1024, sampleRate); if (freq_640 > freq_1024) bitHolder.Append("0"); else bitHolder.Append("1"); } public static bool IsSilence(ref double[] samples) {
Thanks for reading. I hope you help me.