source: trunk/src/3rdparty/phonon/mmf/effectfactory.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1/* This file is part of the KDE project.
2
3Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5This library is free software: you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation, either version 2.1 or 3 of the License.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public License
15along with this library. If not, see <http://www.gnu.org/licenses/>.
16
17*/
18
19#include <QObject>
20#include <QCoreApplication>
21
22#include <mdaaudiooutputstream.h>
23
24#include "audioequalizer.h"
25#include "bassboost.h"
26#include "environmentalreverb.h"
27#include "loudness.h"
28#include "stereowidening.h"
29
30#include "effectfactory.h"
31
32QT_BEGIN_NAMESPACE
33
34using namespace Phonon;
35using namespace Phonon::MMF;
36
37/*! \class MMF::EffectFactory
38 \internal
39*/
40
41EffectFactory::EffectFactory(QObject *parent)
42 : QObject(parent)
43 , m_initialized(false)
44{
45
46}
47
48EffectFactory::~EffectFactory()
49{
50
51}
52
53//-----------------------------------------------------------------------------
54// Public functions
55//-----------------------------------------------------------------------------
56
57AbstractAudioEffect *EffectFactory::createAudioEffect(Type type,
58 QObject *parent)
59{
60 // Lazily initialize
61 if (!m_initialized)
62 initialize();
63
64 Q_ASSERT(parent);
65
66 const QList<EffectParameter>& parameters = data(type).m_parameters;
67
68 AbstractAudioEffect *effect = 0;
69
70 switch (type)
71 {
72 case TypeBassBoost:
73 effect = new BassBoost(parent, parameters);
74 break;
75 case TypeAudioEqualizer:
76 effect = new AudioEqualizer(parent, parameters);
77 break;
78 case TypeEnvironmentalReverb:
79 effect = new EnvironmentalReverb(parent, parameters);
80 break;
81 case TypeLoudness:
82 effect = new Loudness(parent, parameters);
83 break;
84 case TypeStereoWidening:
85 effect = new StereoWidening(parent, parameters);
86 break;
87
88 // Not implemented
89 case TypeDistanceAttenuation:
90 case TypeListenerOrientation:
91 case TypeSourceOrientation:
92 // Fall through
93 default:
94 Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect");
95 }
96
97 return effect;
98}
99
100QHash<QByteArray, QVariant> EffectFactory::audioEffectDescriptions(Type type)
101{
102 // Lazily initialize
103 if (!m_initialized)
104 initialize();
105
106 return data(type).m_descriptions;
107}
108
109QList<int> EffectFactory::effectIndexes()
110{
111 // Lazily initialize
112 if (!m_initialized)
113 initialize();
114
115 QList<int> result;
116
117 QHash<Type, EffectData>::const_iterator i = m_effectData.begin();
118 for ( ; i != m_effectData.end(); ++i)
119 if (i.value().m_supported)
120 result.append(i.key());
121
122 return result;
123}
124
125//-----------------------------------------------------------------------------
126// Private functions
127//-----------------------------------------------------------------------------
128
129#define INITIALIZE_EFFECT(Effect) \
130 { \
131 EffectData data = getData<Effect>(); \
132 m_effectData.insert(Type##Effect, data); \
133 }
134
135void EffectFactory::initialize()
136{
137 Q_ASSERT_X(!m_initialized, Q_FUNC_INFO, "Already initialized");
138
139 INITIALIZE_EFFECT(AudioEqualizer)
140 INITIALIZE_EFFECT(BassBoost)
141 INITIALIZE_EFFECT(EnvironmentalReverb)
142 INITIALIZE_EFFECT(Loudness)
143 INITIALIZE_EFFECT(StereoWidening)
144
145 m_initialized = true;
146}
147
148// This class is just a wrapper which allows us to instantiate a
149// CMdaAudioOutputStream object. This is done in order to allow the
150// effects API to query the DevSound implementation, to discover
151// which effects are supported and what parameters they take.
152// Ideally, we would use CMMFDevSound directly, but this class is not
153// available in the public S60 SDK.
154class OutputStreamFactory : public MMdaAudioOutputStreamCallback
155{
156public:
157 CMdaAudioOutputStream* create()
158 {
159 CMdaAudioOutputStream* stream = 0;
160 QT_TRAP_THROWING(stream = CMdaAudioOutputStream::NewL(*this));
161 return stream;
162 }
163private:
164 void MaoscOpenComplete(TInt /*aError*/) { }
165 void MaoscBufferCopied(TInt /*aError*/, const TDesC8& /*aBuffer*/) { }
166 void MaoscPlayComplete(TInt /*aError*/) { }
167};
168
169template<typename BackendNode>
170EffectFactory::EffectData EffectFactory::getData()
171{
172 EffectData data;
173
174 // Create a temporary CMdaAudioOutputStream object, so that the effects
175 // API can query DevSound to discover which effects are supported.
176 OutputStreamFactory streamFactory;
177 QScopedPointer<CMdaAudioOutputStream> stream(streamFactory.create());
178
179 EffectParameter param(
180 /* parameterId */ AbstractAudioEffect::ParameterEnable,
181 /* name */ tr("Enabled"),
182 /* hints */ EffectParameter::ToggledHint,
183 /* defaultValue */ QVariant(bool(true)));
184 data.m_parameters.append(param);
185
186 data.m_supported = BackendNode::getParameters(stream.data(),
187 data.m_parameters);
188 if (data.m_supported) {
189 const QString description = QCoreApplication::translate
190 ("Phonon::MMF::EffectFactory", BackendNode::description());
191 data.m_descriptions.insert("name", description);
192 data.m_descriptions.insert("description", description);
193 data.m_descriptions.insert("available", true);
194 }
195
196 // Sanity check to ensure that all parameter IDs are unique
197 QSet<int> ids;
198 foreach (param, data.m_parameters) {
199 Q_ASSERT_X(ids.find(param.id()) == ids.end(), Q_FUNC_INFO,
200 "Parameter list contains duplicates");
201 ids.insert(param.id());
202 }
203
204 return data;
205}
206
207const EffectFactory::EffectData& EffectFactory::data(Type type) const
208{
209 QHash<Type, EffectData>::const_iterator i = m_effectData.find(type);
210 Q_ASSERT_X(i != m_effectData.end(), Q_FUNC_INFO, "Effect data not found");
211 return i.value();
212}
213
214QT_END_NAMESPACE
215
Note: See TracBrowser for help on using the repository browser.