4#ifndef QAUDIOSYSTEM_PLATFORM_STREAM_SUPPORT_P_H
5#define QAUDIOSYSTEM_PLATFORM_STREAM_SUPPORT_P_H
18#include <QtMultimedia/qtmultimediaglobal.h>
19#include <QtMultimedia/qaudioformat.h>
20#include <QtMultimedia/qaudiodevice.h>
21#include <QtMultimedia/private/qautoresetevent_p.h>
22#include <QtMultimedia/private/qaudio_qiodevice_support_p.h>
23#include <QtMultimedia/private/qaudio_rtsan_support_p.h>
24#include <QtMultimedia/private/qaudiosystem_p.h>
25#include <QtMultimedia/private/qaudiohelpers_p.h>
26#include <QtMultimedia/private/qaudioringbuffer_p.h>
27#include <QtCore/qscopedvaluerollback.h>
28#include <QtCore/qthread.h>
51 const std::optional<int32_t> &hardwareBufferFrames,
52 const QAudioFormat &);
54 const std::optional<int32_t> &hardwareBufferFrames,
55 const QAudioFormat &);
62 std::optional<
int> ringbufferSize,
63 std::optional<int32_t> hardwareBufferFrames,
float volume);
68 float volume()
const {
return m_volume.load(std::memory_order_relaxed); }
70 template <
typename Functor>
73 return std::visit(f, m_ringbuffer);
76 template <
typename Functor>
79 return std::visit(f, m_ringbuffer);
89 return m_stopRequested.load(memory_order);
98 std::atomic<
float> m_volume{
102 Ringbuffer m_ringbuffer{
108 std::atomic<
bool> m_stopRequested =
false;
130 std::optional<int32_t> hardwareBufferFrames,
float volume);
158 return m_streamIsIdle.load(order);
162 template <
typename Functor>
165 return m_streamIdleDetectionNotifier.callOnActivated(std::forward<Functor>(f));
168 template <
typename ParentType>
172 Q_ASSERT(thread()->isCurrentThread());
173 parent->m_stream = {};
174 parent->setError(QAudio::IOError);
175 parent->updateStreamState(QtAudio::State::StoppedState);
181 template <
typename Functor>
185 QMetaObject::invokeMethod(&m_streamIdleDetectionNotifier, std::forward<Functor>(f));
190 QIODevice *m_device =
nullptr;
193 std::atomic<
bool> m_streamIsIdle =
false;
194 QAutoResetEvent m_streamIdleDetectionNotifier;
195 QMetaObject::Connection m_streamIdleDetectionConnection;
198 QAutoResetEvent m_ringbufferHasSpace;
199 QMetaObject::Connection m_ringbufferHasSpaceConnection;
200 QMetaObject::Connection m_iodeviceHasNewDataConnection;
202 std::unique_ptr<QtPrivate::QIODeviceRingBufferWriterBase> m_ringbufferWriterDevice;
205 std::atomic_int64_t m_totalFrameCount{};
206 std::atomic_int64_t m_processedFrameCount{};
208 void convertToNative(QSpan<
const std::byte> internal, QSpan<std::byte> native,
float volume,
214 template <
typename Functor>
215 void withPullIODeviceReentrancyGuard(Functor f)
217 if (!m_pullIODeviceReentrancyGuard) {
218 QScopedValueRollback<
bool> guard{
219 m_pullIODeviceReentrancyGuard,
224 QMetaObject::invokeMethod(&m_streamIdleDetectionNotifier,
225 [
this, f = std::move(f)]()
mutable {
226 withPullIODeviceReentrancyGuard(std::move(f));
227 }, Qt::QueuedConnection);
230 bool m_pullIODeviceReentrancyGuard =
false;
232 void pullFromQIODeviceImpl();
247 std::optional<
int> ringbufferSize,
248 std::optional<int32_t> hardwareBufferFrames,
float volume);
273 template <
typename ParentType>
277 Q_ASSERT(thread()->isCurrentThread());
282 parent->m_retiredStream =
std::move(parent->m_stream);
284 parent->m_stream = {};
286 parent->setError(QAudio::IOError);
287 parent->updateStreamState(QtAudio::State::StoppedState);
293 template <
typename Functor>
297 QMetaObject::invokeMethod(&m_ringbufferHasData, std::forward<Functor>(f));
302 QIODevice *m_device =
nullptr;
303 std::unique_ptr<QIODevice> m_ringbufferReaderDevice;
306 QAutoResetEvent m_ringbufferHasData;
307 QAutoResetEvent m_ringbufferIsFull;
309 QMetaObject::Connection m_ringbufferHasDataConnection;
310 QMetaObject::Connection m_ringbufferIsFullConnection;
313 std::atomic_uint64_t m_totalNumberOfFramesPushedToRingbuffer{};
315 void convertFromNative(QSpan<
const std::byte> native, QSpan<std::byte> internal,
float volume,
Combined button and popup list for selecting options.