From df1e09fdb7c5d5340a11dc4783bc9fb404e7c8b0 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 2 Jan 2018 03:40:55 +0100 Subject: [PATCH] Tx: new handling of multiple channel sources (1) --- sdrbase/dsp/basebandsamplesource.cpp | 2 + sdrbase/dsp/dspdevicesinkengine.cpp | 171 ++++++++------------------- 2 files changed, 53 insertions(+), 120 deletions(-) diff --git a/sdrbase/dsp/basebandsamplesource.cpp b/sdrbase/dsp/basebandsamplesource.cpp index f8de665b8..05166531a 100644 --- a/sdrbase/dsp/basebandsamplesource.cpp +++ b/sdrbase/dsp/basebandsamplesource.cpp @@ -73,10 +73,12 @@ void BasebandSampleSource::setDeviceSampleSourceFifo(SampleSourceFifo *deviceSam if (m_deviceSampleFifo != deviceSampleFifo) { if (m_deviceSampleFifo) { + qDebug("BasebandSampleSource::setDeviceSampleSourceFifo: disconnect device FIFO %p", m_deviceSampleFifo); disconnect(m_deviceSampleFifo, SIGNAL(dataWrite(int)), this, SLOT(handleWriteToDeviceFifo(int))); } if (deviceSampleFifo) { + qDebug("BasebandSampleSource::setDeviceSampleSourceFifo: connect device FIFO %p", deviceSampleFifo); connect(deviceSampleFifo, SIGNAL(dataWrite(int)), this, SLOT(handleWriteToDeviceFifo(int))); } diff --git a/sdrbase/dsp/dspdevicesinkengine.cpp b/sdrbase/dsp/dspdevicesinkengine.cpp index 053a352ec..714698f44 100644 --- a/sdrbase/dsp/dspdevicesinkengine.cpp +++ b/sdrbase/dsp/dspdevicesinkengine.cpp @@ -176,126 +176,44 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples) { // 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; SampleSourceFifo* sampleFifo = m_deviceSampleSink->getSampleFifo(); sampleFifo->getWriteIterator(writeBegin); SampleVector::iterator writeAt = writeBegin; - Sample s; - int sourceOccurence = 0; + std::vector sampleSourceIterators; for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it) { - (*it)->setDeviceSampleSourceFifo(0); - (*it)->pullAudio(nbWriteSamples); + sampleSourceIterators.push_back(SampleVector::iterator()); + (*it)->getSampleSourceFifo().readAdvance(sampleSourceIterators.back(), nbWriteSamples); + sampleSourceIterators.back() -= nbWriteSamples; } for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it) { - (*it)->setDeviceSampleSourceFifo(0); - (*it)->pullAudio(nbWriteSamples); + sampleSourceIterators.push_back(SampleVector::iterator()); + (*it)->getSampleSourceFifo().readAdvance(sampleSourceIterators.back(), nbWriteSamples); + sampleSourceIterators.back() -= 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; + // pull data from sources FIFOs and merge them in the device sample FIFO + for (std::vector::iterator it = sampleSourceIterators.begin(); it != sampleSourceIterators.end(); ++it) + { + Sample s = (**it); + s /= m_multipleSourcesDivisionFactor; + ++(*it); - if (sourceOccurence == 0) { - (*writeAt) = s; - } else { + if (it == sampleSourceIterators.begin()) { + (*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) -// { -// m_spectrumSink->feed(writeBegin, writeBegin + nbWriteSamples, false); -// } } } @@ -446,29 +364,15 @@ 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<objectName().toStdString().c_str(); - // not used with sample by sample processing -// (*it)->getSampleSourceFifo().resize(2*m_deviceSampleSink->getSampleFifo()->size()); // Equalize channel source FIFO size with device sink FIFO size (*it)->start(); } for (ThreadedBasebandSampleSources::const_iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it) { qDebug() << "DSPDeviceSinkEngine::gotoRunning: starting ThreadedSampleSource(" << (*it)->getSampleSourceObjectName().toStdString().c_str() << ")"; - // not used with sample by sample processing -// (*it)->getSampleSourceFifo().resize(2*m_deviceSampleSink->getSampleFifo()->size()); // Equalize channel source FIFO size with device sink FIFO size (*it)->start(); } @@ -497,17 +401,11 @@ void DSPDeviceSinkEngine::handleSetSink(DeviceSampleSink* sink) { gotoIdle(); -// if(m_sampleSource != 0) -// { -// disconnect(m_sampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData())); -// } - m_deviceSampleSink = sink; if(m_deviceSampleSink != 0) { qDebug("DSPDeviceSinkEngine::handleSetSink: set %s", qPrintable(sink->getDeviceDescription())); - connect(m_deviceSampleSink->getSampleFifo(), SIGNAL(dataWrite(int)), this, SLOT(handleData(int)), Qt::QueuedConnection); } else { @@ -582,6 +480,10 @@ void DSPDeviceSinkEngine::handleSynchronousMessages() BasebandSampleSource* source = ((DSPAddBasebandSampleSource*) message)->getSampleSource(); m_basebandSampleSources.push_back(source); checkNumberOfBasebandSources(); + + if (m_state == StRunning) { + source->start(); + } } else if (DSPRemoveBasebandSampleSource::match(*message)) { @@ -599,6 +501,10 @@ void DSPDeviceSinkEngine::handleSynchronousMessages() ThreadedBasebandSampleSource *threadedSource = ((DSPAddThreadedBasebandSampleSource*) message)->getThreadedSampleSource(); m_threadedBasebandSampleSources.push_back(threadedSource); checkNumberOfBasebandSources(); + + if (m_state == StRunning) { + threadedSource->start(); + } } else if (DSPRemoveThreadedBasebandSampleSource::match(*message)) { @@ -679,23 +585,48 @@ void DSPDeviceSinkEngine::checkNumberOfBasebandSources() // single channel source handling if ((m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size()) == 1) { + qDebug("DSPDeviceSinkEngine::checkNumberOfBasebandSources: single channel mode"); + disconnect(sampleFifo, SIGNAL(dataWrite(int)), this, SLOT(handleData(int))); + if (m_threadedBasebandSampleSources.size() == 1) { m_threadedBasebandSampleSources.back()->setDeviceSampleSourceFifo(sampleFifo); } else if (m_basebandSampleSources.size() == 1) { m_threadedBasebandSampleSources.back()->setDeviceSampleSourceFifo(sampleFifo); } + + m_multipleSourcesDivisionFactor = 1; // for consistency but it is not used in this case } // null or multiple channel sources handling else { + int nbSources = 0; + for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it) { (*it)->setDeviceSampleSourceFifo(0); + nbSources++; } for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it) { (*it)->setDeviceSampleSourceFifo(0); + nbSources++; } + + if (nbSources == 0) { + m_multipleSourcesDivisionFactor = 1; + } else if (nbSources < 3) { + m_multipleSourcesDivisionFactor = nbSources; + } else { + m_multipleSourcesDivisionFactor = 1< 1) { + connect(sampleFifo, SIGNAL(dataWrite(int)), this, SLOT(handleData(int)), Qt::QueuedConnection); + } + + qDebug("DSPDeviceSinkEngine::checkNumberOfBasebandSources: handle %d channel(s)", nbSources); } }