4#ifndef QAUDIO_PLATFORM_IMPLEMENTATION_SUPPORT_P_H
5#define QAUDIO_PLATFORM_IMPLEMENTATION_SUPPORT_P_H
18#include <QtMultimedia/private/qaudiosystem_p.h>
19#include <QtMultimedia/private/qaudiosystem_platform_stream_support_p.h>
20#include <QtMultimedia/qtmultimediaglobal.h>
63# define STREAM_TYPE_ARG QPlatformSinkStream StreamType
65# define STREAM_TYPE_ARG typename StreamType
76 void start(QIODevice *device)
override;
77 void start(AudioCallback &&)
override;
95 void setRole(AudioEndpointRole role)
override;
116 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
131 setError(QAudio::IOError);
136 qWarning(
"QAudioSink::start() called while already started");
140 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
141 static_cast<ConcreteSinkType *>(
this), volume(),
142 m_hardwareBufferFrames, m_role);
144 if (!m_stream->open())
147 bool started = m_stream->start(device);
151 updateStreamState(QAudio::ActiveState);
158 m_stream->requestStop();
159 setError(QAudio::OpenError);
169 qWarning(
"QAudioSink::start() called while already started");
173 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
174 static_cast<ConcreteSinkType *>(
this), volume(),
175 m_hardwareBufferFrames, m_role);
177 if (!m_stream->open())
180 bool started = m_stream->start(std::move(audioCallback));
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()) {
204 QIODevice *device = m_stream->start();
210 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
211 updateStreamIdle(
false);
213 updateStreamIdle(
true);
214 updateStreamState(QAudio::ActiveState);
222 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
224 updateStreamState(QAudio::StoppedState);
226 setError(QtAudio::NoError);
233 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
235 updateStreamState(QAudio::StoppedState);
237 setError(QtAudio::NoError);
244 if (state() == QAudio::SuspendedState)
248 updateStreamState(QAudio::SuspendedState);
256 if (state() != QAudio::SuspendedState)
259 updateStreamState(QAudio::ActiveState);
268 return m_stream->bytesFree();
275 m_internalBufferSize = value;
282 return m_stream->ringbufferSizeInBytes();
284 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
285 m_hardwareBufferFrames, m_format);
292 m_hardwareBufferFrames = arg;
294 m_hardwareBufferFrames = std::nullopt;
300 return m_hardwareBufferFrames.value_or(-1);
307 return m_stream->processedDuration().count();
315 QPlatformAudioEndpointBase::setVolume(volume);
317 m_stream->setVolume(volume);
332#undef STREAM_TYPE_ARG
369# define STREAM_TYPE_ARG QPlatformSourceStream StreamType
371# define STREAM_TYPE_ARG typename StreamType
382 void start(QIODevice *device)
override;
419 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
433 m_stream->requestStop();
434 setError(QAudio::OpenError);
442 setError(QAudio::IOError);
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())
458 bool started = m_stream->start(device);
462 updateStreamState(QAudio::ActiveState);
469 qWarning(
"QAudioSource::start() called while already started");
473 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
474 static_cast<ConcreteSourceType *>(
this), volume(),
475 m_hardwareBufferFrames);
477 if (!m_stream->open()) {
482 QIODevice *device = m_stream->start();
488 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
489 updateStreamIdle(
false);
491 updateStreamIdle(
true, EmitStateSignal::False);
492 updateStreamState(QAudio::ActiveState);
502 if (m_stream->deviceIsRingbufferReader())
504 m_retiredStream = m_stream;
506 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
508 setError(QtAudio::NoError);
509 updateStreamState(QAudio::StoppedState);
515 m_retiredStream = {};
520 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
522 setError(QtAudio::NoError);
523 updateStreamState(QAudio::StoppedState);
531 updateStreamState(QAudio::SuspendedState);
539 updateStreamState(QAudio::ActiveState);
547 return m_stream ? m_stream->bytesReady() : 0;
553 m_internalBufferSize = value;
560 return m_stream->ringbufferSizeInBytes();
562 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
563 m_hardwareBufferFrames, m_format);
571 m_hardwareBufferFrames = arg;
573 m_hardwareBufferFrames = std::nullopt;
579 return m_hardwareBufferFrames.value_or(-1);
585 return m_stream ? m_stream->processedDuration().count() : 0;
591 QPlatformAudioEndpointBase::setVolume(volume);
593 m_stream->setVolume(volume);
608 QT_WARNING_DISABLE_CLANG(
"-Woverloaded-virtual")
616 QPlatformAudioSource::AudioCallback &&audioCallback)
620 BaseClass::m_stream = std::make_shared<StreamType>(
621 BaseClass::m_audioDevice, BaseClass::m_format, BaseClass::m_internalBufferSize,
622 static_cast<
typename BaseClass::ConcreteSourceType *>(
this), BaseClass::volume(),
623 BaseClass::m_hardwareBufferFrames);
626 return BaseClass::handleStreamOpenError();
628 bool started =
BaseClass::m_stream->start(std::move(audioCallback));
630 return BaseClass::handleStreamOpenError();
632 BaseClass::updateStreamState(QAudio::ActiveState);
635#undef STREAM_TYPE_ARG