diff --git a/src/stream.h b/src/stream.h
new file mode 100644
--- /dev/null
+++ b/src/stream.h
@@ -0,0 +1,117 @@
+/*
+ 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 .
+*/
+
+#ifndef STREAM_H
+#define STREAM_H
+
+#include
+#include
+#include
+#include
+
+#include "sink.h"
+#include "source.h"
+#include "channelinfomodel.h"
+#include "streamchannel.h"
+#include "framebuffer.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.
+ */
+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() const;
+
+ unsigned numSamples() const;
+ const StreamChannel* channel(unsigned index) const;
+ StreamChannel* channel(unsigned index);
+ const ChannelInfoModel* infoModel() const;
+ ChannelInfoModel* infoModel();
+
+ /// Saves channel information
+ void saveSettings(QSettings* settings) const;
+ /// Load channel information
+ void loadSettings(QSettings* settings);
+
+protected:
+ // implementations for `Sink`
+ virtual void setNumChannels(unsigned nc, bool x);
+ virtual void feedIn(const SamplePack& pack);
+
+signals:
+ void numChannelsChanged(unsigned value);
+ void numSamplesChanged(unsigned value);
+ 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 setNumSamples(unsigned value);
+
+ /// When paused data feed is ignored
+ void pause(bool paused);
+
+ /// Clears buffer data (fills with 0)
+ void clear();
+
+private:
+ unsigned _numSamples;
+ bool _paused;
+
+ bool _hasx;
+ ResizableBuffer* xData;
+ QList channels;
+
+ ChannelInfoModel _infoModel;
+
+ /**
+ * Applies gain and offset to given pack.
+ *
+ * Caller is responsible for deleting returned `SamplePack`.
+ *
+ * @note Should be called only when gain or offset is enabled. Guard with
+ * `ChannelInfoModel::gainOrOffsetEn()`.
+ *
+ * @param pack input data
+ * @return modified data
+ */
+ const SamplePack* applyGainOffset(const SamplePack& pack) const;
+};
+
+
+#endif // STREAM_H