diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-04 10:51:33 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-04 11:30:37 +0300 |
commit | 4e2ee15086da3cb1e2d16caac7928b80e2bcdb26 (patch) | |
tree | 9c45d7bd0bcc90ba704d54f7d582b7e44efe4d34 /examples | |
parent | 3aa0c8d52af26ba8752450c08865bf674814bcb2 (diff) |
Made audiolevels example show something sensible
+ Fixed zoom level setting via API
Task-number: QTRD-2244
Change-Id: Iab8d877361c480ba4010a79e93af8a0121239b5d
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/audiolevels/audiolevels.cpp | 69 | ||||
-rw-r--r-- | examples/audiolevels/audiolevels.h | 43 | ||||
-rw-r--r-- | examples/audiolevels/audiolevels.pro | 7 | ||||
-rw-r--r-- | examples/audiolevels/audiolevelsiodevice.cpp | 64 | ||||
-rw-r--r-- | examples/audiolevels/audiolevelsiodevice.h | 42 | ||||
-rw-r--r-- | examples/audiolevels/main.cpp | 166 |
6 files changed, 227 insertions, 164 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp new file mode 100644 index 00000000..91b95b7d --- /dev/null +++ b/examples/audiolevels/audiolevels.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "audiolevelsiodevice.h" +#include "audiolevels.h" + +#include <QtDataVis3D/qbardataproxy.h> +#include <QtDataVis3D/qvalueaxis.h> + +#include <QAudioDeviceInfo> +#include <QAudioInput> + +QT_DATAVIS3D_USE_NAMESPACE + +AudioLevels::AudioLevels(Q3DBars *chart, QObject *parent) + : QObject(parent), + m_device(0), + m_graph(chart), + m_audioInput(0) +{ + // Set up the graph + QBarDataRow *row = new QBarDataRow; + m_graph->activeDataProxy()->addRow(row); + m_graph->setDataWindow(1, 700); + m_graph->setBarSpecs(0.04, QSizeF(0.0, 0.0)); + m_graph->setGridVisible(false); + m_graph->setBackgroundVisible(false); + m_graph->valueAxis()->setRange(0.0, 1.0); + m_graph->setShadowQuality(QDataVis::ShadowNone); + m_graph->setCameraPosition(-20.0, 10.0, 10); + m_graph->setTheme(QDataVis::ThemeHighContrast); + + QAudioFormat formatAudio; + formatAudio.setSampleRate(8000); + formatAudio.setChannelCount(1); + formatAudio.setSampleSize(8); + formatAudio.setCodec("audio/pcm"); + formatAudio.setByteOrder(QAudioFormat::LittleEndian); + formatAudio.setSampleType(QAudioFormat::UnSignedInt); + + QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice(); + m_audioInput = new QAudioInput(inputDevices,formatAudio, this); + + m_device = new AudioLevelsIODevice(m_graph->activeDataProxy(), this); + m_device->open(QIODevice::WriteOnly); + + m_audioInput->start(m_device); +} + +AudioLevels::~AudioLevels() +{ + m_audioInput->stop(); + m_device->close(); +} diff --git a/examples/audiolevels/audiolevels.h b/examples/audiolevels/audiolevels.h new file mode 100644 index 00000000..5b91a0db --- /dev/null +++ b/examples/audiolevels/audiolevels.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef AUDIOLEVELS_H +#define AUDIOLEVELS_H + +#include <QtDataVis3D/q3dbars.h> + +QT_DATAVIS3D_USE_NAMESPACE + +class AudioLevelsIODevice; +class QAudioInput; + +class AudioLevels : public QObject +{ + Q_OBJECT + +public: + AudioLevels(Q3DBars *chart, QObject *parent = 0); + ~AudioLevels(); + +private: + AudioLevelsIODevice *m_device; + Q3DBars *m_graph; + QAudioInput *m_audioInput; +}; + +#endif diff --git a/examples/audiolevels/audiolevels.pro b/examples/audiolevels/audiolevels.pro index 8a75e6f3..79356f18 100644 --- a/examples/audiolevels/audiolevels.pro +++ b/examples/audiolevels/audiolevels.pro @@ -6,6 +6,11 @@ TARGET = audiolevels QT += multimedia -SOURCES += main.cpp +SOURCES += main.cpp \ + audiolevels.cpp \ + audiolevelsiodevice.cpp + +HEADERS += audiolevels.h \ + audiolevelsiodevice.h INSTALLS += target diff --git a/examples/audiolevels/audiolevelsiodevice.cpp b/examples/audiolevels/audiolevelsiodevice.cpp new file mode 100644 index 00000000..46e5aadb --- /dev/null +++ b/examples/audiolevels/audiolevelsiodevice.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "audiolevelsiodevice.h" +#include <QDebug> + +QT_DATAVIS3D_USE_NAMESPACE + +AudioLevelsIODevice::AudioLevelsIODevice(QBarDataProxy *proxy, QObject *parent) + : QIODevice(parent), + m_proxy(proxy) +{ +} + +// Implementation required for this pure virtual function +qint64 AudioLevelsIODevice::readData(char *data, qint64 maxSize) +{ + Q_UNUSED(data) + Q_UNUSED(maxSize) + return -1; +} + +qint64 AudioLevelsIODevice::writeData(const char *data, qint64 maxSize) +{ + static const int resolution = 8; + static const int maxRowSize = 1000; + + int newDataSize = maxSize / resolution; + + const QBarDataRow *oldRow = m_proxy->rowAt(0); + + int rowSize = qMin((newDataSize + oldRow->size()), maxRowSize); + + QBarDataRow *row = new QBarDataRow(rowSize); + + // Insert data in reverse order, so that newest data is always at the front of the row + for (int i = newDataSize - 1; i >= 0; i--) + (*row)[i].setValue(((quint8)data[resolution * i] - 128) / 2.0); + + // Append old data to new row + for (int i = newDataSize; i < rowSize; i++) + (*row)[i].setValue(oldRow->at(i - newDataSize).value()); + + m_proxy->setRow(0, row); + + return maxSize; +} + + diff --git a/examples/audiolevels/audiolevelsiodevice.h b/examples/audiolevels/audiolevelsiodevice.h new file mode 100644 index 00000000..b2342866 --- /dev/null +++ b/examples/audiolevels/audiolevelsiodevice.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef AUDIOLEVELSIODEVICE_H +#define AUDIOLEVELSIODEVICE_H + +#include <QtDataVis3D/qbardataproxy.h> +#include <QIODevice> + +QT_DATAVIS3D_USE_NAMESPACE + +class AudioLevelsIODevice : public QIODevice +{ + Q_OBJECT +public: + explicit AudioLevelsIODevice(QBarDataProxy *proxy, QObject *parent = 0); + +protected: + qint64 readData(char *data, qint64 maxSize); + qint64 writeData(const char *data, qint64 maxSize); + +private: + QBarDataProxy *m_proxy; + int m_visibleCount; +}; + +#endif diff --git a/examples/audiolevels/main.cpp b/examples/audiolevels/main.cpp index c31b35cc..2b8556e1 100644 --- a/examples/audiolevels/main.cpp +++ b/examples/audiolevels/main.cpp @@ -16,183 +16,23 @@ ** ****************************************************************************/ -#include <QtDataVis3D/q3dbars.h> -#include <QtDataVis3D/qbardataproxy.h> -#include <QtDataVis3D/qvalueaxis.h> +#include "audiolevels.h" #include <QGuiApplication> #include <QAudio> -#include <QTimer> - -//#define USE_CONES using namespace QtDataVis3D; -#if 0 -class AudioLevels : public QObject -{ -public: - AudioLevels(Q3DBars *window); - ~AudioLevels(); - - void start(QString fileName); - -public slots: - void spectrumChanged(qint64 position, qint64 length, const FrequencySpectrum &spectrum); - void stateChanged(QAudio::Mode mode, QAudio::State state); - -private slots: - void restart(); - -private: - int barIndex(qreal frequency) const; - -private: - Q3DBars *m_chart; - Engine *m_engine; - QTimer *m_restartTimer; - // Lower bound of first band in the spectrum in Hz - qreal m_lowFreq; - // Upper band of last band in the spectrum in Hz - qreal m_highFreq; -}; - -AudioLevels::AudioLevels(Q3DBars *window) - : m_chart(window), - m_engine(new Engine(this)), - m_restartTimer(new QTimer(this)), - m_lowFreq(SpectrumLowFreq), - m_highFreq(SpectrumHighFreq) -{ - m_chart->setDataWindow(SpectrumNumBands * 2, SpectrumNumBands); - // Disable grid - m_chart->setGridVisible(false); - // Disable auto-scaling of height by defining explicit range - m_chart->valueAxis()->setRange(0.0, 1.0); - // Disable shadows - m_chart->setShadowQuality(QDataVis::ShadowNone); -#if USE_CONES - // Set bar specifications; make them a bit wider than deep and make them be drawn 75% - // inside each other - m_chart->setBarSpecs(1.25), QSizeF(0.2, -0.75)); - // Set bar type, smooth cones - m_chart->setBarType(QDataVis::Cones, true); - // Adjust zoom manually; automatic zoom level calculation does not work well with negative - // spacings (in setBarSpecs) - m_chart->setCameraPosition(10.0f, 5.0f, 70); -#else - // Set bar specifications; make them twice as wide as they're deep - m_chart->setBarSpecs(2.0, QSizeF(0.0, 0.0)); - // Set bar type, flat bars - m_chart->setBarType(QDataVis::Bars, false); - // Adjust camera position - m_chart->setCameraPosition(10.0f, 7.5f, 75); -#endif - // Set color scheme - m_chart->setBarColor(QColor(Qt::black), QColor(Qt::red), QColor(Qt::darkYellow)); - // Disable selection - m_chart->setSelectionMode(QDataVis::ModeNone); - QObject::connect(m_engine, &Engine::changedSpectrum, this, &AudioLevels::spectrumChanged); - QObject::connect(m_engine, &Engine::stateChanged, this, &AudioLevels::stateChanged); - m_restartTimer->setSingleShot(true); - QObject::connect(m_restartTimer, &QTimer::timeout, this, &AudioLevels::restart); - - QBarDataProxy *proxy = new QBarDataProxy; - m_chart->setActiveDataProxy(proxy); -} - -AudioLevels::~AudioLevels() -{ - delete m_engine; - delete m_restartTimer; -} -void AudioLevels::start(QString fileName) -{ - m_engine->loadFile(fileName); - m_engine->startPlayback(); -} - -//----------------------------------------------------------------------------- -// Public slots -//----------------------------------------------------------------------------- - -void AudioLevels::spectrumChanged(qint64 position, qint64 length, const FrequencySpectrum &spectrum) -{ - Q_UNUSED(position); - Q_UNUSED(length); - //qDebug() << "updating bar values" << position << length; - QBarDataRow *data = new QBarDataRow(SpectrumNumBands); - for (int bar = 0; bar < SpectrumNumBands; bar++) { - // init data set - (*data)[bar].setValue(qreal(0.0)); - } - FrequencySpectrum::const_iterator i = spectrum.begin(); - const FrequencySpectrum::const_iterator end = spectrum.end(); - for ( ; i != end; ++i) { - const FrequencySpectrum::Element e = *i; - if (e.frequency >= m_lowFreq && e.frequency < m_highFreq) { - (*data)[barIndex(e.frequency)].setValue(qMax(data->at(barIndex(e.frequency)).value(), qreal(e.amplitude))); - } - } - static_cast<QBarDataProxy *>(m_chart->activeDataProxy())->insertRow(0, data); -} - -void AudioLevels::stateChanged(QAudio::Mode mode, QAudio::State state) -{ - //qDebug() << "mode:" << mode << " state: " << state; - // Restart once playback is finished - if (QAudio::AudioOutput == mode && QAudio::StoppedState == state) - m_restartTimer->start(500); -} - -//----------------------------------------------------------------------------- -// Private slots -//----------------------------------------------------------------------------- - -void AudioLevels::restart() -{ - // Change file each time - QString fileToLoad = QStringLiteral(":/file"); - static int fileNo = 3; - QString nrStr; - nrStr.setNum(fileNo); - fileToLoad.append(nrStr); - //qDebug() << fileToLoad; - start(fileToLoad); - fileNo++; - if (fileNo > 3) - fileNo = 1; -} - -//----------------------------------------------------------------------------- -// Private functions -//----------------------------------------------------------------------------- - -int AudioLevels::barIndex(qreal frequency) const -{ - Q_ASSERT(frequency >= m_lowFreq && frequency < m_highFreq); - const qreal bandWidth = (m_highFreq - m_lowFreq) / SpectrumNumBands; - const int index = (frequency - m_lowFreq) / bandWidth; - if (index < 0 || index >= SpectrumNumBands) - Q_ASSERT(false); - //qDebug() << "insert to" << index; - return index; -} -#endif -//----------------------------------------------------------------------------- -// main -//----------------------------------------------------------------------------- int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); - app.setApplicationName("QtDataVis3D spectrum analyzer"); Q3DBars window; window.resize(1024, 768); + window.setTitle("QtDataVis3D microphone audio levels visualizer"); window.show(); -// AudioLevels *AudioLevels = new AudioLevels(&window); -// AudioLevels->start(QStringLiteral(":/file2")); + AudioLevels audioLevels(&window); return app.exec(); } |