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);
169 if (!validateAudioCallback(audioCallback, m_format)) {
170 setError(QAudio::OpenError);
175 qWarning(
"QAudioSink::start() called while already started");
179 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
180 static_cast<ConcreteSinkType *>(
this), volume(),
181 m_hardwareBufferFrames, m_role);
183 if (!m_stream->open())
186 bool started = m_stream->start(std::move(audioCallback));
190 updateStreamState(QAudio::ActiveState);
197 qWarning(
"QAudioSink::start() called while already started");
201 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
202 static_cast<ConcreteSinkType *>(
this), volume(),
203 m_hardwareBufferFrames, m_role);
205 if (!m_stream->open()) {
210 QIODevice *device = m_stream->start();
216 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
217 updateStreamIdle(
false);
219 updateStreamIdle(
true);
220 updateStreamState(QAudio::ActiveState);
228 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
230 updateStreamState(QAudio::StoppedState);
238 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
240 updateStreamState(QAudio::StoppedState);
249 updateStreamState(QAudio::SuspendedState);
257 updateStreamState(QAudio::ActiveState);
266 return m_stream->bytesFree();
273 m_internalBufferSize = value;
280 return m_stream->ringbufferSizeInBytes();
282 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
283 m_hardwareBufferFrames, m_format);
290 m_hardwareBufferFrames = arg;
292 m_hardwareBufferFrames = std::nullopt;
298 return m_hardwareBufferFrames.value_or(-1);
305 return m_stream->processedDuration().count();
313 QPlatformAudioEndpointBase::setVolume(volume);
315 m_stream->setVolume(volume);
330#undef STREAM_TYPE_ARG
367# define STREAM_TYPE_ARG QPlatformSourceStream StreamType
369# define STREAM_TYPE_ARG typename StreamType
380 void start(QIODevice *device)
override;
417 QAudioDevice device,
const QAudioFormat &format, QObject *parent)
431 m_stream->requestStop();
432 setError(QAudio::OpenError);
440 setError(QAudio::IOError);
445 qWarning(
"QAudioSource::start() called while already started");
449 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
450 static_cast<ConcreteSourceType *>(
this), volume(),
451 m_hardwareBufferFrames);
453 if (!m_stream->open())
456 bool started = m_stream->start(device);
460 updateStreamState(QAudio::ActiveState);
467 qWarning(
"QAudioSource::start() called while already started");
471 m_stream = std::make_shared<StreamType>(m_audioDevice, m_format, m_internalBufferSize,
472 static_cast<ConcreteSourceType *>(
this), volume(),
473 m_hardwareBufferFrames);
475 if (!m_stream->open()) {
480 QIODevice *device = m_stream->start();
486 QObject::connect(device, &QIODevice::readyRead,
this, [
this] {
487 updateStreamIdle(
false);
489 updateStreamIdle(
true, EmitStateSignal::False);
490 updateStreamState(QAudio::ActiveState);
500 if (m_stream->deviceIsRingbufferReader())
502 m_retiredStream = m_stream;
504 m_stream->stop(ShutdownPolicy::DrainRingbuffer);
506 updateStreamState(QAudio::StoppedState);
512 m_retiredStream = {};
517 m_stream->stop(ShutdownPolicy::DiscardRingbuffer);
519 updateStreamState(QAudio::StoppedState);
527 updateStreamState(QAudio::SuspendedState);
535 updateStreamState(QAudio::ActiveState);
543 return m_stream ? m_stream->bytesReady() : 0;
549 m_internalBufferSize = value;
556 return m_stream->ringbufferSizeInBytes();
558 return QPlatformAudioIOStream::inferRingbufferBytes(m_internalBufferSize,
559 m_hardwareBufferFrames, m_format);
567 m_hardwareBufferFrames = arg;
569 m_hardwareBufferFrames = std::nullopt;
575 return m_hardwareBufferFrames.value_or(-1);
581 return m_stream ? m_stream->processedDuration().count() : 0;
587 QPlatformAudioEndpointBase::setVolume(volume);
589 m_stream->setVolume(volume);
604 QT_WARNING_DISABLE_CLANG(
"-Woverloaded-virtual")
612 QPlatformAudioSource::AudioCallback &&audioCallback)
615 if (!validateAudioCallback(audioCallback,
BaseClass::m_format)) {
616 BaseClass::setError(QAudio::OpenError);
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