1 /***************************************************************************
2 initeffects.cpp - description
5 copyright : (C) 2006 by Jean-Baptiste Mardelle
7 copyright : (C) 2008 Marco Gittler
8 email : g.marco@freenet.de
9 ***************************************************************************/
11 /***************************************************************************
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
18 ***************************************************************************/
27 #include <KStandardDirs>
29 #include "initeffects.h"
31 initEffects::initEffects()
35 initEffects::~initEffects()
40 Mlt::Repository *initEffects::parseEffectFiles(EffectsList *audioEffectList, EffectsList *videoEffectList)
42 QStringList::Iterator more;
43 QStringList::Iterator it;
48 // Build effects. Retrieve the list of MLT's available effects first.
49 Mlt::Repository *repository = Mlt::Factory::init();
51 kDebug() << "Repository did not finish init " ;
54 Mlt::Properties *filters = repository->filters();
55 QStringList filtersList;
57 for (int i=0 ; i <filters->count() ; i++){
58 filtersList << filters->get_name(i);
61 // Build effects. check producers first.
63 Mlt::Properties *producers = repository->producers();
64 QStringList producersList;
65 for (int i=0 ; i <producers->count() ; i++){
66 producersList << producers->get_name(i);
71 KGlobal::dirs()->addResourceType("ladspa_plugin", "lib/ladspa");
72 KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/lib/ladspa");
73 KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/local/lib/ladspa");
74 KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/lib/ladspa");
75 KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/local/lib/ladspa");
77 kDebug()<<"// INIT EFFECT SEARCH"<<endl;
79 QStringList direc = KGlobal::dirs()->findDirs("data", "kdenlive/effects");
82 for ( more = direc.begin() ; more != direc.end() ; ++more ) {
83 directory = QDir(*more);
84 fileList = directory.entryList( QDir::Files );
85 for ( it = fileList.begin() ; it != fileList.end() ; ++it ){
86 itemName = KUrl(*more + *it).path();
87 parseEffectFile(audioEffectList, videoEffectList, itemName, filtersList, producersList);
88 // kDebug()<<"// FOUND EFFECT FILE: "<<itemName<<endl;
91 foreach(QString filtername,filtersList){
92 QDomDocument doc=createDescriptionFromMlt(repository,"filters",filtername);
94 videoEffectList->append(doc.documentElement());
100 void initEffects::parseEffectFile(EffectsList *audioEffectList, EffectsList *videoEffectList, QString name, QStringList filtersList, QStringList producersList)
104 doc.setContent(&file, false);
105 QDomElement documentElement = doc.documentElement();
106 QDomNodeList effects = doc.elementsByTagName("effect");
108 if (effects.count() == 0) {
109 kDebug()<<"// EFFECT FILET: "<<name<<" IS BROKEN"<<endl;
113 if (doc.elementsByTagName("effectgroup").item(0).toElement().tagName() == "effectgroup") {
114 groupName = documentElement.attribute("name", QString::null);
119 while (!effects.item(i).isNull()) {
120 documentElement = effects.item(i).toElement();
121 QString tag = documentElement.attribute("tag", QString::null);
122 bool ladspaOk = true;
123 if (tag == "ladspa") {
124 QString library = documentElement.attribute("library", QString::null);
125 if (KStandardDirs::locate("ladspa_plugin", library).isEmpty()) ladspaOk = false;
129 if ((filtersList.contains(tag) || producersList.contains(tag)) && ladspaOk) {
130 bool isAudioEffect = false;
131 QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
132 if (!propsnode.isNull()) {
133 QDomElement propselement = propsnode.toElement();
134 // id = propselement.attribute("id", QString::null);
135 // effectTag = propselement.attribute("tag", QString::null);
136 if (propselement.attribute("type", QString::null) == "audio") isAudioEffect = true;
137 //else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
138 //else type = VIDEOEFFECT;
140 if (isAudioEffect) audioEffectList->append(documentElement);
141 else videoEffectList->append(documentElement);
145 QDomNode n = documentElement.firstChild();
146 QString id, effectName, effectTag, paramType;
151 EffectParamDescFactory effectDescParamFactory;
152 EffectDesc *effect = NULL;
155 QDomNode namenode = documentElement.elementsByTagName("name").item(0);
156 if (!namenode.isNull()) effectName = i18n(namenode.toElement().text());
157 if (!groupName.isEmpty()) effectName.prepend("_" + groupName + "_");
159 QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
160 if (!propsnode.isNull()) {
161 QDomElement propselement = propsnode.toElement();
162 id = propselement.attribute("id", QString::null);
163 effectTag = propselement.attribute("tag", QString::null);
164 if (propselement.attribute("type", QString::null) == "audio") type = AUDIOEFFECT;
165 else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
166 else type = VIDEOEFFECT;
169 QString effectDescription;
170 QDomNode descnode = documentElement.elementsByTagName("description").item(0);
171 if (!descnode.isNull()) effectDescription = descnode.toElement().text() + "<br />";
173 QString effectAuthor;
174 QDomNode authnode = documentElement.elementsByTagName("author").item(0);
175 if (!authnode.isNull()) effectAuthor = authnode.toElement().text() + "<br />";
177 if (effectName.isEmpty() || id.isEmpty() || effectTag.isEmpty()) return;
179 effect = new EffectDesc(effectName, id, effectTag, effectDescription, effectAuthor, type);
181 QDomNodeList paramList = documentElement.elementsByTagName("parameter");
182 if (paramList.count() == 0) {
183 QDomElement fixed = doc.createElement("parameter");
184 fixed.setAttribute("type", "fixed");
185 effect->addParameter(effectDescParamFactory.createParameter(fixed));
187 else for (int i = 0; i < paramList.count(); i++) {
188 QDomElement e = paramList.item(i).toElement();
191 QDomNamedNodeMap attrs = e.attributes();
194 while (!attrs.item(i).isNull()) {
195 QDomNode n = attrs.item(i);
196 value = n.nodeValue();
197 if (value.find("MAX_WIDTH") != -1)
198 value.replace("MAX_WIDTH", QString::number(KdenliveSettings::defaultwidth()));
199 if (value.find("MID_WIDTH") != -1)
200 value.replace("MID_WIDTH", QString::number(KdenliveSettings::defaultwidth() / 2));
201 if (value.find("MAX_HEIGHT") != -1)
202 value.replace("MAX_HEIGHT", QString::number(KdenliveSettings::defaultheight()));
203 if (value.find("MID_HEIGHT") != -1)
204 value.replace("MID_HEIGHT", QString::number(KdenliveSettings::defaultheight() / 2));
205 n.setNodeValue(value);
208 effect->addParameter(effectDescParamFactory.createParameter(e));
211 effectList->append(effect);
218 char* initEffects::ladspaEffectString(int ladspaId, QStringList params)
220 if (ladspaId == 1433 ) //Pitch
221 return ladspaPitchEffectString(params);
222 else if (ladspaId == 1216 ) //Room Reverb
223 return ladspaRoomReverbEffectString(params);
224 else if (ladspaId == 1423 ) //Reverb
225 return ladspaReverbEffectString(params);
226 else if (ladspaId == 1901 ) //Reverb
227 return ladspaEqualizerEffectString(params);
229 kDebug()<<"++++++++++ ASKING FOR UNKNOWN LADSPA EFFECT: "<<ladspaId<<endl;
230 return("<jackrack></jackrack>");
235 void initEffects::ladspaEffectFile(const QString & fname, int ladspaId, QStringList params)
240 filterString = ladspaPitchEffectString(params);
243 filterString = ladspaVinylEffectString(params);
245 case 1216 : //Room Reverb
246 filterString = ladspaRoomReverbEffectString(params);
249 filterString = ladspaReverbEffectString(params);
251 case 1195: //Declipper
252 filterString = ladspaDeclipEffectString(params);
255 filterString = ladspaEqualizerEffectString(params);
257 case 1913: // Limiter
258 filterString = ladspaLimiterEffectString(params);
260 case 1193: // Pitch Shifter
261 filterString = ladspaPitchShifterEffectString(params);
263 case 1417: // Rate Scaler
264 filterString = ladspaRateScalerEffectString(params);
267 filterString = ladspaPhaserEffectString(params);
270 kDebug()<<"++++++++++ ASKING FOR UNKNOWN LADSPA EFFECT: "<<ladspaId<<endl;
276 if ( f.open( QIODevice::WriteOnly ) )
278 QTextStream stream( &f );
279 stream << filterString;
282 else kDebug()<<"++++++++++ ERROR CANNOT WRITE TO: "<<KdenliveSettings::currenttmpfolder() + fname<<endl;
286 QString jackString = "<?xml version=\"1.0\"?><!DOCTYPE jackrack SYSTEM \"http://purge.bash.sh/~rah/jack_rack_1.2.dtd\"><jackrack><channels>2</channels><samplerate>48000</samplerate><plugin><id>";
289 char* initEffects::ladspaDeclipEffectString(QStringList)
291 return qstrdup(QString(jackString + "1195</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall></plugin></jackrack>").toUtf8());
295 char* initEffects::ladspaVocoderEffectString(QStringList params)
297 return qstrdup( QString(jackString + "1441</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>0.000000</value><value>0.000000</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]));
300 char* initEffects::ladspaVinylEffectString(QStringList params)
302 return qstrdup( QString(jackString + "1905</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow><controlrow><value>%3</value></controlrow><controlrow><value>%4</value></controlrow><controlrow><value>%5</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]).arg(params[4]).toUtf8());
305 char* initEffects::ladspaPitchEffectString(QStringList params)
307 return qstrdup( QString(jackString + "1433</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.0</value><value>1.0</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>4.000000</value><value>4.000000</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
310 char* initEffects::ladspaRoomReverbEffectString(QStringList params)
312 return qstrdup( QString(jackString + "1216</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>0.750000</value><value>0.750000</value></controlrow><controlrow><lock>true</lock><value>-70.000000</value><value>-70.000000</value></controlrow><controlrow><lock>true</lock><value>0.000000</value><value>0.000000</value></controlrow><controlrow><lock>true</lock><value>-17.500000</value><value>-17.500000</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
315 char* initEffects::ladspaReverbEffectString(QStringList params)
317 return qstrdup( QString(jackString + "1423</id><enabled>true</enabled> <wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked> <wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values> <lockall>true</lockall><controlrow><lock>true</lock><value>%1</value> <value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>0.250000</value><value>0.250000</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).toUtf8());
320 char* initEffects::ladspaEqualizerEffectString(QStringList params)
322 return qstrdup( QString(jackString + "1901</id><enabled>true</enabled> <wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked> <wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow> <controlrow><value>%3</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
325 char* initEffects::ladspaLimiterEffectString(QStringList params)
327 return qstrdup( QString(jackString + "1913</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><controlrow><value>%1</value></controlrow><controlrow><value>%2</value></controlrow><controlrow><value>%3</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).toUtf8());
330 char* initEffects::ladspaPitchShifterEffectString(QStringList params)
332 return qstrdup( QString(jackString + "1193</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
335 char* initEffects::ladspaRateScalerEffectString(QStringList params)
337 return qstrdup( QString(jackString + "1417</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow></plugin></jackrack>").arg(params[0]).toUtf8());
340 char* initEffects::ladspaPhaserEffectString(QStringList params)
342 return qstrdup( QString(jackString + "1217</id><enabled>true</enabled><wet_dry_enabled>false</wet_dry_enabled><wet_dry_locked>true</wet_dry_locked><wet_dry_values><value>1.000000</value><value>1.000000</value></wet_dry_values><lockall>true</lockall><controlrow><lock>true</lock><value>%1</value><value>%1</value></controlrow><controlrow><lock>true</lock><value>%2</value><value>%2</value></controlrow><controlrow><lock>true</lock><value>%3</value><value>%3</value></controlrow><controlrow><lock>true</lock><value>%4</value><value>%4</value></controlrow></plugin></jackrack>").arg(params[0]).arg(params[1]).arg(params[2]).arg(params[3]).toUtf8());
346 QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository* repository, const QString& type, const QString& filtername){
349 Mlt::Properties *metadata=repository->metadata(filter_type,filtername.toAscii().data());
350 kDebug() << filtername;
351 if (metadata && metadata->is_valid()){
352 if (metadata->get("title") && metadata->get("identifier")){
353 QDomElement eff=ret.createElement("effect");
354 eff.setAttribute("tag",metadata->get("identifier"));
356 QDomElement name=ret.createElement("name");
357 name.appendChild(ret.createTextNode(metadata->get("title")));
359 QDomElement desc=ret.createElement("description");
360 desc.appendChild(ret.createTextNode(metadata->get("description")));
362 QDomElement author=ret.createElement("author");
363 author.appendChild(ret.createTextNode(metadata->get("creator")));
365 QDomElement prop=ret.createElement("properties");
366 prop.setAttribute("id",metadata->get("identifier"));
367 prop.setAttribute("tag",metadata->get("identifier"));
368 eff.appendChild(name);
369 eff.appendChild(author);
370 eff.appendChild(desc);
371 eff.appendChild(prop);
373 Mlt::Properties param_props( (mlt_properties) metadata->get_data("parameters") );
374 for (int j=0; param_props.is_valid() && j<param_props.count();j++){
375 QDomElement params=ret.createElement("parameter");
377 Mlt::Properties paramdesc ( (mlt_properties) param_props.get_data(param_props.get_name(j)));
379 params.setAttribute("name", paramdesc.get("identifier") );
381 if (paramdesc.get("maximum") ) params.setAttribute("max",paramdesc.get("maximum"));
382 if (paramdesc.get("minimum") ) params.setAttribute("min",paramdesc.get("minimum"));
383 if (QString(paramdesc.get("type"))=="integer" )
384 params.setAttribute("type","constant");
385 if (QString(paramdesc.get("type"))=="boolean" )
386 params.setAttribute("type","bool");
387 if (!QString(paramdesc.get("format")).isEmpty()){
388 params.setAttribute("type","complex");
389 params.setAttribute("format",paramdesc.get("format"));
391 if (paramdesc.get("default") ) params.setAttribute("default",paramdesc.get("default"));
392 if (paramdesc.get("value") ){
393 params.setAttribute("value",paramdesc.get("value"));
395 params.setAttribute("value",paramdesc.get("default"));
399 QDomElement pname=ret.createElement("name");
400 pname.appendChild(ret.createTextNode(paramdesc.get("title")));
401 params.appendChild(pname);
403 eff.appendChild(params);
405 ret.appendChild(eff);
409 QTextStream str(&outstr);