]> git.sesse.net Git - kdenlive/blob - src/initeffects.cpp
Reindent all source files
[kdenlive] / src / initeffects.cpp
1 /***************************************************************************
2                           initeffects.cpp  -  description
3                              -------------------
4     begin                :  Jul 2006
5     copyright            : (C) 2006 by Jean-Baptiste Mardelle
6     email                : jb@ader.ch
7     copyright            : (C) 2008 Marco Gittler
8     email                : g.marco@freenet.de
9  ***************************************************************************/
10
11 /***************************************************************************
12  *                                                                         *
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.                                   *
17  *                                                                         *
18  ***************************************************************************/
19
20
21 #include <QFile>
22 #include <qregexp.h>
23 #include <QDir>
24
25 #include <KDebug>
26 #include <kglobal.h>
27 #include <KStandardDirs>
28
29 #include "initeffects.h"
30
31 initEffects::initEffects() {
32 }
33
34 initEffects::~initEffects() {
35 }
36
37 //static
38 Mlt::Repository *initEffects::parseEffectFiles(EffectsList *audioEffectList, EffectsList *videoEffectList) {
39     QStringList::Iterator more;
40     QStringList::Iterator it;
41     QStringList fileList;
42     QString itemName;
43
44
45     // Build effects. Retrieve the list of MLT's available effects first.
46     Mlt::Repository *repository = Mlt::Factory::init();
47     if (!repository) {
48         kDebug() << "Repository did not finish init " ;
49         return NULL;
50     }
51     Mlt::Properties *filters = repository->filters();
52     QStringList filtersList;
53
54     for (int i = 0 ; i < filters->count() ; i++) {
55         filtersList << filters->get_name(i);
56     }
57
58     // Build effects. check producers first.
59
60     Mlt::Properties *producers = repository->producers();
61     QStringList producersList;
62     for (int i = 0 ; i < producers->count() ; i++) {
63         producersList << producers->get_name(i);
64     }
65     delete filters;
66     delete producers;
67
68     KGlobal::dirs()->addResourceType("ladspa_plugin", "lib/ladspa");
69     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/lib/ladspa");
70     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/usr/local/lib/ladspa");
71     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/lib/ladspa");
72     KGlobal::dirs()->addResourceDir("ladspa_plugin", "/opt/local/lib/ladspa");
73
74     kDebug() << "//  INIT EFFECT SEARCH" << endl;
75
76     QStringList direc = KGlobal::dirs()->findDirs("data", "kdenlive/effects");
77
78     QDir directory;
79     for (more = direc.begin() ; more != direc.end() ; ++more) {
80         directory = QDir(*more);
81         fileList = directory.entryList(QDir::Files);
82         for (it = fileList.begin() ; it != fileList.end() ; ++it) {
83             itemName = KUrl(*more + *it).path();
84             parseEffectFile(audioEffectList, videoEffectList, itemName, filtersList, producersList);
85             // kDebug()<<"//  FOUND EFFECT FILE: "<<itemName<<endl;
86         }
87     }
88     foreach(QString filtername, filtersList) {
89         QDomDocument doc = createDescriptionFromMlt(repository, "filters", filtername);
90         if (!doc.isNull())
91             videoEffectList->append(doc.documentElement());
92     }
93     return repository;
94 }
95
96 // static
97 void initEffects::parseEffectFile(EffectsList *audioEffectList, EffectsList *videoEffectList, QString name, QStringList filtersList, QStringList producersList) {
98     QDomDocument doc;
99     QFile file(name);
100     doc.setContent(&file, false);
101     QDomElement documentElement = doc.documentElement();
102     QDomNodeList effects = doc.elementsByTagName("effect");
103
104     if (effects.count() == 0) {
105         kDebug() << "// EFFECT FILET: " << name << " IS BROKEN" << endl;
106         return;
107     }
108     QString groupName;
109     if (doc.elementsByTagName("effectgroup").item(0).toElement().tagName() == "effectgroup") {
110         groupName = documentElement.attribute("name", QString::null);
111     }
112
113     int i = 0;
114
115     while (!effects.item(i).isNull()) {
116         documentElement = effects.item(i).toElement();
117         QString tag = documentElement.attribute("tag", QString::null);
118         bool ladspaOk = true;
119         if (tag == "ladspa") {
120             QString library = documentElement.attribute("library", QString::null);
121             if (KStandardDirs::locate("ladspa_plugin", library).isEmpty()) ladspaOk = false;
122         }
123
124         // Parse effect file
125         if ((filtersList.contains(tag) || producersList.contains(tag)) && ladspaOk) {
126             bool isAudioEffect = false;
127             QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
128             if (!propsnode.isNull()) {
129                 QDomElement propselement = propsnode.toElement();
130 //     id = propselement.attribute("id", QString::null);
131 //     effectTag = propselement.attribute("tag", QString::null);
132                 if (propselement.attribute("type", QString::null) == "audio") isAudioEffect = true;
133                 //else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
134                 //else type = VIDEOEFFECT;
135             }
136             if (isAudioEffect) audioEffectList->append(documentElement);
137             else videoEffectList->append(documentElement);
138         }
139
140         /*
141              QDomNode n = documentElement.firstChild();
142          QString id, effectName, effectTag, paramType;
143          int paramCount = 0;
144          EFFECTTYPE type;
145
146                 // Create Effect
147                 EffectParamDescFactory effectDescParamFactory;
148                 EffectDesc *effect = NULL;
149
150          // parse effect file
151          QDomNode namenode = documentElement.elementsByTagName("name").item(0);
152          if (!namenode.isNull()) effectName = i18n(namenode.toElement().text());
153          if (!groupName.isEmpty()) effectName.prepend("_" + groupName + "_");
154
155          QDomNode propsnode = documentElement.elementsByTagName("properties").item(0);
156          if (!propsnode.isNull()) {
157              QDomElement propselement = propsnode.toElement();
158              id = propselement.attribute("id", QString::null);
159              effectTag = propselement.attribute("tag", QString::null);
160              if (propselement.attribute("type", QString::null) == "audio") type = AUDIOEFFECT;
161              else if (propselement.attribute("type", QString::null) == "custom") type = CUSTOMEFFECT;
162              else type = VIDEOEFFECT;
163          }
164
165          QString effectDescription;
166          QDomNode descnode = documentElement.elementsByTagName("description").item(0);
167          if (!descnode.isNull()) effectDescription = descnode.toElement().text() + "<br />";
168
169          QString effectAuthor;
170          QDomNode authnode = documentElement.elementsByTagName("author").item(0);
171          if (!authnode.isNull()) effectAuthor = authnode.toElement().text() + "<br />";
172
173          if (effectName.isEmpty() || id.isEmpty() || effectTag.isEmpty()) return;
174
175          effect = new EffectDesc(effectName, id, effectTag, effectDescription, effectAuthor, type);
176
177          QDomNodeList paramList = documentElement.elementsByTagName("parameter");
178          if (paramList.count() == 0) {
179              QDomElement fixed = doc.createElement("parameter");
180              fixed.setAttribute("type", "fixed");
181              effect->addParameter(effectDescParamFactory.createParameter(fixed));
182          }
183          else for (int i = 0; i < paramList.count(); i++) {
184              QDomElement e = paramList.item(i).toElement();
185              if (!e.isNull()) {
186           paramCount++;
187            QDomNamedNodeMap attrs = e.attributes();
188           int i = 0;
189           QString value;
190           while (!attrs.item(i).isNull()) {
191               QDomNode n = attrs.item(i);
192               value = n.nodeValue();
193               if (value.find("MAX_WIDTH") != -1)
194            value.replace("MAX_WIDTH", QString::number(KdenliveSettings::defaultwidth()));
195               if (value.find("MID_WIDTH") != -1)
196            value.replace("MID_WIDTH", QString::number(KdenliveSettings::defaultwidth() / 2));
197               if (value.find("MAX_HEIGHT") != -1)
198            value.replace("MAX_HEIGHT", QString::number(KdenliveSettings::defaultheight()));
199               if (value.find("MID_HEIGHT") != -1)
200            value.replace("MID_HEIGHT", QString::number(KdenliveSettings::defaultheight() / 2));
201               n.setNodeValue(value);
202               i++;
203           }
204           effect->addParameter(effectDescParamFactory.createParameter(e));
205              }
206          }
207                 effectList->append(effect);
208          }*/
209         i++;
210     }
211 }
212
213 //static
214 char* initEffects::ladspaEffectString(int ladspaId, QStringList params) {
215     if (ladspaId == 1433)  //Pitch
216         return ladspaPitchEffectString(params);
217     else if (ladspaId == 1216)  //Room Reverb
218         return ladspaRoomReverbEffectString(params);
219     else if (ladspaId == 1423)  //Reverb
220         return ladspaReverbEffectString(params);
221     else if (ladspaId == 1901)  //Reverb
222         return ladspaEqualizerEffectString(params);
223     else {
224         kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
225         return("<jackrack></jackrack>");
226     }
227 }
228
229 //static
230 void initEffects::ladspaEffectFile(const QString & fname, int ladspaId, QStringList params) {
231     char *filterString;
232     switch (ladspaId) {
233     case 1433: //Pitch
234         filterString = ladspaPitchEffectString(params);
235         break;
236     case 1905: //Vinyl
237         filterString = ladspaVinylEffectString(params);
238         break;
239     case 1216 : //Room Reverb
240         filterString = ladspaRoomReverbEffectString(params);
241         break;
242     case 1423: //Reverb
243         filterString = ladspaReverbEffectString(params);
244         break;
245     case 1195: //Declipper
246         filterString = ladspaDeclipEffectString(params);
247         break;
248     case 1901:  //Reverb
249         filterString = ladspaEqualizerEffectString(params);
250         break;
251     case 1913: // Limiter
252         filterString = ladspaLimiterEffectString(params);
253         break;
254     case 1193: // Pitch Shifter
255         filterString = ladspaPitchShifterEffectString(params);
256         break;
257     case 1417: // Rate Scaler
258         filterString = ladspaRateScalerEffectString(params);
259         break;
260     case 1217: // Phaser
261         filterString = ladspaPhaserEffectString(params);
262         break;
263     default:
264         kDebug() << "++++++++++  ASKING FOR UNKNOWN LADSPA EFFECT: " << ladspaId << endl;
265         return;
266         break;
267     }
268
269     QFile f(fname);
270     if (f.open(QIODevice::WriteOnly)) {
271         QTextStream stream(&f);
272         stream << filterString;
273         f.close();
274     } else kDebug() << "++++++++++  ERROR CANNOT WRITE TO: " << KdenliveSettings::currenttmpfolder() +  fname << endl;
275     delete filterString;
276 }
277
278 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>";
279
280
281 char* initEffects::ladspaDeclipEffectString(QStringList) {
282     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());
283 }
284
285 /*
286 char* initEffects::ladspaVocoderEffectString(QStringList params)
287 {
288  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]));
289 }*/
290
291 char* initEffects::ladspaVinylEffectString(QStringList params) {
292     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());
293 }
294
295 char* initEffects::ladspaPitchEffectString(QStringList params) {
296     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());
297 }
298
299 char* initEffects::ladspaRoomReverbEffectString(QStringList params) {
300     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());
301 }
302
303 char* initEffects::ladspaReverbEffectString(QStringList params) {
304     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());
305 }
306
307 char* initEffects::ladspaEqualizerEffectString(QStringList params) {
308     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());
309 }
310
311 char* initEffects::ladspaLimiterEffectString(QStringList params) {
312     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());
313 }
314
315 char* initEffects::ladspaPitchShifterEffectString(QStringList params) {
316     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());
317 }
318
319 char* initEffects::ladspaRateScalerEffectString(QStringList params) {
320     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());
321 }
322
323 char* initEffects::ladspaPhaserEffectString(QStringList params) {
324     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());
325 }
326
327
328 QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository* repository, const QString& type, const QString& filtername) {
329
330     QDomDocument ret;
331     Mlt::Properties *metadata = repository->metadata(filter_type, filtername.toAscii().data());
332     kDebug() << filtername;
333     if (metadata && metadata->is_valid()) {
334         if (metadata->get("title") && metadata->get("identifier")) {
335             QDomElement eff = ret.createElement("effect");
336             eff.setAttribute("tag", metadata->get("identifier"));
337
338             QDomElement name = ret.createElement("name");
339             name.appendChild(ret.createTextNode(metadata->get("title")));
340
341             QDomElement desc = ret.createElement("description");
342             desc.appendChild(ret.createTextNode(metadata->get("description")));
343
344             QDomElement author = ret.createElement("author");
345             author.appendChild(ret.createTextNode(metadata->get("creator")));
346
347             QDomElement prop = ret.createElement("properties");
348             prop.setAttribute("id", metadata->get("identifier"));
349             prop.setAttribute("tag", metadata->get("identifier"));
350             eff.appendChild(name);
351             eff.appendChild(author);
352             eff.appendChild(desc);
353             eff.appendChild(prop);
354
355             Mlt::Properties param_props((mlt_properties) metadata->get_data("parameters"));
356             for (int j = 0; param_props.is_valid() && j < param_props.count();j++) {
357                 QDomElement params = ret.createElement("parameter");
358
359                 Mlt::Properties paramdesc((mlt_properties) param_props.get_data(param_props.get_name(j)));
360
361                 params.setAttribute("name", paramdesc.get("identifier"));
362
363                 if (paramdesc.get("maximum")) params.setAttribute("max", paramdesc.get("maximum"));
364                 if (paramdesc.get("minimum")) params.setAttribute("min", paramdesc.get("minimum"));
365                 if (QString(paramdesc.get("type")) == "integer")
366                     params.setAttribute("type", "constant");
367                 if (QString(paramdesc.get("type")) == "boolean")
368                     params.setAttribute("type", "bool");
369                 if (!QString(paramdesc.get("format")).isEmpty()) {
370                     params.setAttribute("type", "complex");
371                     params.setAttribute("format", paramdesc.get("format"));
372                 }
373                 if (paramdesc.get("default")) params.setAttribute("default", paramdesc.get("default"));
374                 if (paramdesc.get("value")) {
375                     params.setAttribute("value", paramdesc.get("value"));
376                 } else {
377                     params.setAttribute("value", paramdesc.get("default"));
378                 }
379
380
381                 QDomElement pname = ret.createElement("name");
382                 pname.appendChild(ret.createTextNode(paramdesc.get("title")));
383                 params.appendChild(pname);
384
385                 eff.appendChild(params);
386             }
387             ret.appendChild(eff);
388         }
389     }
390     QString outstr;
391     QTextStream str(&outstr);
392     ret.save(str, 2);
393     kDebug() << outstr;
394     return ret;
395 }
396