ggwave : remove <functional> header dependency

This commit is contained in:
Georgi Gerganov
2022-05-30 22:01:38 +03:00
parent 422f0dcc84
commit 782ab237ac
13 changed files with 283 additions and 314 deletions

View File

@@ -88,6 +88,7 @@ else()
add_subdirectory(ggwave-to-file)
add_subdirectory(arduino-rx)
add_subdirectory(arduino-tx)
endif()
if (GGWAVE_SUPPORT_SDL2)

View File

@@ -16,6 +16,7 @@
#include <chrono>
#include <string>
#include <thread>
#include <functional>
namespace {
@@ -257,14 +258,6 @@ bool GGWave_mainLoop() {
return false;
}
static GGWave::CBWaveformOut cbWaveformOut = [&](const void * data, uint32_t nBytes) {
SDL_QueueAudio(g_devIdOut, data, nBytes);
};
static GGWave::CBWaveformInp cbWaveformInp = [&](void * data, uint32_t nMaxBytes) {
return SDL_DequeueAudio(g_devIdInp, data, nMaxBytes);
};
if (g_ggWave->hasTxData() == false) {
SDL_PauseAudioDevice(g_devIdOut, SDL_FALSE);
@@ -273,22 +266,29 @@ bool GGWave_mainLoop() {
if ((int) SDL_GetQueuedAudioSize(g_devIdOut) < g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesOut()) {
SDL_PauseAudioDevice(g_devIdInp, SDL_FALSE);
if (::getTime_ms(tLastNoData, tNow) > 500.0f) {
g_ggWave->decode(cbWaveformInp);
const int nHave = (int) SDL_GetQueuedAudioSize(g_devIdInp);
const int nNeed = g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp();
if (::getTime_ms(tLastNoData, tNow) > 500.0f && nHave >= nNeed) {
static std::vector<uint8_t> dataInp(nNeed);
SDL_DequeueAudio(g_devIdInp, dataInp.data(), nNeed);
GGWave::TxRxData rxData;
int n = g_ggWave->takeRxData(rxData);
if (n > 0) {
for (int i = 0; i < n; i++) {
rxData[i] ^= kDSSMagic[i%kDSSMagic.size()];
if (g_ggWave->decode(dataInp.data(), dataInp.size()) == false) {
fprintf(stderr, "Warning: failed to decode input data!\n");
} else {
GGWave::TxRxData rxData;
int n = g_ggWave->takeRxData(rxData);
if (n > 0) {
for (int i = 0; i < n; i++) {
rxData[i] ^= kDSSMagic[i%kDSSMagic.size()];
}
std::time_t timestamp = std::time(nullptr);
std::string tstr = std::asctime(std::localtime(&timestamp));
tstr.back() = 0;
printf("[%s] Received: '%s'\n", tstr.c_str(), rxData.data());
}
std::time_t timestamp = std::time(nullptr);
std::string tstr = std::asctime(std::localtime(&timestamp));
tstr.back() = 0;
printf("[%s] Received: '%s'\n", tstr.c_str(), rxData.data());
}
if ((int) SDL_GetQueuedAudioSize(g_devIdInp) > 32*g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp()) {
if (nHave > 32*nNeed) {
fprintf(stderr, "Warning: slow processing, clearing queued audio buffer of %d bytes ...", SDL_GetQueuedAudioSize(g_devIdInp));
SDL_ClearQueuedAudio(g_devIdInp);
}
@@ -302,7 +302,8 @@ bool GGWave_mainLoop() {
SDL_PauseAudioDevice(g_devIdOut, SDL_TRUE);
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
g_ggWave->encode(cbWaveformOut);
const auto nBytes = g_ggWave->encode();
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
}
return true;

View File

@@ -1,4 +1,6 @@
#include "ggwave.h"
#include <ArduinoSTL.h>
#include "ggwave/ggwave.h"
const int kPinLed0 = 13;
const int kPinSpeaker = 10;
@@ -6,53 +8,53 @@ const int kPinButton0 = 2;
const int kPinButton1 = 4;
void setup() {
Serial.begin(57600);
//Serial.begin(57600);
pinMode(kPinLed0, OUTPUT);
pinMode(kPinSpeaker, OUTPUT);
pinMode(kPinButton0, INPUT);
pinMode(kPinButton1, INPUT);
//pinMode(kPinLed0, OUTPUT);
//pinMode(kPinSpeaker, OUTPUT);
//pinMode(kPinButton0, INPUT);
//pinMode(kPinButton1, INPUT);
delay(3000);
//delay(3000);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, "Hello!", GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
//digitalWrite(kPinLed0, HIGH);
//GGWave::send_text(kPinSpeaker, "Hello!", GGWave::TX_ARDUINO_512_FASTEST);
//digitalWrite(kPinLed0, LOW);
delay(2000);
//delay(2000);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, "This is a", GGWave::TX_ARDUINO_512_FASTEST);
GGWave::send_text(kPinSpeaker, "ggwave demo", GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
//digitalWrite(kPinLed0, HIGH);
//GGWave::send_text(kPinSpeaker, "This is a", GGWave::TX_ARDUINO_512_FASTEST);
//GGWave::send_text(kPinSpeaker, "ggwave demo", GGWave::TX_ARDUINO_512_FASTEST);
//digitalWrite(kPinLed0, LOW);
delay(2000);
//delay(2000);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, "The arduino", GGWave::TX_ARDUINO_512_FASTEST);
delay(200);
GGWave::send_text(kPinSpeaker, "transmits data", GGWave::TX_ARDUINO_512_FASTEST);
delay(200);
GGWave::send_text(kPinSpeaker, "using sound", GGWave::TX_ARDUINO_512_FASTEST);
delay(200);
GGWave::send_text(kPinSpeaker, "through a buzzer", GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
//digitalWrite(kPinLed0, HIGH);
//GGWave::send_text(kPinSpeaker, "The arduino", GGWave::TX_ARDUINO_512_FASTEST);
//delay(200);
//GGWave::send_text(kPinSpeaker, "transmits data", GGWave::TX_ARDUINO_512_FASTEST);
//delay(200);
//GGWave::send_text(kPinSpeaker, "using sound", GGWave::TX_ARDUINO_512_FASTEST);
//delay(200);
//GGWave::send_text(kPinSpeaker, "through a buzzer", GGWave::TX_ARDUINO_512_FASTEST);
//digitalWrite(kPinLed0, LOW);
delay(1000);
//delay(1000);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, "The sound is", GGWave::TX_ARDUINO_512_FASTEST);
delay(200);
GGWave::send_text(kPinSpeaker, "decoded in a", GGWave::TX_ARDUINO_512_FASTEST);
delay(200);
GGWave::send_text(kPinSpeaker, "web page.", GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
//digitalWrite(kPinLed0, HIGH);
//GGWave::send_text(kPinSpeaker, "The sound is", GGWave::TX_ARDUINO_512_FASTEST);
//delay(200);
//GGWave::send_text(kPinSpeaker, "decoded in a", GGWave::TX_ARDUINO_512_FASTEST);
//delay(200);
//GGWave::send_text(kPinSpeaker, "web page.", GGWave::TX_ARDUINO_512_FASTEST);
//digitalWrite(kPinLed0, LOW);
delay(1000);
//delay(1000);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, "Press the button!", GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
//digitalWrite(kPinLed0, HIGH);
//GGWave::send_text(kPinSpeaker, "Press the button!", GGWave::TX_ARDUINO_512_FASTEST);
//digitalWrite(kPinLed0, LOW);
}
char txt[16];
@@ -62,23 +64,23 @@ bool isDown = false;
void loop() {
Serial.println("hello");
int but0 = digitalRead(kPinButton0);
int but1 = digitalRead(kPinButton1);
//int but0 = digitalRead(kPinButton0);
//int but1 = digitalRead(kPinButton1);
if (but1 == LOW && isDown == false) {
delay(200);
++pressed;
isDown = true;
} else if (but1 == HIGH) {
isDown = false;
}
//if (but1 == LOW && isDown == false) {
// delay(200);
// ++pressed;
// isDown = true;
//} else if (but1 == HIGH) {
// isDown = false;
//}
if (but0 == LOW) {
snprintf(txt, 16, "Pressed: %d", pressed);
//if (but0 == LOW) {
// snprintf(txt, 16, "Pressed: %d", pressed);
digitalWrite(kPinLed0, HIGH);
GGWave::send_text(kPinSpeaker, txt, GGWave::TX_ARDUINO_512_FASTEST);
digitalWrite(kPinLed0, LOW);
pressed = 0;
}
// digitalWrite(kPinLed0, HIGH);
// GGWave::send_text(kPinSpeaker, txt, GGWave::TX_ARDUINO_512_FASTEST);
// digitalWrite(kPinLed0, LOW);
// pressed = 0;
//}
}

View File

@@ -62,11 +62,11 @@ int main(int argc, char** argv) {
if (printTones) {
printf("Printing generated waveform tones (Hz):\n");
auto waveformTones = ggWave->getWaveformTones();
for (int i = 0; i < (int) waveformTones.size(); ++i) {
const auto tones = ggWave->txTones();
for (int i = 0; i < (int) tones.size(); ++i) {
printf(" - frame %3d: ", i);
for (int j = 0; j < (int) waveformTones[i].size(); ++j) {
printf("%8.2f ", waveformTones[i][j].freq_hz);
for (int j = 0; j < (int) tones[i].size(); ++j) {
printf("%8.2f ", tones[i][j].freq_hz);
}
printf("\n");
}

View File

@@ -240,14 +240,6 @@ bool GGWave_mainLoop() {
return false;
}
static GGWave::CBWaveformOut cbWaveformOut = [&](const void * data, uint32_t nBytes) {
SDL_QueueAudio(g_devIdOut, data, nBytes);
};
static GGWave::CBWaveformInp cbWaveformInp = [&](void * data, uint32_t nMaxBytes) {
return SDL_DequeueAudio(g_devIdInp, data, nMaxBytes);
};
if (g_ggWave->hasTxData() == false) {
SDL_PauseAudioDevice(g_devIdOut, SDL_FALSE);
@@ -256,9 +248,17 @@ bool GGWave_mainLoop() {
if ((int) SDL_GetQueuedAudioSize(g_devIdOut) < g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesOut()) {
SDL_PauseAudioDevice(g_devIdInp, SDL_FALSE);
if (::getTime_ms(tLastNoData, tNow) > 500.0f) {
g_ggWave->decode(cbWaveformInp);
if ((int) SDL_GetQueuedAudioSize(g_devIdInp) > 32*g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp()) {
const int nHave = (int) SDL_GetQueuedAudioSize(g_devIdInp);
const int nNeed = g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp();
if (::getTime_ms(tLastNoData, tNow) > 500.0f && nHave >= nNeed) {
static std::vector<uint8_t> dataInp(nNeed);
SDL_DequeueAudio(g_devIdInp, dataInp.data(), nNeed);
if (g_ggWave->decode(dataInp.data(), dataInp.size()) == false) {
fprintf(stderr, "Warning: failed to decode input data!\n");
}
if (nHave > 32*nNeed) {
fprintf(stderr, "Warning: slow processing, clearing queued audio buffer of %d bytes ...\n", SDL_GetQueuedAudioSize(g_devIdInp));
SDL_ClearQueuedAudio(g_devIdInp);
}
@@ -272,7 +272,8 @@ bool GGWave_mainLoop() {
SDL_PauseAudioDevice(g_devIdOut, SDL_TRUE);
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
g_ggWave->encode(cbWaveformOut);
const auto nBytes = g_ggWave->encode();
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
}
return true;

View File

@@ -84,17 +84,15 @@ int main(int argc, char** argv) {
});
ggWave.init(message.size(), message.data(), ggWave.getTxProtocol(protocolId), volume);
std::vector<char> bufferPCM;
GGWave::CBWaveformOut cbWaveformOut = [&](const void * data, uint32_t nBytes) {
bufferPCM.resize(nBytes);
std::memcpy(bufferPCM.data(), data, nBytes);
};
if (ggWave.encode(cbWaveformOut) == false) {
const auto nBytes = ggWave.encode();
if (nBytes == 0) {
fprintf(stderr, "Failed to generate waveform!\n");
return -4;
}
std::vector<char> bufferPCM(nBytes);
std::memcpy(bufferPCM.data(), ggWave.txData(), nBytes);
fprintf(stderr, "Output size = %d bytes\n", (int) bufferPCM.size());
drwav_data_format format;

View File

@@ -132,14 +132,12 @@ int main(int argc, char** argv) {
}
ggWave.init(message.size(), message.data(), protocols.at(GGWave::TxProtocolId(txProtocolId)), 10);
GGWave::CBWaveformOut tmp = [](const void * , uint32_t ){};
ggWave.encode(tmp);
ggWave.encode();
int nFrames = 0;
double lastF = -1.0f;
auto tones = ggWave.getWaveformTones();
auto tones = ggWave.txTones();
for (auto & tonesCur : tones) {
if (tonesCur.size() == 0) continue;
const auto & tone = tonesCur.front();

View File

@@ -15,6 +15,7 @@
#include <chrono>
#include <string>
#include <thread>
#include <functional>
namespace {
@@ -247,14 +248,6 @@ bool GGWave_mainLoop() {
return false;
}
static GGWave::CBWaveformOut cbWaveformOut = [&](const void * data, uint32_t nBytes) {
SDL_QueueAudio(g_devIdOut, data, nBytes);
};
static GGWave::CBWaveformInp cbWaveformInp = [&](void * data, uint32_t nMaxBytes) {
return SDL_DequeueAudio(g_devIdInp, data, nMaxBytes);
};
if (g_ggWave->hasTxData() == false) {
SDL_PauseAudioDevice(g_devIdOut, SDL_FALSE);
@@ -263,10 +256,18 @@ bool GGWave_mainLoop() {
if ((int) SDL_GetQueuedAudioSize(g_devIdOut) < g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesOut()) {
SDL_PauseAudioDevice(g_devIdInp, SDL_FALSE);
if (::getTime_ms(tLastNoData, tNow) > 500.0f) {
g_ggWave->decode(cbWaveformInp);
if ((int) SDL_GetQueuedAudioSize(g_devIdInp) > 32*g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp()) {
fprintf(stderr, "Warning: slow processing, clearing queued audio buffer of %d bytes ...", SDL_GetQueuedAudioSize(g_devIdInp));
const int nHave = (int) SDL_GetQueuedAudioSize(g_devIdInp);
const int nNeed = g_ggWave->getSamplesPerFrame()*g_ggWave->getSampleSizeBytesInp();
if (::getTime_ms(tLastNoData, tNow) > 500.0f && nHave >= nNeed) {
static std::vector<uint8_t> dataInp(nNeed);
SDL_DequeueAudio(g_devIdInp, dataInp.data(), nNeed);
if (g_ggWave->decode(dataInp.data(), dataInp.size()) == false) {
fprintf(stderr, "Warning: failed to decode input data!\n");
}
if (nHave > 32*nNeed) {
fprintf(stderr, "Warning: slow processing, clearing queued audio buffer of %d bytes ...\n", SDL_GetQueuedAudioSize(g_devIdInp));
SDL_ClearQueuedAudio(g_devIdInp);
}
} else {
@@ -279,7 +280,8 @@ bool GGWave_mainLoop() {
SDL_PauseAudioDevice(g_devIdOut, SDL_TRUE);
SDL_PauseAudioDevice(g_devIdInp, SDL_TRUE);
g_ggWave->encode(cbWaveformOut);
const auto nBytes = g_ggWave->encode();
SDL_QueueAudio(g_devIdOut, g_ggWave->txData(), nBytes);
}
return true;

View File

@@ -173,14 +173,6 @@ bool GGWave_mainLoop() {
return false;
}
static GGWave::CBWaveformOut cbQueueAudio = [&](const void * data, uint32_t nBytes) {
SDL_QueueAudio(g_devIdOut, data, nBytes);
};
static GGWave::CBWaveformInp cbWaveformInp = [&](void * data, uint32_t nMaxBytes) {
return SDL_DequeueAudio(g_devIdInp, data, nMaxBytes);
};
SDL_PauseAudioDevice(g_devIdInp, SDL_FALSE);
if (!g_isCapturing) {
SDL_ClearQueuedAudio(g_devIdInp);
@@ -190,7 +182,7 @@ bool GGWave_mainLoop() {
static float data[g_nSamplesPerFrame];
static float out[2*g_nSamplesPerFrame];
do {
n = cbWaveformInp(data, sizeof(float)*g_nSamplesPerFrame);
n = SDL_DequeueAudio(g_devIdInp, data, sizeof(float)*g_nSamplesPerFrame);
if (n <= 0) break;
FFT(data, out, g_nSamplesPerFrame, 1.0);