Changeset - 6b58eb9e9a3c
[Not reviewed]
default
0 2 0
Hasan Yavuz Ă–ZDERYA - 10 years ago 2015-08-15 09:26:15
hy@ozderya.net
re-implemented FrameBuffer as a better ring buffer
2 files changed with 75 insertions and 31 deletions:
0 comments (0 inline, 0 general)
framebuffer.cpp
Show inline comments
 
@@ -19,80 +19,119 @@
 

	
 
#include "framebuffer.h"
 

	
 
FrameBuffer::FrameBuffer(size_t size) :
 
    data(size, 0.)
 
FrameBuffer::FrameBuffer(size_t size)
 
{
 
    _size = size;
 
    data = new double[_size]();
 
    headIndex = 0;
 
}
 

	
 
FrameBuffer::~FrameBuffer()
 
{
 
    delete data;
 
}
 

	
 
void FrameBuffer::resize(size_t size)
 
{
 
    size_t old_size = this->size();
 
    size_t new_size = size;
 
    int offset = size - _size;
 
    if (offset == 0) return;
 

	
 
    double* newData = new double[size];
 

	
 
    if (new_size < old_size)
 
    // move data to new array
 
    int fill_start = offset > 0 ? offset : 0;
 

	
 
    for (int i = fill_start; i < int(size); i++)
 
    {
 
        data.remove(0, old_size - new_size);
 
        newData[i] = _sample(i - offset);
 
    }
 
    else if (new_size > old_size)
 

	
 
    // fill the beginning of the new data
 
    if (fill_start > 0)
 
    {
 
        // This is seriously inefficient!
 
        for (size_t i = old_size; i < new_size; i++)
 
        for (int i = 0; i < fill_start; i++)
 
        {
 
            data.prepend(0);
 
            newData[i] = 0;
 
        }
 
    }
 

	
 
    // data is ready, clean and re-point
 
    delete data;
 
    data = newData;
 
    headIndex = 0;
 
    _size = size;
 
}
 

	
 
void FrameBuffer::addSamples(QVector<double> samples)
 
{
 
    int offset = size() - samples.size();
 
    unsigned shift = samples.size();
 
    if (shift < _size)
 
    {
 
        unsigned x = _size - headIndex; // distance of `head` to end
 

	
 
    if (offset < 0)
 
        if (shift <= x) // there is enough room at the end of array
 
        {
 
            for (size_t i = 0; i < shift; i++)
 
    {
 
        // new samples exceed the size of frame buffer
 
        // excess part (from beginning) of the input will be ignored
 
        for (unsigned int i = 0; i < size(); i++)
 
                data[i+headIndex] = samples[i];
 
            }
 

	
 
            if (shift == x) // we used all the room at the end
 
        {
 
            data[i] = samples[i - offset];
 
                headIndex = 0;
 
            }
 
            else
 
            {
 
                headIndex += shift;
 
        }
 
    }
 
    else if (offset == 0) // input is the same size as the framebuffer
 
        else // there isn't enough room
 
        {
 
            for (size_t i = 0; i < x; i++) // fill the end part
 
    {
 
        data = samples;
 
                data[i+headIndex] = samples[i];
 
    }
 
    else // regular case; input is smaller than framebuffer
 
            for (size_t i = 0; i < (shift-x); i++) // continue from the beginning
 
    {
 
        // shift old samples
 
        int shift = samples.size();
 
        for (int i = 0; i < offset; i++)
 
        {
 
            data[i] = data[i + shift];
 
                data[i] = samples[i+x];
 
            }
 
            headIndex = shift-x;
 
        }
 
        }
 
        // place new samples
 
        for (int i = 0; i < samples.size(); i++)
 
    else // number of new samples equal or bigger than current size
 
        {
 
            data[offset + i] = samples[i];
 
        int x = shift - _size;
 
        for (size_t i = 0; i < _size; i++)
 
        {
 
            data[i] = samples[i+x];
 
        }
 
        headIndex = 0;
 
    }
 
}
 

	
 
void FrameBuffer::clear()
 
{
 
    data.fill(0);
 
    for (size_t i=0; i < _size; i++) data[i] = 0.;
 
}
 

	
 
size_t FrameBuffer::size() const
 
{
 
    return (size_t) data.size();
 
    return _size;
 
}
 

	
 
QPointF FrameBuffer::sample(size_t i) const
 
{
 
    return QPointF(i, data[i]);
 
    return QPointF(i, _sample(i));
 
}
 

	
 
QRectF FrameBuffer::boundingRect() const
 
{
 
    return qwtBoundingRect(*this);
 
}
 

	
 
double FrameBuffer::_sample(size_t i) const
 
{
 
    size_t index = headIndex + i;
 
    if (index >= _size) index -= _size;
 
    return data[index];
 
}
framebuffer.h
Show inline comments
 
@@ -28,6 +28,7 @@ class FrameBuffer : public QwtSeriesData
 
{
 
public:
 
    FrameBuffer(size_t size);
 
    ~FrameBuffer();
 

	
 
    void resize(size_t size);
 
    void addSamples(QVector<double> samples);
 
@@ -39,7 +40,11 @@ public:
 
    QRectF boundingRect() const;
 

	
 
private:
 
    QVector<double> data;
 
    size_t _size; // size of `data`
 
    double* data;
 
    size_t headIndex; // indicates the actual `0` index of the ring buffer
 

	
 
    double _sample(size_t i) const;
 
};
 

	
 
#endif // FRAMEBUFFER_H
0 comments (0 inline, 0 general)