diff options
author | Frans Englich <frans.englich@nokia.com> | 2009-08-26 14:36:32 (GMT) |
---|---|---|
committer | Gareth Stockwell <gareth.stockwell@sosco.com> | 2009-09-09 13:35:38 (GMT) |
commit | 7d2d15bbc9d598daf94800b576aff19a68119ed1 (patch) | |
tree | 61f881bda38b0559db6543ed87b55089e64ef25e /src | |
parent | c4d341ecf26d63cc7410756f8f7d1926c277f02f (diff) | |
download | Qt-7d2d15bbc9d598daf94800b576aff19a68119ed1.zip Qt-7d2d15bbc9d598daf94800b576aff19a68119ed1.tar.gz Qt-7d2d15bbc9d598daf94800b576aff19a68119ed1.tar.bz2 |
Work on extending the framework for accomodating effects.
This extends the framework for being able to handle audio effects, largely
affecting how the audio chain is set up, connected and disconnected, and
therefore the Backend has been refactored slightly, and the class MediaNode
introduced, see its documentation.
In addition two effects has been written: BassBoost and AudioEqualizer.
Diffstat (limited to 'src')
24 files changed, 993 insertions, 67 deletions
diff --git a/src/3rdparty/phonon/mmf/TODO.txt b/src/3rdparty/phonon/mmf/TODO.txt index 846f0bb..1d2cb44 100644 --- a/src/3rdparty/phonon/mmf/TODO.txt +++ b/src/3rdparty/phonon/mmf/TODO.txt @@ -37,4 +37,7 @@ Compare video frame rate obtained using default S60 media player and Qt demo app * Implement MMF::Backend::disconnectNodes This should probably be left for now, particularly until audio effects have been implemented. This is because the node connection mechanism may need to be refactored slightly once we start building up longer graphs (e.g. MediaObject -> Effect -> Effect -> AudioOutput). +* Before merging, ensure the UID3 is properly allocated, see the .pro file. + +* Metadata is not implemented. diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp new file mode 100644 index 0000000..4c876e1 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -0,0 +1,105 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#include <AudioEffectBase.h> +#include "mediaobject.h" + +#include "abstractaudioeffect.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +AbstractAudioEffect::AbstractAudioEffect(QObject *parent, + const QList<EffectParameter> ¶ms) : MediaNode::MediaNode(parent) + , m_params(params) + , m_isApplied(false) +{ +} + +bool AbstractAudioEffect::disconnectMediaNode(MediaNode *target) +{ + MediaNode::disconnectMediaNode(target); + m_effect.reset(); + return true; +} + +QList<EffectParameter> AbstractAudioEffect::parameters() const +{ + return m_params; +} + +QVariant AbstractAudioEffect::parameterValue(const EffectParameter &queriedParam) const +{ + const QVariant &val = m_values.value(queriedParam.id()); + + if (val.isNull()) + return queriedParam.defaultValue(); + else + return val; +} + +void AbstractAudioEffect::setParameterValue(const EffectParameter ¶m, + const QVariant &newValue) +{ + m_values.insert(param.id(), newValue); + parameterChanged(param.id(), newValue); +} + +bool AbstractAudioEffect::activateBackwardsInChain(MediaNode *target) +{ + // TODO we need to walk forward too. + MediaNode *current = target; + + while (current) { + MMF::MediaObject *const mo = qobject_cast<MMF::MediaObject *>(current); + if(!mo) + continue; + + AudioPlayer *const ap = qobject_cast<AudioPlayer *>(mo->abstractPlayer()); + + if (ap) { + activateOn(ap->player()); + // There might be stuff before the mediaobject, but + // that's undefined for us. + return true; + } + else + current = current->source(); + } + + return false; +} + +bool AbstractAudioEffect::connectMediaNode(MediaNode *target) +{ + /** + * We first call this function, so source() and target() + * is properly set up. + */ + MediaNode::connectMediaNode(target); + + if (!m_isApplied && activateBackwardsInChain(target)) + m_isApplied = true; + + return true; +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h new file mode 100644 index 0000000..4c2eba3 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -0,0 +1,108 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_ABSTRACTEFFECT_H +#define PHONON_MMF_ABSTRACTEFFECT_H + +#include "mmf_medianode.h" + +#include <QScopedPointer> + +#include <Phonon/EffectInterface> +#include <Phonon/EffectParameter> +#include "audioplayer.h" + +class CAudioEffect; + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ + +/** + * @short Base class for all effects for MMF. + * + * Adhering to Phonon with MMF is cumbersome because of a number of reasons: + * + * - MMF has no concept of effect chaining. Simply, an effect is a applied + * to PlayerUtility, that's it. This means that the order of effects is + * undefined. + * - We apply an effect to a PlayerUtility, and MediaObject has that one. + * However, effects might be created before MediaObject, but nevertheless + * needs to work. We solve this by that we are aware of the whole connection + * chain, and whenever a connection happens, we walk the chain, find effects + * that aren't applied, and apply it if we have a media object. + * - There are plenty of corner cases which we don't handle and where behavior + * are undefined. For instance, graphs with more than one MediaObject. + */ +class AbstractAudioEffect : public MediaNode + , public EffectInterface +{ + Q_OBJECT + Q_INTERFACES(Phonon::EffectInterface) +public: + AbstractAudioEffect(QObject *parent, + const QList<EffectParameter> ¶ms); + + virtual QList<EffectParameter> parameters() const; + virtual QVariant parameterValue(const EffectParameter ¶m) const; + virtual void setParameterValue(const EffectParameter &, + const QVariant &newValue); + + virtual bool connectMediaNode(MediaNode *target); + virtual bool disconnectMediaNode(MediaNode *target); + + enum Type + { + EffectAudioEqualizer = 1, + EffectBassBoost, + EffectDistanceAttenuation, + EffectEnvironmentalReverb, + EffectListenerOrientation, + EffectLoudness, + //EffectRoomLevel, + EffectSourceOrientation, + EffectStereoWidening + }; + +protected: + virtual void activateOn(CPlayerType *player) = 0; + virtual void parameterChanged(const int id, + const QVariant &value) = 0; + + QScopedPointer<CAudioEffect> m_effect; +private: + /** + * From @p target, we walk the chain backwards and try to find the media + * object, and apply ourselves to that one. + */ + bool activateBackwardsInChain(MediaNode *target); + + const QList<EffectParameter> m_params; + bool m_isApplied; + QHash<int, QVariant> m_values; +}; +} +} + +QT_END_NAMESPACE + +#endif + diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index da0fe51..0f846ca 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -48,8 +48,8 @@ class VideoOutput; * - Audio, in which case the implementation is AudioPlayer * - Video, in which case the implementation is VideoPlayer */ -class AbstractPlayer : public QObject - , public VolumeObserver +class AbstractPlayer : public QObject + , public VolumeObserver { // Required although this class has no signals or slots // Without this, qobject_cast will fail diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp new file mode 100644 index 0000000..28a8741 --- /dev/null +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -0,0 +1,86 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#include <AudioEqualizerBase.h> + +#include "audioequalizer.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +AudioEqualizer::AudioEqualizer(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect(parent, createParams()) +{ +} + +void AudioEqualizer::parameterChanged(const int pid, + const QVariant &value) +{ + // There is no way to return an error from this function, so we just + // have to trap and ignore exceptions. + TRAP_IGNORE(eq()->SetBandLevelL(pid, value.toInt())); +} + +void AudioEqualizer::activateOn(CPlayerType *player) +{ + m_effect.reset(CAudioEqualizer::NewL(*player)); +} + +CAudioEqualizer *AudioEqualizer::eq() const +{ + return static_cast<CAudioEqualizer *>(m_effect.data()); +} + +QList<EffectParameter> AudioEqualizer::createParams() +{ + QList<EffectParameter> retval; + + // We temporarily create an AudioPlayer, and run the effect on it, so + // we can extract the readonly data we need. + AudioPlayer dummyPlayer; + activateOn(dummyPlayer.player()); + + TInt32 dbMin; + TInt32 dbMax; + eq()->DbLevelLimits(dbMin, dbMax); + + const int bandCount = eq()->NumberOfBands(); + + for (int i = 0; i < bandCount; ++i) { + const qint32 hz = eq()->CenterFrequency(i); + + const qint32 defVol = eq()->BandLevel(i); + + retval.append(EffectParameter(i, + tr("Frequency band, %1 Hz").arg(hz), + EffectParameter::LogarithmicHint, + QVariant(qint32(defVol)), + QVariant(qint32(dbMin)), + QVariant(qint32(dbMax)), + QVariantList(), + QString())); + } + + m_effect.reset(); + + return retval; +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h new file mode 100644 index 0000000..5ef2af9 --- /dev/null +++ b/src/3rdparty/phonon/mmf/audioequalizer.h @@ -0,0 +1,63 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_AUDIOEQUALIZER_H +#define PHONON_MMF_AUDIOEQUALIZER_H + +#include "abstractaudioeffect.h" + +class CAudioEqualizer; + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ +/** + * @short A classic equalizer. + * + * The equalizer has a number of bands, and each band has a frequency, and a + * volume. With Phonon's API, this is modeled such that each band is one + * Phonon::EffectParameter, where Phonon::EffectParameter::id() is the band + * number, and the setting is the volume level. + */ +class AudioEqualizer : public AbstractAudioEffect +{ + Q_OBJECT +public: + AudioEqualizer(QObject *parent); + +protected: + virtual void parameterChanged(const int id, + const QVariant &value); + + virtual void activateOn(CPlayerType *player); + +private: + inline CAudioEqualizer *eq() const; + QList<EffectParameter> createParams(); + QScopedPointer<CAudioEqualizer> m_bassBoost; +}; +} +} + +QT_END_NAMESPACE + +#endif + diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index 909e568..d2e7d76 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -33,7 +33,7 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AudioOutput::AudioOutput(Backend *, QObject *parent) : QObject(parent) +MMF::AudioOutput::AudioOutput(Backend *, QObject *parent) : MediaNode(parent) , m_volume(InitialVolume) , m_observer(NULL) { diff --git a/src/3rdparty/phonon/mmf/audiooutput.h b/src/3rdparty/phonon/mmf/audiooutput.h index 001190f..0d3cca7 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.h +++ b/src/3rdparty/phonon/mmf/audiooutput.h @@ -19,6 +19,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_AUDIOOUTPUT_H #define PHONON_MMF_AUDIOOUTPUT_H +#include "mmf_medianode.h" #include <phonon/audiooutputinterface.h> QT_BEGIN_NAMESPACE @@ -46,8 +47,8 @@ class VolumeObserver; * * @author Frans Englich<frans.englich@nokia.com> */ -class AudioOutput : public QObject - , public AudioOutputInterface +class AudioOutput : public MediaNode + , public AudioOutputInterface { Q_OBJECT Q_INTERFACES(Phonon::AudioOutputInterface) diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 1229625..127b921 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -220,6 +220,12 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) TRACE_EXIT_0(); } +CPlayerType *MMF::AudioPlayer::player() const +{ + return m_player; +} + + #ifdef QT_PHONON_MMF_AUDIO_DRM void MMF::AudioPlayer::MaloLoadingStarted() { diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index 424985c..3245159 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -44,9 +44,9 @@ namespace MMF * @short Wrapper over MMF audio client utility */ class AudioPlayer : public AbstractMediaPlayer - , public MPlayerObserverType // typedef + , public MPlayerObserverType // typedef #ifdef QT_PHONON_MMF_AUDIO_DRM - , public MAudioLoadingObserver + , public MAudioLoadingObserver #endif { Q_OBJECT @@ -86,6 +86,7 @@ public: virtual void MapcPlayComplete(TInt aError); #endif + CPlayerType *player() const; Q_SIGNALS: void totalTimeChanged(qint64 length); void finished(); @@ -99,7 +100,6 @@ private: * CMdaAudioPlayerUtility and CDrmPlayerUtility */ CPlayerType* m_player; - }; } } diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 71e51d9..d05b543 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -23,8 +23,11 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <apmrec.h> // for CDataTypeArray #include <apmstd.h> // for TDataType -#include "backend.h" +#include "abstractaudioeffect.h" #include "audiooutput.h" +#include "audioplayer.h" +#include "backend.h" +#include "effectfactory.h" #include "mediaobject.h" #include "utils.h" #include "videowidget.h" @@ -48,7 +51,7 @@ Backend::Backend(QObject *parent) : QObject(parent) TRACE_EXIT_0(); } -QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &) +QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args) { TRACE_CONTEXT(Backend::createObject, EBackend); TRACE_ENTRY("class %d", c); @@ -61,15 +64,20 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const break; case MediaObjectClass: - result = new MediaObject(parent); + result = new MediaObject(parent); break; case VolumeFaderEffectClass: case VisualizationClass: case VideoDataOutputClass: case EffectClass: - break; + { + Q_ASSERT(args.count() == 1); + Q_ASSERT(args.first().type() == QVariant::Int); + const AbstractAudioEffect::Type effect = AbstractAudioEffect::Type(args.first().toInt()); + return EffectFactory::createAudioEffect(effect, parent); + } case VideoWidgetClass: result = new VideoWidget(qobject_cast<QWidget *>(parent)); break; @@ -81,14 +89,32 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const TRACE_RETURN("0x%08x", result); } -QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType) const +QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const { - return QList<int>(); + TRACE_CONTEXT(Backend::objectDescriptionIndexes, EAudioApi); + TRACE_ENTRY_0(); + QList<int> retval; + + switch(type) + { + case EffectType: + retval.append(EffectFactory::effectIndexes()); + default: + ; + } + + TRACE_EXIT_0(); + return retval; } -QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType, int) const +QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const { - return QHash<QByteArray, QVariant>(); + TRACE_CONTEXT(Backend::connectNodes, EBackend); + + if (type == EffectType) + return EffectFactory::audioEffectDescriptions(AbstractAudioEffect::Type(index)); + else + return QHash<QByteArray, QVariant>(); } bool Backend::startConnectionChange(QSet<QObject *>) @@ -100,40 +126,25 @@ bool Backend::connectNodes(QObject *source, QObject *target) { TRACE_CONTEXT(Backend::connectNodes, EBackend); TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); + Q_ASSERT(qobject_cast<MediaNode *>(source)); + Q_ASSERT(qobject_cast<MediaNode *>(target)); - MediaObject *const mediaObject = qobject_cast<MediaObject *>(source); - AudioOutput *const audioOutput = qobject_cast<AudioOutput *>(target); - VideoWidget *const videoWidget = qobject_cast<VideoWidget *>(target); - - bool result = false; - - if (mediaObject and audioOutput) { - TRACE("mediaObject 0x%08x -> audioOutput 0x%08x", mediaObject, audioOutput); - audioOutput->setVolumeObserver(mediaObject); - result = true; - } + MediaNode *const mediaSource = static_cast<MediaNode *>(source); + MediaNode *const mediaTarget = static_cast<MediaNode *>(target); - if (mediaObject and videoWidget) { - TRACE("mediaObject 0x%08x -> videoWidget 0x%08x", mediaObject, videoWidget); - mediaObject->setVideoOutput(&videoWidget->videoOutput()); - result = true; - } + mediaSource->connectMediaNode(mediaTarget); - TRACE_RETURN("%d", result); + return false; } bool Backend::disconnectNodes(QObject *source, QObject *target) { TRACE_CONTEXT(Backend::disconnectNodes, EBackend); TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); + Q_ASSERT(qobject_cast<MediaNode *>(source)); + Q_ASSERT(qobject_cast<MediaNode *>(target)); - MediaObject *const mediaObject = qobject_cast<MediaObject *>(source); - AudioOutput *const audioOutput = qobject_cast<AudioOutput *>(target); - VideoWidget *const videoWidget = qobject_cast<VideoWidget *>(target); - - bool result = true; - - // TODO: disconnection + const bool result = static_cast<MediaNode *>(source)->disconnectMediaNode(static_cast<MediaNode *>(target)); TRACE_RETURN("%d", result); } diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 7598fa7..1886ae6 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -29,7 +29,7 @@ namespace Phonon namespace MMF { class Backend : public QObject - , public BackendInterface + , public BackendInterface { Q_OBJECT Q_INTERFACES(Phonon::BackendInterface) diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp new file mode 100644 index 0000000..ca9d5cc --- /dev/null +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -0,0 +1,45 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#include <BassBoostBase.h> + +#include "bassboost.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +BassBoost::BassBoost(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect(parent, + QList<EffectParameter>()) +{ +} + +void BassBoost::parameterChanged(const int, + const QVariant &) +{ + // We should never be called, because we have no parameters. +} + +void BassBoost::activateOn(CPlayerType *player) +{ + m_effect.reset(CBassBoost::NewL(*player, true)); +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h new file mode 100644 index 0000000..bf3c6c4 --- /dev/null +++ b/src/3rdparty/phonon/mmf/bassboost.h @@ -0,0 +1,59 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_BASSBOOST_H +#define PHONON_MMF_BASSBOOST_H + +#include "abstractaudioeffect.h" + +class CBassBoost; + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ +/** + * @short An "bass boost" effect. + * + * The documentation does not say what "bass boost" is, neither has it anykind + * of setting. It's an on or off thing. + */ +class BassBoost : public AbstractAudioEffect +{ + Q_OBJECT +public: + BassBoost(QObject *parent); + +protected: + virtual void parameterChanged(const int id, + const QVariant &value); + + virtual void activateOn(CPlayerType *player); + +private: + QScopedPointer<CBassBoost> m_bassBoost; +}; +} +} + +QT_END_NAMESPACE + +#endif + diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp new file mode 100644 index 0000000..41f48d2 --- /dev/null +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -0,0 +1,156 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#include <QObject> + +#include <AudioEqualizerBase.h> +#include <BassBoostBase.h> +#include <DistanceAttenuationBase.h> +#include <DopplerBase.h> +#include <EnvironmentalReverbBase.h> +#include <ListenerOrientationBase.h> +#include <LocationBase.h> +#include <LoudnessBase.h> +#include <RoomLevelBase.h> +#include <SourceOrientationBase.h> +#include <StereoWideningBase.h> + +#include "audioequalizer.h" +#include "bassboost.h" + +#include "effectfactory.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +QHash<QByteArray, QVariant> EffectFactory::constructEffectDescription(const QString &name, + const QString &description) +{ + QHash<QByteArray, QVariant> retval; + + retval.insert("name", name); + retval.insert("description", description); + retval.insert("available", true); + + return retval; +} + + +QHash<QByteArray, QVariant> EffectFactory::audioEffectDescriptions(AbstractAudioEffect::Type type) +{ + switch (type) + { + case AbstractAudioEffect::EffectAudioEqualizer: + return constructEffectDescription(QObject::tr("audio equalizer"), "Audio equalizer."); + case AbstractAudioEffect::EffectBassBoost: + return constructEffectDescription(QObject::tr("Bass boost"), "Bass boost."); + case AbstractAudioEffect::EffectDistanceAttenuation: + return constructEffectDescription(QObject::tr("Distance Attenuation"), "Distance Attenuation."); + case AbstractAudioEffect::EffectEnvironmentalReverb: + return constructEffectDescription(QObject::tr("Environmental Reverb"), "Environmental Reverb."); + case AbstractAudioEffect::EffectListenerOrientation: + return constructEffectDescription(QObject::tr("Environmental Reverb"), "Environmental Reverb."); + case AbstractAudioEffect::EffectLoudness: + return constructEffectDescription(QObject::tr("Loudness"), "Loudness."); + //case EffectRoomLevel: + case AbstractAudioEffect::EffectSourceOrientation: + return constructEffectDescription(QObject::tr("Source Orientation"), "Source Orientation."); + case AbstractAudioEffect::EffectStereoWidening: + return constructEffectDescription(QObject::tr("Stereo Widening"), "Stereo Widening."); + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect type."); + return QHash<QByteArray, QVariant>(); +} + +AbstractAudioEffect *EffectFactory::createAudioEffect(AbstractAudioEffect::Type type, + QObject *parent) +{ + Q_ASSERT(parent); + + switch (type) + { + case AbstractAudioEffect::EffectBassBoost: + return new BassBoost(parent); + case AbstractAudioEffect::EffectAudioEqualizer: + return new AudioEqualizer(parent); + case AbstractAudioEffect::EffectDistanceAttenuation: + case AbstractAudioEffect::EffectEnvironmentalReverb: + case AbstractAudioEffect::EffectListenerOrientation: + case AbstractAudioEffect::EffectLoudness: + //AbstractAudioEffect::EffectRoomLevel, + case AbstractAudioEffect::EffectSourceOrientation: + case AbstractAudioEffect::EffectStereoWidening: + ; + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect."); + return 0; +} + +template<typename TEffect> +bool isEffectSupported() +{ + AudioPlayer audioPlayer; + + QScopedPointer<TEffect> eff; + TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.player()))); + + return errorCode != KErrNone; +} + +QList<int> EffectFactory::effectIndexes() +{ + QList<int> retval; + + if (isEffectSupported<CAudioEqualizer>()) + retval.append(AbstractAudioEffect::EffectAudioEqualizer); + + if (isEffectSupported<CBassBoost>()) + retval.append(AbstractAudioEffect::EffectBassBoost); + + if (isEffectSupported<CDistanceAttenuation>()) + retval.append(AbstractAudioEffect::EffectDistanceAttenuation); + + if (isEffectSupported<CEnvironmentalReverb>()) + retval.append(AbstractAudioEffect::EffectEnvironmentalReverb); + + if (isEffectSupported<CLoudness>()) + retval.append(AbstractAudioEffect::EffectLoudness); + + if (isEffectSupported<CListenerOrientation>()) + retval.append(AbstractAudioEffect::EffectListenerOrientation); + + if (isEffectSupported<CSourceOrientation>()) + retval.append(AbstractAudioEffect::EffectSourceOrientation); + + /* + if (isEffectSupported<CRoomLevel>()) + retval.append(EffectRoomLevel); + */ + + if (isEffectSupported<CStereoWidening>()) + retval.append(AbstractAudioEffect::EffectStereoWidening); + + return retval; +} + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/effectfactory.h b/src/3rdparty/phonon/mmf/effectfactory.h new file mode 100644 index 0000000..d5dde27 --- /dev/null +++ b/src/3rdparty/phonon/mmf/effectfactory.h @@ -0,0 +1,76 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_EFFECTFACTORY_H +#define PHONON_MMF_EFFECTFACTORY_H + +#include "abstractaudioeffect.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace MMF +{ + +/** + * @short Contains utility functions related to effects. + */ +class EffectFactory +{ +public: + /** + * @short Creates an audio effect of type @p type. + */ + static AbstractAudioEffect *createAudioEffect(AbstractAudioEffect::Type type, + QObject *parent); + + /** + * @short Return the properties for effect @p type. + * + * This handles the effects for + * BackendInterface::objectDescriptionProperties(). + */ + static QHash<QByteArray, QVariant> audioEffectDescriptions(AbstractAudioEffect::Type type); + + /** + * @short Returns the indexes for the supported effects. + * + * This handles the effects for + * BackendInterface::objectDescriptionIndexes(). + */ + static QList<int> effectIndexes(); + +private: + static inline QHash<QByteArray, QVariant> constructEffectDescription(const QString &name, + const QString &description); + + /** + * This class is not supposed to be instantiated, so disable + * the default constructor. + */ + inline EffectFactory(); + Q_DISABLE_COPY(EffectFactory); +}; +} +} + +QT_END_NAMESPACE + +#endif + diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index a2a7e4d..4c7dc6d 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -16,12 +16,16 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include "audiooutput.h" #include "audioplayer.h" #include "defs.h" #include "dummyplayer.h" -#include "mediaobject.h" +#include "utils.h" #include "utils.h" #include "videoplayer.h" +#include "videowidget.h" + +#include "mediaobject.h" #include <QDir> @@ -34,8 +38,8 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::MediaObject::MediaObject(QObject *parent) : QObject(parent) - , m_recognizerOpened(false) +MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(parent) + , m_recognizerOpened(false) { m_player.reset(new DummyPlayer()); @@ -366,5 +370,41 @@ void MMF::MediaObject::setVideoOutput(VideoOutput* videoOutput) } +AbstractPlayer *MediaObject::abstractPlayer() const +{ + return m_player.data(); +} + +bool MediaObject::connectMediaNode(MediaNode *target) +{ + TRACE_CONTEXT(Backend::connect, EBackend); + + MediaNode::connectMediaNode(target); + + bool result = false; + + { + AudioOutput *const audioOutput = qobject_cast<AudioOutput *>(target); + + if (audioOutput) { + TRACE("this 0x%08x -> audioOutput 0x%08x", this, audioOutput); + audioOutput->setVolumeObserver(this); + return true; + } + } + + { + VideoWidget *const videoWidget = qobject_cast<VideoWidget *>(target); + + if (videoWidget) { + TRACE("this 0x%08x -> videoWidget 0x%08x", this, videoWidget); + this->setVideoOutput(&videoWidget->videoOutput()); + return true; + } + } + + return false; +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index c53b908..1f19068 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 <http://www.gnu.org/licenses/>. // For recognizer #include <apgcli.h> +#include "abstractplayer.h" +#include "mmf_medianode.h" #include "defs.h" #include "volumeobserver.h" @@ -42,9 +44,9 @@ class VideoOutput; /** * @short Facade class which wraps MMF client utility instance */ -class MediaObject : public QObject - , public MediaObjectInterface - , public VolumeObserver +class MediaObject : public MediaNode + , public MediaObjectInterface + , public VolumeObserver { Q_OBJECT Q_INTERFACES(Phonon::MediaObjectInterface) @@ -78,7 +80,14 @@ public: // VolumeObserver void volumeChanged(qreal volume); - void setVideoOutput(VideoOutput* videoOutput); + // MediaNode + virtual bool connectMediaNode(MediaNode *target); + + /** + * This class owns the AbstractPlayer, and will delete it upon + * destruction. + */ + AbstractPlayer *abstractPlayer() const; Q_SIGNALS: void totalTimeChanged(qint64 length); @@ -109,6 +118,8 @@ private: static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); private: + void setVideoOutput(VideoOutput* videoOutput); + // Audio / video media type recognition bool m_recognizerOpened; RApaLsSession m_recognizer; diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.cpp b/src/3rdparty/phonon/mmf/mmf_medianode.cpp new file mode 100644 index 0000000..a210c49 --- /dev/null +++ b/src/3rdparty/phonon/mmf/mmf_medianode.cpp @@ -0,0 +1,63 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#include "mmf_medianode.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +MMF::MediaNode::MediaNode(QObject *parent) : QObject::QObject(parent) + , m_source(0) + , m_target(0) +{ +} + +bool MMF::MediaNode::connectMediaNode(MediaNode *target) +{ + m_target = target; + m_target->setSource(this); + return true; +} + +bool MMF::MediaNode::disconnectMediaNode(MediaNode *target) +{ + Q_UNUSED(target); + m_target = 0; + return false; +} + +void MMF::MediaNode::setSource(MediaNode *source) +{ + m_source = source; +} + +MMF::MediaNode *MMF::MediaNode::source() const +{ + return m_source; +} + +MMF::MediaNode *MMF::MediaNode::target() const +{ + return m_target; +} + + +QT_END_NAMESPACE + diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.h b/src/3rdparty/phonon/mmf/mmf_medianode.h new file mode 100644 index 0000000..17917aa --- /dev/null +++ b/src/3rdparty/phonon/mmf/mmf_medianode.h @@ -0,0 +1,79 @@ +/* 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef PHONON_MMF_MEDIANODE_H +#define PHONON_MMF_MEDIANODE_H + +#include <QObject> +#include <Phonon/EffectInterface> +#include "audioplayer.h" + +QT_BEGIN_NAMESPACE + +/** + * @file mmf_medianode.h mmf_medianode.cpp + * + * This file starts with mmf_ in order to avoid clash with Phonon's + * medianode.h. The GStreamer backend has a file named medianode.h, but it + * isn't compiled with ABLD build system, which have problems with separating + * user and system include paths. + */ + +namespace Phonon +{ +namespace MMF +{ +/** + * @short Base class for all nodes in the MMF backend. + * + * MediaNode is the base class for all nodes in the chain for MMF. Currently + * they are: + * + * - MediaObject: a source of media + * - AbstractEffect: supplying audio effects + * - AudioOutput: pretty much a dummy interface, but is also MediaNode in order + * to simplify connection/disconnection. + * + * MediaNode provides spectatability into the chain, and also allows the + * connection code to be written in a polymorphic manner, instead of putting it + * all in the Backend class. + */ +class MediaNode : public QObject +{ + Q_OBJECT +public: + MediaNode(QObject *parent); + + virtual bool connectMediaNode(MediaNode *target); + virtual bool disconnectMediaNode(MediaNode *target); + void setSource(MediaNode *source); + + MediaNode *source() const; + MediaNode *target() const; + +private: + MediaNode *m_source; + MediaNode *m_target; +}; +} +} + +QT_END_NAMESPACE + +#endif + diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp index be3c752..67e245e 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -44,7 +44,7 @@ static const qreal DefaultSaturation = 1.0; //----------------------------------------------------------------------------- MMF::VideoWidget::VideoWidget(QWidget* parent) - : QObject(parent) + : MediaNode(parent) , m_widget(new VideoOutput(parent)) , m_aspectRatio(DefaultAspectRatio) , m_brightness(DefaultBrightness) diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index e2e1f33..89551b7 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -19,9 +19,11 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_VIDEOWIDGET_H #define PHONON_MMF_VIDEOWIDGET_H +#include "mmf_medianode.h" + #include <QtGui/QWidget> -#include <phonon/videowidget.h> -#include <phonon/videowidgetinterface.h> +#include <Phonon/VideoWidget> +#include <Phonon/VideoWidgetInterface> QT_BEGIN_NAMESPACE @@ -31,8 +33,8 @@ namespace MMF { class VideoOutput; -class VideoWidget : public QObject - , public Phonon::VideoWidgetInterface +class VideoWidget : public MediaNode + , public Phonon::VideoWidgetInterface { Q_OBJECT Q_INTERFACES(Phonon::VideoWidgetInterface) diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index dc18d20..4e764dc 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -1,3 +1,2 @@ -TEMPLATE = subdirs -SUBDIRS = objectdump plugin - +TEMPLATE = subdirs +SUBDIRS = objectdump plugin diff --git a/src/plugins/phonon/mmf/plugin/plugin.pro b/src/plugins/phonon/mmf/plugin/plugin.pro index 418d354..f3a6a9c 100644 --- a/src/plugins/phonon/mmf/plugin/plugin.pro +++ b/src/plugins/phonon/mmf/plugin/plugin.pro @@ -22,28 +22,38 @@ phonon_mmf_audio_drm { } HEADERS += \ - $$PHONON_MMF_DIR/abstractplayer.h \ + $$PHONON_MMF_DIR/abstractaudioeffect.h \ $$PHONON_MMF_DIR/abstractmediaplayer.h \ + $$PHONON_MMF_DIR/abstractplayer.h \ $$PHONON_MMF_DIR/audiooutput.h \ + $$PHONON_MMF_DIR/audioequalizer.h \ $$PHONON_MMF_DIR/audioplayer.h \ $$PHONON_MMF_DIR/backend.h \ + $$PHONON_MMF_DIR/bassboost.h \ $$PHONON_MMF_DIR/defs.h \ $$PHONON_MMF_DIR/dummyplayer.h \ + $$PHONON_MMF_DIR/effectfactory.h \ + $$PHONON_MMF_DIR/mmf_medianode.h \ $$PHONON_MMF_DIR/mediaobject.h \ $$PHONON_MMF_DIR/utils.h \ $$PHONON_MMF_DIR/videooutput.h \ $$PHONON_MMF_DIR/videooutputobserver.h \ $$PHONON_MMF_DIR/videoplayer.h \ $$PHONON_MMF_DIR/videowidget.h \ - $$PHONON_MMF_DIR/volumeobserver.h + $$PHONON_MMF_DIR/volumeobserver.h SOURCES += \ + $$PHONON_MMF_DIR/abstractaudioeffect.cpp \ + $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ $$PHONON_MMF_DIR/abstractplayer.cpp \ - $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ $$PHONON_MMF_DIR/audiooutput.cpp \ + $$PHONON_MMF_DIR/audioequalizer.cpp \ $$PHONON_MMF_DIR/audioplayer.cpp \ $$PHONON_MMF_DIR/backend.cpp \ + $$PHONON_MMF_DIR/bassboost.cpp \ $$PHONON_MMF_DIR/dummyplayer.cpp \ + $$PHONON_MMF_DIR/effectfactory.cpp \ + $$PHONON_MMF_DIR/mmf_medianode.cpp \ $$PHONON_MMF_DIR/mediaobject.cpp \ $$PHONON_MMF_DIR/utils.cpp \ $$PHONON_MMF_DIR/videooutput.cpp \ @@ -51,15 +61,18 @@ SOURCES += \ $$PHONON_MMF_DIR/videowidget.cpp debug { - INCLUDEPATH += $$PHONON_MMF_DIR/objectdump - LIBS += -lobjectdump + INCLUDEPATH += $$PHONON_MMF_DIR/objectdump + LIBS += -lobjectdump } - -LIBS += -lmediaclientvideo # For CVideoPlayerUtility -LIBS += -lcone # For CCoeEnv -LIBS += -lws32 # For RWindow -LIBS += -lefsrv # For file server -LIBS += -lapgrfx -lapmime # For recognizer + +LIBS += -lmediaclientvideo # For CVideoPlayerUtility +LIBS += -lcone # For CCoeEnv +LIBS += -lws32 # For RWindow +LIBS += -lefsrv # For file server +LIBS += -lapgrfx -lapmime # For recognizer + +# These are for effects. +LIBS += -lAudioEqualizerEffect.lib -lBassBoostEffect.lib -lDistanceAttenuationEffect.lib -lDopplerBase.lib -lEffectBase.lib -lEnvironmentalReverbEffect.lib -lListenerDopplerEffect.lib -lListenerLocationEffect.lib -lListenerOrientationEffect.lib -lLocationBase.lib -lLoudnessEffect.lib -lOrientationBase.lib -lRoomLevelEffect.lib -lSourceDopplerEffect.lib -lSourceLocationEffect.lib -lSourceOrientationEffect.lib -lStereoWideningEffect.lib # This is needed for having the .qtplugin file properly created on Symbian. QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/phonon_backend |