Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
audiogenerationutils_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef AUDIOGENERATIONUTILS_H
5#define AUDIOGENERATIONUTILS_H
6
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QAudioFormat>
20#include <QAudioBuffer>
21#include <chrono>
22#include <limits>
23
25
26inline QByteArray createSineWaveData(const QAudioFormat &format, std::chrono::microseconds duration,
27 qint32 sampleIndex = 0, qreal frequency = 500,
28 qreal volume = 0.8)
29{
30 if (!format.isValid())
31 return {};
32
33 const qint32 length = format.bytesForDuration(duration.count());
34
35 QByteArray data(format.bytesForDuration(duration.count()), Qt::Uninitialized);
36 unsigned char *ptr = reinterpret_cast<unsigned char *>(data.data());
37 const auto end = ptr + length;
38
39 auto writeNextFrame = [&](auto value) {
40 Q_ASSERT(sizeof(value) == format.bytesPerSample());
41 *reinterpret_cast<decltype(value) *>(ptr) = value;
42 ptr += sizeof(value);
43 };
44
45 for (; ptr < end; ++sampleIndex) {
46 const qreal x = sin(2 * M_PI * frequency * sampleIndex / format.sampleRate()) * volume;
47 for (int ch = 0; ch < format.channelCount(); ++ch) {
48 switch (format.sampleFormat()) {
49 case QAudioFormat::UInt8:
50 writeNextFrame(static_cast<quint8>(std::round((1.0 + x) / 2 * 255)));
51 break;
52 case QAudioFormat::Int16:
53 writeNextFrame(
54 static_cast<qint16>(std::round(x * std::numeric_limits<qint16>::max())));
55 break;
56 case QAudioFormat::Int32:
57 writeNextFrame(
58 static_cast<qint32>(std::round(x * std::numeric_limits<qint32>::max())));
59 break;
60 case QAudioFormat::Float:
61 writeNextFrame(static_cast<float>(x));
62 break;
63 case QAudioFormat::Unknown:
64 case QAudioFormat::NSampleFormats:
65 break;
66 }
67 }
68 }
69
70 Q_ASSERT(ptr == end);
71
72 return data;
73}
74
75class AudioGenerator : public QObject
76{
78public:
85
87 { //
89 }
90
92 { //
94 }
95
100
102 { //
104 }
105
107 { //
109 }
110
120
121signals:
122 void done();
123 void audioBufferCreated(const QAudioBuffer &buffer);
124
125public slots:
127{
129 emit done();
132 return;
133 }
134
136
139 }
140
141private:
142 int m_maxBufferCount = 1;
143 std::chrono::microseconds m_duration{ std::chrono::seconds{ 1 } };
144 int m_bufferIndex = 0;
145 QAudioFormat m_format;
146 bool m_emitEmptyBufferOnStop = false;
147 qreal m_frequency = 500.;
148 qint32 m_sampleIndex = 0;
149};
150
151QT_END_NAMESPACE
152
153#endif // AUDIOGENERATIONUTILS_H
void audioBufferCreated(const QAudioBuffer &buffer)
\inmodule QtCore
Definition qbytearray.h:58