2 Copyright (C) 2012 Simon A. Eugster (Granjow) <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 3 of the License, or
8 (at your option) any later version.
18 #include <QStringList>
19 #include <QCoreApplication>
20 #include <mlt++/Mlt.h>
25 #include "../src/lib/audio/audioInfo.h"
26 #include "../src/lib/audio/audioStreamInfo.h"
27 #include "../src/lib/audio/audioEnvelope.h"
28 #include "../src/lib/audio/audioCorrelation.h"
30 void printUsage(const char *path)
32 std::cout << "This executable takes two audio/video files A and B and determines " << std::endl
33 << "how much B needs to be shifted in order to be synchronized with A." << std::endl << std::endl
34 << path << " <main audio file> <second audio file>" << std::endl
35 << "\t-h, --help\n\t\tDisplay this help" << std::endl
36 << "\t--fft\n\t\tUse Fourier Transform (FFT) to calculate the offset. This only takes" << std::endl
37 << "\t\tO(n log n) time compared to O(n²) when using normal correlation and should be " << std::endl
38 << "\t\tfaster for large data (several minutes)." << std::endl
39 << "\t--profile=<profile>\n\t\tUse the given profile for calculation (run: melt -query profiles)" << std::endl
40 << "\t--no-images\n\t\tDo not save envelope and correlation images" << std::endl
44 int main(int argc, char *argv[])
46 QCoreApplication app(argc, argv);
47 QStringList args = app.arguments();
50 std::string profile = "atsc_1080p_24";
51 bool saveImages = true;
55 foreach (const QString &str, args) {
57 if (str.startsWith("--profile=")) {
59 s.remove(0, QString("--profile=").length());
60 profile = s.toStdString();
63 } else if (str == "-h" || str == "--help") {
67 } else if (str == "--no-images") {
71 } else if (str == "--fft") {
78 if (args.length() < 2) {
85 std::string fileMain(args.at(0).toStdString());
87 std::string fileSub = args.at(0).toStdString();
91 qDebug() << "Unused arguments: " << args;
98 std::cout << "Usage: " << argv[0] << " <main audio file> <second audio file>" << std::endl;
101 std::cout << "Trying to align (2)\n\t" << fileSub << "\nto fit on (1)\n\t" << fileMain
102 << "\n, result will indicate by how much (2) has to be moved." << std::endl
103 << "Profile used: " << profile << std::endl
106 std::cout << "Will use FFT based correlation." << std::endl;
111 Mlt::Factory::init(NULL);
113 // Load an arbitrary profile
114 Mlt::Profile prof(profile.c_str());
116 // Load the MLT producers
117 Mlt::Producer prodMain(prof, fileMain.c_str());
118 if (!prodMain.is_valid()) {
119 std::cout << fileMain << " is invalid." << std::endl;
122 Mlt::Producer prodSub(prof, fileSub.c_str());
123 if (!prodSub.is_valid()) {
124 std::cout << fileSub << " is invalid." << std::endl;
129 // Build the audio envelopes for the correlation
130 AudioEnvelope *envelopeMain = new AudioEnvelope(&prodMain);
131 envelopeMain->loadEnvelope();
132 envelopeMain->loadStdDev();
133 envelopeMain->dumpInfo();
135 AudioEnvelope *envelopeSub = new AudioEnvelope(&prodSub);
136 envelopeSub->loadEnvelope();
137 envelopeSub->loadStdDev();
138 envelopeSub->dumpInfo();
145 // Calculate the correlation and hereby the audio shift
146 AudioCorrelation corr(envelopeMain);
147 int index = corr.addChild(envelopeSub, useFFT);
149 int shift = corr.getShift(index);
150 std::cout << " Should be shifted by " << shift << " frames: " << fileSub << std::endl
151 << "\trelative to " << fileMain << std::endl
152 << "\tin a " << prodMain.get_fps() << " fps profile (" << profile << ")." << std::endl
158 outImg = QString("envelope-main-%1.png")
159 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
160 envelopeMain->drawEnvelope().save(outImg);
161 std::cout << "Saved volume envelope as "
162 << QFileInfo(outImg).absoluteFilePath().toStdString()
164 outImg = QString("envelope-sub-%1.png")
165 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
166 envelopeSub->drawEnvelope().save(outImg);
167 std::cout << "Saved volume envelope as "
168 << QFileInfo(outImg).absoluteFilePath().toStdString()
170 outImg = QString("correlation-%1.png")
171 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
172 corr.info(index)->toImage().save(outImg);
173 std::cout << "Saved correlation image as "
174 << QFileInfo(outImg).absoluteFilePath().toStdString()
179 // Mlt::Factory::close();