Drawing a waveform using QCustomPlot
-
wrote on 6 Sept 2022, 17:43 last edited by
On stackoverflow I came across a piece of code that will use QCustomPlot to draw a waveform from an audio. Trying to adapt the code to my needs I came across an issue where the plot lines were drawn on the whole plot as seen in the screenshot bellow.
What I changed is I've made the script use an already existing AudioDecoder here.
Could someone help me on what's going wrong? Thanks.
Waveform.h
#ifndef WAVEFORM_H #define WAVEFORM_H #include "qcustomplot.h" #include <QAudioBuffer> class QAudioDecoder; class Waveform : public QCustomPlot { Q_OBJECT public: Waveform(QWidget *parent = Q_NULLPTR); ~Waveform(); void setBuffer(QAudioBuffer buffer); void plot(); void reset(); private: qreal getPeakValue(const QAudioFormat& format); QVector<double> samples; QCPGraph *wavePlot; }; #endif // WAVEFORM_H
Waveform.cpp
#include "waveform.h" #include <QAudioDecoder> Waveform::Waveform(QWidget *parent) : QCustomPlot(parent) { wavePlot = addGraph(); setMinimumHeight(250); } Waveform::~Waveform() { } void Waveform::setBuffer(QAudioBuffer buffer) { qreal peak = getPeakValue(buffer.format()); const qint16 *data = buffer.constData<qint16>(); int count = buffer.sampleCount() / 2; for (int i=0; i<count; i++){ double val = data[i]/peak; samples.append(val); } } void Waveform::plot() { QVector<double> x(samples.size()); for (int i=0; i<x.size(); i++) x[i] = i; wavePlot->addData(x, samples); yAxis->setRange(QCPRange(-1, 1)); xAxis->setRange(QCPRange(0, samples.size())); replot(); } void Waveform::reset() { samples.clear(); } qreal Waveform::getPeakValue(const QAudioFormat &format) { qreal ret(0); if (format.isValid()){ switch (format.sampleType()) { case QAudioFormat::Unknown: break; case QAudioFormat::Float: if (format.sampleSize() != 32) // other sample formats are not supported ret = 0; else ret = 1.00003; break; case QAudioFormat::SignedInt: if (format.sampleSize() == 32) #ifdef Q_OS_WIN ret = INT_MAX; #endif #ifdef Q_OS_UNIX ret = SHRT_MAX; #endif else if (format.sampleSize() == 16) ret = SHRT_MAX; else if (format.sampleSize() == 8) ret = CHAR_MAX; break; case QAudioFormat::UnSignedInt: if (format.sampleSize() == 32) ret = UINT_MAX; else if (format.sampleSize() == 16) ret = USHRT_MAX; else if (format.sampleSize() == 8) ret = UCHAR_MAX; break; default: break; } } return ret; }
1/1