diff --git a/src/imports/multimedia/plugins.qmltypes b/src/imports/multimedia/plugins.qmltypes index 12d7ea8..8a95637 100644 --- a/src/imports/multimedia/plugins.qmltypes +++ b/src/imports/multimedia/plugins.qmltypes @@ -189,7 +189,8 @@ Module { Property { name: "status"; type: "Status"; isReadonly: true } Property { name: "duration"; type: "int"; isReadonly: true } Property { name: "position"; type: "int"; isReadonly: true } - Property { name: "volume"; type: "double" } + Property { name: "volume"; type: "double" } + Property { name: "pan"; type: "double" } Property { name: "muted"; type: "bool" } Property { name: "hasAudio"; type: "bool"; isReadonly: true } Property { name: "hasVideo"; type: "bool"; isReadonly: true } diff --git a/src/imports/multimedia/qdeclarativeaudio.cpp b/src/imports/multimedia/qdeclarativeaudio.cpp index 37509b1..ec367a6 100644 --- a/src/imports/multimedia/qdeclarativeaudio.cpp +++ b/src/imports/multimedia/qdeclarativeaudio.cpp @@ -116,6 +116,7 @@ QDeclarativeAudio::QDeclarativeAudio(QObject *parent) , m_runningCount(0) , m_position(0) , m_vol(1.0) + , m_pan(0) , m_playbackRate(1.0) , m_playbackState(QMediaPlayer::StoppedState) , m_status(QMediaPlayer::NoMedia) @@ -301,6 +302,29 @@ void QDeclarativeAudio::setVolume(qreal volume) } } +qreal QDeclarativeAudio::pan() const +{ + return !m_complete ? m_pan : m_player->pan(); +} + +void QDeclarativeAudio::setPan(qreal pan) +{ + if (pan < -1 || pan > 1) { + qmlInfo(this) << tr("volume should be between -1.0 and 1.0"); + return; + } + + if (this->pan() == pan) + return; + + if (m_complete) { + m_player->setPan(pan); + } else { + m_pan = pan; + emit panChanged(); + } +} + bool QDeclarativeAudio::isMuted() const { return !m_complete ? m_muted : m_player->isMuted(); @@ -697,6 +721,8 @@ void QDeclarativeAudio::componentComplete() { if (!qFuzzyCompare(m_vol, qreal(1.0))) m_player->setVolume(m_vol * 100); + if (!qFuzzyCompare(m_pan, qreal(0.0))) + m_player->setPan(m_pan); if (m_muted) m_player->setMuted(m_muted); if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) diff --git a/src/imports/multimedia/qdeclarativeaudio_p.h b/src/imports/multimedia/qdeclarativeaudio_p.h index 1c67bc3..f3c3dba 100644 --- a/src/imports/multimedia/qdeclarativeaudio_p.h +++ b/src/imports/multimedia/qdeclarativeaudio_p.h @@ -82,6 +82,7 @@ class QDeclarativeAudio : public QObject, public QQmlParserStatus Q_PROPERTY(int duration READ duration NOTIFY durationChanged) Q_PROPERTY(int position READ position NOTIFY positionChanged) Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(qreal pan READ pan WRITE setPan NOTIFY panChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool hasAudio READ hasAudio NOTIFY hasAudioChanged) Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged) @@ -173,6 +174,9 @@ public: qreal volume() const; void setVolume(qreal volume); + qreal pan() const; + void setPan(qreal p); + bool isMuted() const; void setMuted(bool muted); @@ -217,6 +221,7 @@ Q_SIGNALS: void positionChanged(); void volumeChanged(); + void panChanged(); void mutedChanged(); void hasAudioChanged(); void hasVideoChanged(); @@ -250,6 +255,7 @@ private: int m_runningCount; int m_position; qreal m_vol; + qreal m_pan; qreal m_playbackRate; QMediaPlayer::State m_playbackState; diff --git a/src/multimedia/controls/qmediaplayercontrol.h b/src/multimedia/controls/qmediaplayercontrol.h index aed5183..12f78d1 100644 --- a/src/multimedia/controls/qmediaplayercontrol.h +++ b/src/multimedia/controls/qmediaplayercontrol.h @@ -72,6 +72,9 @@ public: virtual int volume() const = 0; virtual void setVolume(int volume) = 0; + virtual qreal pan() const = 0; + virtual void setPan(qreal p) = 0; + virtual bool isMuted() const = 0; virtual void setMuted(bool muted) = 0; @@ -102,6 +105,7 @@ Q_SIGNALS: void stateChanged(QMediaPlayer::State newState); void mediaStatusChanged(QMediaPlayer::MediaStatus status); void volumeChanged(int volume); + void panChanged(qreal volume); void mutedChanged(bool muted); void audioAvailableChanged(bool audioAvailable); void videoAvailableChanged(bool videoAvailable); diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index bf6294a..6c7263c 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -507,6 +507,7 @@ QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags): connect(d->control, SIGNAL(audioAvailableChanged(bool)), SIGNAL(audioAvailableChanged(bool))); connect(d->control, SIGNAL(videoAvailableChanged(bool)), SIGNAL(videoAvailableChanged(bool))); connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int))); + connect(d->control, SIGNAL(panChanged(qreal)), SIGNAL(panChanged(qreal))); connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); connect(d->control, SIGNAL(seekableChanged(bool)), SIGNAL(seekableChanged(bool))); connect(d->control, SIGNAL(playbackRateChanged(qreal)), SIGNAL(playbackRateChanged(qreal))); @@ -650,6 +651,16 @@ int QMediaPlayer::volume() const return 0; } +qreal QMediaPlayer::pan() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->pan(); + + return 0; +} + bool QMediaPlayer::isMuted() const { Q_D(const QMediaPlayer); @@ -836,6 +847,20 @@ void QMediaPlayer::setVolume(int v) d->control->setVolume(clamped); } +void QMediaPlayer::setPan(qreal p) +{ + Q_D(QMediaPlayer); + + if (d->control == 0) + return; + + qreal clamped = qBound((qreal)-1, p, (qreal)1); + if (clamped == pan()) + return; + + d->control->setPan(clamped); +} + void QMediaPlayer::setMuted(bool muted) { Q_D(QMediaPlayer); diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h index 454b0f1..bdbb26f 100644 --- a/src/multimedia/playback/qmediaplayer.h +++ b/src/multimedia/playback/qmediaplayer.h @@ -66,6 +66,7 @@ class Q_MULTIMEDIA_EXPORT QMediaPlayer : public QMediaObject Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(qreal pan READ pan WRITE setPan NOTIFY panChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(int bufferStatus READ bufferStatus NOTIFY bufferStatusChanged) Q_PROPERTY(bool audioAvailable READ isAudioAvailable NOTIFY audioAvailableChanged) @@ -143,9 +144,10 @@ public: qint64 position() const; int volume() const; + qreal pan() const; bool isMuted() const; bool isAudioAvailable() const; - bool isVideoAvailable() const; + bool isVideoAvailable() const; int bufferStatus() const; @@ -166,6 +168,7 @@ public Q_SLOTS: void setPosition(qint64 position); void setVolume(int volume); + void setPan(qreal pan); void setMuted(bool muted); void setPlaybackRate(qreal rate); @@ -186,6 +189,7 @@ Q_SIGNALS: void positionChanged(qint64 position); void volumeChanged(int volume); + void panChanged(qreal pan); void mutedChanged(bool muted); void audioAvailableChanged(bool available); void videoAvailableChanged(bool videoAvailable); diff --git a/src/plugins/wmf/player/mfplayercontrol.cpp b/src/plugins/wmf/player/mfplayercontrol.cpp index a50c213..1efd861 100644 --- a/src/plugins/wmf/player/mfplayercontrol.cpp +++ b/src/plugins/wmf/player/mfplayercontrol.cpp @@ -254,6 +254,16 @@ void MFPlayerControl::setVolume(int volume) m_session->setVolume(volume); } +qreal MFPlayerControl::pan() const +{ + return m_session->pan(); +} + +void MFPlayerControl::setPan(qreal pan) +{ + m_session->setPan(pan); +} + bool MFPlayerControl::isMuted() const { return m_session->isMuted(); diff --git a/src/plugins/wmf/player/mfplayercontrol.h b/src/plugins/wmf/player/mfplayercontrol.h index 3a841c6..c577a9d 100644 --- a/src/plugins/wmf/player/mfplayercontrol.h +++ b/src/plugins/wmf/player/mfplayercontrol.h @@ -70,6 +70,9 @@ public: int volume() const; void setVolume(int volume); + qreal pan() const; + void setPan(qreal volume); + bool isMuted() const; void setMuted(bool muted); diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index f61f7ab..8c0612d 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -84,6 +84,7 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) , m_closing(false) , m_pendingRate(1) , m_volume(100) + , m_pan(0) , m_muted(false) , m_status(QMediaPlayer::NoMedia) , m_scrubbing(false) @@ -1368,6 +1369,31 @@ void MFPlayerSession::setVolume(int volume) emit volumeChanged(m_volume); } +qreal MFPlayerSession::pan() const +{ + return m_pan; +} + +void MFPlayerSession::setPan(qreal pan) +{ + if (m_pan == pan) + return; + m_pan = pan; + + if (m_volumeControl) { + quint32 channelCount = 0; + if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount)) || channelCount != 2){ + qDebug()<<"Setting pan has no effect when using momre than 2 channels!"; + return; + } + } + + if (!m_muted) + setVolumeInternal(m_volume); + + emit panChanged(m_pan); +} + bool MFPlayerSession::isMuted() const { return m_muted; @@ -1393,8 +1419,16 @@ void MFPlayerSession::setVolumeInternal(int volume) return; float scaled = volume * 0.01f; - for (quint32 i = 0; i < channelCount; ++i) - m_volumeControl->SetChannelVolume(i, scaled); + if(channelCount != 2 || m_pan == 0){ + for (quint32 i = 0; i < channelCount; ++i) + m_volumeControl->SetChannelVolume(i, scaled); + } + else{ + float leftVol = m_pan <= 0 ? scaled : (1 - m_pan) * scaled; + float rightVol = m_pan >= 0 ? scaled : (1 + m_pan) * scaled; + m_volumeControl->SetChannelVolume(0, leftVol); + m_volumeControl->SetChannelVolume(1, rightVol); + } } } diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h index 2c87f3c..ca5a0be 100644 --- a/src/plugins/wmf/player/mfplayersession.h +++ b/src/plugins/wmf/player/mfplayersession.h @@ -112,6 +112,8 @@ public: void setPlaybackRate(qreal rate); int volume() const; void setVolume(int volume); + qreal pan() const; + void setPan(qreal pan); bool isMuted() const; void setMuted(bool muted); int bufferStatus(); @@ -137,6 +139,7 @@ Q_SIGNALS: void positionChanged(qint64 position); void playbackRateChanged(qreal rate); void volumeChanged(int volume); + void panChanged(qreal pan); void mutedChanged(bool muted); void bufferStatusChanged(int percentFilled); @@ -217,6 +220,7 @@ private: QMediaPlayer::MediaStatus m_status; bool m_canScrub; int m_volume; + qreal m_pan; bool m_muted; void setVolumeInternal(int volume);