source: trunk/src/3rdparty/phonon/qt7/audioeffects.mm

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.4 KB
Line 
1/* This file is part of the KDE project.
2
3 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5 This library is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 2.1 or 3 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this library. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "audioeffects.h"
19
20QT_BEGIN_NAMESPACE
21
22namespace Phonon
23{
24namespace QT7
25{
26
27AudioEffectAudioNode::AudioEffectAudioNode(int effectType)
28 : AudioNode(1, 1), m_effectType(effectType)
29{
30}
31
32ComponentDescription AudioEffectAudioNode::getAudioNodeDescription() const
33{
34 ComponentDescription d;
35 d.componentType = kAudioUnitType_Effect;
36 d.componentSubType = m_effectType;
37 d.componentManufacturer = kAudioUnitManufacturer_Apple;
38 d.componentFlags = 0;
39 d.componentFlagsMask = 0;
40 return d;
41}
42
43void AudioEffectAudioNode::initializeAudioUnit()
44{
45 if (!m_audioUnit)
46 return;
47 foreach(int id, m_alteredParameters.keys()){
48 Float32 value = m_alteredParameters.value(id);
49 ComponentResult res = AudioUnitSetParameter(m_audioUnit, id, kAudioUnitScope_Global, 0, value, 0);
50 BACKEND_ASSERT2(res == noErr, "Could not initialize audio effect.", NORMAL_ERROR)
51 }
52}
53
54QVariant AudioEffectAudioNode::parameterValue(const Phonon::EffectParameter &parameter) const
55{
56 if (m_audioUnit){
57 Float32 value = 0;
58 AudioUnitGetParameter(m_audioUnit, parameter.id(), kAudioUnitScope_Global, 0, &value);
59 return QVariant(value);
60 } else if (m_alteredParameters.contains(parameter.id())){
61 return QVariant(m_alteredParameters.value(parameter.id()));
62 } else {
63 // Use default value:
64 AudioUnit tmpAudioUnit;
65 ComponentDescription description = getAudioNodeDescription();
66 Component component = FindNextComponent(0, &description);
67 BACKEND_ASSERT3(component, "Could not get parameters of audio effect.", NORMAL_ERROR, QVariant())
68 OSErr err = OpenAComponent(component, &tmpAudioUnit);
69 BACKEND_ASSERT3(err == noErr, "Could not get parameters of audio effect.", NORMAL_ERROR, QVariant())
70 AudioUnitParameterInfo info;
71 UInt32 size = sizeof(info);
72 ComponentResult res = AudioUnitGetProperty(tmpAudioUnit,
73 kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, parameter.id(), &info, &size);
74 BACKEND_ASSERT3(res == noErr, "Could not get parameter info from audio effect.", NORMAL_ERROR, QVariant())
75 return QVariant(info.defaultValue);
76 }
77}
78
79void AudioEffectAudioNode::setParameterValue(const Phonon::EffectParameter &parameter, const QVariant &newValue)
80{
81 Float32 value = 0;
82 if (newValue.isValid()){
83 value = newValue.toDouble();
84 m_alteredParameters.insert(parameter.id(), value);
85 } else {
86 // Use default value:
87 m_alteredParameters.remove(parameter.id());
88 if (m_audioUnit){
89 AudioUnit tmpAudioUnit;
90 ComponentDescription description = getAudioNodeDescription();
91 Component component = FindNextComponent(0, &description);
92 BACKEND_ASSERT2(component, "Could not get parameters of audio effect.", NORMAL_ERROR)
93 OSErr err = OpenAComponent(component, &tmpAudioUnit);
94 BACKEND_ASSERT2(err == noErr, "Could not get parameters of audio effect.", NORMAL_ERROR)
95 AudioUnitParameterInfo info;
96 UInt32 size = sizeof(info);
97 ComponentResult res = AudioUnitGetProperty(tmpAudioUnit,
98 kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, parameter.id(), &info, &size);
99 BACKEND_ASSERT2(res == noErr, "Could not get parameter info from audio effect.", NORMAL_ERROR)
100 value = info.defaultValue;
101 }
102 }
103
104 if (m_audioUnit){
105 ComponentResult res = AudioUnitSetParameter(m_audioUnit, parameter.id(), kAudioUnitScope_Global, 0, value, 0);
106 BACKEND_ASSERT2(res == noErr, "Could not set effect parameter value.", NORMAL_ERROR)
107 }
108}
109
110///////////////////////////////////////////////////////////////////////
111
112AudioEffect::AudioEffect(int effectType, QObject *parent)
113 : MediaNode(AudioSink | AudioSource, 0, parent)
114{
115 m_audioNode = new AudioEffectAudioNode(effectType);
116 setAudioNode(m_audioNode);
117}
118
119QList<Phonon::EffectParameter> AudioEffect::parameters() const
120{
121 QList<Phonon::EffectParameter> effectList;
122 // Create a temporary audio unit:
123 AudioUnit audioUnit;
124 ComponentDescription description = m_audioNode->getAudioNodeDescription();
125 Component component = FindNextComponent(0, &description);
126 BACKEND_ASSERT3(component, "Could not get parameters of audio effect.", NORMAL_ERROR, effectList)
127 OSErr err = OpenAComponent(component, &audioUnit);
128 BACKEND_ASSERT3(err == noErr, "Could not get parameters of audio effect.", NORMAL_ERROR, effectList)
129
130 UInt32 size = 0;
131 // Get parameter count:
132 ComponentResult res = AudioUnitGetProperty(audioUnit,
133 kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, 0, &size);
134 BACKEND_ASSERT3(res == noErr, "Could not get parameter count from audio effect.", NORMAL_ERROR, effectList)
135 int paramCount = size / sizeof(AudioUnitParameterID);
136
137 // Get parameters:
138 AudioUnitParameterID parameters[paramCount];
139 res = AudioUnitGetProperty(audioUnit,
140 kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, &parameters, &size);
141 BACKEND_ASSERT3(res == noErr, "Could not get parameter list from audio effect.", NORMAL_ERROR, effectList)
142
143 for (int i=0; i<paramCount; ++i)
144 effectList << createParameter(audioUnit, parameters[i]);
145
146 CloseComponent(audioUnit);
147 return effectList;
148}
149
150QString AudioEffect::name()
151{
152 ComponentDescription description = m_audioNode->getAudioNodeDescription();
153 Component component = FindNextComponent(0, &description);
154 BACKEND_ASSERT3(component, "Could not get audio effect name.", NORMAL_ERROR, QLatin1String("<unknown effect>"))
155
156 ComponentDescription cDesc;
157 Handle nameH = NewHandle(0);
158 GetComponentInfo(component, &cDesc, nameH, 0, 0);
159 HLock(nameH);
160 char *namePtr = *nameH;
161 int len = *namePtr++;
162 namePtr[len] = 0;
163 QString qsName = QString::fromUtf8(namePtr);
164 DisposeHandle(nameH);
165 return qsName;
166}
167
168QString AudioEffect::description()
169{
170 ComponentDescription description = m_audioNode->getAudioNodeDescription();
171 Component component = FindNextComponent(0, &description);
172 BACKEND_ASSERT3(component, "Could not get audio effect description.", NORMAL_ERROR, QLatin1String("<unknown effect>"))
173
174 ComponentDescription cDesc;
175 Handle descH = NewHandle(0);
176 GetComponentInfo(component, &cDesc, 0, descH, 0);
177 HLock(descH);
178 char *descPtr = *descH;
179 int len = *descPtr++;
180 descPtr[len] = 0;
181 QString qsDesc = QString::fromUtf8(descPtr);
182 DisposeHandle(descH);
183 return qsDesc;
184}
185
186QList<int> AudioEffect::effectList()
187{
188 QList<int> effects;
189
190 ComponentDescription d;
191 d.componentType = kAudioUnitType_Effect;
192 d.componentSubType = 0;
193 d.componentManufacturer = 0;
194 d.componentFlags = 0;
195 d.componentFlagsMask = 0;
196 Component component = FindNextComponent(0, &d);
197
198 while (component) {
199 ComponentDescription cDesc;
200 GetComponentInfo(component, &cDesc, 0, 0, 0);
201 effects << cDesc.componentSubType;
202 component = FindNextComponent(component, &d);
203 }
204 return effects;
205}
206
207Phonon::EffectParameter AudioEffect::createParameter(const AudioUnit &audioUnit, const AudioUnitParameterID &id) const
208{
209 AudioUnitParameterInfo info;
210 UInt32 size = sizeof(info);
211 ComponentResult res = AudioUnitGetProperty(audioUnit,
212 kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, id, &info, &size);
213 BACKEND_ASSERT3(res == noErr, "Could not get parameter info from audio effect.", NORMAL_ERROR, Phonon::EffectParameter())
214
215 QString name = info.flags & kAudioUnitParameterFlag_HasCFNameString
216 ? PhononCFString::toQString(info.cfNameString) : QLatin1String("<unknown parameter>");
217
218 Phonon::EffectParameter::Hint hint;
219 switch(info.unit){
220 case (kAudioUnitParameterUnit_Indexed):
221 case (kAudioUnitParameterUnit_Seconds):
222 case (kAudioUnitParameterUnit_SampleFrames):
223 case (kAudioUnitParameterUnit_Milliseconds):
224 hint = Phonon::EffectParameter::IntegerHint;
225 break;
226 case (kAudioUnitParameterUnit_Boolean):
227 hint = Phonon::EffectParameter::ToggledHint;
228 break;
229 default:
230 hint = Phonon::EffectParameter::LogarithmicHint;
231 break;
232 }
233
234 QVariant def(info.defaultValue);
235 QVariant min(info.minValue);
236 QVariant max(info.maxValue);
237 return Phonon::EffectParameter(id, name, hint, def, min, max, QVariantList(), name);
238}
239
240QVariant AudioEffect::parameterValue(const Phonon::EffectParameter &value) const
241{
242 return m_audioNode->parameterValue(value);
243}
244
245void AudioEffect::setParameterValue(const Phonon::EffectParameter &parameter, const QVariant &newValue)
246{
247 m_audioNode->setParameterValue(parameter, newValue);
248}
249
250}} //namespace Phonon::QT7
251
252QT_END_NAMESPACE
253
254#include "moc_audioeffects.cpp"
Note: See TracBrowser for help on using the repository browser.