DSP tutorial: RTTY encoder
Last modified: March 4th, 2012This example is similar to the FSK encoder one, the main difference is that it uses a start and two stop bits, and encodes the message using the Baudot code to produce an RTTY signal. You can decode the sound generated with this encoder easily using a radio amateur digital mode app like FLdigi, MixW or DM780.
The generated RTTY signal’s parameters are:
- Freq0: 915 Hz
- Freq1: 1085 Hz
- Baud rate: 45.45
- Start bits: 1
- Stop bits: 2
An RTTY signal looks like this:
Image taken from this page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | private static void playBit(int bit) { int samplesNeeded = (int)Math.round(SAMPLERATE/BITSPERSEC); double[] abBufferDouble = new double[samplesNeeded]; for (int j = 0; j < samplesNeeded; j++) { oscPhase += (2 * Math.PI * (bit == 0 ? FREQ0 : FREQ1)) / SAMPLERATE; abBufferDouble[j] = Math.sin(oscPhase) * 0.2; if (oscPhase >= 2 * Math.PI) oscPhase -= 2 * Math.PI; } sdl.write(getBytesFromDoubles(abBufferDouble, samplesNeeded), 0, samplesNeeded*sdl.getFormat().getFrameSize()); } public static void playStopBits() { System.out.print(" 1"); playBit(1); // stop bit System.out.print(1); playBit(1); // stop bit } public static void switchToLetterMode() { System.out.print("LTRS: 0 "); playBit(0); // start bit for (int i = 0; i < 5; i++) { System.out.print(1); playBit(1); } playStopBits(); mode = RTTYMode.letters; System.out.println(); } public static void switchToSymbolMode() { System.out.print("FIGS: 0 "); playBit(0); // start bit System.out.print(1); playBit(1); System.out.print(1); playBit(1); System.out.print(0); playBit(0); System.out.print(1); playBit(1); System.out.print(1); playBit(1); playStopBits(); mode = RTTYMode.symbols; System.out.println(); } public static void main(String[] args) { AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, SAMPLERATE, 16, 1, 2, SAMPLERATE, false); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, BUFFERSIZE); try { sdl = (SourceDataLine)AudioSystem.getLine(info); sdl.open(audioFormat, BUFFERSIZE); } catch (LineUnavailableException e2) { e2.printStackTrace(); } sdl.start(); // initializing tone for (int i = 0; i < 16; i++) playBit(0); for (;;) { switchToLetterMode(); for (int msgPos = 0; msgPos < msg.length(); msgPos++) { char c = Character.toUpperCase(msg.charAt(msgPos)); int foundAt = -1; for (int i = 0; i < RTTYLetters.length; i++) { if (RTTYLetters[i] == c) { foundAt = i; if (mode != RTTYMode.letters) switchToLetterMode(); break; } } if (foundAt < 0) { for (int i = 0; i < RTTYSymbols.length; i++) { if (RTTYSymbols[i] == c) { foundAt = i; if (mode != RTTYMode.symbols) switchToSymbolMode(); break; } } if (foundAt < 0) foundAt = 4; // sending space if character is not in the baudot table } if (c == '\n') System.out.print("NL"); else System.out.print(c); System.out.print(" (" + foundAt + "): 1 "); playBit(0); // start bit for (int charBitPos = 0; charBitPos < 5; charBitPos++) { int bit = ((foundAt & (1 << charBitPos)) == 0 ? 0 : 1); System.out.print(bit); playBit(bit); } playStopBits(); System.out.println(); } } //sdl.drain(); //sdl.close(); } |
download (9.3 kb)
RSS feed for comments
Trackback URL
Trackback URL
2 Comments »
Trackback responses to this post
About me
I'm Nonoo. This is my blog about music, sounds, filmmaking, amateur radio, computers, programming, electronics and other things I'm obsessed with.
... »
Hallo,
herzlichen Dank für Software. Ich möchte damit meinen Navtex Empfänger testen.
Gruss
Jörg
[…] but finally under the advice of some Ham radio enthusiast friends of mine I implemented the RTTY line protocol running at 150 baud, which in practice gives me maybe about 10 bytes per second. It’s not […]