annotate base/Window.h @ 392:183ee2a55fc7

* More work to abstract out interactive components used in the data library, so that it does not need to depend on QtGui.
author Chris Cannam
date Fri, 14 Mar 2008 17:14:21 +0000
parents d7c41483af8f
children 7e1b7fcb6c00
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@0 23
Chris@0 24 enum WindowType {
Chris@0 25 RectangularWindow,
Chris@0 26 BartlettWindow,
Chris@0 27 HammingWindow,
Chris@0 28 HanningWindow,
Chris@0 29 BlackmanWindow,
Chris@0 30 GaussianWindow,
Chris@142 31 ParzenWindow,
Chris@142 32 NuttallWindow,
Chris@142 33 BlackmanHarrisWindow
Chris@0 34 };
Chris@0 35
Chris@0 36 template <typename T>
Chris@0 37 class Window
Chris@0 38 {
Chris@0 39 public:
Chris@0 40 /**
Chris@0 41 * Construct a windower of the given type.
Chris@0 42 */
Chris@0 43 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
Chris@0 44 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
Chris@0 45 Window &operator=(const Window &w) {
Chris@52 46 if (&w == this) return *this;
Chris@0 47 m_type = w.m_type;
Chris@0 48 m_size = w.m_size;
Chris@0 49 encache();
Chris@0 50 return *this;
Chris@0 51 }
Chris@142 52 virtual ~Window() { delete[] m_cache; }
Chris@0 53
Chris@0 54 void cut(T *src) const { cut(src, src); }
Chris@0 55 void cut(T *src, T *dst) const {
Chris@0 56 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
Chris@0 57 }
Chris@0 58
Chris@162 59 T getArea() { return m_area; }
Chris@140 60 T getValue(size_t i) { return m_cache[i]; }
Chris@140 61
Chris@0 62 WindowType getType() const { return m_type; }
Chris@0 63 size_t getSize() const { return m_size; }
Chris@0 64
Chris@350 65 // The names used by these functions are un-translated, for use in
Chris@350 66 // e.g. XML I/O. Use Preferences::getPropertyValueLabel if you
Chris@350 67 // want translated names for use in the user interface.
Chris@350 68 static std::string getNameForType(WindowType type);
Chris@350 69 static WindowType getTypeForName(std::string name);
Chris@350 70
Chris@0 71 protected:
Chris@0 72 WindowType m_type;
Chris@0 73 size_t m_size;
Chris@0 74 T *m_cache;
Chris@162 75 T m_area;
Chris@0 76
Chris@0 77 void encache();
Chris@142 78 void cosinewin(T *, T, T, T, T);
Chris@0 79 };
Chris@0 80
Chris@0 81 template <typename T>
Chris@0 82 void Window<T>::encache()
Chris@0 83 {
Chris@141 84 int n = int(m_size);
Chris@0 85 T *mult = new T[n];
Chris@141 86 int i;
Chris@0 87 for (i = 0; i < n; ++i) mult[i] = 1.0;
Chris@0 88
Chris@0 89 switch (m_type) {
Chris@0 90
Chris@0 91 case RectangularWindow:
Chris@0 92 for (i = 0; i < n; ++i) {
Chris@141 93 mult[i] *= 0.5;
Chris@0 94 }
Chris@0 95 break;
Chris@0 96
Chris@0 97 case BartlettWindow:
Chris@0 98 for (i = 0; i < n/2; ++i) {
Chris@141 99 mult[i] *= (i / T(n/2));
Chris@141 100 mult[i + n/2] *= (1.0 - (i / T(n/2)));
Chris@0 101 }
Chris@0 102 break;
Chris@0 103
Chris@0 104 case HammingWindow:
Chris@142 105 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
Chris@0 106 break;
Chris@0 107
Chris@0 108 case HanningWindow:
Chris@142 109 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
Chris@0 110 break;
Chris@0 111
Chris@0 112 case BlackmanWindow:
Chris@142 113 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
Chris@0 114 break;
Chris@0 115
Chris@0 116 case GaussianWindow:
Chris@0 117 for (i = 0; i < n; ++i) {
Chris@142 118 mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
Chris@0 119 }
Chris@0 120 break;
Chris@0 121
Chris@0 122 case ParzenWindow:
Chris@141 123 {
Chris@141 124 int N = n-1;
Chris@141 125 for (i = 0; i < N/4; ++i) {
Chris@141 126 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
Chris@141 127 mult[i] *= m;
Chris@141 128 mult[N-i] *= m;
Chris@141 129 }
Chris@141 130 for (i = N/4; i <= N/2; ++i) {
Chris@141 131 int wn = i - N/2;
Chris@141 132 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
Chris@141 133 mult[i] *= m;
Chris@141 134 mult[N-i] *= m;
Chris@141 135 }
Chris@142 136 break;
Chris@142 137 }
Chris@142 138
Chris@142 139 case NuttallWindow:
Chris@142 140 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
Chris@0 141 break;
Chris@142 142
Chris@142 143 case BlackmanHarrisWindow:
Chris@142 144 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
Chris@142 145 break;
Chris@0 146 }
Chris@0 147
Chris@0 148 m_cache = mult;
Chris@162 149
Chris@162 150 m_area = 0;
Chris@162 151 for (int i = 0; i < n; ++i) {
Chris@162 152 m_area += m_cache[i];
Chris@162 153 }
Chris@162 154 m_area /= n;
Chris@0 155 }
Chris@0 156
Chris@142 157 template <typename T>
Chris@142 158 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
Chris@142 159 {
Chris@142 160 int n = int(m_size);
Chris@142 161 for (int i = 0; i < n; ++i) {
Chris@142 162 mult[i] *= (a0
Chris@262 163 - a1 * cos((2 * M_PI * i) / n)
Chris@262 164 + a2 * cos((4 * M_PI * i) / n)
Chris@262 165 - a3 * cos((6 * M_PI * i) / n));
Chris@142 166 }
Chris@142 167 }
Chris@142 168
Chris@350 169 template <typename T>
Chris@350 170 std::string
Chris@350 171 Window<T>::getNameForType(WindowType type)
Chris@350 172 {
Chris@350 173 switch (type) {
Chris@350 174 case RectangularWindow: return "rectangular";
Chris@350 175 case BartlettWindow: return "bartlett";
Chris@350 176 case HammingWindow: return "hamming";
Chris@350 177 case HanningWindow: return "hanning";
Chris@350 178 case BlackmanWindow: return "blackman";
Chris@350 179 case GaussianWindow: return "gaussian";
Chris@350 180 case ParzenWindow: return "parzen";
Chris@350 181 case NuttallWindow: return "nuttall";
Chris@350 182 case BlackmanHarrisWindow: return "blackman-harris";
Chris@350 183 }
Chris@350 184
Chris@350 185 std::cerr << "WARNING: Window::getNameForType: unknown type "
Chris@350 186 << type << std::endl;
Chris@350 187
Chris@350 188 return "unknown";
Chris@350 189 }
Chris@350 190
Chris@350 191 template <typename T>
Chris@350 192 WindowType
Chris@350 193 Window<T>::getTypeForName(std::string name)
Chris@350 194 {
Chris@350 195 if (name == "rectangular") return RectangularWindow;
Chris@350 196 if (name == "bartlett") return BartlettWindow;
Chris@350 197 if (name == "hamming") return HammingWindow;
Chris@350 198 if (name == "hanning") return HanningWindow;
Chris@350 199 if (name == "blackman") return BlackmanWindow;
Chris@350 200 if (name == "gaussian") return GaussianWindow;
Chris@350 201 if (name == "parzen") return ParzenWindow;
Chris@350 202 if (name == "nuttall") return NuttallWindow;
Chris@350 203 if (name == "blackman-harris") return BlackmanHarrisWindow;
Chris@350 204
Chris@350 205 std::cerr << "WARNING: Window::getTypeForName: unknown name \""
Chris@350 206 << name << "\", defaulting to \"hanning\"" << std::endl;
Chris@350 207
Chris@350 208 return HanningWindow;
Chris@350 209 }
Chris@350 210
Chris@0 211 #endif