mirror of
https://github.com/ggerganov/ggwave.git
synced 2026-04-21 05:36:33 +08:00
ggwave : add default constructor
This commit is contained in:
@@ -293,7 +293,7 @@ bool GGWave_mainLoop() {
|
|||||||
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
||||||
|
|
||||||
const auto nBytes = g_ggWave->encode();
|
const auto nBytes = g_ggWave->encode();
|
||||||
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
|
SDL_QueueAudio(g_devIdOut, g_ggWave->txWaveform(), nBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -5,28 +5,29 @@
|
|||||||
const int kPinSpeaker = 10;
|
const int kPinSpeaker = 10;
|
||||||
|
|
||||||
using TSample = int16_t;
|
using TSample = int16_t;
|
||||||
static const size_t kSampleSize_bytes = sizeof(TSample);
|
const size_t kSampleSize_bytes = sizeof(TSample);
|
||||||
|
|
||||||
// default number of output channels
|
// default number of output channels
|
||||||
static const char channels = 1;
|
const char channels = 1;
|
||||||
|
|
||||||
// default PCM output frequency
|
// default PCM output frequency
|
||||||
static const int frequency = 6000;
|
const int frequency = 6000;
|
||||||
static const int samplesPerFrame = 128;
|
const int samplesPerFrame = 128;
|
||||||
|
|
||||||
static const int qpow = 9;
|
const int qpow = 9;
|
||||||
static const int qmax = 1 << qpow;
|
const int qmax = 1 << qpow;
|
||||||
|
|
||||||
volatile int qhead = 0;
|
volatile int qhead = 0;
|
||||||
volatile int qtail = 0;
|
volatile int qtail = 0;
|
||||||
volatile int qsize = 0;
|
volatile int qsize = 0;
|
||||||
|
|
||||||
// Buffer to read samples into, each sample is 16-bits
|
// buffer to read samples into, each sample is 16-bits
|
||||||
TSample sampleBuffer[qmax];
|
TSample sampleBuffer[qmax];
|
||||||
|
|
||||||
volatile int err = 0;
|
volatile int err = 0;
|
||||||
|
|
||||||
GGWave * g_ggwave = nullptr;
|
// global GGwave instance
|
||||||
|
GGWave ggwave;
|
||||||
|
|
||||||
// helper function to output the generated GGWave waveform via a buzzer
|
// helper function to output the generated GGWave waveform via a buzzer
|
||||||
void send_text(GGWave & ggwave, uint8_t pin, const char * text, GGWave::TxProtocolId protocolId) {
|
void send_text(GGWave & ggwave, uint8_t pin, const char * text, GGWave::TxProtocolId protocolId) {
|
||||||
@@ -57,6 +58,8 @@ void setup() {
|
|||||||
|
|
||||||
Serial.println(F("Trying to create ggwave instance"));
|
Serial.println(F("Trying to create ggwave instance"));
|
||||||
|
|
||||||
|
ggwave.setLogFile(nullptr);
|
||||||
|
|
||||||
auto p = GGWave::getDefaultParameters();
|
auto p = GGWave::getDefaultParameters();
|
||||||
|
|
||||||
p.payloadLength = 16;
|
p.payloadLength = 16;
|
||||||
@@ -84,17 +87,12 @@ void setup() {
|
|||||||
GGWave::Protocols::rx().toggle(GGWAVE_PROTOCOL_MT_FAST, true);
|
GGWave::Protocols::rx().toggle(GGWAVE_PROTOCOL_MT_FAST, true);
|
||||||
GGWave::Protocols::rx().toggle(GGWAVE_PROTOCOL_MT_FASTEST, true);
|
GGWave::Protocols::rx().toggle(GGWAVE_PROTOCOL_MT_FASTEST, true);
|
||||||
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
static GGWave ggwave(p);
|
ggwave.prepare(p);
|
||||||
Serial.println(ggwave.heapSize());
|
Serial.println(ggwave.heapSize());
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
ggwave.setLogFile(nullptr);
|
|
||||||
|
|
||||||
g_ggwave = &ggwave;
|
|
||||||
|
|
||||||
Serial.println(F("Instance initialized"));
|
Serial.println(F("Instance initialized"));
|
||||||
|
|
||||||
// Configure the data receive callback
|
// Configure the data receive callback
|
||||||
@@ -115,8 +113,6 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
auto & ggwave = *g_ggwave;
|
|
||||||
|
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
int niter = 0;
|
int niter = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ const int kPinButton1 = 4;
|
|||||||
const int samplesPerFrame = 128;
|
const int samplesPerFrame = 128;
|
||||||
const int sampleRate = 6000;
|
const int sampleRate = 6000;
|
||||||
|
|
||||||
GGWave * g_ggwave = nullptr;
|
// global GGwave instance
|
||||||
|
GGWave ggwave;
|
||||||
|
|
||||||
char txt[64];
|
char txt[64];
|
||||||
#define P(str) (strcpy_P(txt, PSTR(str)), txt)
|
#define P(str) (strcpy_P(txt, PSTR(str)), txt)
|
||||||
@@ -36,6 +37,7 @@ void send_text(GGWave & ggwave, uint8_t pin, const char * text, GGWave::TxProtoc
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(57600);
|
Serial.begin(57600);
|
||||||
|
while (!Serial);
|
||||||
|
|
||||||
pinMode(kPinLed0, OUTPUT);
|
pinMode(kPinLed0, OUTPUT);
|
||||||
pinMode(kPinSpeaker, OUTPUT);
|
pinMode(kPinSpeaker, OUTPUT);
|
||||||
@@ -55,12 +57,10 @@ void setup() {
|
|||||||
p.operatingMode = (ggwave_OperatingMode) (GGWAVE_OPERATING_MODE_TX | GGWAVE_OPERATING_MODE_TX_ONLY_TONES | GGWAVE_OPERATING_MODE_USE_DSS);
|
p.operatingMode = (ggwave_OperatingMode) (GGWAVE_OPERATING_MODE_TX | GGWAVE_OPERATING_MODE_TX_ONLY_TONES | GGWAVE_OPERATING_MODE_USE_DSS);
|
||||||
|
|
||||||
GGWave::Protocols::tx().only(GGWAVE_PROTOCOL_MT_FASTEST);
|
GGWave::Protocols::tx().only(GGWAVE_PROTOCOL_MT_FASTEST);
|
||||||
static GGWave ggwave(p);
|
ggwave.prepare(p);
|
||||||
ggwave.setLogFile(nullptr);
|
ggwave.setLogFile(nullptr);
|
||||||
Serial.println(ggwave.heapSize());
|
Serial.println(ggwave.heapSize());
|
||||||
|
|
||||||
g_ggwave = &ggwave;
|
|
||||||
|
|
||||||
Serial.println(F("Instance initialized"));
|
Serial.println(F("Instance initialized"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +68,6 @@ int pressed = 0;
|
|||||||
bool isDown = false;
|
bool isDown = false;
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
auto & ggwave = *g_ggwave;
|
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
digitalWrite(kPinLed0, HIGH);
|
digitalWrite(kPinLed0, HIGH);
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ bool GGWave_mainLoop() {
|
|||||||
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
||||||
|
|
||||||
const auto nBytes = g_ggWave->encode();
|
const auto nBytes = g_ggWave->encode();
|
||||||
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
|
SDL_QueueAudio(g_devIdOut, g_ggWave->txWaveform(), nBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> bufferPCM(nBytes);
|
std::vector<char> bufferPCM(nBytes);
|
||||||
std::memcpy(bufferPCM.data(), ggWave.txData(), nBytes);
|
std::memcpy(bufferPCM.data(), ggWave.txWaveform(), nBytes);
|
||||||
|
|
||||||
fprintf(stderr, "Output size = %d bytes\n", (int) bufferPCM.size());
|
fprintf(stderr, "Output size = %d bytes\n", (int) bufferPCM.size());
|
||||||
|
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ bool GGWave_mainLoop() {
|
|||||||
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
|
||||||
|
|
||||||
const auto nBytes = g_ggWave->encode();
|
const auto nBytes = g_ggWave->encode();
|
||||||
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
|
SDL_QueueAudio(g_devIdOut, g_ggWave->txWaveform(), nBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -518,9 +518,9 @@ public:
|
|||||||
|
|
||||||
using Tone = int8_t;
|
using Tone = int8_t;
|
||||||
|
|
||||||
// generated tones
|
// Tone data structure
|
||||||
//
|
//
|
||||||
// Each Tone is the bin index of the tone frequency.
|
// Each Tone element is the bin index of the tone frequency.
|
||||||
// For protocol p:
|
// For protocol p:
|
||||||
// - freq_hz = (p.freqStart + Tone) * hzPerSample
|
// - freq_hz = (p.freqStart + Tone) * hzPerSample
|
||||||
// - duration_ms = p.txDuration_ms(samplesPerFrame, sampleRate)
|
// - duration_ms = p.txDuration_ms(samplesPerFrame, sampleRate)
|
||||||
@@ -537,27 +537,32 @@ public:
|
|||||||
using RecordedData = ggvector<float>;
|
using RecordedData = ggvector<float>;
|
||||||
using TxRxData = ggvector<uint8_t>;
|
using TxRxData = ggvector<uint8_t>;
|
||||||
|
|
||||||
// default constructor
|
// Default constructor
|
||||||
//
|
//
|
||||||
// The GGWave object is not ready to use until you call prepare()
|
// The GGWave object is not ready to use until you call prepare()
|
||||||
// No memory is allocated with this constructor.
|
// No memory is allocated with this constructor.
|
||||||
//
|
//
|
||||||
GGWave() = default;
|
GGWave() = default;
|
||||||
|
|
||||||
// constructor with parameters
|
// Constructor with parameters
|
||||||
//
|
//
|
||||||
// Construct and prepare the GGWave object using the given parameters.
|
// Construct and prepare the GGWave object using the given parameters.
|
||||||
// The constructor calls prepare() for you.
|
// This constructor calls prepare() for you.
|
||||||
//
|
//
|
||||||
GGWave(const Parameters & parameters);
|
GGWave(const Parameters & parameters);
|
||||||
|
|
||||||
~GGWave();
|
~GGWave();
|
||||||
|
|
||||||
// prepare the GGWave object
|
// Prepare the GGWave object
|
||||||
//
|
//
|
||||||
// All memory buffers used by the GGWave instance are allocated with this function.
|
// All memory buffers used by the GGWave instance are allocated with this function.
|
||||||
// No memory allocations occur after that.
|
// No memory allocations occur after that.
|
||||||
//
|
//
|
||||||
|
// Call this method if you used the default constructor.
|
||||||
|
// Do not call this method if you used the constructor with parameters.
|
||||||
|
//
|
||||||
|
// The encode() and decode() methods will not work until this method is called.
|
||||||
|
//
|
||||||
// The sizes of the buffers are determined by the parameters and the contents of:
|
// The sizes of the buffers are determined by the parameters and the contents of:
|
||||||
//
|
//
|
||||||
// - GGWave::Protocols::rx()
|
// - GGWave::Protocols::rx()
|
||||||
@@ -593,7 +598,7 @@ public:
|
|||||||
//
|
//
|
||||||
bool prepare(const Parameters & parameters, bool allocate = true);
|
bool prepare(const Parameters & parameters, bool allocate = true);
|
||||||
|
|
||||||
// set file stream for the internal ggwave logging
|
// Set file stream for the internal ggwave logging
|
||||||
//
|
//
|
||||||
// By default, ggwave prints internal log messages to stderr.
|
// By default, ggwave prints internal log messages to stderr.
|
||||||
// To disable logging all together, call this method with nullptr.
|
// To disable logging all together, call this method with nullptr.
|
||||||
@@ -604,53 +609,55 @@ public:
|
|||||||
|
|
||||||
static const Parameters & getDefaultParameters();
|
static const Parameters & getDefaultParameters();
|
||||||
|
|
||||||
// set Tx data to encode
|
// Set Tx data to encode into sound
|
||||||
//
|
//
|
||||||
// This prepares the GGWave instance for transmission.
|
// This prepares the GGWave instance for transmission.
|
||||||
// To perform the actual encoding, the encode() method must be called
|
// To perform the actual encoding, call the encode() method.
|
||||||
//
|
//
|
||||||
// returns false upon invalid parameters or failure to initialize
|
// Returns false upon invalid parameters or failure to initialize the transmission
|
||||||
//
|
//
|
||||||
bool init(const char * text, TxProtocolId protocolId, const int volume = kDefaultVolume);
|
bool init(const char * text, TxProtocolId protocolId, const int volume = kDefaultVolume);
|
||||||
bool init(int dataSize, const char * dataBuffer, TxProtocolId protocolId, const int volume = kDefaultVolume);
|
bool init(int dataSize, const char * dataBuffer, TxProtocolId protocolId, const int volume = kDefaultVolume);
|
||||||
|
|
||||||
// expected waveform size of the encoded Tx data in bytes
|
// Expected waveform size of the encoded Tx data in bytes
|
||||||
//
|
//
|
||||||
// When the output sampling rate is not equal to operating sample rate the result of this method is overestimation of
|
// When the output sampling rate is not equal to operating sample rate the result of this method is overestimation
|
||||||
// the actual number of bytes that would be produced
|
// of the actual number of bytes that would be produced
|
||||||
//
|
//
|
||||||
uint32_t encodeSize_bytes() const;
|
uint32_t encodeSize_bytes() const;
|
||||||
|
|
||||||
// expected waveform size of the encoded Tx data in samples
|
// Expected waveform size of the encoded Tx data in samples
|
||||||
//
|
//
|
||||||
// When the output sampling rate is not equal to operating sample rate the result of this method is overestimation of
|
// When the output sampling rate is not equal to operating sample rate the result of this method is overestimation
|
||||||
// the actual number of samples that would be produced
|
// of the actual number of samples that would be produced
|
||||||
//
|
//
|
||||||
uint32_t encodeSize_samples() const;
|
uint32_t encodeSize_samples() const;
|
||||||
|
|
||||||
// encode Tx data into an audio waveform
|
// Encode Tx data into an audio waveform
|
||||||
//
|
//
|
||||||
// After calling this method, the generated waveform is available through the txData() method
|
// After calling this method, use the Tx methods to get the encoded audio data.
|
||||||
//
|
//
|
||||||
// returns the number of bytes in the generated waveform
|
// The generated waveform is available through the txWaveform() method
|
||||||
|
// The tone frequencies are available through the txTones() method
|
||||||
|
//
|
||||||
|
// Returns the number of bytes in the generated waveform
|
||||||
//
|
//
|
||||||
uint32_t encode();
|
uint32_t encode();
|
||||||
|
|
||||||
const void * txData() const;
|
// Decode an audio waveform
|
||||||
|
|
||||||
// decode an audio waveform
|
|
||||||
//
|
//
|
||||||
// data - pointer to the waveform data
|
// data - pointer to the waveform data
|
||||||
// nBytes - number of bytes in the waveform
|
// nBytes - number of bytes in the waveform
|
||||||
//
|
//
|
||||||
|
// The samples pointed to by "data" should be in the format given by sampleFormatInp().
|
||||||
// After calling this method, use the Rx methods to check if any data was decoded successfully.
|
// After calling this method, use the Rx methods to check if any data was decoded successfully.
|
||||||
//
|
//
|
||||||
// returns false if the provided waveform is somehow invalid
|
// Returns false if the provided waveform is somehow invalid
|
||||||
//
|
//
|
||||||
bool decode(const void * data, uint32_t nBytes);
|
bool decode(const void * data, uint32_t nBytes);
|
||||||
|
|
||||||
//
|
//
|
||||||
// instance state
|
// Instance state
|
||||||
//
|
//
|
||||||
|
|
||||||
bool isDSSEnabled() const;
|
bool isDSSEnabled() const;
|
||||||
@@ -659,7 +666,7 @@ public:
|
|||||||
int sampleSizeInp() const;
|
int sampleSizeInp() const;
|
||||||
int sampleSizeOut() const;
|
int sampleSizeOut() const;
|
||||||
|
|
||||||
float hzPerSample() const;
|
float hzPerSample() const;
|
||||||
float sampleRateInp() const;
|
float sampleRateInp() const;
|
||||||
float sampleRateOut() const;
|
float sampleRateOut() const;
|
||||||
SampleFormat sampleFormatInp() const;
|
SampleFormat sampleFormatInp() const;
|
||||||
@@ -671,21 +678,27 @@ public:
|
|||||||
// Tx
|
// Tx
|
||||||
//
|
//
|
||||||
|
|
||||||
// get a list of the tones generated for the last waveform
|
// Get the generated Wavform samples for the last encode() call
|
||||||
//
|
//
|
||||||
// Call this method after calling encode() to get a list of the tones
|
// Call this method after calling encode() to get the generated waveform. The format of the samples pointed to by
|
||||||
// participating in the generated waveform
|
// the returned pointer is determined by the sampleFormatOut() method.
|
||||||
|
//
|
||||||
|
const void * txWaveform() const;
|
||||||
|
|
||||||
|
// Get a list of the tones generated for the last encode() call
|
||||||
|
//
|
||||||
|
// Call this method after calling encode() to get a list of the tones participating in the generated waveform
|
||||||
//
|
//
|
||||||
const Tones txTones() const;
|
const Tones txTones() const;
|
||||||
|
|
||||||
// true if there is data pending to be transmitted
|
// true if there is data pending to be transmitted
|
||||||
bool txHasData() const;
|
bool txHasData() const;
|
||||||
|
|
||||||
// consume the amplitude data from the last generated waveform
|
// Consume the amplitude data from the last generated waveform
|
||||||
bool txTakeAmplitudeI16(AmplitudeI16 & dst);
|
bool txTakeAmplitudeI16(AmplitudeI16 & dst);
|
||||||
|
|
||||||
// the instance will allow Tx only with these protocols
|
// The instance will allow Tx only with these protocols. They are determined upon construction or when calling the
|
||||||
// they are determined upon construction, using GGWave::Protocols::tx()
|
// prepare() method, base on the contents of the global GGWave::Protocols::tx()
|
||||||
const TxProtocols & txProtocols() const;
|
const TxProtocols & txProtocols() const;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -703,14 +716,16 @@ public:
|
|||||||
|
|
||||||
bool rxStopReceiving();
|
bool rxStopReceiving();
|
||||||
|
|
||||||
// the instance will attempt to decode only these protocols
|
// The instance will attempt to decode only these protocols.
|
||||||
// they are determined upon construction, using GGWave::Protocols::rx()
|
// They are determined upon construction or when calling the prepare() method, base on the contents of the global
|
||||||
|
// GGWave::Protocols::rx()
|
||||||
|
//
|
||||||
|
// Note: do not enable protocols that were not enabled upon preparation of the GGWave instance, or the decoding
|
||||||
|
// will likely crash
|
||||||
//
|
//
|
||||||
// note: do not enable protocols that were not enabled upon construction of the GGWave
|
|
||||||
// instance, or the decoding will likely crash
|
|
||||||
RxProtocols & rxProtocols();
|
RxProtocols & rxProtocols();
|
||||||
|
|
||||||
// information about last received data
|
// Information about last received data
|
||||||
int rxDataLength() const;
|
int rxDataLength() const;
|
||||||
const TxRxData & rxData() const;
|
const TxRxData & rxData() const;
|
||||||
const RxProtocol & rxProtocol() const;
|
const RxProtocol & rxProtocol() const;
|
||||||
@@ -718,14 +733,16 @@ public:
|
|||||||
const Spectrum & rxSpectrum() const;
|
const Spectrum & rxSpectrum() const;
|
||||||
const Amplitude & rxAmplitude() const;
|
const Amplitude & rxAmplitude() const;
|
||||||
|
|
||||||
// consume the received data
|
// Consume the received data
|
||||||
|
//
|
||||||
|
// Returns the data length in bytes
|
||||||
//
|
//
|
||||||
// returns the data length in bytes
|
|
||||||
int rxTakeData(TxRxData & dst);
|
int rxTakeData(TxRxData & dst);
|
||||||
|
|
||||||
// consume the received spectrum / amplitude data
|
// Consume the received spectrum / amplitude data
|
||||||
|
//
|
||||||
|
// Returns true if there was new data available
|
||||||
//
|
//
|
||||||
// returns true if there was new data available
|
|
||||||
bool rxTakeSpectrum(Spectrum & dst);
|
bool rxTakeSpectrum(Spectrum & dst);
|
||||||
bool rxTakeAmplitude(Amplitude & dst);
|
bool rxTakeAmplitude(Amplitude & dst);
|
||||||
|
|
||||||
@@ -733,7 +750,7 @@ public:
|
|||||||
// Utils
|
// Utils
|
||||||
//
|
//
|
||||||
|
|
||||||
// compute FFT of real values
|
// Compute FFT of real values
|
||||||
//
|
//
|
||||||
// src - input real-valued data, size is N
|
// src - input real-valued data, size is N
|
||||||
// dst - output complex-valued data, size is 2*N
|
// dst - output complex-valued data, size is 2*N
|
||||||
@@ -742,7 +759,7 @@ public:
|
|||||||
//
|
//
|
||||||
bool computeFFTR(const float * src, float * dst, int N);
|
bool computeFFTR(const float * src, float * dst, int N);
|
||||||
|
|
||||||
// resample audio waveforms from one sample rate to another using sinc interpolation
|
// Resample audio waveforms from one sample rate to another using sinc interpolation
|
||||||
class Resampler {
|
class Resampler {
|
||||||
public:
|
public:
|
||||||
// this controls the number of neighboring samples
|
// this controls the number of neighboring samples
|
||||||
@@ -803,7 +820,7 @@ private:
|
|||||||
|
|
||||||
double bitFreq(const Protocol & p, int bit) const;
|
double bitFreq(const Protocol & p, int bit) const;
|
||||||
|
|
||||||
// initialized via prepare()
|
// Initialized via prepare()
|
||||||
float m_sampleRateInp = -1.0f;
|
float m_sampleRateInp = -1.0f;
|
||||||
float m_sampleRateOut = -1.0f;
|
float m_sampleRateOut = -1.0f;
|
||||||
float m_sampleRate = -1.0f;
|
float m_sampleRate = -1.0f;
|
||||||
@@ -835,7 +852,7 @@ private:
|
|||||||
bool m_txOnlyTones = false;
|
bool m_txOnlyTones = false;
|
||||||
bool m_isDSSEnabled = false;
|
bool m_isDSSEnabled = false;
|
||||||
|
|
||||||
// common
|
// Common
|
||||||
TxRxData m_dataEncoded;
|
TxRxData m_dataEncoded;
|
||||||
TxRxData m_workRSLength; // Reed-Solomon work buffers
|
TxRxData m_workRSLength; // Reed-Solomon work buffers
|
||||||
TxRxData m_workRSData;
|
TxRxData m_workRSData;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ int ggwave_encode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto pSrc = (const char *) ggWave->txData();
|
auto pSrc = (const char *) ggWave->txWaveform();
|
||||||
auto pDst = ( char *) waveformBuffer;
|
auto pDst = ( char *) waveformBuffer;
|
||||||
memcpy(pDst, pSrc, nBytes);
|
memcpy(pDst, pSrc, nBytes);
|
||||||
}
|
}
|
||||||
@@ -1023,35 +1023,11 @@ uint32_t GGWave::encode() {
|
|||||||
|
|
||||||
m_tx.lastAmplitudeSize = offset;
|
m_tx.lastAmplitudeSize = offset;
|
||||||
|
|
||||||
// the encoded waveform can be accessed via the txData() method
|
// the encoded waveform can be accessed via the txWaveform() method
|
||||||
// we return the size of the waveform in bytes:
|
// we return the size of the waveform in bytes:
|
||||||
return offset*m_sampleSizeOut;
|
return offset*m_sampleSizeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void * GGWave::txData() const {
|
|
||||||
if (m_isTxEnabled == false) {
|
|
||||||
ggprintf("Tx is disabled - cannot transmit data with this GGWave instance\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_sampleFormatOut) {
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_UNDEFINED: break;
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_I16:
|
|
||||||
{
|
|
||||||
return m_tx.outputI16.data();
|
|
||||||
} break;
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_U8:
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_I8:
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_U16:
|
|
||||||
case GGWAVE_SAMPLE_FORMAT_F32:
|
|
||||||
{
|
|
||||||
return m_tx.outputTmp.data();
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GGWave::decode(const void * data, uint32_t nBytes) {
|
bool GGWave::decode(const void * data, uint32_t nBytes) {
|
||||||
if (m_isRxEnabled == false) {
|
if (m_isRxEnabled == false) {
|
||||||
ggprintf("Rx is disabled - cannot receive data with this GGWave instance\n");
|
ggprintf("Rx is disabled - cannot receive data with this GGWave instance\n");
|
||||||
@@ -1213,6 +1189,25 @@ int GGWave::heapSize() const { return m_heapSize; }
|
|||||||
// Tx
|
// Tx
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const void * GGWave::txWaveform() const {
|
||||||
|
switch (m_sampleFormatOut) {
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_UNDEFINED: break;
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_I16:
|
||||||
|
{
|
||||||
|
return m_tx.outputI16.data();
|
||||||
|
} break;
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_U8:
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_I8:
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_U16:
|
||||||
|
case GGWAVE_SAMPLE_FORMAT_F32:
|
||||||
|
{
|
||||||
|
return m_tx.outputTmp.data();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const GGWave::Tones GGWave::txTones() const { return { m_tx.tones.data(), m_tx.nTones }; }
|
const GGWave::Tones GGWave::txTones() const { return { m_tx.tones.data(), m_tx.nTones }; }
|
||||||
|
|
||||||
bool GGWave::txHasData() const { return m_tx.hasData; }
|
bool GGWave::txHasData() const { return m_tx.hasData; }
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ int main(int argc, char ** argv) {
|
|||||||
const auto nBytes = instanceOut.encode();
|
const auto nBytes = instanceOut.encode();
|
||||||
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
||||||
CHECK(expectedSize >= nBytes);
|
CHECK(expectedSize >= nBytes);
|
||||||
{ auto p = (const uint8_t *)(instanceOut.txData()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
{ auto p = (const uint8_t *)(instanceOut.txWaveform()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
||||||
addNoiseHelper(0.01, parameters.sampleFormatOut); // add some artificial noise
|
addNoiseHelper(0.01, parameters.sampleFormatOut); // add some artificial noise
|
||||||
convertHelper(parameters.sampleFormatOut, parameters.sampleFormatInp);
|
convertHelper(parameters.sampleFormatOut, parameters.sampleFormatInp);
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ int main(int argc, char ** argv) {
|
|||||||
const auto nBytes = instance.encode();
|
const auto nBytes = instance.encode();
|
||||||
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
||||||
CHECK(expectedSize == nBytes);
|
CHECK(expectedSize == nBytes);
|
||||||
{ auto p = (const uint8_t *)(instance.txData()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
{ auto p = (const uint8_t *)(instance.txWaveform()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
||||||
convertHelper(formatOut, formatInp);
|
convertHelper(formatOut, formatInp);
|
||||||
instance.decode(buffer.data(), buffer.size());
|
instance.decode(buffer.data(), buffer.size());
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ int main(int argc, char ** argv) {
|
|||||||
const auto nBytes = instance.encode();
|
const auto nBytes = instance.encode();
|
||||||
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
printf("Expected = %d, actual = %d\n", expectedSize, nBytes);
|
||||||
CHECK(expectedSize == nBytes);
|
CHECK(expectedSize == nBytes);
|
||||||
{ auto p = (const uint8_t *)(instance.txData()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
{ auto p = (const uint8_t *)(instance.txWaveform()); buffer.resize(nBytes); memcpy(buffer.data(), p, nBytes); }
|
||||||
convertHelper(formatOut, formatInp);
|
convertHelper(formatOut, formatInp);
|
||||||
instance.decode(buffer.data(), buffer.size());
|
instance.decode(buffer.data(), buffer.size());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user