From de3b56bd3cb07e36fee4df5166e24c52a758fc0a Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 1 Jun 2021 10:58:29 +0200 Subject: [PATCH] GLScope redesign: added missing bits --- sdrbase/CMakeLists.txt | 1 + sdrbase/util/doublebuffermultiple.h | 268 ++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 sdrbase/util/doublebuffermultiple.h diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 49a418d9f..aca193d6f 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -388,6 +388,7 @@ set(sdrbase_HEADERS util/db.h util/doublebuffer.h util/doublebufferfifo.h + util/doublebuffermultiple.h util/fixedtraits.h util/fits.h util/golay2312.h diff --git a/sdrbase/util/doublebuffermultiple.h b/sdrbase/util/doublebuffermultiple.h new file mode 100644 index 000000000..a24e25fca --- /dev/null +++ b/sdrbase/util/doublebuffermultiple.h @@ -0,0 +1,268 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 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 SDRBASE_UTIL_DOUBLEBUFFERMULTIPLE_H_ +#define SDRBASE_UTIL_DOUBLEBUFFERMULTIPLE_H_ + +#include +#include + +#include + +#include "simpleserializer.h" + +template +class DoubleBufferMultiple +{ +public: + DoubleBufferMultiple() + { + m_size = 0; + m_currentPosition = 0; + m_current = m_data.end(); + } + + ~DoubleBufferMultiple() {} + + DoubleBufferMultiple(const DoubleBufferMultiple& other) + { + m_size = other.m_size; + m_data.resize(other.m_data.size()); + m_current.resize(other.m_data.size()); + m_currentPosition = 0; + + for (unsigned int i = 0; i < other.m_data.size(); i++) + { + m_data[i] = other.m_data[i]; + m_current[i] = m_data[i].begin(); + } + } + + DoubleBufferMultiple& operator=(const DoubleBufferMultiple& other) + { + if (&other == this) { + return *this; + } + + m_size = other.m_size; + m_data.resize(other.m_data.size()); + m_current.resize(other.m_data.size()); + m_currentPosition = 0; + + for (unsigned int i = 0; i < other.m_data.size(); i++) + { + m_data[i] = other.m_data[i]; + m_current[i] = m_data[i].begin(); + } + + return *this; + } + + void resize(int size) + { + m_size = size; + m_currentPosition = 0; + + for (unsigned int i = 0; i < m_data.size(); i++) + { + m_data[i].resize(2*size); + m_current[i] = m_data[i].begin(); + } + } + + void addStream() + { + m_data.push_back(std::vector(2*m_size)); + m_current.push_back(std::vector::iterator()); + m_current.back() = m_data.back().begin(); + } + + void write(const std::vector::const_iterator>& vbegin, int length) + { + int insize = length > m_size ? m_size : length; + + if ((m_currentPosition + insize) > m_size) + { + int sizeLeft = m_size - m_currentPosition; + m_currentPosition = insize - sizeLeft; + } + else + { + m_currentPosition += insize; + } + + for (unsigned int i = 0; i < vbegin.size(); i++) + { + if (i >= m_data.size()) { + break; + } + + std::copy(vbegin[i], vbegin[i] + insize, m_current[i]); + + if (((m_current[i] - m_data[i].begin()) + insize) > m_size) + { + int sizeLeft = m_size - (m_current[i] - m_data[i].begin()); + std::copy(vbegin[i], vbegin[i] + sizeLeft, m_current[i] + m_size); + std::copy(vbegin[i] + sizeLeft, vbegin[i] + insize, m_data[i].begin()); + m_current[i] = m_data[i].begin() + (insize - sizeLeft); + } + else + { + std::copy(vbegin[i], vbegin[i] + insize, m_current[i] + m_size); + m_current[i] += insize; + } + } + } + + // void write(const typename std::vector::const_iterator& begin, const typename std::vector::const_iterator& cend) + // { + // typename std::vector::const_iterator end = cend; + + // if ((end - begin) > m_size) { + // end = begin + m_size; + // } + + // int insize = end - begin; + + // std::copy(begin, end, m_current); + + // if (((m_current - m_data.begin()) + insize) > m_size) + // { + // int sizeLeft = m_size - (m_current - m_data.begin()); + // std::copy(begin, begin + sizeLeft, m_current + m_size); + // std::copy(begin + sizeLeft, end, m_data.begin()); + // m_current = m_data.begin() + (insize - sizeLeft); + // } + // else + // { + // std::copy(begin, end, m_current + m_size); + // m_current += insize; + // } + // } + + typename std::vector::iterator getCurrent(unsigned int i) const { return m_current[i] + m_size; } + typename std::vector::const_iterator begin(unsigned int i) const { return m_data[i].begin(); } + typename std::vector::iterator begin(unsigned int i) { return m_data[i].begin(); } + unsigned int absoluteFill(unsigned int i) const { return m_current[i] - m_data[i].begin(); } + void reset(unsigned int i) { m_current[i] = m_data[i].begin(); } + + void getCurrent(std::vector::iterator>& vcurrent) const + { + vcurrent.clear(); + + for (unsigned int i = 0; i < m_data.size(); i++) { + vcurrent.push_back(m_data[i].begin() + m_currentPosition + m_size); + } + } + + int getCurrentPosition() const { + return m_currentPosition + m_size; + } + + void begin(typename std::vector::const_iterator>& vbegin) const + { + vbegin.clear(); + + for (unsigned int i = 0; i < m_data.size(); i++) { + vbegin.push_back(m_data[i].begin()); + } + } + + void begin(typename std::vector::iterator>& vbegin) + { + vbegin.clear(); + + for (unsigned int i = 0; i < m_data.size(); i++) { + vbegin.push_back(m_data[i].begin()); + } + } + + unsigned int absoluteFill() const { return m_currentPosition; } + + void reset() + { + m_currentPosition = 0; + + for (unsigned int i = 0; i < m_current.size(); i++) { + m_current[i] = m_data[i].begin(); + } + } + + QByteArray serialize() const + { + SimpleSerializer s(1); + + s.writeU32(1, std::min(m_data.size(), 10U)); + s.writeS32(2, m_size); + + for (unsigned int i = 0; i < std::min(m_data.size(), 10U); i++) + { + QByteArray buf(reinterpret_cast(m_data[i].data()), m_data[i].size()*sizeof(T)); + s.writeU32(10*i + 11, m_current[i] - m_data[i].begin()); + s.writeBlob(10*i + 12, buf); + } + + return s.final(); + } + + bool deserialize(const QByteArray& data) + { + SimpleDeserializer d(data); + + if(!d.isValid()) { + return false; + } + + if (d.getVersion() == 1) + { + unsigned int tmpUInt; + unsigned int nbStreams; + QByteArray buf; + + d.readU32(1, &nbStreams, 0); + nbStreams = nbStreams > 10 ? 10 : nbStreams; + m_data.resize(nbStreams); + m_current.resize(nbStreams); + d.readS32(2, &m_size, 0); + + for (unsigned int i = 0; i < nbStreams; i++) + { + m_data.resize(2*m_size); + d.readU32(10*i + 11, &tmpUInt, 0); + d.readBlob(10*i + 12, &buf); + m_current[i] = m_data[i].begin() + tmpUInt; + memcpy(reinterpret_cast(m_data[i].data()), buf.data(), buf.size()); + //qDebug("DoubleBufferMutiple::deserialize: i: %u m_data.size(): %u buf.size(): %d", i, m_data[i].size(), buf.size()); + //std::copy(reinterpret_cast(m_data.data()), buf.data(), buf.data() + buf.size()); // bug + } + + return true; + } + else + { + return false; + } + } + +private: + int m_size; + std::vector> m_data; + std::vector::iterator> m_current; + int m_currentPosition; +}; + +#endif /* SDRBASE_UTIL_DOUBLEBUFFERMULTIPLE_H_ */