diff --git a/src/stream.cpp b/src/stream.cpp --- a/src/stream.cpp +++ b/src/stream.cpp @@ -142,39 +142,72 @@ void Stream::setNumChannels(unsigned 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(xData)->addSamples(data.xData(), ns); + static_cast(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(channels[ci]->yData())->addSamples(mdata, ns); - delete[] mdata; + auto buf = static_cast(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(); } diff --git a/src/stream.h b/src/stream.h --- a/src/stream.h +++ b/src/stream.h @@ -69,7 +69,7 @@ public: 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); @@ -98,6 +98,19 @@ private: QList 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; };