]> git.sesse.net Git - kdenlive/blob - testingArea/audioOffset.cpp
Volume envelope calculation
[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 <QFileInfo>
17 #include <QDateTime>
18 #include <mlt++/Mlt.h>
19 #include <iostream>
20 #include <cstdlib>
21 #include <cmath>
22
23 #include "audioInfo.h"
24 #include "audioStreamInfo.h"
25
26 int main(int argc, char *argv[])
27 {
28     char *fileMain;
29     char *fileSub;
30     if (argc > 2) {
31         fileMain = argv[1];
32         fileSub = argv[2];
33     } else {
34         std::cout << "Usage: " << argv[0] << " <main audio file> <second audio file>" << std::endl;
35         return 0;
36     }
37     std::cout << "Trying to align (1)\n\t" << fileSub << "\nto fit on (2)\n\t" << fileMain
38               << "\n, result will indicate by how much (1) has to be moved." << std::endl;
39
40     // Initialize MLT
41     Mlt::Factory::init(NULL);
42
43     // Load an arbitrary profile
44     Mlt::Profile prof("hdv_1080_25p");
45
46     // Load the MLT producers
47     Mlt::Producer prodMain(prof, fileMain);
48     if (!prodMain.is_valid()) {
49         std::cout << fileMain << " is invalid." << std::endl;
50         return 2;
51     }
52     Mlt::Producer profSub(prof, fileSub);
53     if (!profSub.is_valid()) {
54         std::cout << fileSub << " is invalid." << std::endl;
55         return 2;
56     }
57
58     AudioInfo infoMain(&prodMain);
59     AudioInfo infoSub(&profSub);
60     infoMain.dumpInfo();
61     infoSub.dumpInfo();
62
63     prodMain.get_fps();
64
65
66     int framesToFetch = prodMain.get_length();
67     std::cout << "Length: " << framesToFetch
68               << " (Seconds: " << framesToFetch/prodMain.get_fps() << ")"
69               << std::endl;
70     if (framesToFetch > 5000) {
71         framesToFetch = 5000;
72     }
73
74     mlt_audio_format format_s16 = mlt_audio_s16;
75     int samplingRate = infoMain.info(0)->samplingRate();
76     int channels = 1;
77
78     Mlt::Frame *frame;
79     int64_t position;
80     int samples;
81
82     uint64_t envelope[framesToFetch];
83     uint64_t max = 0;
84
85     QTime t;
86     t.start();
87     for (int i = 0; i < framesToFetch; i++) {
88
89         frame = prodMain.get_frame(i);
90         position = mlt_frame_get_position(frame->get_frame());
91         samples = mlt_sample_calculator(prodMain.get_fps(), infoMain.info(0)->samplingRate(), position);
92
93         int16_t *data = static_cast<int16_t*>(frame->get_audio(format_s16, samplingRate, channels, samples));
94
95         uint64_t sum = 0;
96         for (int k = 0; k < samples; k++) {
97             sum += fabs(data[k]);
98         }
99         envelope[i] = sum;
100
101         if (sum > max) {
102             max = sum;
103         }
104     }
105     std::cout << "Calculating the envelope (" << framesToFetch << " frames) took "
106               << t.elapsed() << " ms." << std::endl;
107
108     QImage img(framesToFetch, 400, QImage::Format_ARGB32);
109     img.fill(qRgb(255,255,255));
110     double fy;
111     for (int x = 0; x < img.width(); x++) {
112         fy = envelope[x]/double(max) * img.height();
113         for (int y = img.height()-1; y > img.height()-1-fy; y--) {
114             img.setPixel(x,y, qRgb(50, 50, 50));
115         }
116     }
117
118     QString outImg = QString("envelope-%1.png")
119             .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
120     img.save(outImg);
121     std::cout << "Saved volume envelope as "
122               << QFileInfo(outImg).absoluteFilePath().toStdString()
123               << std::endl;
124
125     return 0;
126
127 }