waver v1.5.2 : add option to shift the base tx/rx freqency

This can be used to easily change the frequency range of a protocols.
Make sure that the transmitter and receiver are using the same exact
shift.
This commit is contained in:
Georgi Gerganov
2022-07-10 17:36:06 +03:00
parent f2c8231cfc
commit 3591285bd9
3 changed files with 91 additions and 26 deletions

View File

@@ -89,6 +89,13 @@ void setup() {
// Protocols to use for TX
GGWave::Protocols::tx().only(GGWAVE_PROTOCOL_MT_FASTEST);
// Sometimes, the speaker might not be able to produce frequencies in the Mono-tone range of 1-2 kHz.
// In such cases, you can shift the base frequency up by changing the "freqStart" parameter of the protocol.
// Make sure that in the receiver (for example, the "Waver" app) the base frequency is shifted by the same amount.
// Here we shift the frequency by +48 bins. Each bin is equal to 48000/1024 = 46.875 Hz.
// So the base frequency is shifted by +2250 Hz.
//GGWave::Protocols::tx()[GGWAVE_PROTOCOL_MT_FASTEST].freqStart += 48;
// Initialize the ggwave instance and print the memory usage
ggwave.prepare(p);
Serial.println(ggwave.heapSize());

View File

@@ -236,6 +236,7 @@ struct Input {
dst.update = true;
dst.flags.needReinit = true;
dst.sampleRateOffset = std::move(this->sampleRateOffset);
dst.freqStartShift = std::move(this->freqStartShift);
dst.payloadLength = std::move(this->payloadLength);
dst.directSequenceSpread = std::move(this->directSequenceSpread);
}
@@ -266,6 +267,7 @@ struct Input {
// reinit
float sampleRateOffset = 0;
int freqStartShift = 0;
int payloadLength = -1;
// spectrum
@@ -636,10 +638,19 @@ void updateCore() {
if (inputCurrent.flags.needReinit) {
static auto sampleRateInpOld = ggWave->sampleRateInp();
static auto sampleRateOutOld = ggWave->sampleRateOut();
static auto freqStartShiftOld = 0;
auto sampleFormatInpOld = ggWave->sampleFormatInp();
auto sampleFormatOutOld = ggWave->sampleFormatOut();
auto rxProtocolsOld = ggWave->rxProtocols();
for (int i = 0; i < GGWAVE_PROTOCOL_COUNT; ++i) {
GGWave::Protocols::tx()[i].freqStart = std::max(1, GGWave::Protocols::tx()[i].freqStart + inputCurrent.freqStartShift - freqStartShiftOld);
rxProtocolsOld[i].freqStart = std::max(1, rxProtocolsOld[i].freqStart + inputCurrent.freqStartShift - freqStartShiftOld);
}
freqStartShiftOld = inputCurrent.freqStartShift;
GGWave::OperatingMode mode = GGWAVE_OPERATING_MODE_RX_AND_TX;
if (inputCurrent.directSequenceSpread) mode |= GGWAVE_OPERATING_MODE_USE_DSS;
@@ -853,6 +864,8 @@ void renderMain() {
int protocolId = GGWAVE_PROTOCOL_AUDIBLE_FAST;
bool isSampleRateOffset = false;
float sampleRateOffset = -512.0f;
bool isFreqStartShift = false;
int freqStartShift = 48;
bool isFixedLength = false;
bool directSequenceSpread = false;
int payloadLength = 16;
@@ -1055,7 +1068,7 @@ void renderMain() {
if (windowId == WindowId::Settings) {
ImGui::BeginChild("Settings:main", ImGui::GetContentRegionAvail(), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
ImGui::Text("Waver v1.5.1");
ImGui::Text("Waver v1.5.2");
ImGui::Separator();
ImGui::Text("%s", "");
@@ -1177,7 +1190,10 @@ void renderMain() {
{
const float df = statsCurrent.sampleRate/statsCurrent.samplesPerFrame;
const auto & protocol = settings.txProtocols[settings.protocolId];
ImGui::Text("%6.2f Hz - %6.2f Hz", df*protocol.freqStart, df*(protocol.freqStart + float(2*16*protocol.bytesPerTx)/protocol.extra));
const auto freqStart = std::max(1, protocol.freqStart + (settings.isFreqStartShift ? settings.freqStartShift : 0));
const float f0 = df*freqStart;
const float f1 = df*(freqStart + float(2*16*protocol.bytesPerTx)/protocol.extra);
ImGui::Text("%6.2f Hz - %6.2f Hz", f0, f1);
}
// fixed-length
@@ -1204,7 +1220,7 @@ void renderMain() {
if (settings.isFixedLength) {
ImGui::SameLine();
ImGui::PushItemWidth(0.5*ImGui::GetContentRegionAvailWidth());
if (ImGui::SliderInt("Bytes", &settings.payloadLength, 1, GGWave::kMaxLengthFixed)) {
if (ImGui::DragInt("Bytes", &settings.payloadLength, 1, 1, GGWave::kMaxLengthFixed)) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.flags.needReinit = true;
g_buffer.inputUI.payloadLength = settings.isFixedLength ? settings.payloadLength : -1;
@@ -1212,8 +1228,71 @@ void renderMain() {
ImGui::PopItemWidth();
}
// Direct-sequence spread
//ImGui::Text("%s", "");
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("%s", "");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
ImGui::PushTextWrapPos();
ImGui::TextDisabled("Direct-sequence spread");
ImGui::PopTextWrapPos();
}
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("Use DSS: ");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
}
if (ImGui::Checkbox("##direct-sequence-spread", &settings.directSequenceSpread)) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.flags.needReinit = true;
g_buffer.inputUI.directSequenceSpread = settings.directSequenceSpread;
}
// FreqStart offset
//ImGui::Text("%s", "");
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("%s", "");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
ImGui::PushTextWrapPos();
ImGui::TextDisabled("Apply tx/rx frequency shift");
ImGui::PopTextWrapPos();
}
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("Freq shift: ");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
}
if (ImGui::Checkbox("##freq-start-offset", &settings.isFreqStartShift)) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.flags.needReinit = true;
g_buffer.inputUI.freqStartShift = settings.isFreqStartShift ? settings.freqStartShift : 0;
}
if (settings.isFreqStartShift) {
ImGui::SameLine();
ImGui::PushItemWidth(0.5*ImGui::GetContentRegionAvailWidth());
if (ImGui::DragInt("bins", &settings.freqStartShift, 1, -64, 64, "%d")) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.flags.needReinit = true;
g_buffer.inputUI.freqStartShift = settings.isFreqStartShift ? settings.freqStartShift : 0;
}
ImGui::PopItemWidth();
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
}
{
const float df = statsCurrent.sampleRate/statsCurrent.samplesPerFrame;
ImGui::Text("%6.2f Hz", df*settings.freqStartShift);
}
}
// Output sample-rate offset
ImGui::Text("%s", "");
//ImGui::Text("%s", "");
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("%s", "");
@@ -1244,27 +1323,6 @@ void renderMain() {
ImGui::PopItemWidth();
}
// Direct-sequence spread
ImGui::Text("%s", "");
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("%s", "");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
ImGui::PushTextWrapPos();
ImGui::TextDisabled("Direct-sequence spread");
ImGui::PopTextWrapPos();
}
{
auto posSave = ImGui::GetCursorScreenPos();
ImGui::Text("Use DSS: ");
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
}
if (ImGui::Checkbox("##direct-sequence-spread", &settings.directSequenceSpread)) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.flags.needReinit = true;
g_buffer.inputUI.directSequenceSpread = settings.directSequenceSpread;
}
// rx protocols
bool updateRxProtocols = false;
ImGui::Text("%s", "");