mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-04-25 08:53:59 -04:00
SigMF file sink: more GUI changes
This commit is contained in:
parent
80ea534840
commit
ed3a300829
@ -38,7 +38,6 @@
|
||||
#include "sigmffilesink.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(SigMFFileSink::MsgConfigureSigMFFileSink, Message)
|
||||
MESSAGE_CLASS_DEFINITION(SigMFFileSink::MsgBasebandSampleRateNotification, Message)
|
||||
|
||||
const QString SigMFFileSink::m_channelIdURI = "sdrangel.channel.sigmffilesink";
|
||||
const QString SigMFFileSink::m_channelId = "SigMFFileSink";
|
||||
@ -52,9 +51,8 @@ SigMFFileSink::SigMFFileSink(DeviceAPI *deviceAPI) :
|
||||
{
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_thread = new QThread(this);
|
||||
m_basebandSink = new SigMFFileSinkBaseband();
|
||||
m_basebandSink->moveToThread(m_thread);
|
||||
m_basebandSink->moveToThread(&m_thread);
|
||||
|
||||
applySettings(m_settings, true);
|
||||
|
||||
@ -71,8 +69,12 @@ SigMFFileSink::~SigMFFileSink()
|
||||
delete m_networkManager;
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
|
||||
if (m_basebandSink->isRunning()) {
|
||||
stop();
|
||||
}
|
||||
|
||||
delete m_basebandSink;
|
||||
delete m_thread;
|
||||
}
|
||||
|
||||
uint32_t SigMFFileSink::getNumberOfDeviceStreams() const
|
||||
@ -90,38 +92,43 @@ void SigMFFileSink::start()
|
||||
{
|
||||
qDebug("SigMFFileSink::start");
|
||||
m_basebandSink->reset();
|
||||
m_thread->start();
|
||||
m_basebandSink->startWork();
|
||||
m_thread.start();
|
||||
|
||||
DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency);
|
||||
m_basebandSink->getInputMessageQueue()->push(dspMsg);
|
||||
|
||||
SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkBaseband *msg = SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkBaseband::create(m_settings, true);
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
void SigMFFileSink::stop()
|
||||
{
|
||||
qDebug("SigMFFileSink::stop");
|
||||
m_thread->exit();
|
||||
m_thread->wait();
|
||||
m_basebandSink->stopWork();
|
||||
m_thread.exit();
|
||||
m_thread.wait();
|
||||
}
|
||||
|
||||
bool SigMFFileSink::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
DSPSignalNotification& cfg = (DSPSignalNotification&) cmd;
|
||||
|
||||
qDebug() << "SigMFFileSink::handleMessage: DSPSignalNotification:"
|
||||
<< " inputSampleRate: " << notif.getSampleRate()
|
||||
<< " centerFrequency: " << notif.getCenterFrequency();
|
||||
<< " inputSampleRate: " << cfg.getSampleRate()
|
||||
<< " centerFrequency: " << cfg.getCenterFrequency();
|
||||
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
m_centerFrequency = notif.getCenterFrequency();
|
||||
|
||||
calculateFrequencyOffset(m_settings.m_log2Decim, m_settings.m_filterChainHash); // This is when device sample rate changes
|
||||
|
||||
DSPSignalNotification *msg = new DSPSignalNotification(notif.getSampleRate(), notif.getCenterFrequency());
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
m_basebandSampleRate = cfg.getSampleRate();
|
||||
m_centerFrequency = cfg.getCenterFrequency();
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(cfg);
|
||||
m_basebandSink->getInputMessageQueue()->push(notif);
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgBasebandSampleRateNotification *msg = MsgBasebandSampleRateNotification::create(notif.getSampleRate());
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
DSPSignalNotification *notifToGUI = new DSPSignalNotification(cfg);
|
||||
getMessageQueueToGUI()->push(notifToGUI);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -214,22 +221,16 @@ DeviceSampleSource *SigMFFileSink::getLocalDevice(uint32_t index)
|
||||
void SigMFFileSink::applySettings(const SigMFFileSinkSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "SigMFFileSink::applySettings:"
|
||||
<< "force: " << force;
|
||||
<< "m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||
<< "m_log2Decim: " << settings.m_log2Decim
|
||||
<< "m_fileRecordName: " << settings.m_fileRecordName
|
||||
<< "force: " << force;
|
||||
|
||||
QList<QString> reverseAPIKeys;
|
||||
|
||||
if ((settings.m_log2Decim != m_settings.m_log2Decim) || force) {
|
||||
reverseAPIKeys.append("log2Decim");
|
||||
}
|
||||
if ((settings.m_filterChainHash != m_settings.m_filterChainHash) || force) {
|
||||
reverseAPIKeys.append("filterChainHash");
|
||||
}
|
||||
|
||||
if ((settings.m_log2Decim != m_settings.m_log2Decim)
|
||||
|| (settings.m_filterChainHash != m_settings.m_filterChainHash) || force)
|
||||
{
|
||||
calculateFrequencyOffset(settings.m_log2Decim, settings.m_filterChainHash);
|
||||
}
|
||||
} // TOOO: the rest
|
||||
|
||||
SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkBaseband *msg = SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkBaseband::create(settings, force);
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
@ -253,23 +254,6 @@ void SigMFFileSink::record(bool record)
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
void SigMFFileSink::validateFilterChainHash(SigMFFileSinkSettings& settings)
|
||||
{
|
||||
unsigned int s = 1;
|
||||
|
||||
for (unsigned int i = 0; i < settings.m_log2Decim; i++) {
|
||||
s *= 3;
|
||||
}
|
||||
|
||||
settings.m_filterChainHash = settings.m_filterChainHash >= s ? s-1 : settings.m_filterChainHash;
|
||||
}
|
||||
|
||||
void SigMFFileSink::calculateFrequencyOffset(uint32_t log2Decim, uint32_t filterChainHash)
|
||||
{
|
||||
double shiftFactor = HBFilterChainConverter::getShiftFactor(log2Decim, filterChainHash);
|
||||
m_frequencyOffset = m_basebandSampleRate * shiftFactor;
|
||||
}
|
||||
|
||||
int SigMFFileSink::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
@ -320,13 +304,6 @@ void SigMFFileSink::webapiUpdateChannelSettings(
|
||||
if (channelSettingsKeys.contains("log2Decim")) {
|
||||
settings.m_log2Decim = response.getLocalSinkSettings()->getLog2Decim();
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("filterChainHash"))
|
||||
{
|
||||
settings.m_filterChainHash = response.getLocalSinkSettings()->getFilterChainHash();
|
||||
validateFilterChainHash(settings);
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("useReverseAPI")) {
|
||||
settings.m_useReverseAPI = response.getLocalSinkSettings()->getUseReverseApi() != 0;
|
||||
}
|
||||
@ -355,7 +332,6 @@ void SigMFFileSink::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings&
|
||||
}
|
||||
|
||||
response.getLocalSinkSettings()->setLog2Decim(settings.m_log2Decim);
|
||||
response.getLocalSinkSettings()->setFilterChainHash(settings.m_filterChainHash);
|
||||
response.getLocalSinkSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
|
||||
|
||||
if (response.getLocalSinkSettings()->getReverseApiAddress()) {
|
||||
@ -390,9 +366,6 @@ void SigMFFileSink::webapiReverseSendSettings(QList<QString>& channelSettingsKey
|
||||
if (channelSettingsKeys.contains("log2Decim") || force) {
|
||||
swgLocalSinkSettings->setLog2Decim(settings.m_log2Decim);
|
||||
}
|
||||
if (channelSettingsKeys.contains("filterChainHash") || force) {
|
||||
swgLocalSinkSettings->setFilterChainHash(settings.m_filterChainHash);
|
||||
}
|
||||
|
||||
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
|
||||
.arg(settings.m_reverseAPIAddress)
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#define INCLUDE_SIGMFFILESINK_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
@ -29,7 +30,6 @@
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QThread;
|
||||
|
||||
class DeviceAPI;
|
||||
class DeviceSampleSource;
|
||||
@ -61,26 +61,6 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgBasebandSampleRateNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgBasebandSampleRateNotification* create(int sampleRate) {
|
||||
return new MsgBasebandSampleRateNotification(sampleRate);
|
||||
}
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
|
||||
private:
|
||||
|
||||
MsgBasebandSampleRateNotification(int sampleRate) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate)
|
||||
{ }
|
||||
|
||||
int m_sampleRate;
|
||||
};
|
||||
|
||||
SigMFFileSink(DeviceAPI *deviceAPI);
|
||||
virtual ~SigMFFileSink();
|
||||
virtual void destroy() { delete this; }
|
||||
@ -135,7 +115,7 @@ public:
|
||||
|
||||
private:
|
||||
DeviceAPI *m_deviceAPI;
|
||||
QThread *m_thread;
|
||||
QThread m_thread;
|
||||
SigMFFileSinkBaseband *m_basebandSink;
|
||||
SigMFFileSinkSettings m_settings;
|
||||
|
||||
@ -148,8 +128,6 @@ private:
|
||||
|
||||
void applySettings(const SigMFFileSinkSettings& settings, bool force = false);
|
||||
void propagateSampleRateAndFrequency(uint32_t index, uint32_t log2Decim);
|
||||
static void validateFilterChainHash(SigMFFileSinkSettings& settings);
|
||||
void calculateFrequencyOffset(uint32_t log2Decim, uint32_t filterChainHash);
|
||||
DeviceSampleSource *getLocalDevice(uint32_t index);
|
||||
|
||||
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const SigMFFileSinkSettings& settings, bool force);
|
||||
|
||||
@ -27,12 +27,31 @@ MESSAGE_CLASS_DEFINITION(SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkBaseban
|
||||
MESSAGE_CLASS_DEFINITION(SigMFFileSinkBaseband::MsgConfigureSigMFFileSinkWork, Message)
|
||||
|
||||
SigMFFileSinkBaseband::SigMFFileSinkBaseband() :
|
||||
m_running(false),
|
||||
m_mutex(QMutex::Recursive)
|
||||
{
|
||||
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000));
|
||||
m_channelizer = new DownChannelizer(&m_sink);
|
||||
|
||||
qDebug("SigMFFileSinkBaseband::SigMFFileSinkBaseband");
|
||||
}
|
||||
|
||||
SigMFFileSinkBaseband::~SigMFFileSinkBaseband()
|
||||
{
|
||||
m_inputMessageQueue.clear();
|
||||
delete m_channelizer;
|
||||
}
|
||||
|
||||
void SigMFFileSinkBaseband::reset()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_inputMessageQueue.clear();
|
||||
m_sampleFifo.reset();
|
||||
}
|
||||
|
||||
void SigMFFileSinkBaseband::startWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
QObject::connect(
|
||||
&m_sampleFifo,
|
||||
&SampleSinkFifo::dataReady,
|
||||
@ -40,19 +59,21 @@ SigMFFileSinkBaseband::SigMFFileSinkBaseband() :
|
||||
&SigMFFileSinkBaseband::handleData,
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
SigMFFileSinkBaseband::~SigMFFileSinkBaseband()
|
||||
{
|
||||
delete m_channelizer;
|
||||
}
|
||||
|
||||
void SigMFFileSinkBaseband::reset()
|
||||
void SigMFFileSinkBaseband::stopWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_sampleFifo.reset();
|
||||
disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
QObject::disconnect(
|
||||
&m_sampleFifo,
|
||||
&SampleSinkFifo::dataReady,
|
||||
this,
|
||||
&SigMFFileSinkBaseband::handleData
|
||||
);
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void SigMFFileSinkBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
@ -115,10 +136,19 @@ bool SigMFFileSinkBaseband::handleMessage(const Message& cmd)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
qDebug() << "SigMFFileSinkBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate();
|
||||
qDebug() << "SigMFFileSinkBaseband::handleMessage: DSPSignalNotification:"
|
||||
<< " basebandSampleRate: " << notif.getSampleRate()
|
||||
<< " cnterFrequency: " << notif.getCenterFrequency();
|
||||
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate()));
|
||||
m_channelizer->setBasebandSampleRate(notif.getSampleRate(), true); // apply decimation
|
||||
m_sink.setSampleRate(getChannelSampleRate());
|
||||
m_centerFrequency = notif.getCenterFrequency();
|
||||
m_channelizer->setBasebandSampleRate(notif.getSampleRate());
|
||||
int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<m_settings.m_log2Decim);
|
||||
m_channelizer->setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset);
|
||||
m_sink.applyChannelSettings(
|
||||
m_channelizer->getChannelSampleRate(),
|
||||
desiredSampleRate,
|
||||
m_channelizer->getChannelFrequencyOffset(),
|
||||
m_centerFrequency + m_settings.m_inputFrequencyOffset);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -146,17 +176,24 @@ void SigMFFileSinkBaseband::applySettings(const SigMFFileSinkSettings& settings,
|
||||
{
|
||||
qDebug() << "SigMFFileSinkBaseband::applySettings:"
|
||||
<< "m_log2Decim:" << settings.m_log2Decim
|
||||
<< "m_filterChainHash:" << settings.m_filterChainHash
|
||||
<< " force: " << force;
|
||||
<< "m_inputFrequencyOffset:" << settings.m_inputFrequencyOffset
|
||||
<< "m_fileRecordName: " << settings.m_fileRecordName
|
||||
<< "m_centerFrequency: " << m_centerFrequency
|
||||
<< "force: " << force;
|
||||
|
||||
if ((settings.m_log2Decim != m_settings.m_log2Decim)
|
||||
|| (settings.m_filterChainHash != m_settings.m_filterChainHash) || force)
|
||||
|| (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
|
||||
{
|
||||
m_channelizer->setDecimation(settings.m_log2Decim, settings.m_filterChainHash);
|
||||
m_sink.setSampleRate(getChannelSampleRate());
|
||||
int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<settings.m_log2Decim);
|
||||
m_channelizer->setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset);
|
||||
m_sink.applyChannelSettings(
|
||||
m_channelizer->getChannelSampleRate(),
|
||||
desiredSampleRate,
|
||||
m_channelizer->getChannelFrequencyOffset(),
|
||||
m_centerFrequency + settings.m_inputFrequencyOffset);
|
||||
}
|
||||
|
||||
//m_source.applySettings(settings, force);
|
||||
m_sink.applySettings(settings, force);
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
|
||||
@ -81,10 +81,13 @@ public:
|
||||
~SigMFFileSinkBaseband();
|
||||
|
||||
void reset();
|
||||
void startWork();
|
||||
void stopWork();
|
||||
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||
int getChannelSampleRate() const;
|
||||
void setBasebandSampleRate(int sampleRate);
|
||||
bool isRunning() const { return m_running; }
|
||||
|
||||
private:
|
||||
SampleSinkFifo m_sampleFifo;
|
||||
@ -92,6 +95,8 @@ private:
|
||||
SigMFFileSinkSink m_sink;
|
||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||
SigMFFileSinkSettings m_settings;
|
||||
int64_t m_centerFrequency;
|
||||
bool m_running;
|
||||
QMutex m_mutex;
|
||||
|
||||
bool handleMessage(const Message& cmd);
|
||||
|
||||
@ -16,11 +16,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QLocale>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "device/deviceuiset.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "gui/devicestreamselectiondialog.h"
|
||||
#include "dsp/hbfilterchainconverter.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "sigmffilesinkgui.h"
|
||||
@ -86,12 +88,22 @@ bool SigMFFileSinkGUI::deserialize(const QByteArray& data)
|
||||
|
||||
bool SigMFFileSinkGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (SigMFFileSink::MsgBasebandSampleRateNotification::match(message))
|
||||
if (DSPSignalNotification::match(message))
|
||||
{
|
||||
SigMFFileSink::MsgBasebandSampleRateNotification& notif = (SigMFFileSink::MsgBasebandSampleRateNotification&) message;
|
||||
//m_channelMarker.setBandwidth(notif.getSampleRate());
|
||||
DSPSignalNotification notif = (const DSPSignalNotification&) message;
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
displayRateAndShift();
|
||||
displayRate();
|
||||
|
||||
if (m_fixedPosition)
|
||||
{
|
||||
setFrequencyFromPos();
|
||||
applySettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
setPosFromFrequency();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (SigMFFileSink::MsgConfigureSigMFFileSink::match(message))
|
||||
@ -114,7 +126,10 @@ SigMFFileSinkGUI::SigMFFileSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISe
|
||||
ui(new Ui::SigMFFileSinkGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_channelMarker(this),
|
||||
m_fixedShiftIndex(0),
|
||||
m_basebandSampleRate(0),
|
||||
m_fixedPosition(false),
|
||||
m_tickCount(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -132,6 +147,7 @@ SigMFFileSinkGUI::SigMFFileSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISe
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.setBandwidth(m_basebandSampleRate);
|
||||
m_channelMarker.setTitle("SigMF File Sink");
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setVisible(true); // activate signal on the last setting only
|
||||
@ -142,8 +158,9 @@ SigMFFileSinkGUI::SigMFFileSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISe
|
||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||
m_deviceUISet->addRollupWidget(this);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
|
||||
//connect(&(m_deviceUISet->m_deviceSourceAPI->getMasterTimer()), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
@ -175,10 +192,9 @@ void SigMFFileSinkGUI::applySettings(bool force)
|
||||
void SigMFFileSinkGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
m_channelMarker.setBandwidth(m_basebandSampleRate / (1<<m_settings.m_log2Decim));
|
||||
m_channelMarker.setMovable(false); // do not let user move the center arbitrarily
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
|
||||
|
||||
@ -187,9 +203,11 @@ void SigMFFileSinkGUI::displaySettings()
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
ui->fileNameText->setText(m_settings.m_fileRecordName);
|
||||
ui->decimationFactor->setCurrentIndex(m_settings.m_log2Decim);
|
||||
applyDecimation();
|
||||
displayStreamIndex();
|
||||
setPosFromFrequency();
|
||||
|
||||
blockApplySettings(false);
|
||||
}
|
||||
@ -203,18 +221,19 @@ void SigMFFileSinkGUI::displayStreamIndex()
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::displayRateAndShift()
|
||||
void SigMFFileSinkGUI::displayRate()
|
||||
{
|
||||
int shift = m_shiftFrequencyFactor * m_basebandSampleRate;
|
||||
ui->deltaFrequency->setValue(shift);
|
||||
//QLocale loc;
|
||||
//ui->offsetFrequencyText->setText(tr("%1 Hz").arg(loc.toString(shift)));
|
||||
double channelSampleRate = ((double) m_basebandSampleRate) / (1<<m_settings.m_log2Decim);
|
||||
ui->channelRateText->setText(tr("%1k").arg(QString::number(channelSampleRate / 1000.0, 'g', 5)));
|
||||
m_channelMarker.setCenterFrequency(shift);
|
||||
m_channelMarker.setBandwidth(channelSampleRate);
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::displayPos()
|
||||
{
|
||||
ui->position->setValue(m_fixedShiftIndex);
|
||||
ui->filterChainIndex->setText(tr("%1").arg(m_fixedShiftIndex));
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::leaveEvent(QEvent*)
|
||||
{
|
||||
m_channelMarker.setHighlighted(false);
|
||||
@ -225,6 +244,23 @@ void SigMFFileSinkGUI::enterEvent(QEvent*)
|
||||
m_channelMarker.setHighlighted(true);
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
if (m_fixedPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
setPosFromFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::channelMarkerHighlightedByCursor()
|
||||
{
|
||||
setHighlighted(m_channelMarker.getHighlighted());
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::handleSourceMessages()
|
||||
{
|
||||
Message* message;
|
||||
@ -289,46 +325,119 @@ void SigMFFileSinkGUI::onMenuDialogCalled(const QPoint &p)
|
||||
resetContextMenuType();
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
if (!m_fixedPosition)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
setPosFromFrequency();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::on_decimationFactor_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_log2Decim = index;
|
||||
applyDecimation();
|
||||
displayRate();
|
||||
displayPos();
|
||||
|
||||
if (m_fixedPosition)
|
||||
{
|
||||
setFrequencyFromPos();
|
||||
applySettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
setPosFromFrequency();
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::on_fixedPosition_toggled(bool checked)
|
||||
{
|
||||
m_fixedPosition = checked;
|
||||
m_channelMarker.setMovable(!checked);
|
||||
ui->deltaFrequency->setEnabled(!checked);
|
||||
ui->position->setEnabled(checked);
|
||||
|
||||
if (m_fixedPosition)
|
||||
{
|
||||
setFrequencyFromPos();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::on_position_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_filterChainHash = value;
|
||||
applyPosition();
|
||||
m_fixedShiftIndex = value;
|
||||
displayPos();
|
||||
|
||||
if (m_fixedPosition)
|
||||
{
|
||||
setFrequencyFromPos();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::on_record_toggled(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
ui->record->setStyleSheet("QToolButton { background-color : red; }");
|
||||
} else {
|
||||
ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||
}
|
||||
|
||||
m_sigMFFileSink->record(checked);
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::applyDecimation()
|
||||
void SigMFFileSinkGUI::on_showFileDialog_clicked(bool checked)
|
||||
{
|
||||
uint32_t maxHash = 1;
|
||||
(void) checked;
|
||||
QFileDialog fileDialog(
|
||||
this,
|
||||
tr("Save SigMF record file"),
|
||||
m_settings.m_fileRecordName,
|
||||
tr("SigMF Files (*.sigmf-meta)")
|
||||
);
|
||||
|
||||
for (uint32_t i = 0; i < m_settings.m_log2Decim; i++) {
|
||||
maxHash *= 3;
|
||||
fileDialog.setOptions(QFileDialog::DontUseNativeDialog);
|
||||
fileDialog.setFileMode(QFileDialog::AnyFile);
|
||||
QStringList fileNames;
|
||||
|
||||
if (fileDialog.exec())
|
||||
{
|
||||
fileNames = fileDialog.selectedFiles();
|
||||
|
||||
if (fileNames.size() > 0)
|
||||
{
|
||||
m_settings.m_fileRecordName = fileNames.at(0);
|
||||
ui->fileNameText->setText(m_settings.m_fileRecordName);
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
ui->position->setMaximum(maxHash-1);
|
||||
ui->position->setValue(m_settings.m_filterChainHash);
|
||||
m_settings.m_filterChainHash = ui->position->value();
|
||||
applyPosition();
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::applyPosition()
|
||||
void SigMFFileSinkGUI::setFrequencyFromPos()
|
||||
{
|
||||
ui->filterChainIndex->setText(tr("%1").arg(m_settings.m_filterChainHash));
|
||||
QString s;
|
||||
m_shiftFrequencyFactor = HBFilterChainConverter::convertToString(m_settings.m_log2Decim, m_settings.m_filterChainHash, s);
|
||||
ui->filterChainText->setText(s);
|
||||
int inputFrequencyOffset = SigMFFileSinkSettings::getOffsetFromFixedShiftIndex(
|
||||
m_basebandSampleRate,
|
||||
m_settings.m_log2Decim,
|
||||
m_fixedShiftIndex);
|
||||
m_channelMarker.setCenterFrequency(inputFrequencyOffset);
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
}
|
||||
|
||||
displayRateAndShift();
|
||||
applySettings();
|
||||
void SigMFFileSinkGUI::setPosFromFrequency()
|
||||
{
|
||||
int fshift = SigMFFileSinkSettings::getHalfBand(m_basebandSampleRate, m_settings.m_log2Decim + 1);
|
||||
m_fixedShiftIndex = SigMFFileSinkSettings::getFixedShiftIndexFromOffset(
|
||||
m_basebandSampleRate,
|
||||
m_settings.m_log2Decim,
|
||||
m_settings.m_inputFrequencyOffset + (m_settings.m_inputFrequencyOffset < 0 ? -fshift : fshift)
|
||||
);
|
||||
displayPos();
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::tick()
|
||||
@ -337,3 +446,10 @@ void SigMFFileSinkGUI::tick()
|
||||
m_tickCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SigMFFileSinkGUI::applyDecimation()
|
||||
{
|
||||
ui->position->setMaximum(SigMFFileSinkSettings::getNbFixedShiftIndexes(m_settings.m_log2Decim)-1);
|
||||
ui->position->setValue(m_fixedShiftIndex);
|
||||
m_fixedShiftIndex = ui->position->value();
|
||||
}
|
||||
|
||||
@ -55,14 +55,20 @@ public:
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual bool handleMessage(const Message& message);
|
||||
|
||||
public slots:
|
||||
void channelMarkerChangedByCursor();
|
||||
void channelMarkerHighlightedByCursor();
|
||||
|
||||
private:
|
||||
Ui::SigMFFileSinkGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
ChannelMarker m_channelMarker;
|
||||
SigMFFileSinkSettings m_settings;
|
||||
int m_fixedShiftIndex;
|
||||
int m_basebandSampleRate;
|
||||
double m_shiftFrequencyFactor; //!< Channel frequency shift factor
|
||||
bool m_fixedPosition;
|
||||
bool m_doApplySettings;
|
||||
|
||||
SigMFFileSink* m_sigMFFileSink;
|
||||
@ -75,22 +81,25 @@ private:
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void applyDecimation();
|
||||
void displaySettings();
|
||||
void displayStreamIndex();
|
||||
void displayRateAndShift();
|
||||
void updateLocalDevices();
|
||||
void displayRate();
|
||||
void displayPos();
|
||||
void setFrequencyFromPos();
|
||||
void setPosFromFrequency();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
|
||||
void applyDecimation();
|
||||
void applyPosition();
|
||||
|
||||
private slots:
|
||||
void handleSourceMessages();
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_decimationFactor_currentIndexChanged(int index);
|
||||
void on_fixedPosition_toggled(bool checked);
|
||||
void on_position_valueChanged(int value);
|
||||
void on_record_toggled(bool checked);
|
||||
void on_showFileDialog_clicked(bool checked);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void tick();
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
<item>
|
||||
<widget class="ValueDialZ" name="deltaFrequency" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
@ -125,13 +125,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="nco">
|
||||
<property name="text">
|
||||
<string>NCO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="decimationLabel">
|
||||
<property name="text">
|
||||
@ -227,7 +220,10 @@
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="positionLabel">
|
||||
<widget class="QCheckBox" name="fixedPosition">
|
||||
<property name="toolTip">
|
||||
<string>Use fixed frequency shift positions for little performance improvement</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pos</string>
|
||||
</property>
|
||||
@ -268,22 +264,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="filterChainText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Filter chain stages left to right (L: low, C: center, H: high) </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LLLLLL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@ -35,7 +35,6 @@ void SigMFFileSinkSettings::resetToDefaults()
|
||||
m_rgbColor = QColor(140, 4, 4).rgb();
|
||||
m_title = "SigMF File Sink";
|
||||
m_log2Decim = 0;
|
||||
m_filterChainHash = 0;
|
||||
m_channelMarker = nullptr;
|
||||
m_streamIndex = 0;
|
||||
m_useReverseAPI = false;
|
||||
@ -60,7 +59,6 @@ QByteArray SigMFFileSinkSettings::serialize() const
|
||||
s.writeU32(10, m_reverseAPIDeviceIndex);
|
||||
s.writeU32(11, m_reverseAPIChannelIndex);
|
||||
s.writeU32(12, m_log2Decim);
|
||||
s.writeU32(13, m_filterChainHash);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -102,7 +100,6 @@ bool SigMFFileSinkSettings::deserialize(const QByteArray& data)
|
||||
m_reverseAPIChannelIndex = tmp > 99 ? 99 : tmp;
|
||||
d.readU32(12, &tmp, 0);
|
||||
m_log2Decim = tmp > 6 ? 6 : tmp;
|
||||
d.readU32(13, &m_filterChainHash, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -113,7 +110,34 @@ bool SigMFFileSinkSettings::deserialize(const QByteArray& data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int SigMFFileSinkSettings::getNbFixedShiftIndexes(int log2Decim)
|
||||
{
|
||||
int decim = (1<<log2Decim);
|
||||
return 2*decim - 1;
|
||||
}
|
||||
|
||||
int SigMFFileSinkSettings::getHalfBand(int sampleRate, int log2Decim)
|
||||
{
|
||||
int decim = (1<<log2Decim);
|
||||
return sampleRate / (2*decim);
|
||||
}
|
||||
|
||||
unsigned int SigMFFileSinkSettings::getFixedShiftIndexFromOffset(int sampleRate, int log2Decim, int frequencyOffset)
|
||||
{
|
||||
if (sampleRate == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decim = (1<<log2Decim);
|
||||
int mid = decim - 1;
|
||||
return ((frequencyOffset*2*decim) / sampleRate) + mid;
|
||||
}
|
||||
|
||||
int SigMFFileSinkSettings::getOffsetFromFixedShiftIndex(int sampleRate, int log2Decim, int shiftIndex)
|
||||
{
|
||||
int decim = (1<<log2Decim);
|
||||
int mid = decim - 1;
|
||||
return ((shiftIndex - mid) * sampleRate) / (2*decim);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ struct SigMFFileSinkSettings
|
||||
quint32 m_rgbColor;
|
||||
QString m_title;
|
||||
uint32_t m_log2Decim;
|
||||
uint32_t m_filterChainHash;
|
||||
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
@ -46,6 +45,11 @@ struct SigMFFileSinkSettings
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
|
||||
static unsigned int getNbFixedShiftIndexes(int log2Decim);
|
||||
static int getHalfBand(int sampleRate, int log2Decim);
|
||||
static unsigned int getFixedShiftIndexFromOffset(int sampleRate, int log2Decim, int frequencyOffset);
|
||||
static int getOffsetFromFixedShiftIndex(int sampleRate, int log2Decim, int shiftIndex);
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_SIFMFFILESINKSETTINGS_H_ */
|
||||
|
||||
@ -15,11 +15,15 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dsp/filerecord.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/sigmffilerecord.h"
|
||||
|
||||
#include "sigmffilesinksink.h"
|
||||
|
||||
SigMFFileSinkSink::SigMFFileSinkSink() :
|
||||
m_recordEnabled(false),
|
||||
m_record(false)
|
||||
{}
|
||||
|
||||
@ -28,12 +32,8 @@ SigMFFileSinkSink::~SigMFFileSinkSink()
|
||||
|
||||
void SigMFFileSinkSink::startRecording()
|
||||
{
|
||||
QString fileBase;
|
||||
FileRecordInterface::RecordType recordType = FileRecordInterface::guessTypeFromFileName(m_settings.m_fileRecordName, fileBase);
|
||||
|
||||
if (recordType == FileRecordInterface::RecordTypeSigMF)
|
||||
if (m_recordEnabled)
|
||||
{
|
||||
m_fileSink.setFileName(fileBase);
|
||||
m_fileSink.startRecording();
|
||||
m_record = true;
|
||||
}
|
||||
@ -47,11 +47,105 @@ void SigMFFileSinkSink::stopRecording()
|
||||
|
||||
void SigMFFileSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
{
|
||||
for (SampleVector::const_iterator it = begin; it < end; ++it)
|
||||
{
|
||||
Complex c(it->real(), it->imag());
|
||||
c *= m_nco.nextIQ();
|
||||
|
||||
if (m_interpolatorDistance == 1)
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(c.real(), c.imag()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Complex ci;
|
||||
|
||||
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
|
||||
{
|
||||
m_sampleBuffer.push_back(Sample(ci.real(), ci.imag()));
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_record) {
|
||||
m_fileSink.feed(begin, end, true);
|
||||
m_fileSink.feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true);
|
||||
}
|
||||
|
||||
m_sampleBuffer.clear();
|
||||
}
|
||||
|
||||
void SigMFFileSinkSink::setSampleRate(int sampleRate)
|
||||
void SigMFFileSinkSink::applyChannelSettings(
|
||||
int channelSampleRate,
|
||||
int sinkSampleRate,
|
||||
int channelFrequencyOffset,
|
||||
int64_t centerFrequency,
|
||||
bool force)
|
||||
{
|
||||
qDebug() << "SigMFFileSinkSink::applyChannelSettings:"
|
||||
<< " channelSampleRate: " << channelSampleRate
|
||||
<< " sinkSampleRate: " << sinkSampleRate
|
||||
<< " channelFrequencyOffset: " << channelFrequencyOffset
|
||||
<< " centerFrequency: " << centerFrequency
|
||||
<< " force: " << force;
|
||||
|
||||
if ((m_channelFrequencyOffset != channelFrequencyOffset) ||
|
||||
(m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
m_nco.setFreq(-channelFrequencyOffset, channelSampleRate);
|
||||
}
|
||||
|
||||
if ((m_channelSampleRate != channelSampleRate)
|
||||
|| (m_sinkSampleRate != sinkSampleRate) || force)
|
||||
{
|
||||
m_interpolator.create(16, channelSampleRate, channelSampleRate / 2.2f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) channelSampleRate / (Real) sinkSampleRate;
|
||||
}
|
||||
|
||||
if ((m_centerFrequency != centerFrequency)
|
||||
|| (m_channelFrequencyOffset != channelFrequencyOffset)
|
||||
|| (m_sinkSampleRate != sinkSampleRate) || force)
|
||||
{
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(sinkSampleRate, centerFrequency + m_settings.m_inputFrequencyOffset);
|
||||
m_fileSink.getInputMessageQueue()->push(notif);
|
||||
}
|
||||
|
||||
m_channelSampleRate = channelSampleRate;
|
||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||
m_sinkSampleRate = sinkSampleRate;
|
||||
m_centerFrequency = centerFrequency;
|
||||
}
|
||||
|
||||
void SigMFFileSinkSink::applySettings(const SigMFFileSinkSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "SigMFFileSinkSink::applySettings:"
|
||||
<< "m_log2Decim:" << settings.m_log2Decim
|
||||
<< "m_inputFrequencyOffset:" << settings.m_inputFrequencyOffset
|
||||
<< "m_fileRecordName: " << settings.m_fileRecordName
|
||||
<< "force: " << force;
|
||||
|
||||
if ((settings.m_fileRecordName != m_settings.m_fileRecordName) || force)
|
||||
{
|
||||
QString fileBase;
|
||||
FileRecordInterface::RecordType recordType = FileRecordInterface::guessTypeFromFileName(settings.m_fileRecordName, fileBase);
|
||||
|
||||
if (recordType == FileRecordInterface::RecordTypeSigMF)
|
||||
{
|
||||
m_fileSink.setFileName(fileBase);
|
||||
m_recordEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_recordEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
|
||||
{
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(m_sinkSampleRate, m_centerFrequency + m_settings.m_inputFrequencyOffset);
|
||||
m_fileSink.getInputMessageQueue()->push(notif);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
@ -20,6 +20,8 @@
|
||||
|
||||
#include "dsp/channelsamplesink.h"
|
||||
#include "dsp/sigmffilerecord.h"
|
||||
#include "dsp/interpolator.h"
|
||||
#include "dsp/ncof.h"
|
||||
|
||||
#include "sigmffilesinksettings.h"
|
||||
|
||||
@ -37,15 +39,27 @@ public:
|
||||
void stopRecording();
|
||||
void setDeviceHwId(const QString& hwId) { m_deviceHwId = hwId; }
|
||||
void setDeviceUId(int uid) { m_deviceUId = uid; }
|
||||
void setSampleRate(int sampleRate);
|
||||
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||
void applyChannelSettings(
|
||||
int channelSampleRate,
|
||||
int sinkSampleRate,
|
||||
int channelFrequencyOffset,
|
||||
int64_t centerFrequency,
|
||||
bool force = false);
|
||||
void applySettings(const SigMFFileSinkSettings& settings, bool force = false);
|
||||
|
||||
private:
|
||||
int m_channelSampleRate;
|
||||
int m_channelFrequencyOffset;
|
||||
int m_sinkSampleRate;
|
||||
int64_t m_centerFrequency;
|
||||
NCOF m_nco;
|
||||
Interpolator m_interpolator;
|
||||
Real m_interpolatorDistance;
|
||||
Real m_interpolatorDistanceRemain;
|
||||
SampleVector m_sampleBuffer;
|
||||
SigMFFileSinkSettings m_settings;
|
||||
SigMFFileRecord m_fileSink;
|
||||
bool m_recordEnabled;
|
||||
bool m_record;
|
||||
QString m_deviceHwId;
|
||||
int m_deviceUId;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user