mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-04-04 06:05:40 -04:00
FT8 demod: more code linting
This commit is contained in:
parent
c32aa8001a
commit
e98b4bdeb1
62
ft8/ft4.cpp
62
ft8/ft4.cpp
@ -1,13 +1,29 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 //
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// Experimental FT4 decoder scaffold derived from FT8 decoder architecture. //
|
||||
// This is the code from ft8mon: https://github.com/rtmrtmrtmrtm/ft8mon //
|
||||
// reformatted and adapted to Qt and SDRangel context and FT4 scheme //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <functional>
|
||||
#include <cstdio>
|
||||
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
@ -241,7 +257,7 @@ int FT4::blocksize(float rate) const
|
||||
// look for potential psignals by searching FFT bins for Costas symbol
|
||||
// blocks. returns a vector of candidate positions.
|
||||
//
|
||||
std::vector<Strength> FT4::coarse(const FFTEngine::ffts_t &bins, int si0, int si1)
|
||||
std::vector<Strength> FT4::coarse(const FFTEngine::ffts_t &bins, int si0, int si1) const
|
||||
{
|
||||
int block = blocksize(rate_);
|
||||
int nbins = bins[0].size();
|
||||
@ -420,13 +436,11 @@ void FT4::go(int npasses)
|
||||
int irate = round(rate_);
|
||||
for (int xrate = 100; xrate < rate_; xrate += 100)
|
||||
{
|
||||
if (xrate < rate_ && (params.oddrate || (irate % xrate) == 0))
|
||||
if (xrate < rate_ && (params.oddrate || (irate % xrate) == 0) &&
|
||||
((max_hz_ - min_hz_) + 93.6 + 2 * params.go_extra) < params.nyquist * (xrate / 2))
|
||||
{
|
||||
if (((max_hz_ - min_hz_) + 93.6 + 2 * params.go_extra) < params.nyquist * (xrate / 2))
|
||||
{
|
||||
nrate = xrate;
|
||||
break;
|
||||
}
|
||||
nrate = xrate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +473,7 @@ void FT4::go(int npasses)
|
||||
t1 - t0);
|
||||
}
|
||||
|
||||
if (0)
|
||||
if (false)
|
||||
{
|
||||
fprintf(stderr, "%.0f..%.0f, range %.0f, rate %.0f -> %d, delta hz %.0f, %.6f sec\n",
|
||||
min_hz_,
|
||||
@ -583,7 +597,7 @@ void FT4::go(int npasses)
|
||||
|
||||
// just do this once, reuse for every fractional fft_shift
|
||||
// and down_v7_f() to 200 sps.
|
||||
std::vector<std::complex<float>> bins = fftEngine_->one_fft(
|
||||
std::vector<std::complex<float>> fbins = fftEngine_->one_fft(
|
||||
samples_, 0, samples_.size());
|
||||
|
||||
for (int hz_frac_i = 0; hz_frac_i < params.coarse_hz_n; hz_frac_i++)
|
||||
@ -595,7 +609,7 @@ void FT4::go(int npasses)
|
||||
if (hz_frac_i == 0) {
|
||||
samples1 = samples_;
|
||||
} else {
|
||||
samples1 = fft_shift_f(bins, rate_, hz_frac);
|
||||
samples1 = fft_shift_f(fbins, rate_, hz_frac);
|
||||
}
|
||||
|
||||
for (int off_frac_i = 0; off_frac_i < params.coarse_off_n; off_frac_i++)
|
||||
@ -650,7 +664,7 @@ void FT4::go(int npasses)
|
||||
}
|
||||
|
||||
int off = order[ii].off_;
|
||||
int ret = one_merge(bins, samples_.size(), hz, off);
|
||||
int ret = one_merge(fbins, samples_.size(), hz, off);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
@ -1963,9 +1977,9 @@ void FT4::soft_decode_pairs(
|
||||
// FT4 sync blocks are [0..3], [33..36], [66..69], [99..102].
|
||||
// Since we process pairs, sync pairs are start/start+1 and start+2/start+3.
|
||||
if (si == 0 || si == 33 || si == 66 || si == 99) {
|
||||
bests.add(corrs[kFT4SyncTones[(si / 33)][0] * 4 + kFT4SyncTones[(si / 33)][1]]);
|
||||
bests.add(corrs[kFT4SyncTones[si / 33][0] * 4 + kFT4SyncTones[si / 33][1]]);
|
||||
} else if (si == 2 || si == 35 || si == 68 || si == 101) {
|
||||
bests.add(corrs[kFT4SyncTones[((si - 2) / 33)][2] * 4 + kFT4SyncTones[((si - 2) / 33)][3]]);
|
||||
bests.add(corrs[kFT4SyncTones[(si - 2) / 33][2] * 4 + kFT4SyncTones[(si - 2) / 33][3]]);
|
||||
} else {
|
||||
bests.add(mx);
|
||||
}
|
||||
@ -2052,7 +2066,7 @@ void FT4::soft_decode_triples(
|
||||
{
|
||||
int bitind = (si + 0) * 2 + (1 - bit);
|
||||
|
||||
if ((i & (1 << bit)))
|
||||
if (i & (1 << bit))
|
||||
{
|
||||
// symbol i would make this bit a one.
|
||||
if (x > bitinfo[bitind].one) {
|
||||
@ -2077,7 +2091,7 @@ void FT4::soft_decode_triples(
|
||||
{
|
||||
int bitind = (si + 1) * 2 + (1 - bit);
|
||||
|
||||
if ((i & (1 << bit)))
|
||||
if (i & (1 << bit))
|
||||
{
|
||||
// symbol i would make this bit a one.
|
||||
if (x > bitinfo[bitind].one) {
|
||||
@ -2103,7 +2117,7 @@ void FT4::soft_decode_triples(
|
||||
{
|
||||
int bitind = (si + 2) * 2 + (1 - bit);
|
||||
|
||||
if ((i & (1 << bit)))
|
||||
if (i & (1 << bit))
|
||||
{
|
||||
// symbol i would make this bit a one.
|
||||
if (x > bitinfo[bitind].one) {
|
||||
@ -2174,7 +2188,7 @@ int FT4::decode(const float ll174[], int a174[], const FT8Params& _params, int u
|
||||
{
|
||||
int plain[174]; // will be 0/1 bits.
|
||||
int ldpc_ok = 0; // 83 will mean success.
|
||||
LDPC::ldpc_decode((float *)ll174, _params.ldpc_iters, plain, &ldpc_ok);
|
||||
LDPC::ldpc_decode(ll174, _params.ldpc_iters, plain, &ldpc_ok);
|
||||
int ok_thresh = 83; // 83 is perfect
|
||||
|
||||
if (ldpc_ok >= ok_thresh)
|
||||
@ -2200,7 +2214,7 @@ int FT4::decode(const float ll174[], int a174[], const FT8Params& _params, int u
|
||||
{
|
||||
int oplain[91];
|
||||
int got_depth = -1;
|
||||
int osd_ok = OSD::osd_decode((float *)ll174, _params.osd_depth, oplain, &got_depth);
|
||||
int osd_ok = OSD::osd_decode(ll174, _params.osd_depth, oplain, &got_depth);
|
||||
|
||||
if (osd_ok)
|
||||
{
|
||||
@ -3142,22 +3156,22 @@ void FT4::subtract(
|
||||
|
||||
// at start of this symbol's off-ramp.
|
||||
float theta = phase + (block - ramp) * dtheta;
|
||||
float hz1;
|
||||
float hz1_;
|
||||
float phase1;
|
||||
|
||||
if (si + 1 >= 103)
|
||||
{
|
||||
hz1 = hz;
|
||||
hz1_ = hz;
|
||||
phase1 = phase;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sym1 = bin0 + re103[si + 1];
|
||||
hz1 = sym1 * bin_hz;
|
||||
hz1_ = sym1 * bin_hz;
|
||||
phase1 = phases[si + 1];
|
||||
}
|
||||
|
||||
float dtheta1 = 2 * M_PI / (rate_ / hz1);
|
||||
float dtheta1 = 2 * M_PI / (rate_ / hz1_);
|
||||
// add this to dtheta for each sample, to gradually
|
||||
// change the frequency.
|
||||
float inc = (dtheta1 - dtheta) / (2.0 * ramp);
|
||||
|
||||
21
ft8/ft4.h
21
ft8/ft4.h
@ -1,8 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 //
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// Experimental FT4 decoder scaffold derived from FT8 decoder architecture. //
|
||||
// This is the code from ft8mon: https://github.com/rtmrtmrtmrtm/ft8mon //
|
||||
// reformatted and adapted to Qt and SDRangel context and FT4 scheme //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ft4_h
|
||||
#define ft4_h
|
||||
|
||||
@ -67,7 +82,7 @@ public:
|
||||
// look for potential signals by searching FFT bins for Costas symbol
|
||||
// blocks. returns a vector of candidate positions.
|
||||
//
|
||||
std::vector<Strength> coarse(const FFTEngine::ffts_t &bins, int si0, int si1);
|
||||
std::vector<Strength> coarse(const FFTEngine::ffts_t &bins, int si0, int si1) const;
|
||||
|
||||
FT8Params& getParams() { return params; }
|
||||
//
|
||||
|
||||
14
ft8/ft8.cpp
14
ft8/ft8.cpp
@ -238,7 +238,7 @@ int FT8::blocksize(int rate) const
|
||||
// look for potential psignals by searching FFT bins for Costas symbol
|
||||
// blocks. returns a vector of candidate positions.
|
||||
//
|
||||
std::vector<Strength> FT8::coarse(const FFTEngine::ffts_t &bins, int si0, int si1)
|
||||
std::vector<Strength> FT8::coarse(const FFTEngine::ffts_t &bins, int si0, int si1) const
|
||||
{
|
||||
int block = blocksize(rate_);
|
||||
int nbins = bins[0].size();
|
||||
@ -386,7 +386,7 @@ std::vector<float> FT8::reduce_rate(
|
||||
|
||||
void FT8::go(int npasses)
|
||||
{
|
||||
if (0)
|
||||
if (false)
|
||||
{
|
||||
fprintf(stderr, "go: %.0f .. %.0f, %.0f, rate=%d\n",
|
||||
min_hz_, max_hz_, max_hz_ - min_hz_, rate_);
|
||||
@ -1849,7 +1849,7 @@ void FT8::soft_decode(const FFTEngine::ffts_t &c79, float ll174[]) const
|
||||
// ll174 is the resulting 174 soft bits of payload
|
||||
// used in FT-chirp modulation scheme - generalized to any number of symbol bits
|
||||
//
|
||||
void FT8::soft_decode_mags(FT8Params& params, const std::vector<std::vector<float>>& mags_, int nbSymbolBits, float ll174[])
|
||||
void FT8::soft_decode_mags(const FT8Params& params, const std::vector<std::vector<float>>& mags_, int nbSymbolBits, float ll174[])
|
||||
{
|
||||
if ((nbSymbolBits > 16) || (nbSymbolBits < 1)) {
|
||||
return;
|
||||
@ -2166,7 +2166,7 @@ void FT8::set_ones_zeroes(int ones[], int zeroes[], int nbBits, int bitIndex)
|
||||
// each returned element is < 0 for 1, > 0 for zero,
|
||||
// scaled by str.
|
||||
//
|
||||
std::vector<float> FT8::extract_bits(const std::vector<int> &syms, const std::vector<float> str) const
|
||||
std::vector<float> FT8::extract_bits(const std::vector<int> &syms, const std::vector<float>& str) const
|
||||
{
|
||||
// assert(syms.size() == 79);
|
||||
// assert(str.size() == 79);
|
||||
@ -3566,7 +3566,7 @@ int FT8::try_decode(
|
||||
// used to help ensure that subtraction subtracts
|
||||
// at the right place.
|
||||
//
|
||||
std::vector<int> FT8::recode(int a174[]) const
|
||||
std::vector<int> FT8::recode(const int a174[]) const
|
||||
{
|
||||
int i174 = 0;
|
||||
int costas[] = {3, 1, 4, 0, 6, 5, 2};
|
||||
@ -3620,8 +3620,8 @@ void FT8Decoder::entry(
|
||||
int rate,
|
||||
float min_hz,
|
||||
float max_hz,
|
||||
int hints1[],
|
||||
int hints2[],
|
||||
const int hints1[],
|
||||
const int hints2[],
|
||||
double time_left,
|
||||
double total_time_left,
|
||||
CallbackInterface *cb,
|
||||
|
||||
12
ft8/ft8.h
12
ft8/ft8.h
@ -266,7 +266,7 @@ public:
|
||||
// look for potential signals by searching FFT bins for Costas symbol
|
||||
// blocks. returns a vector of candidate positions.
|
||||
//
|
||||
std::vector<Strength> coarse(const FFTEngine::ffts_t &bins, int si0, int si1);
|
||||
std::vector<Strength> coarse(const FFTEngine::ffts_t &bins, int si0, int si1) const;
|
||||
|
||||
FT8Params& getParams() { return params; }
|
||||
//
|
||||
@ -290,7 +290,7 @@ public:
|
||||
// ll174 is the resulting 174 soft bits of payload
|
||||
// used in FT-chirp modulation scheme - generalized to any number of symbol bits
|
||||
//
|
||||
static void soft_decode_mags(FT8Params& params, const std::vector<std::vector<float>>& mags, int nbSymbolBits, float ll174[]);
|
||||
static void soft_decode_mags(const FT8Params& params, const std::vector<std::vector<float>>& mags, int nbSymbolBits, float ll174[]);
|
||||
|
||||
//
|
||||
// Generic Gray decoding for magnitudes (floats)
|
||||
@ -497,7 +497,7 @@ private:
|
||||
// each returned element is < 0 for 1, > 0 for zero,
|
||||
// scaled by str.
|
||||
//
|
||||
std::vector<float> extract_bits(const std::vector<int> &syms, const std::vector<float> str) const;
|
||||
std::vector<float> extract_bits(const std::vector<int> &syms, const std::vector<float>& str) const;
|
||||
// decode successive pairs of symbols. exploits the likelihood
|
||||
// that they have the same phase, by summing the complex
|
||||
// correlations for each possible pair and using the max.
|
||||
@ -615,7 +615,7 @@ private:
|
||||
// used to help ensure that subtraction subtracts
|
||||
// at the right place.
|
||||
//
|
||||
std::vector<int> recode(int a174[]) const;
|
||||
std::vector<int> recode(const int a174[]) const;
|
||||
//
|
||||
// the signal is at roughly 25 hz in samples200.
|
||||
//
|
||||
@ -679,8 +679,8 @@ public:
|
||||
int rate,
|
||||
float min_hz,
|
||||
float max_hz,
|
||||
int hints1[],
|
||||
int hints2[],
|
||||
const int hints1[],
|
||||
const int hints2[],
|
||||
double time_left,
|
||||
double total_time_left,
|
||||
CallbackInterface *cb,
|
||||
|
||||
@ -76,7 +76,7 @@ int LDPC::ldpc_check(int codeword[])
|
||||
// iters is how hard to try.
|
||||
// ok is the number of parity checks that worked out,
|
||||
// ok == 83 means success.
|
||||
void LDPC::ldpc_decode(float llcodeword[], int iters, int plain[], int *ok)
|
||||
void LDPC::ldpc_decode(const float llcodeword[], int iters, int plain[], int *ok)
|
||||
{
|
||||
REAL m[83][174];
|
||||
REAL e[83][174];
|
||||
|
||||
@ -26,7 +26,7 @@ namespace FT8 {
|
||||
|
||||
class LDPC {
|
||||
public:
|
||||
static void ldpc_decode(float llcodeword[], int iters, int plain[], int *ok);
|
||||
static void ldpc_decode(const float llcodeword[], int iters, int plain[], int *ok);
|
||||
static void ldpc_decode_log(float codeword[], int iters, int plain[], int *ok);
|
||||
static void ft8_crc(int msg1[], int msglen, int out[14]);
|
||||
static void gauss_jordan(int rows, int cols, int m[174][2 * 91], int which[91], int *ok);
|
||||
|
||||
@ -96,7 +96,7 @@ void OSD::ldpc_encode(int plain[91], int codeword[174])
|
||||
// ll174 is what was received.
|
||||
// ldpc-encode xplain; how close is the
|
||||
// result to what we received?
|
||||
float OSD::osd_score(int xplain[91], float ll174[174])
|
||||
float OSD::osd_score(int xplain[91], const float ll174[174])
|
||||
{
|
||||
int xcode[174];
|
||||
ldpc_encode(xplain, xcode);
|
||||
@ -163,7 +163,7 @@ void OSD::matmul(int a[91][91], int b[91], int c[91])
|
||||
// first 91 bits are plaintext, remaining 83 are parity.
|
||||
// returns 0 or 1, with decoded plain bits in out91[].
|
||||
// and actual depth used in *out_depth.
|
||||
int OSD::osd_decode(float codeword[174], int depth, int out[91], int *out_depth)
|
||||
int OSD::osd_decode(const float codeword[174], int depth, int out[91], int *out_depth)
|
||||
{
|
||||
// strength = abs(codeword)
|
||||
float strength[174];
|
||||
|
||||
@ -30,13 +30,12 @@ public:
|
||||
static const int gen_sys[174][91];
|
||||
static int check_crc(const int a91[91]);
|
||||
static void ldpc_encode(int plain[91], int codeword[174]);
|
||||
static float osd_score(int xplain[91], float ll174[174]);
|
||||
static float osd_score(int xplain[91], const float ll174[174]);
|
||||
static int osd_check(const int plain[91]);
|
||||
static void matmul(int a[91][91], int b[91], int c[91]);
|
||||
static int osd_decode(float codeword[174], int depth, int out[91], int *out_depth);
|
||||
static int osd_decode(const float codeword[174], int depth, int out[91], int *out_depth);
|
||||
};
|
||||
|
||||
} // namespace FT8
|
||||
|
||||
#endif // osd_h
|
||||
|
||||
|
||||
@ -330,16 +330,13 @@ void FT8DemodBaseband::tick()
|
||||
const qint64 periodIndex = nowMs / periodMs;
|
||||
const int periodOffsetMs = nowMs % periodMs;
|
||||
|
||||
if (periodOffsetMs < activeWindowMs)
|
||||
if (periodOffsetMs < activeWindowMs && m_lastProcessPeriodIndex != periodIndex)
|
||||
{
|
||||
if (m_lastProcessPeriodIndex != periodIndex)
|
||||
{
|
||||
const qint64 previousPeriodStartMs = (periodIndex - 1) * periodMs;
|
||||
QDateTime periodTs = QDateTime::fromMSecsSinceEpoch(previousPeriodStartMs, Qt::UTC);
|
||||
const int frameSamples = FT8DemodSettings::getDecoderFrameSamples(m_settings.m_decoderMode);
|
||||
m_ft8Buffer.getCurrentBuffer(m_ft8WorkerBuffer, frameSamples);
|
||||
emit bufferReady(m_ft8WorkerBuffer, periodTs);
|
||||
m_lastProcessPeriodIndex = periodIndex;
|
||||
}
|
||||
const qint64 previousPeriodStartMs = (periodIndex - 1) * periodMs;
|
||||
QDateTime periodTs = QDateTime::fromMSecsSinceEpoch(previousPeriodStartMs, Qt::UTC);
|
||||
const int frameSamples = FT8DemodSettings::getDecoderFrameSamples(m_settings.m_decoderMode);
|
||||
m_ft8Buffer.getCurrentBuffer(m_ft8WorkerBuffer, frameSamples);
|
||||
emit bufferReady(m_ft8WorkerBuffer, periodTs);
|
||||
m_lastProcessPeriodIndex = periodIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ void FT8DemodWorker::setDecoderMode(FT8DemodSettings::DecoderMode decoderMode)
|
||||
}
|
||||
|
||||
|
||||
void FT8DemodWorker::processFT8(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, int *hints)
|
||||
void FT8DemodWorker::processFT8(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, const int *hints)
|
||||
{
|
||||
m_ft8Decoder.getParams().nthreads = m_nbDecoderThreads;
|
||||
m_ft8Decoder.getParams().use_osd = m_useOSD ? 1 : 0;
|
||||
@ -218,7 +218,7 @@ void FT8DemodWorker::processFT8(int16_t *buffer, int frameSampleCount, FT8Callba
|
||||
m_ft8Decoder.wait(m_decoderTimeBudget + 1.0); // add one second to budget to force quit threads
|
||||
}
|
||||
|
||||
void FT8DemodWorker::processFT4(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, int *hints)
|
||||
void FT8DemodWorker::processFT4(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, const int *hints)
|
||||
{
|
||||
std::vector<float> samples(frameSampleCount);
|
||||
std::transform(
|
||||
|
||||
@ -94,8 +94,8 @@ private:
|
||||
const QSet<QString> *m_validCallsigns;
|
||||
};
|
||||
|
||||
void processFT8(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, int *hints);
|
||||
void processFT4(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, int *hints);
|
||||
void processFT8(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, const int *hints);
|
||||
void processFT4(int16_t *buffer, int frameSampleCount, FT8Callback& ft8Callback, const int *hints);
|
||||
|
||||
QString m_samplesPath;
|
||||
QString m_logsPath;
|
||||
|
||||
@ -18,6 +18,11 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
#include "mainbench.h"
|
||||
#include "dsp/wavfilerecord.h"
|
||||
@ -29,7 +34,7 @@ void MainBench::testFT4(const QString& wavFile, const QString& argsStr)
|
||||
{
|
||||
(void) wavFile;
|
||||
(void) argsStr;
|
||||
qWarning("MainBench::testFT8: this version has no FT8 support");
|
||||
qWarning("MainBench::testFT4: this version has no FT8/FT4 support");
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user