annotate base/Window.h @ 661:a4faa1840384

* If a FileSource URL won't convert at all in strict mode, try again in tolerant mode (necessary for e.g. filenames with square brackets in them)
author Chris Cannam
date Tue, 19 Oct 2010 21:47:55 +0100
parents 65311fb86166
children 97741fe16205
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@52 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@52 9 This program is free software; you can redistribute it and/or
Chris@52 10 modify it under the terms of the GNU General Public License as
Chris@52 11 published by the Free Software Foundation; either version 2 of the
Chris@52 12 License, or (at your option) any later version. See the file
Chris@52 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #ifndef _WINDOW_H_
Chris@0 17 #define _WINDOW_H_
Chris@0 18
Chris@0 19 #include <cmath>
Chris@0 20 #include <iostream>
Chris@350 21 #include <string>
Chris@0 22 #include <map>
Chris@402 23 #include <cstdlib>
Chris@0 24
Chris@405 25 #include <cstdlib>
Chris@405 26
Chris@0 27 enum WindowType {
Chris@0 28 RectangularWindow,
Chris@0 29 BartlettWindow,
Chris@0 30 HammingWindow,
Chris@0 31 HanningWindow,
Chris@0 32 BlackmanWindow,
Chris@0 33 GaussianWindow,
Chris@142 34 ParzenWindow,
Chris@142 35 NuttallWindow,
Chris@142 36 BlackmanHarrisWindow
Chris@0 37 };
Chris@0 38
Chris@0 39 template <typename T>
Chris@0 40 class Window
Chris@0 41 {
Chris@0 42 public:
Chris@0 43 /**
Chris@0 44 * Construct a windower of the given type.
Chris@0 45 */
Chris@0 46 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
Chris@0 47 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
Chris@0 48 Window &operator=(const Window &w) {
Chris@52 49 if (&w == this) return *this;
Chris@0 50 m_type = w.m_type;
Chris@0 51 m_size = w.m_size;
Chris@0 52 encache();
Chris@0 53 return *this;
Chris@0 54 }
Chris@142 55 virtual ~Window() { delete[] m_cache; }
Chris@0 56
Chris@0 57 void cut(T *src) const { cut(src, src); }
Chris@0 58 void cut(T *src, T *dst) const {
Chris@0 59 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
Chris@0 60 }
Chris@0 61
Chris@162 62 T getArea() { return m_area; }
Chris@140 63 T getValue(size_t i) { return m_cache[i]; }
Chris@140 64
Chris@0 65 WindowType getType() const { return m_type; }
Chris@0 66 size_t getSize() const { return m_size; }
Chris@0 67
Chris@350 68 // The names used by these functions are un-translated, for use in
Chris@350 69 // e.g. XML I/O. Use Preferences::getPropertyValueLabel if you
Chris@350 70 // want translated names for use in the user interface.
Chris@350 71 static std::string getNameForType(WindowType type);
Chris@350 72 static WindowType getTypeForName(std::string name);
Chris@350 73
Chris@0 74 protected:
Chris@0 75 WindowType m_type;
Chris@0 76 size_t m_size;
Chris@0 77 T *m_cache;
Chris@162 78 T m_area;
Chris@0 79
Chris@0 80 void encache();
Chris@142 81 void cosinewin(T *, T, T, T, T);
Chris@0 82 };
Chris@0 83
Chris@0 84 template <typename T>
Chris@0 85 void Window<T>::encache()
Chris@0 86 {
Chris@141 87 int n = int(m_size);
Chris@0 88 T *mult = new T[n];
Chris@141 89 int i;
Chris@0 90 for (i = 0; i < n; ++i) mult[i] = 1.0;
Chris@0 91
Chris@0 92 switch (m_type) {
Chris@0 93
Chris@0 94 case RectangularWindow:
Chris@0 95 for (i = 0; i < n; ++i) {
Chris@141 96 mult[i] *= 0.5;
Chris@0 97 }
Chris@0 98 break;
Chris@0 99
Chris@0 100 case BartlettWindow:
Chris@0 101 for (i = 0; i < n/2; ++i) {
Chris@141 102 mult[i] *= (i / T(n/2));
Chris@141 103 mult[i + n/2] *= (1.0 - (i / T(n/2)));
Chris@0 104 }
Chris@0 105 break;
Chris@0 106
Chris@0 107 case HammingWindow:
Chris@142 108 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
Chris@0 109 break;
Chris@0 110
Chris@0 111 case HanningWindow:
Chris@142 112 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
Chris@0 113 break;
Chris@0 114
Chris@0 115 case BlackmanWindow:
Chris@142 116 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
Chris@0 117 break;
Chris@0 118
Chris@0 119 case GaussianWindow:
Chris@0 120 for (i = 0; i < n; ++i) {
Chris@142 121 mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
Chris@0 122 }
Chris@0 123 break;
Chris@0 124
Chris@0 125 case ParzenWindow:
Chris@141 126 {
Chris@141 127 int N = n-1;
Chris@141 128 for (i = 0; i < N/4; ++i) {
Chris@141 129 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
Chris@141 130 mult[i] *= m;
Chris@141 131 mult[N-i] *= m;
Chris@141 132 }
Chris@141 133 for (i = N/4; i <= N/2; ++i) {
Chris@141 134 int wn = i - N/2;
Chris@141 135 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
Chris@141 136 mult[i] *= m;
Chris@141 137 mult[N-i] *= m;
Chris@141 138 }
Chris@142 139 break;
Chris@142 140 }
Chris@142 141
Chris@142 142 case NuttallWindow:
Chris@142 143 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
Chris@0 144 break;
Chris@142 145
Chris@142 146 case BlackmanHarrisWindow:
Chris@142 147 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
Chris@142 148 break;
Chris@0 149 }
Chris@0 150
Chris@0 151 m_cache = mult;
Chris@162 152
Chris@162 153 m_area = 0;
Chris@162 154 for (int i = 0; i < n; ++i) {
Chris@162 155 m_area += m_cache[i];
Chris@162 156 }
Chris@162 157 m_area /= n;
Chris@0 158 }
Chris@0 159
Chris@142 160 template <typename T>
Chris@142 161 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
Chris@142 162 {
Chris@142 163 int n = int(m_size);
Chris@142 164 for (int i = 0; i < n; ++i) {
Chris@142 165 mult[i] *= (a0
Chris@262 166 - a1 * cos((2 * M_PI * i) / n)
Chris@262 167 + a2 * cos((4 * M_PI * i) / n)
Chris@262 168 - a3 * cos((6 * M_PI * i) / n));
Chris@142 169 }
Chris@142 170 }
Chris@142 171
Chris@350 172 template <typename T>
Chris@350 173 std::string
Chris@350 174 Window<T>::getNameForType(WindowType type)
Chris@350 175 {
Chris@350 176 switch (type) {
Chris@350 177 case RectangularWindow: return "rectangular";
Chris@350 178 case BartlettWindow: return "bartlett";
Chris@350 179 case HammingWindow: return "hamming";
Chris@350 180 case HanningWindow: return "hanning";
Chris@350 181 case BlackmanWindow: return "blackman";
Chris@350 182 case GaussianWindow: return "gaussian";
Chris@350 183 case ParzenWindow: return "parzen";
Chris@350 184 case NuttallWindow: return "nuttall";
Chris@350 185 case BlackmanHarrisWindow: return "blackman-harris";
Chris@350 186 }
Chris@350 187
Chris@350 188 std::cerr << "WARNING: Window::getNameForType: unknown type "
Chris@350 189 << type << std::endl;
Chris@350 190
Chris@350 191 return "unknown";
Chris@350 192 }
Chris@350 193
Chris@350 194 template <typename T>
Chris@350 195 WindowType
Chris@350 196 Window<T>::getTypeForName(std::string name)
Chris@350 197 {
Chris@350 198 if (name == "rectangular") return RectangularWindow;
Chris@350 199 if (name == "bartlett") return BartlettWindow;
Chris@350 200 if (name == "hamming") return HammingWindow;
Chris@350 201 if (name == "hanning") return HanningWindow;
Chris@350 202 if (name == "blackman") return BlackmanWindow;
Chris@350 203 if (name == "gaussian") return GaussianWindow;
Chris@350 204 if (name == "parzen") return ParzenWindow;
Chris@350 205 if (name == "nuttall") return NuttallWindow;
Chris@350 206 if (name == "blackman-harris") return BlackmanHarrisWindow;
Chris@350 207
Chris@350 208 std::cerr << "WARNING: Window::getTypeForName: unknown name \""
Chris@350 209 << name << "\", defaulting to \"hanning\"" << std::endl;
Chris@350 210
Chris@350 211 return HanningWindow;
Chris@350 212 }
Chris@350 213
Chris@0 214 #endif