TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
ModemConfig.h
Go to the documentation of this file.
1#pragma once
2
3#include <ctype.h>
4#include <stdint.h>
5#include <stdlib.h>
6#include <string.h>
7
8#include "AudioTools.h"
9
10namespace tinymodem {
11
21
32struct ModemConfig : public audio_tools::AudioInfo {
34 sample_rate = 48000;
35 channels = 1;
36 bits_per_sample = 16;
37 }
38
40 float baud_rate = 1200.0f;
42 float mark_freq = 0.0f;
44 float space_freq = 0.0f;
46 float bandwidth = 0.0f;
48 int data_bits = 0;
50 int start_bits = -1;
52 float stop_bits = -1.0f;
54 bool invert_start_stop = false;
56 bool inverted = false;
58 bool msb_first = false;
60 bool rx_sync = false;
64 long long sync_byte = -1;
66 float confidence = 1.5f;
68 float search_limit = 2.3f;
70 bool auto_carrier = false;
72 float auto_carrier_threshold = 0.001f;
74 float volume = 1.0f;
76 int leader_bits = 2;
78 int trailer_bits = 2;
80 bool rx_one = false;
82 bool binary_output = false;
86 bool baudot_usos = true;
88 bool print_filter = false;
92 const char* expect_bits = nullptr;
94 uint8_t channel = 0;
96 float rx_noise = 0.0f;
102
109 bool setMode(const char* mode, bool keep_options = false) {
110 if (mode == nullptr) return false;
111 if (!keep_options) resetMode();
112 is_resolved = false;
113 if (equalsIgnoreCase(mode, "rtty")) {
115 baud_rate = 45.45f;
116 if (data_bits == 0) data_bits = 5;
117 if (stop_bits < 0) stop_bits = 1.5f;
118 } else if (equalsIgnoreCase(mode, "tdd")) {
120 baud_rate = 45.45f;
121 if (data_bits == 0) data_bits = 5;
122 if (stop_bits < 0) stop_bits = 2.0f;
123 mark_freq = 1400;
124 space_freq = 1800;
125 } else if (equalsIgnoreCase(mode, "same")) {
126 // http://www.nws.noaa.gov/nwr/nwrsame.htm
127 baud_rate = 520.0f + 5 / 6.0f;
128 data_bits = 8;
129 start_bits = 0;
130 stop_bits = 0;
131 rx_sync = true;
132 tx_sync_bytes = 16;
133 sync_byte = 0xAB;
134 mark_freq = 2083.0f + 1 / 3.0f;
135 space_freq = 1562.5f;
137 } else if (startsWithIgnoreCase(mode, "caller")) {
139 baud_rate = 1200;
140 data_bits = 8;
141 } else if (startsWithIgnoreCase(mode, "uic")) {
142 format = strlen(mode) > 4 && tolower(mode[4]) == 't'
145 baud_rate = 600;
146 data_bits = 39;
147 mark_freq = 1300;
148 space_freq = 1700;
149 start_bits = 8;
150 stop_bits = 0;
151 expect_bits = "11110010ddddddddddddddddddddddddddddddddddddddd";
152 } else if (startsWithIgnoreCase(mode, "V.21")) {
153 baud_rate = 300;
154 mark_freq = 980;
155 space_freq = 1180;
156 data_bits = 8;
157 } else {
158 baud_rate = atof(mode);
159 if (data_bits == 0) data_bits = 8;
160 }
161 return baud_rate > 0.0f;
162 }
163
165 bool isTxSupported() const {
167 }
168
171 bool resolve() {
172 if (is_resolved) return true;
173 if (baud_rate <= 0.0f) return false;
174 if (data_bits == 0) data_bits = 8;
175
177 if (binary_raw_bits) {
178 start_bits = 0;
179 stop_bits = 0;
181 }
182
183 if (baud_rate >= 400) {
184 // Bell 202: baud=1200 mark=1200 space=2200
185 autodetect_shift = -(baud_rate * 5 / 6);
186 if (mark_freq == 0) mark_freq = baud_rate / 2 + 600;
188 if (bandwidth == 0) bandwidth = 200;
189 } else if (baud_rate >= 100) {
190 // Bell 103: baud=300 mark=1270 space=1070
191 autodetect_shift = 200;
192 if (mark_freq == 0) mark_freq = 1270;
194 if (bandwidth == 0) bandwidth = 50;
195 } else {
196 // RTTY: baud=45.45 mark/space=variable shift=-170
197 autodetect_shift = 170;
198 if (mark_freq == 0) mark_freq = 1585;
200 if (bandwidth == 0) bandwidth = 10;
201 }
202
203 // defaults: 1 start bit, 1 stop bit
204 if (start_bits < 0) start_bits = 1;
205 if (stop_bits < 0) stop_bits = 1.0f;
206
207 if (frameBits() > 64) return false;
208 if (start_bits > 20) return false;
209
210 // do not transmit any leader tone if no start bits
211 if (start_bits == 0) leader_bits = 0;
212
213 if (inverted) {
214 float t = mark_freq;
216 space_freq = t;
217 }
218
219 // restrict bandwidth to <= data rate
221
222 // sanitize confidence search limit
224
225 is_resolved = true;
226 return true;
227 }
228
230 unsigned frameBits() const {
231 return data_bits + start_bits + stop_bits;
232 }
233
235 bool isResolved() const { return is_resolved; }
236
237 protected:
238 bool is_resolved = false;
239
240 void resetMode() {
241 baud_rate = 1200.0f;
242 mark_freq = 0.0f;
243 space_freq = 0.0f;
244 bandwidth = 0.0f;
245 data_bits = 0;
246 start_bits = -1;
247 stop_bits = -1.0f;
248 rx_sync = false;
249 tx_sync_bytes = 0;
250 sync_byte = -1;
252 expect_bits = nullptr;
254 }
255
256 static bool equalsIgnoreCase(const char* a, const char* b) {
257 while (*a && *b) {
258 if (tolower(*a++) != tolower(*b++)) return false;
259 }
260 return *a == *b;
261 }
262
263 static bool startsWithIgnoreCase(const char* str, const char* prefix) {
264 while (*prefix) {
265 if (tolower(*str++) != tolower(*prefix++)) return false;
266 }
267 return true;
268 }
269};
270
271} // namespace tinymodem
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
DataFormat
Data encoding which is used for the payload of a frame.
Definition ModemConfig.h:13
@ UIC_GROUND
UIC-751-3 ground to train (receive only).
Definition ModemConfig.h:19
@ CALLERID
Bell 202 Caller-ID (SDMF/MDMF, receive only).
Definition ModemConfig.h:17
@ UIC_TRAIN
UIC-751-3 train to ground (receive only).
Definition ModemConfig.h:18
@ BINARY
print the raw data bits as '0'/'1' (receive only)
Definition ModemConfig.h:16
@ ASCII
ASCII 8-N-1 (or 7-N-1).
Definition ModemConfig.h:14
@ BAUDOT
Baudot 5 bit (RTTY, TDD).
Definition ModemConfig.h:15
bool rx_one
receiver: stop after the first carrier was lost
Definition ModemConfig.h:80
int binary_raw_bits
receiver: output n raw bits without framing (0 = disabled)
Definition ModemConfig.h:84
bool auto_carrier
automatically detect the carrier frequency
Definition ModemConfig.h:70
float auto_carrier_threshold
minimum magnitude for the carrier auto detection
Definition ModemConfig.h:72
bool print_filter
receiver: replace non printable characters with '.'
Definition ModemConfig.h:88
int start_bits
number of start bits (-1 = auto)
Definition ModemConfig.h:50
float search_limit
stop searching for a better frame when this confidence was reached
Definition ModemConfig.h:68
float rx_noise
receiver: (testing only) amplitude of added uniform noise
Definition ModemConfig.h:96
float stop_bits
number of stop bits (-1 = auto)
Definition ModemConfig.h:52
bool rx_sync
receiver: synchronize on sync_byte
Definition ModemConfig.h:60
static bool equalsIgnoreCase(const char *a, const char *b)
Definition ModemConfig.h:256
bool setMode(const char *mode, bool keep_options=false)
Definition ModemConfig.h:109
static bool startsWithIgnoreCase(const char *str, const char *prefix)
Definition ModemConfig.h:263
long long sync_byte
sync byte value (-1 = none)
Definition ModemConfig.h:64
bool isResolved() const
true after resolve() was called successfully
Definition ModemConfig.h:235
float space_freq
space frequency in Hz (0 = auto)
Definition ModemConfig.h:44
DataFormat format
data encoding
Definition ModemConfig.h:90
bool invert_start_stop
invert the start and stop bits
Definition ModemConfig.h:54
uint8_t channel
receiver: input channel which is used for the decoding
Definition ModemConfig.h:94
bool isTxSupported() const
Returns true if the selected format supports transmitting.
Definition ModemConfig.h:165
const char * expect_bits
custom expected frame pattern ('0','1','d')
Definition ModemConfig.h:92
float confidence
minimum confidence threshold (signal-to-noise squelch)
Definition ModemConfig.h:66
int autodetect_shift
derived: shift which is used for the carrier auto detection
Definition ModemConfig.h:101
bool inverted
swap the mark and space frequencies
Definition ModemConfig.h:56
ModemConfig()
Definition ModemConfig.h:33
unsigned frameBits() const
number of bits of a frame: start + data + stop bits
Definition ModemConfig.h:230
int data_bits
number of data bits per frame (0 = auto)
Definition ModemConfig.h:48
bool binary_output
receiver: output the data bits as '0'/'1' text
Definition ModemConfig.h:82
int trailer_bits
number of mark bits which are sent after the last frame
Definition ModemConfig.h:78
float volume
transmit amplitude (0.0 - 1.0)
Definition ModemConfig.h:74
bool is_resolved
Definition ModemConfig.h:238
void resetMode()
Definition ModemConfig.h:240
bool baudot_usos
Baudot: unshift on space.
Definition ModemConfig.h:86
float baud_rate
baud rate in bits per second (default: 1200 baud Bell 202)
Definition ModemConfig.h:40
float mark_freq
mark frequency in Hz (0 = auto)
Definition ModemConfig.h:42
bool msb_first
transmit the most significant data bit first
Definition ModemConfig.h:58
int buffer_divisor
Definition ModemConfig.h:99
int tx_sync_bytes
transmitter: number of sync bytes which are sent as preamble
Definition ModemConfig.h:62
int leader_bits
number of mark bits which are sent before the first frame
Definition ModemConfig.h:76
bool resolve()
Definition ModemConfig.h:171
float bandwidth
receive filter bandwidth in Hz (0 = auto)
Definition ModemConfig.h:46