mirror of
https://github.com/ggerganov/ggwave.git
synced 2026-02-06 08:37:59 +08:00
ggwave : optimize memory footprint even more
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user