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);
233 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
235 updateStreamState(QAudio::StoppedState);
244 updateStreamState(QAudio::SuspendedState);
252 updateStreamState(QAudio::ActiveState);
261 return m_stream->bytesFree();
268 m_internalBufferSize = value;
275 return m_stream->ringbufferSizeInBytes();
277 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
278 m_hardwareBufferFrames, m_format);
285 m_hardwareBufferFrames = arg;
287 m_hardwareBufferFrames = std::nullopt;
293 return m_hardwareBufferFrames.value_or(-1);
300 return m_stream->processedDuration().count();
308 QPlatformAudioEndpointBase::setVolume(volume);
310 m_stream->setVolume(volume);
325#undef STREAM_TYPE_ARG
362# define STREAM_TYPE_ARG QPlatformSourceStream StreamType
364# define STREAM_TYPE_ARG typename StreamType
375 void start(QIODevice *device)
override;
412 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
426 m_stream->requestStop();
427 setError(QAudio::OpenError);
435 setError(QAudio::IOError);
440 qWarning(
"QAudioSource::start() called while already started");
444 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
445 static_cast<ConcreteSourceType *>(
this), volume(),
446 m_hardwareBufferFrames);
448 if (!m_stream->open())
451 bool started = m_stream->start(device);
455 updateStreamState(QAudio::ActiveState);
462 qWarning(
"QAudioSource::start() called while already started");
466 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
467 static_cast<ConcreteSourceType *>(
this), volume(),
468 m_hardwareBufferFrames);
470 if (!m_stream->open()) {
475 QIODevice *device = m_stream->start();
481 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
482 updateStreamIdle(
false);
484 updateStreamIdle(
true, EmitStateSignal::False);
485 updateStreamState(QAudio::ActiveState);
495 if (m_stream->deviceIsRingbufferReader())
497 m_retiredStream = m_stream;
499 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
501 updateStreamState(QAudio::StoppedState);
507 m_retiredStream = {};
512 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
514 updateStreamState(QAudio::StoppedState);
522 updateStreamState(QAudio::SuspendedState);
530 updateStreamState(QAudio::ActiveState);
538 return m_stream ? m_stream->bytesReady() : 0;
544 m_internalBufferSize = value;
551 return m_stream->ringbufferSizeInBytes();
553 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
554 m_hardwareBufferFrames, m_format);
562 m_hardwareBufferFrames = arg;
564 m_hardwareBufferFrames = std::nullopt;
570 return m_hardwareBufferFrames.value_or(-1);
576 return m_stream ? m_stream->processedDuration().count() : 0;
582 QPlatformAudioEndpointBase::setVolume(volume);
584 m_stream->setVolume(volume);
599 QT_WARNING_DISABLE_CLANG(
"-Woverloaded-virtual")
607 QPlatformAudioSource::AudioCallback &&audioCallback)
611 BaseClass::m_stream = std::make_shared<StreamType>(
612 BaseClass::m_audioDevice, BaseClass::m_format, BaseClass::m_internalBufferSize,
613 static_cast<
typename BaseClass::ConcreteSourceType *>(
this), BaseClass::volume(),
614 BaseClass::m_hardwareBufferFrames);
617 return BaseClass::handleStreamOpenError();
619 bool started =
BaseClass::m_stream->start(std::move(audioCallback));
621 return BaseClass::handleStreamOpenError();
623 BaseClass::updateStreamState(QAudio::ActiveState);
626#undef STREAM_TYPE_ARG