diff options
Diffstat (limited to 'src/3rdparty')
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractaudioeffect.cpp | 9 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractaudioeffect.h | 12 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/audioequalizer.cpp | 40 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/audioequalizer.h | 13 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/backend.cpp | 11 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/backend.h | 2 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/bassboost.cpp | 21 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/bassboost.h | 10 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/effectfactory.cpp | 189 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/effectfactory.h | 50 |
10 files changed, 225 insertions, 132 deletions
diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index e7ef9b2..c75c08e 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -37,10 +37,11 @@ using namespace Phonon::MMF; AbstractAudioEffect::AbstractAudioEffect(QObject *parent, const QList<EffectParameter> ¶ms) - : MediaNode::MediaNode(parent) + : MediaNode(parent) , m_player(0) , m_params(params) { + } QList<EffectParameter> AbstractAudioEffect::parameters() const @@ -63,8 +64,10 @@ void AbstractAudioEffect::setParameterValue(const EffectParameter ¶m, { m_values.insert(param.id(), newValue); parameterChanged(param.id(), newValue); - // TODO: handle audio effect errors - TRAP_IGNORE(m_effect->ApplyL()); + + if (m_effect.data()) + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->ApplyL()); } void AbstractAudioEffect::connectMediaObject(MediaObject *mediaObject) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 6f74a73..df1d08a 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -68,18 +68,6 @@ public: virtual void setParameterValue(const EffectParameter &, const QVariant &newValue); - enum Type - { - EffectAudioEqualizer = 1, - EffectBassBoost, - EffectDistanceAttenuation, - EffectEnvironmentalReverb, - EffectListenerOrientation, - EffectLoudness, - EffectSourceOrientation, - EffectStereoWidening - }; - protected: // MediaNode void connectMediaObject(MediaObject *mediaObject); diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp index c2936c5..5aa659a 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.cpp +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -28,8 +28,10 @@ using namespace Phonon::MMF; \internal */ -AudioEqualizer::AudioEqualizer(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect(parent, createParams()) +AudioEqualizer::AudioEqualizer(QObject *parent, const QList<EffectParameter> ¶meters) + : AbstractAudioEffect::AbstractAudioEffect(parent, parameters) { + } void AudioEqualizer::parameterChanged(const int pid, @@ -68,30 +70,32 @@ void AudioEqualizer::setBandLevel(int band, int level) TRAP_IGNORE(effect->SetBandLevelL(band, level)); } -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; +//----------------------------------------------------------------------------- +// Static functions +//----------------------------------------------------------------------------- - CAudioEqualizer *eqPtr = 0; - QT_TRAP_THROWING(eqPtr = CAudioEqualizer::NewL(*dummyPlayer.nativePlayer())); - QScopedPointer<CAudioEqualizer> e(eqPtr); +const char* AudioEqualizer::description() +{ + return "Audio equalizer"; +} +void AudioEqualizer::getParameters(NativeEffect *effect, + QList<EffectParameter> ¶meters) +{ TInt32 dbMin; TInt32 dbMax; - e->DbLevelLimits(dbMin, dbMax); + effect->DbLevelLimits(dbMin, dbMax); - const int bandCount = e->NumberOfBands(); + const int bandCount = effect->NumberOfBands(); - for (int i = 0; i < bandCount; ++i) { - const qint32 hz = e->CenterFrequency(i); + // For some reason, band IDs are 1-based, as opposed to the + // 0-based indices used in just about other Symbian API...! + for (int i = 1; i <= bandCount; ++i) { + const qint32 hz = effect->CenterFrequency(i); - const qint32 defVol = e->BandLevel(i); + const qint32 defVol = effect->BandLevel(i); - retval.append(EffectParameter(i, + parameters.append(EffectParameter(i, tr("Frequency band, %1 Hz").arg(hz), EffectParameter::LogarithmicHint, QVariant(qint32(defVol)), @@ -100,8 +104,6 @@ QList<EffectParameter> AudioEqualizer::createParams() QVariantList(), QString())); } - - return retval; } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h index 10fe9ad..ee3d297 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.h +++ b/src/3rdparty/phonon/mmf/audioequalizer.h @@ -21,6 +21,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "abstractaudioeffect.h" +class CAudioEqualizer; + QT_BEGIN_NAMESPACE namespace Phonon @@ -39,7 +41,13 @@ class AudioEqualizer : public AbstractAudioEffect { Q_OBJECT public: - AudioEqualizer(QObject *parent); + AudioEqualizer(QObject *parent, const QList<EffectParameter> ¶meters); + + // Static interface required by EffectFactory + static const char* description(); + typedef CAudioEqualizer NativeEffect; + static void getParameters(NativeEffect *effect, + QList<EffectParameter> ¶meters); protected: // AbstractAudioEffect @@ -50,9 +58,6 @@ protected: private: void setBandLevel(int band, int level); -private: - static QList<EffectParameter> createParams(); - }; } } diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 0c07f66..3568a49 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -45,6 +45,7 @@ using namespace Phonon::MMF; Backend::Backend(QObject *parent) : QObject(parent) , m_ancestorMoveMonitor(new AncestorMoveMonitor(this)) + , m_effectFactory(new EffectFactory(this)) { TRACE_CONTEXT(Backend::Backend, EBackend); TRACE_ENTRY_0(); @@ -81,9 +82,9 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const { 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); + const EffectFactory::Type type = + static_cast<EffectFactory::Type>(args.first().toInt()); + return m_effectFactory->createAudioEffect(type, parent); } case VideoWidgetClass: result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast<QWidget *>(parent)); @@ -105,7 +106,7 @@ QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const switch(type) { case EffectType: - retval.append(EffectFactory::effectIndexes()); + retval.append(m_effectFactory->effectIndexes()); break; case AudioOutputDeviceType: // We only have one possible output device, but we need at least @@ -126,7 +127,7 @@ QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescripti switch (type) { case EffectType: - return EffectFactory::audioEffectDescriptions(AbstractAudioEffect::Type(index)); + return m_effectFactory->audioEffectDescriptions(EffectFactory::Type(index)); case AudioOutputDeviceType: return AudioOutput::audioOutputDescription(index); default: diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 9e3d3b3..6b85625 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -20,6 +20,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #define PHONON_MMF_BACKEND_H #include "ancestormovemonitor.h" +#include "effectfactory.h" #include <Phonon/MediaSource> #include <Phonon/BackendInterface> @@ -53,6 +54,7 @@ Q_SIGNALS: private: QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor; + QScopedPointer<EffectFactory> m_effectFactory; }; } diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index ae96b45..4edd102 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -28,15 +28,16 @@ using namespace Phonon::MMF; \internal */ -BassBoost::BassBoost(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect(parent, - QList<EffectParameter>()) +BassBoost::BassBoost(QObject *parent, const QList<EffectParameter> ¶meters) + : AbstractAudioEffect::AbstractAudioEffect(parent, parameters) { + } void BassBoost::parameterChanged(const int, const QVariant &) { - Q_ASSERT_X(false, Q_FUNC_INFO, "BassBoost has not parameters"); + Q_ASSERT_X(false, Q_FUNC_INFO, "BassBoost has no parameters"); } void BassBoost::connectAudioPlayer(AudioPlayer::NativePlayer *player) @@ -51,5 +52,19 @@ void BassBoost::applyParameters() // No parameters to apply } +//----------------------------------------------------------------------------- +// Static functions +//----------------------------------------------------------------------------- + +const char* BassBoost::description() +{ + return "Bass boost"; +} + +void BassBoost::getParameters(NativeEffect*, QList<EffectParameter>&) +{ + +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h index 4ad0a6c..c3c48d0 100644 --- a/src/3rdparty/phonon/mmf/bassboost.h +++ b/src/3rdparty/phonon/mmf/bassboost.h @@ -21,6 +21,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "abstractaudioeffect.h" +class CBassBoost; + QT_BEGIN_NAMESPACE namespace Phonon @@ -37,7 +39,13 @@ class BassBoost : public AbstractAudioEffect { Q_OBJECT public: - BassBoost(QObject *parent); + BassBoost(QObject *parent, const QList<EffectParameter> ¶meters); + + // Static interface required by EffectFactory + static const char* description(); + typedef CBassBoost NativeEffect; + static void getParameters(NativeEffect *effect, + QList<EffectParameter> ¶meters); protected: // AbstractAudioEffect diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp index cc94367..a8cbf24 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.cpp +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -30,6 +30,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <SourceOrientationBase.h> #include <StereoWideningBase.h> +#include <mdaaudiooutputstream.h> + #include "audioequalizer.h" #include "bassboost.h" @@ -44,111 +46,154 @@ using namespace Phonon::MMF; \internal */ -QHash<QByteArray, QVariant> EffectFactory::constructEffectDescription(const QString &name, - const QString &description) +EffectFactory::EffectFactory(QObject *parent) + : QObject(parent) + , m_initialized(false) { - 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) +EffectFactory::~EffectFactory() { - switch (type) - { - case AbstractAudioEffect::EffectAudioEqualizer: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Audio Equalizer"), "Audio equalizer."); - case AbstractAudioEffect::EffectBassBoost: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Bass Boost"), "Bass boost."); - case AbstractAudioEffect::EffectDistanceAttenuation: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Distance Attenuation"), "Distance Attenuation."); - case AbstractAudioEffect::EffectEnvironmentalReverb: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Environmental Reverb"), "Environmental Reverb."); - case AbstractAudioEffect::EffectListenerOrientation: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Environmental Reverb"), "Environmental Reverb."); - case AbstractAudioEffect::EffectLoudness: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Loudness"), "Loudness."); - case AbstractAudioEffect::EffectSourceOrientation: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Source Orientation"), "Source Orientation."); - case AbstractAudioEffect::EffectStereoWidening: - return constructEffectDescription(QCoreApplication::translate("Phonon::MMF::EffectFactory", "Stereo Widening"), "Stereo Widening."); - } - Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect type."); - return QHash<QByteArray, QVariant>(); } -AbstractAudioEffect *EffectFactory::createAudioEffect(AbstractAudioEffect::Type type, +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +AbstractAudioEffect *EffectFactory::createAudioEffect(Type type, QObject *parent) { + // Lazily initialize + if (!m_initialized) + initialize(); + Q_ASSERT(parent); + const QList<EffectParameter>& parameters = data(type).m_parameters; + + AbstractAudioEffect *effect = 0; + 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: - case AbstractAudioEffect::EffectSourceOrientation: - case AbstractAudioEffect::EffectStereoWidening: - ; + case TypeBassBoost: + effect = new BassBoost(parent, parameters); + case TypeAudioEqualizer: + effect = new AudioEqualizer(parent, parameters); + case TypeDistanceAttenuation: + case TypeEnvironmentalReverb: + case TypeListenerOrientation: + case TypeLoudness: + case TypeSourceOrientation: + case TypeStereoWidening: + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect"); } - Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect."); - return 0; + return effect; } -template<typename TEffect> -bool isEffectSupported() +QHash<QByteArray, QVariant> EffectFactory::audioEffectDescriptions(Type type) { - AudioPlayer audioPlayer; - - QScopedPointer<TEffect> eff; - TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.nativePlayer()))); + // Lazily initialize + if (!m_initialized) + initialize(); - return errorCode != KErrNone; + return data(type).m_descriptions; } QList<int> EffectFactory::effectIndexes() { - QList<int> retval; + // Lazily initialize + if (!m_initialized) + initialize(); + + QList<int> result; - if (isEffectSupported<CAudioEqualizer>()) - retval.append(AbstractAudioEffect::EffectAudioEqualizer); + QHash<Type, EffectData>::const_iterator i = m_effectData.begin(); + for ( ; i != m_effectData.end(); ++i) + if (i.value().m_supported) + result.append(i.key()); - if (isEffectSupported<CBassBoost>()) - retval.append(AbstractAudioEffect::EffectBassBoost); + return result; +} + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- - /* We haven't implemented these yet. - if (isEffectSupported<CDistanceAttenuation>()) - retval.append(AbstractAudioEffect::EffectDistanceAttenuation); +#define INITIALIZE_EFFECT(Effect) \ + { \ + EffectData data = getData<Effect>(); \ + m_effectData.insert(Type##Effect, data); \ + } - if (isEffectSupported<CEnvironmentalReverb>()) - retval.append(AbstractAudioEffect::EffectEnvironmentalReverb); +void EffectFactory::initialize() +{ + Q_ASSERT_X(!m_initialized, Q_FUNC_INFO, "Already initialized"); - if (isEffectSupported<CLoudness>()) - retval.append(AbstractAudioEffect::EffectLoudness); + INITIALIZE_EFFECT(AudioEqualizer) + //INITIALIZE_EFFECT(BassBoost) - if (isEffectSupported<CListenerOrientation>()) - retval.append(AbstractAudioEffect::EffectListenerOrientation); + m_initialized = true; +} - if (isEffectSupported<CSourceOrientation>()) - retval.append(AbstractAudioEffect::EffectSourceOrientation); +// This class is just a wrapper which allows us to instantiate a +// CMdaAudioOutputStream object. This is done in order to allow the +// effects API to query the DevSound implementation, to discover +// which effects are supported and what parameters they take. +// Ideally, we would use CMMFDevSound directly, but this class is not +// available in the public S60 SDK. +class OutputStreamFactory : public MMdaAudioOutputStreamCallback +{ +public: + CMdaAudioOutputStream* create() + { + CMdaAudioOutputStream* stream = 0; + QT_TRAP_THROWING(stream = CMdaAudioOutputStream::NewL(*this)); + return stream; + } +private: + void MaoscOpenComplete(TInt /*aError*/) { } + void MaoscBufferCopied(TInt /*aError*/, const TDesC8& /*aBuffer*/) { } + void MaoscPlayComplete(TInt /*aError*/) { } +}; + +template<typename BackendNode> +EffectFactory::EffectData EffectFactory::getData() +{ + EffectData data; + + // Create a temporary CMdaAudioOutputStream object, so that the effects + // API can query DevSound to discover which effects are supported. + OutputStreamFactory streamFactory; + QScopedPointer<CMdaAudioOutputStream> stream(streamFactory.create()); + + typedef typename BackendNode::NativeEffect NativeEffect; + QScopedPointer<NativeEffect> effect; + TRAPD(err, effect.reset(NativeEffect::NewL(*stream))); + data.m_supported = (KErrNone == err); + + if (KErrNone == err) { + const QString description = QCoreApplication::translate + ("Phonon::MMF::EffectFactory", BackendNode::description()); + data.m_descriptions.insert("name", description); + data.m_descriptions.insert("description", description); + data.m_descriptions.insert("available", true); + + BackendNode::getParameters(effect.data(), data.m_parameters); + } - if (isEffectSupported<CStereoWidening>()) - retval.append(AbstractAudioEffect::EffectStereoWidening); - */ + return data; +} - return retval; +const EffectFactory::EffectData& EffectFactory::data(Type type) const +{ + QHash<Type, EffectData>::const_iterator i = m_effectData.find(type); + Q_ASSERT_X(i != m_effectData.end(), Q_FUNC_INFO, "Effect data not found"); + return i.value(); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/effectfactory.h b/src/3rdparty/phonon/mmf/effectfactory.h index e83ad15..45bd0f0 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.h +++ b/src/3rdparty/phonon/mmf/effectfactory.h @@ -31,14 +31,30 @@ namespace MMF /** * @short Contains utility functions related to effects. */ -class EffectFactory +class EffectFactory : public QObject { + Q_OBJECT + public: + EffectFactory(QObject *parent); + ~EffectFactory(); + + enum Type + { + TypeAudioEqualizer = 0 + , TypeBassBoost + , TypeDistanceAttenuation + , TypeEnvironmentalReverb + , TypeListenerOrientation + , TypeLoudness + , TypeSourceOrientation + , TypeStereoWidening + }; + /** * @short Creates an audio effect of type @p type. */ - static AbstractAudioEffect *createAudioEffect(AbstractAudioEffect::Type type, - QObject *parent); + AbstractAudioEffect *createAudioEffect(Type type, QObject *parent); /** * @short Return the properties for effect @p type. @@ -46,7 +62,7 @@ public: * This handles the effects for * BackendInterface::objectDescriptionProperties(). */ - static QHash<QByteArray, QVariant> audioEffectDescriptions(AbstractAudioEffect::Type type); + QHash<QByteArray, QVariant> audioEffectDescriptions(Type type); /** * @short Returns the indexes for the supported effects. @@ -54,19 +70,27 @@ public: * This handles the effects for * BackendInterface::objectDescriptionIndexes(). */ - static QList<int> effectIndexes(); + QList<int> effectIndexes(); private: - static inline QHash<QByteArray, QVariant> constructEffectDescription(const QString &name, - const QString &description); + void initialize(); + + struct EffectData + { + bool m_supported; + QHash<QByteArray, QVariant> m_descriptions; + QList<EffectParameter> m_parameters; + }; + + template<typename BackendNode> EffectData getData(); + const EffectData& data(Type type) const; + +private: + bool m_initialized; + QHash<Type, EffectData> m_effectData; - /** - * This class is not supposed to be instantiated, so disable - * the default constructor. - */ - inline EffectFactory(); - Q_DISABLE_COPY(EffectFactory) }; + } } |