19#include <qaudioformat.h>
20#include <pulse/pulseaudio.h>
22#include <QtMultimedia/private/qsharedhandle_p.h>
24#include <QtCore/qdebug.h>
25#include <QtCore/qloggingcategory.h>
29Q_DECLARE_LOGGING_CATEGORY(qLcPulseAudioOut)
30Q_DECLARE_LOGGING_CATEGORY(qLcPulseAudioIn)
31Q_DECLARE_LOGGING_CATEGORY(qLcPulseAudioEngine)
33namespace QPulseAudioInternal
36template <
typename TypeArg, TypeArg *(*RefFn)(TypeArg *),
void (*UnrefFn)(TypeArg *)>
39 using Type = TypeArg *;
40 static constexpr Type invalidValue()
noexcept {
return nullptr; }
42 static Type ref(Type handle)
44 Type ret = (*RefFn)(handle);
47 static bool unref(Type handle)
54using PAOperationHandleTraits = PaHandleTraits<pa_operation, pa_operation_ref, pa_operation_unref>;
55using PAContextHandleTraits = PaHandleTraits<pa_context, pa_context_ref, pa_context_unref>;
56using PAStreamHandleTraits = PaHandleTraits<pa_stream, pa_stream_ref, pa_stream_unref>;
58using PAOperationHandle = QtPrivate::QSharedHandle<PAOperationHandleTraits>;
59using PAContextHandle = QtPrivate::QSharedHandle<PAContextHandleTraits>;
60using PAStreamHandle = QtPrivate::QSharedHandle<PAStreamHandleTraits>;
62struct PAProplistDeleter
64 void operator()(pa_proplist *propList) { pa_proplist_free(propList); }
67using PAProplistHandle = std::unique_ptr<pa_proplist, PAProplistDeleter>;
69struct PaMainLoopDeleter
71 void operator()(pa_threaded_mainloop *m)
const { pa_threaded_mainloop_free(m); }
74pa_sample_spec audioFormatToSampleSpec(
const QAudioFormat &format);
75QAudioFormat sampleSpecToAudioFormat(
const pa_sample_spec &spec);
76pa_channel_map channelMapForAudioFormat(
const QAudioFormat &format);
77QAudioFormat::ChannelConfig channelConfigFromMap(
const pa_channel_map &map);
79QUtf8StringView currentError(
const pa_context *);
80QUtf8StringView currentError(
const pa_stream *);
82[[nodiscard]] PAOperationHandle streamCork(
const PAStreamHandle &,
bool);
86QDebug operator<<(QDebug, pa_stream_state_t);
~QPulseAudioContextManager() override
bool isInMainLoop() const
void wait(const PAOperationHandle &op)
QByteArray defaultDevice(QAudioDevice::Mode mode) const
static QPulseAudioContextManager * instance()
bool waitForAsyncOperation(const PAOperationHandle &)
pa_context_state_t getContextState()
bool waitForAsyncOperation(pa_operation *op)
pa_threaded_mainloop * mainloop()
QList< QAudioDevice > availableDevices(QAudioDevice::Mode mode) const
QPulseAudioContextManager(QObject *parent=nullptr)
void audioOutputsChanged()
static bool updateDevicesMap(QReadWriteLock &lock, const QByteArray &defaultDeviceId, QMap< int, QAudioDevice > &devices, QAudioDevice::Mode mode, const Info &info)
Q_GLOBAL_STATIC(QPulseAudioContextManager, pulseEngine)
static std::unique_ptr< QAudioDevicePrivate > makeQAudioDevicePrivate(const char *device, const char *desc, bool isDef, QAudioDevice::Mode mode, const pa_channel_map &map, const pa_sample_spec &spec)
static bool updateDevicesMap(QReadWriteLock &lock, const QByteArray &defaultDeviceId, QMap< int, QAudioDevice > &devices)
QDebug operator<<(QDebug dbg, pa_sample_format format)
QDebug operator<<(QDebug dbg, pa_context_state_t state)