diff options
author | Michael Goddard <michael.goddard@nokia.com> | 2012-04-13 13:51:09 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-16 10:56:34 +0200 |
commit | 5f7b64346db43a6aa3ea2bbc15c63d4864f4d005 (patch) | |
tree | 845838026bba3e5236999abcab7f0bd9b39d6ec3 /src/multimedia/audio | |
parent | 8441d2e32e3bae40640a1584d1d1d1e82980d718 (diff) | |
download | qtmultimedia-5f7b64346db43a6aa3ea2bbc15c63d4864f4d005.tar.gz |
Expose the audio category information for streams.
QAudioOutput and QSoundEffect now have a category property so that
system volume mixing or processing can be applied.
Initially just pulseaudio supports this but Windows Vista etc should also
work.
Change-Id: I6855b08367e5a055ac7dfcffd644c98bfd7c5a4e
Reviewed-by: Ling Hu <ling.hu@nokia.com>
Diffstat (limited to 'src/multimedia/audio')
-rw-r--r-- | src/multimedia/audio/qaudiooutput.cpp | 35 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput.h | 3 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiosystem.h | 2 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect.cpp | 52 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect.h | 5 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_pulse_p.cpp | 44 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_pulse_p.h | 6 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_qmedia_p.cpp | 14 | ||||
-rw-r--r-- | src/multimedia/audio/qsoundeffect_qmedia_p.h | 6 |
9 files changed, 164 insertions, 3 deletions
diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 8647ecdb5..685667ee5 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -364,6 +364,41 @@ qreal QAudioOutput::volume() const } /*! + Returns the audio category of this audio stream. + + Some platforms can group audio streams into categories + and manage their volumes independently, or display them + in a system mixer control. You can set this property to + allow the platform to distinguish the purpose of your streams. + + \sa setCategory() +*/ +QString QAudioOutput::category() const +{ + return d->category(); +} + +/*! + Sets the audio category of this audio stream. + + Some platforms can group audio streams into categories + and manage their volumes independently, or display them + in a system mixer control. You can set this property to + allow the platform to distinguish the purpose of your streams. + + Not all platforms support audio stream categorization. In this + case, the function call will be ignored. + + Changing an audio output stream's category while it is opened + will not take effect until it is reopened. + \sa category() +*/ +void QAudioOutput::setCategory(const QString &category) +{ + d->setCategory(category); +} + +/*! \fn QAudioOutput::stateChanged(QAudio::State state) This signal is emitted when the device \a state has changed. This is the current state of the audio output. diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h index 400272b10..84725e316 100644 --- a/src/multimedia/audio/qaudiooutput.h +++ b/src/multimedia/audio/qaudiooutput.h @@ -100,6 +100,9 @@ public: void setVolume(qreal); qreal volume() const; + QString category() const; + void setCategory(const QString &category); + Q_SIGNALS: void stateChanged(QAudio::State); void notify(); diff --git a/src/multimedia/audio/qaudiosystem.h b/src/multimedia/audio/qaudiosystem.h index aaf1d5786..390cc9733 100644 --- a/src/multimedia/audio/qaudiosystem.h +++ b/src/multimedia/audio/qaudiosystem.h @@ -97,6 +97,8 @@ public: virtual QAudioFormat format() const = 0; virtual void setVolume(qreal) {} virtual qreal volume() const { return 1.0; } + virtual QString category() const { return QString(); } + virtual void setCategory(const QString &) { } Q_SIGNALS: void errorChanged(QAudio::Error); diff --git a/src/multimedia/audio/qsoundeffect.cpp b/src/multimedia/audio/qsoundeffect.cpp index ffaeb3418..6526f1dcb 100644 --- a/src/multimedia/audio/qsoundeffect.cpp +++ b/src/multimedia/audio/qsoundeffect.cpp @@ -218,6 +218,7 @@ QSoundEffect::QSoundEffect(QObject *parent) : connect(d, SIGNAL(loadedChanged()), SIGNAL(loadedChanged())); connect(d, SIGNAL(playingChanged()), SIGNAL(playingChanged())); connect(d, SIGNAL(statusChanged()), SIGNAL(statusChanged())); + connect(d, SIGNAL(categoryChanged()), SIGNAL(categoryChanged())); } /*! @@ -366,6 +367,57 @@ QSoundEffect::Status QSoundEffect::status() const return d->status(); } +/*! + \qmlproperty string QtMultimedia5::SoundEffect::category + \property QSoundEffect::category + + This property contains the \e category of this sound effect. + + Some platforms can perform different audio routing + for different categories, or may allow the user to + set different volume levels for different categories. + + This setting will be ignored on platforms that do not + support audio categories. +*/ +/*! + Returns the current \e category for this sound effect. + + Some platforms can perform different audio routing + for different categories, or may allow the user to + set different volume levels for different categories. + + This setting will be ignored on platforms that do not + support audio categories. + + \sa setCategory() +*/ +QString QSoundEffect::category() const +{ + return d->category(); +} + +/*! + Sets the \e category of this sound effect to \a category. + + Some platforms can perform different audio routing + for different categories, or may allow the user to + set different volume levels for different categories. + + This setting will be ignored on platforms that do not + support audio categories. + + If this setting is changed while a sound effect is playing + it will only take effect when the sound effect has stopped + playing. + + \sa category() + */ +void QSoundEffect::setCategory(const QString &category) +{ + d->setCategory(category); +} + /*! \qmlmethod QtMultimedia5::SoundEffect::stop() diff --git a/src/multimedia/audio/qsoundeffect.h b/src/multimedia/audio/qsoundeffect.h index 44d2f5ba5..f3de7ec17 100644 --- a/src/multimedia/audio/qsoundeffect.h +++ b/src/multimedia/audio/qsoundeffect.h @@ -68,6 +68,7 @@ class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool playing READ isPlaying NOTIFY playingChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(QString category READ category WRITE setCategory NOTIFY categoryChanged) Q_ENUMS(Loop) Q_ENUMS(Status) @@ -108,6 +109,9 @@ public: bool isPlaying() const; Status status() const; + QString category() const; + void setCategory(const QString &category); + Q_SIGNALS: void sourceChanged(); void loopCountChanged(); @@ -117,6 +121,7 @@ Q_SIGNALS: void loadedChanged(); void playingChanged(); void statusChanged(); + void categoryChanged(); public Q_SLOTS: void play(); diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 609e668fd..3b9278c7d 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -351,7 +351,8 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): m_volume(100), m_loopCount(1), m_runningCount(0), - m_sample(0) , + m_sample(0), + m_reloadCategory(false), m_position(0) { m_ref = new QSoundEffectRef(this); @@ -373,6 +374,32 @@ void QSoundEffectPrivate::release() this->deleteLater(); } +QString QSoundEffectPrivate::category() const +{ + return m_category; +} + +void QSoundEffectPrivate::setCategory(const QString &category) +{ + if (m_category != category) { + m_category = category; + if (m_playing || m_playQueued) { + // Currently playing, we need to disconnect when + // playback stops + m_reloadCategory = true; + } else if (m_pulseStream) { + // We have to disconnect and reconnect + unloadPulseStream(); + createPulseStream(); + } else { + // Well, next time we create the pulse stream + // it should be set + } + + emit categoryChanged(); + } +} + QSoundEffectPrivate::~QSoundEffectPrivate() { m_ref->release(); @@ -700,6 +727,7 @@ void QSoundEffectPrivate::unloadPulseStream() pa_stream_unref(m_pulseStream); disconnect(pulseDaemon(), SIGNAL(volumeChanged()), this, SLOT(updateVolume())); m_pulseStream = 0; + m_reloadCategory = false; // category will be reloaded when we connect anyway } } @@ -808,11 +836,16 @@ void QSoundEffectPrivate::stop() setPlaying(false); PulseDaemonLocker locker; m_stopping = true; - if (m_pulseStream) + if (m_pulseStream) { emptyStream(); + if (m_reloadCategory) { + unloadPulseStream(); // upon play we reconnect anyway + } + } setLoopsRemaining(0); m_position = 0; m_playQueued = false; + m_reloadCategory = false; } void QSoundEffectPrivate::underRun() @@ -846,7 +879,12 @@ void QSoundEffectPrivate::createPulseStream() #endif pa_proplist *propList = pa_proplist_new(); - pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, "soundeffect"); + if (m_category.isNull()) { + // Meant to be one of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" + pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, "game"); + } else { + pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); + } pa_stream *stream = pa_stream_new_with_proplist(pulseDaemon()->context(), m_name.constData(), &m_pulseSpec, 0, propList); pa_proplist_free(propList); diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h index 08c010493..6c7202c24 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.h +++ b/src/multimedia/audio/qsoundeffect_pulse_p.h @@ -94,6 +94,9 @@ public: void release(); + QString category() const; + void setCategory(const QString &category); + public Q_SLOTS: void play(); void stop(); @@ -105,6 +108,7 @@ Q_SIGNALS: void loadedChanged(); void playingChanged(); void statusChanged(); + void categoryChanged(); private Q_SLOTS: void decoderError(); @@ -157,6 +161,8 @@ private: int m_runningCount; QUrl m_source; QByteArray m_name; + QString m_category; + bool m_reloadCategory; QSample *m_sample; int m_position; diff --git a/src/multimedia/audio/qsoundeffect_qmedia_p.cpp b/src/multimedia/audio/qsoundeffect_qmedia_p.cpp index dd83f60f1..66d05e662 100644 --- a/src/multimedia/audio/qsoundeffect_qmedia_p.cpp +++ b/src/multimedia/audio/qsoundeffect_qmedia_p.cpp @@ -250,6 +250,20 @@ void QSoundEffectPrivate::setLoopsRemaining(int loopsRemaining) emit loopsRemainingChanged(); } +/* Categories are ignored */ +QString QSoundEffectPrivate::category() const +{ + return m_category; +} + +void QSoundEffectPrivate::setCategory(const QString &category) +{ + if (m_category != category && !m_playing) { + m_category = category; + emit categoryChanged(); + } +} + QT_END_NAMESPACE #include "moc_qsoundeffect_qmedia_p.cpp" diff --git a/src/multimedia/audio/qsoundeffect_qmedia_p.h b/src/multimedia/audio/qsoundeffect_qmedia_p.h index 159c60c15..cc4786c44 100644 --- a/src/multimedia/audio/qsoundeffect_qmedia_p.h +++ b/src/multimedia/audio/qsoundeffect_qmedia_p.h @@ -91,6 +91,10 @@ public: void release(); + // Categories are not really supported with QMediaPlayer + QString category() const; + void setCategory(const QString &); + public Q_SLOTS: void play(); void stop(); @@ -102,6 +106,7 @@ Q_SIGNALS: void loadedChanged(); void playingChanged(); void statusChanged(); + void categoryChanged(); private Q_SLOTS: void stateChanged(QMediaPlayer::State); @@ -118,6 +123,7 @@ private: bool m_playing; QSoundEffect::Status m_status; QMediaPlayer *m_player; + QString m_category; }; QT_END_NAMESPACE |