4#ifndef QAUDIO_PLATFORM_IMPLEMENTATION_SUPPORT_P_H
5#define QAUDIO_PLATFORM_IMPLEMENTATION_SUPPORT_P_H
18#include <QtMultimedia/qtmultimediaglobal.h>
20#include <QtMultimedia/private/qaudiosystem_p.h>
21#include <QtMultimedia/private/qaudiosystem_platform_stream_support_p.h>
64# define STREAM_TYPE_ARG QPlatformSinkStream StreamType
66# define STREAM_TYPE_ARG typename StreamType
77 void start(QIODevice *device)
override;
78 void start(AudioCallback &&)
override;
96 void setRole(AudioEndpointRole role)
override;
115 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
130 setError(QAudio::IOError);
135 qWarning(
"QAudioSink::start() called while already started");
139 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
140 static_cast<ConcreteSinkType *>(
this), volume(),
141 m_hardwareBufferFrames, m_role);
143 if (!m_stream->open()) {
144 setError(QAudio::OpenError);
149 m_stream->start(device);
150 updateStreamState(QAudio::ActiveState);
157 if (!validateAudioCallback(audioCallback, m_format)) {
158 setError(QAudio::OpenError);
163 qWarning(
"QAudioSink::start() called while already started");
167 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
168 static_cast<ConcreteSinkType *>(
this), volume(),
169 m_hardwareBufferFrames, m_role);
171 if (!m_stream->open()) {
172 setError(QAudio::OpenError);
177 bool started = m_stream->start(std::move(audioCallback));
179 setError(QAudio::OpenError);
184 updateStreamState(QAudio::ActiveState);
191 qWarning(
"QAudioSink::start() called while already started");
195 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
196 static_cast<ConcreteSinkType *>(
this), volume(),
197 m_hardwareBufferFrames, m_role);
199 if (!m_stream->open()) {
200 setError(QAudio::OpenError);
205 QIODevice *device = m_stream->start();
206 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
207 updateStreamIdle(
false);
209 updateStreamIdle(
true);
210 updateStreamState(QAudio::ActiveState);
218 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
220 updateStreamState(QAudio::StoppedState);
228 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
230 updateStreamState(QAudio::StoppedState);
239 updateStreamState(QAudio::SuspendedState);
247 updateStreamState(QAudio::ActiveState);
256 return m_stream->bytesFree();
263 m_internalBufferSize = value;
270 return m_stream->ringbufferSizeInBytes();
272 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
273 m_hardwareBufferFrames, m_format);
280 m_hardwareBufferFrames = arg;
282 m_hardwareBufferFrames = std::nullopt;
288 return m_hardwareBufferFrames.value_or(-1);
295 return m_stream->processedDuration().count();
303 QPlatformAudioEndpointBase::setVolume(volume);
305 m_stream->setVolume(volume);
320#undef STREAM_TYPE_ARG
357# define STREAM_TYPE_ARG QPlatformSourceStream StreamType
359# define STREAM_TYPE_ARG typename StreamType
370 void start(QIODevice *device)
override;
405 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
420 setError(QAudio::IOError);
425 qWarning(
"QAudioSource::start() called while already started");
429 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
430 static_cast<ConcreteSourceType *>(
this), volume(),
431 m_hardwareBufferFrames);
433 if (!m_stream->open()) {
434 setError(QAudio::OpenError);
439 m_stream->start(device);
440 updateStreamState(QAudio::ActiveState);
447 qWarning(
"QAudioSource::start() called while already started");
451 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
452 static_cast<ConcreteSourceType *>(
this), volume(),
453 m_hardwareBufferFrames);
455 if (!m_stream->open()) {
456 setError(QAudio::OpenError);
461 QIODevice *device = m_stream->start();
462 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
463 updateStreamIdle(
false);
465 updateStreamIdle(
true, EmitStateSignal::False);
466 updateStreamState(QAudio::ActiveState);
476 if (m_stream->deviceIsRingbufferReader())
478 m_retiredStream = m_stream;
480 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
482 updateStreamState(QAudio::StoppedState);
488 m_retiredStream = {};
493 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
495 updateStreamState(QAudio::StoppedState);
503 updateStreamState(QAudio::SuspendedState);
511 updateStreamState(QAudio::ActiveState);
519 return m_stream ? m_stream->bytesReady() : 0;
525 m_internalBufferSize = value;
532 return m_stream->ringbufferSizeInBytes();
534 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
535 m_hardwareBufferFrames, m_format);
543 m_hardwareBufferFrames = arg;
545 m_hardwareBufferFrames = std::nullopt;
551 return m_hardwareBufferFrames.value_or(-1);
557 return m_stream ? m_stream->processedDuration().count() : 0;
563 QPlatformAudioEndpointBase::setVolume(volume);
565 m_stream->setVolume(volume);
580 QT_WARNING_DISABLE_CLANG(
"-Woverloaded-virtual")
588 QPlatformAudioSource::AudioCallback &&audioCallback)
591 if (!validateAudioCallback(audioCallback,
BaseClass::m_format)) {
592 BaseClass::setError(QAudio::OpenError);
596 BaseClass::m_stream = std::make_shared<StreamType>(
597 BaseClass::m_audioDevice, BaseClass::m_format, BaseClass::m_internalBufferSize,
598 static_cast<
typename BaseClass::ConcreteSourceType *>(
this), BaseClass::volume(),
599 BaseClass::m_hardwareBufferFrames);
602 BaseClass::setError(QAudio::OpenError);
607 bool started = BaseClass::m_stream->start(std::move(audioCallback));
609 BaseClass::setError(QAudio::OpenError);
614 BaseClass::updateStreamState(QAudio::ActiveState);
617#undef STREAM_TYPE_ARG