1 /***************************************************************************
2 * Copyright (C) 2012 by Simon Andreas Eugster (simon.eu@gmail.com) *
3 * This file is part of kdenlive. See www.kdenlive.org. *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
19 #include <QStringList>
20 #include <QCoreApplication>
21 #include <mlt++/Mlt.h>
26 #include "audioInfo.h"
27 #include "audioStreamInfo.h"
28 #include "audioEnvelope.h"
29 #include "audioCorrelation.h"
31 void printUsage(const char *path)
33 std::cout << "Usage: " << path << " <main audio file> <second audio file>" << std::endl
34 << "\t-h, --help\tDisplay this help" << std::endl
35 << "\t--profile=<profile>\tUse the given profile for calculation (run: melt -query profiles)" << std::endl
36 << "\t--no-images\tDo not save envelope and correlation images" << std::endl
40 int main(int argc, char *argv[])
42 QCoreApplication app(argc, argv);
43 QStringList args = app.arguments();
46 std::string profile = "atsc_1080p_24";
47 bool saveImages = true;
50 foreach (QString str, args) {
52 if (str.startsWith("--profile=")) {
54 s.remove(0, QString("--profile=").length());
55 profile = s.toStdString();
58 } else if (str == "-h" || str == "--help") {
62 } else if (str == "--no-images") {
69 if (args.length() < 2) {
76 std::string fileMain(args.at(0).toStdString());
78 std::string fileSub = args.at(0).toStdString();
82 qDebug() << "Unused arguments: " << args;
89 std::cout << "Usage: " << argv[0] << " <main audio file> <second audio file>" << std::endl;
92 std::cout << "Trying to align (2)\n\t" << fileSub << "\nto fit on (1)\n\t" << fileMain
93 << "\n, result will indicate by how much (2) has to be moved." << std::endl
94 << "Profile used: " << profile << std::endl
99 Mlt::Factory::init(NULL);
101 // Load an arbitrary profile
102 Mlt::Profile prof(profile.c_str());
104 // Load the MLT producers
105 Mlt::Producer prodMain(prof, fileMain.c_str());
106 if (!prodMain.is_valid()) {
107 std::cout << fileMain << " is invalid." << std::endl;
110 Mlt::Producer prodSub(prof, fileSub.c_str());
111 if (!prodSub.is_valid()) {
112 std::cout << fileSub << " is invalid." << std::endl;
117 // Build the audio envelopes for the correlation
118 AudioEnvelope envelopeMain(&prodMain);
119 envelopeMain.loadEnvelope();
120 envelopeMain.loadStdDev();
121 envelopeMain.dumpInfo();
123 AudioEnvelope envelopeSub(&prodSub);
124 envelopeSub.loadEnvelope();
125 envelopeSub.loadStdDev();
126 envelopeSub.dumpInfo();
133 // Calculate the correlation and hereby the audio shift
134 AudioCorrelation corr(&envelopeMain);
135 int index = corr.addChild(&envelopeSub);
137 int shift = corr.getShift(index);
138 std::cout << fileSub << " should be shifted by " << shift << " frames" << std::endl
139 << "\trelative to " << fileMain << std::endl
140 << "\tin a " << prodMain.get_fps() << " fps profile (" << profile << ")." << std::endl
146 outImg = QString("envelope-main-%1.png")
147 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
148 envelopeMain.drawEnvelope().save(outImg);
149 std::cout << "Saved volume envelope as "
150 << QFileInfo(outImg).absoluteFilePath().toStdString()
152 outImg = QString("envelope-sub-%1.png")
153 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
154 envelopeSub.drawEnvelope().save(outImg);
155 std::cout << "Saved volume envelope as "
156 << QFileInfo(outImg).absoluteFilePath().toStdString()
158 outImg = QString("correlation-%1.png")
159 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
160 corr.info(index)->toImage().save(outImg);
161 std::cout << "Saved correlation image as "
162 << QFileInfo(outImg).absoluteFilePath().toStdString()