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