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 "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();

View File

@ -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