summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/mmf/effectfactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/phonon/mmf/effectfactory.cpp')
-rw-r--r--src/3rdparty/phonon/mmf/effectfactory.cpp189
1 files changed, 117 insertions, 72 deletions
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