From 7bc413f8a90c8172a4dc68293c4ea6bac5c13a55 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 3 Oct 2019 01:19:43 +0200 Subject: [PATCH] Sample MI FIFO fixes --- sdrbase/dsp/dspdevicemimoengine.cpp | 66 +-- sdrbase/dsp/samplemififo.cpp | 609 ++++++++++------------------ sdrbase/dsp/samplemififo.h | 94 +++-- 3 files changed, 308 insertions(+), 461 deletions(-) diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp index cd6d471dc..7652add2f 100644 --- a/sdrbase/dsp/dspdevicemimoengine.cpp +++ b/sdrbase/dsp/dspdevicemimoengine.cpp @@ -243,34 +243,51 @@ void DSPDeviceMIMOEngine::workSampleSinkFifos() return; } - int iPart1Begin; - int iPart1End; - int iPart2Begin; - int iPart2End; - std::vector data = sampleFifo->getData(); + unsigned int iPart1Begin; + unsigned int iPart1End; + unsigned int iPart2Begin; + unsigned int iPart2End; + const std::vector& data = sampleFifo->getData(); + //unsigned int samplesDone = 0; - while (sampleFifo->fillSync() > 0) + while ((sampleFifo->fillSync() > 0) && (m_inputMessageQueue.size() == 0)) { - unsigned int count = sampleFifo->readSync(sampleFifo->fillSync(), iPart1Begin, iPart1End, iPart2Begin, iPart2End); + //unsigned int count = sampleFifo->readSync(sampleFifo->fillSync(), iPart1Begin, iPart1End, iPart2Begin, iPart2End); + sampleFifo->readSync(iPart1Begin, iPart1End, iPart2Begin, iPart2End); - for (unsigned int stream = 0; stream < data.size(); stream++) + if (iPart1Begin != iPart1End) { - SampleVector::const_iterator begin = data[stream].begin(); - - if (iPart1Begin != iPart1End) { - m_vectorBuffer.write(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, false); + for (unsigned int stream = 0; stream < data.size(); stream++) { + workSamples(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, stream); } - - if (iPart2Begin != iPart2End) { - m_vectorBuffer.write(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End); - } - - SampleVector::iterator vbegin, vend; - m_vectorBuffer.read(vbegin, vend); - workSamples(vbegin, vend, stream); } - sampleFifo->readCommitSync(count); + if (iPart2Begin != iPart2End) + { + for (unsigned int stream = 0; stream < data.size(); stream++) { + workSamples(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End, stream); + } + } + + // for (unsigned int stream = 0; stream < data.size(); stream++) + // { + // SampleVector::const_iterator begin = data[stream].begin(); + + // if (iPart1Begin != iPart1End) { + // m_vectorBuffer.write(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, false); + // } + + // if (iPart2Begin != iPart2End) { + // m_vectorBuffer.write(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End, false); + // } + + // SampleVector::iterator vbegin, vend; + // m_vectorBuffer.read(vbegin, vend); + // workSamples(vbegin, vend, stream); + // } + + //sampleFifo->readCommitSync(count); + //samplesDone += count; } } @@ -287,9 +304,10 @@ void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int stream) SampleVector::const_iterator part2begin; SampleVector::const_iterator part2end; - while (sampleFifo->fillAsync(stream) > 0) + while ((sampleFifo->fillAsync(stream) > 0) && (m_inputMessageQueue.size() == 0)) { - unsigned int count = sampleFifo->readAsync(sampleFifo->fillAsync(stream), &part1begin, &part1end, &part2begin, &part2end, stream); + //unsigned int count = sampleFifo->readAsync(sampleFifo->fillAsync(stream), &part1begin, &part1end, &part2begin, &part2end, stream); + sampleFifo->readAsync(&part1begin, &part1end, &part2begin, &part2end, stream); if (part1begin != part1end) { // first part of FIFO data m_vectorBuffer.write(part1begin, part1end, false); @@ -303,7 +321,7 @@ void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int stream) m_vectorBuffer.read(vbegin, vend); workSamples(vbegin, vend, stream); - sampleFifo->readCommitAsync(count, stream); + //sampleFifo->readCommitAsync(count, stream); } } diff --git a/sdrbase/dsp/samplemififo.cpp b/sdrbase/dsp/samplemififo.cpp index c27cd79b5..3d1d792ce 100644 --- a/sdrbase/dsp/samplemififo.cpp +++ b/sdrbase/dsp/samplemififo.cpp @@ -17,494 +17,325 @@ #include "samplemififo.h" -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) - void SampleMIFifo::init(unsigned int nbStreams, unsigned int size) { m_nbStreams = nbStreams; m_size = size; m_fill = 0; m_head = 0; - m_tail = 0; - m_data.resize(nbStreams); - m_vfill.resize(nbStreams); - m_vhead.resize(nbStreams); - m_vtail.resize(nbStreams); + m_data.resize(nbStreams); + m_vFill.clear(); + m_vHead.clear(); for (unsigned int stream = 0; stream < nbStreams; stream++) { m_data[stream].resize(size); - m_vfill[stream] = 0; - m_vhead[stream] = 0; - m_vtail[stream] = 0; + m_vFill.push_back(0); + m_vHead.push_back(0); } } -SampleMIFifo::SampleMIFifo(QObject* parent) : - QObject(parent) +void SampleMIFifo::reset() { - m_suppressed = -1; - m_size = 0; + QMutexLocker mutexLocker(&m_mutex); m_fill = 0; m_head = 0; - m_tail = 0; -} - -SampleMIFifo::SampleMIFifo(unsigned int nbStreams, unsigned int size, QObject* parent) : - QObject(parent) -{ - init(nbStreams, size); - - m_suppressed = -1; - - for (unsigned int stream = 0; stream < nbStreams; stream++) + for (unsigned int stream = 0; stream < m_nbStreams; stream++) { - m_vsuppressed[stream] = -1; - m_vmsgRateTimer.push_back(QTime()); + m_vFill[stream] = 0; + m_vHead[stream] = 0; } } -unsigned int SampleMIFifo::writeSync(const quint8* data, unsigned int count) +SampleMIFifo::SampleMIFifo(QObject *parent) : + QObject(parent), + m_nbStreams(0), + m_size(0), + m_fill(0), + m_head(0) { - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - unsigned int byteCount = count; - count /= sizeof(Sample); +} - total = std::min(count, m_size - m_fill); +SampleMIFifo::SampleMIFifo(unsigned int nbStreams, unsigned int size, QObject *parent) : + QObject(parent) +{ + init(nbStreams, size); +} - if (total < count) +void SampleMIFifo::writeSync(const quint8* data, unsigned int count) +{ + QMutexLocker mutexLocker(&m_mutex); + unsigned int spaceLeft = m_size - m_fill; + unsigned int size = count / sizeof(Sample); + + for (unsigned int stream = 0; stream < m_data.size(); stream++) { - if (m_suppressed < 0) + if (size < spaceLeft) { - m_suppressed = 0; - m_msgRateTimer.start(); - qCritical("SampleMIFifo: overflow - dropping %u samples", count - total); - } + std::copy(&data[stream*count], &data[stream*count] + count, m_data[stream].begin() + m_fill); + m_fill += size; + } else { - if (m_msgRateTimer.elapsed() > 2500) - { - qCritical("SampleMIFifo: %u messages dropped", m_suppressed); - qCritical("SampleMIFifo: overflow - dropping %u samples", count - total); - m_suppressed = -1; - } - else - { - m_suppressed++; - } - } - } - - remaining = total; - std::vector vbegin; - vbegin.resize(m_nbStreams); - - for (unsigned int stream = 0; stream < m_nbStreams; stream++) { - vbegin[stream] = (const Sample*) &data[stream*byteCount]; - } - - while (remaining > 0) - { - len = std::min(remaining, m_size - m_tail); - - for (unsigned int stream = 0; stream < m_nbStreams; stream++) - { - std::copy(vbegin[stream], vbegin[stream] + len, m_data[stream].begin() + m_tail); - vbegin[stream] += len; + unsigned int remaining = size - spaceLeft; + unsigned int bytesLeft = spaceLeft*sizeof(Sample); + std::copy(&data[stream*count], &data[stream*count] + bytesLeft, m_data[stream].begin() + m_fill); + std::copy(&data[stream*count] + bytesLeft, &data[stream*count] + count, m_data[stream].begin()); + m_fill = remaining; } - - m_tail += len; - m_tail %= m_size; - m_fill += len; - remaining -= len; - } - - if (m_fill > 0) { - emit dataSyncReady(); } - return total; + emit dataSyncReady(); } -unsigned int SampleMIFifo::writeSync(std::vector vbegin, unsigned int count) +void SampleMIFifo::writeSync(const std::vector& vbegin, unsigned int size) { - if ((vbegin.size() != m_nbStreams)) { - return 0; + if ((m_data.size() == 0) || (m_data.size() != vbegin.size())) { + return; } - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; + QMutexLocker mutexLocker(&m_mutex); + unsigned int spaceLeft = m_size - m_fill; - total = std::min(count, m_size - m_fill); - - if (total < count) + if (size < spaceLeft) { - if (m_suppressed < 0) - { - m_suppressed = 0; - m_msgRateTimer.start(); - qCritical("SampleMIFifo::writeSync: overflow - dropping %u samples", count - total); - } - else - { - if (m_msgRateTimer.elapsed() > 2500) - { - qCritical("SampleMIFifo::writeSync: %u messages dropped", m_suppressed); - qCritical("SampleMIFifo::writeSync: overflow - dropping %u samples", count - total); - m_suppressed = -1; - } - else - { - m_suppressed++; - } - } - } - - remaining = total; - - while (remaining > 0) - { - len = std::min(remaining, m_size - m_tail); - - for (unsigned int stream = 0; stream < m_nbStreams; stream++) - { - std::copy(vbegin[stream], vbegin[stream] + len, m_data[stream].begin() + m_tail); - vbegin[stream] += len; + for (unsigned int stream = 0; stream < m_data.size(); stream++) { + std::copy(vbegin[stream], vbegin[stream] + size, m_data[stream].begin() + m_fill); } - m_tail += len; - m_tail %= m_size; - m_fill += len; - remaining -= len; - } + m_fill += size; + } + else + { + unsigned int remaining = size - spaceLeft; - if (m_fill > 0) { - emit dataSyncReady(); + for (unsigned int stream = 0; stream < m_data.size(); stream++) + { + std::copy(vbegin[stream], vbegin[stream] + spaceLeft, m_data[stream].begin() + m_fill); + std::copy(vbegin[stream] + spaceLeft, vbegin[stream] + size, m_data[stream].begin()); + } + + m_fill = remaining; } - return total; + emit dataSyncReady(); } -unsigned int SampleMIFifo::readSync(unsigned int count, +void SampleMIFifo::readSync( std::vector vpart1Begin, std::vector vpart1End, - std::vector vpart2Begin, std::vector vpart2End) + std::vector vpart2Begin, std::vector vpart2End +) { - if ((vpart1Begin.size() != m_nbStreams) - || (vpart2Begin.size() != m_nbStreams) - || (vpart1End.size() != m_nbStreams) - || (vpart2End.size() != m_nbStreams)) - { - return 0; + if (m_data.size() == 0) { + return; } - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - unsigned int head = m_head; + QMutexLocker mutexLocker(&m_mutex); + std::vector::iterator dataIt = m_data.begin(); + vpart1Begin.resize(m_nbStreams); + vpart1End.resize(m_nbStreams); + vpart2Begin.resize(m_nbStreams); + vpart2End.resize(m_nbStreams); - total = std::min(count, m_fill); - - if (total < count) { - qCritical("SampleMIFifo::readSync: underflow - missing %u samples", count - total); - } - - remaining = total; - - if (remaining > 0) + if (m_head < m_fill) { - len = std::min(remaining, m_size - head); - - for (unsigned int stream = 0; stream < m_nbStreams; stream++) - { - *vpart1Begin[stream] = m_data[stream].begin() + head; - *vpart1End[stream] = m_data[stream].begin() + head + len; - } - - head += len; - head %= m_size; - remaining -= len; - } - else - { - for (unsigned int stream = 0; stream < m_nbStreams; stream++) - { - *vpart1Begin[stream] = m_data[stream].end(); - *vpart1End[stream] = m_data[stream].end(); - } - } - - if (remaining > 0) - { - len = std::min(remaining, m_size - head); - - for (unsigned int stream = 0; stream < m_nbStreams; stream++) - { - *vpart2Begin[stream] = m_data[stream].begin() + head; - *vpart2End[stream] = m_data[stream].begin() + head + len; - } - } - else - { - for (unsigned int stream = 0; stream < m_nbStreams; stream++) + for (unsigned int stream = 0; stream < m_data.size(); stream++) { + *vpart1Begin[stream] = m_data[stream].begin() + m_head; + *vpart1End[stream] = m_data[stream].begin() + m_fill; *vpart2Begin[stream] = m_data[stream].end(); *vpart2End[stream] = m_data[stream].end(); } - } - - return total; -} - -unsigned int SampleMIFifo::readSync(unsigned int count, - int& ipart1Begin, int& ipart1End, - int& ipart2Begin, int& ipart2End) -{ - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - unsigned int head = m_head; - - total = std::min(count, m_fill); - - if (total < count) { - qCritical("SampleMIFifo::readSync: underflow - missing %u samples", count - total); } - - remaining = total; - - if (remaining > 0) - { - len = std::min(remaining, m_size - head); - ipart1Begin = head; - ipart1End =head + len; - head += len; - head %= m_size; - remaining -= len; - } else { - ipart1Begin = m_size; - ipart1End = m_size; - } + for (unsigned int stream = 0; stream < m_data.size(); stream++) + { + *vpart1Begin[stream] = m_data[stream].begin() + m_head; + *vpart1End[stream] = m_data[stream].end(); + *vpart2Begin[stream] = m_data[stream].begin(); + *vpart2End[stream] = m_data[stream].begin() + m_fill; + } + } - if (remaining > 0) + m_head = m_fill; +} + +void SampleMIFifo::readSync( + std::vector& vpart1Begin, std::vector& vpart1End, + std::vector& vpart2Begin, std::vector& vpart2End +) +{ + if (m_data.size() == 0) { + return; + } + + QMutexLocker mutexLocker(&m_mutex); + std::vector::iterator dataIt = m_data.begin(); + vpart1Begin.resize(m_nbStreams); + vpart1End.resize(m_nbStreams); + vpart2Begin.resize(m_nbStreams); + vpart2End.resize(m_nbStreams); + + + if (m_head < m_fill) { - len = std::min(remaining, m_size - head); - ipart2Begin = head; - ipart2End = head + len; - } + for (unsigned int stream = 0; stream < m_data.size(); stream++) + { + vpart1Begin[stream] = m_head; + vpart1End[stream] = m_fill; + vpart2Begin[stream] = 0; + vpart2End[stream] = 0; + } + } else { - ipart2Begin = m_size; - ipart2End = m_size; - } + for (unsigned int stream = 0; stream < m_data.size(); stream++) + { + vpart1Begin[stream] = m_head; + vpart1End[stream] = m_size; + vpart2Begin[stream] = 0; + vpart2End[stream] = m_fill; + } + } - return total; + m_head = m_fill; } -unsigned int SampleMIFifo::readCommitSync(unsigned int count) +void SampleMIFifo::readSync( + unsigned int& ipart1Begin, unsigned int& ipart1End, + unsigned int& ipart2Begin, unsigned int& ipart2End +) { - QMutexLocker mutexLocker(&m_mutex); + if (m_data.size() == 0) { + return; + } - if (count > m_fill) + if (m_head < m_fill) { - qCritical("SampleMIFifo::readCommitSync: cannot commit more than available samples"); - count = m_fill; - } + ipart1Begin = m_head; + ipart1End = m_fill; + ipart2Begin = 0; + ipart2End = 0; + } + else + { + ipart1Begin = m_head; + ipart1End = m_size; + ipart2Begin = 0; + ipart2End = m_fill; + } - m_head = (m_head + count) % m_size; - m_fill -= count; - - return count; + m_head = m_fill; } -unsigned int SampleMIFifo::writeAsync(const quint8* data, unsigned int count, unsigned int stream) +void SampleMIFifo::writeAsync(const quint8* data, unsigned int count, unsigned int stream) { if (stream >= m_nbStreams) { - return 0; + return; } - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - const Sample* begin = (const Sample*) data; - count /= sizeof(Sample); - total = std::min(count, m_size - m_vfill[stream]); + QMutexLocker mutexLocker(&m_mutex); + unsigned int spaceLeft = m_size - m_vFill[stream]; + unsigned int size = count / sizeof(Sample); - if (total < count) + if (size < spaceLeft) { - if (m_vsuppressed[stream] < 0) - { - m_vsuppressed[stream] = 0; - m_msgRateTimer.start(); - qCritical("SampleSinkFifo::writeAsync[%u]: overflow - dropping %u samples", stream, count - total); - } - else - { - if (m_msgRateTimer.elapsed() > 2500) - { - qCritical("SampleSinkFifo::writeAsync[%u]: %u messages dropped", stream, m_vsuppressed[stream]); - qCritical("SampleSinkFifo::writeAsync[%u]: overflow - dropping %u samples", stream, count - total); - m_vsuppressed[stream] = -1; - } - else - { - m_vsuppressed[stream]++; - } - } - } - - remaining = total; - - while (remaining > 0) + std::copy(&data[stream*count], &data[stream*count] + count, m_data[stream].begin() + m_vFill[stream]); + m_vFill[stream] += size; + } + else { - len = std::min(remaining, m_size - m_vtail[stream]); - std::copy(begin, begin + len, m_data[stream].begin() + m_vtail[stream]); - begin += len; - m_vtail[stream] += len; - m_vtail[stream] %= m_size; - m_vfill[stream] += len; - remaining -= len; - } - - if (m_vfill[stream] > 0) { - emit dataAsyncReady(stream); + unsigned int remaining = size - spaceLeft; + unsigned int bytesLeft = spaceLeft * sizeof(Sample); + std::copy(&data[stream*count], &data[stream*count] + bytesLeft, m_data[stream].begin() + m_vFill[stream]); + std::copy(&data[stream*count] + bytesLeft, &data[stream*count] + count, m_data[stream].begin()); + m_vFill[stream] = remaining; } - return total; + emit dataAsyncReady(stream); } -unsigned int SampleMIFifo::writeAsync(SampleVector::const_iterator begin, unsigned int count, unsigned int stream) +void SampleMIFifo::writeAsync(const SampleVector::const_iterator& begin, unsigned int size, unsigned int stream) { if (stream >= m_nbStreams) { - return 0; + return; } - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - total = std::min(count, m_size - m_vfill[stream]); + QMutexLocker mutexLocker(&m_mutex); + int spaceLeft = m_data[stream].size() - m_vFill[stream]; - if (total < count) + if (size < spaceLeft) { - if (m_vsuppressed[stream] < 0) - { - m_vsuppressed[stream] = 0; - m_vmsgRateTimer[stream].start(); - qCritical("SampleSinkFifo::writeAsync[%u]: overflow - dropping %u samples", stream, count - total); - } - else - { - if (m_vmsgRateTimer[stream].elapsed() > 2500) - { - qCritical("SampleSinkFifo::writeAsync[%u]: %u messages dropped", stream, m_vsuppressed[stream]); - qCritical("SampleSinkFifo::writeAsync[%u]: overflow - dropping %u samples", stream, count - total); - m_vsuppressed[stream] = -1; - } - else - { - m_vsuppressed[stream]++; - } - } - } - - remaining = total; - - while (remaining > 0) + std::copy(begin, begin + size, m_data[stream].begin() + m_vFill[stream]); + m_vFill[stream] += size; + } + else { - len = std::min(remaining, m_size - m_vtail[stream]); - std::copy(begin, begin + len, m_data[stream].begin() + m_vtail[stream]); - begin += len; - m_vtail[stream] += len; - m_vtail[stream] %= m_size; - m_vfill[stream] += len; - remaining -= len; - } - - if (m_vfill[stream] > 0) { - emit dataAsyncReady(stream); + int remaining = size - spaceLeft; + std::copy(begin, begin + spaceLeft, m_data[stream].begin() + m_vFill[stream]); + std::copy(begin + spaceLeft, begin + size, m_data[stream].begin()); + m_vFill[stream] = remaining; } - return total; + emit dataAsyncReady(stream); } -unsigned int SampleMIFifo::readAsync(unsigned int count, - SampleVector::const_iterator* part1Begin, SampleVector::const_iterator* part1End, - SampleVector::const_iterator* part2Begin, SampleVector::const_iterator* part2End, + +void SampleMIFifo::readAsync( + SampleVector::const_iterator* part1Begin, SampleVector::const_iterator* part1End, + SampleVector::const_iterator* part2Begin, SampleVector::const_iterator* part2End, + unsigned int stream) +{ + if (stream >= m_data.size()) { + return; + } + + QMutexLocker mutexLocker(&m_mutex); + + if (m_vHead[stream] < m_vFill[stream]) + { + *part1Begin = m_data[stream].begin() + m_vHead[stream]; + *part1End = m_data[stream].begin() + m_vFill[stream]; + *part2Begin = m_data[stream].begin(); + *part2End = m_data[stream].begin(); + } + else + { + *part1Begin = m_data[stream].begin() + m_vHead[stream]; + *part1End = m_data[stream].end(); + *part2Begin = m_data[stream].begin(); + *part2End = m_data[stream].begin() + m_vFill[stream]; + } + + m_vHead[stream] = m_vFill[stream]; +} + +void SampleMIFifo::readAsync( + unsigned int& ipart1Begin, unsigned int& ipart1End, + unsigned int& ipart2Begin, unsigned int& ipart2End, unsigned int stream) { - if (stream >= m_nbStreams) { - return 0; + if (stream >= m_data.size()) { + return; } - QMutexLocker mutexLocker(&m_mutex); - unsigned int total; - unsigned int remaining; - unsigned int len; - unsigned int head = m_vhead[stream]; - total = std::min(count, m_vfill[stream]); + QMutexLocker mutexLocker(&m_mutex); - if (total < count) { - qCritical("SampleSinkFifo::readAsync[%u]: underflow - missing %u samples", stream, count - total); - } - - remaining = total; - - if (remaining > 0) + if (m_vHead[stream] < m_vFill[stream]) { - len = std::min(remaining, m_size - head); - *part1Begin = m_data[stream].begin() + head; - *part1End = m_data[stream].begin() + head + len; - head += len; - head %= m_size; - remaining -= len; - } + ipart1Begin = m_vHead[stream]; + ipart1End = m_vFill[stream]; + ipart2Begin = m_size; + ipart2End = m_size; + } else { - *part1Begin = m_data[stream].end(); - *part1End = m_data[stream].end(); - } - - if (remaining > 0) - { - len = std::min(remaining, m_size - head); - *part2Begin = m_data[stream].begin() + head; - *part2End = m_data[stream].begin() + head + len; - } - else - { - *part2Begin = m_data[stream].end(); - *part2End = m_data[stream].end(); - } - - return total; -} - -unsigned int SampleMIFifo::readCommitAsync(unsigned int count, unsigned int stream) -{ - if (stream >= m_nbStreams) { - return 0; + ipart1Begin = m_vHead[stream]; + ipart1End = m_size; + ipart2Begin = 0; + ipart2End = m_vFill[stream]; } - QMutexLocker mutexLocker(&m_mutex); - - if (count > m_vfill[stream]) - { - qCritical("SampleSinkFifo::readCommitAsync[%u]: cannot commit more than available samples", stream); - count = m_vfill[stream]; - } - - m_vhead[stream] = (m_vhead[stream] + count) % m_size; - m_vfill[stream] -= count; - - return count; -} + m_vHead[stream] = m_vFill[stream]; +} \ No newline at end of file diff --git a/sdrbase/dsp/samplemififo.h b/sdrbase/dsp/samplemififo.h index e542ca9ef..e2e9f8043 100644 --- a/sdrbase/dsp/samplemififo.h +++ b/sdrbase/dsp/samplemififo.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include "dsp/dsptypes.h" #include "export.h" @@ -28,16 +28,46 @@ class SDRBASE_API SampleMIFifo : public QObject { Q_OBJECT public: - SampleMIFifo(QObject* parent = nullptr); - SampleMIFifo(unsigned int nbStreams, unsigned int size, QObject* parent = nullptr); + SampleMIFifo(QObject *parent = nullptr); + SampleMIFifo(unsigned int nbStreams, unsigned int size, QObject *parent = nullptr); + void init(unsigned int nbStreams, unsigned int size); + void reset(); - void init(unsigned int nbStreams, unsigned int size); - inline unsigned int size() const { return m_size; } + void writeSync(const quint8* data, unsigned int count); //!< de-interleaved data in input with count bytes for each stream + void writeSync(const std::vector& vbegin, unsigned int size); + void readSync( + std::vector vpart1Begin, std::vector vpart1End, + std::vector vpart2Begin, std::vector vpart2End + ); + void readSync( + std::vector& vPart1Begin, std::vector& vPart1End, + std::vector& vPart2Begin, std::vector& vPart2End + ); + void readSync( + unsigned int& ipart1Begin, unsigned int& ipart1End, + unsigned int& ipart2Begin, unsigned int& ipart2End + ); + + void writeAsync(const quint8* data, unsigned int count, unsigned int stream); + void writeAsync(const SampleVector::const_iterator& begin, unsigned int size, unsigned int stream); + void readAsync( + SampleVector::const_iterator* part1Begin, SampleVector::const_iterator* part1End, + SampleVector::const_iterator* part2Begin, SampleVector::const_iterator* part2End, + unsigned int stream); + void readAsync( + unsigned int& ipart1Begin, unsigned int& ipart1End, + unsigned int& ipart2Begin, unsigned int& ipart2End, + unsigned int stream); + + + const std::vector& getData() { return m_data; } + const SampleVector& getData(unsigned int stream) { return m_data[stream]; } + unsigned int getNbStreams() const { return m_data.size(); } inline unsigned int fillSync() { QMutexLocker mutexLocker(&m_mutex); - unsigned int fill = m_fill; + unsigned int fill = m_head <= m_fill ? m_fill - m_head : m_size - (m_head - m_fill); return fill; } @@ -48,55 +78,23 @@ public: } QMutexLocker mutexLocker(&m_mutex); - unsigned int fill = m_vfill[stream]; + unsigned int fill = m_vHead[stream] <= m_vFill[stream] ? m_vFill[stream] - m_vHead[stream] : m_size - (m_vHead[stream] - m_vFill[stream]); return fill; } - const std::vector& getData() { return m_data; } - unsigned int getNbStreams() const { return m_nbStreams; } - - unsigned int writeSync(const quint8* data, unsigned int count); //!< de-interleaved data in input with count bytes for each stream - unsigned int writeSync(std::vector vbegin, unsigned int count); - unsigned int readSync(unsigned int count, - std::vector vpart1Begin, std::vector vpart1End, - std::vector vpart2Begin, std::vector vpart2End); - unsigned int readSync(unsigned int count, - int& ipart1Begin, int& ipart1End, - int& ipart2Begin, int& ipart2End); - unsigned int readCommitSync(unsigned int count); - - unsigned int writeAsync(const quint8* data, unsigned int count, unsigned int stream); - unsigned int writeAsync(SampleVector::const_iterator begin, unsigned int count, unsigned int stream); - unsigned int readAsync(unsigned int count, - SampleVector::const_iterator* part1Begin, SampleVector::const_iterator* part1End, - SampleVector::const_iterator* part2Begin, SampleVector::const_iterator* part2End, - unsigned int stream); - unsigned int readCommitAsync(unsigned int count, unsigned int stream); - signals: void dataSyncReady(); - void dataAsyncReady(int streamIndex); + void dataAsyncReady(int streamIndex); private: - QMutex m_mutex; - - std::vector m_data; + std::vector m_data; unsigned int m_nbStreams; - unsigned int m_size; - - // Synchronous - int m_suppressed; - QTime m_msgRateTimer; - unsigned int m_fill; - unsigned int m_head; - unsigned int m_tail; - - // Asynchronous - std::vector m_vsuppressed; - std::vector m_vmsgRateTimer; - std::vector m_vfill; - std::vector m_vhead; - std::vector m_vtail; + unsigned int m_size; + unsigned int m_fill; //!< Number of samples written from beginning of samples vector (sync) + unsigned int m_head; //!< Number of samples read from beginning of samples vector (sync) + std::vector m_vFill; //!< Number of samples written from beginning of samples vector (async) + std::vector m_vHead; //!< Number of samples read from beginning of samples vector (async) + QMutex m_mutex; }; -#endif // INCLUDE_SAMPLEMIFIFO_H +#endif // INCLUDE_SAMPLEMIFIFO_H \ No newline at end of file