2 #include "AudioConfig.h"
3 #include "AudioTools/CoreAudio/BaseStream.h"
29 template <
int bytecount,
class block_t>
41 int availableForWrite()
override {
45 size_t write(
const uint8_t* data,
size_t len)
override{
46 if (p_print==
nullptr)
return 0;
47 for (
int j=0;j<len;j++){
50 encode(raw.
data(), raw.size());
57 int available()
override{
61 size_t readBytes(uint8_t* data,
size_t len)
override{
62 if (p_stream==
nullptr)
return 0;
63 if (encoded.isEmpty()){
65 p_stream->readBytes(encoded.
data(), encodedSize());
68 if(decode((block_t*)encoded.
data(), bytecount)){
78 Stream* p_stream =
nullptr;
79 Print* p_print =
nullptr;
83 int bits =
sizeof(block_t) * 8;
86 int messageBits = bits - log2(bits) - 1;
89 int block_ts = ceil((
float) bytecount / messageBits);
95 return getBlocks()+1*
sizeof(block_t);
98 int encode(uint8_t *input,
int len) {
101 int bits =
sizeof(block_t) * 8;
104 int messageBits = bits - log2(bits) - 1;
107 int block_ts = ceil((
float) len / messageBits);
110 block_t encoded[block_ts+1];
113 for (
int i = 0; i < block_ts+1; i++) {
116 block_t thisBlock = 0;
128 for (
int j = 0; j < bits; j++) {
131 if ((j & (j - 1)) == 0) {
141 int currentBit = i*messageBits + (j-skipped);
144 int currentChar = currentBit/(
sizeof(uint8_t)*8);
147 thisBit = currentBit < len*
sizeof(uint8_t)*8 ? getCharBit(input[currentChar], currentBit-currentChar*8) : 0;
151 thisBit = getBit(len/8, j-skipped+(
sizeof(block_t)*8-messageBits));
161 thisBlock = modifyBit(thisBlock, j, thisBit);
165 block_t parityBits = multipleXor(onList, onCount);
168 for (
int k = 1; k < skipped; k++) {
171 if (getBit(parityBits,
sizeof(block_t)*8-skipped+k)) {
176 thisBlock = modifyBit(thisBlock, (
int) pow(2, skipped-k-1) , getBit(parityBits,
sizeof(block_t)*8-skipped+k));
180 thisBlock = modifyBit(thisBlock, 0, onCount & 1);
183 encoded[i] = thisBlock;
187 return p_print->write((
const uint8_t*)encoded,
sizeof(block_t)*block_ts+1);
190 bool decode(block_t input[],
int len) {
191 uint8_t* output = (uint8_t*)raw.
data();
194 int bits =
sizeof(block_t) * 8;
196 for (
int b = 0; b < (len/
sizeof(block_t)); b++) {
205 for (
int i = 1; i < bits; i++) {
207 if (getBit(input[b], i)) {
214 int errorLoc = multipleXor(onList, onCount);
219 if (!(onCount & 1 ^ getBit(input[b], 0))) {
220 LOGE(
"\nMore than one error detected. Aborting.\n");
226 input[b] = toggleBit(input[b], (bits-1) - errorLoc);
232 int messageBits = bits - log2(bits) - 1;
234 int currentBit, currentChar;
238 for (
int i = 0; i < len/
sizeof(block_t); i++) {
244 for (
int j = 0; j < bits; j++) {
247 if ((j & (j - 1)) == 0) {
253 currentBit = i*messageBits + (j-skipped);
256 currentChar = currentBit/(
sizeof(uint8_t)*8);
259 bool thisBit = getBit(input[i], j);
261 if (i != len/
sizeof(block_t)-1) {
264 output[currentChar] = modifyCharBit(output[currentChar], currentBit-currentChar*
sizeof(uint8_t)*8, thisBit);
268 uint8_ts = modifyBit(uint8_ts, j-skipped+(
sizeof(block_t)*8-messageBits), thisBit);
278 int multipleXor(
int *indicies,
int len) {
279 int val = indicies[0];
280 for (
int i = 1; i < len; i++) {
281 val = val ^ indicies[i];
286 block_t modifyBit(block_t n,
int p,
bool b) {
287 return ((n & ~(1 << (
sizeof(block_t)*8-1-p))) | (b << (
sizeof(block_t)*8-1-p)));
290 uint8_t modifyCharBit(uint8_t n,
int p,
bool b) {
291 return ((n & ~(1 << (
sizeof(uint8_t)*8-1-p))) | (b << (
sizeof(uint8_t)*8-1-p)));
294 bool getBit(block_t b,
int i) {
295 return (b << i) & (int) pow(2, (
sizeof(block_t)*8-1));
298 bool getCharBit(uint8_t b,
int i) {
299 return (b << i) & (int) pow(2, (
sizeof(uint8_t)*8-1));
302 block_t toggleBit(block_t b,
int i) {
306 int inList(uint8_t **list, uint8_t *testString,
int listLen) {
307 for (
int i = 0; i < listLen; i++) {
308 if (strcmp(list[i], testString) == 0) {