qtmobility/src/multimedia/audio/qaudiodeviceinfo.cpp
changeset 14 6fbed849b4f4
child 15 1f895d8a5b2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/src/multimedia/audio/qaudiodeviceinfo.cpp	Wed Jun 23 19:08:38 2010 +0300
@@ -0,0 +1,492 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaudiodevicefactory_p.h"
+#include "qaudiosystem.h"
+#include "qaudiodeviceinfo.h"
+
+#include <QtCore/qmap.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAudioDeviceInfoPrivate : public QSharedData
+{
+public:
+    QAudioDeviceInfoPrivate():info(0) {}
+    QAudioDeviceInfoPrivate(const QString &r, const QByteArray &h, QAudio::Mode m):
+        realm(r), handle(h), mode(m)
+    {
+        info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+    }
+
+    QAudioDeviceInfoPrivate(const QAudioDeviceInfoPrivate &other):
+        QSharedData(other),
+        realm(other.realm), handle(other.handle), mode(other.mode)
+    {
+        info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+    }
+
+    QAudioDeviceInfoPrivate& operator=(const QAudioDeviceInfoPrivate &other)
+    {
+        delete info;
+
+        realm = other.realm;
+        handle = other.handle;
+        mode = other.mode;
+        info = QAudioDeviceFactory::audioDeviceInfo(realm, handle, mode);
+        return *this;
+    }
+
+    ~QAudioDeviceInfoPrivate()
+    {
+        delete info;
+    }
+
+    QString     realm;
+    QByteArray  handle;
+    QAudio::Mode mode;
+    QAbstractAudioDeviceInfo*   info;
+};
+
+
+/*!
+    \class QAudioDeviceInfo
+    \brief The QAudioDeviceInfo class provides an interface to query audio devices and their functionality.
+    \inmodule QtMultimedia
+    \ingroup multimedia
+
+    \since 4.6
+
+    QAudioDeviceInfo lets you query for audio devices--such as sound
+    cards and USB headsets--that are currently available on the system.
+    The audio devices available are dependent on the platform or audio plugins installed.
+
+    You can also query each device for the formats it supports. A
+    format in this context is a set consisting of a specific byte
+    order, channel, codec, frequency, sample rate, and sample type.  A
+    format is represented by the QAudioFormat class.
+
+    The values supported by the the device for each of these
+    parameters can be fetched with
+    supportedByteOrders(), supportedChannelCounts(), supportedCodecs(),
+    supportedSampleRates(), supportedSampleSizes(), and
+    supportedSampleTypes(). The combinations supported are dependent on the platform,
+    audio plugins installed and the audio device capabilities. If you need a specific format, you can check if
+    the device supports it with isFormatSupported(), or fetch a
+    supported format that is as close as possible to the format with
+    nearestFormat(). For instance:
+
+    \code
+        QAudioFormat format;
+        format.setFrequency(44100);
+    \endcode
+    \dots 8
+    \code
+        format.setSampleType(QAudioFormat::SignedInt);
+
+        QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
+
+        if (!info.isFormatSupported(format))
+            format = info.nearestFormat(format);
+    \endcode
+
+    A QAudioDeviceInfo is used by Qt to construct
+    classes that communicate with the device--such as
+    QAudioInput, and QAudioOutput. The static
+    functions defaultInputDevice(), defaultOutputDevice(), and
+    availableDevices() let you get a list of all available
+    devices. Devices are fetch according to the value of mode
+    this is specified by the QAudio::Mode enum.
+    The QAudioDeviceInfo returned are only valid for the QAudio::Mode.
+
+    For instance:
+
+    \code
+    foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
+        qDebug() << "Device name: " << deviceInfo.deviceName();
+    \endcode
+
+    In this code sample, we loop through all devices that are able to output
+    sound, i.e., play an audio stream in a supported format. For each device we
+    find, we simply print the deviceName().
+
+    \sa QAudioOutput, QAudioInput
+*/
+
+/*!
+    Constructs an empty QAudioDeviceInfo object.
+*/
+
+QAudioDeviceInfo::QAudioDeviceInfo():
+    d(new QAudioDeviceInfoPrivate)
+{
+}
+
+/*!
+    Constructs a copy of \a other.
+*/
+
+QAudioDeviceInfo::QAudioDeviceInfo(const QAudioDeviceInfo& other):
+    d(other.d)
+{
+}
+
+/*!
+    Destroy this audio device info.
+*/
+
+QAudioDeviceInfo::~QAudioDeviceInfo()
+{
+}
+
+/*!
+    Sets the QAudioDeviceInfo object to be equal to \a other.
+*/
+
+QAudioDeviceInfo& QAudioDeviceInfo::operator=(const QAudioDeviceInfo &other)
+{
+    d = other.d;
+    return *this;
+}
+
+/*!
+    Returns whether this QAudioDeviceInfo object holds a device definition.
+*/
+
+bool QAudioDeviceInfo::isNull() const
+{
+    return d->info == 0;
+}
+
+/*!
+    Returns human readable name of audio device.
+
+    Device names vary depending on platform/audio plugin being used.
+
+    They are a unique string identifiers for the audio device.
+
+    eg. default, Intel, U0x46d0x9a4
+*/
+
+QString QAudioDeviceInfo::deviceName() const
+{
+    return isNull() ? QString() : d->info->deviceName();
+}
+
+/*!
+    Returns true if \a settings are supported by the audio device of this QAudioDeviceInfo.
+*/
+
+bool QAudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const
+{
+    return isNull() ? false : d->info->isFormatSupported(settings);
+}
+
+/*!
+    Returns QAudioFormat of default settings.
+
+    These settings are provided by the platform/audio plugin being used.
+
+    They also are dependent on the QAudio::Mode being used.
+
+    A typical audio system would provide something like:
+    \list
+    \o Input settings: 8000Hz mono 8 bit.
+    \o Output settings: 44100Hz stereo 16 bit little endian.
+    \endlist
+*/
+
+QAudioFormat QAudioDeviceInfo::preferredFormat() const
+{
+    return isNull() ? QAudioFormat() : d->info->preferredFormat();
+}
+
+/*!
+    Returns closest QAudioFormat to \a settings that system audio supports.
+
+    These settings are provided by the platform/audio plugin being used.
+
+    They also are dependent on the QAudio::Mode being used.
+*/
+
+QAudioFormat QAudioDeviceInfo::nearestFormat(const QAudioFormat &settings) const
+{
+    if (isFormatSupported(settings))
+        return settings;
+
+    QAudioFormat nearest = settings;
+
+    QList<QString> testCodecs = supportedCodecs();
+    QList<int> testChannels = supportedChannels();
+    QList<QAudioFormat::Endian> testByteOrders = supportedByteOrders();
+    QList<QAudioFormat::SampleType> testSampleTypes;
+    QList<QAudioFormat::SampleType> sampleTypesAvailable = supportedSampleTypes();
+    QMap<int,int> testFrequencies;
+    QList<int> frequenciesAvailable = supportedFrequencies();
+    QMap<int,int> testSampleSizes;
+    QList<int> sampleSizesAvailable = supportedSampleSizes();
+
+    // Get sorted lists for checking
+    if (testCodecs.contains(settings.codec())) {
+        testCodecs.removeAll(settings.codec());
+        testCodecs.insert(0, settings.codec());
+    }
+    testChannels.removeAll(settings.channels());
+    testChannels.insert(0, settings.channels());
+    testByteOrders.removeAll(settings.byteOrder());
+    testByteOrders.insert(0, settings.byteOrder());
+
+    if (sampleTypesAvailable.contains(settings.sampleType()))
+        testSampleTypes.append(settings.sampleType());
+    if (sampleTypesAvailable.contains(QAudioFormat::SignedInt))
+        testSampleTypes.append(QAudioFormat::SignedInt);
+    if (sampleTypesAvailable.contains(QAudioFormat::UnSignedInt))
+        testSampleTypes.append(QAudioFormat::UnSignedInt);
+    if (sampleTypesAvailable.contains(QAudioFormat::Float))
+        testSampleTypes.append(QAudioFormat::Float);
+
+    if (sampleSizesAvailable.contains(settings.sampleSize()))
+        testSampleSizes.insert(0,settings.sampleSize());
+    sampleSizesAvailable.removeAll(settings.sampleSize());
+    foreach (int size, sampleSizesAvailable) {
+        int larger  = (size > settings.sampleSize()) ? size : settings.sampleSize();
+        int smaller = (size > settings.sampleSize()) ? settings.sampleSize() : size;
+        bool isMultiple = ( 0 == (larger % smaller));
+        int diff = larger - smaller;
+        testSampleSizes.insert((isMultiple ? diff : diff+100000), size);
+    }
+    if (frequenciesAvailable.contains(settings.frequency()))
+        testFrequencies.insert(0,settings.frequency());
+    frequenciesAvailable.removeAll(settings.frequency());
+    foreach (int frequency, frequenciesAvailable) {
+        int larger  = (frequency > settings.frequency()) ? frequency : settings.frequency();
+        int smaller = (frequency > settings.frequency()) ? settings.frequency() : frequency;
+        bool isMultiple = ( 0 == (larger % smaller));
+        int diff = larger - smaller;
+        testFrequencies.insert((isMultiple ? diff : diff+100000), frequency);
+    }
+
+    // Try to find nearest
+    foreach (QString codec, testCodecs) {
+        nearest.setCodec(codec);
+        foreach (QAudioFormat::Endian order, testByteOrders) {
+            nearest.setByteOrder(order);
+            foreach (QAudioFormat::SampleType sample, testSampleTypes) {
+                nearest.setSampleType(sample);
+                QMapIterator<int, int> sz(testSampleSizes);
+                while (sz.hasNext()) {
+                    sz.next();
+                    nearest.setSampleSize(sz.value());
+                    foreach (int channel, testChannels) {
+                        nearest.setChannels(channel);
+                        QMapIterator<int, int> i(testFrequencies);
+                        while (i.hasNext()) {
+                            i.next();
+                            nearest.setFrequency(i.value());
+                            if (isFormatSupported(nearest))
+                                return nearest;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    //Fallback
+    return preferredFormat();
+}
+
+/*!
+    Returns a list of supported codecs.
+
+    All platform and plugin implementations should provide support for:
+
+    "audio/pcm" - Linear PCM
+
+    For writing plugins to support additional codecs refer to:
+
+    http://www.iana.org/assignments/media-types/audio/
+*/
+
+QStringList QAudioDeviceInfo::supportedCodecs() const
+{
+    return isNull() ? QStringList() : d->info->supportedCodecs();
+}
+
+/*!
+    Returns a list of supported sample rates.
+
+    \since 4.7
+*/
+
+QList<int> QAudioDeviceInfo::supportedSampleRates() const
+{
+    return supportedFrequencies();
+}
+
+/*!
+    \obsolete
+
+    Use supportedSampleRates() instead.
+*/
+
+QList<int> QAudioDeviceInfo::supportedFrequencies() const
+{
+    return isNull() ? QList<int>() : d->info->supportedSampleRates();
+}
+
+/*!
+    Returns a list of supported channel counts.
+
+    \since 4.7
+*/
+
+QList<int> QAudioDeviceInfo::supportedChannelCounts() const
+{
+    return supportedChannels();
+}
+
+/*!
+    \obsolete
+
+    Use supportedChannelCount() instead.
+*/
+
+QList<int> QAudioDeviceInfo::supportedChannels() const
+{
+    return isNull() ? QList<int>() : d->info->supportedChannelCounts();
+}
+
+/*!
+    Returns a list of supported sample sizes.
+*/
+
+QList<int> QAudioDeviceInfo::supportedSampleSizes() const
+{
+    return isNull() ? QList<int>() : d->info->supportedSampleSizes();
+}
+
+/*!
+    Returns a list of supported byte orders.
+*/
+
+QList<QAudioFormat::Endian> QAudioDeviceInfo::supportedByteOrders() const
+{
+    return isNull() ? QList<QAudioFormat::Endian>() : d->info->supportedByteOrders();
+}
+
+/*!
+    Returns a list of supported sample types.
+*/
+
+QList<QAudioFormat::SampleType> QAudioDeviceInfo::supportedSampleTypes() const
+{
+    return isNull() ? QList<QAudioFormat::SampleType>() : d->info->supportedSampleTypes();
+}
+
+/*!
+    Returns the name of the default input audio device.
+    All platform and audio plugin implementations provide a default audio device to use.
+*/
+
+QAudioDeviceInfo QAudioDeviceInfo::defaultInputDevice()
+{
+    return QAudioDeviceFactory::defaultInputDevice();
+}
+
+/*!
+    Returns the name of the default output audio device.
+    All platform and audio plugin implementations provide a default audio device to use.
+*/
+
+QAudioDeviceInfo QAudioDeviceInfo::defaultOutputDevice()
+{
+    return QAudioDeviceFactory::defaultOutputDevice();
+}
+
+/*!
+    Returns a list of audio devices that support \a mode.
+*/
+
+QList<QAudioDeviceInfo> QAudioDeviceInfo::availableDevices(QAudio::Mode mode)
+{
+    return QAudioDeviceFactory::availableDevices(mode);
+}
+
+
+/*!
+    \internal
+*/
+
+QAudioDeviceInfo::QAudioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode):
+    d(new QAudioDeviceInfoPrivate(realm, handle, mode))
+{
+}
+
+/*!
+    \internal
+*/
+
+QString QAudioDeviceInfo::realm() const
+{
+    return d->realm;
+}
+
+/*!
+    \internal
+*/
+
+QByteArray QAudioDeviceInfo::handle() const
+{
+    return d->handle;
+}
+
+
+/*!
+    \internal
+*/
+
+QAudio::Mode QAudioDeviceInfo::mode() const
+{
+    return d->mode;
+}
+
+QT_END_NAMESPACE
+