Commit 3c9b8561 authored by Matthieu Gallien's avatar Matthieu Gallien 🎵
Browse files

add a wrapper around QMediaPlayer and allow volume to match pulseaudio one

now the volume is the same in Elisa and in Pulseaudio

if the pulseaudio volume is changed, it will also get changed in Elisa

still need to get a matching curve, currently Qt is linear and
Pulseaudio looks like it is dB
parent aea20194
......@@ -21,6 +21,7 @@ if (Qt5Quick_FOUND AND Qt5Widgets_FOUND)
albumfilterproxymodel.cpp
trackslistener.cpp
elisaapplication.cpp
audiowrapper.cpp
MediaServer.qml
......
......@@ -122,14 +122,17 @@ ApplicationWindow {
id: allListeners
}
Audio {
AudioWrapper {
id: audioPlayer
audioRole: Audio.MusicRole
muted: playControlItem.muted
volume: playControlItem.volume
volume: playControlItem.volume * 100
onVolumeChanged: playControlItem.volume = volume / 100.0
source: manageAudioPlayer.playerSource
onPlaying: {
......
/*
* Copyright 2017 Matthieu Gallien <matthieu_gallien@yahoo.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "audiowrapper.h"
#include <QTimer>
#include "config-upnp-qt.h"
class AudioWrapperPrivate
{
public:
QMediaPlayer mPlayer;
};
AudioWrapper::AudioWrapper(QObject *parent) : QObject(parent), d(new AudioWrapperPrivate)
{
connect(&d->mPlayer, &QMediaPlayer::mutedChanged, this, &AudioWrapper::mutedChanged);
connect(&d->mPlayer, &QMediaPlayer::volumeChanged, this, &AudioWrapper::playerVolumeChanged);
connect(&d->mPlayer, &QMediaPlayer::mediaChanged, this, &AudioWrapper::sourceChanged);
connect(&d->mPlayer, &QMediaPlayer::mediaStatusChanged, this, &AudioWrapper::statusChanged);
connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playbackStateChanged);
connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playerStateChanged);
connect(&d->mPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SIGNAL(errorChanged()));
connect(&d->mPlayer, &QMediaPlayer::durationChanged, this, &AudioWrapper::durationChanged);
connect(&d->mPlayer, &QMediaPlayer::positionChanged, this, &AudioWrapper::positionChanged);
connect(&d->mPlayer, &QMediaPlayer::seekableChanged, this, &AudioWrapper::seekableChanged);
}
AudioWrapper::~AudioWrapper()
{
delete d;
}
bool AudioWrapper::muted() const
{
return d->mPlayer.isMuted();
}
int AudioWrapper::volume() const
{
return d->mPlayer.volume();
}
QUrl AudioWrapper::source() const
{
return d->mPlayer.media().canonicalUrl();
}
QString AudioWrapper::error() const
{
return d->mPlayer.errorString();
}
qint64 AudioWrapper::duration() const
{
return d->mPlayer.duration();
}
qint64 AudioWrapper::position() const
{
return d->mPlayer.position();
}
bool AudioWrapper::seekable() const
{
return d->mPlayer.isSeekable();
}
QAudio::Role AudioWrapper::audioRole() const
{
return d->mPlayer.audioRole();
}
QMediaPlayer::State AudioWrapper::playbackState() const
{
return d->mPlayer.state();
}
QMediaPlayer::MediaStatus AudioWrapper::status() const
{
return d->mPlayer.mediaStatus();
}
void AudioWrapper::setMuted(bool muted)
{
d->mPlayer.setMuted(muted);
}
void AudioWrapper::setVolume(int volume)
{
d->mPlayer.setVolume(volume);
}
void AudioWrapper::setSource(QUrl source)
{
d->mPlayer.setMedia({source});
}
void AudioWrapper::setPosition(qint64 position)
{
d->mPlayer.setPosition(position);
}
void AudioWrapper::play()
{
d->mPlayer.play();
}
void AudioWrapper::pause()
{
d->mPlayer.pause();
}
void AudioWrapper::stop()
{
d->mPlayer.stop();
}
void AudioWrapper::seek(int position)
{
d->mPlayer.setPosition(position);
}
void AudioWrapper::setAudioRole(QAudio::Role audioRole)
{
d->mPlayer.setAudioRole(audioRole);
}
void AudioWrapper::playerStateChanged()
{
switch(d->mPlayer.state()) {
case QMediaPlayer::State::StoppedState:
Q_EMIT stopped();
break;
case QMediaPlayer::State::PlayingState:
Q_EMIT playing();
break;
case QMediaPlayer::State::PausedState:
Q_EMIT paused();
break;
}
}
void AudioWrapper::playerVolumeChanged()
{
QTimer::singleShot(0, [this]() {Q_EMIT volumeChanged();});
}
#include "moc_audiowrapper.cpp"
/*
* Copyright 2017 Matthieu Gallien <matthieu_gallien@yahoo.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef AUDIOWRAPPER_H
#define AUDIOWRAPPER_H
#include <QObject>
#include <QUrl>
#include <QMediaPlayer>
#include <QString>
class AudioWrapperPrivate;
class AudioWrapper : public QObject
{
Q_OBJECT
Q_PROPERTY(bool muted
READ muted
WRITE setMuted
NOTIFY mutedChanged)
Q_PROPERTY(int volume
READ volume
WRITE setVolume
NOTIFY volumeChanged)
Q_PROPERTY(QUrl source
READ source
WRITE setSource
NOTIFY sourceChanged)
Q_PROPERTY(QMediaPlayer::MediaStatus status
READ status
NOTIFY statusChanged)
Q_PROPERTY(QMediaPlayer::State playbackState
READ playbackState
NOTIFY playbackStateChanged)
Q_PROPERTY(QString error
READ error
NOTIFY errorChanged)
Q_PROPERTY(qint64 duration
READ duration
NOTIFY durationChanged)
Q_PROPERTY(qint64 position
READ position
WRITE setPosition
NOTIFY positionChanged)
Q_PROPERTY(bool seekable
READ seekable
NOTIFY seekableChanged)
Q_PROPERTY(QAudio::Role audioRole
READ audioRole
WRITE setAudioRole
NOTIFY audioRoleChanged)
public:
explicit AudioWrapper(QObject *parent = 0);
~AudioWrapper();
bool muted() const;
int volume() const;
QUrl source() const;
QMediaPlayer::MediaStatus status() const;
QMediaPlayer::State playbackState() const;
QString error() const;
qint64 duration() const;
qint64 position() const;
bool seekable() const;
QAudio::Role audioRole() const;
Q_SIGNALS:
void mutedChanged();
void volumeChanged();
void sourceChanged();
void statusChanged();
void playbackStateChanged();
void errorChanged();
void durationChanged();
void positionChanged();
void seekableChanged();
void playing();
void paused();
void stopped();
void audioRoleChanged();
public Q_SLOTS:
void setMuted(bool muted);
void setVolume(int volume);
void setSource(QUrl source);
void setPosition(qint64 position);
void play();
void pause();
void stop();
void seek(int position);
void setAudioRole(QAudio::Role audioRole);
private Q_SLOTS:
void playerStateChanged();
void playerVolumeChanged();
private:
AudioWrapperPrivate *d = nullptr;
};
#endif // AUDIOWRAPPER_H
......@@ -51,6 +51,7 @@
#include "musiclistenersmanager.h"
#include "albumfilterproxymodel.h"
#include "elisaapplication.h"
#include "audiowrapper.h"
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
#include "mpris2/mpris2.h"
......@@ -79,6 +80,7 @@
#include <QApplication>
#include <QCommandLineParser>
#include <QtGlobal>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
......@@ -88,6 +90,8 @@
int __attribute__((visibility("default"))) main(int argc, char *argv[])
{
qputenv("QT_GSTREAMER_USE_PLAYBIN_VOLUME", "true");
QApplication app(argc, argv);
#if defined KF5Crash_FOUND && KF5Crash_FOUND
......@@ -133,6 +137,7 @@ int __attribute__((visibility("default"))) main(int argc, char *argv[])
qmlRegisterType<MusicListenersManager>("org.mgallien.QmlExtension", 1, 0, "MusicListenersManager");
qmlRegisterType<QSortFilterProxyModel>("org.mgallien.QmlExtension", 1, 0, "SortFilterProxyModel");
qmlRegisterType<AlbumFilterProxyModel>("org.mgallien.QmlExtension", 1, 0, "AlbumFilterProxyModel");
qmlRegisterType<AudioWrapper>("org.mgallien.QmlExtension", 1, 0, "AudioWrapper");
#if defined Qt5DBus_FOUND && Qt5DBus_FOUND
qmlRegisterType<Mpris2>("org.mgallien.QmlExtension", 1, 0, "Mpris2");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment