// Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QPIPEWIRE_AUDIOSOURCE_P_H #define QPIPEWIRE_AUDIOSOURCE_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include QT_BEGIN_NAMESPACE namespace QtPipeWire { using namespace QtMultimediaPrivate; class QPipewireAudioSource; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // LATER: // ideally the ringbuffer should fill a buffer that can grow via a worker thread on which we can // allocate. struct QPipewireAudioSourceStream final : std::enable_shared_from_this, QPipewireAudioStream, QPlatformAudioSourceStream { using SourceType = QPipewireAudioSource; using SampleFormat = QAudioFormat::SampleFormat; QPipewireAudioSourceStream(QAudioDevice, const QAudioFormat &, std::optional ringbufferSize, QPipewireAudioSource *parent, float volume, std::optional hardwareBufferFrames); Q_DISABLE_COPY_MOVE(QPipewireAudioSourceStream) ~QPipewireAudioSourceStream(); bool open() { return true; } bool start(QIODevice *device); QIODevice *start(); void stop(ShutdownPolicy); using QPlatformAudioSourceStream::bytesReady; using QPlatformAudioSourceStream::deviceIsRingbufferReader; using QPlatformAudioSourceStream::processedDuration; using QPlatformAudioSourceStream::ringbufferSizeInBytes; using QPlatformAudioSourceStream::setVolume; void updateStreamIdle(bool idle) override; private: std::optional findSourceNodeSerial(); using QPlatformAudioSourceStream::m_format; void processRingbuffer() noexcept QT_MM_NONBLOCKING override; void processCallback() noexcept QT_MM_NONBLOCKING override { Q_ASSERT(false); } void handleDeviceRemoved() override; void stateChanged(pw_stream_state old, pw_stream_state state, const char *error) override; void disconnectStream(); std::shared_ptr m_self; QSemaphore m_streamDisconnected; // xrun detection void xrunOccurred(int /*xrunCount*/) override { m_xrunOccurred.set(); } QtPrivate::QAutoResetEvent m_xrunOccurred; QMetaObject::Connection m_xrunNotification; QPipewireAudioSource *m_parent; }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class QPipewireAudioSource final : public QPlatformAudioSourceImplementation { using BaseClass = QPlatformAudioSourceImplementation; public: QPipewireAudioSource(QAudioDevice, const QAudioFormat &, QObject *parent); void reportXRuns(int); }; } // namespace QtPipeWire QT_END_NAMESPACE #endif