<name>Sox Gain</name>
<description>Sox gain audio effect</description>
<author>http://sox.sourceforge.net</author>
- <parameter type="constant" name="gain" max="50" min="-50" default="5">
+ <parameter type="double" name="gain" max="50" min="-50" default="5.00" decimals="2">
<name>Gain</name>
</parameter>
+ <parameter type="filterjob" filtertag="sox:analysis" filterparams="" consumer="null" consumerparams="video_off=1 all=1" wantedproperties="gain" finalfilter="sox_gain">
+ <name>Normalize</name>
+ </parameter>
</effect>
return;
}
QDomElement effect = insertedEffect.cloneNode().toElement();
- //kDebug() << "// update effect ix: " << effect.attribute("kdenlive_ix")<<", TRACK: "<<track;
+ //kDebug() << "// update effect ix: " << effect.attribute("kdenlive_ix")<<", GAIN: "<<EffectsList::parameter(effect, "gain");
if (pos < GenTime()) {
// editing a track effect
EffectsParameterList effectParams = getEffectArgs(effect);
emit clipItemSelected(clip, ix);
}
}
+ else emit displayMessage(i18n("Cannot find clip to update effect"), ErrorMessage);
setDocumentModified();
}
}
+void CustomTrackView::slotGotFilterJobResults(const QString &id, int startPos, int track, const QString &filter, stringMap filterParams)
+{
+ ClipItem *clip = getClipItemAt(GenTime(startPos, m_document->fps()), track);
+ if (clip == NULL) {
+ emit displayMessage(i18n("Cannot find clip for effect update %1.", filter), ErrorMessage);
+ return;
+ }
+ QDomElement newEffect;
+ QDomElement effect = clip->getEffectAt(clip->selectedEffectIndex());
+ if (effect.attribute("id") == filter) {
+ newEffect = effect.cloneNode().toElement();
+ QMap<QString, QString>::const_iterator i = filterParams.constBegin();
+ while (i != filterParams.constEnd()) {
+ EffectsList::setParameter(newEffect, i.key(), i.value());
+ kDebug()<<"// RESULT FILTER: "<<i.key()<<"="<< i.value();
+ ++i;
+ }
+ EditEffectCommand *command = new EditEffectCommand(this, m_document->tracksCount() - clip->track(), clip->startPos(), effect, newEffect, clip->selectedEffectIndex(), true);
+ m_commandStack->push(command);
+ emit clipItemSelected(clip, clip->selectedEffectIndex());
+ }
+
+}
+
+
* @param id The clip's Id string.
* @param resetThumbs Should we recreate the timeline thumbnails. */
void slotRefreshThumbs(const QString &id, bool resetThumbs);
+ /** @brief A Filter job producer results. */
+ void slotGotFilterJobResults(const QString &id, int startPos, int track, const QString &filter, stringMap filterParams);
signals:
void cursorMoved(int, int);
QDomElement pa = namenode.item(i).toElement();
QString type = pa.attribute("type");
if (type == "filterjob") {
- emit startFilterJob(pa.attribute("filtertag"), pa.attribute("filterparams"), pa.attribute("consumer"), pa.attribute("consumerparams"), pa.attribute("wantedproperties"));
+ emit startFilterJob(pa.attribute("filtertag"), pa.attribute("filterparams"), pa.attribute("finalfilter"), pa.attribute("consumer"), pa.attribute("consumerparams"), pa.attribute("wantedproperties"));
kDebug()<<" - - -PROPS:\n"<<pa.attribute("filtertag")<<"-"<< pa.attribute("filterparams")<<"-"<< pa.attribute("consumer")<<"-"<< pa.attribute("consumerparams")<<"-"<< pa.attribute("wantedproperties");
break;
}
void showComments(bool show);
void effectStateChanged(bool enabled);
/** @brief Start an MLT filter job on this clip. */
- void startFilterJob(const QString &filterName, const QString &filterParams, const QString &consumer, const QString &consumerParams, const QString &properties);
+ void startFilterJob(const QString &filterName, const QString &filterParams, const QString &finalFilterName, const QString &consumer, const QString &consumerParams, const QString &properties);
};
#endif
connect(m_ui.checkAll, SIGNAL(stateChanged(int)), this, SLOT(slotCheckAll(int)));
connect(m_ui.buttonShowComments, SIGNAL(clicked()), this, SLOT(slotShowComments()));
connect(m_effectedit, SIGNAL(parameterChanged(const QDomElement &, const QDomElement &)), this , SLOT(slotUpdateEffectParams(const QDomElement &, const QDomElement &)));
- connect(m_effectedit, SIGNAL(startFilterJob(QString,QString,QString,QString,QString)), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,QString)));
+ connect(m_effectedit, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QString)), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,QString,QString)));
connect(m_effectedit, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int)));
connect(m_effectedit, SIGNAL(displayMessage(const QString&, int)), this, SIGNAL(displayMessage(const QString&, int)));
connect(m_effectedit, SIGNAL(checkMonitorPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
+
connect(monitor, SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int)));
connect(this, SIGNAL(showComments(bool)), m_effectedit, SIGNAL(showComments(bool)));
m_effectLists["audio"] = &MainWindow::audioEffects;
emit showComments(m_ui.buttonShowComments->isChecked());
}
-void EffectStackView::slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QString&properties)
+void EffectStackView::slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QString&properties)
{
if (!m_clipref) return;
- emit startFilterJob(m_clipref->clipProducer(), filterName, filterParams, consumer, consumerParams, properties);
+ emit startFilterJob(m_clipref->info(), m_clipref->clipProducer(), filterName, filterParams, finalFilterName, consumer, consumerParams, properties);
}
#include "effectstackview.moc"
void slotShowComments();
/** @brief Triggers a filter job on this clip. */
- void slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QString&properties);
+ void slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QString&properties);
signals:
void removeEffect(ClipItem*, int, QDomElement);
void updateClipRegion(ClipItem*, int, QString);
void displayMessage(const QString&, int);
void showComments(bool show);
- void startFilterJob(const QString &clipId, const QString &filterName, const QString &filterParams, const QString &consumer, const QString &consumerParams, const QString &properties);
+ void startFilterJob(ItemInfo info, const QString &clipId, const QString &filterName, const QString &filterParams, const QString&finalFilterName, const QString &consumer, const QString &consumerParams, const QString &properties);
};
#endif
m_effectStack = new EffectStackView(m_projectMonitor);
m_effectStackDock->setWidget(m_effectStack);
addDockWidget(Qt::TopDockWidgetArea, m_effectStackDock);
- connect(m_effectStack, SIGNAL(startFilterJob(const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)), m_projectList, SLOT(slotStartFilterJob(const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)));
+ connect(m_effectStack, SIGNAL(startFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)), m_projectList, SLOT(slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)));
m_transitionConfigDock = new QDockWidget(i18n("Transition"), this);
m_transitionConfigDock->setObjectName("transition");
disconnect(m_activeTimeline->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay()));
disconnect(m_activeTimeline->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType)));
disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int)));
+ disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap)));
+
disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
disconnect(m_activeTimeline, SIGNAL(insertTrack(int)), this, SLOT(slotInsertTrack(int)));
disconnect(m_activeTimeline, SIGNAL(deleteTrack(int)), this, SLOT(slotDeleteTrack(int)));
connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*)));
connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*)));
+
+ connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap)));
connect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int)));
connect(m_effectStack, SIGNAL(updateClipRegion(ClipItem*, int, QString)), trackView->projectView(), SLOT(slotUpdateClipRegion(ClipItem*, int, QString)));
}
connect(job, SIGNAL(jobProgress(QString, int, int)), this, SIGNAL(processLog(QString, int, int)));
connect(job, SIGNAL(cancelRunningJob(const QString, stringMap)), this, SIGNAL(cancelRunningJob(const QString, stringMap)));
+ connect(job, SIGNAL(gotFilterJobResults(QString,int, int, QString,stringMap)), this, SIGNAL(gotFilterJobResults(QString,int, int, QString,stringMap)));
if (job->jobType == MLTJOB) {
MeltJob *jb = static_cast<MeltJob *> (job);
}
}
-void ProjectList::slotStartFilterJob(const QString&id, const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QString&properties)
+void ProjectList::slotStartFilterJob(ItemInfo info, const QString&id, const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QString&properties)
{
ProjectItem *item = getItemById(id);
if (!item) return;
QStringList jobParams;
- jobParams << filterName << filterParams << consumer << consumerParams << properties;
- kDebug()<<"// STARTING JOB: "<<jobParams;
+ jobParams << QString::number(info.cropStart.frames(m_fps)) << QString::number((info.cropStart + info.cropDuration).frames(m_fps));
+ jobParams << filterName << filterParams << consumer << consumerParams << properties << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track) << finalFilterName;
MeltJob *job = new MeltJob(item->clipType(), id, jobParams);
if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
delete job;
void slotCutClipJob(const QString &id, QPoint zone);
void slotTranscodeClipJob(QStringList ids, QString params, QString desc);
/** @brief Start an MLT process job. */
- void slotStartFilterJob(const QString&,const QString&,const QString&,const QString&,const QString&,const QString&);
+ void slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QString&);
private:
ProjectListView *m_listView;
void updateJobStatus(const QString, int, int, const QString &label = QString(), const QString &actionName = QString(), const QString details = QString());
void gotProxy(const QString);
void checkJobProcess();
+ /** @brief A Filter Job produced results, send them back to the clip. */
+ void gotFilterJobResults(const QString &id, int startPos, int track, const QString &filterName, stringMap params);
};
#endif
signals:
void jobProgress(QString, int, int);
void cancelRunningJob(const QString, stringMap);
+ void gotFilterJobResults(const QString &id, int startPos, int track, const QString &filterName, stringMap params);
};
setStatus(JOBCRASHED);
return;
}
+ int in = m_params.takeFirst().toInt();
+ int out = m_params.takeFirst().toInt();
QString filter = m_params.takeFirst();
QString filterParams = m_params.takeFirst();
QString consumer = m_params.takeFirst();
QString consumerParams = m_params.takeFirst();
QString properties = m_params.takeFirst();
+ int startPos = m_params.takeFirst().toInt();
+ int track = m_params.takeFirst().toInt();
+ QString finalFilter;
+ if (!m_params.isEmpty()) finalFilter = m_params.takeFirst();
+ else finalFilter = filter;
+
+ if (out <= in) {
+ m_errorMessage.append(i18n("Clip zone undefined (%1 - %2).", in, out));
+ setStatus(JOBCRASHED);
+ return;
+ }
+ Mlt::Producer *prod = m_producer->cut(in, out);
m_profile = m_producer->profile();
m_consumer = new Mlt::Consumer(*m_profile, consumer.toUtf8().constData());
if (!m_consumer || !m_consumer->is_valid()) {
mltFilter.set(data.section('=', 0, 0).toUtf8().constData(), data.section('=', 1, 1).toUtf8().constData());
}
}
- m_producer->attach(mltFilter);
- m_length = m_producer->get_length();
- m_consumer->connect(*m_producer);
- m_producer->set_speed(0);
- m_producer->seek(0);
+ prod->attach(mltFilter);
+ m_length = prod->get_length();
+ m_consumer->connect(*prod);
+ prod->set_speed(0);
+ prod->seek(0);
m_showFrameEvent = m_consumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_render);
m_consumer->start();
- m_producer->set_speed(1);
+ prod->set_speed(1);
while (jobStatus != JOBABORTED && !m_consumer->is_stopped()) {
}
m_consumer->stop();
QStringList wanted = properties.split(',', QString::SkipEmptyParts);
+ stringMap jobResults;
foreach(const QString key, wanted) {
QString value = mltFilter.get(key.toUtf8().constData());
+ jobResults.insert(key, value);
kDebug()<<"RESULT: "<<key<<" = "<< value;
}
+ if (!jobResults.isEmpty()) emit gotFilterJobResults(m_clipId, startPos, track, finalFilter, jobResults);
setStatus(JOBDONE);
delete m_consumer;
+ delete prod;
return;
}