annotate base/Window.h @ 142:0ba66b160a02

* Add frequency plot to window shape preference -- just because... * Fix some window shapes
author Chris Cannam
date Mon, 24 Jul 2006 14:36:35 +0000
parents 4f26f623a8bc
children 3fe6660f8fe2
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@140 58 T getValue(size_t i) { return m_cache[i]; }
Chris@140 59
Chris@0 60 WindowType getType() const { return m_type; }
Chris@0 61 size_t getSize() const { return m_size; }
Chris@0 62
Chris@0 63 protected:
Chris@0 64 WindowType m_type;
Chris@0 65 size_t m_size;
Chris@0 66 T *m_cache;
Chris@0 67
Chris@0 68 void encache();
Chris@142 69 void cosinewin(T *, T, T, T, T);
Chris@0 70 };
Chris@0 71
Chris@0 72 template <typename T>
Chris@0 73 void Window<T>::encache()
Chris@0 74 {
Chris@141 75 int n = int(m_size);
Chris@0 76 T *mult = new T[n];
Chris@141 77 int i;
Chris@0 78 for (i = 0; i < n; ++i) mult[i] = 1.0;
Chris@0 79
Chris@0 80 switch (m_type) {
Chris@0 81
Chris@0 82 case RectangularWindow:
Chris@0 83 for (i = 0; i < n; ++i) {
Chris@141 84 mult[i] *= 0.5;
Chris@0 85 }
Chris@0 86 break;
Chris@0 87
Chris@0 88 case BartlettWindow:
Chris@0 89 for (i = 0; i < n/2; ++i) {
Chris@141 90 mult[i] *= (i / T(n/2));
Chris@141 91 mult[i + n/2] *= (1.0 - (i / T(n/2)));
Chris@0 92 }
Chris@0 93 break;
Chris@0 94
Chris@0 95 case HammingWindow:
Chris@142 96 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
Chris@0 97 break;
Chris@0 98
Chris@0 99 case HanningWindow:
Chris@142 100 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
Chris@0 101 break;
Chris@0 102
Chris@0 103 case BlackmanWindow:
Chris@142 104 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
Chris@0 105 break;
Chris@0 106
Chris@0 107 case GaussianWindow:
Chris@0 108 for (i = 0; i < n; ++i) {
Chris@142 109 mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
Chris@0 110 }
Chris@0 111 break;
Chris@0 112
Chris@0 113 case ParzenWindow:
Chris@141 114 {
Chris@141 115 int N = n-1;
Chris@141 116 for (i = 0; i < N/4; ++i) {
Chris@141 117 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
Chris@141 118 mult[i] *= m;
Chris@141 119 mult[N-i] *= m;
Chris@141 120 }
Chris@141 121 for (i = N/4; i <= N/2; ++i) {
Chris@141 122 int wn = i - N/2;
Chris@141 123 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
Chris@141 124 mult[i] *= m;
Chris@141 125 mult[N-i] *= m;
Chris@141 126 }
Chris@142 127 break;
Chris@142 128 }
Chris@142 129
Chris@142 130 case NuttallWindow:
Chris@142 131 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
Chris@0 132 break;
Chris@142 133
Chris@142 134 case BlackmanHarrisWindow:
Chris@142 135 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
Chris@142 136 break;
Chris@0 137 }
Chris@0 138
Chris@0 139 m_cache = mult;
Chris@0 140 }
Chris@0 141
Chris@142 142 template <typename T>
Chris@142 143 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
Chris@142 144 {
Chris@142 145 int n = int(m_size);
Chris@142 146 for (int i = 0; i < n; ++i) {
Chris@142 147 mult[i] *= (a0
Chris@142 148 - a1 * cos(2 * M_PI * i / n)
Chris@142 149 + a2 * cos(4 * M_PI * i / n)
Chris@142 150 - a3 * cos(6 * M_PI * i / n));
Chris@142 151 }
Chris@142 152 }
Chris@142 153
Chris@0 154 #endif