]> git.sesse.net Git - kdenlive/blob - testingArea/audioOffset.cpp
QString::toStdString() replaced by QString::toLocal8Bit() as KDE4
[kdenlive] / testingArea / audioOffset.cpp
1 /***************************************************************************
2  *   Copyright (C) 2012 by Simon Andreas Eugster (simon.eu@gmail.com)      *
3  *   This file is part of kdenlive. See www.kdenlive.org.                  *
4  *                                                                         *
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  ***************************************************************************/
10
11
12 #include <QMap>
13 #include <QFile>
14 #include <QTime>
15 #include <QImage>
16 #include <QDebug>
17 #include <QFileInfo>
18 #include <QDateTime>
19 #include <QStringList>
20 #include <QCoreApplication>
21 #include <mlt++/Mlt.h>
22 #include <iostream>
23 #include <cstdlib>
24 #include <cmath>
25
26 #include "../src/lib/audio/audioInfo.h"
27 #include "../src/lib/audio/audioStreamInfo.h"
28 #include "../src/lib/audio/audioEnvelope.h"
29 #include "../src/lib/audio/audioCorrelation.h"
30
31 void printUsage(const char *path)
32 {
33     std::cout << "This executable takes two audio/video files A and B and determines " << std::endl
34               << "how much B needs to be shifted in order to be synchronized with A." << std::endl << std::endl
35               << path << " <main audio file> <second audio file>" << std::endl
36               << "\t-h, --help\n\t\tDisplay this help" << std::endl
37               << "\t--profile=<profile>\n\t\tUse the given profile for calculation (run: melt -query profiles)" << std::endl
38               << "\t--no-images\n\t\tDo not save envelope and correlation images" << std::endl
39                  ;
40 }
41
42 int main(int argc, char *argv[])
43 {
44     QCoreApplication app(argc, argv);
45     QStringList args = app.arguments();
46     args.removeAt(0);
47
48     std::string profile = "atsc_1080p_24";
49     bool saveImages = true;
50
51     // Load arguments
52     foreach (QString str, args) {
53
54         if (str.startsWith("--profile=")) {
55             QString s = str;
56             s.remove(0, QString("--profile=").length());
57             profile = s.toStdString();
58             args.removeOne(str);
59
60         } else if (str == "-h" || str == "--help") {
61             printUsage(argv[0]);
62             return 0;
63
64         } else if (str == "--no-images") {
65             saveImages = false;
66             args.removeOne(str);
67         }
68
69     }
70
71     if (args.length() < 2) {
72         printUsage(argv[0]);
73         return 1;
74     }
75
76
77
78     std::string fileMain(args.at(0).toStdString());
79     args.removeFirst();
80     std::string fileSub = args.at(0).toStdString();
81     args.removeFirst();
82
83
84     qDebug() << "Unused arguments: " << args;
85
86
87     if (argc > 2) {
88         fileMain = argv[1];
89         fileSub = argv[2];
90     } else {
91         std::cout << "Usage: " << argv[0] << " <main audio file> <second audio file>" << std::endl;
92         return 0;
93     }
94     std::cout << "Trying to align (2)\n\t" << fileSub << "\nto fit on (1)\n\t" << fileMain
95               << "\n, result will indicate by how much (2) has to be moved." << std::endl
96               << "Profile used: " << profile << std::endl
97                  ;
98
99
100     // Initialize MLT
101     Mlt::Factory::init(NULL);
102
103     // Load an arbitrary profile
104     Mlt::Profile prof(profile.c_str());
105
106     // Load the MLT producers
107     Mlt::Producer prodMain(prof, fileMain.c_str());
108     if (!prodMain.is_valid()) {
109         std::cout << fileMain << " is invalid." << std::endl;
110         return 2;
111     }
112     Mlt::Producer prodSub(prof, fileSub.c_str());
113     if (!prodSub.is_valid()) {
114         std::cout << fileSub << " is invalid." << std::endl;
115         return 2;
116     }
117
118
119     // Build the audio envelopes for the correlation
120     AudioEnvelope *envelopeMain = new AudioEnvelope(&prodMain);
121     envelopeMain->loadEnvelope();
122     envelopeMain->loadStdDev();
123     envelopeMain->dumpInfo();
124
125     AudioEnvelope *envelopeSub = new AudioEnvelope(&prodSub);
126     envelopeSub->loadEnvelope();
127     envelopeSub->loadStdDev();
128     envelopeSub->dumpInfo();
129
130
131
132
133
134
135     // Calculate the correlation and hereby the audio shift
136     AudioCorrelation corr(envelopeMain);
137     int index = corr.addChild(envelopeSub);
138
139     int shift = corr.getShift(index);
140     std::cout << fileSub << " should be shifted by " << shift << " frames" << std::endl
141               << "\trelative to " << fileMain << std::endl
142               << "\tin a " << prodMain.get_fps() << " fps profile (" << profile << ")." << std::endl
143                  ;
144
145
146     if (saveImages) {
147         QString outImg;
148         outImg = QString("envelope-main-%1.png")
149                 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
150         envelopeMain->drawEnvelope().save(outImg);
151         std::cout << "Saved volume envelope as "
152                   << QFileInfo(outImg).absoluteFilePath().toStdString()
153                   << std::endl;
154         outImg = QString("envelope-sub-%1.png")
155                 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
156         envelopeSub->drawEnvelope().save(outImg);
157         std::cout << "Saved volume envelope as "
158                   << QFileInfo(outImg).absoluteFilePath().toStdString()
159                   << std::endl;
160         outImg = QString("correlation-%1.png")
161                 .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
162         corr.info(index)->toImage().save(outImg);
163         std::cout << "Saved correlation image as "
164                   << QFileInfo(outImg).absoluteFilePath().toStdString()
165                   << std::endl;
166     }
167
168
169     return 0;
170
171 }
172
173
174