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;
117 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
132 setError(QAudio::IOError);
137 qWarning(
"QAudioSink::start() called while already started");
141 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
142 static_cast<ConcreteSinkType *>(
this), volume(),
143 m_hardwareBufferFrames, m_role);
145 if (!m_stream->open())
148 bool started = m_stream->start(device);
152 updateStreamState(QAudio::ActiveState);
159 m_stream->requestStop();
160 setError(QAudio::OpenError);
170 qWarning(
"QAudioSink::start() called while already started");
174 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
175 static_cast<ConcreteSinkType *>(
this), volume(),
176 m_hardwareBufferFrames, m_role);
178 if (!m_stream->open())
181 bool started = m_stream->start(std::move(audioCallback));
185 updateStreamState(QAudio::ActiveState);
192 qWarning(
"QAudioSink::start() called while already started");
196 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
197 static_cast<ConcreteSinkType *>(
this), volume(),
198 m_hardwareBufferFrames, m_role);
200 if (!m_stream->open()) {
205 QIODevice *device = m_stream->start();
211 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
212 updateStreamIdle(
false);
214 updateStreamIdle(
true);
215 updateStreamState(QAudio::ActiveState);
223 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
225 updateStreamState(QAudio::StoppedState);
227 setError(QtAudio::NoError);
234 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
236 updateStreamState(QAudio::StoppedState);
238 setError(QtAudio::NoError);
245 if (state() == QAudio::SuspendedState)
249 updateStreamState(QAudio::SuspendedState);
257 if (state() != QAudio::SuspendedState)
260 updateStreamState(QAudio::ActiveState);
269 return m_stream->bytesFree();
276 m_internalBufferSize = value;
283 return m_stream->ringbufferSizeInBytes();
285 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
286 m_hardwareBufferFrames, m_format);
293 m_hardwareBufferFrames = arg;
295 m_hardwareBufferFrames = std::nullopt;
301 return m_hardwareBufferFrames.value_or(-1);
308 return m_stream->processedDuration().count();
316 QPlatformAudioEndpointBase::setVolume(volume);
318 m_stream->setVolume(volume);
333#undef STREAM_TYPE_ARG
370# define STREAM_TYPE_ARG QPlatformSourceStream StreamType
372# define STREAM_TYPE_ARG typename StreamType
383 void start(QIODevice *device)
override;
420 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
434 m_stream->requestStop();
435 setError(QAudio::OpenError);
443 setError(QAudio::IOError);
448 qWarning(
"QAudioSource::start() called while already started");
452 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
453 static_cast<ConcreteSourceType *>(
this), volume(),
454 m_hardwareBufferFrames);
456 if (!m_stream->open())
459 bool started = m_stream->start(device);
463 updateStreamState(QAudio::ActiveState);
470 qWarning(
"QAudioSource::start() called while already started");
474 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
475 static_cast<ConcreteSourceType *>(
this), volume(),
476 m_hardwareBufferFrames);
478 if (!m_stream->open()) {
483 QIODevice *device = m_stream->start();
489 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
490 updateStreamIdle(
false);
492 updateStreamIdle(
true, EmitStateSignal::False);
493 updateStreamState(QAudio::ActiveState);
503 if (m_stream->deviceIsRingbufferReader())
505 m_retiredStream = m_stream;
507 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
509 setError(QtAudio::NoError);
510 updateStreamState(QAudio::StoppedState);
516 m_retiredStream = {};
521 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
523 setError(QtAudio::NoError);
524 updateStreamState(QAudio::StoppedState);
532 updateStreamState(QAudio::SuspendedState);
540 updateStreamState(QAudio::ActiveState);
548 return m_stream ? m_stream->bytesReady() : 0;
554 m_internalBufferSize = value;
561 return m_stream->ringbufferSizeInBytes();
563 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
564 m_hardwareBufferFrames, m_format);
572 m_hardwareBufferFrames = arg;
574 m_hardwareBufferFrames = std::nullopt;
580 return m_hardwareBufferFrames.value_or(-1);
586 return m_stream ? m_stream->processedDuration().count() : 0;
592 QPlatformAudioEndpointBase::setVolume(volume);
594 m_stream->setVolume(volume);
609 QT_WARNING_DISABLE_CLANG(
"-Woverloaded-virtual")
617 QPlatformAudioSource::AudioCallback &&audioCallback)
621 BaseClass::m_stream = std::make_shared<StreamType>(
622 BaseClass::m_audioDevice, BaseClass::m_format, BaseClass::m_internalBufferSize,
623 static_cast<
typename BaseClass::ConcreteSourceType *>(
this), BaseClass::volume(),
624 BaseClass::m_hardwareBufferFrames);
627 return BaseClass::handleStreamOpenError();
629 bool started =
BaseClass::m_stream->start(std::move(audioCallback));
631 return BaseClass::handleStreamOpenError();
633 BaseClass::updateStreamState(QAudio::ActiveState);
636#undef STREAM_TYPE_ARG