Files @ 554b8bcc9538
Branch filter:

Location: tempo-plotter/src/binarystreamreader.cpp - annotation

Mehmet ASLAN
QCW library is removed from github. New location in gitlab
ecd02467c397
d5f251708ffb
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
e0c6c43cbcf5
e0c6c43cbcf5
e0c6c43cbcf5
ecd02467c397
ecd02467c397
ecd02467c397
556aa6f24713
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
556aa6f24713
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
556aa6f24713
556aa6f24713
556aa6f24713
556aa6f24713
556aa6f24713
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
d90a9a2092c3
d90a9a2092c3
d90a9a2092c3
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
b4195bca68b4
556aa6f24713
c3e7e4cfc78d
b4195bca68b4
b4195bca68b4
b4195bca68b4
b4195bca68b4
b4195bca68b4
b4195bca68b4
556aa6f24713
c3e7e4cfc78d
556aa6f24713
556aa6f24713
556aa6f24713
d5f251708ffb
556aa6f24713
556aa6f24713
b4195bca68b4
b4195bca68b4
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
538d40c57b2b
ecd02467c397
f0efea025c96
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
ecd02467c397
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
3da4b5482573
/*
  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 <QtEndian>
#include <QtDebug>

#include "binarystreamreader.h"
#include "floatswap.h"

BinaryStreamReader::BinaryStreamReader(QIODevice* device, ChannelManager* channelMan,
                                       DataRecorder* recorder, QObject* parent) :
    AbstractReader(device, channelMan, recorder, parent)
{
    paused = false;
    skipByteRequested = false;
    skipSampleRequested = false;

    _numOfChannels = _settingsWidget.numOfChannels();
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numOfChannelsChanged,
            this, &BinaryStreamReader::numOfChannelsChanged);
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numOfChannelsChanged,
            this, &BinaryStreamReader::onNumOfChannelsChanged);

    // initial number format selection
    onNumberFormatChanged(_settingsWidget.numberFormat());
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numberFormatChanged,
            this, &BinaryStreamReader::onNumberFormatChanged);

    // enable skip byte and sample buttons
    connect(&_settingsWidget, &BinaryStreamReaderSettings::skipByteRequested,
            [this]()
            {
                skipByteRequested = true;
            });
    connect(&_settingsWidget, &BinaryStreamReaderSettings::skipSampleRequested,
            [this]()
            {
                skipSampleRequested = true;
            });
}

QWidget* BinaryStreamReader::settingsWidget()
{
    return &_settingsWidget;
}

unsigned BinaryStreamReader::numOfChannels()
{
    return _numOfChannels;
}

void BinaryStreamReader::enable(bool enabled)
{
    if (enabled)
    {
        QObject::connect(_device, &QIODevice::readyRead,
                         this, &BinaryStreamReader::onDataReady);
    }
    else
    {
        QObject::disconnect(_device, 0, this, 0);
    }
}

void BinaryStreamReader::pause(bool enabled)
{
    paused = enabled;
}

void BinaryStreamReader::onNumberFormatChanged(NumberFormat numberFormat)
{
    switch(numberFormat)
    {
        case NumberFormat_uint8:
            sampleSize = 1;
            readSample = &BinaryStreamReader::readSampleAs<quint8>;
            break;
        case NumberFormat_int8:
            sampleSize = 1;
            readSample = &BinaryStreamReader::readSampleAs<qint8>;
            break;
        case NumberFormat_uint16:
            sampleSize = 2;
            readSample = &BinaryStreamReader::readSampleAs<quint16>;
            break;
        case NumberFormat_int16:
            sampleSize = 2;
            readSample = &BinaryStreamReader::readSampleAs<qint16>;
            break;
        case NumberFormat_uint32:
            sampleSize = 4;
            readSample = &BinaryStreamReader::readSampleAs<quint32>;
            break;
        case NumberFormat_int32:
            sampleSize = 4;
            readSample = &BinaryStreamReader::readSampleAs<qint32>;
            break;
        case NumberFormat_float:
            sampleSize = 4;
            readSample = &BinaryStreamReader::readSampleAs<float>;
            break;
        case NumberFormat_INVALID:
            Q_ASSERT(1); // never
            break;
    }
}

void BinaryStreamReader::onNumOfChannelsChanged(unsigned value)
{
    _numOfChannels = value;
}

void BinaryStreamReader::onDataReady()
{
    // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
    int packageSize = sampleSize * _numOfChannels;
    int bytesAvailable = _device->bytesAvailable();

    // skip 1 byte if requested
    if (skipByteRequested && bytesAvailable > 0)
    {
        _device->read(1);
        skipByteRequested = false;
        bytesAvailable--;
    }

    // skip 1 sample (channel) if requested
    if (skipSampleRequested && bytesAvailable >= (int) sampleSize)
    {
        _device->read(sampleSize);
        skipSampleRequested = false;
        bytesAvailable -= sampleSize;
    }

    if (bytesAvailable < packageSize) return;

    int numOfPackagesToRead =
        (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;

    if (paused)
    {
        // read and discard data
        _device->read(numOfPackagesToRead*packageSize);
        return;
    }

    double* channelSamples = new double[numOfPackagesToRead*_numOfChannels];

    for (int i = 0; i < numOfPackagesToRead; i++)
    {
        for (unsigned int ci = 0; ci < _numOfChannels; ci++)
        {
            // channelSamples[ci].replace(i, (this->*readSample)());
            channelSamples[ci*numOfPackagesToRead+i] = (this->*readSample)();
        }
    }

    addData(channelSamples, numOfPackagesToRead*_numOfChannels);

    delete[] channelSamples;
}

template<typename T> double BinaryStreamReader::readSampleAs()
{
    T data;

    _device->read((char*) &data, sizeof(data));

    if (_settingsWidget.endianness() == LittleEndian)
    {
        data = qFromLittleEndian(data);
    }
    else
    {
        data = qFromBigEndian(data);
    }

    return double(data);
}

void BinaryStreamReader::saveSettings(QSettings* settings)
{
    _settingsWidget.saveSettings(settings);
}

void BinaryStreamReader::loadSettings(QSettings* settings)
{
    _settingsWidget.loadSettings(settings);
}