Formatted the entire codebase and added a CI check for formatting

This commit is contained in:
AlexandreRouma
2021-12-19 22:11:44 +01:00
parent 8644957881
commit ea587db0cb
161 changed files with 3302 additions and 3393 deletions

View File

@ -3,37 +3,36 @@
#include <inttypes.h>
// WTF???
extern "C"
{
extern "C" {
#include <correct.h>
}
const uint8_t toDB[] = {
0x00, 0x7b, 0xaf, 0xd4, 0x99, 0xe2, 0x36, 0x4d, 0xfa, 0x81, 0x55, 0x2e, 0x63, 0x18, 0xcc, 0xb7, 0x86, 0xfd, 0x29, 0x52, 0x1f,
0x64, 0xb0, 0xcb, 0x7c, 0x07, 0xd3, 0xa8, 0xe5, 0x9e, 0x4a, 0x31, 0xec, 0x97, 0x43, 0x38, 0x75, 0x0e, 0xda, 0xa1, 0x16, 0x6d, 0xb9, 0xc2, 0x8f, 0xf4,
0x20, 0x5b, 0x6a, 0x11, 0xc5, 0xbe, 0xf3, 0x88, 0x5c, 0x27, 0x90, 0xeb, 0x3f, 0x44, 0x09, 0x72, 0xa6, 0xdd, 0xef, 0x94, 0x40, 0x3b, 0x76, 0x0d, 0xd9,
0xa2, 0x15, 0x6e, 0xba, 0xc1, 0x8c, 0xf7, 0x23, 0x58, 0x69, 0x12, 0xc6, 0xbd, 0xf0, 0x8b, 0x5f, 0x24, 0x93, 0xe8, 0x3c, 0x47, 0x0a, 0x71, 0xa5, 0xde,
0x03, 0x78, 0xac, 0xd7, 0x9a, 0xe1, 0x35, 0x4e, 0xf9, 0x82, 0x56, 0x2d, 0x60, 0x1b, 0xcf, 0xb4, 0x85, 0xfe, 0x2a, 0x51, 0x1c, 0x67, 0xb3, 0xc8, 0x7f,
0x04, 0xd0, 0xab, 0xe6, 0x9d, 0x49, 0x32, 0x8d, 0xf6, 0x22, 0x59, 0x14, 0x6f, 0xbb, 0xc0, 0x77, 0x0c, 0xd8, 0xa3, 0xee, 0x95, 0x41, 0x3a, 0x0b, 0x70,
0xa4, 0xdf, 0x92, 0xe9, 0x3d, 0x46, 0xf1, 0x8a, 0x5e, 0x25, 0x68, 0x13, 0xc7, 0xbc, 0x61, 0x1a, 0xce, 0xb5, 0xf8, 0x83, 0x57, 0x2c, 0x9b, 0xe0, 0x34,
0x4f, 0x02, 0x79, 0xad, 0xd6, 0xe7, 0x9c, 0x48, 0x33, 0x7e, 0x05, 0xd1, 0xaa, 0x1d, 0x66, 0xb2, 0xc9, 0x84, 0xff, 0x2b, 0x50, 0x62, 0x19, 0xcd, 0xb6,
0xfb, 0x80, 0x54, 0x2f, 0x98, 0xe3, 0x37, 0x4c, 0x01, 0x7a, 0xae, 0xd5, 0xe4, 0x9f, 0x4b, 0x30, 0x7d, 0x06, 0xd2, 0xa9, 0x1e, 0x65, 0xb1, 0xca, 0x87,
0xfc, 0x28, 0x53, 0x8e, 0xf5, 0x21, 0x5a, 0x17, 0x6c, 0xb8, 0xc3, 0x74, 0x0f, 0xdb, 0xa0, 0xed, 0x96, 0x42, 0x39, 0x08, 0x73, 0xa7, 0xdc, 0x91, 0xea,
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
const uint8_t toDB[] = {
0x00, 0x7b, 0xaf, 0xd4, 0x99, 0xe2, 0x36, 0x4d, 0xfa, 0x81, 0x55, 0x2e, 0x63, 0x18, 0xcc, 0xb7, 0x86, 0xfd, 0x29, 0x52, 0x1f,
0x64, 0xb0, 0xcb, 0x7c, 0x07, 0xd3, 0xa8, 0xe5, 0x9e, 0x4a, 0x31, 0xec, 0x97, 0x43, 0x38, 0x75, 0x0e, 0xda, 0xa1, 0x16, 0x6d, 0xb9, 0xc2, 0x8f, 0xf4,
0x20, 0x5b, 0x6a, 0x11, 0xc5, 0xbe, 0xf3, 0x88, 0x5c, 0x27, 0x90, 0xeb, 0x3f, 0x44, 0x09, 0x72, 0xa6, 0xdd, 0xef, 0x94, 0x40, 0x3b, 0x76, 0x0d, 0xd9,
0xa2, 0x15, 0x6e, 0xba, 0xc1, 0x8c, 0xf7, 0x23, 0x58, 0x69, 0x12, 0xc6, 0xbd, 0xf0, 0x8b, 0x5f, 0x24, 0x93, 0xe8, 0x3c, 0x47, 0x0a, 0x71, 0xa5, 0xde,
0x03, 0x78, 0xac, 0xd7, 0x9a, 0xe1, 0x35, 0x4e, 0xf9, 0x82, 0x56, 0x2d, 0x60, 0x1b, 0xcf, 0xb4, 0x85, 0xfe, 0x2a, 0x51, 0x1c, 0x67, 0xb3, 0xc8, 0x7f,
0x04, 0xd0, 0xab, 0xe6, 0x9d, 0x49, 0x32, 0x8d, 0xf6, 0x22, 0x59, 0x14, 0x6f, 0xbb, 0xc0, 0x77, 0x0c, 0xd8, 0xa3, 0xee, 0x95, 0x41, 0x3a, 0x0b, 0x70,
0xa4, 0xdf, 0x92, 0xe9, 0x3d, 0x46, 0xf1, 0x8a, 0x5e, 0x25, 0x68, 0x13, 0xc7, 0xbc, 0x61, 0x1a, 0xce, 0xb5, 0xf8, 0x83, 0x57, 0x2c, 0x9b, 0xe0, 0x34,
0x4f, 0x02, 0x79, 0xad, 0xd6, 0xe7, 0x9c, 0x48, 0x33, 0x7e, 0x05, 0xd1, 0xaa, 0x1d, 0x66, 0xb2, 0xc9, 0x84, 0xff, 0x2b, 0x50, 0x62, 0x19, 0xcd, 0xb6,
0xfb, 0x80, 0x54, 0x2f, 0x98, 0xe3, 0x37, 0x4c, 0x01, 0x7a, 0xae, 0xd5, 0xe4, 0x9f, 0x4b, 0x30, 0x7d, 0x06, 0xd2, 0xa9, 0x1e, 0x65, 0xb1, 0xca, 0x87,
0xfc, 0x28, 0x53, 0x8e, 0xf5, 0x21, 0x5a, 0x17, 0x6c, 0xb8, 0xc3, 0x74, 0x0f, 0xdb, 0xa0, 0xed, 0x96, 0x42, 0x39, 0x08, 0x73, 0xa7, 0xdc, 0x91, 0xea,
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
};
const uint8_t fromDB[] = {
0x00, 0xcc, 0xac, 0x60, 0x79, 0xb5, 0xd5, 0x19, 0xf0, 0x3c, 0x5c, 0x90, 0x89, 0x45, 0x25, 0xe9, 0xfd, 0x31, 0x51, 0x9d,
0x84, 0x48, 0x28, 0xe4, 0x0d, 0xc1, 0xa1, 0x6d, 0x74, 0xb8, 0xd8, 0x14, 0x2e, 0xe2, 0x82, 0x4e, 0x57, 0x9b, 0xfb, 0x37, 0xde, 0x12, 0x72, 0xbe, 0xa7,
0x6b, 0x0b, 0xc7, 0xd3, 0x1f, 0x7f, 0xb3, 0xaa, 0x66, 0x06, 0xca, 0x23, 0xef, 0x8f, 0x43, 0x5a, 0x96, 0xf6, 0x3a, 0x42, 0x8e, 0xee, 0x22, 0x3b, 0xf7,
0x97, 0x5b, 0xb2, 0x7e, 0x1e, 0xd2, 0xcb, 0x07, 0x67, 0xab, 0xbf, 0x73, 0x13, 0xdf, 0xc6, 0x0a, 0x6a, 0xa6, 0x4f, 0x83, 0xe3, 0x2f, 0x36, 0xfa, 0x9a,
0x56, 0x6c, 0xa0, 0xc0, 0x0c, 0x15, 0xd9, 0xb9, 0x75, 0x9c, 0x50, 0x30, 0xfc, 0xe5, 0x29, 0x49, 0x85, 0x91, 0x5d, 0x3d, 0xf1, 0xe8, 0x24, 0x44, 0x88,
0x61, 0xad, 0xcd, 0x01, 0x18, 0xd4, 0xb4, 0x78, 0xc5, 0x09, 0x69, 0xa5, 0xbc, 0x70, 0x10, 0xdc, 0x35, 0xf9, 0x99, 0x55, 0x4c, 0x80, 0xe0, 0x2c, 0x38,
0xf4, 0x94, 0x58, 0x41, 0x8d, 0xed, 0x21, 0xc8, 0x04, 0x64, 0xa8, 0xb1, 0x7d, 0x1d, 0xd1, 0xeb, 0x27, 0x47, 0x8b, 0x92, 0x5e, 0x3e, 0xf2, 0x1b, 0xd7,
0xb7, 0x7b, 0x62, 0xae, 0xce, 0x02, 0x16, 0xda, 0xba, 0x76, 0x6f, 0xa3, 0xc3, 0x0f, 0xe6, 0x2a, 0x4a, 0x86, 0x9f, 0x53, 0x33, 0xff, 0x87, 0x4b, 0x2b,
0xe7, 0xfe, 0x32, 0x52, 0x9e, 0x77, 0xbb, 0xdb, 0x17, 0x0e, 0xc2, 0xa2, 0x6e, 0x7a, 0xb6, 0xd6, 0x1a, 0x03, 0xcf, 0xaf, 0x63, 0x8a, 0x46, 0x26, 0xea,
0xf3, 0x3f, 0x5f, 0x93, 0xa9, 0x65, 0x05, 0xc9, 0xd0, 0x1c, 0x7c, 0xb0, 0x59, 0x95, 0xf5, 0x39, 0x20, 0xec, 0x8c, 0x40, 0x54, 0x98, 0xf8, 0x34, 0x2d,
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
0x84, 0x48, 0x28, 0xe4, 0x0d, 0xc1, 0xa1, 0x6d, 0x74, 0xb8, 0xd8, 0x14, 0x2e, 0xe2, 0x82, 0x4e, 0x57, 0x9b, 0xfb, 0x37, 0xde, 0x12, 0x72, 0xbe, 0xa7,
0x6b, 0x0b, 0xc7, 0xd3, 0x1f, 0x7f, 0xb3, 0xaa, 0x66, 0x06, 0xca, 0x23, 0xef, 0x8f, 0x43, 0x5a, 0x96, 0xf6, 0x3a, 0x42, 0x8e, 0xee, 0x22, 0x3b, 0xf7,
0x97, 0x5b, 0xb2, 0x7e, 0x1e, 0xd2, 0xcb, 0x07, 0x67, 0xab, 0xbf, 0x73, 0x13, 0xdf, 0xc6, 0x0a, 0x6a, 0xa6, 0x4f, 0x83, 0xe3, 0x2f, 0x36, 0xfa, 0x9a,
0x56, 0x6c, 0xa0, 0xc0, 0x0c, 0x15, 0xd9, 0xb9, 0x75, 0x9c, 0x50, 0x30, 0xfc, 0xe5, 0x29, 0x49, 0x85, 0x91, 0x5d, 0x3d, 0xf1, 0xe8, 0x24, 0x44, 0x88,
0x61, 0xad, 0xcd, 0x01, 0x18, 0xd4, 0xb4, 0x78, 0xc5, 0x09, 0x69, 0xa5, 0xbc, 0x70, 0x10, 0xdc, 0x35, 0xf9, 0x99, 0x55, 0x4c, 0x80, 0xe0, 0x2c, 0x38,
0xf4, 0x94, 0x58, 0x41, 0x8d, 0xed, 0x21, 0xc8, 0x04, 0x64, 0xa8, 0xb1, 0x7d, 0x1d, 0xd1, 0xeb, 0x27, 0x47, 0x8b, 0x92, 0x5e, 0x3e, 0xf2, 0x1b, 0xd7,
0xb7, 0x7b, 0x62, 0xae, 0xce, 0x02, 0x16, 0xda, 0xba, 0x76, 0x6f, 0xa3, 0xc3, 0x0f, 0xe6, 0x2a, 0x4a, 0x86, 0x9f, 0x53, 0x33, 0xff, 0x87, 0x4b, 0x2b,
0xe7, 0xfe, 0x32, 0x52, 0x9e, 0x77, 0xbb, 0xdb, 0x17, 0x0e, 0xc2, 0xa2, 0x6e, 0x7a, 0xb6, 0xd6, 0x1a, 0x03, 0xcf, 0xaf, 0x63, 0x8a, 0x46, 0x26, 0xea,
0xf3, 0x3f, 0x5f, 0x93, 0xa9, 0x65, 0x05, 0xc9, 0xd0, 0x1c, 0x7c, 0xb0, 0x59, 0x95, 0xf5, 0x39, 0x20, 0xec, 0x8c, 0x40, 0x54, 0x98, 0xf8, 0x34, 0x2d,
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
};
const uint8_t randVals[] = {
@ -73,7 +72,7 @@ namespace dsp {
for (int i = 0; i < 5; i++) { memset(outBuffers[i], 0, 255); }
rs = correct_reed_solomon_create(correct_rs_primitive_polynomial_ccsds, 120, 11, 16);
if (rs == NULL) { printf("Error creating the reed solomon decoder\n"); }
generic_block<FalconRS>::registerInput(_in);
generic_block<FalconRS>::registerOutput(&out);
}
@ -85,29 +84,44 @@ namespace dsp {
uint8_t* data = _in->readBuf + 4;
// Deinterleave
for (int i = 0; i < 255*5; i++) {
buffers[i%5][i/5] = fromDB[data[i]];
for (int i = 0; i < 255 * 5; i++) {
buffers[i % 5][i / 5] = fromDB[data[i]];
}
// Reed the solomon :weary:
int result = 0;
result = correct_reed_solomon_decode(rs, buffers[0], 255, outBuffers[0]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[1], 255, outBuffers[1]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[2], 255, outBuffers[2]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[3], 255, outBuffers[3]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[4], 255, outBuffers[4]);
if (result == -1) { _in->flush(); return count; }
// Reinterleave
for (int i = 0; i < 255*5; i++) {
out.writeBuf[i] = toDB[outBuffers[i%5][i/5]] ^ randVals[i % 255];
if (result == -1) {
_in->flush();
return count;
}
out.swap(255*5);
// Reinterleave
for (int i = 0; i < 255 * 5; i++) {
out.writeBuf[i] = toDB[outBuffers[i % 5][i / 5]] ^ randVals[i % 255];
}
out.swap(255 * 5);
_in->flush();
return count;
@ -120,8 +134,7 @@ namespace dsp {
uint8_t buffers[5][255];
uint8_t outBuffers[5][255];
correct_reed_solomon* rs;
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
}

View File

@ -20,7 +20,7 @@ namespace dsp {
void init(stream<uint8_t>* in) {
_in = in;
generic_block<FalconPacketSync>::registerInput(_in);
generic_block<FalconPacketSync>::registerOutput(&out);
}
@ -56,7 +56,7 @@ namespace dsp {
else if (header.packet == 2047) {
printf("Wow, all data\n");
_in->flush();
return count;
return count;
}
// Finish reading the last package and send it
@ -84,9 +84,8 @@ namespace dsp {
packetRead = -1;
break;
}
uint64_t pktId = ((uint64_t)data[i + 2] << 56) | ((uint64_t)data[i + 3] << 48) | ((uint64_t)data[i + 4] << 40) | ((uint64_t)data[i + 5] << 32)
| ((uint64_t)data[i + 6] << 24) | ((uint64_t)data[i + 7] << 16) | ((uint64_t)data[i + 8] << 8) | data[i + 9];
uint64_t pktId = ((uint64_t)data[i + 2] << 56) | ((uint64_t)data[i + 3] << 48) | ((uint64_t)data[i + 4] << 40) | ((uint64_t)data[i + 5] << 32) | ((uint64_t)data[i + 6] << 24) | ((uint64_t)data[i + 7] << 16) | ((uint64_t)data[i + 8] << 8) | data[i + 9];
// If the packet doesn't fit the frame, save and go to next frame
if (dataLen - i < length) {
@ -99,7 +98,6 @@ namespace dsp {
memcpy(out.writeBuf, &data[i], length);
out.swap(length);
i += length;
}
_in->flush();
@ -114,8 +112,7 @@ namespace dsp {
int packetRead = -1;
uint8_t packet[0x4008];
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
}

View File

@ -23,9 +23,9 @@
#include <fstream>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "falcon9_decoder",
/* Description: */ "Falcon9 telemetry decoder for SDR++",
/* Author: */ "Ryzerth",
@ -33,7 +33,7 @@ SDRPP_MOD_INFO {
/* Max instances */ -1
};
#define INPUT_SAMPLE_RATE 6000000
#define INPUT_SAMPLE_RATE 6000000
std::ofstream file("output.ts");
@ -84,7 +84,6 @@ public:
}
~Falcon9DecoderModule() {
}
void postInit() {}
@ -187,10 +186,9 @@ private:
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
uint16_t length = (((data[0] & 0b1111) << 8) | data[1]) + 2;
uint64_t pktId = ((uint64_t)data[2] << 56) | ((uint64_t)data[3] << 48) | ((uint64_t)data[4] << 40) | ((uint64_t)data[5] << 32)
| ((uint64_t)data[6] << 24) | ((uint64_t)data[7] << 16) | ((uint64_t)data[8] << 8) | data[9];
uint64_t pktId = ((uint64_t)data[2] << 56) | ((uint64_t)data[3] << 48) | ((uint64_t)data[4] << 40) | ((uint64_t)data[5] << 32) | ((uint64_t)data[6] << 24) | ((uint64_t)data[7] << 16) | ((uint64_t)data[8] << 8) | data[9];
if (pktId == 0x0117FE0800320303 || pktId == 0x0112FA0800320303) {
if (pktId == 0x0117FE0800320303 || pktId == 0x0112FA0800320303) {
data[length - 2] = 0;
_this->logsMtx.lock();
_this->gpsLogs += (char*)(data + 25);
@ -207,13 +205,13 @@ private:
static void symSinkHandler(float* data, int count, void* ctx) {
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
float* buf = _this->symDiag.acquireBuffer();
memcpy(buf, data, 1024*sizeof(float));
memcpy(buf, data, 1024 * sizeof(float));
_this->symDiag.releaseBuffer();
}
std::string name;
bool enabled = true;
bool logsVisible = false;
std::mutex logsMtx;
@ -232,7 +230,7 @@ private:
dsp::stream<float> thrInput;
dsp::Threshold thr;
uint8_t syncWord[32] = {0,0,0,1,1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,1};
uint8_t syncWord[32] = { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1 };
dsp::Deframer deframe;
dsp::FalconRS falconRS;
dsp::FalconPacketSync pkt;
@ -243,7 +241,6 @@ private:
VFOManager::VFO* vfo;
ImGui::SymbolDiagram symDiag;
};
MOD_EXPORT void _INIT_() {

View File

@ -1,11 +1,11 @@
#include <base40.h>
void decode_callsign_base40(uint64_t encoded, char *callsign) {
void decode_callsign_base40(uint64_t encoded, char* callsign) {
if (encoded >= 262144000000000) { // 40^9
*callsign = 0;
return;
}
char *p = callsign;
char* p = callsign;
for (; encoded > 0; p++) {
*p = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."[encoded % 40];
encoded /= 40;

View File

@ -6,67 +6,57 @@
#include <array>
#include <cstddef>
namespace mobilinkd
{
namespace mobilinkd {
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
struct CRC16
{
static constexpr uint16_t MASK = 0xFFFF;
static constexpr uint16_t LSB = 0x0001;
static constexpr uint16_t MSB = 0x8000;
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
struct CRC16 {
static constexpr uint16_t MASK = 0xFFFF;
static constexpr uint16_t LSB = 0x0001;
static constexpr uint16_t MSB = 0x8000;
uint16_t reg_ = Init;
uint16_t reg_ = Init;
void reset()
{
reg_ = Init;
void reset() {
reg_ = Init;
for (size_t i = 0; i != 16; ++i)
{
auto bit = reg_ & LSB;
if (bit) reg_ ^= Poly;
reg_ >>= 1;
if (bit) reg_ |= MSB;
for (size_t i = 0; i != 16; ++i) {
auto bit = reg_ & LSB;
if (bit) reg_ ^= Poly;
reg_ >>= 1;
if (bit) reg_ |= MSB;
}
reg_ &= MASK;
}
reg_ &= MASK;
}
void operator()(uint8_t byte)
{
reg_ = crc(byte, reg_);
}
uint16_t crc(uint8_t byte, uint16_t reg)
{
for (size_t i = 0; i != 8; ++i)
{
auto msb = reg & MSB;
reg = ((reg << 1) & MASK) | ((byte >> (7 - i)) & LSB);
if (msb) reg ^= Poly;
void operator()(uint8_t byte) {
reg_ = crc(byte, reg_);
}
return reg & MASK;
}
uint16_t get()
{
auto reg = reg_;
for (size_t i = 0; i != 16; ++i)
{
auto msb = reg & MSB;
reg = ((reg << 1) & MASK);
if (msb) reg ^= Poly;
uint16_t crc(uint8_t byte, uint16_t reg) {
for (size_t i = 0; i != 8; ++i) {
auto msb = reg & MSB;
reg = ((reg << 1) & MASK) | ((byte >> (7 - i)) & LSB);
if (msb) reg ^= Poly;
}
return reg & MASK;
}
return reg;
}
std::array<uint8_t, 2> get_bytes()
{
auto crc = get();
std::array<uint8_t, 2> result{uint8_t((crc >> 8) & 0xFF), uint8_t(crc & 0xFF)};
return result;
}
};
uint16_t get() {
auto reg = reg_;
for (size_t i = 0; i != 16; ++i) {
auto msb = reg & MSB;
reg = ((reg << 1) & MASK);
if (msb) reg ^= Poly;
}
return reg;
}
std::array<uint8_t, 2> get_bytes() {
auto crc = get();
std::array<uint8_t, 2> result{ uint8_t((crc >> 8) & 0xFF), uint8_t(crc & 0xFF) };
return result;
}
};
} // mobilinkd

View File

@ -10,224 +10,194 @@
namespace mobilinkd {
// Parts are adapted from:
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
// Parts are adapted from:
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
namespace Golay24
{
namespace Golay24 {
int popcount(uint32_t n) {
int count = 0;
for (int i = 0; i < 32; i++) {
count += ((n >> i) & 1);
int popcount(uint32_t n) {
int count = 0;
for (int i = 0; i < 32; i++) {
count += ((n >> i) & 1);
}
return count;
}
return count;
}
namespace detail
{
namespace detail {
// Need a constexpr sort.
// https://stackoverflow.com/a/40030044/854133
template<class T>
void swap(T& l, T& r)
{
T tmp = std::move(l);
l = std::move(r);
r = std::move(tmp);
}
// Need a constexpr sort.
// https://stackoverflow.com/a/40030044/854133
template <class T>
void swap(T& l, T& r) {
T tmp = std::move(l);
l = std::move(r);
r = std::move(tmp);
}
template <typename T, size_t N>
struct array
{
constexpr T& operator[](size_t i)
{
return arr[i];
}
template <typename T, size_t N>
struct array {
constexpr T& operator[](size_t i) {
return arr[i];
}
constexpr const T& operator[](size_t i) const
{
return arr[i];
}
constexpr const T& operator[](size_t i) const {
return arr[i];
}
constexpr const T* begin() const
{
return arr;
}
constexpr const T* end() const
{
return arr + N;
}
constexpr const T* begin() const {
return arr;
}
constexpr const T* end() const {
return arr + N;
}
T arr[N];
};
T arr[N];
};
template <typename T, size_t N>
void sort_impl(array<T, N> &array, size_t left, size_t right)
{
if (left < right)
{
size_t m = left;
template <typename T, size_t N>
void sort_impl(array<T, N>& array, size_t left, size_t right) {
if (left < right) {
size_t m = left;
for (size_t i = left + 1; i<right; i++)
if (array[i]<array[left])
swap(array[++m], array[i]);
for (size_t i = left + 1; i < right; i++)
if (array[i] < array[left])
swap(array[++m], array[i]);
swap(array[left], array[m]);
swap(array[left], array[m]);
sort_impl(array, left, m);
sort_impl(array, m + 1, right);
}
}
sort_impl(array, left, m);
sort_impl(array, m + 1, right);
}
}
template <typename T, size_t N>
array<T, N> sort(array<T, N> array)
{
auto sorted = array;
sort_impl(sorted, 0, N);
return sorted;
}
template <typename T, size_t N>
array<T, N> sort(array<T, N> array) {
auto sorted = array;
sort_impl(sorted, 0, N);
return sorted;
}
} // detail
} // detail
// static constexpr uint16_t POLY = 0xAE3;
constexpr uint16_t POLY = 0xC75;
// static constexpr uint16_t POLY = 0xAE3;
constexpr uint16_t POLY = 0xC75;
#pragma pack(push, 1)
struct SyndromeMapEntry
{
uint32_t a{0};
uint16_t b{0};
};
struct SyndromeMapEntry {
uint32_t a{ 0 };
uint16_t b{ 0 };
};
#pragma pack(pop)
/**
/**
* Calculate the syndrome of a [23,12] Golay codeword.
*
* @return the 11-bit syndrome of the codeword in bits [22:12].
*/
uint32_t syndrome(uint32_t codeword)
{
codeword &= 0xffffffl;
for (size_t i = 0; i != 12; ++i)
{
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return (codeword << 12);
}
bool parity(uint32_t codeword)
{
return popcount(codeword) & 1;
}
SyndromeMapEntry makeSyndromeMapEntry(uint64_t val)
{
return SyndromeMapEntry{uint32_t(val >> 16), uint16_t(val & 0xFFFF)};
}
uint64_t makeSME(uint64_t syndrome, uint32_t bits)
{
return (syndrome << 24) | (bits & 0xFFFFFF);
}
constexpr size_t LUT_SIZE = 2048;
std::array<SyndromeMapEntry, LUT_SIZE> make_lut()
{
constexpr size_t VECLEN=23;
detail::array<uint64_t, LUT_SIZE> result{};
size_t index = 0;
result[index++] = makeSME(syndrome(0), 0);
for (size_t i = 0; i != VECLEN; ++i)
{
auto v = (1 << i);
result[index++] = makeSME(syndrome(v), v);
}
for (size_t i = 0; i != VECLEN - 1; ++i)
{
for (size_t j = i + 1; j != VECLEN; ++j)
{
auto v = (1 << i) | (1 << j);
result[index++] = makeSME(syndrome(v), v);
uint32_t syndrome(uint32_t codeword) {
codeword &= 0xffffffl;
for (size_t i = 0; i != 12; ++i) {
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return (codeword << 12);
}
}
for (size_t i = 0; i != VECLEN - 2; ++i)
{
for (size_t j = i + 1; j != VECLEN - 1; ++j)
{
for (size_t k = j + 1; k != VECLEN; ++k)
{
auto v = (1 << i) | (1 << j) | (1 << k);
bool parity(uint32_t codeword) {
return popcount(codeword) & 1;
}
SyndromeMapEntry makeSyndromeMapEntry(uint64_t val) {
return SyndromeMapEntry{ uint32_t(val >> 16), uint16_t(val & 0xFFFF) };
}
uint64_t makeSME(uint64_t syndrome, uint32_t bits) {
return (syndrome << 24) | (bits & 0xFFFFFF);
}
constexpr size_t LUT_SIZE = 2048;
std::array<SyndromeMapEntry, LUT_SIZE> make_lut() {
constexpr size_t VECLEN = 23;
detail::array<uint64_t, LUT_SIZE> result{};
size_t index = 0;
result[index++] = makeSME(syndrome(0), 0);
for (size_t i = 0; i != VECLEN; ++i) {
auto v = (1 << i);
result[index++] = makeSME(syndrome(v), v);
}
for (size_t i = 0; i != VECLEN - 1; ++i) {
for (size_t j = i + 1; j != VECLEN; ++j) {
auto v = (1 << i) | (1 << j);
result[index++] = makeSME(syndrome(v), v);
}
}
for (size_t i = 0; i != VECLEN - 2; ++i) {
for (size_t j = i + 1; j != VECLEN - 1; ++j) {
for (size_t k = j + 1; k != VECLEN; ++k) {
auto v = (1 << i) | (1 << j) | (1 << k);
result[index++] = makeSME(syndrome(v), v);
}
}
}
result = detail::sort(result);
std::array<SyndromeMapEntry, LUT_SIZE> tmp;
for (size_t i = 0; i != LUT_SIZE; ++i) {
tmp[i] = makeSyndromeMapEntry(result[i]);
}
return tmp;
}
}
result = detail::sort(result);
inline auto LUT = make_lut();
std::array<SyndromeMapEntry, LUT_SIZE> tmp;
for (size_t i = 0; i != LUT_SIZE; ++i)
{
tmp[i] = makeSyndromeMapEntry(result[i]);
}
return tmp;
}
inline auto LUT = make_lut();
/**
/**
* Calculate [23,12] Golay codeword.
*
* @return checkbits(11)|data(12).
*/
uint32_t encode23(uint16_t data)
{
// data &= 0xfff;
uint32_t codeword = data;
for (size_t i = 0; i != 12; ++i)
{
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return codeword | (data << 11);
}
uint32_t encode23(uint16_t data) {
// data &= 0xfff;
uint32_t codeword = data;
for (size_t i = 0; i != 12; ++i) {
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return codeword | (data << 11);
}
uint32_t encode24(uint16_t data)
{
auto codeword = encode23(data);
return ((codeword << 1) | parity(codeword));
}
uint32_t encode24(uint16_t data) {
auto codeword = encode23(data);
return ((codeword << 1) | parity(codeword));
}
bool decode(uint32_t input, uint32_t& output)
{
auto syndrm = syndrome(input >> 1);
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
[](const SyndromeMapEntry& sme, uint32_t val){
return (sme.a >> 8) < val;
});
bool decode(uint32_t input, uint32_t& output) {
auto syndrm = syndrome(input >> 1);
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
[](const SyndromeMapEntry& sme, uint32_t val) {
return (sme.a >> 8) < val;
});
if ((it->a >> 8) == syndrm)
{
// Build the correction from the compressed entry.
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
// Apply the correction to the input.
output = input ^ correction;
// Only test parity for 3-bit errors.
return popcount(syndrm) < 3 || !parity(output);
}
if ((it->a >> 8) == syndrm) {
// Build the correction from the compressed entry.
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
// Apply the correction to the input.
output = input ^ correction;
// Only test parity for 3-bit errors.
return popcount(syndrm) < 3 || !parity(output);
}
return false;
}
return false;
}
} // Golay24
} // Golay24
} // mobilinkd

View File

@ -31,7 +31,7 @@ M17LSF M17DecodeLSF(uint8_t* _lsf) {
// Extract CRC
lsf.rawCRC = 0;
for (int i = 0; i < 16; i++) {
lsf.rawCRC |= (((uint16_t)_lsf[(i+48+48+16+112) / 8] >> (7 - (i%8))) & 1) << (15 - i);
lsf.rawCRC |= (((uint16_t)_lsf[(i + 48 + 48 + 16 + 112) / 8] >> (7 - (i % 8))) & 1) << (15 - i);
}
// Check CRC
@ -50,19 +50,19 @@ M17LSF M17DecodeLSF(uint8_t* _lsf) {
// Extract DST
lsf.rawDst = 0;
for (int i = 0; i < 48; i++) {
lsf.rawDst |= (((uint64_t)_lsf[i / 8] >> (7 - (i%8))) & 1) << (47 - i);
lsf.rawDst |= (((uint64_t)_lsf[i / 8] >> (7 - (i % 8))) & 1) << (47 - i);
}
// Extract SRC
lsf.rawSrc = 0;
for (int i = 0; i < 48; i++) {
lsf.rawSrc |= (((uint64_t)_lsf[(i+48) / 8] >> (7 - (i%8))) & 1) << (47 - i);
lsf.rawSrc |= (((uint64_t)_lsf[(i + 48) / 8] >> (7 - (i % 8))) & 1) << (47 - i);
}
// Extract TYPE
lsf.rawType = 0;
for (int i = 0; i < 16; i++) {
lsf.rawType |= (((uint16_t)_lsf[(i+48+48) / 8] >> (7 - (i%8))) & 1) << (15 - i);
lsf.rawType |= (((uint16_t)_lsf[(i + 48 + 48) / 8] >> (7 - (i % 8))) & 1) << (15 - i);
}
// Extract META

View File

@ -3,17 +3,17 @@
#include <stdint.h>
enum M17DataType {
M17_DATATYPE_UNKNOWN = 0b00,
M17_DATATYPE_DATA = 0b01,
M17_DATATYPE_VOICE = 0b10,
M17_DATATYPE_UNKNOWN = 0b00,
M17_DATATYPE_DATA = 0b01,
M17_DATATYPE_VOICE = 0b10,
M17_DATATYPE_DATA_VOICE = 0b11
};
enum M17EncryptionType {
M17_ENCRYPTION_NONE = 0b00,
M17_ENCRYPTION_AES = 0b01,
M17_ENCRYPTION_NONE = 0b00,
M17_ENCRYPTION_AES = 0b01,
M17_ENCRYPTION_SCRAMBLE = 0b10,
M17_ENCRYPTION_UNKNOWN = 0b11
M17_ENCRYPTION_UNKNOWN = 0b11
};
extern const char* M17DataTypesTxt[4];

View File

@ -7,50 +7,50 @@
#include <lsf_decode.h>
extern "C" {
#include <correct.h>
#include <correct.h>
}
#define M17_DEVIATION 2400.0f
#define M17_BAUDRATE 4800.0f
#define M17_RRC_ALPHA 0.5f
#define M17_4FSK_HIGH_CUT 0.5f
#define M17_DEVIATION 2400.0f
#define M17_BAUDRATE 4800.0f
#define M17_RRC_ALPHA 0.5f
#define M17_4FSK_HIGH_CUT 0.5f
#define M17_SYNC_SIZE 16
#define M17_LICH_SIZE 96
#define M17_PAYLOAD_SIZE 144
#define M17_ENCODED_PAYLOAD_SIZE 296
#define M17_LSF_SIZE 240
#define M17_ENCODED_LSF_SIZE 488
#define M17_RAW_FRAME_SIZE 384
#define M17_CUT_FRAME_SIZE 368
#define M17_SYNC_SIZE 16
#define M17_LICH_SIZE 96
#define M17_PAYLOAD_SIZE 144
#define M17_ENCODED_PAYLOAD_SIZE 296
#define M17_LSF_SIZE 240
#define M17_ENCODED_LSF_SIZE 488
#define M17_RAW_FRAME_SIZE 384
#define M17_CUT_FRAME_SIZE 368
const uint8_t M17_LSF_SYNC[16] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1 };
const uint8_t M17_STF_SYNC[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 };
const uint8_t M17_PKF_SYNC[16] = { 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
const uint8_t M17_LSF_SYNC[16] = { 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1 };
const uint8_t M17_STF_SYNC[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 };
const uint8_t M17_PKF_SYNC[16] = { 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
const uint8_t M17_SCRAMBLER[368] = { 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0,
0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1,
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1,
0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0,
1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0,
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1,
1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 };
const uint8_t M17_SCRAMBLER[368] = { 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0,
0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1,
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1,
0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0,
1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0,
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1,
1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 };
const uint16_t M17_INTERLEAVER[368] = { 0, 137, 90, 227, 180, 317, 270, 39, 360, 129, 82, 219, 172, 309, 262, 31,
352, 121, 74, 211, 164, 301, 254, 23, 344, 113, 66, 203, 156, 293, 246, 15,
@ -83,7 +83,7 @@ const uint8_t M17_PUNCTURING_P1[61] = { 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1
const uint8_t M17_PUNCTURING_P2[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 };
static const correct_convolutional_polynomial_t correct_conv_m17_polynomial[] = {0b11001, 0b10111};
static const correct_convolutional_polynomial_t correct_conv_m17_polynomial[] = { 0b11001, 0b10111 };
namespace dsp {
class M17Slice4FSK : public generic_block<M17Slice4FSK> {
@ -116,8 +116,8 @@ namespace dsp {
float val;
for (int i = 0; i < count; i++) {
val = _in->readBuf[i];
out.writeBuf[i*2] = (val < 0.0f);
out.writeBuf[(i*2)+1] = (fabsf(val) > M17_4FSK_HIGH_CUT);
out.writeBuf[i * 2] = (val < 0.0f);
out.writeBuf[(i * 2) + 1] = (fabsf(val) > M17_4FSK_HIGH_CUT);
}
_in->flush();
@ -130,7 +130,6 @@ namespace dsp {
private:
stream<float>* _in;
};
class M17FrameDemux : public generic_block<M17FrameDemux> {
@ -176,7 +175,10 @@ namespace dsp {
for (int i = 0; i < count;) {
if (detect) {
if (outCount < M17_SYNC_SIZE) { outCount++; i++; }
if (outCount < M17_SYNC_SIZE) {
outCount++;
i++;
}
else {
int id = M17_INTERLEAVER[outCount - M17_SYNC_SIZE];
@ -192,21 +194,21 @@ namespace dsp {
else if (type == 2) {
packetOut.writeBuf[id - M17_LICH_SIZE] = (delay[i++] ^ M17_SCRAMBLER[outCount - M17_SYNC_SIZE]);
}
outCount++;
}
if (outCount >= M17_RAW_FRAME_SIZE) {
detect = false;
if (type == 0) {
if (!linkSetupOut.swap(M17_CUT_FRAME_SIZE)) { return -1; }
}
else if (type == 1) {
if (!lichOut.swap(M17_LICH_SIZE)) {return -1; }
if (!streamOut.swap(M17_CUT_FRAME_SIZE)) {return -1; }
if (!lichOut.swap(M17_LICH_SIZE)) { return -1; }
if (!streamOut.swap(M17_CUT_FRAME_SIZE)) { return -1; }
}
else if (type == 2) {
if (!lichOut.swap(M17_LICH_SIZE)) {return -1; }
if (!lichOut.swap(M17_LICH_SIZE)) { return -1; }
if (!packetOut.swap(M17_CUT_FRAME_SIZE)) { return -1; }
}
}
@ -242,7 +244,7 @@ namespace dsp {
i++;
}
memmove(delay, &delay[count], 16);
_in->flush();
@ -264,7 +266,6 @@ namespace dsp {
int type;
int outCount = 0;
};
class M17LSFDecoder : public generic_block<M17LSFDecoder> {
@ -283,7 +284,7 @@ namespace dsp {
_in = in;
_handler = handler;
_ctx = ctx;
conv = correct_convolutional_create(2, 5, correct_conv_m17_polynomial);
generic_block<M17LSFDecoder>::registerInput(_in);
@ -319,7 +320,7 @@ namespace dsp {
// Pack into bytes
memset(packed, 0, 61);
for (int i = 0; i < M17_ENCODED_LSF_SIZE; i++) {
packed[i/8] |= depunctured[i] << (7 - (i%8));
packed[i / 8] |= depunctured[i] << (7 - (i % 8));
}
// Run through convolutional decoder
@ -343,7 +344,6 @@ namespace dsp {
uint8_t lsf[30];
correct_convolutional* conv;
};
class M17PayloadFEC : public generic_block<M17PayloadFEC> {
@ -360,7 +360,7 @@ namespace dsp {
void init(stream<uint8_t>* in) {
_in = in;
conv = correct_convolutional_create(2, 5, correct_conv_m17_polynomial);
generic_block<M17PayloadFEC>::registerInput(_in);
@ -395,13 +395,13 @@ namespace dsp {
// Pack into bytes
memset(packed, 0, 37);
for (int i = 0; i < M17_ENCODED_PAYLOAD_SIZE; i++) {
if (!(i%8)) { packed[i/8] = 0; }
packed[i/8] |= depunctured[i] << (7 - (i%8));
if (!(i % 8)) { packed[i / 8] = 0; }
packed[i / 8] |= depunctured[i] << (7 - (i % 8));
}
// Run through convolutional decoder
correct_convolutional_decode(conv, packed, M17_ENCODED_PAYLOAD_SIZE, out.writeBuf);
_in->flush();
if (!out.swap(M17_PAYLOAD_SIZE / 8)) { return -1; }
@ -417,7 +417,6 @@ namespace dsp {
uint8_t packed[37];
correct_convolutional* conv;
};
class M17Codec2Decode : public generic_block<M17Codec2Decode> {
@ -464,7 +463,7 @@ namespace dsp {
// Decode both parts using codec
codec2_decode(codec, int16Audio, &_in->readBuf[2]);
codec2_decode(codec, &int16Audio[sampsPerC2Frame], &_in->readBuf[2+8]);
codec2_decode(codec, &int16Audio[sampsPerC2Frame], &_in->readBuf[2 + 8]);
// Convert to float
volk_16i_s32f_convert_32f(floatAudio, int16Audio, 32768.0f, sampsPerC2FrameDouble);
@ -489,7 +488,6 @@ namespace dsp {
CODEC2* codec;
int sampsPerC2Frame = 0;
int sampsPerC2FrameDouble = 0;
};
class M17LICHDecoder : public generic_block<M17LICHDecoder> {
@ -543,7 +541,7 @@ namespace dsp {
uint8_t temp;
for (int i = 0; i < 12; i++) {
id = (b * 12) + i;
chunk[id / 8] |= ((decodedBlock >> (23 - i)) & 1) << (7 - (id%8));
chunk[id / 8] |= ((decodedBlock >> (23 - i)) & 1) << (7 - (id % 8));
}
}
@ -555,7 +553,7 @@ namespace dsp {
if (partId == 0) {
newFrame = true;
lastId = 0;
memcpy(&lsf[partId*5], chunk, 5);
memcpy(&lsf[partId * 5], chunk, 5);
return count;
}
@ -568,7 +566,7 @@ namespace dsp {
// If we're recording and there's no discontinuity (see above), add the data to the full frame
if (newFrame) {
lastId = partId;
memcpy(&lsf[partId*5], chunk, 5);
memcpy(&lsf[partId * 5], chunk, 5);
// If the lsf is complete, send it out
if (partId == 5) {
@ -590,7 +588,6 @@ namespace dsp {
uint8_t lsf[240];
bool newFrame = false;
int lastId = 0;
};
class M17Decoder : public generic_hier_block<M17Decoder> {
@ -620,7 +617,7 @@ namespace dsp {
diagOut = &doubler.outB;
out = &decodeAudio.out;
generic_hier_block<M17Decoder>::registerBlock(&demod);
generic_hier_block<M17Decoder>::registerBlock(&fir);
generic_hier_block<M17Decoder>::registerBlock(&recov);
@ -661,7 +658,6 @@ namespace dsp {
NullSink<uint8_t> ns2;
float _sampleRate;
float _sampleRate;
};
}

View File

@ -21,9 +21,9 @@
#include <fstream>
#include <chrono>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "m17_decoder",
/* Description: */ "M17 Digital Voice Decoder for SDR++",
/* Author: */ "Ryzerth",
@ -84,7 +84,7 @@ public:
sigpath::sinkManager.registerStream(name, &stream);
stream.start();
gui::menu.registerEntry(name, menuHandler, this, this);
}
@ -107,7 +107,7 @@ public:
void enable() {
double bw = gui::waterfall.getBandwidth();
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double>(0, -bw/2.0, bw/2.0), 9600, INPUT_SAMPLE_RATE, 9600, 9600, true);
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double>(0, -bw / 2.0, bw / 2.0), 9600, INPUT_SAMPLE_RATE, 9600, 9600, true);
vfo->setSnapInterval(250);
// Set Input of demod here
@ -152,7 +152,7 @@ private:
std::lock_guard lck(_this->lsfMtx);
auto now = std::chrono::high_resolution_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now-_this->lastUpdated).count() > 1000) {
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - _this->lastUpdated).count() > 1000) {
_this->lsf.valid = false;
}
@ -251,7 +251,7 @@ private:
M17DecoderModule* _this = (M17DecoderModule*)ctx;
// TODO: If too slow, change all demods here and not when setting
_this->audioSampRate = sampleRate;
_this->resampWin.setCutoff(std::min<float>(sampleRate/2, 4000));
_this->resampWin.setCutoff(std::min<float>(sampleRate / 2, 4000));
_this->resamp.tempStop();
_this->resamp.setOutSampleRate(sampleRate);
_this->resampWin.setSampleRate(8000 * _this->resamp.getInterpolation());
@ -273,7 +273,7 @@ private:
VFOManager::VFO* vfo;
dsp::M17Decoder decoder;
dsp::Reshaper<float> reshape;
dsp::HandlerSink<float> diagHandler;

View File

@ -21,9 +21,9 @@
#include <fstream>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "meteor_demodulator",
/* Description: */ "Meteor demodulator for SDR++",
/* Author: */ "Ryzerth",
@ -35,7 +35,7 @@ ConfigManager config;
std::string genFileName(std::string prefix, std::string suffix) {
time_t now = time(0);
tm *ltm = localtime(&now);
tm* ltm = localtime(&now);
char buf[1024];
sprintf(buf, "%s_%02d-%02d-%02d_%02d-%02d-%02d%s", prefix.c_str(), ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ltm->tm_mday, ltm->tm_mon + 1, ltm->tm_year + 1900, suffix.c_str());
return buf;
@ -74,7 +74,7 @@ public:
reshape.start();
symSink.start();
sink.start();
gui::menu.registerEntry(name, menuHandler, this, this);
core::modComManager.registerInterface("meteor_demodulator", name, moduleInterfaceHandler, this);
}
@ -98,7 +98,7 @@ public:
void enable() {
double bw = gui::waterfall.getBandwidth();
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double>(0, -bw/2.0, bw/2.0), 150000, INPUT_SAMPLE_RATE, 150000, 150000, true);
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double>(0, -bw / 2.0, bw / 2.0), 150000, INPUT_SAMPLE_RATE, 150000, 150000, true);
demod.setInput(vfo->output);
@ -155,12 +155,12 @@ private:
}
else {
if (ImGui::Button(CONCAT("Record##_recorder_rec_", _this->name), ImVec2(menuWidth, 0))) {
_this->startRecording();
_this->startRecording();
}
ImGui::Text("Idle --.--MB");
}
if (!_this->folderSelect.pathIsValid() && _this->enabled) { style::endDisabled(); }
if (!_this->folderSelect.pathIsValid() && _this->enabled) { style::endDisabled(); }
if (!_this->enabled) { style::endDisabled(); }
}
@ -196,7 +196,7 @@ private:
}
else {
spdlog::error("Could not open file for recording!");
}
}
}
void stopRecording() {
@ -240,7 +240,6 @@ private:
std::ofstream recFile;
int8_t* writeBuffer;
};
MOD_EXPORT void _INIT_() {

View File

@ -40,7 +40,7 @@ namespace demod {
virtual double getAFBandwidth(double bandwidth) = 0;
virtual bool getFMIFNRAllowed() = 0;
virtual bool getNBAllowed() = 0;
virtual bool getDynamicAFBandwidth() = 0;
virtual dsp::stream<dsp::stereo_t>* getOutput() = 0;
};

View File

@ -7,7 +7,7 @@ namespace demod {
class AM : public Demodulator {
public:
AM() {}
AM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -52,23 +52,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "AM"; }
double getIFSampleRate() { return 15000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 10000.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 1000.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "AM"; }
double getIFSampleRate() { return 15000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 10000.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 1000.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return false; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return false; }
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class CW : public Demodulator {
public:
CW() {}
CW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -53,23 +53,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "CW"; }
double getIFSampleRate() { return 3000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 500.0; }
double getMinBandwidth() { return 50.0; }
double getMaxBandwidth() { return 500.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 10.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "CW"; }
double getIFSampleRate() { return 3000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 500.0; }
double getMinBandwidth() { return 50.0; }
double getMaxBandwidth() { return 500.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 10.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return (bandwidth / 2.0) + 1000.0; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return false; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return false; }
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class DSB : public Demodulator {
public:
DSB() {}
DSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -54,23 +54,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "DSB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 4600.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "DSB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 4600.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class LSB : public Demodulator {
public:
LSB() {}
LSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -54,23 +54,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "LSB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 2800.0; }
double getMinBandwidth() { return 500.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_UPPER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "LSB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 2800.0; }
double getMinBandwidth() { return 500.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_UPPER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class NFM : public Demodulator {
public:
NFM() {}
NFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -46,23 +46,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "FM"; }
double getIFSampleRate() { return 50000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 12500.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 2500.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return true; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "FM"; }
double getIFSampleRate() { return 50000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 12500.0; }
double getMinBandwidth() { return 1000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 2500.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return true; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return true; }
bool getNBAllowed() { return false; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return true; }
bool getNBAllowed() { return false; }
dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class RAW : public Demodulator {
public:
RAW() {}
RAW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -47,23 +47,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "RAW"; }
double getIFSampleRate() { return audioSampleRate; }
double getAFSampleRate() { return audioSampleRate; }
double getDefaultBandwidth() { return audioSampleRate; }
double getMinBandwidth() { return audioSampleRate; }
double getMaxBandwidth() { return audioSampleRate; }
bool getBandwidthLocked() { return true; }
double getMaxAFBandwidth() { return audioSampleRate; }
double getDefaultSnapInterval() { return 2500.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return false; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "RAW"; }
double getIFSampleRate() { return audioSampleRate; }
double getAFSampleRate() { return audioSampleRate; }
double getDefaultBandwidth() { return audioSampleRate; }
double getMinBandwidth() { return audioSampleRate; }
double getMaxBandwidth() { return audioSampleRate; }
bool getBandwidthLocked() { return true; }
double getMaxAFBandwidth() { return audioSampleRate; }
double getDefaultSnapInterval() { return 2500.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return false; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth; }
bool getDynamicAFBandwidth() { return false; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
bool getDynamicAFBandwidth() { return false; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
dsp::stream<dsp::stereo_t>* getOutput() { return &c2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class USB : public Demodulator {
public:
USB() {}
USB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -54,23 +54,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "USB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 2800.0; }
double getMinBandwidth() { return 500.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_LOWER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
const char* getName() { return "USB"; }
double getIFSampleRate() { return 24000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 2800.0; }
double getMinBandwidth() { return 500.0; }
double getMaxBandwidth() { return getIFSampleRate() / 2.0; }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return getIFSampleRate() / 2.0; }
double getDefaultSnapInterval() { return 100.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_LOWER; }
bool getDeempAllowed() { return false; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; }
double getAFBandwidth(double bandwidth) { return bandwidth; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
bool getDynamicAFBandwidth() { return true; }
bool getFMIFNRAllowed() { return false; }
bool getNBAllowed() { return true; }
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
private:

View File

@ -7,7 +7,7 @@ namespace demod {
class WFM : public Demodulator {
public:
WFM() {}
WFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, double audioSR) {
init(name, config, input, bandwidth, outputChangeHandler, audioSR);
}
@ -23,7 +23,7 @@ namespace demod {
// Load config
_config->acquire();
bool modified =false;
bool modified = false;
if (!config->conf[name].contains(getName())) {
config->conf[name][getName()]["stereo"] = false;
modified = true;
@ -70,23 +70,23 @@ namespace demod {
// ============= INFO =============
const char* getName() { return "WFM"; }
double getIFSampleRate() { return 250000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 150000.0; }
double getMinBandwidth() { return 50000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return 16000.0; }
double getDefaultSnapInterval() { return 100000.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return true; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_50US; }
const char* getName() { return "WFM"; }
double getIFSampleRate() { return 250000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 150000.0; }
double getMinBandwidth() { return 50000.0; }
double getMaxBandwidth() { return getIFSampleRate(); }
bool getBandwidthLocked() { return false; }
double getMaxAFBandwidth() { return 16000.0; }
double getDefaultSnapInterval() { return 100000.0; }
int getVFOReference() { return ImGui::WaterfallVFO::REF_CENTER; }
bool getDeempAllowed() { return true; }
bool getPostProcEnabled() { return true; }
int getDefaultDeemphasisMode() { return DEEMP_MODE_50US; }
double getAFBandwidth(double bandwidth) { return 16000.0; }
bool getDynamicAFBandwidth() { return false; }
bool getFMIFNRAllowed() { return true; }
bool getNBAllowed() { return false; }
bool getDynamicAFBandwidth() { return false; }
bool getFMIFNRAllowed() { return true; }
bool getNBAllowed() { return false; }
dsp::stream<dsp::stereo_t>* getOutput() { return stereo ? demodStereo.out : &demod.out; }
// ============= DEDICATED FUNCTIONS =============
@ -108,9 +108,9 @@ namespace demod {
private:
dsp::FMDemod demod;
dsp::StereoFMDemod demodStereo;
ConfigManager* _config = NULL;
bool stereo = false;
std::string name;

View File

@ -1,7 +1,7 @@
#include "radio_module.h"
#include <options.h>
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "radio",
/* Description: */ "Analog radio decoder",
/* Author: */ "Ryzerth",

View File

@ -14,12 +14,12 @@
ConfigManager config;
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
std::map<DeemphasisMode, double> deempTaus = {
{DEEMP_MODE_22US, 22e-6},
{DEEMP_MODE_50US, 50e-6},
{DEEMP_MODE_75US, 75e-6}
{ DEEMP_MODE_22US, 22e-6 },
{ DEEMP_MODE_50US, 50e-6 },
{ DEEMP_MODE_75US, 75e-6 }
};
class RadioModule : public ModuleManager::Instance {
@ -91,11 +91,11 @@ public:
config.conf[name][demod->getName()]["squelchEnabled"] = false;
}
bw = std::clamp<double>(bw, demod->getMinBandwidth(), demod->getMaxBandwidth());
// Initialize
demod->init(name, &config, ifChain.getOutput(), bw, _demodOutputChangeHandler, stream.getSampleRate());
}
// Initialize audio DSP chain
afChainOutputChanged.ctx = this;
afChainOutputChanged.handler = afChainOutputChangeHandler;
@ -194,7 +194,7 @@ private:
ImGui::BeginGroup();
ImGui::Columns(4, CONCAT("RadioModeColumns##_", _this->name), false);
if (ImGui::RadioButton(CONCAT("NFM##_", _this->name), _this->selectedDemodID == 0) && _this->selectedDemodID != 0) {
if (ImGui::RadioButton(CONCAT("NFM##_", _this->name), _this->selectedDemodID == 0) && _this->selectedDemodID != 0) {
_this->selectDemodByID(RADIO_DEMOD_NFM);
}
if (ImGui::RadioButton(CONCAT("WFM##_", _this->name), _this->selectedDemodID == 1) && _this->selectedDemodID != 1) {
@ -204,7 +204,7 @@ private:
if (ImGui::RadioButton(CONCAT("AM##_", _this->name), _this->selectedDemodID == 2) && _this->selectedDemodID != 2) {
_this->selectDemodByID(RADIO_DEMOD_AM);
}
if (ImGui::RadioButton(CONCAT("DSB##_", _this->name), _this->selectedDemodID == 3) && _this->selectedDemodID != 3) {
if (ImGui::RadioButton(CONCAT("DSB##_", _this->name), _this->selectedDemodID == 3) && _this->selectedDemodID != 3) {
_this->selectDemodByID(RADIO_DEMOD_DSB);
}
ImGui::NextColumn();
@ -279,7 +279,7 @@ private:
}
if (!_this->nbEnabled && _this->enabled) { style::endDisabled(); }
}
// // Notch filter
// if (ImGui::Checkbox("Notch##_radio_notch_ena_", &_this->notchEnabled)) {
@ -484,7 +484,7 @@ private:
// Configure deemphasis sample rate
deemp.block.setSampleRate(audioSampleRate);
afChain.start();
}
@ -626,7 +626,7 @@ private:
// Success
return;
}
// Handlers
EventHandler<double> onUserChangedBandwidthHandler;
EventHandler<float> srChangeHandler;
@ -686,5 +686,4 @@ private:
const double MAX_SQUELCH = 0.0;
bool enabled = true;
};

View File

@ -22,9 +22,9 @@
#include <sat_decoder.h>
#include <noaa_hrpt_decoder.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "weather_sat_decoder",
/* Description: */ "Weather Satellite Decoder for SDR++",
/* Author: */ "Ryzerth",
@ -34,7 +34,7 @@ SDRPP_MOD_INFO {
std::string genFileName(std::string prefix, std::string suffix) {
time_t now = time(0);
tm *ltm = localtime(&now);
tm* ltm = localtime(&now);
char buf[1024];
sprintf(buf, "%s_%02d-%02d-%02d_%02d-%02d-%02d%s", prefix.c_str(), ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ltm->tm_mday, ltm->tm_mon + 1, ltm->tm_year + 1900, suffix.c_str());
return buf;
@ -59,7 +59,7 @@ public:
}
selectDecoder(decoderNames[0], false);
gui::menu.registerEntry(name, menuHandler, this, this);
}
@ -120,7 +120,7 @@ private:
std::string name;
bool enabled = true;
VFOManager::VFO* vfo;
std::map<std::string, SatDecoder*> decoders;
@ -129,7 +129,6 @@ private:
int decoderId = 0;
SatDecoder* decoder;
};
MOD_EXPORT void _INIT_() {

View File

@ -9,8 +9,8 @@
#include <gui/widgets/line_push_image.h>
#include <gui/gui.h>
#define NOAA_HRPT_VFO_SR 3000000.0f
#define NOAA_HRPT_VFO_BW 2000000.0f
#define NOAA_HRPT_VFO_SR 3000000.0f
#define NOAA_HRPT_VFO_BW 2000000.0f
class NOAAHRPTDecoder : public SatDecoder {
public:
@ -19,15 +19,15 @@ public:
_name = name;
// Core DSP
demod.init(vfo->output, NOAA_HRPT_VFO_SR, 665400.0f * 2.0f, 0.02e-3, (0.06f*0.06f) / 2.0f, 32, 0.6f, (0.01f*0.01f) / 4.0f, 0.01f, 0.005);
demod.init(vfo->output, NOAA_HRPT_VFO_SR, 665400.0f * 2.0f, 0.02e-3, (0.06f * 0.06f) / 2.0f, 32, 0.6f, (0.01f * 0.01f) / 4.0f, 0.01f, 0.005);
split.init(demod.out);
split.bindStream(&dataStream);
split.bindStream(&visStream);
reshape.init(&visStream, 1024, (NOAA_HRPT_VFO_SR/30) - 1024);
reshape.init(&visStream, 1024, (NOAA_HRPT_VFO_SR / 30) - 1024);
visSink.init(&reshape.out, visHandler, this);
deframe.init(&dataStream, 11090 * 10 * 2, (uint8_t*)dsp::noaa::HRPTSyncWord, 60);
manDec.init(&deframe.out, false);
packer.init(&manDec.out);
@ -125,7 +125,7 @@ public:
compositeThread = std::thread(&NOAAHRPTDecoder::avhrrCompositeWorker, this);
};
void stop() {
compositeIn1.stopReader();
compositeIn1.stopWriter();
@ -187,7 +187,7 @@ public:
compositeIn2.clearReadStop();
compositeIn2.clearWriteStop();
};
void setVFO(VFOManager::VFO* vfo) {
_vfo = vfo;
demod.setInput(_vfo->output);
@ -196,7 +196,7 @@ public:
virtual bool canRecord() {
return false;
}
// bool startRecording(std::string recPath) {
// };
@ -208,7 +208,7 @@ public:
// bool isRecording() {
// };
void drawMenu(float menuWidth) {
ImGui::SetNextItemWidth(menuWidth);
symDiag.draw();
@ -285,7 +285,7 @@ public:
ImGui::Checkbox("Show Image", &showWindow);
};
private:
// AVHRR Data Handlers
void avhrrCompositeWorker() {
@ -294,16 +294,16 @@ private:
while (true) {
if (compositeIn1.read() < 0) { return; }
if (compositeIn2.read() < 0) { return; }
uint8_t* buf = avhrrRGBImage.acquireNextLine();
float rg, b;
for (int i = 0; i < 2048; i++) {
b = ((float)compositeIn1.readBuf[i] * 255.0f) / 1024.0f;
rg = ((float)compositeIn2.readBuf[i] * 255.0f) / 1024.0f;
buf[(i*4)] = rg;
buf[(i*4) + 1] = rg;
buf[(i*4) + 2] = b;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = rg;
buf[(i * 4) + 1] = rg;
buf[(i * 4) + 2] = b;
buf[(i * 4) + 3] = 255;
}
avhrrRGBImage.releaseNextLine();
@ -318,10 +318,10 @@ private:
float val;
for (int i = 0; i < 2048; i++) {
val = ((float)data[i] * 255.0f) / 1024.0f;
buf[(i*4)] = val;
buf[(i*4) + 1] = val;
buf[(i*4) + 2] = val;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = val;
buf[(i * 4) + 1] = val;
buf[(i * 4) + 2] = val;
buf[(i * 4) + 3] = 255;
}
_this->avhrr1Image.releaseNextLine();
@ -335,10 +335,10 @@ private:
float val;
for (int i = 0; i < 2048; i++) {
val = ((float)data[i] * 255.0f) / 1024.0f;
buf[(i*4)] = val;
buf[(i*4) + 1] = val;
buf[(i*4) + 2] = val;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = val;
buf[(i * 4) + 1] = val;
buf[(i * 4) + 2] = val;
buf[(i * 4) + 3] = 255;
}
_this->avhrr2Image.releaseNextLine();
@ -352,10 +352,10 @@ private:
float val;
for (int i = 0; i < 2048; i++) {
val = ((float)data[i] * 255.0f) / 1024.0f;
buf[(i*4)] = val;
buf[(i*4) + 1] = val;
buf[(i*4) + 2] = val;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = val;
buf[(i * 4) + 1] = val;
buf[(i * 4) + 2] = val;
buf[(i * 4) + 3] = 255;
}
_this->avhrr3Image.releaseNextLine();
}
@ -366,10 +366,10 @@ private:
float val;
for (int i = 0; i < 2048; i++) {
val = ((float)data[i] * 255.0f) / 1024.0f;
buf[(i*4)] = val;
buf[(i*4) + 1] = val;
buf[(i*4) + 2] = val;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = val;
buf[(i * 4) + 1] = val;
buf[(i * 4) + 2] = val;
buf[(i * 4) + 3] = 255;
}
_this->avhrr4Image.releaseNextLine();
}
@ -380,10 +380,10 @@ private:
float val;
for (int i = 0; i < 2048; i++) {
val = ((float)data[i] * 255.0f) / 1024.0f;
buf[(i*4)] = val;
buf[(i*4) + 1] = val;
buf[(i*4) + 2] = val;
buf[(i*4) + 3] = 255;
buf[(i * 4)] = val;
buf[(i * 4) + 1] = val;
buf[(i * 4) + 2] = val;
buf[(i * 4) + 3] = 255;
}
_this->avhrr5Image.releaseNextLine();
}
@ -391,102 +391,82 @@ private:
// HIRS Data Handlers
static void hirs1Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs2Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs3Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs4Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs5Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs6Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs7Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs8Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs9Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs10Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs11Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs12Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs13Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs14Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs15Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs16Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs17Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs18Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs19Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void hirs20Handler(uint16_t* data, int count, void* ctx) {
NOAAHRPTDecoder* _this = (NOAAHRPTDecoder*)ctx;
}
static void visHandler(float* data, int count, void* ctx) {
@ -568,5 +548,4 @@ private:
std::thread compositeThread;
bool showWindow = false;
};

View File

@ -10,7 +10,7 @@ public:
virtual void setVFO(VFOManager::VFO* vfo) = 0;
virtual bool canRecord() = 0;
virtual bool startRecording(std::string recPath) { return false; };
virtual void stopRecording() { };
virtual void stopRecording(){};
virtual bool isRecording() { return false; };
virtual void drawMenu(float menuWidth) = 0;
};