annotate base/Window.h @ 167:665342c6ec57

* Add a bit of resistance to pane dragging so as to make it harder to inadvertently drag in the other axis from the one you intended
author Chris Cannam
date Fri, 22 Sep 2006 16:46:10 +0000
parents 3fe6660f8fe2
children 524bcd89743b
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@0 21 #include <map>
Chris@0 22
Chris@0 23 enum WindowType {
Chris@0 24 RectangularWindow,
Chris@0 25 BartlettWindow,
Chris@0 26 HammingWindow,
Chris@0 27 HanningWindow,
Chris@0 28 BlackmanWindow,
Chris@0 29 GaussianWindow,
Chris@142 30 ParzenWindow,
Chris@142 31 NuttallWindow,
Chris@142 32 BlackmanHarrisWindow
Chris@0 33 };
Chris@0 34
Chris@0 35 template <typename T>
Chris@0 36 class Window
Chris@0 37 {
Chris@0 38 public:
Chris@0 39 /**
Chris@0 40 * Construct a windower of the given type.
Chris@0 41 */
Chris@0 42 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
Chris@0 43 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
Chris@0 44 Window &operator=(const Window &w) {
Chris@52 45 if (&w == this) return *this;
Chris@0 46 m_type = w.m_type;
Chris@0 47 m_size = w.m_size;
Chris@0 48 encache();
Chris@0 49 return *this;
Chris@0 50 }
Chris@142 51 virtual ~Window() { delete[] m_cache; }
Chris@0 52
Chris@0 53 void cut(T *src) const { cut(src, src); }
Chris@0 54 void cut(T *src, T *dst) const {
Chris@0 55 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
Chris@0 56 }
Chris@0 57
Chris@162 58 T getArea() { return m_area; }
Chris@140 59 T getValue(size_t i) { return m_cache[i]; }
Chris@140 60
Chris@0 61 WindowType getType() const { return m_type; }
Chris@0 62 size_t getSize() const { return m_size; }
Chris@0 63
Chris@0 64 protected:
Chris@0 65 WindowType m_type;
Chris@0 66 size_t m_size;
Chris@0 67 T *m_cache;
Chris@162 68 T m_area;
Chris@0 69
Chris@0 70 void encache();
Chris@142 71 void cosinewin(T *, T, T, T, T);
Chris@0 72 };
Chris@0 73
Chris@0 74 template <typename T>
Chris@0 75 void Window<T>::encache()
Chris@0 76 {
Chris@141 77 int n = int(m_size);
Chris@0 78 T *mult = new T[n];
Chris@141 79 int i;
Chris@0 80 for (i = 0; i < n; ++i) mult[i] = 1.0;
Chris@0 81
Chris@0 82 switch (m_type) {
Chris@0 83
Chris@0 84 case RectangularWindow:
Chris@0 85 for (i = 0; i < n; ++i) {
Chris@141 86 mult[i] *= 0.5;
Chris@0 87 }
Chris@0 88 break;
Chris@0 89
Chris@0 90 case BartlettWindow:
Chris@0 91 for (i = 0; i < n/2; ++i) {
Chris@141 92 mult[i] *= (i / T(n/2));
Chris@141 93 mult[i + n/2] *= (1.0 - (i / T(n/2)));
Chris@0 94 }
Chris@0 95 break;
Chris@0 96
Chris@0 97 case HammingWindow:
Chris@142 98 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
Chris@0 99 break;
Chris@0 100
Chris@0 101 case HanningWindow:
Chris@142 102 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
Chris@0 103 break;
Chris@0 104
Chris@0 105 case BlackmanWindow:
Chris@142 106 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
Chris@0 107 break;
Chris@0 108
Chris@0 109 case GaussianWindow:
Chris@0 110 for (i = 0; i < n; ++i) {
Chris@142 111 mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
Chris@0 112 }
Chris@0 113 break;
Chris@0 114
Chris@0 115 case ParzenWindow:
Chris@141 116 {
Chris@141 117 int N = n-1;
Chris@141 118 for (i = 0; i < N/4; ++i) {
Chris@141 119 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
Chris@141 120 mult[i] *= m;
Chris@141 121 mult[N-i] *= m;
Chris@141 122 }
Chris@141 123 for (i = N/4; i <= N/2; ++i) {
Chris@141 124 int wn = i - N/2;
Chris@141 125 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
Chris@141 126 mult[i] *= m;
Chris@141 127 mult[N-i] *= m;
Chris@141 128 }
Chris@142 129 break;
Chris@142 130 }
Chris@142 131
Chris@142 132 case NuttallWindow:
Chris@142 133 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
Chris@0 134 break;
Chris@142 135
Chris@142 136 case BlackmanHarrisWindow:
Chris@142 137 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
Chris@142 138 break;
Chris@0 139 }
Chris@0 140
Chris@0 141 m_cache = mult;
Chris@162 142
Chris@162 143 m_area = 0;
Chris@162 144 for (int i = 0; i < n; ++i) {
Chris@162 145 m_area += m_cache[i];
Chris@162 146 }
Chris@162 147 m_area /= n;
Chris@0 148 }
Chris@0 149
Chris@142 150 template <typename T>
Chris@142 151 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
Chris@142 152 {
Chris@142 153 int n = int(m_size);
Chris@142 154 for (int i = 0; i < n; ++i) {
Chris@142 155 mult[i] *= (a0
Chris@142 156 - a1 * cos(2 * M_PI * i / n)
Chris@142 157 + a2 * cos(4 * M_PI * i / n)
Chris@142 158 - a3 * cos(6 * M_PI * i / n));
Chris@142 159 }
Chris@142 160 }
Chris@142 161
Chris@0 162 #endif