]> git.sesse.net Git - kdenlive/blob - src/audioscopes/ffttools.cpp
Audio scopes: Caching window functions for better performance
[kdenlive] / src / audioscopes / ffttools.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 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 <math.h>
12
13 #include <QString>
14
15 #include "ffttools.h"
16
17 //#define DEBUG_FFTTOOLS
18 #ifdef DEBUG_FFTTOOLS
19 #include <QDebug>
20 #endif
21
22 FFTTools::FFTTools()
23 {
24 }
25
26 const QString FFTTools::windowSignature(const WindowType windowType, const int size, const float param)
27 {
28     return QString("s%1_t%2_p%3").arg(size).arg(windowType).arg(param, 0, 'f', 3);
29 }
30
31 // http://cplusplus.syntaxerrors.info/index.php?title=Cannot_declare_member_function_%E2%80%98static_int_Foo::bar%28%29%E2%80%99_to_have_static_linkage
32 const QVector<float> FFTTools::window(const WindowType windowType, const int size, const float param)
33 {
34     // Deliberately avoid converting size to a float
35     // to keep mid an integer.
36     float mid = (size-1)/2;
37     float max = size-1;
38     QVector<float> window;
39
40     switch (windowType) {
41     case Window_Rect:
42         return QVector<float>(size+1, 1);
43         break;
44     case Window_Triangle:
45         window = QVector<float>(size+1);
46
47         for (int x = 0; x < mid; x++) {
48             window[x] = x/mid + (mid-x)/mid*param;
49         }
50         for (int x = mid; x < size; x++) {
51             window[x] = (x-mid)/(max-mid) * param + (max-x)/(max-mid);
52         }
53         window[size] = .5 + param/2;
54
55 #ifdef DEBUG_FFTTOOLS
56         qDebug() << "Triangle window (factor " << window[size] << "):";
57         for (int i = 0; i < size; i++) {
58             qDebug() << window[i];
59         }
60         qDebug() << "Triangle window end.";
61 #endif
62
63         return window;
64         break;
65     case Window_Hamming:
66         // Use a quick version of the Hamming window here: Instead of
67         // interpolating values between (-max/2) and (max/2)
68         // we use integer values instead, ranging from -mid to (max-mid).
69         window = QVector<float>(size+1);
70
71         for (int x = 0; x < size; x++) {
72             window[x] = .54 + .46 * cos( 2*M_PI*(x-mid) / size );
73         }
74
75         // Integrating the cosine over the window function results in
76         // an area of 0; So only the constant factor 0.54 counts.
77         window[size] = .54;
78
79 #ifdef DEBUG_FFTTOOLS
80         qDebug() << "Hanning window (factor " << window[size] << "):";
81         for (int i = 0; i < size; i++) {
82             qDebug() << window[i];
83         }
84         qDebug() << "Hanning window end.";
85 #endif
86
87         return window;
88         break;
89     }
90     Q_ASSERT(false);
91     return QVector<float>();
92 }
93
94 #ifdef DEBUG_FFTTOOLS
95 #undef DEBUG_FFTTOOLS
96 #endif