Chris@317
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@317
|
2
|
Chris@317
|
3 /*
|
Chris@317
|
4 Vamp
|
Chris@317
|
5
|
Chris@317
|
6 An API for audio analysis and feature extraction plugins.
|
Chris@317
|
7
|
Chris@317
|
8 Centre for Digital Music, Queen Mary, University of London.
|
Chris@317
|
9 Copyright 2006-2011 Chris Cannam and QMUL.
|
Chris@317
|
10
|
Chris@317
|
11 Permission is hereby granted, free of charge, to any person
|
Chris@317
|
12 obtaining a copy of this software and associated documentation
|
Chris@317
|
13 files (the "Software"), to deal in the Software without
|
Chris@317
|
14 restriction, including without limitation the rights to use, copy,
|
Chris@317
|
15 modify, merge, publish, distribute, sublicense, and/or sell copies
|
Chris@317
|
16 of the Software, and to permit persons to whom the Software is
|
Chris@317
|
17 furnished to do so, subject to the following conditions:
|
Chris@317
|
18
|
Chris@317
|
19 The above copyright notice and this permission notice shall be
|
Chris@317
|
20 included in all copies or substantial portions of the Software.
|
Chris@317
|
21
|
Chris@317
|
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Chris@317
|
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Chris@317
|
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Chris@317
|
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
Chris@317
|
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
Chris@317
|
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Chris@317
|
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Chris@317
|
29
|
Chris@317
|
30 Except as contained in this notice, the names of the Centre for
|
Chris@317
|
31 Digital Music; Queen Mary, University of London; and Chris Cannam
|
Chris@317
|
32 shall not be used in advertising or otherwise to promote the sale,
|
Chris@317
|
33 use or other dealings in this Software without prior written
|
Chris@317
|
34 authorization.
|
Chris@317
|
35 */
|
Chris@317
|
36
|
Chris@317
|
37 #ifndef _WINDOW_H_
|
Chris@317
|
38 #define _WINDOW_H_
|
Chris@317
|
39
|
Chris@317
|
40 #include <vamp-hostsdk/hostguard.h>
|
Chris@317
|
41
|
Chris@317
|
42 #include <cmath>
|
Chris@317
|
43 #include <cstdlib>
|
Chris@317
|
44
|
Chris@317
|
45 _VAMP_SDK_HOSTSPACE_BEGIN(Window.h)
|
Chris@317
|
46
|
Chris@317
|
47 template <typename T>
|
Chris@317
|
48 class Window
|
Chris@317
|
49 {
|
Chris@317
|
50 public:
|
Chris@317
|
51 enum WindowType {
|
Chris@317
|
52 RectangularWindow,
|
Chris@317
|
53 BartlettWindow,
|
Chris@317
|
54 HammingWindow,
|
Chris@317
|
55 HanningWindow,
|
Chris@317
|
56 BlackmanWindow,
|
Chris@317
|
57 NuttallWindow,
|
Chris@317
|
58 BlackmanHarrisWindow
|
Chris@317
|
59 };
|
Chris@317
|
60
|
Chris@317
|
61 /**
|
Chris@317
|
62 * Construct a windower of the given type.
|
Chris@317
|
63 */
|
Chris@317
|
64 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
|
Chris@317
|
65 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
|
Chris@317
|
66 Window &operator=(const Window &w) {
|
Chris@317
|
67 if (&w == this) return *this;
|
Chris@317
|
68 m_type = w.m_type;
|
Chris@317
|
69 m_size = w.m_size;
|
Chris@317
|
70 encache();
|
Chris@317
|
71 return *this;
|
Chris@317
|
72 }
|
Chris@317
|
73 virtual ~Window() { delete[] m_cache; }
|
Chris@317
|
74
|
Chris@317
|
75 void cut(T *src) const { cut(src, src); }
|
Chris@317
|
76 void cut(T *src, T *dst) const {
|
Chris@317
|
77 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
|
Chris@317
|
78 }
|
Chris@444
|
79 template <typename T0, typename T1>
|
Chris@444
|
80 void cut(T0 *src, T1 *dst) const {
|
Chris@317
|
81 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
|
Chris@317
|
82 }
|
Chris@317
|
83
|
Chris@317
|
84 T getArea() { return m_area; }
|
Chris@317
|
85 T getValue(size_t i) { return m_cache[i]; }
|
Chris@317
|
86
|
Chris@317
|
87 WindowType getType() const { return m_type; }
|
Chris@317
|
88 size_t getSize() const { return m_size; }
|
Chris@317
|
89
|
Chris@317
|
90 protected:
|
Chris@317
|
91 WindowType m_type;
|
Chris@317
|
92 size_t m_size;
|
Chris@317
|
93 T *m_cache;
|
Chris@317
|
94 T m_area;
|
Chris@317
|
95
|
Chris@317
|
96 void encache();
|
Chris@317
|
97 void cosinewin(T *, T, T, T, T);
|
Chris@317
|
98 };
|
Chris@317
|
99
|
Chris@317
|
100 template <typename T>
|
Chris@317
|
101 void Window<T>::encache()
|
Chris@317
|
102 {
|
Chris@317
|
103 int n = int(m_size);
|
Chris@317
|
104 T *mult = new T[n];
|
Chris@317
|
105 int i;
|
Chris@317
|
106 for (i = 0; i < n; ++i) mult[i] = 1.0;
|
Chris@317
|
107
|
Chris@317
|
108 switch (m_type) {
|
Chris@317
|
109
|
Chris@317
|
110 case RectangularWindow:
|
Chris@317
|
111 for (i = 0; i < n; ++i) {
|
Chris@317
|
112 mult[i] *= 0.5;
|
Chris@317
|
113 }
|
Chris@317
|
114 break;
|
Chris@317
|
115
|
Chris@317
|
116 case BartlettWindow:
|
Chris@317
|
117 for (i = 0; i < n/2; ++i) {
|
Chris@317
|
118 mult[i] *= (i / T(n/2));
|
Chris@317
|
119 mult[i + n/2] *= (1.0 - (i / T(n/2)));
|
Chris@317
|
120 }
|
Chris@317
|
121 break;
|
Chris@317
|
122
|
Chris@317
|
123 case HammingWindow:
|
Chris@317
|
124 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
|
Chris@317
|
125 break;
|
Chris@317
|
126
|
Chris@317
|
127 case HanningWindow:
|
Chris@317
|
128 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
|
Chris@317
|
129 break;
|
Chris@317
|
130
|
Chris@317
|
131 case BlackmanWindow:
|
Chris@317
|
132 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
|
Chris@317
|
133 break;
|
Chris@317
|
134
|
Chris@317
|
135 case NuttallWindow:
|
Chris@317
|
136 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
|
Chris@317
|
137 break;
|
Chris@317
|
138
|
Chris@317
|
139 case BlackmanHarrisWindow:
|
Chris@317
|
140 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
|
Chris@317
|
141 break;
|
Chris@317
|
142 }
|
Chris@317
|
143
|
Chris@317
|
144 m_cache = mult;
|
Chris@317
|
145
|
Chris@317
|
146 m_area = 0;
|
Chris@317
|
147 for (int i = 0; i < n; ++i) {
|
Chris@317
|
148 m_area += m_cache[i];
|
Chris@317
|
149 }
|
Chris@317
|
150 m_area /= n;
|
Chris@317
|
151 }
|
Chris@317
|
152
|
Chris@317
|
153 template <typename T>
|
Chris@317
|
154 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
|
Chris@317
|
155 {
|
Chris@317
|
156 int n = int(m_size);
|
Chris@317
|
157 for (int i = 0; i < n; ++i) {
|
Chris@317
|
158 mult[i] *= (a0
|
Chris@317
|
159 - a1 * cos((2 * M_PI * i) / n)
|
Chris@317
|
160 + a2 * cos((4 * M_PI * i) / n)
|
Chris@317
|
161 - a3 * cos((6 * M_PI * i) / n));
|
Chris@317
|
162 }
|
Chris@317
|
163 }
|
Chris@317
|
164
|
Chris@317
|
165 _VAMP_SDK_HOSTSPACE_END(Window.h)
|
Chris@317
|
166
|
Chris@317
|
167 #endif
|