1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-07 16:34:45 -04:00

MIMO: device engine Tx handling (1)

This commit is contained in:
f4exb
2019-10-19 05:07:24 +02:00
parent 1171d71c87
commit 7a1b727a36
6 changed files with 214 additions and 14 deletions
+132 -11
View File
@@ -258,20 +258,42 @@ void DSPDeviceMIMOEngine::workSampleSinkFifos()
if (iPart1Begin != iPart1End)
{
for (unsigned int stream = 0; stream < data.size(); stream++) {
workSamples(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, stream);
workSamplesSink(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, stream);
}
}
if (iPart2Begin != iPart2End)
{
for (unsigned int stream = 0; stream < data.size(); stream++) {
workSamples(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End, stream);
workSamplesSink(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End, stream);
}
}
}
}
void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int stream)
void DSPDeviceMIMOEngine::workSampleSourceFifos()
{
SampleMOFifo* sampleFifo = m_deviceSampleMIMO->getSampleMOFifo();
if (!sampleFifo) {
return;
}
std::vector<SampleVector::const_iterator> vbegin;
vbegin.resize(sampleFifo->getNbStreams());
while ((sampleFifo->remainderSync() > 0) && (m_inputMessageQueue.size() == 0))
{
// pull remainderSync() samples from the sources by stream
for (unsigned int streamIndex = 0; streamIndex < sampleFifo->getNbStreams(); streamIndex++) {
workSamplesSource(vbegin[streamIndex], sampleFifo->remainderSync(), streamIndex);
}
// write pulled samples to FIFO
sampleFifo->writeSync(vbegin, sampleFifo->remainderSync());
}
}
void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int streamIndex)
{
SampleMIFifo* sampleFifo = m_deviceSampleMIMO->getSampleMIFifo();
@@ -284,26 +306,46 @@ void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int stream)
SampleVector::const_iterator part2begin;
SampleVector::const_iterator part2end;
while ((sampleFifo->fillAsync(stream) > 0) && (m_inputMessageQueue.size() == 0))
while ((sampleFifo->fillAsync(streamIndex) > 0) && (m_inputMessageQueue.size() == 0))
{
//unsigned int count = sampleFifo->readAsync(sampleFifo->fillAsync(stream), &part1begin, &part1end, &part2begin, &part2end, stream);
sampleFifo->readAsync(&part1begin, &part1end, &part2begin, &part2end, stream);
sampleFifo->readAsync(&part1begin, &part1end, &part2begin, &part2end, streamIndex);
if (part1begin != part1end) { // first part of FIFO data
workSamples(part1begin, part1end, stream);
workSamplesSink(part1begin, part1end, streamIndex);
}
if (part2begin != part2end) { // second part of FIFO data (used when block wraps around)
workSamples(part2begin, part2end, stream);
workSamplesSink(part2begin, part2end, streamIndex);
}
}
}
void DSPDeviceMIMOEngine::workSampleSourceFifo(unsigned int streamIndex)
{
SampleMOFifo* sampleFifo = m_deviceSampleMIMO->getSampleMOFifo();
if (!sampleFifo) {
return;
}
SampleVector::const_iterator begin;
while ((sampleFifo->remainderAsync(streamIndex) > 0) && (m_inputMessageQueue.size() == 0))
{
// pull remainderAsync() samples from the sources stream
workSamplesSource(begin, sampleFifo->remainderAsync(streamIndex), streamIndex);
// write pulled samples to FIFO's corresponding stream
sampleFifo->writeAsync(begin, sampleFifo->remainderAsync(streamIndex), streamIndex);
}
}
/**
* Routes samples from device source FIFO to sink channels that are registered for the FIFO
* Routes samples from source channels registered for the FIFO to the device sink FIFO
*/
void DSPDeviceMIMOEngine::workSamples(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int sinkIndex)
void DSPDeviceMIMOEngine::workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int sinkIndex)
{
bool positiveOnly = false;
// DC and IQ corrections
@@ -336,6 +378,55 @@ void DSPDeviceMIMOEngine::workSamples(const SampleVector::const_iterator& vbegin
}
}
void DSPDeviceMIMOEngine::workSamplesSource(SampleVector::const_iterator& begin, unsigned int nbSamples, unsigned int streamIndex)
{
if (m_threadedBasebandSampleSources[streamIndex].size() == 0)
{
m_sourceSampleBuffers[streamIndex].allocate(nbSamples);
std::fill(
m_sourceSampleBuffers[streamIndex].m_vector.begin(),
m_sourceSampleBuffers[streamIndex].m_vector.begin()+nbSamples,
Sample{0,0}
);
begin = m_sourceSampleBuffers[streamIndex].m_vector.begin();
}
else if (m_threadedBasebandSampleSources[streamIndex].size() == 1)
{
ThreadedBasebandSampleSource *sampleSource = m_threadedBasebandSampleSources[streamIndex].front();
sampleSource->getSampleSourceFifo().readAdvance(begin, nbSamples);
begin -= nbSamples;
}
else
{
SampleVector::const_iterator sourceBegin;
ThreadedBasebandSampleSources::const_iterator it = m_threadedBasebandSampleSources[streamIndex].begin();
ThreadedBasebandSampleSource *sampleSource = *it;
sampleSource->getSampleSourceFifo().readAdvance(sourceBegin, nbSamples);
sourceBegin -= nbSamples;
m_sourceSampleBuffers[streamIndex].allocate(nbSamples);
std::copy(sourceBegin, sourceBegin + nbSamples, m_sourceSampleBuffers[streamIndex].m_vector.begin());
++it;
for (; it != m_threadedBasebandSampleSources[streamIndex].end(); ++it)
{
sampleSource = *it;
sampleSource->getSampleSourceFifo().readAdvance(sourceBegin, nbSamples);
sourceBegin -= nbSamples;
std::transform(
m_sourceSampleBuffers[streamIndex].m_vector.begin(),
m_sourceSampleBuffers[streamIndex].m_vector.begin() + nbSamples,
sourceBegin,
m_sourceSampleBuffers[streamIndex].m_vector.begin(),
[](Sample& a, const Sample& b) -> Sample {
return Sample{a.real()+b.real(), a.imag()+b.imag()};
}
);
}
begin = m_sourceSampleBuffers[streamIndex].m_vector.begin();
}
}
// notStarted -> idle -> init -> running -+
// ^ |
// +-----------------------+
@@ -589,10 +680,24 @@ void DSPDeviceMIMOEngine::handleDataRxSync()
}
}
void DSPDeviceMIMOEngine::handleDataRxAsync(int sinkIndex)
void DSPDeviceMIMOEngine::handleDataRxAsync(int streamIndex)
{
if (m_state == StRunning) {
workSampleSinkFifo(sinkIndex);
workSampleSinkFifo(streamIndex);
}
}
void DSPDeviceMIMOEngine::handleDataTxSync()
{
if (m_state == StRunning) {
workSampleSourceFifos();
}
}
void DSPDeviceMIMOEngine::handleDataTxAsync(int streamIndex)
{
if (m_state == StRunning) {
workSampleSourceFifo(streamIndex);
}
}
@@ -611,8 +716,10 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo)
m_sourcesCorrections.push_back(SourceCorrection());
}
for (int i = 0; i < m_deviceSampleMIMO->getNbSourceFifos(); i++) {
for (int i = 0; i < m_deviceSampleMIMO->getNbSourceFifos(); i++)
{
m_threadedBasebandSampleSources.push_back(ThreadedBasebandSampleSources());
m_sourceSampleBuffers.push_back(IncrementalVector<Sample>());
}
if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOHalfSynchronous) // synchronous FIFOs on Rx and not with Tx
@@ -626,6 +733,13 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo)
&DSPDeviceMIMOEngine::handleDataRxSync,
Qt::QueuedConnection
);
QObject::connect(
m_deviceSampleMIMO->getSampleMOFifo(),
&SampleMOFifo::dataSyncRead,
this,
&DSPDeviceMIMOEngine::handleDataTxSync,
Qt::QueuedConnection
);
}
else if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOAsynchronous) // asynchronous FIFOs
{
@@ -640,6 +754,13 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo)
&DSPDeviceMIMOEngine::handleDataRxAsync,
Qt::QueuedConnection
);
QObject::connect(
m_deviceSampleMIMO->getSampleMOFifo(),
&SampleMOFifo::dataAsyncRead,
this,
&DSPDeviceMIMOEngine::handleDataTxAsync,
Qt::QueuedConnection
);
// QObject::connect(
// m_deviceSampleMIMO->getSampleSinkFifo(stream),
// &SampleSinkFifo::dataReady,