arduino-audio-tools
Loading...
Searching...
No Matches
ReedSolomonFEC.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
6
7namespace audio_tools {
8
26template <int bytecount, int additional_bytes>
27class ReedSolomonFEC : public BaseStream {
28 public:
29
31 p_stream = &stream;
32 p_print = &stream;
33 }
34
36 p_print = &print;
37 }
38
41 bool begin() override {
42 raw_len = 0;
43 rx_len = 0;
44 decoded_pos = 0;
45 decoded_len = 0;
46 failed_blocks = 0;
47 return true;
48 }
49
51 int availableForWrite() override {
52 return bytecount - raw_len;
53 }
54
55 size_t write(const uint8_t* data, size_t len) override {
56 if (p_print==nullptr) return 0;
57 for (size_t j=0;j<len;j++){
58 raw[raw_len++] = data[j];
59 if(raw_len == bytecount){
61 raw_len = 0;
62 if (!writeBlock()) return j + 1;
63 }
64 }
65 return len;
66 }
67
69 int available() override {
70 if (p_stream==nullptr) return 0;
71 if (decoded_pos == decoded_len) {
72 // read the available encoded data without blocking
73 int open = bytecount + additional_bytes - rx_len;
74 int avail = p_stream->available();
75 if (avail > 0) {
76 int n = avail < open ? avail : open;
79 }
80 }
81 return decoded_len - decoded_pos;
82 }
83
84 size_t readBytes(uint8_t* data, size_t len) override{
85 if (p_stream==nullptr) return 0;
86 size_t result = 0;
87 while (result < len) {
88 if (decoded_pos == decoded_len) {
89 // collect a complete encoded block
90 int open = bytecount + additional_bytes - rx_len;
91 int n = p_stream->readBytes(rx_encoded + rx_len, open);
92 if (n <= 0) break;
93 rx_len += n;
94 if (!decodeBlock()) continue;
95 }
96 int n = decoded_len - decoded_pos;
97 if ((size_t)n > len - result) n = len - result;
98 memcpy(data + result, decoded + decoded_pos, n);
99 decoded_pos += n;
100 result += n;
101 }
102 return result;
103 }
104
106 size_t failedBlocks() { return failed_blocks; }
107
108 protected:
109 // write side
110 uint8_t raw[bytecount];
111 int raw_len = 0;
112 uint8_t tx_encoded[bytecount + additional_bytes];
113 // read side
114 uint8_t rx_encoded[bytecount + additional_bytes];
115 int rx_len = 0;
116 uint8_t decoded[bytecount];
117 int decoded_pos = 0;
118 int decoded_len = 0;
119 size_t failed_blocks = 0;
120 const int max_write_retries = 1000;
122 Stream* p_stream = nullptr;
123 Print* p_print = nullptr;
124
127 bool writeBlock() {
128 int total = bytecount + additional_bytes;
129 int written = 0;
130 int retry = 0;
131 while (written < total) {
132 int n = p_print->write(tx_encoded + written, total - written);
133 if (n > 0) {
134 written += n;
135 retry = 0;
136 } else if (++retry > max_write_retries) {
137 LOGE("ReedSolomonFEC: could not write block: %d of %d bytes", written, total);
138 return false;
139 } else {
140 delay(1);
141 }
142 }
143 return true;
144 }
145
148 bool decodeBlock() {
149 if (rx_len < bytecount + additional_bytes) return false;
150 if (rs.Decode(rx_encoded, decoded) != 0) {
151 // provide the uncorrected data bytes
152 LOGW("ReedSolomonFEC: block could not be corrected");
153 memcpy(decoded, rx_encoded, bytecount);
155 }
156 rx_len = 0;
157 decoded_pos = 0;
158 decoded_len = bytecount;
159 return true;
160 }
161
162};
163
164}
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Definition rs.hpp:28
int Decode(const void *src, void *dst, uint8_t *erase_pos=NULL, size_t erase_count=0)
Definition rs.hpp:234
void Encode(const void *src, void *dst)
Definition rs.hpp:120
Definition Arduino.h:136
virtual size_t readBytes(uint8_t *data, size_t len)
Definition Arduino.h:140
virtual int available()
Definition Arduino.h:139
Base class for all Streams. It relies on write(const uint8_t *buffer, size_t size) and readBytes(uint...
Definition BaseStream.h:33
Forward error correction using Reed-Solomon: write is encoding and readBytes does the decoding.
Definition ReedSolomonFEC.h:27
uint8_t decoded[bytecount]
Definition ReedSolomonFEC.h:116
uint8_t raw[bytecount]
Definition ReedSolomonFEC.h:110
int raw_len
Definition ReedSolomonFEC.h:111
const int max_write_retries
Definition ReedSolomonFEC.h:120
uint8_t rx_encoded[bytecount+additional_bytes]
Definition ReedSolomonFEC.h:114
ReedSolomonFEC(Print &print)
Definition ReedSolomonFEC.h:35
size_t failed_blocks
Definition ReedSolomonFEC.h:119
size_t readBytes(uint8_t *data, size_t len) override
Definition ReedSolomonFEC.h:84
size_t failedBlocks()
Number of blocks which could not be corrected.
Definition ReedSolomonFEC.h:106
int available() override
Number of decoded bytes which can be read without blocking.
Definition ReedSolomonFEC.h:69
size_t write(const uint8_t *data, size_t len) override
Definition ReedSolomonFEC.h:55
Stream * p_stream
Definition ReedSolomonFEC.h:122
int decoded_pos
Definition ReedSolomonFEC.h:117
int availableForWrite() override
Number of bytes which can be written until the next block is encoded.
Definition ReedSolomonFEC.h:51
bool writeBlock()
Definition ReedSolomonFEC.h:127
int rx_len
Definition ReedSolomonFEC.h:115
uint8_t tx_encoded[bytecount+additional_bytes]
Definition ReedSolomonFEC.h:112
bool begin() override
Definition ReedSolomonFEC.h:41
Print * p_print
Definition ReedSolomonFEC.h:123
bool decodeBlock()
Definition ReedSolomonFEC.h:148
ReedSolomonFEC(Stream &stream)
Definition ReedSolomonFEC.h:30
RS::ReedSolomon< bytecount, additional_bytes > rs
Definition ReedSolomonFEC.h:121
int decoded_len
Definition ReedSolomonFEC.h:118
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
void delay(uint32_t ms)
Definition Arduino.h:259