mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-08-03 22:42:27 -04:00
FT8 demod: make FT8::FFTEngine a singleton. Name worker threads for debugging
This commit is contained in:
parent
6c15a0ffd2
commit
2b5078e000
11
ft8/fft.cpp
11
ft8/fft.cpp
@ -28,6 +28,17 @@
|
|||||||
|
|
||||||
namespace FT8 {
|
namespace FT8 {
|
||||||
|
|
||||||
|
FFTEngine* FFTEngine::m_instance= nullptr;;
|
||||||
|
|
||||||
|
FFTEngine *FFTEngine::GetInstance()
|
||||||
|
{
|
||||||
|
if (!m_instance) {
|
||||||
|
m_instance = new FFTEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
FFTEngine::Plan *FFTEngine::get_plan(int n, const char *why)
|
FFTEngine::Plan *FFTEngine::get_plan(int n, const char *why)
|
||||||
{
|
{
|
||||||
// cache fftw plans in the parent process,
|
// cache fftw plans in the parent process,
|
||||||
|
11
ft8/fft.h
11
ft8/fft.h
@ -67,8 +67,9 @@ public:
|
|||||||
int uses_;
|
int uses_;
|
||||||
}; // Plan
|
}; // Plan
|
||||||
|
|
||||||
FFTEngine() : m_nplans(0)
|
FFTEngine(FFTEngine& other) = delete;
|
||||||
{}
|
void operator=(const FFTEngine &) = delete;
|
||||||
|
static FFTEngine *GetInstance();
|
||||||
|
|
||||||
Plan *get_plan(int n, const char *why);
|
Plan *get_plan(int n, const char *why);
|
||||||
|
|
||||||
@ -82,6 +83,12 @@ public:
|
|||||||
std::vector<std::complex<float>> analytic(const std::vector<float> &x, const char *why);
|
std::vector<std::complex<float>> analytic(const std::vector<float> &x, const char *why);
|
||||||
std::vector<float> hilbert_shift(const std::vector<float> &x, float hz0, float hz1, int rate);
|
std::vector<float> hilbert_shift(const std::vector<float> &x, float hz0, float hz1, int rate);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FFTEngine() :
|
||||||
|
m_nplans(0)
|
||||||
|
{}
|
||||||
|
static FFTEngine *m_instance;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fft_stats();
|
void fft_stats();
|
||||||
QMutex m_plansmu;
|
QMutex m_plansmu;
|
||||||
|
@ -3533,13 +3533,14 @@ void FT8Decoder::entry(
|
|||||||
final_deadline,
|
final_deadline,
|
||||||
cb,
|
cb,
|
||||||
prevdecs,
|
prevdecs,
|
||||||
&fftEngine
|
FFTEngine::GetInstance()
|
||||||
);
|
);
|
||||||
ft8->getParams() = getParams(); // transfer parameters
|
ft8->getParams() = getParams(); // transfer parameters
|
||||||
|
|
||||||
int npasses = nprevdecs > 0 ? params.npasses_two : params.npasses_one;
|
int npasses = nprevdecs > 0 ? params.npasses_two : params.npasses_one;
|
||||||
ft8->set_npasses(npasses);
|
ft8->set_npasses(npasses);
|
||||||
QThread *th = new QThread();
|
QThread *th = new QThread();
|
||||||
|
th->setObjectName(tr("ft8:%1:%2").arg(cb->get_name()).arg(i));
|
||||||
threads.push_back(th);
|
threads.push_back(th);
|
||||||
// std::thread *th = new std::thread([ft8, npasses] () { ft8->go(npasses); });
|
// std::thread *th = new std::thread([ft8, npasses] () { ft8->go(npasses); });
|
||||||
// thv.push_back(std::pair<FT8*, std::thread*>(ft8, th));
|
// thv.push_back(std::pair<FT8*, std::thread*>(ft8, th));
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include "fft.h"
|
#include "fft.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
int pass,
|
int pass,
|
||||||
int correct_bits
|
int correct_bits
|
||||||
) = 0; //!< virtual nathod called each time there is a result
|
) = 0; //!< virtual nathod called each time there is a result
|
||||||
|
virtual QString get_name() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -684,7 +686,6 @@ public:
|
|||||||
void forceQuit(); //!< force quit all threads
|
void forceQuit(); //!< force quit all threads
|
||||||
FT8Params& getParams() { return params; }
|
FT8Params& getParams() { return params; }
|
||||||
private:
|
private:
|
||||||
FFTEngine fftEngine;
|
|
||||||
FT8Params params;
|
FT8Params params;
|
||||||
std::vector<QThread*> threads;
|
std::vector<QThread*> threads;
|
||||||
}; // FT8Decoder
|
}; // FT8Decoder
|
||||||
|
@ -214,6 +214,7 @@ void FT8DemodGUI::on_filterIndex_valueChanged(int value)
|
|||||||
void FT8DemodGUI::on_clearMessages_clicked()
|
void FT8DemodGUI::on_clearMessages_clicked()
|
||||||
{
|
{
|
||||||
ui->messages->setRowCount(0);
|
ui->messages->setRowCount(0);
|
||||||
|
ui->nbDecodesInTable->setText("0");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FT8DemodGUI::on_recordWav_toggled(bool checked)
|
void FT8DemodGUI::on_recordWav_toggled(bool checked)
|
||||||
@ -621,7 +622,7 @@ void FT8DemodGUI::resizeMessageTable()
|
|||||||
ui->messages->setItem(row, MESSAGE_COL_DEC, new QTableWidgetItem("174"));
|
ui->messages->setItem(row, MESSAGE_COL_DEC, new QTableWidgetItem("174"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_DT, new QTableWidgetItem("-0.0"));
|
ui->messages->setItem(row, MESSAGE_COL_DT, new QTableWidgetItem("-0.0"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_DF, new QTableWidgetItem("0000"));
|
ui->messages->setItem(row, MESSAGE_COL_DF, new QTableWidgetItem("0000"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_CALL1, new QTableWidgetItem("123456789ABCD"));
|
ui->messages->setItem(row, MESSAGE_COL_CALL1, new QTableWidgetItem("CQ PA900RAALTE"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_CALL2, new QTableWidgetItem("PA900RAALTE"));
|
ui->messages->setItem(row, MESSAGE_COL_CALL2, new QTableWidgetItem("PA900RAALTE"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_LOC, new QTableWidgetItem("JN000"));
|
ui->messages->setItem(row, MESSAGE_COL_LOC, new QTableWidgetItem("JN000"));
|
||||||
ui->messages->setItem(row, MESSAGE_COL_INFO, new QTableWidgetItem("OSD-0-73"));
|
ui->messages->setItem(row, MESSAGE_COL_INFO, new QTableWidgetItem("OSD-0-73"));
|
||||||
@ -680,6 +681,8 @@ void FT8DemodGUI::messagesReceived(const QList<FT8Message>& messages)
|
|||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui->nbDecodesInTable->setText(tr("%1").arg(row));
|
||||||
|
|
||||||
if (scrollToBottom) {
|
if (scrollToBottom) {
|
||||||
ui->messages->scrollToBottom();
|
ui->messages->scrollToBottom();
|
||||||
}
|
}
|
||||||
|
@ -886,11 +886,43 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="nbDecodesText">
|
<widget class="QLabel" name="nbDecodesText">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>15</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Number of messages decoded in the last sequence</string>
|
<string>Number of messages decoded in the last sequence</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>00</string>
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>/</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="nbDecodesInTable">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>45</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -977,6 +1009,9 @@
|
|||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
</property>
|
</property>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
<attribute name="verticalHeaderMinimumSectionSize">
|
<attribute name="verticalHeaderMinimumSectionSize">
|
||||||
<number>15</number>
|
<number>15</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
@ -45,7 +45,7 @@ void FT8DemodSettings::resetToDefaults()
|
|||||||
m_agc = false;
|
m_agc = false;
|
||||||
m_recordWav = false;
|
m_recordWav = false;
|
||||||
m_logMessages = false;
|
m_logMessages = false;
|
||||||
m_nbDecoderThreads = 6;
|
m_nbDecoderThreads = 3;
|
||||||
m_decoderTimeBudget = 0.5;
|
m_decoderTimeBudget = 0.5;
|
||||||
m_volume = 1.0;
|
m_volume = 1.0;
|
||||||
m_inputFrequencyOffset = 0;
|
m_inputFrequencyOffset = 0;
|
||||||
@ -136,7 +136,7 @@ bool FT8DemodSettings::deserialize(const QByteArray& data)
|
|||||||
d.readU32(5, &m_rgbColor);
|
d.readU32(5, &m_rgbColor);
|
||||||
d.readBool(6, &m_recordWav, false);
|
d.readBool(6, &m_recordWav, false);
|
||||||
d.readBool(7, &m_logMessages, false);
|
d.readBool(7, &m_logMessages, false);
|
||||||
d.readS32(8, &m_nbDecoderThreads, 6);
|
d.readS32(8, &m_nbDecoderThreads, 3);
|
||||||
d.readFloat(9, &m_decoderTimeBudget, 0.5);
|
d.readFloat(9, &m_decoderTimeBudget, 0.5);
|
||||||
d.readBool(11, &m_agc, false);
|
d.readBool(11, &m_agc, false);
|
||||||
d.readString(16, &m_title, "SSB Demodulator");
|
d.readString(16, &m_title, "SSB Demodulator");
|
||||||
|
@ -27,10 +27,16 @@
|
|||||||
#include "ft8demodsettings.h"
|
#include "ft8demodsettings.h"
|
||||||
#include "ft8demodworker.h"
|
#include "ft8demodworker.h"
|
||||||
|
|
||||||
FT8DemodWorker::FT8Callback::FT8Callback(const QDateTime& periodTS, qint64 baseFrequency, FT8::Packing& packing) :
|
FT8DemodWorker::FT8Callback::FT8Callback(
|
||||||
|
const QDateTime& periodTS,
|
||||||
|
qint64 baseFrequency,
|
||||||
|
FT8::Packing& packing,
|
||||||
|
const QString& name
|
||||||
|
) :
|
||||||
m_packing(packing),
|
m_packing(packing),
|
||||||
m_periodTS(periodTS),
|
m_periodTS(periodTS),
|
||||||
m_baseFrequency(baseFrequency)
|
m_baseFrequency(baseFrequency),
|
||||||
|
m_name(name)
|
||||||
{
|
{
|
||||||
m_msgReportFT8Messages = MsgReportFT8Messages::create();
|
m_msgReportFT8Messages = MsgReportFT8Messages::create();
|
||||||
m_msgReportFT8Messages->setBaseFrequency(baseFrequency);
|
m_msgReportFT8Messages->setBaseFrequency(baseFrequency);
|
||||||
@ -92,6 +98,11 @@ int FT8DemodWorker::FT8Callback::hcb(
|
|||||||
return 2; // 2 => new decode, do subtract.
|
return 2; // 2 => new decode, do subtract.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FT8DemodWorker::FT8Callback::get_name()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
FT8DemodWorker::FT8DemodWorker() :
|
FT8DemodWorker::FT8DemodWorker() :
|
||||||
m_recordSamples(false),
|
m_recordSamples(false),
|
||||||
m_nbDecoderThreads(6),
|
m_nbDecoderThreads(6),
|
||||||
@ -108,7 +119,7 @@ FT8DemodWorker::FT8DemodWorker() :
|
|||||||
dir.mkpath(relPath);
|
dir.mkpath(relPath);
|
||||||
m_samplesPath = dir.absolutePath() + "/" + relPath;
|
m_samplesPath = dir.absolutePath() + "/" + relPath;
|
||||||
qDebug("FT8DemodWorker::FT8DemodWorker: samples path: %s", qPrintable(m_samplesPath));
|
qDebug("FT8DemodWorker::FT8DemodWorker: samples path: %s", qPrintable(m_samplesPath));
|
||||||
relPath = "sdrangel/ft8";
|
relPath = "sdrangel/ft8/logs";
|
||||||
m_logsPath = dir.absolutePath() + "/" + relPath;
|
m_logsPath = dir.absolutePath() + "/" + relPath;
|
||||||
qDebug("FT8DemodWorker::FT8DemodWorker: logs path: %s", qPrintable(m_logsPath));
|
qDebug("FT8DemodWorker::FT8DemodWorker: logs path: %s", qPrintable(m_logsPath));
|
||||||
}
|
}
|
||||||
@ -134,8 +145,14 @@ void FT8DemodWorker::processBuffer(int16_t *buffer, QDateTime periodTS)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString channelReference = "d0c0"; // default
|
||||||
|
|
||||||
|
if (m_channel) {
|
||||||
|
channelReference = tr("d%1c%2").arg(m_channel->getDeviceSetIndex()).arg(m_channel->getIndexInDeviceSet());
|
||||||
|
}
|
||||||
|
|
||||||
int hints[2] = { 2, 0 }; // CQ
|
int hints[2] = { 2, 0 }; // CQ
|
||||||
FT8Callback ft8Callback(periodTS, m_baseFrequency, m_packing);
|
FT8Callback ft8Callback(periodTS, m_baseFrequency, m_packing, channelReference);
|
||||||
m_ft8Decoder.getParams().nthreads = m_nbDecoderThreads;
|
m_ft8Decoder.getParams().nthreads = m_nbDecoderThreads;
|
||||||
std::vector<float> samples(15*FT8DemodSettings::m_ft8SampleRate);
|
std::vector<float> samples(15*FT8DemodSettings::m_ft8SampleRate);
|
||||||
|
|
||||||
@ -180,12 +197,6 @@ void FT8DemodWorker::processBuffer(int16_t *buffer, QDateTime periodTS)
|
|||||||
{
|
{
|
||||||
if (!logFile.is_open())
|
if (!logFile.is_open())
|
||||||
{
|
{
|
||||||
QString channelReference = "d0c0"; // default
|
|
||||||
|
|
||||||
if (m_channel) {
|
|
||||||
channelReference = tr("d%1c%2").arg(m_channel->getDeviceSetIndex()).arg(m_channel->getIndexInDeviceSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString logFileName(tr("%1_%2.txt").arg(periodTS.toString("yyyyMMdd")).arg(channelReference));
|
QString logFileName(tr("%1_%2.txt").arg(periodTS.toString("yyyyMMdd")).arg(channelReference));
|
||||||
QFileInfo lfi(QDir(m_logsPath), logFileName);
|
QFileInfo lfi(QDir(m_logsPath), logFileName);
|
||||||
QString logFilePath = lfi.absoluteFilePath();
|
QString logFilePath = lfi.absoluteFilePath();
|
||||||
|
@ -51,7 +51,12 @@ private:
|
|||||||
class FT8Callback : public FT8::CallbackInterface
|
class FT8Callback : public FT8::CallbackInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FT8Callback(const QDateTime& periodTS, qint64 baseFrequency, FT8::Packing& packing);
|
FT8Callback
|
||||||
|
(const QDateTime& periodTS,
|
||||||
|
qint64 baseFrequency,
|
||||||
|
FT8::Packing& packing,
|
||||||
|
const QString& name
|
||||||
|
);
|
||||||
virtual int hcb(
|
virtual int hcb(
|
||||||
int *a91,
|
int *a91,
|
||||||
float hz0,
|
float hz0,
|
||||||
@ -61,6 +66,7 @@ private:
|
|||||||
int pass,
|
int pass,
|
||||||
int correct_bits
|
int correct_bits
|
||||||
);
|
);
|
||||||
|
virtual QString get_name();
|
||||||
const std::map<std::string, bool>& getMsgMap() { return cycle_already; }
|
const std::map<std::string, bool>& getMsgMap() { return cycle_already; }
|
||||||
MsgReportFT8Messages *getReportMessage() { return m_msgReportFT8Messages; }
|
MsgReportFT8Messages *getReportMessage() { return m_msgReportFT8Messages; }
|
||||||
|
|
||||||
@ -71,6 +77,7 @@ private:
|
|||||||
MsgReportFT8Messages *m_msgReportFT8Messages;
|
MsgReportFT8Messages *m_msgReportFT8Messages;
|
||||||
const QDateTime& m_periodTS;
|
const QDateTime& m_periodTS;
|
||||||
qint64 m_baseFrequency;
|
qint64 m_baseFrequency;
|
||||||
|
QString m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString m_samplesPath;
|
QString m_samplesPath;
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
int pass,
|
int pass,
|
||||||
int correct_bits
|
int correct_bits
|
||||||
);
|
);
|
||||||
|
virtual QString get_name();
|
||||||
const std::map<std::string, bool>& getMsgMap() {
|
const std::map<std::string, bool>& getMsgMap() {
|
||||||
return cycle_already;
|
return cycle_already;
|
||||||
}
|
}
|
||||||
@ -102,6 +103,11 @@ int TestFT8Callback::hcb(
|
|||||||
return 2; // 2 => new decode, do subtract.
|
return 2; // 2 => new decode, do subtract.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TestFT8Callback::get_name()
|
||||||
|
{
|
||||||
|
return "test";
|
||||||
|
}
|
||||||
|
|
||||||
void MainBench::testFT8(const QString& wavFile, const QString& argsStr)
|
void MainBench::testFT8(const QString& wavFile, const QString& argsStr)
|
||||||
{
|
{
|
||||||
int nthreads = 8; // number of threads (default)
|
int nthreads = 8; // number of threads (default)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user