ggwave : optimize memory footprint even more

This commit is contained in:
Georgi Gerganov
2022-06-11 15:23:02 +03:00
parent 535392d41f
commit 68367c2d09
3 changed files with 45 additions and 27 deletions

View File

@@ -11,6 +11,9 @@ const int sampleRate = 6000;
GGWave * g_ggwave = nullptr;
void send_text(GGWave & ggwave, uint8_t pin, const char * text, GGWave::TxProtocolId protocolId) {
Serial.print(F("Sending text: "));
Serial.println(text);
ggwave.init(text, protocolId);
ggwave.encode();
@@ -64,6 +67,8 @@ bool isDown = false;
#define P(str) (strcpy_P(txt, PSTR(str)), txt)
void loop() {
Serial.println(F("Starting main loop"));
auto & ggwave = *g_ggwave;
delay(1000);

View File

@@ -389,6 +389,10 @@ public:
#include <stdint.h>
#include <stdio.h>
#ifdef ARDUINO
#include <avr/pgmspace.h>
#endif
class GGWave {
public:
static constexpr auto kSampleRateMin = 1000.0f;
@@ -480,22 +484,28 @@ public:
protocols.data[i].name = nullptr;
protocols.data[i].enabled = false;
}
#ifndef ARDUINO
#define PSTR(str) (str)
#endif
#ifndef GGWAVE_CONFIG_FEW_PROTOCOLS
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_NORMAL] = { "Normal", 40, 9, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_FAST] = { "Fast", 40, 6, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_FASTEST] = { "Fastest", 40, 3, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_NORMAL] = { "[U] Normal", 320, 9, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_FAST] = { "[U] Fast", 320, 6, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_FASTEST] = { "[U] Fastest", 320, 3, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_NORMAL] = { "[DT] Normal", 24, 9, 1, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_FAST] = { "[DT] Fast", 24, 6, 1, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_FASTEST] = { "[DT] Fastest", 24, 3, 1, 1, true, };
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_NORMAL] = { PSTR("Normal"), 40, 9, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_FAST] = { PSTR("Fast"), 40, 6, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_AUDIBLE_FASTEST] = { PSTR("Fastest"), 40, 3, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_NORMAL] = { PSTR("[U] Normal"), 320, 9, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_FAST] = { PSTR("[U] Fast"), 320, 6, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_ULTRASOUND_FASTEST] = { PSTR("[U] Fastest"), 320, 3, 3, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_NORMAL] = { PSTR("[DT] Normal"), 24, 9, 1, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_FAST] = { PSTR("[DT] Fast"), 24, 6, 1, 1, true, };
protocols.data[GGWAVE_PROTOCOL_DT_FASTEST] = { PSTR("[DT] Fastest"), 24, 3, 1, 1, true, };
#endif
protocols.data[GGWAVE_PROTOCOL_MT_NORMAL] = { "[MT] Normal", 24, 9, 1, 2, true, };
protocols.data[GGWAVE_PROTOCOL_MT_FAST] = { "[MT] Fast", 24, 6, 1, 2, true, };
protocols.data[GGWAVE_PROTOCOL_MT_FASTEST] = { "[MT] Fastest", 24, 3, 1, 2, true, };
protocols.data[GGWAVE_PROTOCOL_MT_NORMAL] = { PSTR("[MT] Normal"), 24, 9, 1, 2, true, };
protocols.data[GGWAVE_PROTOCOL_MT_FAST] = { PSTR("[MT] Fast"), 24, 6, 1, 2, true, };
protocols.data[GGWAVE_PROTOCOL_MT_FASTEST] = { PSTR("[MT] Fastest"), 24, 3, 1, 2, true, };
#ifndef ARDUINO
#undef PSTR
#endif
initialized = true;
}

View File

@@ -2,8 +2,6 @@
#if !defined(ARDUINO) && !defined(PROGMEM)
#define PROGMEM
#else
#include <avr/pgmspace.h>
#endif
#include "fft.h"
@@ -317,7 +315,9 @@ template struct ggvector<int16_t>;
template <typename T>
void ggmatrix<T>::zero() {
memset(m_data, 0, m_size0*m_size1*sizeof(T));
if (m_size0 > 0 && m_size1 > 0) {
memset(m_data, 0, m_size0*m_size1*sizeof(T));
}
}
//
@@ -539,8 +539,18 @@ bool GGWave::prepare(const Parameters & parameters) {
}
bool GGWave::alloc(void * p, int & n) {
const int maxLength = m_isFixedPayloadLength ? m_payloadLength : kMaxLengthVariable;
const int totalLength = maxLength + getECCBytesForLength(maxLength);
const int totalTxs = (totalLength + minBytesPerTx(Protocols::rx()) - 1)/minBytesPerTx(Protocols::tx());
if (totalLength > kMaxDataSize) {
ggprintf("Error: total length %d (payload %d + ECC %d bytes) is too large ( > %d)\n",
totalLength, maxLength, getECCBytesForLength(maxLength), kMaxDataSize);
return false;
}
// common
::ggalloc(m_dataEncoded, kMaxDataSize, p, n);
::ggalloc(m_dataEncoded, totalLength + m_encodedDataOffset, p, n);
if (m_isRxEnabled) {
::ggalloc(m_rx.fftOut, 2*m_samplesPerFrame, p, n);
@@ -554,7 +564,7 @@ bool GGWave::alloc(void * p, int & n) {
::ggalloc(m_rx.amplitudeResampled, m_needResampling ? 8*m_samplesPerFrame : m_samplesPerFrame, p, n);
::ggalloc(m_rx.amplitudeTmp, m_needResampling ? 8*m_samplesPerFrame*m_sampleSizeInp : m_samplesPerFrame*m_sampleSizeInp, p, n);
::ggalloc(m_rx.data, kMaxDataSize, p, n);
::ggalloc(m_rx.data, maxLength + 1, p, n); // extra byte for null-termination
if (m_isFixedPayloadLength) {
if (m_payloadLength > kMaxLengthFixed) {
@@ -562,9 +572,6 @@ bool GGWave::alloc(void * p, int & n) {
return false;
}
const int totalLength = m_payloadLength + getECCBytesForLength(m_payloadLength);
const int totalTxs = (totalLength + minBytesPerTx(Protocols::rx()) - 1)/minBytesPerTx(Protocols::rx());
::ggalloc(m_rx.spectrumHistoryFixed, totalTxs*maxFramesPerTx(Protocols::rx(), false), m_samplesPerFrame, p, n);
::ggalloc(m_rx.detectedBins, 2*totalLength, p, n);
::ggalloc(m_rx.detectedTones, 2*16*maxBytesPerTx(Protocols::rx()), p, n);
@@ -579,9 +586,6 @@ bool GGWave::alloc(void * p, int & n) {
if (m_isTxEnabled) {
const int maxDataBits = 2*16*maxBytesPerTx(Protocols::tx());
::ggalloc(m_tx.data, kMaxDataSize, p, n);
::ggalloc(m_tx.dataBits, maxDataBits, p, n);
if (m_txOnlyTones == false) {
::ggalloc(m_tx.phaseOffsets, maxDataBits, p, n);
::ggalloc(m_tx.bit0Amplitude, maxDataBits, m_samplesPerFrame, p, n);
@@ -592,12 +596,11 @@ bool GGWave::alloc(void * p, int & n) {
::ggalloc(m_tx.outputI16, kMaxRecordedFrames*m_samplesPerFrame, p, n);
}
const int maxLength = m_isFixedPayloadLength ? m_payloadLength : kMaxLengthVariable;
const int totalLength = maxLength + getECCBytesForLength(maxLength);
const int totalTxs = (totalLength + minBytesPerTx(Protocols::rx()) - 1)/minBytesPerTx(Protocols::tx());
const int maxTones = m_isFixedPayloadLength ? maxTonesPerTx(Protocols::tx()) : m_nBitsInMarker;
::ggalloc(m_tx.tones, maxTones*totalTxs + (maxTones > 1 ? totalTxs : 0), p, n);
::ggalloc(m_tx.data, maxLength + 1, p, n); // first byte stores the length
::ggalloc(m_tx.dataBits, maxDataBits, p, n);
::ggalloc(m_tx.tones, maxTones*totalTxs + (maxTones > 1 ? totalTxs : 0), p, n);
}
// pre-allocate Reed-Solomon memory buffers