1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 18:15:45 -05: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:
f4exb 2016-12-26 12:45:19 +01:00
parent 5598265e66
commit 9213c85d6a
2 changed files with 115 additions and 92 deletions

View File

@ -28,7 +28,7 @@
#include "samplesourcefifo.h"
#include "threadedbasebandsamplesource.h"
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint uid, QObject* parent) :
DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) :
m_uid(uid),
QThread(parent),
m_state(StNotStarted),
@ -37,7 +37,8 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint uid, QObject* parent) :
m_basebandSampleSources(),
m_spectrumSink(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_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
@ -190,96 +191,37 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
// multiple channel sources handling
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;
sampleFifo->getWriteIterator(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;
// SampleVector::iterator writeBegin;
// sampleFifo->getWriteIterator(writeBegin);
// SampleVector::iterator writeAt = writeBegin;
// Sample s;
// int sourceOccurence = 0;
//
// 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_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
// // Read a chunk of data from the sources
//
// if (sourceOccurence == 0) {
// (*writeAt) = s;
// } else {
// (*writeAt) += s;
// }
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
// {
// ((*it)->getSampleSourceFifo()).readAdvance(m_threadedBasebandSampleSourcesIteratorMap[*it], nbWriteSamples);
// 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
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
// {
// (*it)->pull(s);
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
// // 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;
@ -288,11 +230,80 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
// }
//
// 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;
// }
// }
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
// if (m_spectrumSink)
@ -443,6 +454,16 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoRunning()
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++)
{
qDebug() << "DSPDeviceSinkEngine::gotoRunning: starting " << (*it)->objectName().toStdString().c_str();

View File

@ -22,6 +22,7 @@
#include <QTimer>
#include <QMutex>
#include <QWaitCondition>
#include <stdint.h>
#include <list>
#include <map>
#include "dsp/dsptypes.h"
@ -47,10 +48,10 @@ public:
StError //!< engine is in error
};
DSPDeviceSinkEngine(uint uid, QObject* parent = NULL);
DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL);
~DSPDeviceSinkEngine();
uint getUID() const { return m_uid; }
uint32_t getUID() const { return m_uid; }
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
MessageQueue* getOutputMessageQueue() { return &m_outputMessageQueue; }
@ -80,7 +81,7 @@ public:
QString sinkDeviceDescription(); //!< Return the sink device description
private:
uint m_uid; //!< unique ID
uint32_t m_uid; //!< unique ID
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
MessageQueue m_outputMessageQueue; //<! Output message queue. Listen here.
@ -110,8 +111,9 @@ private:
BasebandSampleSink *m_spectrumSink;
uint m_sampleRate;
uint32_t m_sampleRate;
quint64 m_centerFrequency;
uint32_t m_multipleSourcesDivisionFactor;
void run();
void work(int nbWriteSamples); //!< transfer samples from beseband sources to sink if in running state