]> git.sesse.net Git - kdenlive/blobdiff - testingArea/audioCorrelation.cpp
Audio alignment works.
[kdenlive] / testingArea / audioCorrelation.cpp
diff --git a/testingArea/audioCorrelation.cpp b/testingArea/audioCorrelation.cpp
new file mode 100644 (file)
index 0000000..96adab6
--- /dev/null
@@ -0,0 +1,109 @@
+#include "audioCorrelation.h"
+
+#include <QTime>
+#include <cmath>
+#include <iostream>
+
+AudioCorrelation::AudioCorrelation(AudioEnvelope *mainTrackEnvelope) :
+    m_mainTrackEnvelope(mainTrackEnvelope)
+{
+    m_mainTrackEnvelope->normalizeEnvelope();
+}
+
+AudioCorrelation::~AudioCorrelation()
+{
+}
+
+int AudioCorrelation::addChild(AudioEnvelope *envelope)
+{
+    envelope->normalizeEnvelope();
+
+    const int sizeMain = m_mainTrackEnvelope->envelopeSize();
+    const int sizeSub = envelope->envelopeSize();
+
+
+    AudioCorrelationInfo *info = new AudioCorrelationInfo(sizeMain, sizeSub);
+    int64_t *correlation = info->correlationVector();
+
+    const int64_t *envMain = m_mainTrackEnvelope->envelope();
+    const int64_t *envSub = envelope->envelope();
+    int64_t const* left;
+    int64_t const* right;
+    int size;
+    int64_t sum;
+    int64_t max = 0;
+
+
+    /*
+      Correlation:
+
+      SHIFT \in [-sS..sM]
+
+      <--sS----
+      [  sub  ]----sM--->[ sub ]
+               [  main  ]
+
+            ^ correlation vector index = SHIFT + sS
+
+      main is fixed, sub is shifted along main.
+
+    */
+
+
+    QTime t;
+    t.start();
+    for (int shift = -sizeSub; shift <= sizeMain; shift++) {
+
+        if (shift <= 0) {
+            left = envSub-shift;
+            right = envMain;
+            size = std::min(sizeSub+shift, sizeMain);
+        } else {
+            left = envSub;
+            right = envMain+shift;
+            size = std::min(sizeSub, sizeMain-shift);
+        }
+
+        sum = 0;
+        for (int i = 0; i < size; i++) {
+            sum += (*left) * (*right);
+            left++;
+            right++;
+        }
+        correlation[sizeSub+shift] = std::abs(sum);
+
+        if (sum > max) {
+            max = sum;
+        }
+
+    }
+    info->setMax(max);
+    std::cout << "Correlation calculated. Time taken: " << t.elapsed() << " ms." << std::endl;
+
+
+    m_children.append(envelope);
+    m_correlations.append(info);
+
+    Q_ASSERT(m_correlations.size() == m_children.size());
+
+    return m_children.indexOf(envelope);
+}
+
+int AudioCorrelation::getShift(int childIndex) const
+{
+    Q_ASSERT(childIndex >= 0);
+    Q_ASSERT(childIndex < m_correlations.size());
+
+    int indexOffset = m_correlations.at(childIndex)->maxIndex();
+    indexOffset -= m_children.at(childIndex)->envelopeSize();
+
+    return indexOffset;
+}
+
+AudioCorrelationInfo const* AudioCorrelation::info(int childIndex) const
+{
+    Q_ASSERT(childIndex >= 0);
+    Q_ASSERT(childIndex < m_correlations.size());
+
+    return m_correlations.at(childIndex);
+}