| 1 | // Copyright (C) 2016 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 | |
| 4 | #include "qaudiosystem_p.h" |
| 5 | #include "qaudiodevice_p.h" |
| 6 | #include <private/qplatformaudiodevices_p.h> |
| 7 | #include <private/qplatformmediaintegration_p.h> |
| 8 | |
| 9 | #include <QtCore/qmap.h> |
| 10 | |
| 11 | QT_BEGIN_NAMESPACE |
| 12 | |
| 13 | QAudioDevicePrivate::~QAudioDevicePrivate() = default; |
| 14 | |
| 15 | QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QAudioDevicePrivate); |
| 16 | |
| 17 | /*! |
| 18 | \class QAudioDevice |
| 19 | \brief The QAudioDevice class provides an information about audio devices and their |
| 20 | functionality. |
| 21 | \inmodule QtMultimedia |
| 22 | \ingroup multimedia |
| 23 | \ingroup multimedia_audio |
| 24 | |
| 25 | QAudioDevice describes an audio device available in the system, either for input or for |
| 26 | playback. |
| 27 | |
| 28 | A QAudioDevice is used by Qt to construct |
| 29 | classes that communicate with the device -- such as |
| 30 | QAudioSource, and QAudioSink. It is also used to determine the |
| 31 | input or output device to use in a capture session or during media playback. |
| 32 | |
| 33 | The QAudioDevice instance retains its properties throughout its lifetime, |
| 34 | even if the corresponding physical device is disconnected or its settings are |
| 35 | modified. To keep track of updated properties, the user should load new instances |
| 36 | of QAudioDevice from \l{QMediaDevices} when the relevant signals are fired. |
| 37 | |
| 38 | You can also query each device for the formats it supports. A |
| 39 | format in this context is a set consisting of a channel count, sample rate, and sample type. A |
| 40 | format is represented by the QAudioFormat class. |
| 41 | |
| 42 | The values supported by the device for each of these parameters can be |
| 43 | fetched with minimumChannelCount(), maximumChannelCount(), |
| 44 | minimumSampleRate(), maximumSampleRate() and supportedSampleFormats(). The |
| 45 | combinations supported are dependent on the audio device capabilities. If |
| 46 | you need a specific format, you can check if the device supports it with |
| 47 | isFormatSupported(). For instance: |
| 48 | |
| 49 | \snippet multimedia-snippets/audio.cpp Audio output setup |
| 50 | |
| 51 | The set of available devices can be retrieved from the QMediaDevices class. |
| 52 | |
| 53 | For instance: |
| 54 | |
| 55 | \snippet multimedia-snippets/audio.cpp Dumping audio formats |
| 56 | |
| 57 | In this code sample, we loop through all devices that are able to output |
| 58 | sound, i.e., play an audio stream in a supported format. For each device we |
| 59 | find, we simply print the deviceName(). |
| 60 | |
| 61 | \sa QAudioSink, QAudioSource, QAudioFormat |
| 62 | */ |
| 63 | |
| 64 | /*! |
| 65 | \qmlvaluetype audioDevice |
| 66 | \inqmlmodule QtMultimedia |
| 67 | \since 6.2 |
| 68 | //! \nativetype QAudioDevice |
| 69 | \brief Describes an audio device. |
| 70 | \ingroup multimedia_qml |
| 71 | \ingroup multimedia_audio_qml |
| 72 | \ingroup qmlvaluetypes |
| 73 | |
| 74 | The audioDevice value type describes the properties of an audio device that |
| 75 | is connected to the system. |
| 76 | |
| 77 | The audioDevice instance retains its properties throughout its lifetime, |
| 78 | even if the corresponding physical device is disconnected or its settings are |
| 79 | modified. To keep track of updated properties, the user should load new instances |
| 80 | of audioDevice from \l{MediaDevices} when the relevant signals are fired. |
| 81 | |
| 82 | The list of audio input or output devices can be queried from the \l{MediaDevices} |
| 83 | type. To select a certain audio device for input or output set it as the device |
| 84 | on \l{AudioInput} or \l{AudioOutput}. |
| 85 | |
| 86 | \qml |
| 87 | MediaPlayer { |
| 88 | audioOutput: AudioOutput { |
| 89 | device: mediaDevices.defaultAudioOutput |
| 90 | } |
| 91 | } |
| 92 | MediaDevices { |
| 93 | id: mediaDevices |
| 94 | } |
| 95 | \endqml |
| 96 | */ |
| 97 | |
| 98 | /*! |
| 99 | Constructs a null QAudioDevice object. |
| 100 | */ |
| 101 | QAudioDevice::QAudioDevice() = default; |
| 102 | |
| 103 | /*! |
| 104 | Constructs a copy of \a other. |
| 105 | */ |
| 106 | QAudioDevice::QAudioDevice(const QAudioDevice &other) = default; |
| 107 | |
| 108 | /*! |
| 109 | \fn QAudioDevice::QAudioDevice(QAudioDevice &&other) |
| 110 | |
| 111 | Move constructs from \a other. |
| 112 | */ |
| 113 | /*! |
| 114 | \fn void QAudioDevice::swap(QAudioDevice &other) noexcept |
| 115 | |
| 116 | Swaps the audio device with the \a other. |
| 117 | */ |
| 118 | /*! |
| 119 | Destroy this audio device info. |
| 120 | */ |
| 121 | QAudioDevice::~QAudioDevice() = default; |
| 122 | |
| 123 | /*! |
| 124 | Sets the QAudioDevice object to be equal to \a other. |
| 125 | */ |
| 126 | QAudioDevice &QAudioDevice::operator=(const QAudioDevice &other) = default; |
| 127 | |
| 128 | /*! |
| 129 | \fn QAudioDevice& QAudioDevice::operator=(QAudioDevice &&other) |
| 130 | |
| 131 | Moves \a other into this QAudioDevice object. |
| 132 | */ |
| 133 | |
| 134 | /*! |
| 135 | Returns true if this QAudioDevice class represents the |
| 136 | same audio device as \a other. |
| 137 | */ |
| 138 | bool QAudioDevice::operator==(const QAudioDevice &other) const |
| 139 | { |
| 140 | return mode() == other.mode() && id() == other.id(); |
| 141 | } |
| 142 | |
| 143 | /*! |
| 144 | Returns true if this QAudioDevice class represents a |
| 145 | different audio device than \a other |
| 146 | */ |
| 147 | bool QAudioDevice::operator!=(const QAudioDevice &other) const |
| 148 | { |
| 149 | return !operator==(other); |
| 150 | } |
| 151 | |
| 152 | /*! |
| 153 | Returns whether this QAudioDevice object holds a valid device definition. |
| 154 | */ |
| 155 | bool QAudioDevice::isNull() const |
| 156 | { |
| 157 | return d == nullptr; |
| 158 | } |
| 159 | |
| 160 | /*! |
| 161 | \qmlproperty string QtMultimedia::audioDevice::id |
| 162 | |
| 163 | Holds an identifier for the audio device. |
| 164 | |
| 165 | Device names vary depending on the platform/audio plugin being used. |
| 166 | |
| 167 | They are a unique identifier for the audio device. |
| 168 | */ |
| 169 | |
| 170 | /*! |
| 171 | \property QAudioDevice::id |
| 172 | |
| 173 | Returns an identifier for the audio device. |
| 174 | |
| 175 | Device names vary depending on the platform/audio plugin being used. |
| 176 | |
| 177 | They are a unique identifier for the audio device. |
| 178 | */ |
| 179 | QByteArray QAudioDevice::id() const |
| 180 | { |
| 181 | return isNull() ? QByteArray() : d->id; |
| 182 | } |
| 183 | |
| 184 | /*! |
| 185 | \qmlproperty string QtMultimedia::audioDevice::description |
| 186 | |
| 187 | Holds a human readable name of the audio device. |
| 188 | |
| 189 | Use this string to present the device to the user. |
| 190 | */ |
| 191 | |
| 192 | /*! |
| 193 | \property QAudioDevice::description |
| 194 | |
| 195 | Returns a human readable name of the audio device. |
| 196 | |
| 197 | Use this string to present the device to the user. |
| 198 | */ |
| 199 | QString QAudioDevice::description() const |
| 200 | { |
| 201 | return isNull() ? QString() : d->description; |
| 202 | } |
| 203 | |
| 204 | /*! |
| 205 | \qmlproperty bool QtMultimedia::audioDevice::isDefault |
| 206 | |
| 207 | Is true if this is the default audio device. |
| 208 | */ |
| 209 | |
| 210 | /*! |
| 211 | \property QAudioDevice::isDefault |
| 212 | |
| 213 | Returns true if this is the default audio device. |
| 214 | */ |
| 215 | bool QAudioDevice::isDefault() const |
| 216 | { |
| 217 | return d ? d->isDefault : false; |
| 218 | } |
| 219 | |
| 220 | /*! |
| 221 | Returns true if the supplied \a settings are supported by the audio |
| 222 | device described by this QAudioDevice. |
| 223 | */ |
| 224 | bool QAudioDevice::isFormatSupported(const QAudioFormat &settings) const |
| 225 | { |
| 226 | if (isNull()) |
| 227 | return false; |
| 228 | if (settings.sampleRate() < d->minimumSampleRate |
| 229 | || settings.sampleRate() > d->maximumSampleRate) |
| 230 | return false; |
| 231 | if (settings.channelCount() < d->minimumChannelCount |
| 232 | || settings.channelCount() > d->maximumChannelCount) |
| 233 | return false; |
| 234 | if (!d->supportedSampleFormats.contains(t: settings.sampleFormat())) |
| 235 | return false; |
| 236 | return true; |
| 237 | } |
| 238 | |
| 239 | /*! |
| 240 | Returns the default audio format settings for this device. |
| 241 | |
| 242 | These settings are provided by the platform/audio plugin being used. |
| 243 | |
| 244 | They are also dependent on the \l {QtAudio}::Mode being used. |
| 245 | |
| 246 | A typical audio system would provide something like: |
| 247 | \list |
| 248 | \li Input settings: 48000Hz mono 16 bit. |
| 249 | \li Output settings: 48000Hz stereo 16 bit. |
| 250 | \endlist |
| 251 | */ |
| 252 | QAudioFormat QAudioDevice::preferredFormat() const |
| 253 | { |
| 254 | return isNull() ? QAudioFormat() : d->preferredFormat; |
| 255 | } |
| 256 | |
| 257 | /*! |
| 258 | Returns the minimum supported sample rate (in Hertz). |
| 259 | */ |
| 260 | int QAudioDevice::minimumSampleRate() const |
| 261 | { |
| 262 | return isNull() ? 0 : d->minimumSampleRate; |
| 263 | } |
| 264 | |
| 265 | /*! |
| 266 | Returns the maximum supported sample rate (in Hertz). |
| 267 | */ |
| 268 | int QAudioDevice::maximumSampleRate() const |
| 269 | { |
| 270 | return isNull() ? 0 : d->maximumSampleRate; |
| 271 | } |
| 272 | |
| 273 | /*! |
| 274 | Returns the minimum number of supported channel counts. |
| 275 | |
| 276 | This is typically 1 for mono sound, or 2 for stereo sound. |
| 277 | */ |
| 278 | int QAudioDevice::minimumChannelCount() const |
| 279 | { |
| 280 | return isNull() ? 0 : d->minimumChannelCount; |
| 281 | } |
| 282 | |
| 283 | /*! |
| 284 | Returns the maximum number of supported channel counts. |
| 285 | |
| 286 | This is typically 1 for mono sound, or 2 for stereo sound. |
| 287 | */ |
| 288 | int QAudioDevice::maximumChannelCount() const |
| 289 | { |
| 290 | return isNull() ? 0 : d->maximumChannelCount; |
| 291 | } |
| 292 | |
| 293 | /*! |
| 294 | Returns a list of supported sample types. |
| 295 | */ |
| 296 | QList<QAudioFormat::SampleFormat> QAudioDevice::supportedSampleFormats() const |
| 297 | { |
| 298 | return isNull() ? QList<QAudioFormat::SampleFormat>() : d->supportedSampleFormats; |
| 299 | } |
| 300 | |
| 301 | /*! |
| 302 | Returns the channel configuration of the device. |
| 303 | */ |
| 304 | QAudioFormat::ChannelConfig QAudioDevice::channelConfiguration() const |
| 305 | { |
| 306 | return isNull() ? QAudioFormat::ChannelConfigUnknown : d->channelConfiguration; |
| 307 | } |
| 308 | |
| 309 | /*! |
| 310 | \fn QAudioDevicePrivate QAudioDevice::handle() const |
| 311 | \internal |
| 312 | */ |
| 313 | /*! |
| 314 | \internal |
| 315 | */ |
| 316 | QAudioDevice::QAudioDevice(QAudioDevicePrivate *p) : d(p) { } |
| 317 | |
| 318 | /*! |
| 319 | \enum QAudioDevice::Mode |
| 320 | |
| 321 | Describes the mode of this device. |
| 322 | |
| 323 | \value Null |
| 324 | A null device. |
| 325 | \value Input |
| 326 | An input device. |
| 327 | \value Output |
| 328 | An output device. |
| 329 | */ |
| 330 | |
| 331 | /*! |
| 332 | \qmlproperty enumeration QtMultimedia::audioDevice::mode |
| 333 | |
| 334 | Holds whether this device is an input or output device. |
| 335 | |
| 336 | The returned value can be one of the following: |
| 337 | |
| 338 | |
| 339 | \value audioDevice.Null A null device. |
| 340 | \value audioDevice.Input input device. |
| 341 | \value audioDevice.Output An output device. |
| 342 | |
| 343 | */ |
| 344 | |
| 345 | /*! |
| 346 | \property QAudioDevice::mode |
| 347 | |
| 348 | Returns whether this device is an input or output device. |
| 349 | */ |
| 350 | QAudioDevice::Mode QAudioDevice::mode() const |
| 351 | { |
| 352 | return d ? d->mode : Null; |
| 353 | } |
| 354 | |
| 355 | #ifndef QT_NO_DEBUG_STREAM |
| 356 | QDebug operator<<(QDebug dbg, QAudioDevice::Mode mode) |
| 357 | { |
| 358 | QDebugStateSaver saver(dbg); |
| 359 | dbg.nospace(); |
| 360 | switch (mode) { |
| 361 | case QAudioDevice::Input: |
| 362 | dbg << "QAudioDevice::Input" ; |
| 363 | break; |
| 364 | case QAudioDevice::Output: |
| 365 | dbg << "QAudioDevice::Output" ; |
| 366 | break; |
| 367 | case QAudioDevice::Null: |
| 368 | dbg << "QAudioDevice::Null" ; |
| 369 | break; |
| 370 | } |
| 371 | return dbg; |
| 372 | } |
| 373 | #endif |
| 374 | |
| 375 | QT_END_NAMESPACE |
| 376 | |
| 377 | #include "moc_qaudiodevice.cpp" |
| 378 | |