annotate src/rubberband-1.8.1/src/dsp/Window.h @ 95:89f5e221ed7b

Add FFTW3
author Chris Cannam <cannam@all-day-breakfast.com>
date Wed, 20 Mar 2013 15:35:50 +0000
parents
children
rev   line source
cannam@95 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@95 2
cannam@95 3 /*
cannam@95 4 Rubber Band Library
cannam@95 5 An audio time-stretching and pitch-shifting library.
cannam@95 6 Copyright 2007-2012 Particular Programs Ltd.
cannam@95 7
cannam@95 8 This program is free software; you can redistribute it and/or
cannam@95 9 modify it under the terms of the GNU General Public License as
cannam@95 10 published by the Free Software Foundation; either version 2 of the
cannam@95 11 License, or (at your option) any later version. See the file
cannam@95 12 COPYING included with this distribution for more information.
cannam@95 13
cannam@95 14 Alternatively, if you have a valid commercial licence for the
cannam@95 15 Rubber Band Library obtained by agreement with the copyright
cannam@95 16 holders, you may redistribute and/or modify it under the terms
cannam@95 17 described in that licence.
cannam@95 18
cannam@95 19 If you wish to distribute code using the Rubber Band Library
cannam@95 20 under terms other than those of the GNU General Public License,
cannam@95 21 you must obtain a valid commercial licence before doing so.
cannam@95 22 */
cannam@95 23
cannam@95 24 #ifndef _RUBBERBAND_WINDOW_H_
cannam@95 25 #define _RUBBERBAND_WINDOW_H_
cannam@95 26
cannam@95 27 #include <cmath>
cannam@95 28 #include <cstdlib>
cannam@95 29 #include <map>
cannam@95 30
cannam@95 31 #include "system/sysutils.h"
cannam@95 32 #include "system/VectorOps.h"
cannam@95 33 #include "system/Allocators.h"
cannam@95 34
cannam@95 35 namespace RubberBand {
cannam@95 36
cannam@95 37 enum WindowType {
cannam@95 38 RectangularWindow,
cannam@95 39 BartlettWindow,
cannam@95 40 HammingWindow,
cannam@95 41 HanningWindow,
cannam@95 42 BlackmanWindow,
cannam@95 43 GaussianWindow,
cannam@95 44 ParzenWindow,
cannam@95 45 NuttallWindow,
cannam@95 46 BlackmanHarrisWindow
cannam@95 47 };
cannam@95 48
cannam@95 49 template <typename T>
cannam@95 50 class Window
cannam@95 51 {
cannam@95 52 public:
cannam@95 53 /**
cannam@95 54 * Construct a windower of the given type.
cannam@95 55 */
cannam@95 56 Window(WindowType type, int size) : m_type(type), m_size(size), m_cache(0) {
cannam@95 57 encache();
cannam@95 58 }
cannam@95 59 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size), m_cache(0) {
cannam@95 60 encache();
cannam@95 61 }
cannam@95 62 Window &operator=(const Window &w) {
cannam@95 63 if (&w == this) return *this;
cannam@95 64 m_type = w.m_type;
cannam@95 65 m_size = w.m_size;
cannam@95 66 m_cache = 0;
cannam@95 67 encache();
cannam@95 68 return *this;
cannam@95 69 }
cannam@95 70 virtual ~Window() {
cannam@95 71 deallocate(m_cache);
cannam@95 72 }
cannam@95 73
cannam@95 74 inline void cut(T *const R__ block) const {
cannam@95 75 v_multiply(block, m_cache, m_size);
cannam@95 76 }
cannam@95 77
cannam@95 78 inline void cut(const T *const R__ src, T *const R__ dst) const {
cannam@95 79 v_multiply(dst, src, m_cache, m_size);
cannam@95 80 }
cannam@95 81
cannam@95 82 inline void add(T *const R__ dst, T scale) const {
cannam@95 83 v_add_with_gain(dst, m_cache, m_size, scale);
cannam@95 84 }
cannam@95 85
cannam@95 86 inline T getRMS() const {
cannam@95 87 T total = 0;
cannam@95 88 for (int i = 0; i < m_size; ++i) {
cannam@95 89 total += m_cache[i] * m_cache[i];
cannam@95 90 }
cannam@95 91 T rms = sqrt(total / m_size);
cannam@95 92 return rms;
cannam@95 93 }
cannam@95 94
cannam@95 95 inline T getArea() const { return m_area; }
cannam@95 96 inline T getValue(int i) const { return m_cache[i]; }
cannam@95 97
cannam@95 98 inline WindowType getType() const { return m_type; }
cannam@95 99 inline int getSize() const { return m_size; }
cannam@95 100
cannam@95 101 protected:
cannam@95 102 WindowType m_type;
cannam@95 103 int m_size;
cannam@95 104 T *R__ m_cache;
cannam@95 105 T m_area;
cannam@95 106
cannam@95 107 void encache();
cannam@95 108 void cosinewin(T *, T, T, T, T);
cannam@95 109 };
cannam@95 110
cannam@95 111 template <typename T>
cannam@95 112 void Window<T>::encache()
cannam@95 113 {
cannam@95 114 if (!m_cache) m_cache = allocate<T>(m_size);
cannam@95 115
cannam@95 116 const int n = m_size;
cannam@95 117 v_set(m_cache, T(1.0), n);
cannam@95 118 int i;
cannam@95 119
cannam@95 120 switch (m_type) {
cannam@95 121
cannam@95 122 case RectangularWindow:
cannam@95 123 for (i = 0; i < n; ++i) {
cannam@95 124 m_cache[i] *= 0.5;
cannam@95 125 }
cannam@95 126 break;
cannam@95 127
cannam@95 128 case BartlettWindow:
cannam@95 129 for (i = 0; i < n/2; ++i) {
cannam@95 130 m_cache[i] *= (i / T(n/2));
cannam@95 131 m_cache[i + n/2] *= (1.0 - (i / T(n/2)));
cannam@95 132 }
cannam@95 133 break;
cannam@95 134
cannam@95 135 case HammingWindow:
cannam@95 136 cosinewin(m_cache, 0.54, 0.46, 0.0, 0.0);
cannam@95 137 break;
cannam@95 138
cannam@95 139 case HanningWindow:
cannam@95 140 cosinewin(m_cache, 0.50, 0.50, 0.0, 0.0);
cannam@95 141 break;
cannam@95 142
cannam@95 143 case BlackmanWindow:
cannam@95 144 cosinewin(m_cache, 0.42, 0.50, 0.08, 0.0);
cannam@95 145 break;
cannam@95 146
cannam@95 147 case GaussianWindow:
cannam@95 148 for (i = 0; i < n; ++i) {
cannam@95 149 m_cache[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
cannam@95 150 }
cannam@95 151 break;
cannam@95 152
cannam@95 153 case ParzenWindow:
cannam@95 154 {
cannam@95 155 int N = n-1;
cannam@95 156 for (i = 0; i < N/4; ++i) {
cannam@95 157 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
cannam@95 158 m_cache[i] *= m;
cannam@95 159 m_cache[N-i] *= m;
cannam@95 160 }
cannam@95 161 for (i = N/4; i <= N/2; ++i) {
cannam@95 162 int wn = i - N/2;
cannam@95 163 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
cannam@95 164 m_cache[i] *= m;
cannam@95 165 m_cache[N-i] *= m;
cannam@95 166 }
cannam@95 167 break;
cannam@95 168 }
cannam@95 169
cannam@95 170 case NuttallWindow:
cannam@95 171 cosinewin(m_cache, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
cannam@95 172 break;
cannam@95 173
cannam@95 174 case BlackmanHarrisWindow:
cannam@95 175 cosinewin(m_cache, 0.35875, 0.48829, 0.14128, 0.01168);
cannam@95 176 break;
cannam@95 177 }
cannam@95 178
cannam@95 179 m_area = 0;
cannam@95 180 for (i = 0; i < n; ++i) {
cannam@95 181 m_area += m_cache[i];
cannam@95 182 }
cannam@95 183 m_area /= n;
cannam@95 184 }
cannam@95 185
cannam@95 186 template <typename T>
cannam@95 187 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
cannam@95 188 {
cannam@95 189 int n = int(m_size);
cannam@95 190 for (int i = 0; i < n; ++i) {
cannam@95 191 mult[i] *= (a0
cannam@95 192 - a1 * cos(2 * M_PI * i / n)
cannam@95 193 + a2 * cos(4 * M_PI * i / n)
cannam@95 194 - a3 * cos(6 * M_PI * i / n));
cannam@95 195 }
cannam@95 196 }
cannam@95 197
cannam@95 198 }
cannam@95 199
cannam@95 200 #endif