]> git.sesse.net Git - kdenlive/blob - src/lib/audio/audioCorrelation.cpp
0a308c1c8368e1af7bb208aa12a9d54d282e8026
[kdenlive] / src / lib / audio / audioCorrelation.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 #include "audioCorrelation.h"
12
13 #include <QTime>
14 #include <cmath>
15 #include <iostream>
16
17 AudioCorrelation::AudioCorrelation(AudioEnvelope *mainTrackEnvelope) :
18     m_mainTrackEnvelope(mainTrackEnvelope)
19 {
20     m_mainTrackEnvelope->normalizeEnvelope();
21 }
22
23 AudioCorrelation::~AudioCorrelation()
24 {
25     delete m_mainTrackEnvelope;
26     foreach (AudioEnvelope *envelope, m_children) {
27         delete envelope;
28     }
29 }
30
31 int AudioCorrelation::addChild(AudioEnvelope *envelope)
32 {
33     envelope->normalizeEnvelope();
34
35     const int sizeMain = m_mainTrackEnvelope->envelopeSize();
36     const int sizeSub = envelope->envelopeSize();
37
38
39     AudioCorrelationInfo *info = new AudioCorrelationInfo(sizeMain, sizeSub);
40     int64_t *correlation = info->correlationVector();
41
42     const int64_t *envMain = m_mainTrackEnvelope->envelope();
43     const int64_t *envSub = envelope->envelope();
44     int64_t const* left;
45     int64_t const* right;
46     int size;
47     int64_t sum;
48     int64_t max = 0;
49
50
51     /*
52       Correlation:
53
54       SHIFT \in [-sS..sM]
55
56       <--sS----
57       [  sub  ]----sM--->[ sub ]
58                [  main  ]
59
60             ^ correlation vector index = SHIFT + sS
61
62       main is fixed, sub is shifted along main.
63
64     */
65
66
67     QTime t;
68     t.start();
69     for (int shift = -sizeSub; shift <= sizeMain; shift++) {
70
71         if (shift <= 0) {
72             left = envSub-shift;
73             right = envMain;
74             size = std::min(sizeSub+shift, sizeMain);
75         } else {
76             left = envSub;
77             right = envMain+shift;
78             size = std::min(sizeSub, sizeMain-shift);
79         }
80
81         sum = 0;
82         for (int i = 0; i < size; i++) {
83             sum += (*left) * (*right);
84             left++;
85             right++;
86         }
87         correlation[sizeSub+shift] = std::abs(sum);
88
89         if (sum > max) {
90             max = sum;
91         }
92
93     }
94     info->setMax(max);
95     std::cout << "Correlation calculated. Time taken: " << t.elapsed() << " ms." << std::endl;
96
97
98     m_children.append(envelope);
99     m_correlations.append(info);
100
101     Q_ASSERT(m_correlations.size() == m_children.size());
102
103     return m_children.indexOf(envelope);
104 }
105
106 int AudioCorrelation::getShift(int childIndex) const
107 {
108     Q_ASSERT(childIndex >= 0);
109     Q_ASSERT(childIndex < m_correlations.size());
110
111     int indexOffset = m_correlations.at(childIndex)->maxIndex();
112     indexOffset -= m_children.at(childIndex)->envelopeSize();
113
114     return indexOffset;
115 }
116
117 AudioCorrelationInfo const* AudioCorrelation::info(int childIndex) const
118 {
119     Q_ASSERT(childIndex >= 0);
120     Q_ASSERT(childIndex < m_correlations.size());
121
122     return m_correlations.at(childIndex);
123 }