1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-28 15:56:33 -04:00

Deep redesign: debug AM demod removing extraneous interpolator init in start method

This commit is contained in:
f4exb 2015-08-24 00:51:27 +02:00
parent bc287a4c33
commit 19b234c4df
16 changed files with 181 additions and 124 deletions

View File

@ -18,11 +18,13 @@
#ifndef INCLUDE_AUDIOFIFO_H
#define INCLUDE_AUDIOFIFO_H
#include <QObject>
#include <QMutex>
#include <QWaitCondition>
#include "util/export.h"
class SDRANGELOVE_API AudioFifo {
class SDRANGELOVE_API AudioFifo : public QObject {
Q_OBJECT
public:
AudioFifo();
AudioFifo(uint sampleSize, uint numSamples);
@ -30,8 +32,8 @@ public:
bool setSize(uint sampleSize, uint numSamples);
uint write(const quint8* data, uint numSamples, int timeout = INT_MAX);
uint read(quint8* data, uint numSamples, int timeout = INT_MAX);
uint write(const quint8* data, uint numSamples, int timeout_ms = INT_MAX);
uint read(quint8* data, uint numSamples, int timeout_ms = INT_MAX);
uint drain(uint numSamples);
void clear();

View File

@ -20,6 +20,7 @@
#include <QMutex>
#include <QIODevice>
#include <QAudioFormat>
#include <list>
#include <vector>
#include "util/export.h"
@ -39,6 +40,8 @@ public:
void addFifo(AudioFifo* audioFifo);
void removeFifo(AudioFifo* audioFifo);
uint getRate() const { return m_audioFormat.sampleRate(); }
private:
QMutex m_mutex;
QAudioOutput* m_audioOutput;
@ -47,6 +50,8 @@ private:
AudioFifos m_audioFifos;
std::vector<qint32> m_mixBuffer;
QAudioFormat m_audioFormat;
//virtual bool open(OpenMode mode);
virtual qint64 readData(char* data, qint64 maxLen);
virtual qint64 writeData(const char* data, qint64 len);

View File

@ -55,6 +55,9 @@ public:
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
MessageQueue* getOutputMessageQueue() { return &m_outputMessageQueue; }
uint getAudioSampleRate() const { return m_audioSampleRate; }
void setAudioSampleRate(uint rate);
void start(); //!< This thread start
void stop(); //!< This thread stop
@ -102,6 +105,7 @@ private:
uint m_sampleRate;
quint64 m_centerFrequency;
uint m_audioSampleRate;
bool m_dcOffsetCorrection;
bool m_iqImbalanceCorrection;

View File

@ -20,13 +20,18 @@ public:
void free();
// Original code allowed for upsampling, but was never used that way
bool interpolate(Real* distance, const Complex& next, Complex* result)
bool interpolate(Real *distance, const Complex& next, Complex* result)
{
advanceFilter(next);
*distance -= 1.0;
if (*distance >= 1.0)
{
return false;
doInterpolate((int)floor(*distance * (Real)m_phaseSteps), result);
}
doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result);
return true;
}

View File

@ -103,15 +103,15 @@ private:
PluginManager* m_pluginManager;
void loadSettings();
void loadSettings(const Preset* preset);
void saveSettings(Preset* preset);
void loadPresetSettings(const Preset* preset);
void savePresetSettings(Preset* preset);
void saveSettings();
void createStatusBar();
void closeEvent(QCloseEvent*);
void updateCenterFreqDisplay();
void updateSampleRate();
void updatePresets();
void updatePresetControls();
QTreeWidgetItem* addPresetToTree(const Preset* preset);
void applySettings();

View File

@ -23,11 +23,29 @@
#include "dsp/samplefifo.h"
#include "util/messagequeue.h"
#include "util/export.h"
#include "util/syncmessenger.h"
class SampleSink;
class QThread;
/**
* Because Qt is a piece of shit this class cannot be a nested protected class of ThreadedSampleSink
* So let's make everything public
*/
class ThreadedSampleFifo : public QObject {
Q_OBJECT
public:
ThreadedSampleFifo(SampleSink* sampleSink, std::size_t size = 1<<18);
~ThreadedSampleFifo();
void writeToFifo(SampleVector::const_iterator& begin, SampleVector::const_iterator& end);
SampleSink* m_sampleSink;
SampleFifo m_sampleFifo;
public slots:
void handleFifoData();
};
/**
* This class is a wrapper for SampleSink that runs the SampleSink object in its own thread
*/
@ -51,13 +69,10 @@ public:
QString getSampleSinkObjectName() const;
protected:
QThread *m_thread; //!< The thead object
SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread
SampleSink* m_sampleSink;
SampleFifo m_sampleFifo;
protected slots:
void handleData();
QThread *m_thread; //!< The thead object
ThreadedSampleFifo *m_threadedSampleFifo;
SampleSink* m_sampleSink;
};
#endif // INCLUDE_THREADEDSAMPLESINK_H

View File

@ -21,14 +21,15 @@
#include <stdio.h>
#include <complex.h>
#include "audio/audiooutput.h"
#include "dsp/dspengine.h"
#include "dsp/channelizer.h"
#include "dsp/pidcontroller.h"
MESSAGE_CLASS_DEFINITION(AMDemod::MsgConfigureAMDemod, Message)
AMDemod::AMDemod(AudioFifo* audioFifo, SampleSink* sampleSink) :
AMDemod::AMDemod(SampleSink* sampleSink) :
m_sampleSink(sampleSink),
m_audioFifo(audioFifo)
m_audioFifo(4, 48000)
{
setObjectName("AMDemod");
@ -38,15 +39,17 @@ AMDemod::AMDemod(AudioFifo* audioFifo, SampleSink* sampleSink) :
m_config.m_afBandwidth = 3000;
m_config.m_squelch = -40.0;
m_config.m_volume = 2.0;
m_config.m_audioSampleRate = 48000;
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
apply();
m_audioBuffer.resize(16384);
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
m_movingAverage.resize(16, 0);
m_volumeAGC.resize(4096, 0.003, 0);
DSPEngine::instance()->addAudioSink(&m_audioFifo);
}
AMDemod::~AMDemod()
@ -63,7 +66,7 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera
{
Complex ci;
if (m_audioFifo->size() == 0)
if (m_audioFifo.size() == 0)
{
return;
}
@ -82,7 +85,7 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera
if (m_movingAverage.average() >= m_squelchLevel)
{
m_squelchState = m_running.m_audioSampleRate/ 20;
m_squelchState = m_running.m_audioSampleRate / 20;
}
qint16 sample;
@ -122,12 +125,11 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera
if (m_audioBufferFill >= m_audioBuffer.size())
{
uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1);
uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10);
// FIXME: Not necessarily bad, There is a race between threads but generally it works i.e. samples are not lost
if (res != m_audioBufferFill)
{
qDebug("AMDemod::feed: %u/%u audio samples lost", m_audioBufferFill - res, m_audioBufferFill);
qDebug("AMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill);
}
m_audioBufferFill = 0;
@ -139,14 +141,12 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera
if (m_audioBufferFill > 0)
{
uint res = m_audioFifo->write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1);
uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 10);
// Same remark as above
/*
if (res != m_audioBufferFill)
{
qDebug("AMDemod::feed: %u samples written vs %u requested", res, m_audioBufferFill);
}*/
qDebug("AMDemod::feed: %u/%u tail samples written", res, m_audioBufferFill);
}
m_audioBufferFill = 0;
}
@ -161,12 +161,11 @@ void AMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_itera
void AMDemod::start()
{
qDebug() << "AMDemod::start: m_inputSampleRate: " << m_config.m_inputSampleRate
<< " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset;
m_squelchState = 0;
m_audioFifo->clear();
m_interpolatorRegulation = 0.9999;
m_interpolatorDistance = 1.0;
m_interpolatorDistanceRemain = 0.0;
m_lastSample = 0;
m_audioFifo.clear();
}
void AMDemod::stop()
@ -203,7 +202,7 @@ bool AMDemod::handleMessage(const Message& cmd)
apply();
qDebug() << " - MsgConfigureAMDemod:"
qDebug() << "AMDemod::handleMessage: MsgConfigureAMDemod:"
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
<< " m_afBandwidth: " << m_config.m_afBandwidth
<< " m_volume: " << m_config.m_volume
@ -239,6 +238,8 @@ void AMDemod::apply()
m_interpolator.create(16, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_audioSampleRate;
qDebug() << "AMDemod::apply: m_inputSampleRate: " << m_config.m_inputSampleRate
<< " m_interpolatorDistance: " << m_interpolatorDistance;
}
if((m_config.m_afBandwidth != m_running.m_afBandwidth) ||

View File

@ -30,8 +30,9 @@
class AudioFifo;
class AMDemod : public SampleSink {
Q_OBJECT
public:
AMDemod(AudioFifo* audioFifo, SampleSink* sampleSink);
AMDemod(SampleSink* sampleSink);
~AMDemod();
void configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandwidth, Real volume, Real squelch);
@ -106,7 +107,6 @@ private:
Config m_running;
NCO m_nco;
Real m_interpolatorRegulation;
Interpolator m_interpolator;
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
@ -115,8 +115,6 @@ private:
Real m_squelchLevel;
int m_squelchState;
Real m_lastArgument;
Complex m_lastSample;
MovingAverage<Real> m_movingAverage;
SimpleAGC m_volumeAGC;
@ -124,7 +122,7 @@ private:
uint m_audioBufferFill;
SampleSink* m_sampleSink;
AudioFifo* m_audioFifo;
AudioFifo m_audioFifo;
SampleVector m_sampleBuffer;
void apply();

View File

@ -201,11 +201,9 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked()));
m_audioFifo = new AudioFifo(4, 48000);
m_amDemod = new AMDemod(m_audioFifo, 0);
m_amDemod = new AMDemod(0);
m_channelizer = new Channelizer(m_amDemod);
m_threadedChannelizer = new ThreadedSampleSink(m_channelizer, this);
DSPEngine::instance()->addAudioSink(m_audioFifo);
DSPEngine::instance()->addThreadedSink(m_threadedChannelizer);
m_channelMarker = new ChannelMarker(this);
@ -227,7 +225,6 @@ AMDemodGUI::~AMDemodGUI()
delete m_threadedChannelizer;
delete m_channelizer;
delete m_amDemod;
delete m_audioFifo;
delete m_channelMarker;
delete ui;
}

View File

@ -62,7 +62,7 @@ bool AudioFifo::setSize(uint sampleSize, uint numSamples)
return create(sampleSize, numSamples);
}
uint AudioFifo::write(const quint8* data, uint numSamples, int timeout)
uint AudioFifo::write(const quint8* data, uint numSamples, int timeout_ms)
{
QTime time;
uint total;
@ -77,7 +77,7 @@ uint AudioFifo::write(const quint8* data, uint numSamples, int timeout)
time.start();
m_mutex.lock();
if(timeout == 0)
if(timeout_ms == 0)
{
total = MIN(numSamples, m_size - m_fill);
}
@ -92,11 +92,11 @@ uint AudioFifo::write(const quint8* data, uint numSamples, int timeout)
{
if (isFull())
{
if (time.elapsed() < timeout)
if (time.elapsed() < timeout_ms)
{
m_writeWaitLock.lock();
m_mutex.unlock();
int ms = timeout - time.elapsed();
int ms = timeout_ms - time.elapsed();
if(ms < 1)
{
@ -141,7 +141,7 @@ uint AudioFifo::write(const quint8* data, uint numSamples, int timeout)
return total;
}
uint AudioFifo::read(quint8* data, uint numSamples, int timeout)
uint AudioFifo::read(quint8* data, uint numSamples, int timeout_ms)
{
QTime time;
uint total;
@ -156,7 +156,7 @@ uint AudioFifo::read(quint8* data, uint numSamples, int timeout)
time.start();
m_mutex.lock();
if(timeout == 0)
if(timeout_ms == 0)
{
total = MIN(numSamples, m_fill);
}
@ -171,11 +171,11 @@ uint AudioFifo::read(quint8* data, uint numSamples, int timeout)
{
if(isEmpty())
{
if(time.elapsed() < timeout)
if(time.elapsed() < timeout_ms)
{
m_readWaitLock.lock();
m_mutex.unlock();
int ms = timeout - time.elapsed();
int ms = timeout_ms - time.elapsed();
if(ms < 1)
{

View File

@ -50,7 +50,6 @@ bool AudioOutput::start(int device, int rate)
//Q_UNUSED(device);
//Q_UNUSED(rate);
QAudioFormat format;
QAudioDeviceInfo devInfo;
if (device < 0)
@ -76,31 +75,36 @@ bool AudioOutput::start(int device, int rate)
//QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice());
format.setSampleRate(rate);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
m_audioFormat.setSampleRate(rate);
m_audioFormat.setChannelCount(2);
m_audioFormat.setSampleSize(16);
m_audioFormat.setCodec("audio/pcm");
m_audioFormat.setByteOrder(QAudioFormat::LittleEndian);
m_audioFormat.setSampleType(QAudioFormat::SignedInt);
if (!devInfo.isFormatSupported(format))
if (!devInfo.isFormatSupported(m_audioFormat))
{
qWarning("AudioOutput::start: %d Hz S16_LE audio format not supported", rate);
format = devInfo.nearestFormat(format);
m_audioFormat = devInfo.nearestFormat(m_audioFormat);
qWarning("AudioOutput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate());
}
if (format.sampleSize() != 16)
if (m_audioFormat.sampleSize() != 16)
{
qWarning("AudioOutput::start: Audio device ( %s ) failed", qPrintable(devInfo.defaultOutputDevice().deviceName()));
return false;
}
m_audioOutput = new QAudioOutput(devInfo, format);
m_audioOutput = new QAudioOutput(devInfo, m_audioFormat);
QIODevice::open(QIODevice::ReadOnly);
m_audioOutput->start(this);
if (m_audioOutput->state() != QAudio::ActiveState)
{
qWarning("AudioOutput::start: cannot start");
}
return true;
}

View File

@ -32,7 +32,7 @@ void Channelizer::configure(MessageQueue* messageQueue, int sampleRate, int cent
void Channelizer::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly)
{
if(m_sampleSink == NULL) {
if(m_sampleSink == 0) {
m_sampleBuffer.clear();
return;
}
@ -55,16 +55,19 @@ void Channelizer::feed(SampleVector::const_iterator begin, SampleVector::const_i
void Channelizer::start()
{
if(m_sampleSink != NULL)
if(m_sampleSink != 0)
{
qDebug() << "Channelizer::start: thread: " << thread();
qDebug() << "Channelizer::start: thread: " << thread()
<< " m_inputSampleRate: " << m_inputSampleRate
<< " m_requestedOutputSampleRate: " << m_requestedOutputSampleRate
<< " m_requestedCenterFrequency: " << m_requestedCenterFrequency;
m_sampleSink->start();
}
}
void Channelizer::stop()
{
if(m_sampleSink != NULL)
if(m_sampleSink != 0)
m_sampleSink->stop();
}
@ -79,7 +82,7 @@ bool Channelizer::handleMessage(const Message& cmd)
qDebug() << "Channelizer::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_inputSampleRate;
applyConfiguration();
if (m_sampleSink != NULL)
if (m_sampleSink != 0)
{
m_sampleSink->handleMessage(notif);
}
@ -99,17 +102,11 @@ bool Channelizer::handleMessage(const Message& cmd)
applyConfiguration();
if (m_sampleSink != NULL)
{
MsgChannelizerNotification notif(m_currentOutputSampleRate, m_currentCenterFrequency);
m_sampleSink->handleMessage(notif);
}
return true;
}
else
{
if (m_sampleSink != NULL)
if (m_sampleSink != 0)
{
return m_sampleSink->handleMessage(cmd);
}
@ -132,11 +129,17 @@ void Channelizer::applyConfiguration()
<< ", req=" << m_requestedOutputSampleRate
<< ", out=" << m_currentOutputSampleRate
<< ", fc=" << m_currentCenterFrequency;
if (m_sampleSink != 0)
{
MsgChannelizerNotification notif(m_currentOutputSampleRate, m_currentCenterFrequency);
m_sampleSink->handleMessage(notif);
}
}
Channelizer::FilterStage::FilterStage(Mode mode) :
m_filter(new IntHalfbandFilter),
m_workFunction(NULL)
m_workFunction(0)
{
switch(mode) {
case ModeCenter:

View File

@ -32,6 +32,7 @@ DSPEngine::DSPEngine(QObject* parent) :
m_sampleSinks(),
m_sampleRate(0),
m_centerFrequency(0),
m_audioSampleRate(48000),
m_dcOffsetCorrection(false),
m_iqImbalanceCorrection(false),
m_iOffset(0),
@ -411,13 +412,13 @@ DSPEngine::State DSPEngine::gotoInit()
for (SampleSinks::const_iterator it = m_sampleSinks.begin(); it != m_sampleSinks.end(); ++it)
{
qDebug() << " - initializing " << (*it)->objectName().toStdString().c_str();
qDebug() << "DSPEngine::gotoInit: initializing " << (*it)->objectName().toStdString().c_str();
(*it)->handleMessage(notif);
}
for (ThreadedSampleSinks::const_iterator it = m_threadedSampleSinks.begin(); it != m_threadedSampleSinks.end(); ++it)
{
qDebug() << " - initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
qDebug() << "DSPEngine::gotoInit: initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
(*it)->handleSinkMessage(notif);
}
@ -431,8 +432,8 @@ DSPEngine::State DSPEngine::gotoInit()
DSPEngine::State DSPEngine::gotoRunning()
{
qDebug() << "DSPEngine::gotoRunning";
qDebug() << "DSPEngine::gotoRunning";
switch(m_state)
{
case StNotStarted:
@ -450,10 +451,10 @@ DSPEngine::State DSPEngine::gotoRunning()
}
if(m_sampleSource == NULL) {
return gotoError("No sample source configured");
return gotoError("DSPEngine::gotoRunning: No sample source configured");
}
qDebug() << " - " << m_deviceDescription.toStdString().c_str() << " started";
qDebug() << "DSPEngine::gotoRunning: " << m_deviceDescription.toStdString().c_str() << " started";
// Start everything
@ -463,20 +464,21 @@ DSPEngine::State DSPEngine::gotoRunning()
}
m_audioOutput.start(-1, 48000); // Use default output device at 48 kHz
m_audioSampleRate = m_audioOutput.getRate();
for(SampleSinks::const_iterator it = m_sampleSinks.begin(); it != m_sampleSinks.end(); it++)
{
qDebug() << " - starting " << (*it)->objectName().toStdString().c_str();
qDebug() << "DSPEngine::gotoRunning: starting " << (*it)->objectName().toStdString().c_str();
(*it)->start();
}
for (ThreadedSampleSinks::const_iterator it = m_threadedSampleSinks.begin(); it != m_threadedSampleSinks.end(); ++it)
{
qDebug() << " - starting ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
qDebug() << "DSPEngine::gotoRunning: starting ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
(*it)->start();
}
qDebug() << " - input message queue pending: " << m_inputMessageQueue.size();
qDebug() << "DSPEngine::gotoRunning:input message queue pending: " << m_inputMessageQueue.size();
return StRunning;
}
@ -681,3 +683,8 @@ void DSPEngine::handleSourceMessages()
delete message;
}
}
void DSPEngine::setAudioSampleRate(uint rate)
{
m_audioSampleRate = rate;
}

View File

@ -90,7 +90,7 @@ bool FileSink::handleMessage(const Message& message)
DSPSignalNotification& notif = (DSPSignalNotification&) message;
m_sampleRate = notif.getSampleRate();
m_centerFrequency = notif.getCenterFrequency();
qDebug() << " - DSPSignalNotification: m_inputSampleRate: " << m_sampleRate
qDebug() << "FileSink::handleMessage: DSPSignalNotification: m_inputSampleRate: " << m_sampleRate
<< " m_centerFrequency: " << m_centerFrequency;
return true;
}
@ -98,7 +98,7 @@ bool FileSink::handleMessage(const Message& message)
{
MsgConfigureFileSink& conf = (MsgConfigureFileSink&) message;
handleConfigure(conf.getFileName());
qDebug() << " - MsgConfigureFileSink: fileName: " << m_fileName.c_str();
qDebug() << "FileSink::handleMessage: MsgConfigureFileSink: fileName: " << m_fileName.c_str();
return true;
}
else

View File

@ -1,10 +1,26 @@
#include <QThread>
#include <QDebug>
#include <QApplication>
#include "dsp/threadedsamplesink.h"
#include "dsp/dspcommands.h"
#include "util/message.h"
ThreadedSampleFifo::ThreadedSampleFifo(SampleSink *sampleSink, std::size_t size) :
m_sampleSink(sampleSink)
{
connect(&m_sampleFifo, SIGNAL(dataReady()), this, SLOT(handleFifoData()));
m_sampleFifo.setSize(size);
}
ThreadedSampleFifo::~ThreadedSampleFifo()
{
m_sampleFifo.readCommit(m_sampleFifo.fill());
}
void ThreadedSampleFifo::writeToFifo(SampleVector::const_iterator& begin, SampleVector::const_iterator& end)
{
m_sampleFifo.write(begin, end);
}
ThreadedSampleSink::ThreadedSampleSink(SampleSink* sampleSink, QObject *parent) :
m_sampleSink(sampleSink)
{
@ -14,11 +30,13 @@ ThreadedSampleSink::ThreadedSampleSink(SampleSink* sampleSink, QObject *parent)
qDebug() << "ThreadedSampleSink::ThreadedSampleSink: " << name;
m_thread = new QThread(parent);
moveToThread(m_thread); // FIXME: the intermediate FIFO should be handled within the sink. Define a new type of sink that is compatible with threading
m_threadedSampleFifo = new ThreadedSampleFifo(m_sampleSink);
//moveToThread(m_thread); // FIXME: Fixed? the intermediate FIFO should be handled within the sink. Define a new type of sink that is compatible with threading
m_sampleSink->moveToThread(m_thread);
m_sampleFifo.moveToThread(m_thread);
connect(&m_sampleFifo, SIGNAL(dataReady()), this, SLOT(handleData()));
m_sampleFifo.setSize(262144);
m_threadedSampleFifo->moveToThread(m_thread);
//m_sampleFifo.moveToThread(m_thread);
//connect(&m_sampleFifo, SIGNAL(dataReady()), this, SLOT(handleData()));
//m_sampleFifo.setSize(262144);
qDebug() << "ThreadedSampleSink::ThreadedSampleSink: thread: " << thread() << " m_thread: " << m_thread;
}
@ -41,14 +59,13 @@ void ThreadedSampleSink::stop()
m_sampleSink->stop();
m_thread->exit();
m_thread->wait();
m_sampleFifo.readCommit(m_sampleFifo.fill());
}
void ThreadedSampleSink::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly)
{
// m_sampleSink->feed(begin, end, positiveOnly);
m_sampleFifo.write(begin, end);
//m_sampleSink->feed(begin, end, positiveOnly);
//m_sampleFifo.write(begin, end);
m_threadedSampleFifo->writeToFifo(begin, end);
}
bool ThreadedSampleSink::handleSinkMessage(Message& cmd)
@ -62,7 +79,7 @@ QString ThreadedSampleSink::getSampleSinkObjectName() const
}
void ThreadedSampleSink::handleData() // FIXME: Move it to the new threadable sink class
void ThreadedSampleFifo::handleFifoData() // FIXME: Fixed? Move it to the new threadable sink class
{
bool positiveOnly = false;

View File

@ -100,14 +100,13 @@ MainWindow::MainWindow(QWidget* parent) :
ui->sampleSource->blockSignals(sampleSourceSignalsBlocked);
m_spectrumVis = new SpectrumVis(ui->glSpectrum);
ui->glSpectrum->connectTimer(m_masterTimer);
ui->glSpectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
m_dspEngine->addSink(m_spectrumVis);
m_fileSink = new FileSink();
m_dspEngine->addSink(m_fileSink);
ui->glSpectrum->connectTimer(m_masterTimer);
ui->glSpectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum);
qDebug() << "MainWindow::MainWindow: loadSettings...";
loadSettings();
@ -123,17 +122,17 @@ MainWindow::MainWindow(QWidget* parent) :
ui->sampleSource->blockSignals(sampleSourceSignalsBlocked);
}
qDebug() << "MainWindow::MainWindow: load current settings...";
qDebug() << "MainWindow::MainWindow: load current preset settings...";
loadSettings(m_settings.getCurrent());
loadPresetSettings(m_settings.getCurrent());
qDebug() << "MainWindow::MainWindow: apply settings...";
applySettings();
qDebug() << "MainWindow::MainWindow: update presets...";
qDebug() << "MainWindow::MainWindow: update preset controls...";
updatePresets();
updatePresetControls();
qDebug() << "MainWindow::MainWindow: end";
}
@ -203,15 +202,11 @@ void MainWindow::loadSettings()
{
addPresetToTree(m_settings.getPreset(i));
}
Preset* current = m_settings.getCurrent();
//loadSettings(current);
}
void MainWindow::loadSettings(const Preset* preset)
void MainWindow::loadPresetSettings(const Preset* preset)
{
qDebug() << "MainWindow::loadSettings(preset): " << preset->getSource().toStdString().c_str();
qDebug() << "MainWindow::loadPresetSettings: preset: " << preset->getSource().toStdString().c_str();
ui->glSpectrumGUI->deserialize(preset->getSpectrumConfig());
ui->dcOffset->setChecked(preset->getDCOffsetCorrection());
@ -227,14 +222,14 @@ void MainWindow::saveSettings()
{
qDebug() << "MainWindow::saveSettings";
saveSettings(m_settings.getCurrent());
savePresetSettings(m_settings.getCurrent());
m_settings.save();
}
void MainWindow::saveSettings(Preset* preset)
void MainWindow::savePresetSettings(Preset* preset)
{
qDebug() << "MainWindow::saveSettings(preset): " << preset->getSource().toStdString().c_str();
qDebug() << "MainWindow::savePresetSettings: preset: " << preset->getSource().toStdString().c_str();
preset->setSpectrumConfig(ui->glSpectrumGUI->serialize());
preset->clearChannels();
@ -281,13 +276,17 @@ void MainWindow::updateSampleRate()
m_sampleRateWidget->setText(tr("Rate: %1 kHz").arg((float)m_sampleRate / 1000));
}
void MainWindow::updatePresets()
void MainWindow::updatePresetControls()
{
ui->presetTree->resizeColumnToContents(0);
if(ui->presetTree->currentItem() != 0) {
if(ui->presetTree->currentItem() != 0)
{
ui->presetDelete->setEnabled(true);
ui->presetLoad->setEnabled(true);
} else {
}
else
{
ui->presetDelete->setEnabled(false);
ui->presetLoad->setEnabled(false);
}
@ -318,7 +317,7 @@ QTreeWidgetItem* MainWindow::addPresetToTree(const Preset* preset)
item->setData(0, Qt::UserRole, qVariantFromValue(preset));
ui->presetTree->resizeColumnToContents(0);
updatePresets();
updatePresetControls();
return item;
}
@ -477,7 +476,7 @@ void MainWindow::on_presetSave_clicked()
if(dlg.exec() == QDialog::Accepted) {
Preset* preset = m_settings.newPreset(dlg.group(), dlg.description());
saveSettings(preset);
savePresetSettings(preset);
ui->presetTree->setCurrentItem(addPresetToTree(preset));
}
@ -492,7 +491,7 @@ void MainWindow::on_presetUpdate_clicked()
const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
if (preset != 0) {
Preset* preset_mod = const_cast<Preset*>(preset);
saveSettings(preset_mod);
savePresetSettings(preset_mod);
}
}
}
@ -504,7 +503,7 @@ void MainWindow::on_presetLoad_clicked()
QTreeWidgetItem* item = ui->presetTree->currentItem();
if(item == 0) {
updatePresets();
updatePresetControls();
return;
}
const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
@ -512,7 +511,7 @@ void MainWindow::on_presetLoad_clicked()
return;
}
loadSettings(preset);
loadPresetSettings(preset);
applySettings();
}
@ -520,7 +519,7 @@ void MainWindow::on_presetDelete_clicked()
{
QTreeWidgetItem* item = ui->presetTree->currentItem();
if(item == 0) {
updatePresets();
updatePresetControls();
return;
}
const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
@ -535,7 +534,7 @@ void MainWindow::on_presetDelete_clicked()
void MainWindow::on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
updatePresets();
updatePresetControls();
}
void MainWindow::on_presetTree_itemActivated(QTreeWidgetItem *item, int column)