From f695026fce1c20fdf4ca101dd7ac8da291ecf381 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 20 Aug 2009 12:24:03 +0100 Subject: Added VolumeControlInterface to abstract details of path between MediaObject and AudioOutput --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 32 ++++---------- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 25 +++++------ src/3rdparty/phonon/mmf/abstractplayer.h | 23 ++++++---- src/3rdparty/phonon/mmf/audiooutput.cpp | 55 +++++++++++++++++------- src/3rdparty/phonon/mmf/audiooutput.h | 20 +++++---- src/3rdparty/phonon/mmf/audioplayer.cpp | 9 +++- src/3rdparty/phonon/mmf/backend.cpp | 49 ++++++++++++++------- src/3rdparty/phonon/mmf/dummyplayer.cpp | 14 +++--- src/3rdparty/phonon/mmf/dummyplayer.h | 22 ++++++---- src/3rdparty/phonon/mmf/mediaobject.cpp | 6 +-- src/3rdparty/phonon/mmf/mediaobject.h | 6 ++- src/3rdparty/phonon/mmf/volumecontrolinterface.h | 48 +++++++++++++++++++++ src/plugins/phonon/mmf/mmf.pro | 3 +- 13 files changed, 201 insertions(+), 111 deletions(-) create mode 100644 src/3rdparty/phonon/mmf/volumecontrolinterface.h diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 4bfd839..0777276 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -30,6 +30,9 @@ using namespace Phonon::MMF; const qint32 DefaultTickInterval = 20; const int NullMaxVolume = -1; +// TODO: consolidate this with constant used in AudioOutput +const qreal InitialVolume = 0.5; + //----------------------------------------------------------------------------- // Constructor / destructor @@ -40,9 +43,8 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer() : , m_error(NoError) , m_tickInterval(DefaultTickInterval) , m_tickTimer(new QTimer(this)) - , m_volume(0.0) + , m_volume(InitialVolume) , m_mmfMaxVolume(NullMaxVolume) - , m_audioOutput(NULL) { connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); } @@ -54,7 +56,7 @@ MMF::AbstractMediaPlayer::~AbstractMediaPlayer() //----------------------------------------------------------------------------- -// Public functions (AbstractPlayer interface) +// MediaObjectInterface //----------------------------------------------------------------------------- void MMF::AbstractMediaPlayer::play() @@ -335,7 +337,7 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f //----------------------------------------------------------------------------- -// Volume +// VolumeControlInterface //----------------------------------------------------------------------------- qreal MMF::AbstractMediaPlayer::volume() const @@ -355,7 +357,7 @@ bool MMF::AbstractMediaPlayer::setVolume(qreal volume) case GroundState: case LoadingState: case ErrorState: - // Do nothing + m_volume = volume; break; case StoppedState: @@ -371,12 +373,6 @@ bool MMF::AbstractMediaPlayer::setVolume(qreal volume) { m_volume = volume; volumeChanged = true; - - if(m_audioOutput) - { - // Trigger AudioOutput signal - m_audioOutput->triggerVolumeChanged(m_volume); - } } else { @@ -398,16 +394,6 @@ bool MMF::AbstractMediaPlayer::setVolume(qreal volume) //----------------------------------------------------------------------------- -// Proxies -//----------------------------------------------------------------------------- - -void MMF::AbstractMediaPlayer::setAudioOutput(AudioOutput* audioOutput) -{ - m_audioOutput = audioOutput; -} - - -//----------------------------------------------------------------------------- // Protected functions //----------------------------------------------------------------------------- @@ -421,10 +407,10 @@ void MMF::AbstractMediaPlayer::stopTickTimer() m_tickTimer->stop(); } -void MMF::AbstractMediaPlayer::initVolume(int initialVolume, int mmfMaxVolume) +void MMF::AbstractMediaPlayer::initVolume(int mmfMaxVolume) { - m_volume = static_cast(initialVolume) / mmfMaxVolume; m_mmfMaxVolume = mmfMaxVolume; + doSetVolume(m_volume * m_mmfMaxVolume); } Phonon::State MMF::AbstractMediaPlayer::phononState() const diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 9f86ee6..2f95e73 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -32,6 +32,10 @@ namespace Phonon { class AudioOutput; + /** + * Interface via which MMF client APIs for both audio and video can be + * accessed. + */ class AbstractMediaPlayer : public AbstractPlayer { Q_OBJECT @@ -41,7 +45,7 @@ namespace Phonon ~AbstractMediaPlayer(); public: - // AbstractPlayer + // MediaObjectInterface virtual void play(); virtual void pause(); virtual void stop(); @@ -56,18 +60,12 @@ namespace Phonon virtual qint32 transitionTime() const; virtual void setTransitionTime(qint32); virtual MediaSource source() const; + virtual void setFileSource(const Phonon::MediaSource&, RFile&); virtual void setNextSource(const MediaSource &source); - - // This is a temporary hack to work around KErrInUse from MMF - // client utility OpenFileL calls - //virtual void setSource(const Phonon::MediaSource &) = 0; - virtual void setFileSource - (const Phonon::MediaSource&, RFile&); - + + // VolumeControlInterface qreal volume() const; - bool setVolume(qreal volume); - - void setAudioOutput(AudioOutput* audioOutput); + bool setVolume(qreal volume); protected: virtual void doPlay() = 0; @@ -80,7 +78,7 @@ namespace Phonon protected: void startTickTimer(); void stopTickTimer(); - void initVolume(int initialVolume, int maxVolume); + void initVolume(int maxVolume); /** * Defined private state enumeration in order to add GroundState @@ -138,9 +136,6 @@ namespace Phonon qreal m_volume; int m_mmfMaxVolume; - // Not owned - AudioOutput* m_audioOutput; - MediaSource m_source; MediaSource m_nextSource; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 02c0807..0f496ac 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -23,6 +23,8 @@ along with this library. If not, see . #include #include +#include "volumecontrolinterface.h" + class RFile; namespace Phonon @@ -31,13 +33,23 @@ namespace Phonon { class AudioOutput; - class AbstractPlayer : public QObject + /** + * Interface which abstracts from MediaObject the current media type. + * This may be: + * - Nothing, in which case this interface is implemented by + * DummyPlayer + * - Audio, in which case the implementation is AudioPlayer + * - Video, in which case the implementation is VideoPlayer + */ + class AbstractPlayer : public QObject + , public VolumeControlInterface { // Required although this class has no signals or slots // Without this, qobject_cast will fail Q_OBJECT public: + // Mirror of Phonon::MediaObjectInterfac virtual void play() = 0; virtual void pause() = 0; virtual void stop() = 0; @@ -51,22 +63,17 @@ namespace Phonon virtual QString errorString() const = 0; virtual Phonon::ErrorType errorType() const = 0; virtual qint64 totalTime() const = 0; - virtual Phonon::MediaSource source() const = 0; - + virtual Phonon::MediaSource source() const = 0; // This is a temporary hack to work around KErrInUse from MMF // client utility OpenFileL calls //virtual void setSource(const Phonon::MediaSource &) = 0; virtual void setFileSource(const Phonon::MediaSource&, RFile&) = 0; - virtual void setNextSource(const Phonon::MediaSource &) = 0; - virtual void setTransitionTime(qint32) = 0; virtual qint32 transitionTime() const = 0; virtual qint32 prefinishMark() const = 0; virtual void setPrefinishMark(qint32) = 0; - virtual bool setVolume(qreal) = 0; - virtual qreal volume() const = 0; - virtual void setAudioOutput(AudioOutput *) = 0; + }; } } diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index d8758fd..77d9a6d 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -21,21 +21,41 @@ along with this library. If not, see . #include "mediaobject.h" #include "audiooutput.h" #include "utils.h" +#include "volumecontrolinterface.h" using namespace Phonon; using namespace Phonon::MMF; -MMF::AudioOutput::AudioOutput(Backend *, QObject *parent) : m_mediaObject(NULL) + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +static const qreal InitialVolume = 0.5; + + +//----------------------------------------------------------------------------- +// Constructor / destructor +//----------------------------------------------------------------------------- + +MMF::AudioOutput::AudioOutput(Backend *, QObject *parent) : QObject(parent) + , m_volume(InitialVolume) + , m_volumeControl(NULL) { - setParent(parent); + } + +//----------------------------------------------------------------------------- +// Public API +//----------------------------------------------------------------------------- + qreal MMF::AudioOutput::volume() const { TRACE_CONTEXT(AudioOutput::volume, EAudioApi); - TRACE_ENTRY("m_mediaObject 0x%08x", m_mediaObject); + TRACE_ENTRY("control 0x%08x ", m_volumeControl); - const qreal result = m_mediaObject ? m_mediaObject->volume() : 0.0; + const qreal result = m_volumeControl ? m_volumeControl->volume() : m_volume; TRACE_RETURN("%f", result); } @@ -43,22 +63,24 @@ qreal MMF::AudioOutput::volume() const void MMF::AudioOutput::setVolume(qreal volume) { TRACE_CONTEXT(AudioOutput::setVolume, EAudioApi); - TRACE_ENTRY("volume %f", volume); + TRACE_ENTRY("control 0x%08x volume %f", m_volumeControl, volume); - if(m_mediaObject and m_mediaObject->setVolume(volume)) + if(m_volumeControl) + { + if(m_volumeControl->setVolume(volume)) + { + TRACE("emit volumeChanged(%f)", volume) + emit volumeChanged(volume); + } + } + else { - TRACE("emit volumeChanged(%f)", volume) - emit volumeChanged(volume); + m_volume = volume; } TRACE_EXIT_0(); } -void MMF::AudioOutput::triggerVolumeChanged(qreal volume) -{ - emit volumeChanged(volume); -} - int MMF::AudioOutput::outputDevice() const { return 0; @@ -74,9 +96,10 @@ bool MMF::AudioOutput::setOutputDevice(const Phonon::AudioOutputDevice &) return true; } -void MMF::AudioOutput::setMediaObject(MediaObject *mo) +void MMF::AudioOutput::setVolumeControl(VolumeControlInterface *volumeControl) { - Q_ASSERT(!m_mediaObject); - m_mediaObject = mo; + Q_ASSERT(!m_volumeControl); + m_volumeControl = volumeControl; + m_volumeControl->setVolume(m_volume); } diff --git a/src/3rdparty/phonon/mmf/audiooutput.h b/src/3rdparty/phonon/mmf/audiooutput.h index 5e4fef2..b8290c7 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.h +++ b/src/3rdparty/phonon/mmf/audiooutput.h @@ -26,16 +26,13 @@ namespace Phonon namespace MMF { class Backend; - class MediaObject; + class VolumeControlInterface; /** * @short AudioOutputInterface implementation for MMF. * - * Implements the AudioOutputInterface for Symbian/S60's MMF - * framework. - * - * This class has a very small role, we simply access CDrmPlayerUtility - * in MediaObject::m_player and forward everything there. + * Forwards volume commands to the VolumeControlInterface instance, + * provided by the backend. * * \section volume Volume * @@ -69,20 +66,25 @@ namespace Phonon */ virtual bool setOutputDevice(const Phonon::AudioOutputDevice &); - void setMediaObject(MediaObject *mo); + void setVolumeControl(VolumeControlInterface *volumeControl); /** * Called by MediaObject to pass initial volume when clip has been * successfully opened */ - void triggerVolumeChanged(qreal volume); + //void triggerVolumeChanged(qreal volume); Q_SIGNALS: void volumeChanged(qreal volume); void audioDeviceFailed(); private: - MediaObject * m_mediaObject; + /** + * This value is used when m_volumeControl is NULL. + */ + qreal m_volume; + + VolumeControlInterface * m_volumeControl; }; } } diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index ec29ac1..c0a0767 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -164,15 +164,22 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, if(KErrNone == aError) { +// TODO: CLEANUP +/* TInt volume = 0; aError = m_player->GetVolume(volume); if(KErrNone == aError) { - initVolume(volume, m_player->MaxVolume()); +*/ + initVolume(m_player->MaxVolume()); emit totalTimeChanged(); changeState(StoppedState); + +// TODO: CLEANUP +/* } +*/ } else { diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 8d7903e..7a0f3f5 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -26,10 +26,10 @@ along with this library. If not, see . using namespace Phonon; using namespace Phonon::MMF; -Backend::Backend(QObject *parent) +Backend::Backend(QObject *parent) : QObject(parent) { + // TODO: replace this with logging macros as per rest of the module qDebug() << Q_FUNC_INFO; - setParent(parent); setProperty("identifier", QLatin1String("phonon_mmf")); setProperty("backendName", QLatin1String("MMF")); @@ -40,12 +40,20 @@ Backend::Backend(QObject *parent) QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList &) { + // TODO: add trace + + QObject* result = NULL; + switch(c) { case AudioOutputClass: - return new AudioOutput(this, parent); + result = new AudioOutput(this, parent); + break; + case MediaObjectClass: - return new MediaObject(parent); + result = new MediaObject(parent); + break; + case VolumeFaderEffectClass: /* Fallthrough. */ case VisualizationClass: @@ -55,12 +63,14 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const case EffectClass: /* Fallthrough. */ case VideoWidgetClass: - return 0; + result = NULL; + break; + + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "This line should never be reached."); } - Q_ASSERT_X(false, Q_FUNC_INFO, - "This line should never be reached."); - return 0; + return result; } QList Backend::objectDescriptionIndexes(ObjectDescriptionType) const @@ -80,20 +90,25 @@ bool Backend::startConnectionChange(QSet) bool Backend::connectNodes(QObject *source, QObject *target) { - MediaObject *const mo = qobject_cast(source); - AudioOutput *const ao = qobject_cast(target); + // TODO: add trace - if(!mo || !ao) - return false; + MediaObject *const mediaObject = qobject_cast(source); + AudioOutput *const audioOutput = qobject_cast(target); - ao->setMediaObject(mo); - mo->setAudioOutput(ao); - - return true; + if(mediaObject and audioOutput) + { + audioOutput->setVolumeControl(mediaObject); + return true; + } + + // Node types not recognised + return false; } bool Backend::disconnectNodes(QObject *, QObject *) { + // TODO: add trace + return true; } @@ -104,6 +119,8 @@ bool Backend::endConnectionChange(QSet) QStringList Backend::availableMimeTypes() const { + // TODO: query MMF for available MIME types + return QStringList(); } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp index ecd6815..26257c0 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.cpp +++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp @@ -21,6 +21,10 @@ along with this library. If not, see . using namespace Phonon; using namespace Phonon::MMF; +//----------------------------------------------------------------------------- +// Public functions (AbstractPlayer interface) +//----------------------------------------------------------------------------- + void MMF::DummyPlayer::play() { } @@ -86,9 +90,11 @@ MediaSource MMF::DummyPlayer::source() const return MediaSource(); } +/* void MMF::DummyPlayer::setSource(const MediaSource &) { } +*/ void MMF::DummyPlayer::setNextSource(const MediaSource &) { @@ -116,10 +122,6 @@ void MMF::DummyPlayer::setFileSource(const Phonon::MediaSource &, RFile &) { } -//----------------------------------------------------------------------------- -// Volume -//----------------------------------------------------------------------------- - qreal MMF::DummyPlayer::volume() const { return 0; @@ -130,8 +132,6 @@ bool MMF::DummyPlayer::setVolume(qreal) return true; } -void MMF::DummyPlayer::setAudioOutput(AudioOutput *) -{ -} + diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h index 263a013..e5c1365 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.h +++ b/src/3rdparty/phonon/mmf/dummyplayer.h @@ -28,13 +28,19 @@ namespace Phonon class AudioOutput; /** - * @short In order to make the implementation of MediaObject simpler, - * we have this class. + * @short Stub implementation of AbstractPlayer. + * + * The functions of this class are: + * - Allow MediaObject to call a subset of the MediaObjectInterface + * API, before SetSource has been called. + * - Cache any parameters which are set in this state (e.g. + * prefinish mark), so that they can be copied into the 'real' + * AbstractPlayer implementation once a source has been loaded. */ class DummyPlayer : public AbstractPlayer { public: - // AbstractPlayer + // MediaObjectInterface virtual void play(); virtual void pause(); virtual void stop(); @@ -49,18 +55,18 @@ namespace Phonon virtual Phonon::ErrorType errorType() const; virtual qint64 totalTime() const; virtual MediaSource source() const; - virtual void setSource(const MediaSource &); + // virtual void setSource(const MediaSource &); + virtual void setFileSource(const Phonon::MediaSource&, RFile&); virtual void setNextSource(const MediaSource &source); virtual qint32 prefinishMark() const; virtual void setPrefinishMark(qint32); virtual qint32 transitionTime() const; virtual void setTransitionTime(qint32); + + // VolumeControlInterface virtual qreal volume() const; virtual bool setVolume(qreal volume); - - virtual void setAudioOutput(AudioOutput* audioOutput); - virtual void setFileSource(const Phonon::MediaSource&, RFile&); - + Q_SIGNALS: void totalTimeChanged(); void stateChanged(Phonon::State oldState, diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index ffc7fb8..6b32eb3 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -319,7 +319,7 @@ void MMF::MediaObject::setTransitionTime(qint32 time) } //----------------------------------------------------------------------------- -// Volume +// VolumeControlInterface //----------------------------------------------------------------------------- qreal MMF::MediaObject::volume() const @@ -332,8 +332,4 @@ bool MMF::MediaObject::setVolume(qreal volume) return m_player->setVolume(volume); } -void MMF::MediaObject::setAudioOutput(AudioOutput* audioOutput) -{ - m_player->setAudioOutput(audioOutput); -} diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index 9c39884..97ea115 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -27,6 +27,8 @@ along with this library. If not, see . // For recognizer #include +#include "volumecontrolinterface.h" + namespace Phonon { namespace MMF @@ -38,6 +40,7 @@ namespace Phonon */ class MediaObject : public QObject , public MediaObjectInterface + , public VolumeControlInterface { Q_OBJECT Q_INTERFACES(Phonon::MediaObjectInterface) @@ -68,11 +71,10 @@ namespace Phonon virtual qint32 transitionTime() const; virtual void setTransitionTime(qint32); + // VolumeControlInterface qreal volume() const; bool setVolume(qreal volume); - void setAudioOutput(AudioOutput* audioOutput); - Q_SIGNALS: void totalTimeChanged(); void stateChanged(Phonon::State oldState, diff --git a/src/3rdparty/phonon/mmf/volumecontrolinterface.h b/src/3rdparty/phonon/mmf/volumecontrolinterface.h new file mode 100644 index 0000000..7965dd4 --- /dev/null +++ b/src/3rdparty/phonon/mmf/volumecontrolinterface.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see . + +*/ + +#ifndef PHONON_MMF_VOLUMECONTROLINTERFACE_H +#define PHONON_MMF_VOLUMECONTROLINTERFACE_H + +#include + +namespace Phonon +{ + namespace MMF + { + /** + * Interface used by AudioOutput to pass volume control commands + * back along the audio path to the MediaObject. + */ + class VolumeControlInterface + { + public: + virtual qreal volume() const = 0; + + /** + * Returns true if the volume of the underlying audio stack is + * changed as a result of this call. The return value is used + * by the AudioDevice to determine whether to emit a + * volumeChanged signal. + */ + virtual bool setVolume(qreal volume) = 0; + }; + } +} + +#endif diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index bb2dffd..a196930 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -30,7 +30,8 @@ HEADERS += \ $$PHONON_MMF_DIR/dummyplayer.h \ $$PHONON_MMF_DIR/mediaobject.h \ $$PHONON_MMF_DIR/utils.h \ - $$PHONON_MMF_DIR/videoplayer.h + $$PHONON_MMF_DIR/videoplayer.h \ + $$PHONON_MMF_DIR/volumecontrolinterface.h SOURCES += \ $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ -- cgit v0.12