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
qaudiosystem_platform_stream_support.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qaudiosystem_platform_stream_support_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qaudio_qiodevice_support_p
.
h
>
7
#
include
<
QtMultimedia
/
private
/
qaudiohelpers_p
.
h
>
8
#
include
<
QtCore
/
qdebug
.
h
>
9
10
QT_BEGIN_NAMESPACE
11
12
namespace
QtMultimediaPrivate
{
13
14
using
namespace
std
::
chrono_literals
;
15
16
QPlatformAudioIOStream
::
QPlatformAudioIOStream
(QAudioDevice m_audioDevice, QAudioFormat m_format,
17
std
::optional<
int
> ringbufferSize,
18
std::optional<NativePeriodFrames> nativePeriodFrames,
19
float
volume)
20
:
m_audioDevice
{
21
std
::
move
(
m_audioDevice
),
22
},
23
m_format
{
24
m_format
,
25
},
26
m_nativePeriodFrames
{
27
nativePeriodFrames
,
28
},
29
m_volume
{
30
volume
,
31
}
32
{
33
prepareRingbuffer
(
ringbufferSize
)
;
34
}
35
36
QPlatformAudioIOStream
::~
QPlatformAudioIOStream
()
37
{
38
Q_ASSERT(m_stopRequested);
39
}
40
41
void
QPlatformAudioIOStream
::
setVolume
(
float
volume)
42
{
43
m_volume.store(volume, std::memory_order_relaxed);
44
}
45
46
void
QPlatformAudioIOStream
::
prepareRingbuffer
(
std
::optional<
int
> ringbufferSize)
47
{
48
using
SampleFormat = QAudioFormat::SampleFormat;
49
50
// Warning: QAudioSink::setBufferSize is measured in *bytes* not in *frames*
51
int
ringbufferElements = inferRingbufferFrames(ringbufferSize, m_nativePeriodFrames, m_format)
52
* m_format.channelCount();
53
54
switch
(m_format.sampleFormat()) {
55
case
SampleFormat::Float:
56
m_ringbuffer.emplace<QAudioRingBuffer<
float
>>(ringbufferElements);
57
break
;
58
case
SampleFormat::Int16:
59
m_ringbuffer.emplace<QAudioRingBuffer<int16_t>>(ringbufferElements);
60
break
;
61
case
SampleFormat::Int32:
62
m_ringbuffer.emplace<QAudioRingBuffer<int32_t>>(ringbufferElements);
63
break
;
64
case
SampleFormat::UInt8:
65
m_ringbuffer.emplace<QAudioRingBuffer<uint8_t>>(ringbufferElements);
66
break
;
67
68
default
:
69
qCritical() <<
"invalid sample format"
;
70
Q_UNREACHABLE_RETURN();
71
}
72
}
73
74
void
QPlatformAudioIOStream
::
requestStop
()
75
{
76
m_stopRequested.store(
true
, std::memory_order_release);
77
}
78
79
qsizetype
80
QPlatformAudioIOStream
::inferRingbufferFrames(
const
std
::optional<
int
> &ringbufferSize,
81
const
std::optional<NativePeriodFrames> &nativePeriodFrames,
82
const
QAudioFormat &format)
83
{
84
int
bytesPerFrame = format.bytesPerFrame();
85
Q_PRESUME(bytesPerFrame > 0);
86
87
return
inferRingbufferBytes(ringbufferSize, nativePeriodFrames, format) / bytesPerFrame;
88
}
89
90
qsizetype
91
QPlatformAudioIOStream
::inferRingbufferBytes(
const
std
::optional<
int
> &ringbufferSize,
92
const
std::optional<NativePeriodFrames> &nativePeriodFrames,
93
const
QAudioFormat &format)
94
{
95
// ensure to a sane minimum ringbuffer size of twice the hw buffer size or 32 frames
96
const
int
minimumRingbufferFrames = nativePeriodFrames
97
? qToUnderlying(*nativePeriodFrames) * 2
98
: 32;
99
const
int
minimumRingbufferBytes = format.bytesForFrames(minimumRingbufferFrames);
100
if
(ringbufferSize)
101
return
ringbufferSize >= minimumRingbufferBytes ? *ringbufferSize : minimumRingbufferBytes;
102
103
using
namespace
std::chrono;
104
static
constexpr
auto
defaultBufferDuration = 250ms;
105
106
return
format.bytesForDuration(microseconds(defaultBufferDuration).count());
107
}
108
109
int
QPlatformAudioIOStream
::
ringbufferSizeInBytes
()
110
{
111
return
visitRingbuffer([](
auto
&ringbuffer) {
112
using
SampleType =
typename
std::decay_t<
decltype
(ringbuffer)>::ValueType;
113
return
ringbuffer.size() *
sizeof
(SampleType);
114
});
115
}
116
117
////////////////////////////////////////////////////////////////////////////////////////////////////
118
119
QPlatformAudioSinkStream
::
QPlatformAudioSinkStream
(QAudioDevice audioDevice,
120
const
QAudioFormat &format,
121
std
::optional<
int
> ringbufferSize,
122
std::optional<NativePeriodFrames> nativePeriodFrames,
123
float
volume)
124
:
QPlatformAudioIOStream
{
125
std
::move(audioDevice), format, ringbufferSize, nativePeriodFrames, volume,
126
}
127
{
128
m_streamIdleDetectionConnection = m_streamIdleDetectionNotifier.callOnActivated([
this
] {
129
if
(isStopRequested())
130
return
;
131
132
bool
sinkIsIdle = m_streamIsIdle.load();
133
134
if
(sinkIsIdle) {
135
// data has been pushed to the ringbuffer, while the stream is
136
// still idle, this will change during the next audio callback
137
bool
ringbufferIsEmpty = visitRingbuffer([&](
auto
&ringbuffer) {
138
return
ringbuffer.free() == ringbuffer.size();
139
});
140
141
sinkIsIdle = ringbufferIsEmpty;
142
}
143
144
updateStreamIdle(sinkIsIdle);
145
});
146
}
147
148
QPlatformAudioSinkStream
::~
QPlatformAudioSinkStream
() =
default
;
149
150
uint64_t
151
QPlatformAudioSinkStream
::
process
(
QSpan
<
std
::
byte
>
hostBuffer
,
qsizetype
totalNumberOfFrames
,
152
std
::
optional
<
NativeSampleFormat
>
nativeFormat
)
noexcept
Q_DECL_NONBLOCKING_FUNCTION
153
{
154
qsizetype
totalNumberOfSamples
=
totalNumberOfFrames
*
m_format
.
channelCount
();
155
156
const
float
vol
=
volume
();
157
158
int
samplesConsumedFromRingbuffer
=
visitRingbuffer
([&](
auto
&
ringbuffer
) {
159
return
ringbuffer
.
consume
(
totalNumberOfSamples
, [&](
auto
ringbufferRange
) {
160
if
(
nativeFormat
) {
161
// Amount of bytes in output range differ from ringbuffer range
162
const
qsizetype
samplesInChunk
=
ringbufferRange
.
size
();
163
const
qsizetype
bytesInChunk
=
samplesInChunk
*
bytesPerSample
(*
nativeFormat
);
164
165
QSpan
<
std
::
byte
>
outputByteRange
=
take
(
hostBuffer
,
bytesInChunk
);
166
hostBuffer
=
drop
(
hostBuffer
,
bytesInChunk
);
167
convertToNative
(
as_bytes
(
ringbufferRange
),
outputByteRange
,
vol
, *
nativeFormat
);
168
}
else
{
169
QSpan
<
std
::
byte
>
outputByteRange
=
take
(
hostBuffer
,
ringbufferRange
.
size_bytes
());
170
hostBuffer
=
drop
(
hostBuffer
,
ringbufferRange
.
size_bytes
());
171
QAudioHelperInternal
::
applyVolume
(
vol
,
m_format
,
as_bytes
(
ringbufferRange
),
172
outputByteRange
);
173
}
174
});
175
});
176
177
if
(
m_ringbufferWriterDevice
) {
178
qint64
bytes
=
samplesConsumedFromRingbuffer
*
m_format
.
bytesPerSample
();
179
m_ringbufferWriterDevice
->
bytesConsumedFromRingbuffer
(
bytes
);
180
}
181
182
if
(!
isStopRequested
()) {
183
if
(
notificationThresholdBytes
== 0 ||
bytesFree
() >
notificationThresholdBytes
)
184
m_ringbufferHasSpace
.
set
();
185
186
bool
streamIsIdle
=
m_streamIsIdle
.
load
(
std
::
memory_order_relaxed
);
187
if
(
streamIsIdle
&&
samplesConsumedFromRingbuffer
) {
188
m_streamIsIdle
.
store
(
false
);
189
m_streamIdleDetectionNotifier
.
set
();
190
}
else
if
(!
streamIsIdle
&& !
samplesConsumedFromRingbuffer
) {
191
m_streamIsIdle
.
store
(
true
);
192
m_streamIdleDetectionNotifier
.
set
();
193
}
194
}
195
if
(!
hostBuffer
.
empty
()) {
196
if
(
nativeFormat
)
197
QAudioHelperInternal
::
fillSilence
(
hostBuffer
, *
nativeFormat
);
198
else
199
QAudioHelperInternal
::
fillSilence
(
hostBuffer
,
m_format
);
200
}
201
202
uint64_t
consumedFrames
=
samplesConsumedFromRingbuffer
/
m_format
.
channelCount
();
203
m_processedFrameCount
+=
consumedFrames
;
204
m_totalFrameCount
+=
totalNumberOfFrames
;
205
206
return
consumedFrames
;
207
}
208
209
quint64
QPlatformAudioSinkStream
::
bytesFree
()
const
210
{
211
return
visitRingbuffer
([](
auto
&
ringbuffer
) {
212
using
SampleType
=
typename
std
::
decay_t
<
decltype
(
ringbuffer
)>::
ValueType
;
213
return
ringbuffer
.
free
() *
sizeof
(
SampleType
);
214
});
215
}
216
217
std
::
chrono
::
microseconds
QPlatformAudioSinkStream
::
processedDuration
()
const
218
{
219
return
std
::
chrono
::
microseconds
{
220
m_processedFrameCount
* 1'000'000 /
m_format
.
sampleRate
(),
221
};
222
}
223
224
void
QPlatformAudioSinkStream
::
pullFromQIODevice
()
225
{
226
withPullIODeviceReentrancyGuard
([
this
] {
227
pullFromQIODeviceImpl
();
228
});
229
}
230
231
void
QPlatformAudioSinkStream
::
pullFromQIODeviceImpl
()
232
{
233
Q_ASSERT
(
thread
()->
isCurrentThread
());
234
Q_ASSERT
(
m_device
);
235
Q_ASSERT
(
m_pullIODeviceReentrancyGuard
);
236
237
visitRingbuffer
([&](
auto
&
ringbuffer
) {
238
int
elementsPulled
=
pullFromQIODeviceToRingbuffer
(*
m_device
,
ringbuffer
);
239
if
(
elementsPulled
)
240
updateStreamIdle
(
false
);
241
});
242
}
243
244
void
QPlatformAudioSinkStream
::
createQIODeviceConnections
(
QIODevice
*
device
)
245
{
246
// consumed from audio thread
247
m_ringbufferHasSpaceConnection
=
m_ringbufferHasSpace
.
callOnActivated
(
device
, [
this
] {
248
pullFromQIODevice
();
249
});
250
251
// data has been pushed to device
252
m_iodeviceHasNewDataConnection
=
253
QObject
::
connect
(
device
, &
QIODevice
::
readyRead
,
device
, [
this
] {
254
withPullIODeviceReentrancyGuard
([
this
] {
255
pullFromQIODeviceImpl
();
256
updateStreamIdle
(
false
);
257
});
258
});
259
}
260
261
void
QPlatformAudioSinkStream
::
disconnectQIODeviceConnections
()
262
{
263
QObject
::
disconnect
(
m_ringbufferHasSpaceConnection
);
264
QObject
::
disconnect
(
m_iodeviceHasNewDataConnection
);
265
}
266
267
QIODevice
*
QPlatformAudioSinkStream
::
createRingbufferWriterDevice
()
268
{
269
m_ringbufferWriterDevice
=
visitRingbuffer
(
270
[&](
auto
&
ringbuffer
) ->
std
::
unique_ptr
<
QtPrivate
::
QIODeviceRingBufferWriterBase
> {
271
using
SampleType
=
typename
std
::
decay_t
<
decltype
(
ringbuffer
)>::
ValueType
;
272
return
std
::
make_unique
<
QtPrivate
::
QIODeviceRingBufferWriter
<
SampleType
>>(&
ringbuffer
);
273
});
274
275
return
m_ringbufferWriterDevice
.
get
();
276
}
277
278
void
QPlatformAudioSinkStream
::
setQIODevice
(
QIODevice
*
device
)
279
{
280
m_device
=
device
;
281
}
282
283
void
QPlatformAudioSinkStream
::
setIdleState
(
bool
x
)
284
{
285
m_streamIsIdle
.
store
(
x
);
286
}
287
288
void
QPlatformAudioSinkStream
::
stopIdleDetection
()
289
{
290
QObject
::
disconnect
(
m_streamIdleDetectionConnection
);
291
}
292
293
QThread
*
QPlatformAudioSinkStream
::
thread
()
const
294
{
295
// QPlatformAudioSinkStream is not a QObject, but still has a notion of an application thread
296
// where it lives on.
297
return
m_streamIdleDetectionNotifier
.
thread
();
298
}
299
300
// we limit alloca calls to 0.5MB. it's good enough for virtually all use cases (i.e. buffers
301
// of 4092 frames / 32 channels) and well in the reasonable range of available stack memory on linux
302
// (8MB)
303
static
constexpr
qsizetype
scratchpadBufferSizeLimit
= 512 * 1024;
304
static_assert
(
scratchpadBufferSizeLimit
> 4092 * 32 *
sizeof
(
float
));
305
306
void
QPlatformAudioSinkStream
::
convertToNative
(
QSpan
<
const
std
::
byte
>
internal
,
307
QSpan
<
std
::
byte
>
native
,
float
volume
,
308
NativeSampleFormat
nativeFormat
)
noexcept
Q_DECL_NONBLOCKING_FUNCTION
309
{
310
using
namespace
QAudioHelperInternal
;
311
312
if
(
volume
== 1.f) {
313
convertSampleFormat
(
internal
,
toNativeSampleFormat
(
m_format
.
sampleFormat
()),
native
,
314
nativeFormat
);
315
return
;
316
}
317
318
withTemporaryBuffer
<
scratchpadBufferSizeLimit
>(
internal
.
size
(),
319
[&](
QSpan
<
std
::
byte
>
scratchpadBuffer
) {
320
applyVolume
(
volume
,
m_format
,
internal
,
scratchpadBuffer
);
321
convertSampleFormat
(
scratchpadBuffer
,
toNativeSampleFormat
(
m_format
.
sampleFormat
()),
native
,
322
nativeFormat
);
323
});
324
}
325
326
////////////////////////////////////////////////////////////////////////////////////////////////////
327
328
QPlatformAudioSourceStream
::
QPlatformAudioSourceStream
(
QAudioDevice
audioDevice
,
329
const
QAudioFormat
&
format
,
330
std
::
optional
<
int
>
ringbufferSize
,
331
std
::
optional
<
NativePeriodFrames
>
nativePeriodFrames
,
332
float
volume
)
333
:
QPlatformAudioIOStream
{
334
std
::
move
(
audioDevice
),
format
,
ringbufferSize
,
nativePeriodFrames
,
volume
,
335
}
336
{
337
}
338
339
QPlatformAudioSourceStream
::~
QPlatformAudioSourceStream
() =
default
;
340
341
uint64_t
QPlatformAudioSourceStream
::
process
(
342
QSpan
<
const
std
::
byte
>
hostBuffer
,
qsizetype
numberOfFrames
,
343
std
::
optional
<
NativeSampleFormat
>
nativeFormat
)
noexcept
Q_DECL_NONBLOCKING_FUNCTION
344
{
345
qsizetype
remainingNumberOfSamples
=
numberOfFrames
*
m_format
.
channelCount
();
346
347
const
float
vol
=
volume
();
348
using
namespace
QtMultimediaPrivate
;
349
350
uint64_t
totalSamplesWritten
=
visitRingbuffer
([&](
auto
&
rb
) {
351
using
SampleType
=
typename
std
::
decay_t
<
decltype
(
rb
)>::
ValueType
;
352
353
// clang-format off
354
return
rb
.
produceSome
([&](
QSpan
<
SampleType
>
ringbufferRange
) {
355
if
(
nativeFormat
) {
356
// Amount of bytes in input range differ from ringbuffer range
357
const
qsizetype
samplesInChunk
=
ringbufferRange
.
size
();
358
const
qsizetype
bytesInChunk
=
samplesInChunk
*
bytesPerSample
(*
nativeFormat
);
359
360
QSpan
<
const
std
::
byte
>
inputByteRange
=
take
(
hostBuffer
,
bytesInChunk
);
361
hostBuffer
=
drop
(
hostBuffer
,
bytesInChunk
);
362
convertFromNative
(
inputByteRange
,
as_writable_bytes
(
ringbufferRange
),
vol
,
363
*
nativeFormat
);
364
}
else
{
365
QSpan
<
const
std
::
byte
>
inputByteRange
=
366
take
(
hostBuffer
,
ringbufferRange
.
size_bytes
());
367
hostBuffer
=
drop
(
hostBuffer
,
ringbufferRange
.
size_bytes
());
368
QAudioHelperInternal
::
applyVolume
(
vol
,
m_format
,
inputByteRange
,
369
as_writable_bytes
(
ringbufferRange
));
370
}
371
return
ringbufferRange
;
372
},
remainingNumberOfSamples
);
373
// clang-format on
374
});
375
376
if
(
totalSamplesWritten
)
377
m_ringbufferHasData
.
set
();
378
379
uint64_t
framesWritten
=
totalSamplesWritten
/
m_format
.
channelCount
();
380
m_totalNumberOfFramesPushedToRingbuffer
+=
framesWritten
;
381
return
framesWritten
;
382
}
383
384
void
QPlatformAudioSourceStream
::
pushToIODevice
()
385
{
386
Q_ASSERT
(
thread
()->
isCurrentThread
());
387
388
qsizetype
bytesPushed
=
visitRingbuffer
([&](
auto
&
ringbuffer
) {
389
return
QtPrivate
::
pushToQIODeviceFromRingbuffer
(*
m_device
,
ringbuffer
);
390
});
391
392
if
(
bytesPushed
)
393
Q_EMIT
m_device
->
readyRead
();
394
}
395
396
bool
QPlatformAudioSourceStream
::
deviceIsRingbufferReader
()
const
397
{
398
return
m_device
==
m_ringbufferReaderDevice
.
get
();
399
}
400
401
void
QPlatformAudioSourceStream
::
finalizeQIODevice
(
ShutdownPolicy
shutdownPolicy
)
402
{
403
switch
(
shutdownPolicy
) {
404
case
ShutdownPolicy
::
DiscardRingbuffer
:
405
return
;
406
case
ShutdownPolicy
::
DrainRingbuffer
:
407
if
(!
deviceIsRingbufferReader
())
408
pushToIODevice
();
409
return
;
410
411
default
:
412
Q_UNREACHABLE_RETURN
();
413
}
414
}
415
416
void
QPlatformAudioSourceStream
::
emptyRingbuffer
()
417
{
418
visitRingbuffer
([](
auto
&
ringbuffer
) {
419
ringbuffer
.
consumeAll
([](
auto
&) {
420
});
421
});
422
}
423
424
QThread
*
QPlatformAudioSourceStream
::
thread
()
const
425
{
426
// QPlatformAudioSourceStream is not a QObject, but still has a notion of an application thread
427
// where it lives on.
428
return
m_ringbufferHasData
.
thread
();
429
}
430
431
qsizetype
QPlatformAudioSourceStream
::
bytesReady
()
const
432
{
433
return
visitRingbuffer
([](
const
auto
&
ringbuffer
) {
434
return
ringbuffer
.
used
() *
sizeof
(
typename
std
::
decay_t
<
decltype
(
ringbuffer
)>::
ValueType
);
435
});
436
}
437
438
std
::
chrono
::
microseconds
QPlatformAudioSourceStream
::
processedDuration
()
const
439
{
440
return
std
::
chrono
::
microseconds
{
441
m_format
.
durationForFrames
(
442
qint32
(
m_totalNumberOfFramesPushedToRingbuffer
.
load
(
std
::
memory_order_relaxed
))),
443
};
444
}
445
446
void
QPlatformAudioSourceStream
::
setQIODevice
(
QIODevice
*
device
)
447
{
448
m_device
=
device
;
449
}
450
451
void
QPlatformAudioSourceStream
::
createQIODeviceConnections
(
QIODevice
*
device
)
452
{
453
bool
pushToDevice
= !
deviceIsRingbufferReader
();
454
455
if
(
pushToDevice
) {
456
m_ringbufferHasDataConnection
=
m_ringbufferHasData
.
callOnActivated
(
device
, [
this
] {
457
if
(!
isStopRequested
())
458
updateStreamIdle
(
false
);
459
pushToIODevice
();
460
});
461
}
else
{
462
m_ringbufferHasDataConnection
=
m_ringbufferHasData
.
callOnActivated
(
device
, [
this
] {
463
if
(!
isStopRequested
())
464
updateStreamIdle
(
false
);
465
Q_EMIT
m_device
->
readyRead
();
466
});
467
}
468
469
m_ringbufferIsFullConnection
=
m_ringbufferHasData
.
callOnActivated
(
device
, [
this
] {
470
if
(!
isStopRequested
())
471
updateStreamIdle
(
false
);
472
});
473
}
474
475
void
QPlatformAudioSourceStream
::
disconnectQIODeviceConnections
()
476
{
477
QObject
::
disconnect
(
m_ringbufferHasDataConnection
);
478
QObject
::
disconnect
(
m_ringbufferIsFullConnection
);
479
}
480
481
QIODevice
*
QPlatformAudioSourceStream
::
createRingbufferReaderDevice
()
482
{
483
using
namespace
QtPrivate
;
484
485
m_ringbufferReaderDevice
=
visitRingbuffer
([&](
auto
&
rb
) ->
std
::
unique_ptr
<
QIODevice
> {
486
using
SampleType
=
typename
std
::
decay_t
<
decltype
(
rb
)>::
ValueType
;
487
return
std
::
make_unique
<
QIODeviceRingBufferReader
<
SampleType
>>(&
rb
);
488
});
489
490
m_ringbufferReaderDevice
->
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Unbuffered
);
491
492
return
m_ringbufferReaderDevice
.
get
();
493
}
494
495
void
QPlatformAudioSourceStream
::
convertFromNative
(
496
QSpan
<
const
std
::
byte
>
native
,
QSpan
<
std
::
byte
>
internal
,
float
volume
,
497
NativeSampleFormat
nativeFormat
)
noexcept
Q_DECL_NONBLOCKING_FUNCTION
498
{
499
using
namespace
QAudioHelperInternal
;
500
if
(
volume
== 1.f) {
501
convertSampleFormat
(
native
,
nativeFormat
,
internal
,
502
QAudioHelperInternal
::
toNativeSampleFormat
(
m_format
.
sampleFormat
()));
503
return
;
504
}
505
506
withTemporaryBuffer
<
scratchpadBufferSizeLimit
>(
internal
.
size
(),
507
[&](
QSpan
<
std
::
byte
>
scratchpadBuffer
) {
508
convertSampleFormat
(
native
,
nativeFormat
,
scratchpadBuffer
,
509
QAudioHelperInternal
::
toNativeSampleFormat
(
m_format
.
sampleFormat
()));
510
applyVolume
(
volume
,
m_format
,
scratchpadBuffer
,
internal
);
511
});
512
}
513
514
}
// namespace QtMultimediaPrivate
515
516
QT_END_NAMESPACE
517
518
#
ifdef
Q_CC_MSVC
519
#
undef
alloca
520
#
endif
QtMultimediaPrivate::QPlatformAudioIOStream
Definition
qaudiosystem_platform_stream_support_p.h:41
QtMultimediaPrivate::QPlatformAudioIOStream::ringbufferSizeInBytes
int ringbufferSizeInBytes()
Definition
qaudiosystem_platform_stream_support.cpp:109
QtMultimediaPrivate::QPlatformAudioIOStream::QPlatformAudioIOStream
QPlatformAudioIOStream(QAudioDevice m_audioDevice, QAudioFormat m_format, std::optional< int > ringbufferSize, std::optional< NativePeriodFrames > nativePeriodFrames, float volume)
Definition
qaudiosystem_platform_stream_support.cpp:16
QtMultimediaPrivate::QPlatformAudioIOStream::~QPlatformAudioIOStream
~QPlatformAudioIOStream()
Definition
qaudiosystem_platform_stream_support.cpp:36
QtMultimediaPrivate::QPlatformAudioIOStream::setVolume
void setVolume(float)
Definition
qaudiosystem_platform_stream_support.cpp:41
QtMultimediaPrivate::QPlatformAudioIOStream::requestStop
void requestStop()
Definition
qaudiosystem_platform_stream_support.cpp:74
QtMultimediaPrivate::QPlatformAudioIOStream::prepareRingbuffer
void prepareRingbuffer(std::optional< int > ringbufferSize)
Definition
qaudiosystem_platform_stream_support.cpp:46
QtMultimediaPrivate::QPlatformAudioSinkStream
Definition
qaudiosystem_platform_stream_support_p.h:120
QtMultimediaPrivate::QPlatformAudioSinkStream::QPlatformAudioSinkStream
QPlatformAudioSinkStream(QAudioDevice, const QAudioFormat &, std::optional< int > ringbufferSize, std::optional< NativePeriodFrames > nativePeriodFrames, float volume)
Definition
qaudiosystem_platform_stream_support.cpp:119
QtMultimediaPrivate::QPlatformAudioSinkStream::~QPlatformAudioSinkStream
~QPlatformAudioSinkStream()
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtMultimediaPrivate::impl
Definition
qaudiosystem_p.h:257
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtmultimedia
src
multimedia
audio
qaudiosystem_platform_stream_support.cpp
Generated on
for Qt by
1.18.0