ggwave : reduce memory for fixed payload + fix bug in decoding

This commit is contained in:
Georgi Gerganov
2022-06-11 23:33:50 +03:00
parent 4cb6ee80a2
commit bc61aff312
2 changed files with 34 additions and 20 deletions

View File

@@ -406,7 +406,7 @@ public:
static constexpr auto kMaxSamplesPerFrame = 1024;
static constexpr auto kMaxDataSize = 256;
static constexpr auto kMaxLengthVariable = 140;
static constexpr auto kMaxLengthFixed = 16;
static constexpr auto kMaxLengthFixed = 64;
static constexpr auto kMaxSpectrumHistory = 4;
static constexpr auto kMaxRecordedFrames = 2048;
@@ -817,6 +817,7 @@ private:
int minBytesPerTx(const Protocols & protocols) const;
int maxBytesPerTx(const Protocols & protocols) const;
int maxTonesPerTx(const Protocols & protocols) const;
int minFreqStart(const Protocols & protocols) const;
double bitFreq(const Protocol & p, int bit) const;
@@ -866,6 +867,7 @@ private:
int nMarkersSuccess = 0;
int markerFreqStart = 0;
int recvDuration_frames = 0;
int minFreqStart = 0;
int framesLeftToAnalyze = 0;
int framesLeftToRecord = 0;
@@ -903,7 +905,7 @@ private:
// fixed-length decoding
int historyIdFixed = 0;
ggmatrix<uint16_t> spectrumHistoryFixed;
ggmatrix<uint8_t> spectrumHistoryFixed;
ggvector<uint8_t> detectedBins;
ggvector<uint8_t> detectedTones;
} m_rx;

View File

@@ -539,6 +539,8 @@ bool GGWave::prepare(const Parameters & parameters, bool allocate) {
m_rx.protocol = {};
m_rx.protocolId = GGWAVE_PROTOCOL_COUNT;
m_rx.protocols = Protocols::rx();
m_rx.minFreqStart = minFreqStart(m_rx.protocols);
}
if (m_isTxEnabled) {
@@ -1779,28 +1781,26 @@ void GGWave::decode_fixed() {
}
for (int i = 1; i < m_samplesPerFrame/2; ++i) {
m_rx.spectrum[i] += m_rx.spectrum[m_samplesPerFrame - i];
amax = GG_MAX(amax, m_rx.spectrum[i]);
if (i >= m_rx.minFreqStart) {
amax = GG_MAX(amax, m_rx.spectrum[i]);
}
}
// original, floating-point version
//m_rx.spectrumHistoryFixed[m_rx.historyIdFixed] = m_rx.spectrum;
//m_rx.spectrumHistoryFixed[m_rx.historyIdFixed].copy(m_rx.spectrum);
// in theory, using uint8_t should work almost the same and save 4 times the memory, but for some reason
// the results are not as good as with the floating-point version
// float -> uint8_t
//amax = 255.0f/(amax == 0.0f ? 1.0f : amax);
//for (int i = 0; i < m_samplesPerFrame; ++i) {
// m_rx.spectrumHistoryFixed[m_rx.historyIdFixed][i] = GG_MIN(255.0f, GG_MAX(0.0f, (float) round(m_rx.spectrum[i]*amax)));
//}
// hence we opt for the uint16_t version, saving 2 times the memory and getting similar results as the floating-point version
// float -> uint16_t
amax = 65535.0f/(amax == 0.0f ? 1.0f : amax);
amax = 255.0f/(amax == 0.0f ? 1.0f : amax);
for (int i = 0; i < m_samplesPerFrame; ++i) {
m_rx.spectrumHistoryFixed[m_rx.historyIdFixed][i] = GG_MIN(65535.0f, GG_MAX(0.0f, (float) round(m_rx.spectrum[i]*amax)));
m_rx.spectrumHistoryFixed[m_rx.historyIdFixed][i] = GG_MIN(255.0f, GG_MAX(0.0f, (float) round(m_rx.spectrum[i]*amax)));
}
// float -> uint16_t
//amax = 65535.0f/(amax == 0.0f ? 1.0f : amax);
//for (int i = 0; i < m_samplesPerFrame; ++i) {
// m_rx.spectrumHistoryFixed[m_rx.historyIdFixed][i] = GG_MIN(65535.0f, GG_MAX(0.0f, (float) round(m_rx.spectrum[i]*amax)));
//}
if (++m_rx.historyIdFixed >= (int) m_rx.spectrumHistoryFixed.size()) {
m_rx.historyIdFixed = 0;
}
@@ -1848,9 +1848,9 @@ void GGWave::decode_fixed() {
for (int j = 0; j < protocol.bytesPerTx; ++j) {
int f0bin = 0;
uint16_t f0max = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta];
auto f0max = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta];
for (int b = 0; b < 16; ++b) {
for (int b = 1; b < 16; ++b) {
{
const auto & v = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta + b];
@@ -1863,8 +1863,8 @@ void GGWave::decode_fixed() {
int f1bin = 0;
if (protocol.extra == 1) {
uint16_t f1max = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta + binOffset];
for (int b = 0; b < 16; ++b) {
auto f1max = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta + binOffset];
for (int b = 1; b < 16; ++b) {
const auto & v = m_rx.spectrumHistoryFixed[historyId][binStart + 2*j*binDelta + binOffset + b];
if (f1max <= v) {
@@ -1990,6 +1990,18 @@ int GGWave::maxTonesPerTx(const Protocols & protocols) const {
return res;
}
int GGWave::minFreqStart(const Protocols & protocols) const {
int res = m_samplesPerFrame;
for (int i = 0; i < protocols.size(); ++i) {
const auto & protocol = protocols[i];
if (protocol.enabled == false) {
continue;
}
res = GG_MIN(res, protocol.freqStart);
}
return res;
}
double GGWave::bitFreq(const Protocol & p, int bit) const {
return m_hzPerSample*p.freqStart + m_freqDelta_hz*bit;
}