Changeset - f5271e6d0ce0
[Not reviewed]
gain-offset
0 2 0
Hasan Yavuz Ă–ZDERYA - 7 years ago 2018-07-09 16:09:14
hy@ozderya.net
apply gain and offset only when enabled
2 files changed with 68 insertions and 22 deletions:
0 comments (0 inline, 0 general)
src/stream.cpp
Show inline comments
 
@@ -121,81 +121,114 @@ void Stream::setNumChannels(unsigned nc,
 
            xData = new RingBuffer(_numSamples);
 
        }
 
        else
 
        {
 
            xData = new IndexBuffer(_numSamples);
 
        }
 

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

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

	
 
    Sink::setNumChannels(nc, x);
 
}
 

	
 
void Stream::feedIn(const SamplePack& data)
 
const SamplePack* Stream::applyGainOffset(const SamplePack& pack) const
 
{
 
    Q_ASSERT(data.numChannels() == numChannels() &&
 
             data.hasX() == hasX());
 
    SamplePack* mPack = nullptr;
 
    unsigned ns = pack.numSamples();
 

	
 
    for (unsigned ci = 0; ci < numChannels(); ci++)
 
    {
 
        bool gainEn = channels[ci]->info()->gainEn(ci);
 
        bool offsetEn = channels[ci]->info()->offsetEn(ci);
 
        double* mdata;
 
        if (gainEn || offsetEn)
 
        {
 
            if (mPack == nullptr)
 
                mPack = new SamplePack(pack);
 

	
 
            mdata = mPack->data(ci);
 

	
 
            double gain = channels[ci]->info()->gain(ci);
 
            double offset = channels[ci]->info()->offset(ci);
 

	
 
            if (gainEn)
 
            {
 
                for (unsigned i = 0; i < ns; i++)
 
                {
 
                    mdata[i] *= gain;
 
                }
 
            }
 
            if (offsetEn)
 
            {
 
                for (unsigned i = 0; i < ns; i++)
 
                {
 
                    mdata[i] += offset;
 
                }
 
            }
 
        }
 
    }
 

	
 
    return mPack;
 
}
 

	
 
void Stream::feedIn(const SamplePack& pack)
 
{
 
    Q_ASSERT(pack.numChannels() == numChannels() &&
 
             pack.hasX() == hasX());
 

	
 
    if (_paused) return;
 

	
 
    unsigned ns = data.numSamples();
 
    unsigned ns = pack.numSamples();
 
    if (_hasx)
 
    {
 
        static_cast<RingBuffer*>(xData)->addSamples(data.xData(), ns);
 
        static_cast<RingBuffer*>(xData)->addSamples(pack.xData(), ns);
 
    }
 

	
 
    // modified pack that gain and offset is applied to
 
    const SamplePack* mPack = applyGainOffset(pack);
 

	
 
    for (unsigned ci = 0; ci < numChannels(); ci++)
 
    {
 
        // TODO: check for gainEn and offsetEn
 
        // apply gain and offset
 
        auto rdata = data.data(ci);
 
        auto mdata = new double[sizeof(double) * ns];
 
        // TODO: add gain&offset access methods to `StreamChannel`
 
        double gain = channels[ci]->info()->gain(ci);
 
        double offset = channels[ci]->info()->offset(ci);
 
        for (int i = 0; i < ns; i++)
 
        {
 
            mdata[i] = rdata[i] * gain + offset;
 
        }
 

	
 
        static_cast<RingBuffer*>(channels[ci]->yData())->addSamples(mdata, ns);
 
        delete[] mdata;
 
        auto buf = static_cast<RingBuffer*>(channels[ci]->yData());
 
        double* data = (mPack == nullptr) ? pack.data(ci) : mPack->data(ci);
 
        buf->addSamples(data, ns);
 
    }
 

	
 
    // TODO: emit modified (gain&offset) data
 
    Sink::feedIn(data);
 
    Sink::feedIn((mPack == nullptr) ? pack : *mPack);
 

	
 
    if (mPack != nullptr) delete mPack;
 
    emit dataAdded();
 
}
 

	
 
void Stream::pause(bool paused)
 
{
 
    _paused = paused;
 
}
 

	
 
void Stream::clear()
 
{
 
    for (auto c : channels)
 
    {
 
        static_cast<RingBuffer*>(c->yData())->clear();
 
    }
 
}
 

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

	
 
    xData->resize(value);
 
    for (auto c : channels)
 
    {
src/stream.h
Show inline comments
 
@@ -48,57 +48,70 @@ public:
 
     * @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& data);
 
    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<StreamChannel*> channels;
 

	
 
    ChannelInfoModel _infoModel;
 

	
 
    /**
 
     * Applies gain and offset to given pack.
 
     *
 
     * If gain or offset isn't enabled this function returns `nullptr`. If gain
 
     * or offset is enabled for at least 1 channel input pack is copied and
 
     * modified. Result is returned. Caller is responsible for deleting
 
     * returned `SamplePack`.
 
     *
 
     * @param pack input data
 
     * @return `nullptr` if no gain or offset is enabled otherwise modified data
 
     */
 
    const SamplePack* applyGainOffset(const SamplePack& pack) const;
 
};
 

	
 

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