mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-28 21:12:26 -04:00
Multiple modulators support: returned to one by one sample handling but pull a chunk of audio samples. Works with at least 3 modulators. Special handling of division factor
This commit is contained in:
parent
5598265e66
commit
9213c85d6a
@ -28,7 +28,7 @@
|
|||||||
#include "samplesourcefifo.h"
|
#include "samplesourcefifo.h"
|
||||||
#include "threadedbasebandsamplesource.h"
|
#include "threadedbasebandsamplesource.h"
|
||||||
|
|
||||||
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint uid, QObject* parent) :
|
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
|
||||||
m_uid(uid),
|
m_uid(uid),
|
||||||
QThread(parent),
|
QThread(parent),
|
||||||
m_state(StNotStarted),
|
m_state(StNotStarted),
|
||||||
@ -37,7 +37,8 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint uid, QObject* parent) :
|
|||||||
m_basebandSampleSources(),
|
m_basebandSampleSources(),
|
||||||
m_spectrumSink(0),
|
m_spectrumSink(0),
|
||||||
m_sampleRate(0),
|
m_sampleRate(0),
|
||||||
m_centerFrequency(0)
|
m_centerFrequency(0),
|
||||||
|
m_multipleSourcesDivisionFactor(1)
|
||||||
{
|
{
|
||||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||||
connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
|
connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
|
||||||
@ -190,96 +191,37 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
|
|||||||
// multiple channel sources handling
|
// multiple channel sources handling
|
||||||
else if ((m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size()) > 1)
|
else if ((m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size()) > 1)
|
||||||
{
|
{
|
||||||
// qDebug("DSPDeviceSinkEngine::work: multiple channel sources handling");
|
// qDebug("DSPDeviceSinkEngine::work: multiple channel sources handling: %u", m_multipleSourcesDivisionFactor);
|
||||||
|
|
||||||
SampleVector::iterator writeBegin;
|
// SampleVector::iterator writeBegin;
|
||||||
sampleFifo->getWriteIterator(writeBegin);
|
// sampleFifo->getWriteIterator(writeBegin);
|
||||||
SampleVector::iterator writeAt = writeBegin;
|
// SampleVector::iterator writeAt = writeBegin;
|
||||||
Sample s;
|
|
||||||
int sourceOccurence = 0;
|
|
||||||
|
|
||||||
// Read a chunk of data from the sources
|
|
||||||
|
|
||||||
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
|
||||||
{
|
|
||||||
((*it)->getSampleSourceFifo()).readAdvance(m_threadedBasebandSampleSourcesIteratorMap[*it], nbWriteSamples);
|
|
||||||
m_threadedBasebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
|
||||||
{
|
|
||||||
((*it)->getSampleSourceFifo()).readAdvance(m_basebandSampleSourcesIteratorMap[*it], nbWriteSamples);
|
|
||||||
m_basebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process sample by sample
|
|
||||||
|
|
||||||
for (int is = 0; is < nbWriteSamples; is++)
|
|
||||||
{
|
|
||||||
// pull data from threaded sources and merge them in the device sample FIFO
|
|
||||||
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
|
||||||
{
|
|
||||||
s = *m_threadedBasebandSampleSourcesIteratorMap[*it];
|
|
||||||
s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
|
||||||
|
|
||||||
if (sourceOccurence == 0) {
|
|
||||||
(*writeAt) = s;
|
|
||||||
} else {
|
|
||||||
(*writeAt) += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceOccurence++;
|
|
||||||
m_threadedBasebandSampleSourcesIteratorMap[*it]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pull data from direct sources and merge them in the device sample FIFO
|
|
||||||
for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
|
||||||
{
|
|
||||||
s = *m_basebandSampleSourcesIteratorMap[*it];
|
|
||||||
s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
|
||||||
|
|
||||||
if (sourceOccurence == 0) {
|
|
||||||
(*writeAt) = s;
|
|
||||||
} else {
|
|
||||||
(*writeAt) += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceOccurence++;
|
|
||||||
m_basebandSampleSourcesIteratorMap[*it]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
sampleFifo->bumpIndex(writeAt);
|
|
||||||
sourceOccurence = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SampleVector::iterator writeBegin;
|
|
||||||
// sampleFifo->getWriteIterator(writeBegin);
|
|
||||||
// SampleVector::iterator writeAt = writeBegin;
|
|
||||||
// Sample s;
|
// Sample s;
|
||||||
// int sourceOccurence = 0;
|
// int sourceOccurence = 0;
|
||||||
//
|
//
|
||||||
// for (int is = 0; is < nbWriteSamples; is++)
|
// // Read a chunk of data from the sources
|
||||||
// {
|
|
||||||
// // pull data from threaded sources and merge them in the device sample FIFO
|
|
||||||
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
|
||||||
// {
|
|
||||||
// (*it)->pull(s);
|
|
||||||
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
|
||||||
//
|
//
|
||||||
// if (sourceOccurence == 0) {
|
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
||||||
// (*writeAt) = s;
|
// {
|
||||||
// } else {
|
// ((*it)->getSampleSourceFifo()).readAdvance(m_threadedBasebandSampleSourcesIteratorMap[*it], nbWriteSamples);
|
||||||
// (*writeAt) += s;
|
// m_threadedBasebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// sourceOccurence++;
|
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
||||||
// }
|
// {
|
||||||
|
// ((*it)->getSampleSourceFifo()).readAdvance(m_basebandSampleSourcesIteratorMap[*it], nbWriteSamples);
|
||||||
|
// m_basebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
|
||||||
|
// }
|
||||||
//
|
//
|
||||||
// // pull data from direct sources and merge them in the device sample FIFO
|
// // Process sample by sample
|
||||||
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
//
|
||||||
// {
|
// for (int is = 0; is < nbWriteSamples; is++)
|
||||||
// (*it)->pull(s);
|
// {
|
||||||
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
// // pull data from threaded sources and merge them in the device sample FIFO
|
||||||
|
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
||||||
|
// {
|
||||||
|
// s = *m_threadedBasebandSampleSourcesIteratorMap[*it];
|
||||||
|
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
||||||
//
|
//
|
||||||
// if (sourceOccurence == 0) {
|
// if (sourceOccurence == 0) {
|
||||||
// (*writeAt) = s;
|
// (*writeAt) = s;
|
||||||
@ -288,11 +230,80 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// sourceOccurence++;
|
// sourceOccurence++;
|
||||||
// }
|
// m_threadedBasebandSampleSourcesIteratorMap[*it]++;
|
||||||
|
// }
|
||||||
//
|
//
|
||||||
// sampleFifo->bumpIndex(writeAt);
|
// // pull data from direct sources and merge them in the device sample FIFO
|
||||||
|
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
||||||
|
// {
|
||||||
|
// s = *m_basebandSampleSourcesIteratorMap[*it];
|
||||||
|
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
|
||||||
|
//
|
||||||
|
// if (sourceOccurence == 0) {
|
||||||
|
// (*writeAt) = s;
|
||||||
|
// } else {
|
||||||
|
// (*writeAt) += s;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// sourceOccurence++;
|
||||||
|
// m_basebandSampleSourcesIteratorMap[*it]++;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// sampleFifo->bumpIndex(writeAt);
|
||||||
// sourceOccurence = 0;
|
// sourceOccurence = 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
SampleVector::iterator writeBegin;
|
||||||
|
sampleFifo->getWriteIterator(writeBegin);
|
||||||
|
SampleVector::iterator writeAt = writeBegin;
|
||||||
|
Sample s;
|
||||||
|
int sourceOccurence = 0;
|
||||||
|
|
||||||
|
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->pullAudio(nbWriteSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->pullAudio(nbWriteSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int is = 0; is < nbWriteSamples; is++)
|
||||||
|
{
|
||||||
|
// pull data from threaded sources and merge them in the device sample FIFO
|
||||||
|
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->pull(s);
|
||||||
|
s /= m_multipleSourcesDivisionFactor;
|
||||||
|
|
||||||
|
if (sourceOccurence == 0) {
|
||||||
|
(*writeAt) = s;
|
||||||
|
} else {
|
||||||
|
(*writeAt) += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceOccurence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pull data from direct sources and merge them in the device sample FIFO
|
||||||
|
for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->pull(s);
|
||||||
|
s /= m_multipleSourcesDivisionFactor;
|
||||||
|
|
||||||
|
if (sourceOccurence == 0) {
|
||||||
|
(*writeAt) = s;
|
||||||
|
} else {
|
||||||
|
(*writeAt) += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceOccurence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleFifo->bumpIndex(writeAt);
|
||||||
|
sourceOccurence = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// feed the mix to the main spectrum sink
|
// feed the mix to the main spectrum sink
|
||||||
// if (m_spectrumSink)
|
// if (m_spectrumSink)
|
||||||
@ -443,6 +454,16 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoRunning()
|
|||||||
return gotoError("DSPDeviceSinkEngine::gotoRunning: Could not start sample source");
|
return gotoError("DSPDeviceSinkEngine::gotoRunning: Could not start sample source");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t nbSources = m_basebandSampleSources.size() + m_threadedBasebandSampleSources.size();
|
||||||
|
|
||||||
|
if (nbSources == 0) {
|
||||||
|
m_multipleSourcesDivisionFactor = 1;
|
||||||
|
} else if (nbSources < 3) {
|
||||||
|
m_multipleSourcesDivisionFactor = nbSources;
|
||||||
|
} else {
|
||||||
|
m_multipleSourcesDivisionFactor = 1<<nbSources;
|
||||||
|
}
|
||||||
|
|
||||||
for(BasebandSampleSources::const_iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); it++)
|
for(BasebandSampleSources::const_iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); it++)
|
||||||
{
|
{
|
||||||
qDebug() << "DSPDeviceSinkEngine::gotoRunning: starting " << (*it)->objectName().toStdString().c_str();
|
qDebug() << "DSPDeviceSinkEngine::gotoRunning: starting " << (*it)->objectName().toStdString().c_str();
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
|
#include <stdint.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "dsp/dsptypes.h"
|
#include "dsp/dsptypes.h"
|
||||||
@ -47,10 +48,10 @@ public:
|
|||||||
StError //!< engine is in error
|
StError //!< engine is in error
|
||||||
};
|
};
|
||||||
|
|
||||||
DSPDeviceSinkEngine(uint uid, QObject* parent = NULL);
|
DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL);
|
||||||
~DSPDeviceSinkEngine();
|
~DSPDeviceSinkEngine();
|
||||||
|
|
||||||
uint getUID() const { return m_uid; }
|
uint32_t getUID() const { return m_uid; }
|
||||||
|
|
||||||
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
|
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||||
MessageQueue* getOutputMessageQueue() { return &m_outputMessageQueue; }
|
MessageQueue* getOutputMessageQueue() { return &m_outputMessageQueue; }
|
||||||
@ -80,7 +81,7 @@ public:
|
|||||||
QString sinkDeviceDescription(); //!< Return the sink device description
|
QString sinkDeviceDescription(); //!< Return the sink device description
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint m_uid; //!< unique ID
|
uint32_t m_uid; //!< unique ID
|
||||||
|
|
||||||
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
|
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
|
||||||
MessageQueue m_outputMessageQueue; //<! Output message queue. Listen here.
|
MessageQueue m_outputMessageQueue; //<! Output message queue. Listen here.
|
||||||
@ -110,8 +111,9 @@ private:
|
|||||||
|
|
||||||
BasebandSampleSink *m_spectrumSink;
|
BasebandSampleSink *m_spectrumSink;
|
||||||
|
|
||||||
uint m_sampleRate;
|
uint32_t m_sampleRate;
|
||||||
quint64 m_centerFrequency;
|
quint64 m_centerFrequency;
|
||||||
|
uint32_t m_multipleSourcesDivisionFactor;
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void work(int nbWriteSamples); //!< transfer samples from beseband sources to sink if in running state
|
void work(int nbWriteSamples); //!< transfer samples from beseband sources to sink if in running state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user