1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/* 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 <QScopedPointer>
#include <AudioEffectBase.h>
#include <phonon/effectinterface.h>
#include "audioplayer.h"
#include "effectparameter.h"
#include "mmf_medianode.h"
class CMdaAudioOutputStream;
QT_BEGIN_NAMESPACE
namespace Phonon
{
namespace MMF
{
class AbstractPlayer;
class AbstractMediaPlayer;
/**
* @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);
// Phonon::EffectInterface
virtual QList<Phonon::EffectParameter> parameters() const;
virtual QVariant parameterValue(const Phonon::EffectParameter ¶m) const;
virtual void setParameterValue(const Phonon::EffectParameter &,
const QVariant &newValue);
// Parameters which are shared by all effects
enum CommonParameters
{
ParameterEnable = 0,
ParameterBase // must be last entry in enum
};
public Q_SLOTS:
void abstractPlayerChanged(AbstractPlayer *player);
void stateChanged(Phonon::State newState,
Phonon::State oldState);
protected:
// MediaNode
void connectMediaObject(MediaObject *mediaObject);
void disconnectMediaObject(MediaObject *mediaObject);
virtual void createEffect(AudioPlayer::NativePlayer *player) = 0;
// Effect-specific parameter changed
virtual int effectParameterChanged(const EffectParameter ¶m,
const QVariant &value);
private:
void createEffect();
void setEnabled(bool enabled);
const EffectParameter& internalParameter(int id) const;
int parameterChanged(const EffectParameter ¶m,
const QVariant &value);
protected:
QScopedPointer<CAudioEffect> m_effect;
private:
const QList<EffectParameter> m_params;
AbstractMediaPlayer * m_player;
QHash<int, QVariant> m_values;
};
}
}
// Macro for defining functions which depend on the native class name
// for each of the effects. Using this reduces repetition of boilerplate
// in the implementations of the backend effect nodes.
#ifdef Q_CC_NOKIAX86
# pragma warn_illtokenpasting off
#endif
#define PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(Effect) \
\
void Effect::createEffect(AudioPlayer::NativePlayer *player) \
{ \
C##Effect *ptr = 0; \
QT_TRAP_THROWING(ptr = C##Effect::NewL(*player)); \
m_effect.reset(ptr); \
} \
\
C##Effect* Effect::concreteEffect() \
{ \
return static_cast<C##Effect *>(m_effect.data()); \
}
QT_END_NAMESPACE
#endif
|