ggwave : add DSS tests + improve enums

This commit is contained in:
Georgi Gerganov
2022-06-11 22:01:08 +03:00
parent 915dd8be16
commit 4cb6ee80a2
8 changed files with 52 additions and 43 deletions

View File

@@ -36,30 +36,27 @@ EMSCRIPTEN_BINDINGS(ggwave) {
.value("GGWAVE_PROTOCOL_CUSTOM_9", GGWAVE_PROTOCOL_CUSTOM_9) .value("GGWAVE_PROTOCOL_CUSTOM_9", GGWAVE_PROTOCOL_CUSTOM_9)
; ;
emscripten::enum_<ggwave_OperatingMode>("OperatingMode") emscripten::constant("GGWAVE_OPERATING_MODE_RX", (int) GGWAVE_OPERATING_MODE_RX);
.value("GGWAVE_OPERATING_MODE_RX", GGWAVE_OPERATING_MODE_RX) emscripten::constant("GGWAVE_OPERATING_MODE_TX", (int) GGWAVE_OPERATING_MODE_TX);
.value("GGWAVE_OPERATING_MODE_TX", GGWAVE_OPERATING_MODE_TX) emscripten::constant("GGWAVE_OPERATING_MODE_RX_AND_TX", (int) GGWAVE_OPERATING_MODE_RX | GGWAVE_OPERATING_MODE_TX);
.value("GGWAVE_OPERATING_MODE_RX_AND_TX", (ggwave_OperatingMode) (GGWAVE_OPERATING_MODE_RX | GGWAVE_OPERATING_MODE_TX)) emscripten::constant("GGWAVE_OPERATING_MODE_TX_ONLY_TONES", (int) GGWAVE_OPERATING_MODE_TX_ONLY_TONES);
.value("GGWAVE_OPERATING_MODE_TX_ONLY_TONES", GGWAVE_OPERATING_MODE_TX_ONLY_TONES) emscripten::constant("GGWAVE_OPERATING_MODE_USE_DSS", (int) GGWAVE_OPERATING_MODE_USE_DSS);
.value("GGWAVE_OPERATING_MODE_TX_USE_DSS", GGWAVE_OPERATING_MODE_USE_DSS)
emscripten::value_object<ggwave_Parameters>("Parameters")
.field("payloadLength", & ggwave_Parameters::payloadLength)
.field("sampleRateInp", & ggwave_Parameters::sampleRateInp)
.field("sampleRateOut", & ggwave_Parameters::sampleRateOut)
.field("sampleRate", & ggwave_Parameters::sampleRate)
.field("samplesPerFrame", & ggwave_Parameters::samplesPerFrame)
.field("soundMarkerThreshold", & ggwave_Parameters::soundMarkerThreshold)
.field("sampleFormatInp", & ggwave_Parameters::sampleFormatInp)
.field("sampleFormatOut", & ggwave_Parameters::sampleFormatOut)
.field("operatingMode", & ggwave_Parameters::operatingMode)
; ;
emscripten::class_<ggwave_Parameters>("Parameters") emscripten::function("getDefaultParameters", & ggwave_getDefaultParameters);
.constructor<>() emscripten::function("init", & ggwave_init);
.property("payloadLength", & ggwave_Parameters::payloadLength) emscripten::function("free", & ggwave_free);
.property("sampleRateInp", & ggwave_Parameters::sampleRateInp)
.property("sampleRateOut", & ggwave_Parameters::sampleRateOut)
.property("sampleRate", & ggwave_Parameters::sampleRate)
.property("samplesPerFrame", & ggwave_Parameters::samplesPerFrame)
.property("soundMarkerThreshold", & ggwave_Parameters::soundMarkerThreshold)
.property("sampleFormatInp", & ggwave_Parameters::sampleFormatInp)
.property("sampleFormatOut", & ggwave_Parameters::sampleFormatOut)
.property("operatingMode", & ggwave_Parameters::operatingMode)
;
emscripten::function("getDefaultParameters", &ggwave_getDefaultParameters);
emscripten::function("init", &ggwave_init);
emscripten::function("free", &ggwave_free);
emscripten::function("encode", emscripten::optional_override( emscripten::function("encode", emscripten::optional_override(
[](ggwave_Instance instance, [](ggwave_Instance instance,
@@ -67,17 +64,25 @@ EMSCRIPTEN_BINDINGS(ggwave) {
ggwave_ProtocolId protocolId, ggwave_ProtocolId protocolId,
int volume) { int volume) {
auto n = ggwave_encode(instance, data.data(), data.size(), protocolId, volume, nullptr, 1); auto n = ggwave_encode(instance, data.data(), data.size(), protocolId, volume, nullptr, 1);
std::vector<char> result(n);
result.resize(n);
ggwave_encode(instance, data.data(), data.size(), protocolId, volume, result.data(), 0);
return emscripten::val(emscripten::typed_memory_view(result.size(), result.data())); // TODO: how to return the waveform data?
// for now using this static vector and returning a pointer to it
static std::vector<char> result(n);
result.resize(n);
int nActual = ggwave_encode(instance, data.data(), data.size(), protocolId, volume, result.data(), 0);
printf("n = %d, nActual = %d\n", n, nActual);
return emscripten::val(emscripten::typed_memory_view(nActual, result.data()));
})); }));
emscripten::function("decode", emscripten::optional_override( emscripten::function("decode", emscripten::optional_override(
[](ggwave_Instance instance, [](ggwave_Instance instance,
const std::string & data) { const std::string & data) {
char output[256]; // TODO: how to return the result?
// again using a static array and returning a pointer to it
static char output[256];
auto n = ggwave_decode(instance, data.data(), data.size(), output); auto n = ggwave_decode(instance, data.data(), data.size(), output);
if (n > 0) { if (n > 0) {

File diff suppressed because one or more lines are too long

View File

@@ -30,7 +30,7 @@ cdef extern from "ggwave.h" nogil:
GGWAVE_PROTOCOL_CUSTOM_8, GGWAVE_PROTOCOL_CUSTOM_8,
GGWAVE_PROTOCOL_CUSTOM_9 GGWAVE_PROTOCOL_CUSTOM_9
ctypedef enum ggwave_OperatingMode: enum:
GGWAVE_OPERATING_MODE_RX, GGWAVE_OPERATING_MODE_RX,
GGWAVE_OPERATING_MODE_TX, GGWAVE_OPERATING_MODE_TX,
GGWAVE_OPERATING_MODE_RX_AND_TX, GGWAVE_OPERATING_MODE_RX_AND_TX,
@@ -46,7 +46,7 @@ cdef extern from "ggwave.h" nogil:
float soundMarkerThreshold float soundMarkerThreshold
ggwave_SampleFormat sampleFormatInp ggwave_SampleFormat sampleFormatInp
ggwave_SampleFormat sampleFormatOut ggwave_SampleFormat sampleFormatOut
ggwave_OperatingMode operatingMode int operatingMode
ctypedef int ggwave_Instance ctypedef int ggwave_Instance

View File

@@ -69,7 +69,7 @@ void setup() {
p.samplesPerFrame = samplesPerFrame; p.samplesPerFrame = samplesPerFrame;
p.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16; p.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16;
p.sampleFormatOut = GGWAVE_SAMPLE_FORMAT_I16; p.sampleFormatOut = GGWAVE_SAMPLE_FORMAT_I16;
p.operatingMode = (ggwave_OperatingMode) (GGWAVE_OPERATING_MODE_RX | GGWAVE_OPERATING_MODE_TX | GGWAVE_OPERATING_MODE_USE_DSS | GGWAVE_OPERATING_MODE_TX_ONLY_TONES); p.operatingMode = GGWAVE_OPERATING_MODE_RX | GGWAVE_OPERATING_MODE_TX | GGWAVE_OPERATING_MODE_USE_DSS | GGWAVE_OPERATING_MODE_TX_ONLY_TONES;
GGWave::Protocols::tx().disableAll(); GGWave::Protocols::tx().disableAll();
GGWave::Protocols::tx().toggle(GGWAVE_PROTOCOL_DT_NORMAL, true); GGWave::Protocols::tx().toggle(GGWAVE_PROTOCOL_DT_NORMAL, true);

View File

@@ -54,7 +54,7 @@ void setup() {
p.samplesPerFrame = samplesPerFrame; p.samplesPerFrame = samplesPerFrame;
p.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16; p.sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16;
p.sampleFormatOut = GGWAVE_SAMPLE_FORMAT_U8; p.sampleFormatOut = GGWAVE_SAMPLE_FORMAT_U8;
p.operatingMode = (ggwave_OperatingMode) (GGWAVE_OPERATING_MODE_TX | GGWAVE_OPERATING_MODE_TX_ONLY_TONES | GGWAVE_OPERATING_MODE_USE_DSS); p.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);
ggwave.prepare(p); ggwave.prepare(p);

View File

@@ -165,7 +165,7 @@ extern "C" {
// This function returns an id that can be used to identify this instance. // This function returns an id that can be used to identify this instance.
// Make sure to deallocate the instance at the end by calling ggwave_free() // Make sure to deallocate the instance at the end by calling ggwave_free()
// //
GGWAVE_API ggwave_Instance ggwave_init(const ggwave_Parameters parameters); GGWAVE_API ggwave_Instance ggwave_init(ggwave_Parameters parameters);
// Free a GGWave instance // Free a GGWave instance
GGWAVE_API void ggwave_free(ggwave_Instance instance); GGWAVE_API void ggwave_free(ggwave_Instance instance);

View File

@@ -51,19 +51,19 @@ ggwave_Parameters ggwave_getDefaultParameters(void) {
} }
extern "C" extern "C"
ggwave_Instance ggwave_init(const ggwave_Parameters parameters) { ggwave_Instance ggwave_init(ggwave_Parameters parameters) {
for (ggwave_Instance id = 0; id < GGWAVE_MAX_INSTANCES; ++id) { for (ggwave_Instance id = 0; id < GGWAVE_MAX_INSTANCES; ++id) {
if (g_instances[id] == nullptr) { if (g_instances[id] == nullptr) {
g_instances[id] = new GGWave({ g_instances[id] = new GGWave({
parameters.payloadLength, parameters.payloadLength,
parameters.sampleRateInp, parameters.sampleRateInp,
parameters.sampleRateOut, parameters.sampleRateOut,
parameters.sampleRate, parameters.sampleRate,
parameters.samplesPerFrame, parameters.samplesPerFrame,
parameters.soundMarkerThreshold, parameters.soundMarkerThreshold,
parameters.sampleFormatInp, parameters.sampleFormatInp,
parameters.sampleFormatOut, parameters.sampleFormatOut,
parameters.operatingMode}); parameters.operatingMode});
return id; return id;
} }
@@ -1123,7 +1123,7 @@ bool GGWave::decode(const void * data, uint32_t nBytes) {
uint32_t offset = m_samplesPerFrame - m_rx.samplesNeeded; uint32_t offset = m_samplesPerFrame - m_rx.samplesNeeded;
if (m_sampleRateInp != m_sampleRate) { if (m_needResampling) {
if (nSamplesRecorded <= 2*Resampler::kWidth) { if (nSamplesRecorded <= 2*Resampler::kWidth) {
m_rx.samplesNeeded = m_samplesPerFrame; m_rx.samplesNeeded = m_samplesPerFrame;
break; break;

View File

@@ -3,7 +3,11 @@ var factory = require('../bindings/javascript/ggwave.js')
factory().then(function(ggwave) { factory().then(function(ggwave) {
// create ggwave instance with default parameters // create ggwave instance with default parameters
var parameters = ggwave.getDefaultParameters(); var parameters = ggwave.getDefaultParameters();
parameters.operatingMode |= ggwave.GGWAVE_OPERATING_MODE_USE_DSS;
var instance = ggwave.init(parameters); var instance = ggwave.init(parameters);
console.log('instance: ' + instance);
var payload = 'hello js'; var payload = 'hello js';