diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-02-07 15:47:05 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-02-08 08:27:54 +0000 |
commit | 9700d6ce42d4e2a644f3ad91bdbd2448e1d50feb (patch) | |
tree | f7cd478e1c24bf0e508b25c13f1bfd1d2b47e9aa /examples | |
parent | c844c1e5bde966c50a41d43c942b806d5c2f251e (diff) |
Polish the audio example
- Use C++ 11 (nullptr, override)
- Bail out cleanly if there is no audio input available
- Rewrite the buffer algorithm to work on a member
variable to make the slidling window principle
clearer and reduce QVector allocations
Task-number: QTBUG-60662
Change-Id: I02827f3dca4f0bf1fb213fa12369455de6c618c5
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/charts/audio/main.cpp | 15 | ||||
-rw-r--r-- | examples/charts/audio/widget.cpp | 29 | ||||
-rw-r--r-- | examples/charts/audio/widget.h | 9 | ||||
-rw-r--r-- | examples/charts/audio/xyseriesiodevice.cpp | 38 | ||||
-rw-r--r-- | examples/charts/audio/xyseriesiodevice.h | 11 |
5 files changed, 60 insertions, 42 deletions
diff --git a/examples/charts/audio/main.cpp b/examples/charts/audio/main.cpp index be287d7b..8c4eca66 100644 --- a/examples/charts/audio/main.cpp +++ b/examples/charts/audio/main.cpp @@ -27,13 +27,24 @@ ** ****************************************************************************/ -#include <QtWidgets/QApplication> #include "widget.h" +#include <QtMultimedia/QAudioDeviceInfo> +#include <QtWidgets/QApplication> +#include <QtWidgets/QMessageBox> + int main(int argc, char *argv[]) { QApplication a(argc, argv); - Widget w; + + const QAudioDeviceInfo inputDevice = QAudioDeviceInfo::defaultInputDevice(); + if (inputDevice.isNull()) { + QMessageBox::warning(nullptr, "audio", + "There is no audio input device available."); + return -1; + } + + Widget w(inputDevice); w.show(); return a.exec(); diff --git a/examples/charts/audio/widget.cpp b/examples/charts/audio/widget.cpp index b285a6ca..86dd6206 100644 --- a/examples/charts/audio/widget.cpp +++ b/examples/charts/audio/widget.cpp @@ -28,31 +28,30 @@ ****************************************************************************/ #include "widget.h" +#include "xyseriesiodevice.h" + #include <QtMultimedia/QAudioDeviceInfo> #include <QtMultimedia/QAudioInput> + #include <QtCharts/QChartView> #include <QtCharts/QLineSeries> #include <QtCharts/QChart> -#include <QtWidgets/QVBoxLayout> #include <QtCharts/QValueAxis> -#include "xyseriesiodevice.h" + +#include <QtWidgets/QVBoxLayout> QT_CHARTS_USE_NAMESPACE -Widget::Widget(QWidget *parent) - : QWidget(parent), - m_device(0), - m_chart(0), - m_series(0), - m_audioInput(0) +Widget::Widget(const QAudioDeviceInfo &deviceInfo, QWidget *parent) : + QWidget(parent), + m_chart(new QChart), + m_series(new QLineSeries) { - m_chart = new QChart; QChartView *chartView = new QChartView(m_chart); chartView->setMinimumSize(800, 600); - m_series = new QLineSeries; m_chart->addSeries(m_series); QValueAxis *axisX = new QValueAxis; - axisX->setRange(0, 2000); + axisX->setRange(0, XYSeriesIODevice::sampleCount); axisX->setLabelFormat("%g"); axisX->setTitleText("Samples"); QValueAxis *axisY = new QValueAxis; @@ -61,11 +60,10 @@ Widget::Widget(QWidget *parent) m_chart->setAxisX(axisX, m_series); m_chart->setAxisY(axisY, m_series); m_chart->legend()->hide(); - m_chart->setTitle("Data from the microphone"); + m_chart->setTitle("Data from the microphone (" + deviceInfo.deviceName() + ')'); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(chartView); - setLayout(mainLayout); QAudioFormat formatAudio; formatAudio.setSampleRate(8000); @@ -75,8 +73,7 @@ Widget::Widget(QWidget *parent) formatAudio.setByteOrder(QAudioFormat::LittleEndian); formatAudio.setSampleType(QAudioFormat::UnSignedInt); - QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice(); - m_audioInput = new QAudioInput(inputDevices,formatAudio, this); + m_audioInput = new QAudioInput(deviceInfo, formatAudio, this); m_device = new XYSeriesIODevice(m_series, this); m_device->open(QIODevice::WriteOnly); diff --git a/examples/charts/audio/widget.h b/examples/charts/audio/widget.h index 70cc3862..82072b92 100644 --- a/examples/charts/audio/widget.h +++ b/examples/charts/audio/widget.h @@ -44,6 +44,7 @@ class XYSeriesIODevice; QT_BEGIN_NAMESPACE class QAudioInput; +class QAudioDeviceInfo; QT_END_NAMESPACE class Widget : public QWidget @@ -51,14 +52,14 @@ class Widget : public QWidget Q_OBJECT public: - Widget(QWidget *parent = 0); + explicit Widget(const QAudioDeviceInfo &deviceInfo, QWidget *parent = nullptr); ~Widget(); private: - XYSeriesIODevice *m_device; + XYSeriesIODevice *m_device = nullptr; QChart *m_chart; - QLineSeries *m_series; - QAudioInput *m_audioInput; + QLineSeries *m_series ; + QAudioInput *m_audioInput = nullptr; }; #endif // WIDGET_H diff --git a/examples/charts/audio/xyseriesiodevice.cpp b/examples/charts/audio/xyseriesiodevice.cpp index 19669ff9..d129725d 100644 --- a/examples/charts/audio/xyseriesiodevice.cpp +++ b/examples/charts/audio/xyseriesiodevice.cpp @@ -28,39 +28,43 @@ ****************************************************************************/ #include "xyseriesiodevice.h" + #include <QtCharts/QXYSeries> -XYSeriesIODevice::XYSeriesIODevice(QXYSeries * series, QObject *parent) : +XYSeriesIODevice::XYSeriesIODevice(QXYSeries *series, QObject *parent) : QIODevice(parent), m_series(series) { } -qint64 XYSeriesIODevice::readData(char * data, qint64 maxSize) +qint64 XYSeriesIODevice::readData(char *data, qint64 maxSize) { Q_UNUSED(data) Q_UNUSED(maxSize) return -1; } -qint64 XYSeriesIODevice::writeData(const char * data, qint64 maxSize) +qint64 XYSeriesIODevice::writeData(const char *data, qint64 maxSize) { - qint64 range = 2000; - QVector<QPointF> oldPoints = m_series->pointsVector(); - QVector<QPointF> points; - int resolution = 4; + static const int resolution = 4; + + if (m_buffer.isEmpty()) { + m_buffer.reserve(sampleCount); + for (int i = 0; i < sampleCount; ++i) + m_buffer.append(QPointF(i, 0)); + } - if (oldPoints.count() < range) { - points = m_series->pointsVector(); - } else { - for (int i = maxSize/resolution; i < oldPoints.count(); i++) - points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y())); + int start = 0; + const int availableSamples = int(maxSize) / resolution; + if (availableSamples < sampleCount) { + start = sampleCount - availableSamples; + for (int s = 0; s < start; ++s) + m_buffer[s].setY(m_buffer.at(s + availableSamples).y()); } - qint64 size = points.count(); - for (int k = 0; k < maxSize/resolution; k++) - points.append(QPointF(k + size, ((quint8)data[resolution * k] - 128)/128.0)); + for (int s = start; s < sampleCount; ++s, data += resolution) + m_buffer[s].setY(qreal(uchar(*data) -128) / qreal(128)); - m_series->replace(points); - return maxSize; + m_series->replace(m_buffer); + return (sampleCount - start) * resolution; } diff --git a/examples/charts/audio/xyseriesiodevice.h b/examples/charts/audio/xyseriesiodevice.h index 05daf974..cbbf2271 100644 --- a/examples/charts/audio/xyseriesiodevice.h +++ b/examples/charts/audio/xyseriesiodevice.h @@ -31,6 +31,8 @@ #define XYSERIESIODEVICE_H #include <QtCore/QIODevice> +#include <QtCore/QPointF> +#include <QtCore/QVector> #include <QtCharts/QChartGlobal> QT_CHARTS_BEGIN_NAMESPACE @@ -43,14 +45,17 @@ class XYSeriesIODevice : public QIODevice { Q_OBJECT public: - explicit XYSeriesIODevice(QXYSeries * series, QObject *parent = 0); + explicit XYSeriesIODevice(QXYSeries *series, QObject *parent = nullptr); + + static const int sampleCount = 2000; protected: - qint64 readData(char * data, qint64 maxSize); - qint64 writeData(const char * data, qint64 maxSize); + qint64 readData(char *data, qint64 maxSize) override; + qint64 writeData(const char *data, qint64 maxSize) override; private: QXYSeries *m_series; + QVector<QPointF> m_buffer; }; #endif // XYSERIESIODEVICE_H |