Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
audio.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
4
/* Audio related snippets */
5
#
include
<
QFile
>
6
#
include
<
QTimer
>
7
#
include
<
QDebug
>
8
#
include
<
qobject
.
h
>
9
#
include
<
qfile
.
h
>
10
11
#
include
"qaudiodevice.h"
12
#
include
"qaudiosource.h"
13
#
include
"qaudiooutput.h"
14
#
include
"qaudiodecoder.h"
15
#
include
"qmediaplayer.h"
16
#
include
"qmediadevices.h"
17
18
class
AudioInputExample :
public
QObject {
19
Q_OBJECT
20
public
:
21
void
setup();
22
23
24
public
Q_SLOTS:
25
void
stopRecording();
26
void
handleStateChanged(QtAudio::State newState);
27
28
private
:
29
//! [Audio input class members]
30
QFile destinationFile;
// Class member
31
QAudioSource* audio;
// Class member
32
//! [Audio input class members]
33
};
34
35
36
void
AudioInputExample::setup()
37
//! [Audio input setup]
38
{
39
destinationFile.setFileName(
"/tmp/test.raw"
);
40
destinationFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
41
42
QAudioFormat format;
43
// Set up the desired format, for example:
44
format.setSampleRate(44100);
45
format.setChannelCount(1);
46
format.setSampleFormat(QAudioFormat::Int16);
47
48
QAudioDevice info = QMediaDevices::defaultAudioInput();
49
if
(!info.isFormatSupported(format)) {
50
qWarning() <<
"Default format not supported, trying to use the nearest."
;
51
}
52
53
audio =
new
QAudioSource(format,
this
);
54
connect(audio, &QAudioSource::stateChanged,
this
, &AudioInputExample::handleStateChanged);
55
56
QTimer::singleShot(3000,
this
, &AudioInputExample::stopRecording);
57
audio->start(&destinationFile);
58
// Records audio for 3000ms
59
}
60
//! [Audio input setup]
61
62
//! [Audio input stop recording]
63
void
AudioInputExample::stopRecording()
64
{
65
audio->stop();
66
destinationFile.close();
67
delete
audio;
68
}
69
//! [Audio input stop recording]
70
71
//! [Audio input state changed]
72
void
AudioInputExample::handleStateChanged(QtAudio::State newState)
73
{
74
switch
(newState) {
75
case
QtAudio::StoppedState:
76
if
(audio->error() != QtAudio::NoError) {
77
// Error handling
78
}
else
{
79
// Finished recording
80
}
81
break
;
82
83
case
QtAudio::ActiveState:
84
// Started recording - read from IO device
85
break
;
86
87
default
:
88
// ... other cases as appropriate
89
break
;
90
}
91
}
92
//! [Audio input state changed]
93
94
95
class
AudioOutputExample
:
public
QObject
{
96
Q_OBJECT
97
public
:
98
void
setup
();
99
100
public
Q_SLOTS
:
101
void
handleStateChanged
(
QtAudio
::
State
newState
);
102
void
stopAudioOutput
();
103
104
private
:
105
//! [Audio output class members]
106
QFile sourceFile;
// class member.
107
QAudioSink* audio;
// class member.
108
//! [Audio output class members]
109
};
110
111
112
void
AudioOutputExample
::setup()
113
//! [Audio output setup]
114
{
115
sourceFile.setFileName(
"/tmp/test.raw"
);
116
sourceFile.open(QIODevice::ReadOnly);
117
118
QAudioFormat format;
119
// Set up the format, eg.
120
format.setSampleRate(44100);
121
format.setChannelCount(1);
122
format.setSampleFormat(QAudioFormat::Int16);
123
124
QAudioDevice info(QMediaDevices::defaultAudioOutput());
125
if
(!info.isFormatSupported(format)) {
126
qWarning() <<
"Raw audio format not supported by backend, cannot play audio."
;
127
return
;
128
}
129
130
audio =
new
QAudioSink(format,
this
);
131
connect(audio, QAudioSink::stateChanged,
this
, &AudioInputExample::handleStateChanged);
132
audio->start(&sourceFile);
133
}
134
//! [Audio output setup]
135
136
//! [Audio output stop]
137
void
AudioOutputExample
::
stopAudioOutput
()
138
{
139
audio->stop();
140
sourceFile.close();
141
delete
audio;
142
}
143
//! [Audio output stop]
144
145
//! [Audio output state changed]
146
void
AudioOutputExample
::handleStateChanged(QtAudio::State newState)
147
{
148
switch
(newState) {
149
case
QtAudio::IdleState:
150
// Finished playing (no more data)
151
AudioOutputExample
::
stopAudioOutput
(
)
;
152
break
;
153
154
case
QtAudio::StoppedState:
155
// Stopped for other reasons
156
if
(audio->error() != QtAudio::NoError) {
157
// Error handling
158
}
159
break
;
160
161
default
:
162
// ... other cases as appropriate
163
break
;
164
}
165
}
166
//! [Audio output state changed]
167
168
class
AudioOutputWithCallbackExample
:
public
QObject
169
{
170
Q_OBJECT
171
public
:
172
void
setupPlaySine
();
173
174
private
:
175
//! [Audio callback output class members]
176
QAudioSink* audio;
// class member.
177
float
phase;
// class member.
178
//! [Audio callback output class members]
179
};
180
181
182
void
AudioOutputWithCallbackExample
::setupPlaySine()
183
//! [Audio callback output setup sine]
184
{
185
QAudioFormat format;
186
// Set up the format, eg.
187
format.setSampleRate(44100);
188
format.setChannelCount(2);
189
format.setSampleFormat(QAudioFormat::Float);
190
191
QAudioDevice info(QMediaDevices::defaultAudioOutput());
192
if
(!info.isFormatSupported(format)) {
193
qWarning() <<
"Raw audio format not supported by backend, cannot play audio."
;
194
return
;
195
}
196
197
audio =
new
QAudioSink(format,
this
);
198
float
phaseIncrement = 2 * M_PI * 220.0 / format.sampleRate();
// 220 Hz sine wave
199
audio->start([&phase, phaseIncrement] (QSpan<
float
> interleavedAudioBuffer) {
200
// The audio callback should not call any functions that may potentially be blocking
201
202
// Fill the audio buffer with a sine wave
203
const
int
sampleCount = interleavedAudioBuffer.size() / 2;
// Stereo, so divide by 2
204
for
(
int
i = 0; i < sampleCount; ++i) {
205
float
sample = std::sin(phase);
206
interleavedAudioBuffer[i * 2] = sample;
// Left channel
207
interleavedAudioBuffer[i * 2 + 1] = sample;
// Right channel
208
phase += phaseIncrement;
// Increment phase for next sample
209
}
210
});
211
212
if
(!audio->error() == QtAudio::Error::NoError) {
213
// in addition to the other start() signatures, starting the audio callback will fail if
214
// * the backend does not implement callback-based IO (the API is available on all major
215
// platforms)
216
// * the signature of the audio callback does not match format.sampleFormat()
217
218
qWarning() <<
"Error starting audio output:"
<< audio->errorString();
219
}
220
}
221
//! [Audio callback output setup sine]
222
223
class
AudioInputWithCallbackExample
:
public
QObject
224
{
225
Q_OBJECT
226
public
:
227
void
setupPeakMeter
();
228
229
private
:
230
//! [Audio callback capture class members]
231
QAudioSource* audio;
// class member.
232
std::atomic<
float
> peakLevel;
// class member.
233
//! [Audio callback capture class members]
234
};
235
236
237
void
AudioInputWithCallbackExample
::setupPeakMeter()
238
//! [Audio callback capture setup peak meter]
239
{
240
QAudioFormat format;
241
// Set up the format, eg.
242
format.setSampleRate(44100);
243
format.setChannelCount(2);
244
format.setSampleFormat(QAudioFormat::Float);
245
246
QAudioDevice info(QMediaDevices::defaultAudioOutput());
247
if
(!info.isFormatSupported(format)) {
248
qWarning() <<
"Raw audio format not supported by backend, cannot capture audio."
;
249
return
;
250
}
251
252
audio =
new
QAudioSource(format,
this
);
253
audio->start([&peakLevel] (QSpan<
float
> interleavedAudioBuffer) {
254
float
level = peakLevel.load();
255
256
for
(
float
sample : interleavedAudioBuffer) {
257
// Calculate the peak level from the audio samples
258
level = std::max(level, std::abs(sample));
259
}
260
261
peakLevel.store(level);
262
// Note: care needs to be taken if the application thread needs to be notified, as the
263
// audio callback should not use any potentially blocking system calls.
264
// Good options are autoreset events (windows), eventfd (linux) or kqueue/EVFILT_USER on macos.
265
});
266
267
if
(!audio->error() == QtAudio::Error::NoError) {
268
// in addition to the other start() signatures, starting the audio callback will fail if
269
// * the backend does not implement callback-based IO (the API is available on all major
270
// platforms)
271
// * the signature of the audio callback does not match format.sampleFormat()
272
273
qWarning() <<
"Error starting audio output:"
<< audio->errorString();
274
}
275
}
276
//! [Audio callback capture setup peak meter]
277
278
void
AudioDeviceInfo
()
279
{
280
//! [Setting audio format]
281
QAudioFormat format;
282
format.setSampleRate(44100);
283
// ... other format parameters
284
format.setSampleFormat(QAudioFormat::Int16);
285
//! [Setting audio format]
286
287
//! [Dumping audio formats]
288
const
auto
devices = QMediaDevices::audioOutputs();
289
for
(
const
QAudioDevice &device : devices)
290
qDebug() <<
"Device: "
<< device.description();
291
//! [Dumping audio formats]
292
}
293
294
class
AudioDecodingExample
:
public
QObject
{
295
Q_OBJECT
296
public
:
297
void
decode
();
298
299
public
Q_SLOTS
:
300
void
handleStateChanged
(
QtAudio
::
State
newState
);
301
void
readBuffer
();
302
};
303
304
void
AudioDecodingExample
::decode()
305
{
306
//! [Local audio decoding]
307
QAudioFormat desiredFormat;
308
desiredFormat.setChannelCount(2);
309
desiredFormat.setSampleFormat(QAudioFormat::Int16);
310
desiredFormat.setSampleRate(48000);
311
312
QAudioDecoder *decoder =
new
QAudioDecoder(
this
);
313
decoder->setAudioFormat(desiredFormat);
314
decoder->setSource(
"level1.mp3"
);
315
316
connect(decoder, &QAudioDecoder::bufferReady,
this
, &
AudioDecodingExample
::
readBuffer
);
317
decoder->start();
318
319
// Now wait for bufferReady() signal and call decoder->read()
320
//! [Local audio decoding]
321
}
322
323
QMediaPlayer
player
;
324
325
//! [Volume conversion]
326
void
applyVolume
(
int
volumeSliderValue)
327
{
328
// volumeSliderValue is in the range [0..100]
329
330
qreal linearVolume = QtAudio::convertVolume(volumeSliderValue / qreal(100.0),
331
QtAudio::LogarithmicVolumeScale,
332
QtAudio::LinearVolumeScale);
333
334
player
.setVolume(qRound(linearVolume * 100));
335
}
336
//! [Volume conversion]
applyVolume
void applyVolume(int volumeSliderValue)
[Volume conversion]
Definition
audio.cpp:326
AudioDeviceInfo
void AudioDeviceInfo()
[Audio callback capture setup peak meter]
Definition
audio.cpp:278
player
QMediaPlayer player
Definition
audio.cpp:323
AudioDecodingExample
Definition
audio.cpp:294
AudioDecodingExample::readBuffer
void readBuffer()
AudioInputWithCallbackExample
[Audio callback output setup sine]
Definition
audio.cpp:224
AudioOutputExample
[Audio input state changed]
Definition
audio.cpp:95
AudioOutputExample::stopAudioOutput
void stopAudioOutput()
[Audio output setup]
Definition
audio.cpp:137
AudioOutputWithCallbackExample
[Audio output state changed]
Definition
audio.cpp:169
qtmultimedia
src
multimedia
doc
snippets
multimedia-snippets
audio.cpp
Generated on
for Qt by
1.18.0