TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
ModemStream.h
Go to the documentation of this file.
1#pragma once
2
3#include <string.h>
4
5#include "AudioTools.h"
6#include "AX25Decoder.h"
7#include "AX25Encoder.h"
8#include "CSSDecoder.h"
9#include "CSSEncoder.h"
10#include "DTMFDecoder.h"
11#include "DTMFEncoder.h"
12#include "FSKDecoder.h"
13#include "FSKEncoder.h"
14#include "GGWaveDecoder.h"
15#include "GGWaveEncoder.h"
16#include "MFSKDecoder.h"
17#include "MFSKEncoder.h"
18#include "MorseDecoder.h"
19#include "MorseEncoder.h"
20#include "PSKDecoder.h"
21#include "PSKEncoder.h"
22#include "OFDMDecoder.h"
23#include "OFDMEncoder.h"
24#include "OliviaDecoder.h"
25#include "OliviaEncoder.h"
26#include "ModemBase.h"
27#include "ModemConfig.h"
28
29namespace tinymodem {
30
43template <class Encoder, class Decoder, class Config>
44class BasicModemStream : public Stream {
45 public:
46 using ConfigType = Config;
47
48 BasicModemStream() = default;
50 BasicModemStream(Print& audio_out) { setOutput(audio_out); }
52 BasicModemStream(Print& audio_out, Stream& audio_in) {
53 setOutput(audio_out);
54 setInput(audio_in);
55 }
56
58 BasicModemStream(Stream& audio, audio_tools::RxTxMode mode) {
59 if (mode & audio_tools::TX_MODE) setOutput(audio);
60 if (mode & audio_tools::RX_MODE) setInput(audio);
61 }
62
64 void setOutput(Print& audio_out) { p_audio_out = &audio_out; }
66 void setInput(Stream& audio_in) { p_audio_in = &audio_in; }
68 void setStatusOutput(Print& out) { decoder.setStatusOutput(out); }
69
70 Config defaultConfig() { return encoder.defaultConfig(); }
71
74 bool begin(Config cfg, int rx_buffer_size = 256) {
75 bool ok = true;
76 if (p_audio_out != nullptr) {
77 encoder.setOutput(*p_audio_out);
78 ok = encoder.begin(cfg) && ok;
79 }
80 if (p_audio_in != nullptr) {
81 rx_limit = rx_buffer_size;
82 rx_queue.clear();
83 decoder.setOutput(rx_queue);
84 ok = decoder.begin(cfg) && ok;
85 }
86 return ok;
87 }
88
89 void end() {
90 encoder.end();
91 decoder.end();
92 }
93
94 size_t write(uint8_t ch) override { return encoder.write(&ch, 1); }
95
96 size_t write(const uint8_t* data, size_t len) override {
97 return encoder.write(data, len);
98 }
99
101 void flush() override { encoder.endTransmission(); }
102
103 int available() override {
104 update();
105 return rx_queue.available();
106 }
107
108 int read() override {
109 update();
110 return rx_queue.read();
111 }
112
113 int peek() override {
114 update();
115 return rx_queue.peek();
116 }
117
119 size_t readBytes(uint8_t* data, size_t len) {
120 size_t n = 0;
121 while (n < len) {
122 int ch = read();
123 if (ch < 0) break;
124 data[n++] = ch;
125 }
126 return n;
127 }
128
129 size_t readBytes(char* data, size_t len) {
130 return readBytes((uint8_t*)data, len);
131 }
132
135 size_t update() {
136 if (p_audio_in == nullptr || !decoder) return 0;
137 // stop reading the input while the received data is not consumed
138 if (rx_queue.available() >= rx_limit) return 0;
139 return readInput();
140 }
141
143 bool isCarrier() { return decoder.isCarrier(); }
144
145 Encoder& getEncoder() { return encoder; }
146 Decoder& getDecoder() { return decoder; }
147
148 protected:
150
151 Print* p_audio_out = nullptr;
152 Stream* p_audio_in = nullptr;
153 Encoder encoder;
154 Decoder decoder;
156 int rx_limit = 256;
157 uint8_t copy_buffer[256];
158
160 size_t readInput() {
161 int len = p_audio_in->available();
162 if (len <= 0) return 0;
163 if (len > (int)sizeof(copy_buffer)) len = sizeof(copy_buffer);
164 len = p_audio_in->readBytes(copy_buffer, len);
165 if (len <= 0) return 0;
166 return decoder.write(copy_buffer, len);
167 }
168};
169
175class ModemStream : public BasicModemStream<FSKEncoder, FSKDecoder, ModemConfig> {
176 public:
178};
179
185class MFSKStream : public BasicModemStream<MFSKEncoder, MFSKDecoder, MFSKConfig> {
186 public:
188};
189
196class AX25Stream : public BasicModemStream<AX25Encoder, AX25Decoder, AX25Config> {
197 public:
199};
200
206class PSKStream : public BasicModemStream<PSKEncoder, PSKDecoder, PSKConfig> {
207 public:
209};
210
216class OFDMStream : public BasicModemStream<OFDMEncoder, OFDMDecoder, OFDMConfig> {
217 public:
219};
220
228 : public BasicModemStream<GGWaveEncoder, GGWaveDecoder, GGWaveConfig> {
229 public:
231};
232
240 : public BasicModemStream<OliviaEncoder, OliviaDecoder, OliviaConfig> {
241 public:
243};
244
251class CSSStream : public BasicModemStream<CSSEncoder, CSSDecoder, CSSConfig> {
252 public:
254};
255
262 : public BasicModemStream<MorseEncoder, MorseDecoder, MorseConfig> {
263 public:
265};
266
273class DTMFStream : public BasicModemStream<DTMFEncoder, DTMFDecoder, DTMFConfig> {
274 public:
276};
277
278} // namespace tinymodem
Arduino Stream API for the AX.25 packet radio modem (APRS): print() transmits the frames,...
Definition ModemStream.h:196
BasicModemStream()=default
size_t update()
Definition ModemStream.h:135
int read() override
Definition ModemStream.h:108
Print * p_audio_out
Definition ModemStream.h:151
void flush() override
Sends the trailer: call this at the end of a message.
Definition ModemStream.h:101
size_t write(uint8_t ch) override
Definition ModemStream.h:94
Encoder encoder
Definition ModemStream.h:153
BasicModemStream(Print &audio_out)
transmit only
Definition ModemStream.h:50
Encoder & getEncoder()
Definition ModemStream.h:145
void end()
Definition ModemStream.h:89
ByteQueue ReceiveQueue
Definition ModemStream.h:149
Config defaultConfig()
Definition ModemStream.h:70
void setStatusOutput(Print &out)
Defines the output for the ### CARRIER / ### NOCARRIER messages.
Definition ModemStream.h:68
bool isCarrier()
true while a carrier is detected
Definition ModemStream.h:143
size_t readBytes(uint8_t *data, size_t len)
Reads the available data (does not wait for more data).
Definition ModemStream.h:119
int peek() override
Definition ModemStream.h:113
void setInput(Stream &audio_in)
Defines the audio input (receiver).
Definition ModemStream.h:66
int available() override
Definition ModemStream.h:103
ReceiveQueue rx_queue
Definition ModemStream.h:155
size_t write(const uint8_t *data, size_t len) override
Definition ModemStream.h:96
uint8_t copy_buffer[256]
Definition ModemStream.h:157
size_t readBytes(char *data, size_t len)
Definition ModemStream.h:129
Decoder & getDecoder()
Definition ModemStream.h:146
int rx_limit
Definition ModemStream.h:156
BasicModemStream(Print &audio_out, Stream &audio_in)
transmit and receive with separate output and input
Definition ModemStream.h:52
Config ConfigType
Definition ModemStream.h:46
BasicModemStream(Stream &audio, audio_tools::RxTxMode mode)
Definition ModemStream.h:58
Decoder decoder
Definition ModemStream.h:154
size_t readInput()
Reads the available audio input and feeds it to the decoder.
Definition ModemStream.h:160
Stream * p_audio_in
Definition ModemStream.h:152
bool begin(Config cfg, int rx_buffer_size=256)
Definition ModemStream.h:74
void setOutput(Print &audio_out)
Defines the audio output (transmitter).
Definition ModemStream.h:64
FIFO for received data which grows when needed: e.g. one decoding step can produce more data than exp...
Definition ModemBase.h:249
Arduino Stream API for the chirp spread spectrum modem (LoRa-like): print() collects the data,...
Definition ModemStream.h:251
BasicModemStream()=default
Arduino Stream API for the DTMF (touch tone) modem: print() sends the keys 0-9, *,...
Definition ModemStream.h:273
BasicModemStream()=default
Arduino Stream API for the ggwave compatible modem: print() collects the data (up to 140 bytes),...
Definition ModemStream.h:228
Arduino Stream API for the multi-tone FSK modem: print() transmits, read() receives....
Definition ModemStream.h:185
BasicModemStream()=default
Arduino Stream API for the minimodem compatible FSK modem: print() transmits, read() receives....
Definition ModemStream.h:175
Arduino Stream API for Morse code (International or American): print() transmits, read() receives....
Definition ModemStream.h:262
Arduino Stream API for the OFDM modem: print() collects the data, flush() sends it as frame,...
Definition ModemStream.h:216
BasicModemStream()=default
Arduino Stream API for the Olivia and Contestia modems (compatible with fldigi): print() transmits,...
Definition ModemStream.h:240
Arduino Stream API for the PSK modem (PSK31 to PSK500): print() transmits, read() receives....
Definition ModemStream.h:206
BasicModemStream()=default
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11