mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-24 11:12:27 -04:00
Fixed LocalSink and LocalInput samples threading model by adding one decoupling FIFO. Fixes issue #549
This commit is contained in:
parent
18cee9d101
commit
cf6c964e69
@ -33,6 +33,7 @@ LocalSinkSink::LocalSinkSink() :
|
|||||||
m_sampleRate(48000),
|
m_sampleRate(48000),
|
||||||
m_deviceSampleRate(48000)
|
m_deviceSampleRate(48000)
|
||||||
{
|
{
|
||||||
|
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000));
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ LocalSinkSink::~LocalSinkSink()
|
|||||||
|
|
||||||
void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||||
{
|
{
|
||||||
emit samplesAvailable((const quint8*) &(*begin), (end-begin)*sizeof(Sample));
|
m_sampleFifo.write(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSinkSink::start(DeviceSampleSource *deviceSource)
|
void LocalSinkSink::start(DeviceSampleSource *deviceSource)
|
||||||
@ -54,16 +55,19 @@ void LocalSinkSink::start(DeviceSampleSource *deviceSource)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_sinkThread = new LocalSinkThread();
|
m_sinkThread = new LocalSinkThread();
|
||||||
|
m_sinkThread->setSampleFifo(&m_sampleFifo);
|
||||||
|
|
||||||
if (deviceSource) {
|
if (deviceSource) {
|
||||||
m_sinkThread->setSampleFifo(deviceSource->getSampleFifo());
|
m_sinkThread->setDeviceSampleFifo(deviceSource->getSampleFifo());
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(this,
|
QObject::connect(
|
||||||
SIGNAL(samplesAvailable(const quint8*, uint)),
|
&m_sampleFifo,
|
||||||
m_sinkThread,
|
&SampleSinkFifo::dataReady,
|
||||||
SLOT(processSamples(const quint8*, uint)),
|
m_sinkThread,
|
||||||
Qt::QueuedConnection);
|
&LocalSinkThread::handleData,
|
||||||
|
Qt::QueuedConnection
|
||||||
|
);
|
||||||
|
|
||||||
m_sinkThread->startStop(true);
|
m_sinkThread->startStop(true);
|
||||||
m_running = true;
|
m_running = true;
|
||||||
@ -73,10 +77,12 @@ void LocalSinkSink::stop()
|
|||||||
{
|
{
|
||||||
qDebug("LocalSinkSink::stop");
|
qDebug("LocalSinkSink::stop");
|
||||||
|
|
||||||
disconnect(this,
|
QObject::disconnect(
|
||||||
SIGNAL(samplesAvailable(const quint8*, uint)),
|
&m_sampleFifo,
|
||||||
m_sinkThread,
|
&SampleSinkFifo::dataReady,
|
||||||
SLOT(processSamples(const quint8*, uint)));
|
m_sinkThread,
|
||||||
|
&LocalSinkThread::handleData
|
||||||
|
);
|
||||||
|
|
||||||
if (m_sinkThread != 0)
|
if (m_sinkThread != 0)
|
||||||
{
|
{
|
||||||
|
@ -40,10 +40,8 @@ public:
|
|||||||
void stop();
|
void stop();
|
||||||
bool isRunning() const { return m_running; }
|
bool isRunning() const { return m_running; }
|
||||||
|
|
||||||
signals:
|
|
||||||
void samplesAvailable(const quint8* data, uint count);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SampleSinkFifo m_sampleFifo;
|
||||||
LocalSinkSettings m_settings;
|
LocalSinkSettings m_settings;
|
||||||
LocalSinkThread *m_sinkThread;
|
LocalSinkThread *m_sinkThread;
|
||||||
bool m_running;
|
bool m_running;
|
||||||
|
@ -72,10 +72,31 @@ void LocalSinkThread::run()
|
|||||||
qDebug("LocalSinkThread::run: end");
|
qDebug("LocalSinkThread::run: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSinkThread::processSamples(const quint8* data, uint count)
|
void LocalSinkThread::handleData()
|
||||||
{
|
{
|
||||||
if (m_sampleFifo && m_running) {
|
while ((m_sampleFifo->fill() > 0) && (m_inputMessageQueue.size() == 0))
|
||||||
m_sampleFifo->write(data, count);
|
{
|
||||||
|
SampleVector::iterator part1begin;
|
||||||
|
SampleVector::iterator part1end;
|
||||||
|
SampleVector::iterator part2begin;
|
||||||
|
SampleVector::iterator part2end;
|
||||||
|
|
||||||
|
std::size_t count = m_sampleFifo->readBegin(m_sampleFifo->fill(), &part1begin, &part1end, &part2begin, &part2end);
|
||||||
|
|
||||||
|
if (m_deviceSampleFifo && m_running)
|
||||||
|
{
|
||||||
|
// first part of FIFO data
|
||||||
|
if (part1begin != part1end) {
|
||||||
|
m_deviceSampleFifo->write(part1begin,part1end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// second part of FIFO data (used when block wraps around)
|
||||||
|
if(part2begin != part2end) {
|
||||||
|
m_deviceSampleFifo->write(part2begin, part2end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sampleFifo->readCommit((unsigned int) count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,15 +56,17 @@ public:
|
|||||||
|
|
||||||
void startStop(bool start);
|
void startStop(bool start);
|
||||||
void setSampleFifo(SampleSinkFifo *sampleFifo) { m_sampleFifo = sampleFifo; }
|
void setSampleFifo(SampleSinkFifo *sampleFifo) { m_sampleFifo = sampleFifo; }
|
||||||
|
void setDeviceSampleFifo(SampleSinkFifo *sampleFifo) { m_deviceSampleFifo = sampleFifo; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void processSamples(const quint8* data, uint count);
|
void handleData(); //!< Handle data when samples have to be processed
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMutex m_startWaitMutex;
|
QMutex m_startWaitMutex;
|
||||||
QWaitCondition m_startWaiter;
|
QWaitCondition m_startWaiter;
|
||||||
volatile bool m_running;
|
volatile bool m_running;
|
||||||
SampleSinkFifo *m_sampleFifo;
|
SampleSinkFifo *m_sampleFifo;
|
||||||
|
SampleSinkFifo *m_deviceSampleFifo;
|
||||||
|
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user