| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example audiolevels |
| \title Audiolevels Example |
| \ingroup qtdatavisualization_examples |
| \brief Simple application showing real time audio data. |
| |
| The audiolevels example shows how feed real-time dynamic data to a graph using Q3DBars. |
| |
| This example reads the audio levels from a microphone and displays those levels |
| in a bar graph. To increase the load for demonstration purposes, and to make the |
| graph little fancier, slightly modified data is used to fill multiple rows. |
| |
| \image audiolevels-example.png |
| |
| The interesting stuff happens in \c AudioLevels and \c AudioLevelsIODevice classes, so we |
| concentrate on those and skip explaining the basic Q3DBars functionality - for that see |
| \l{Bars Example}. |
| |
| \include examples-run.qdocinc |
| |
| \section1 Visualizing Audio Levels |
| |
| \c AudioLevelsIODevice subclasses QIODevice and is given as input device for QAudioInput |
| class, so it receives microphone data. |
| |
| In the header file for \c AudioLevels class we declare necessary members: |
| |
| \snippet audiolevels/audiolevels.h 0 |
| |
| And initialize the microphone listening in the source: |
| |
| \snippet audiolevels/audiolevels.cpp 0 |
| |
| In the header file for \c AudioLevelsIODevice class we store pointers to the data proxy and |
| also the data array we give to the proxy, because we reuse the same array to keep memory |
| reallocations to the minimum: |
| |
| \snippet audiolevels/audiolevelsiodevice.h 0 |
| |
| In the source file we define some static constants to define size of the data array and |
| the middle row index, as well as the resolution of the visualization. You may need to adjust |
| these values to get decent performance in low-end devices: |
| |
| \snippet audiolevels/audiolevelsiodevice.cpp 1 |
| |
| The \c resolution constant indicates the sample rate, for example, value 8 means every eighth |
| byte from audio input is visualized. This is necessary to make the data readable, as it would |
| otherwise make the graph scroll too fast. |
| |
| In the \c AudioLevelsIODevice class constructor we initialize the data array: |
| |
| \snippet audiolevels/audiolevelsiodevice.cpp 0 |
| |
| The \c AudioLevelsIODevice::writeData function is called whenever there is new audio data |
| available to be visualized. There we move the old data along the rows and insert new |
| data in the beginning of the rows: |
| |
| \snippet audiolevels/audiolevelsiodevice.cpp 2 |
| |
| We use a couple of techniques here to improve performance. First, we reuse |
| the existing data array, as this allows us to avoid any extra memory allocations in our |
| application code. This also means the data array dimensions do not change, which further |
| improves efficiency in the bar graph renderer. |
| Secondly, since each row is a QVector of bar data items, which do not allocate any data that needs |
| deletion, we can utilize \c memmove and \c memcpy functions to quickly move and copy data around. |
| |
| \note In the future versions of Qt Data Visualization, QBarDataItem might get extended so that |
| it does allocate some memory to store other optional bar properties besides the value. |
| In use cases where those optional properties are used, using \c memmove and \c memcpy could lead to |
| memory leaks, so use them with care. |
| */ |