Waver v1.4.0 (#23)

* waver : change default protocol

* waver : global scale to 1.25

* waver : more colors

* waver : resend last message

* waver : bigger send button

* waver : start with fixed-length enabled

* waver : fix spectrum display for fixed-length mode

* waver : add option to control input sample rate offset

* ggwave : improve fixed-length decoding

* examples-common : SDL now captures 1024 samples instead of 4096

* waver : spectrum improvements + spectrogram mode

* minor changes

* ggwave : add FFT static method

* waver : realtime spectrum display

* waver : fix dragging behavior

* waver : show current tx protocol in "Messages"

* waver : show frequency range and bandwidth of selected protocol

* waver : change sample rate offset function

output instead of input

* waver : add info about local peers

* waver : add option to pause spectrum by clicking it

* waver : minor

* waver : add option descriptions

* waver : fix data races

* waver : purple-ish background

* waver : cian-ish background

* waver : add option button to cancel receiving

* waver : add option to select Rx Protocols

* waver : change default protocol

* waver : fix displayed protocol for each message
This commit is contained in:
Georgi Gerganov
2021-02-27 11:45:01 +02:00
committed by GitHub
parent 553b414929
commit 5b5293d764
6 changed files with 693 additions and 204 deletions

View File

@@ -153,7 +153,7 @@ int reverse(int N, int n) {
}
void ordina(float * f1, int N) {
float f2[2*GGWave::kMaxSamplesPerFrame];
static thread_local float f2[2*GGWave::kMaxSamplesPerFrame];
for (int i = 0; i < N; i++) {
int ir = reverse(N, i);
f2[2*i + 0] = f1[2*ir + 0];
@@ -210,7 +210,7 @@ void FFT(float * f, int N, float d) {
}
}
void FFT(float * src, float * dst, int N, float d) {
void FFT(const float * src, float * dst, int N, float d) {
for (int i = 0; i < N; ++i) {
dst[2*i + 0] = src[i];
dst[2*i + 1] = 0.0f;
@@ -309,6 +309,7 @@ GGWave::GGWave(const Parameters & parameters) :
m_fftInp(kMaxSamplesPerFrame),
m_fftOut(2*kMaxSamplesPerFrame),
m_hasNewSpectrum(false),
m_hasNewAmplitude(false),
m_sampleSpectrum(kMaxSamplesPerFrame),
m_sampleAmplitude(kMaxSamplesPerFrame + 128), // small extra space because sometimes resampling needs a few more samples
m_sampleAmplitudeResampled(8*kMaxSamplesPerFrame), // min input sampling rate is 0.125*kBaseSampleRate
@@ -798,6 +799,8 @@ void GGWave::decode(const CBWaveformInp & cbWaveformInp) {
// we have enough bytes to do analysis
if (nSamplesRecorded >= m_samplesPerFrame) {
m_hasNewAmplitude = true;
if (m_isFixedPayloadLength) {
decode_fixed();
} else {
@@ -817,6 +820,24 @@ void GGWave::decode(const CBWaveformInp & cbWaveformInp) {
}
}
bool GGWave::takeTxAmplitudeI16(AmplitudeDataI16 & dst) {
if (m_txAmplitudeDataI16.size() == 0) return false;
dst = std::move(m_txAmplitudeDataI16);
return true;
}
bool GGWave::stopReceiving() {
if (m_receivingData == false) {
return false;
}
m_receivingData = false;
return true;
}
int GGWave::takeRxData(TxRxData & dst) {
if (m_lastRxDataLength == 0) return 0;
@@ -830,16 +851,7 @@ int GGWave::takeRxData(TxRxData & dst) {
return res;
}
int GGWave::takeTxAmplitudeDataI16(AmplitudeDataI16 & dst) {
if (m_txAmplitudeDataI16.size() == 0) return 0;
int res = (int) m_txAmplitudeDataI16.size();
dst = std::move(m_txAmplitudeDataI16);
return res;
}
bool GGWave::takeSpectrum(SpectrumData & dst) {
bool GGWave::takeRxSpectrum(SpectrumData & dst) {
if (m_hasNewSpectrum == false) return false;
m_hasNewSpectrum = false;
@@ -848,6 +860,26 @@ bool GGWave::takeSpectrum(SpectrumData & dst) {
return true;
}
bool GGWave::takeRxAmplitude(AmplitudeData & dst) {
if (m_hasNewAmplitude == false) return false;
m_hasNewAmplitude = false;
dst = m_sampleAmplitude;
return true;
}
bool GGWave::computeFFTR(const float * src, float * dst, int N, float d) {
if (N > kMaxSamplesPerFrame) {
fprintf(stderr, "computeFFTR: N (%d) must be <= %d\n", N, GGWave::kMaxSamplesPerFrame);
return false;
}
FFT(src, dst, N, d);
return true;
}
//
// Variable payload length
//
@@ -875,9 +907,7 @@ void GGWave::decode_variable() {
}
// calculate spectrum
std::copy(m_sampleAmplitudeAverage.begin(), m_sampleAmplitudeAverage.begin() + m_samplesPerFrame, m_fftInp.data());
FFT(m_fftInp.data(), m_fftOut.data(), m_samplesPerFrame, 1.0);
FFT(m_sampleAmplitudeAverage.data(), m_fftOut.data(), m_samplesPerFrame, 1.0);
for (int i = 0; i < m_samplesPerFrame; ++i) {
m_sampleSpectrum[i] = (m_fftOut[2*i + 0]*m_fftOut[2*i + 0] + m_fftOut[2*i + 1]*m_fftOut[2*i + 1]);
@@ -1144,10 +1174,10 @@ void GGWave::decode_variable() {
// Fixed payload length
void GGWave::decode_fixed() {
// calculate spectrum
std::copy(m_sampleAmplitude.begin(), m_sampleAmplitude.begin() + m_samplesPerFrame, m_fftInp.data());
m_hasNewSpectrum = true;
FFT(m_fftInp.data(), m_fftOut.data(), m_samplesPerFrame, 1.0);
// calculate spectrum
FFT(m_sampleAmplitude.data(), m_fftOut.data(), m_samplesPerFrame, 1.0);
for (int i = 0; i < m_samplesPerFrame; ++i) {
m_sampleSpectrum[i] = (m_fftOut[2*i + 0]*m_fftOut[2*i + 0] + m_fftOut[2*i + 1]*m_fftOut[2*i + 1]);
@@ -1188,6 +1218,8 @@ void GGWave::decode_fixed() {
std::vector<ToneData> tones(nTones);
bool detectedSignal = true;
int txDetectedTotal = 0;
int txNeededTotal = 0;
for (int k = 0; k < totalTxs; ++k) {
for (auto & tone : tones) {
std::fill(tone.nMax, tone.nMax + 16, 0);
@@ -1231,7 +1263,7 @@ void GGWave::decode_fixed() {
}
}
int detectedTx = 0;
int txDetected = 0;
int txNeeded = 0;
for (int j = 0; j < rxProtocol.bytesPerTx; ++j) {
if (k*rxProtocol.bytesPerTx + j >= totalLength) break;
@@ -1239,18 +1271,25 @@ void GGWave::decode_fixed() {
for (int b = 0; b < 16; ++b) {
if (tones[2*j + 0].nMax[b] > rxProtocol.framesPerTx/2) {
detectedBins[2*(k*rxProtocol.bytesPerTx + j) + 0] = b;
detectedTx++;
txDetected++;
}
if (tones[2*j + 1].nMax[b] > rxProtocol.framesPerTx/2) {
detectedBins[2*(k*rxProtocol.bytesPerTx + j) + 1] = b;
detectedTx++;
txDetected++;
}
}
}
if (detectedTx < txNeeded) {
detectedSignal = false;
}
txDetectedTotal += txDetected;
txNeededTotal += txNeeded;
}
//if (rxProtocolId == GGWAVE_TX_PROTOCOL_DT_FAST) {
// printf("detected = %d, needed = %d\n", txDetectedTotal, txNeededTotal);
//}
if (txDetectedTotal < 0.75*txNeededTotal) {
detectedSignal = false;
}
if (detectedSignal) {