TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
ModemStreamRTOS.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4
5#include "AudioTools.h"
6#include "AudioTools/Concurrency.h"
7#include "ModemStream.h"
8
9#if defined(RP2040) && !defined(USE_FREERTOS)
10#error "ModemStreamRTOS on RP2040: select Tools > Operating System > FreeRTOS SMP and #include <FreeRTOS.h> before AudioTools.h"
11#endif
12
13namespace tinymodem {
14
28template <class Base>
29class BasicModemStreamRTOS : public Base {
30 public:
31 using Base::Base;
32 using Config = typename Base::ConfigType;
33
35
38 void setTaskConfig(int stack_size, int priority = 1, int core = -1) {
39 task_stack_size = stack_size;
40 task_priority = priority;
41 task_core = core;
42 }
43
46 bool begin(Config cfg, int rx_buffer_size = 256) {
47 end();
48 if (!Base::begin(cfg, rx_buffer_size)) return false;
49 if (this->p_audio_in == nullptr) return true;
50 // the decoder runs in the receive task: protect the receive queue
51 locked_queue.p_queue = &this->rx_queue;
52 locked_queue.p_mutex = &mutex;
53 this->decoder.setOutput(locked_queue);
54 if (!task_created) {
55 if (!task.create("tinymodem-rx", task_stack_size, task_priority,
56 task_core)) {
57 LOGE("BasicModemStreamRTOS: could not create the receive task");
58 return false;
59 }
60 task_created = true;
61 }
62 is_idle = false;
63 is_running = true;
64 if (!task.begin([this]() { receive(); })) {
65 LOGE("BasicModemStreamRTOS: could not start the receive task");
66 is_running = false;
67 return false;
68 }
69 is_task_active = true;
70 return true;
71 }
72
74 void end() {
75 if (is_task_active) {
76 // let the task complete the current step before we stop it
77 is_running = false;
78 while (!is_idle) delay(1);
79 task.end();
80 is_task_active = false;
81 }
82 Base::end();
83 }
84
85 int available() override {
86 audio_tools::LockGuard guard(mutex);
87 return this->rx_queue.available();
88 }
89
90 int read() override {
91 audio_tools::LockGuard guard(mutex);
92 return this->rx_queue.read();
93 }
94
95 int peek() override {
96 audio_tools::LockGuard guard(mutex);
97 return this->rx_queue.peek();
98 }
99
101 size_t update() { return 0; }
102
104 bool isRunning() { return is_task_active; }
105
106 protected:
107#ifdef ESP32
108 static constexpr int DEFAULT_STACK_SIZE = 8 * 1024; // bytes
109#else
110 static constexpr int DEFAULT_STACK_SIZE = 2 * 1024; // words
111#endif
112 using Queue = typename Base::ReceiveQueue;
113
115 struct LockedQueue : public Print {
116 Queue* p_queue = nullptr;
117 audio_tools::MutexBase* p_mutex = nullptr;
118 size_t write(uint8_t ch) override {
119 audio_tools::LockGuard guard(p_mutex);
120 return p_queue->write(ch);
121 }
122 size_t write(const uint8_t* data, size_t len) override {
123 audio_tools::LockGuard guard(p_mutex);
124 for (size_t j = 0; j < len; j++) p_queue->write(data[j]);
125 return len;
126 }
127 };
128
129 audio_tools::Task task;
130 audio_tools::Mutex mutex;
134 int task_core = -1;
135 bool task_created = false;
136 bool is_task_active = false;
137 std::atomic<bool> is_running{false};
138 std::atomic<bool> is_idle{false};
139
141 void receive() {
142 if (!is_running) {
143 is_idle = true;
144 delay(10);
145 return;
146 }
147 if (readInputLocked() == 0) delay(1);
148 }
149
152 {
153 // stop reading the input while the received data is not consumed
154 audio_tools::LockGuard guard(mutex);
155 if (this->rx_queue.available() >= this->rx_limit) return 0;
156 }
157 return this->readInput();
158 }
159};
160
166class ModemStreamRTOS : public BasicModemStreamRTOS<ModemStream> {
167 public:
168 using BasicModemStreamRTOS::BasicModemStreamRTOS;
169};
170
176class MFSKStreamRTOS : public BasicModemStreamRTOS<MFSKStream> {
177 public:
178 using BasicModemStreamRTOS::BasicModemStreamRTOS;
179};
180
186class AX25StreamRTOS : public BasicModemStreamRTOS<AX25Stream> {
187 public:
188 using BasicModemStreamRTOS::BasicModemStreamRTOS;
189};
190
196class PSKStreamRTOS : public BasicModemStreamRTOS<PSKStream> {
197 public:
198 using BasicModemStreamRTOS::BasicModemStreamRTOS;
199};
200
206class OFDMStreamRTOS : public BasicModemStreamRTOS<OFDMStream> {
207 public:
208 using BasicModemStreamRTOS::BasicModemStreamRTOS;
209};
210
216class GGWaveStreamRTOS : public BasicModemStreamRTOS<GGWaveStream> {
217 public:
218 using BasicModemStreamRTOS::BasicModemStreamRTOS;
219};
220
226class OliviaStreamRTOS : public BasicModemStreamRTOS<OliviaStream> {
227 public:
228 using BasicModemStreamRTOS::BasicModemStreamRTOS;
229};
230
236class CSSStreamRTOS : public BasicModemStreamRTOS<CSSStream> {
237 public:
238 using BasicModemStreamRTOS::BasicModemStreamRTOS;
239};
240
246class MorseStreamRTOS : public BasicModemStreamRTOS<MorseStream> {
247 public:
248 using BasicModemStreamRTOS::BasicModemStreamRTOS;
249};
250
256class DTMFStreamRTOS : public BasicModemStreamRTOS<DTMFStream> {
257 public:
258 using BasicModemStreamRTOS::BasicModemStreamRTOS;
259};
260
261} // namespace tinymodem
AX25Stream (APRS) which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:186
BasicModemStream which receives in a separate task (FreeRTOS on ESP32 and RP2040, a std::thread on th...
Definition ModemStreamRTOS.h:29
audio_tools::Mutex mutex
Definition ModemStreamRTOS.h:130
LockedQueue locked_queue
Definition ModemStreamRTOS.h:131
bool is_task_active
Definition ModemStreamRTOS.h:136
std::atomic< bool > is_idle
Definition ModemStreamRTOS.h:138
void receive()
One iteration of the receive task.
Definition ModemStreamRTOS.h:141
bool begin(Config cfg, int rx_buffer_size=256)
Definition ModemStreamRTOS.h:46
void setTaskConfig(int stack_size, int priority=1, int core=-1)
Definition ModemStreamRTOS.h:38
std::atomic< bool > is_running
Definition ModemStreamRTOS.h:137
int available() override
Definition ModemStreamRTOS.h:85
size_t readInputLocked()
Reads the available audio input and feeds it to the decoder.
Definition ModemStreamRTOS.h:151
typename Base::ReceiveQueue Queue
Definition ModemStreamRTOS.h:112
size_t update()
Not needed: the receive task processes the input.
Definition ModemStreamRTOS.h:101
int task_stack_size
Definition ModemStreamRTOS.h:132
int read() override
Definition ModemStreamRTOS.h:90
audio_tools::Task task
Definition ModemStreamRTOS.h:129
bool task_created
Definition ModemStreamRTOS.h:135
typename Base::ConfigType Config
Definition ModemStreamRTOS.h:32
~BasicModemStreamRTOS()
Definition ModemStreamRTOS.h:34
bool isRunning()
true while the receive task is running
Definition ModemStreamRTOS.h:104
void end()
Stops the receive task and the modem.
Definition ModemStreamRTOS.h:74
int peek() override
Definition ModemStreamRTOS.h:95
int task_core
Definition ModemStreamRTOS.h:134
static constexpr int DEFAULT_STACK_SIZE
Definition ModemStreamRTOS.h:110
int task_priority
Definition ModemStreamRTOS.h:133
CSSStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:236
DTMFStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:256
GGWaveStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:216
MFSKStream (multi-tone FSK) which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:176
ModemStream (FSK) which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:166
MorseStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:246
OFDMStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:206
OliviaStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:226
PSKStream which receives in a separate task. See BasicModemStreamRTOS.
Definition ModemStreamRTOS.h:196
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
Print which writes the decoded data into the queue with a lock.
Definition ModemStreamRTOS.h:115
Queue * p_queue
Definition ModemStreamRTOS.h:116
audio_tools::MutexBase * p_mutex
Definition ModemStreamRTOS.h:117
size_t write(uint8_t ch) override
Definition ModemStreamRTOS.h:118
size_t write(const uint8_t *data, size_t len) override
Definition ModemStreamRTOS.h:122