mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-10-01 01:06:35 -04:00
MIMO: device engine Tx handling (1)
This commit is contained in:
parent
1171d71c87
commit
7a1b727a36
@ -270,6 +270,8 @@ set(sdrbase_HEADERS
|
|||||||
util/doublebuffer.h
|
util/doublebuffer.h
|
||||||
util/doublebufferfifo.h
|
util/doublebufferfifo.h
|
||||||
util/fixedtraits.h
|
util/fixedtraits.h
|
||||||
|
util/incrementalarray.h
|
||||||
|
util/incrementalvector.h
|
||||||
util/message.h
|
util/message.h
|
||||||
util/messagequeue.h
|
util/messagequeue.h
|
||||||
util/movingaverage.h
|
util/movingaverage.h
|
||||||
|
@ -258,20 +258,42 @@ void DSPDeviceMIMOEngine::workSampleSinkFifos()
|
|||||||
if (iPart1Begin != iPart1End)
|
if (iPart1Begin != iPart1End)
|
||||||
{
|
{
|
||||||
for (unsigned int stream = 0; stream < data.size(); stream++) {
|
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)
|
if (iPart2Begin != iPart2End)
|
||||||
{
|
{
|
||||||
for (unsigned int stream = 0; stream < data.size(); stream++) {
|
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();
|
SampleMIFifo* sampleFifo = m_deviceSampleMIMO->getSampleMIFifo();
|
||||||
|
|
||||||
@ -284,26 +306,46 @@ void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int stream)
|
|||||||
SampleVector::const_iterator part2begin;
|
SampleVector::const_iterator part2begin;
|
||||||
SampleVector::const_iterator part2end;
|
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);
|
//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
|
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)
|
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 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
|
* 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;
|
bool positiveOnly = false;
|
||||||
// DC and IQ corrections
|
// 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 -+
|
// 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) {
|
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());
|
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_threadedBasebandSampleSources.push_back(ThreadedBasebandSampleSources());
|
||||||
|
m_sourceSampleBuffers.push_back(IncrementalVector<Sample>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOHalfSynchronous) // synchronous FIFOs on Rx and not with Tx
|
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,
|
&DSPDeviceMIMOEngine::handleDataRxSync,
|
||||||
Qt::QueuedConnection
|
Qt::QueuedConnection
|
||||||
);
|
);
|
||||||
|
QObject::connect(
|
||||||
|
m_deviceSampleMIMO->getSampleMOFifo(),
|
||||||
|
&SampleMOFifo::dataSyncRead,
|
||||||
|
this,
|
||||||
|
&DSPDeviceMIMOEngine::handleDataTxSync,
|
||||||
|
Qt::QueuedConnection
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOAsynchronous) // asynchronous FIFOs
|
else if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOAsynchronous) // asynchronous FIFOs
|
||||||
{
|
{
|
||||||
@ -640,6 +754,13 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo)
|
|||||||
&DSPDeviceMIMOEngine::handleDataRxAsync,
|
&DSPDeviceMIMOEngine::handleDataRxAsync,
|
||||||
Qt::QueuedConnection
|
Qt::QueuedConnection
|
||||||
);
|
);
|
||||||
|
QObject::connect(
|
||||||
|
m_deviceSampleMIMO->getSampleMOFifo(),
|
||||||
|
&SampleMOFifo::dataAsyncRead,
|
||||||
|
this,
|
||||||
|
&DSPDeviceMIMOEngine::handleDataTxAsync,
|
||||||
|
Qt::QueuedConnection
|
||||||
|
);
|
||||||
// QObject::connect(
|
// QObject::connect(
|
||||||
// m_deviceSampleMIMO->getSampleSinkFifo(stream),
|
// m_deviceSampleMIMO->getSampleSinkFifo(stream),
|
||||||
// &SampleSinkFifo::dataReady,
|
// &SampleSinkFifo::dataReady,
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
#include "util/syncmessenger.h"
|
#include "util/syncmessenger.h"
|
||||||
#include "util/movingaverage.h"
|
#include "util/movingaverage.h"
|
||||||
|
#include "util/incrementalvector.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
|
||||||
class DeviceSampleMIMO;
|
class DeviceSampleMIMO;
|
||||||
@ -347,6 +348,7 @@ private:
|
|||||||
|
|
||||||
typedef std::list<ThreadedBasebandSampleSource*> ThreadedBasebandSampleSources;
|
typedef std::list<ThreadedBasebandSampleSource*> ThreadedBasebandSampleSources;
|
||||||
std::vector<ThreadedBasebandSampleSources> m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream)
|
std::vector<ThreadedBasebandSampleSources> m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream)
|
||||||
|
std::vector<IncrementalVector<Sample>> m_sourceSampleBuffers;
|
||||||
|
|
||||||
typedef std::list<MIMOChannel*> MIMOChannels;
|
typedef std::list<MIMOChannel*> MIMOChannels;
|
||||||
MIMOChannels m_mimoChannels; //!< MIMO channels
|
MIMOChannels m_mimoChannels; //!< MIMO channels
|
||||||
@ -358,9 +360,12 @@ private:
|
|||||||
unsigned int m_spectrumInputIndex; //!< Index of the stream to be used as spectrum sink input
|
unsigned int m_spectrumInputIndex; //!< Index of the stream to be used as spectrum sink input
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void workSampleSinkFifos(); //!< transfer samples of all sinks (sync mode)
|
void workSampleSinkFifos(); //!< transfer samples of all sink streams (sync mode)
|
||||||
void workSampleSinkFifo(unsigned int stream); //!< transfer samples of one sink (async mode)
|
void workSampleSinkFifo(unsigned int streamIndex); //!< transfer samples of one sink stream (async mode)
|
||||||
void workSamples(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int sinkIndex);
|
void workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex);
|
||||||
|
void workSampleSourceFifos(); //!< transfer samples of all source streams (sync mode)
|
||||||
|
void workSampleSourceFifo(unsigned int streamIndex); //!< transfer samples of one source stream (async mode)
|
||||||
|
void workSamplesSource(SampleVector::const_iterator& begin, unsigned int nbSamples, unsigned int streamIndex);
|
||||||
|
|
||||||
State gotoIdle(); //!< Go to the idle state
|
State gotoIdle(); //!< Go to the idle state
|
||||||
State gotoInit(); //!< Go to the acquisition init state from idle
|
State gotoInit(); //!< Go to the acquisition init state from idle
|
||||||
@ -373,6 +378,8 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void handleDataRxSync(); //!< Handle data when Rx samples have to be processed synchronously
|
void handleDataRxSync(); //!< Handle data when Rx samples have to be processed synchronously
|
||||||
void handleDataRxAsync(int streamIndex); //!< Handle data when Rx samples have to be processed asynchronously
|
void handleDataRxAsync(int streamIndex); //!< Handle data when Rx samples have to be processed asynchronously
|
||||||
|
void handleDataTxSync(); //!< Handle data when Tx samples have to be processed synchronously
|
||||||
|
void handleDataTxAsync(int streamIndex); //!< Handle data when Tx samples have to be processed asynchronously
|
||||||
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
|
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
|
||||||
void handleInputMessages(); //!< Handle input message queue
|
void handleInputMessages(); //!< Handle input message queue
|
||||||
};
|
};
|
||||||
|
@ -68,6 +68,17 @@ void SampleSourceFifo::readAdvance(SampleVector::iterator& readUntil, unsigned i
|
|||||||
emit dataRead(nbSamples);
|
emit dataRead(nbSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SampleSourceFifo::readAdvance(SampleVector::const_iterator& readUntil, unsigned int nbSamples)
|
||||||
|
{
|
||||||
|
// QMutexLocker mutexLocker(&m_mutex);
|
||||||
|
assert(nbSamples <= m_size/2);
|
||||||
|
emit dataWrite(nbSamples);
|
||||||
|
|
||||||
|
m_ir = (m_ir + nbSamples) % m_size;
|
||||||
|
readUntil = m_data.begin() + m_size + m_ir;
|
||||||
|
emit dataRead(nbSamples);
|
||||||
|
}
|
||||||
|
|
||||||
void SampleSourceFifo::write(const Sample& sample)
|
void SampleSourceFifo::write(const Sample& sample)
|
||||||
{
|
{
|
||||||
m_data[m_iw] = sample;
|
m_data[m_iw] = sample;
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
void init();
|
void init();
|
||||||
/** advance read pointer for the given length and activate R/W signals */
|
/** advance read pointer for the given length and activate R/W signals */
|
||||||
void readAdvance(SampleVector::iterator& readUntil, unsigned int nbSamples);
|
void readAdvance(SampleVector::iterator& readUntil, unsigned int nbSamples);
|
||||||
|
void readAdvance(SampleVector::const_iterator& readUntil, unsigned int nbSamples);
|
||||||
|
|
||||||
void getReadIterator(SampleVector::iterator& readUntil); //!< get iterator past the last sample of a read advance operation (i.e. current read iterator)
|
void getReadIterator(SampleVector::iterator& readUntil); //!< get iterator past the last sample of a read advance operation (i.e. current read iterator)
|
||||||
void getWriteIterator(SampleVector::iterator& writeAt); //!< get iterator to current item for update - write phase 1
|
void getWriteIterator(SampleVector::iterator& writeAt); //!< get iterator to current item for update - write phase 1
|
||||||
|
58
sdrbase/util/incrementalvector.h
Normal file
58
sdrbase/util/incrementalvector.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2019 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRBASE_UTIL_INCREMENTALVECTOR_H_
|
||||||
|
#define SDRBASE_UTIL_INCREMENTALVECTOR_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class IncrementalVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<T> m_vector;
|
||||||
|
|
||||||
|
IncrementalVector();
|
||||||
|
~IncrementalVector();
|
||||||
|
|
||||||
|
void allocate(uint32_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
IncrementalVector<T>::IncrementalVector() :
|
||||||
|
m_size(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
IncrementalVector<T>::~IncrementalVector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void IncrementalVector<T>::allocate(uint32_t size)
|
||||||
|
{
|
||||||
|
if (size <= m_size) { return; }
|
||||||
|
m_vector.resize(size);
|
||||||
|
m_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SDRBASE_UTIL_INCREMENTALVECTOR_H_ */
|
Loading…
Reference in New Issue
Block a user