Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qplatformaudiodevices.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtMultimedia/private/qaudiosystem_p.h>
7#include <QtMultimedia/qaudiodevice.h>
8#include <QtMultimedia/qmediadevices.h>
9#include <QtCore/private/qminimalflatset_p.h>
10#include <QtCore/qdebug.h>
11#include <QtCore/qvarlengtharray.h>
12
13#if defined(Q_OS_ANDROID)
14# include <QtMultimedia/private/qandroidaudiodevices_p.h>
15#endif
16#if QT_CONFIG(ohaudio)
17# include <QtMultimedia/private/qohosaudiodevices_p.h>
18#endif
19#if defined(Q_OS_DARWIN)
20# include <QtMultimedia/private/qcoreaudiodevices_p.h>
21#endif
22#if defined(Q_OS_WINDOWS)
23# include <QtMultimedia/private/qwindowsaudiodevices_p.h>
24#endif
25#if QT_CONFIG(alsa)
26# include <QtMultimedia/private/qalsaaudiodevices_p.h>
27#endif
28#if QT_CONFIG(pulseaudio)
29# include <QtMultimedia/private/qpulseaudiodevices_p.h>
30# include <QtMultimedia/private/qpulsehelpers_p.h>
31#endif
32#if QT_CONFIG(pipewire)
33# include <QtMultimedia/private/qpipewire_audiodevices_p.h>
34#endif
35#if defined(Q_OS_QNX) && defined(QT_MM_QNX_IO_SND)
36# include <QtMultimedia/private/qqnxsndaudiodevices_p.h>
37#endif
38#if defined(Q_OS_QNX) && defined(QT_MM_QNX_IO_AUDIO)
39# include <QtMultimedia/private/qqnxaudiodevices_p.h>
40#endif
41#if defined(Q_OS_WASM)
42# include <QtMultimedia/private/qwasmmediadevices_p.h>
43#endif
44
46
47using namespace Qt::Literals;
48
49std::unique_ptr<QPlatformAudioDevices> QPlatformAudioDevices::create()
50{
51#ifdef Q_OS_DARWIN
52 return std::make_unique<QCoreAudioDevices>();
53#endif
54#if defined(Q_OS_WINDOWS)
55 return std::make_unique<QWindowsAudioDevices>();
56#endif
57#if defined(Q_OS_ANDROID)
58 return std::make_unique<QAndroidAudioDevices>();
59#endif
60#if QT_CONFIG(ohaudio)
61 return std::make_unique<QOhosAudioDevices>();
62#endif
63#if QT_CONFIG(pipewire)
64 QByteArray requestedBackend = qgetenv("QT_AUDIO_BACKEND");
65 const bool pipewireRequested = requestedBackend == "pipewire"_ba;
66
67# if QT_CONFIG(pulseaudio)
68 using namespace QPulseAudioInternal;
69 // Check if PulseAudio is actually the vanilla PulseAudio server, not PipeWire's PulseAudio server.
70 // Some funny still distros ship PipeWire and PulseAudio side by side. In that case, we should not
71 // use the PipeWire backend, as it might not report any audio devices.
72 auto skipPipewire = [&] {
73 if (pipewireRequested)
74 return false;
75 return requestedBackend.isNull()
76 && pulseaudioDetectServerType() == PulseaudioServerType::Pulseaudio;
77 };
78# else
79 auto skipPipewire = [] {
80 return false;
81 };
82# endif
83
84 const bool considerPipewire = requestedBackend.isNull() || pipewireRequested;
85
86 if (considerPipewire && QtPipeWire::QAudioDevices::isSupported()) {
87 if (!skipPipewire())
88 return std::make_unique<QtPipeWire::QAudioDevices>();
89 }
90
91 if (pipewireRequested)
92 qDebug() << "PipeWire audio backend requested. not available. Using default backend";
93
94#endif
95#if QT_CONFIG(pulseaudio)
96 return std::make_unique<QPulseAudioDevices>();
97#endif
98#if QT_CONFIG(alsa)
99 return std::make_unique<QAlsaAudioDevices>();
100#endif
101#if defined(Q_OS_QNX) && defined(QT_MM_QNX_IO_SND)
102 return std::make_unique<QQnxSndAudioDevices>();
103#endif
104#if defined(Q_OS_QNX) && defined(QT_MM_QNX_IO_AUDIO)
105 return std::make_unique<QQnxAudioDevices>();
106#endif
107#if defined(Q_OS_WASM)
108 return std::make_unique<QWasmAudioDevices>();
109#endif
110 return std::make_unique<QPlatformAudioDevices>();
111}
112
113QPlatformAudioDevices::QPlatformAudioDevices()
114{
115 qRegisterMetaType<PrivateTag>(); // for the case of queued connections
116}
117
118QPlatformAudioDevices::~QPlatformAudioDevices() = default;
119
120QList<QAudioDevice> QPlatformAudioDevices::audioInputs() const
121{
122 return m_audioInputs.ensure([this]() {
123 return findAudioInputs();
124 });
125}
126
127QList<QAudioDevice> QPlatformAudioDevices::audioOutputs() const
128{
129 return m_audioOutputs.ensure([this]() {
130 return findAudioOutputs();
131 });
132}
133
134void QPlatformAudioDevices::onAudioInputsChanged()
135{
136 m_audioInputs.reset();
137 emit audioInputsChanged(PrivateTag{});
138}
139
140void QPlatformAudioDevices::onAudioOutputsChanged()
141{
142 m_audioOutputs.reset();
143 emit audioOutputsChanged(PrivateTag{});
144}
145
146void QPlatformAudioDevices::updateAudioInputsCache()
147{
148 if (m_audioInputs.update(findAudioInputs()))
149 emit audioInputsChanged(PrivateTag{});
150}
151
152void QPlatformAudioDevices::updateAudioOutputsCache()
153{
154 if (m_audioOutputs.update(findAudioOutputs()))
155 emit audioOutputsChanged(PrivateTag{});
156}
157
158QPlatformAudioSource *QPlatformAudioDevices::createAudioSource(const QAudioDevice &,
159 const QAudioFormat &, QObject *)
160{
161 return nullptr;
162}
163QPlatformAudioSink *QPlatformAudioDevices::createAudioSink(const QAudioDevice &,
164 const QAudioFormat &, QObject *)
165{
166 return nullptr;
167}
168
169QPlatformAudioSource *QPlatformAudioDevices::audioInputDevice(QAudioFormat format,
170 const QAudioDevice &deviceInfo,
171 QObject *parent)
172{
173 QAudioDevice device = deviceInfo;
174 if (device.isNull())
175 device = QMediaDevices::defaultAudioInput();
176
177 if (device.isNull())
178 return nullptr;
179
180 if (format == QAudioFormat{})
181 format = device.preferredFormat();
182
183 return createAudioSource(device, format, parent);
184}
185
186QPlatformAudioSink *QPlatformAudioDevices::audioOutputDevice(QAudioFormat format,
187 const QAudioDevice &deviceInfo,
188 QObject *parent)
189{
190 QAudioDevice device = deviceInfo;
191 if (device.isNull())
192 device = QMediaDevices::defaultAudioOutput();
193
194 if (device.isNull())
195 return nullptr;
196
197 if (format == QAudioFormat{})
198 format = device.preferredFormat();
199
200 return createAudioSink(device, format, parent);
201}
202
203bool QPlatformAudioDevices::hasCallbackApi() const
204{
205 return false;
206}
207
208QT_END_NAMESPACE
209
210#include "moc_qplatformaudiodevices_p.cpp"
Combined button and popup list for selecting options.