Changeset - 5c0005f331cf
[Not reviewed]
stream
0 13 2
Hasan Yavuz ÖZDERYA - 8 years ago 2018-02-24 14:14:27
hy@ozderya.net
various fixes to get stream to compile and some basic tests
15 files changed with 255 insertions and 116 deletions:
0 comments (0 inline, 0 general)
src/channelinfomodel.cpp
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -333,13 +333,13 @@ void ChannelInfoModel::resetVisibility()
 
    {
 
        infos[ci].visibility = true;
 
    }
 
    endResetModel();
 
}
 

	
 
void ChannelInfoModel::saveSettings(QSettings* settings)
 
void ChannelInfoModel::saveSettings(QSettings* settings) const
 
{
 
    settings->beginGroup(SettingGroup_Channels);
 
    settings->beginWriteArray(SG_Channels_Channel);
 

	
 
    // save all channel information regardless of current number of channels
 
    for (unsigned ci = 0; (int) ci < infos.length(); ci++)
src/channelinfomodel.h
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -54,13 +54,13 @@ public:
 
    bool          setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
 
    Qt::ItemFlags flags(const QModelIndex &index) const;
 
    QVariant      headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
 

	
 
    void setNumOfChannels(unsigned number);
 
    /// Stores all channel info into a `QSettings`
 
    void saveSettings(QSettings* settings);
 
    void saveSettings(QSettings* settings) const;
 
    /// Loads all channel info from a `QSettings`.
 
    void loadSettings(QSettings* settings);
 

	
 
public slots:
 
    /// reset all channel info (names, color etc.)
 
    void resetInfos();
src/framebuffer2.h
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -42,12 +42,13 @@ public:
 
    virtual Range limits() const = 0;
 
};
 

	
 
/// Common base class for index and writable frame buffers
 
class ResizableBuffer : public FrameBuffer
 
{
 
public:
 
    /// Resize the buffer.
 
    ///
 
    /// @important Resizing to same value is an error.
 
    virtual void resize(unsigned n) = 0;
 
};
 

	
src/samplepack.cpp
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -73,6 +73,16 @@ double* SamplePack::xData() const
 
double* SamplePack::data(unsigned channel) const
 
{
 
    Q_ASSERT(channel < _numChannels);
 

	
 
    return &_yData[channel * _numSamples];
 
}
 

	
 
double* SamplePack::xData()
 
{
 
    return const_cast<double*>(static_cast<const SamplePack&>(*this).xData());
 
}
 

	
 
double* SamplePack::data(unsigned channel)
 
{
 
    return const_cast<double*>(static_cast<const SamplePack&>(*this).data(channel));
 
}
src/samplepack.h
Show inline comments
 
@@ -29,12 +29,15 @@ public:
 
    bool hasX() const;
 
    unsigned numChannels() const;
 
    unsigned numSamples() const;
 
    double* xData() const;
 
    double* data(unsigned channel) const;
 

	
 
    double* xData();
 
    double* data(unsigned channel);
 

	
 
private:
 
    unsigned _numSamples, _numChannels;
 
    double* _xData;
 
    double* _yData;
 
};
 

	
src/sink.h
Show inline comments
 
@@ -27,28 +27,33 @@ class Source;
 

	
 
class Sink
 
{
 
public:
 
    /// Placeholder virtual destructor
 
    virtual ~Sink() {};
 

	
 
    /// Connects a sink to get any data that this sink
 
    /// gets. Connecting an already connected sink is an error.
 
    void connectFollower(Sink* sink);
 

	
 
    /// Disconnects a follower. Disconnecting an unconnected sink is
 
    /// an error.
 
    void disconnectFollower(Sink* sink);
 

	
 
    /// Returns the connected source. `NULL` if it's not connected.
 
    const Source* connectedSource() const;
 

	
 
protected:
 
    /// Entry point for incoming data. Re-implementations should
 
    /// call this function to feed followers.
 
    virtual void feedIn(const SamplePack& data);
 

	
 
    /// Is set by connected source. Re-implementations should call
 
    /// this function to update followers.
 
    virtual void setNumChannels(unsigned nc, bool x);
 

	
 
    /// Set by the connected source when its connected. When
 
    /// disconnecting it's set to `NULL`.
 
    ///
 
    /// @important Trying to connect a source while its already
 
    /// connected is an error.
 
    void setSource(const Source* s);
src/source.cpp
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -18,12 +18,20 @@
 
*/
 

	
 
#include <QtGlobal>
 

	
 
#include "source.h"
 

	
 
Source::~Source()
 
{
 
    for (auto sink : sinks)
 
    {
 
        sink->setSource(NULL);
 
    }
 
}
 

	
 
void Source::connect(Sink* sink)
 
{
 
    Q_ASSERT(!sinks.contains(sink));
 
    Q_ASSERT(sink->connectedSource() == NULL);
 

	
 
    sinks.append(sink);
src/source.h
Show inline comments
 
@@ -25,29 +25,33 @@
 
#include "sink.h"
 
#include "samplepack.h"
 

	
 
class Source
 
{
 
public:
 
    /// Placeholder virtual destructor
 
    virtual ~Source() {};
 
    /// Virtual destructor. Must be called by implementors to notify sinks.
 
    virtual ~Source();
 

	
 
    /// Returns true if source has X data
 
    virtual bool hasX() const = 0;
 

	
 
    /// Returns number of channels
 
    virtual unsigned numChannels() const = 0;
 

	
 
    /// Connects a sink to this source. Trying to connect an already
 
    /// connected sink is an error.
 
    void connect(Sink* sink);
 

	
 
    /// Disconnects an already connected sink. Trying to disconnect an
 
    /// unconnected sink is an error.
 
    void disconnect(Sink* sink);
 

	
 
protected:
 
    /// Feeds "in" given data to connected sinks
 
    void feedOut(const SamplePack& data) const;
 

	
 
    /// Updates "number of channels" of connected sinks. Must be
 
    /// called when num. channels or hasX changes.
 
    void updateNumChannels() const;
 

	
 
private:
 
    QList<Sink*> sinks;
src/stream.cpp
Show inline comments
 
@@ -16,12 +16,13 @@
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "stream.h"
 
#include "ringbuffer.h"
 
#include "indexbuffer.h"
 

	
 
Stream::Stream(unsigned nc, bool x, unsigned ns) :
 
    _infoModel(nc)
 
{
 
    _numSamples = ns;
 
    _paused = false;
 
@@ -53,13 +54,13 @@ Stream::~Stream()
 

	
 
bool Stream::hasX() const
 
{
 
    return _hasx;
 
}
 

	
 
unsigned Stream::numChannels()
 
unsigned Stream::numChannels() const
 
{
 
    return channels.length();
 
}
 

	
 
unsigned Stream::numSamples() const
 
{
 
@@ -69,58 +70,63 @@ unsigned Stream::numSamples() const
 
const StreamChannel* Stream::channel(unsigned index) const
 
{
 
    Q_ASSERT(index < numChannels());
 
    return channels[index];
 
}
 

	
 
StreamChannel* Stream::channel(unsigned index)
 
{
 
    return const_cast<StreamChannel*>(static_cast<const Stream&>(*this).channel(index));
 
}
 

	
 
void Stream::setNumChannels(unsigned nc, bool x)
 
{
 
    unsigned oldNum = numChannels();
 
    if (oldNum == nc && x == _hasX) return;
 
    if (oldNum == nc && x == _hasx) return;
 

	
 
    // adjust the number of channels
 
    if (nc > oldNum)
 
    {
 
        for (int i = oldNum; i < nc; i++)
 
        for (unsigned i = oldNum; i < nc; i++)
 
        {
 
            auto c = new StreamChannel(i, xData, new RingBuffer(ns), &_infoModel);
 
            auto c = new StreamChannel(i, xData, new RingBuffer(_numSamples), &_infoModel);
 
            channels.append(c);
 
        }
 
    }
 
    else if (nc < oldNum)
 
    {
 
        for (int i = oldNum-1; i > nc-1; i--)
 
        for (unsigned i = oldNum-1; i > nc-1; i--)
 
        {
 
            delete channels.takeLast();
 
        }
 
    }
 

	
 
    // change the xdata
 
    if (x != _hasX)
 
    if (x != _hasx)
 
    {
 
        if (x)
 
        {
 
            xData = new RingBuffer(ns);
 
            xData = new RingBuffer(_numSamples);
 
        }
 
        else
 
        {
 
            xData = new IndexBuffer(ns);
 
            xData = new IndexBuffer(_numSamples);
 
        }
 

	
 
        for (auto c : channels)
 
        {
 
            c.setX(xData);
 
            c->setX(xData);
 
        }
 
        _hasX = x;
 
        _hasx = x;
 
    }
 

	
 
    if (nc != oldNum)
 
    {
 
        _infoModel.setNumChannels(nc);
 
        _infoModel.setNumOfChannels(nc);
 
        // TODO: how abut X change?
 
        emit numOfChannelsChanged(nc);
 
        emit numChannelsChanged(nc);
 
    }
 

	
 
    Sink::setNumChannels(nc, x);
 
}
 

	
 
void Stream::feedIn(const SamplePack& data)
 
@@ -128,19 +134,19 @@ void Stream::feedIn(const SamplePack& da
 
    Q_ASSERT(data.numChannels() == numChannels() &&
 
             data.hasX() == hasX());
 

	
 
    if (_paused) return;
 

	
 
    unsigned ns = data.numSamples();
 
    if (_hasX)
 
    if (_hasx)
 
    {
 
        xData.addSamples(data.xData(), ns);
 
        static_cast<RingBuffer*>(xData)->addSamples(data.xData(), ns);
 
    }
 
    for (unsigned i = 0; i < numChannels(); i++)
 
    {
 
        channels[i].yData()->addSamples(data.data(i), ns);
 
        static_cast<RingBuffer*>(channels[i]->yData())->addSamples(data.data(i), ns);
 
    }
 

	
 
    Sink::feedIn(data);
 
}
 

	
 
void Stream::pause(bool paused)
 
@@ -150,16 +156,16 @@ void Stream::pause(bool paused)
 

	
 
void Stream::setNumSamples(unsigned value)
 
{
 
    if (value == _numSamples) return;
 
    _numSamples = value;
 

	
 
    xData.resize(value);
 
    xData->resize(value);
 
    for (auto c : channels)
 
    {
 
        channels[i].yData()->resize(value);
 
        static_cast<RingBuffer*>(c->yData())->resize(value);
 
    }
 
}
 

	
 
void Stream::saveSettings(QSettings* settings) const
 
{
 
    _infoModel.saveSettings(settings);
src/stream.h
Show inline comments
 
@@ -26,38 +26,41 @@
 
#include <QSettings>
 

	
 
#include "sink.h"
 
#include "source.h"
 
#include "channelinfomodel.h"
 
#include "streamchannel.h"
 
#include "resizablebuffer.h"
 
#include "framebuffer2.h"
 

	
 
/**
 
 * Main waveform storage class. It consists of channels. Channels are
 
 * synchronized with each other.
 
 *
 
 * Implements `Sink` class for data entry. It's expected to be
 
 * connected to a `Device` source. Also implements a `Source` class
 
 * for data that exists the buffers.
 
 * connected to a `Device` source.
 
 */
 
class Stream : public Sink, public QObject
 
class Stream : public QObject, public Sink
 
{
 
    Q_OBJECT
 

	
 
public:
 
    /**
 
     * @param nc number of channels
 
     * @param x has X data input
 
     * @param ns number of samples
 
     */
 
    Stream(unsigned nc = 0, bool x = false, unsigned ns = 0);
 
    ~Stream();
 

	
 
    // implementations for `Source`
 
    virtual bool hasX() const;
 
    virtual unsigned numChannels();
 
    virtual unsigned numChannels() const;
 

	
 
    unsigned numSamples() const;
 
    const StreamChannel* channel(unsigned index) const;
 
    StreamChannel* channel(unsigned index);
 

	
 
    /// Saves channel information
 
    void saveSettings(QSettings* settings) const;
 
    /// Load channel information
 
    void loadSettings(QSettings* settings);
 

	
 
@@ -72,13 +75,13 @@ signals:
 
    void channelAdded(const StreamChannel* chan);
 
    void channelNameChanged(unsigned channel, QString name); // TODO: does it stay?
 
    void dataAdded(); ///< emitted when data added to channel man.
 

	
 
public slots:
 
    // TODO: these won't be public
 
    void setNumChannels(unsigned number);
 
    // void setNumChannels(unsigned number);
 
    void setNumSamples(unsigned value);
 

	
 
    /// When paused data feed is ignored
 
    void pause(bool paused);
 

	
 
private:
src/streamchannel.cpp
Show inline comments
 
@@ -31,14 +31,14 @@ StreamChannel::StreamChannel(unsigned i,
 
StreamChannel::~StreamChannel()
 
{
 
    delete _y;
 
}
 

	
 
unsigned StreamChannel::index() const {return _index;}
 
QString StreamChannel::name() const {return _info->name(_index)};
 
QColor StreamChannel::color() const {return _info->color(_index)};
 
bool StreamChannel::visible() const {return _info->isVisible(_index)};
 
QString StreamChannel::name() const {return _info->name(_index);};
 
QColor StreamChannel::color() const {return _info->color(_index);};
 
bool StreamChannel::visible() const {return _info->isVisible(_index);};
 
const FrameBuffer* StreamChannel::xData() const {return _x;}
 
const FrameBuffer* StreamChannel::yData() const {return _y;}
 
FrameBuffer* StreamChannel::yData() {return _y;}
 
const ChannelInfoModel* StreamChannel::info() const {return _info;}
 
void StreamChannel::setX(const FrameBuffer* x) {_x = x};
 
void StreamChannel::setX(const FrameBuffer* x) {_x = x;};
tests/CMakeLists.txt
Show inline comments
 
#
 
# Copyright © 2017 Hasan Yavuz Özderya
 
# Copyright © 2018 Hasan Yavuz Özderya
 
#
 
# This file is part of serialplot.
 
#
 
# serialplot 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, either version 3 of the License, or
 
@@ -21,19 +21,23 @@
 
find_package(Qt5Widgets)
 

	
 
include_directories("../src")
 

	
 
add_executable(Test EXCLUDE_FROM_ALL
 
  test.cpp
 
  test_stream.cpp
 
  ../src/samplepack.cpp
 
  ../src/sink.cpp
 
  ../src/source.cpp
 
  ../src/indexbuffer.cpp
 
  ../src/linindexbuffer.cpp
 
  ../src/ringbuffer.cpp
 
  ../src/readonlybuffer.cpp
 
  ../src/stream.cpp
 
  ../src/streamchannel.cpp
 
  ../src/channelinfomodel.cpp
 
  )
 
add_test(NAME test1 COMMAND Test)
 
qt5_use_modules(Test Widgets)
 

	
 
set(CMAKE_CTEST_COMMAND ctest -V)
 
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
tests/test.cpp
Show inline comments
 
/*
 
  Copyright © 2017 Hasan Yavuz Özderya
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
@@ -24,12 +24,14 @@
 
#include "source.h"
 
#include "indexbuffer.h"
 
#include "linindexbuffer.h"
 
#include "ringbuffer.h"
 
#include "readonlybuffer.h"
 

	
 
#include "test_helpers.h"
 

	
 
TEST_CASE("samplepack with no X", "[memory]")
 
{
 
    SamplePack pack(100, 3, false);
 

	
 
    REQUIRE_FALSE(pack.hasX());
 
    REQUIRE(pack.numChannels() == 3);
 
@@ -50,54 +52,12 @@ TEST_CASE("samplepack with X", "[memory]
 
    REQUIRE(pack.hasX());
 
    REQUIRE(pack.numChannels() == 3);
 
    REQUIRE(pack.numSamples() == 100);
 
    REQUIRE(pack.xData() != nullptr);
 
}
 

	
 
class TestSink : public Sink
 
{
 
public:
 
    int totalFed;
 
    int _numChannels;
 
    bool _hasX;
 

	
 
    TestSink()
 
        {
 
            totalFed = 0;
 
            _numChannels = 0;
 
            _hasX = false;
 
        };
 

	
 
    void feedIn(const SamplePack& data)
 
        {
 
            REQUIRE(data.numChannels() == numChannels());
 

	
 
            totalFed += data.numSamples();
 

	
 
            Sink::feedIn(data);
 
        };
 

	
 
    void setNumChannels(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 

	
 
            Sink::setNumChannels(nc, x);
 
        };
 

	
 
    virtual unsigned numChannels() const
 
        {
 
            return _numChannels;
 
        };
 

	
 
    virtual bool hasX() const
 
        {
 
            return _hasX;
 
        };
 
};
 

	
 
TEST_CASE("sink", "[memory, stream]")
 
{
 
    TestSink sink;
 
    SamplePack pack(100, 3, false);
 

	
 
    sink.setNumChannels(3, false);
 
@@ -126,48 +86,12 @@ TEST_CASE("sink", "[memory, stream]")
 
TEST_CASE("sink must be created unconnected", "[memory, stream]")
 
{
 
    TestSink sink;
 
    REQUIRE(sink.connectedSource() == NULL);
 
}
 

	
 
class TestSource : public Source
 
{
 
public:
 
    int _numChannels;
 
    bool _hasX;
 

	
 
    TestSource(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 
        };
 

	
 
    virtual unsigned numChannels() const
 
        {
 
            return _numChannels;
 
        };
 

	
 
    virtual bool hasX() const
 
        {
 
            return _hasX;
 
        };
 

	
 
    void _feed(const SamplePack& data) const
 
        {
 
            feedOut(data);
 
        };
 

	
 
    void _setNumChannels(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 

	
 
            updateNumChannels();
 
        };
 
};
 

	
 
TEST_CASE("source", "[memory, stream]")
 
{
 
    TestSink sink;
 

	
 
    TestSource source(3, false);
 

	
tests/test_helpers.h
Show inline comments
 
new file 100644
 
#ifndef TEST_HELPERS_H
 
#define TEST_HELPERS_H
 

	
 
#include "source.h"
 
#include "sink.h"
 

	
 
class TestSink : public Sink
 
{
 
public:
 
    int totalFed;
 
    int _numChannels;
 
    bool _hasX;
 

	
 
    TestSink()
 
        {
 
            totalFed = 0;
 
            _numChannels = 0;
 
            _hasX = false;
 
        };
 

	
 
    void feedIn(const SamplePack& data)
 
        {
 
            REQUIRE(data.numChannels() == numChannels());
 

	
 
            totalFed += data.numSamples();
 

	
 
            Sink::feedIn(data);
 
        };
 

	
 
    void setNumChannels(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 

	
 
            Sink::setNumChannels(nc, x);
 
        };
 

	
 
    virtual unsigned numChannels() const
 
        {
 
            return _numChannels;
 
        };
 

	
 
    virtual bool hasX() const
 
        {
 
            return _hasX;
 
        };
 
};
 

	
 
class TestSource : public Source
 
{
 
public:
 
    int _numChannels;
 
    bool _hasX;
 

	
 
    TestSource(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 
        };
 

	
 
    virtual unsigned numChannels() const
 
        {
 
            return _numChannels;
 
        };
 

	
 
    virtual bool hasX() const
 
        {
 
            return _hasX;
 
        };
 

	
 
    void _feed(const SamplePack& data) const
 
        {
 
            feedOut(data);
 
        };
 

	
 
    void _setNumChannels(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 

	
 
            updateNumChannels();
 
        };
 
};
 

	
 

	
 
#endif // TEST_HELPERS_H
tests/test_stream.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2018 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot 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, either version 3 of the License, or
 
  (at your option) any later version.
 

	
 
  serialplot 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 for more details.
 

	
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "stream.h"
 

	
 
#include "catch.hpp"
 
#include "test_helpers.h"
 

	
 
TEST_CASE("construction of stream with default values", "[memory, stream]")
 
{
 
    // default values are an empty stream with no channels
 
    Stream s;
 

	
 
    REQUIRE(s.numChannels() == 0);
 
    REQUIRE(!s.hasX());
 
    REQUIRE(s.numSamples() == 0);
 
}
 

	
 
TEST_CASE("construction of stream with parameters", "[memory, stream]")
 
{
 
    Stream s(4, true, 100);
 

	
 
    REQUIRE(s.numChannels() == 4);
 
    REQUIRE(s.hasX());
 
    REQUIRE(s.numSamples() == 100);
 

	
 
    for (unsigned i = 0; i < 4; i++)
 
    {
 
        const StreamChannel* c = s.channel(i);
 
        REQUIRE(c != NULL);
 
        REQUIRE(c->index() == i);
 
    }
 
}
 

	
 
TEST_CASE("adding data to a stream with no X", "[memory, stream, data]")
 
{
 
    Stream s(3, false, 10);
 

	
 
    // prepare data
 
    SamplePack pack(5, 3, false);
 
    for (unsigned ci = 0; ci < 3; ci++)
 
    {
 
        for (unsigned i = 0; i < 5; i++)
 
        {
 
            pack.data(ci)[i] = i;
 
        }
 
    }
 

	
 
    TestSource so(3, false);
 
    so.connect(&s);
 

	
 
    // test
 
    so._feed(pack);
 

	
 
    for (unsigned ci = 0; ci < 3; ci++)
 
    {
 
        const StreamChannel* c = s.channel(ci);
 
        const FrameBuffer* y = c->yData();
 

	
 
        for (unsigned i = 0; i < 5; i++)
 
        {
 
            REQUIRE(y->sample(i) == 0);
 
        }
 
        for (unsigned i = 5; i < 10; i++)
 
        {
 
            REQUIRE(y->sample(i) == i-5);
 
        }
 
    }
 
}
0 comments (0 inline, 0 general)