From 705ed9d0e3397f9dcc57d1f934f6b79efb430866 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 16 Jul 2020 16:57:51 +0200 Subject: [PATCH] Added a simple circular sample FIFO --- sdrbase/CMakeLists.txt | 2 + sdrbase/dsp/samplesimplefifo.cpp | 157 +++++++++++++++++++++++++++++++ sdrbase/dsp/samplesimplefifo.h | 50 ++++++++++ 3 files changed, 209 insertions(+) create mode 100644 sdrbase/dsp/samplesimplefifo.cpp create mode 100644 sdrbase/dsp/samplesimplefifo.h diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 0cb40c14b..5a5f0642c 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -115,6 +115,7 @@ set(sdrbase_SOURCES dsp/samplemififo.cpp dsp/samplemofifo.cpp dsp/samplesinkfifo.cpp + dsp/samplesimplefifo.cpp dsp/samplesourcefifo.cpp dsp/samplesourcefifodb.cpp dsp/basebandsamplesink.cpp @@ -261,6 +262,7 @@ set(sdrbase_HEADERS dsp/samplemififo.h dsp/samplemofifo.h dsp/samplesinkfifo.h + dsp/samplesimplefifo.h dsp/samplesourcefifo.h dsp/samplesourcefifodb.h dsp/basebandsamplesink.h diff --git a/sdrbase/dsp/samplesimplefifo.cpp b/sdrbase/dsp/samplesimplefifo.cpp new file mode 100644 index 000000000..45af40f2e --- /dev/null +++ b/sdrbase/dsp/samplesimplefifo.cpp @@ -0,0 +1,157 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "samplesimplefifo.h" + +void SampleSimpleFifo::create(unsigned int s) +{ + m_size = 0; + m_fill = 0; + m_head = 0; + m_tail = 0; + + m_data.resize(s); + m_size = m_data.size(); +} + +void SampleSimpleFifo::reset() +{ + m_fill = 0; + m_head = 0; + m_tail = 0; +} + +SampleSimpleFifo::SampleSimpleFifo() : + m_data() +{ + m_size = 0; + m_fill = 0; + m_head = 0; + m_tail = 0; +} + +SampleSimpleFifo::SampleSimpleFifo(int size) : + m_data() +{ + create(size); +} + +SampleSimpleFifo::SampleSimpleFifo(const SampleSimpleFifo& other) : + m_data(other.m_data) +{ + m_size = m_data.size(); + m_fill = 0; + m_head = 0; + m_tail = 0; +} + +SampleSimpleFifo::~SampleSimpleFifo() +{ + m_size = 0; +} + +bool SampleSimpleFifo::setSize(int size) +{ + create(size); + return m_data.size() == (unsigned int) size; +} + +unsigned int SampleSimpleFifo::write(SampleVector::const_iterator begin, SampleVector::const_iterator end) +{ + unsigned int count = end - begin; + unsigned int total; + unsigned int remaining; + unsigned int len; + + total = count; + remaining = total; + + while (remaining > 0) + { + len = std::min(remaining, m_size - m_tail); + std::copy(begin, begin + len, m_data.begin() + m_tail); + m_tail += len; + m_tail %= m_size; + m_fill += len; + begin += len; + remaining -= len; + } + + if (m_fill >= m_size) // has wrapped around at least once + { + m_head = m_tail; + m_fill = m_size; + } + + return m_fill; +} + +unsigned int SampleSimpleFifo::readBegin(unsigned int count, + SampleVector::iterator* part1Begin, SampleVector::iterator* part1End, + SampleVector::iterator* part2Begin, SampleVector::iterator* part2End) +{ + unsigned int total; + unsigned int remaining; + unsigned int len; + unsigned int head = m_head; + + total = count; + remaining = total; + + if (remaining > 0) + { + len = std::min(remaining, m_size - head); + *part1Begin = m_data.begin() + head; + *part1End = m_data.begin() + head + len; + head += len; + head %= m_size; + remaining -= len; + } + else + { + *part1Begin = m_data.end(); + *part1End = m_data.end(); + } + + if (remaining > 0) + { + len = std::min(remaining, m_size - head); + *part2Begin = m_data.begin() + head; + *part2End = m_data.begin() + head + len; + } + else + { + *part2Begin = m_data.end(); + *part2End = m_data.end(); + } + + return total; +} + +unsigned int SampleSimpleFifo::readCommit(unsigned int count) +{ + if (count > m_fill) + { + qCritical("SampleSinkFifo::readCommit: cannot commit more than available samples"); + count = m_fill; + } + + m_head = (m_head + count) % m_size; + m_fill -= count; + + return count; +} \ No newline at end of file diff --git a/sdrbase/dsp/samplesimplefifo.h b/sdrbase/dsp/samplesimplefifo.h new file mode 100644 index 000000000..ae285d81e --- /dev/null +++ b/sdrbase/dsp/samplesimplefifo.h @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_SAMPLESIMPLEFIFO_H +#define INCLUDE_SAMPLESIMPLEFIFO_H + +#include "dsp/dsptypes.h" +#include "export.h" + +class SDRBASE_API SampleSimpleFifo { +public: + SampleSimpleFifo(); + SampleSimpleFifo(int size); + SampleSimpleFifo(const SampleSimpleFifo& other); + ~SampleSimpleFifo(); + + bool setSize(int size); + void reset(); + unsigned int getSize() { return m_size; } + unsigned int write(SampleVector::const_iterator begin, SampleVector::const_iterator end); + unsigned int readBegin(unsigned int count, + SampleVector::iterator* part1Begin, SampleVector::iterator* part1End, + SampleVector::iterator* part2Begin, SampleVector::iterator* part2End); + unsigned int readCommit(unsigned int count); + +private: + SampleVector m_data; //!< FIFO container + unsigned int m_size; //!< size of FIFO (above) + unsigned int m_fill; //!< number of samples in FIFO + unsigned int m_head; //!< read point + unsigned int m_tail; //!< write point + + void create(unsigned int s); +}; + +#endif // INCLUDE_SAMPLESIMPLEFIFO_H \ No newline at end of file