00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _WINDOW_H_
00017 #define _WINDOW_H_
00018
00019 #include <cmath>
00020 #include <iostream>
00021 #include <string>
00022 #include <map>
00023
00024 enum WindowType {
00025 RectangularWindow,
00026 BartlettWindow,
00027 HammingWindow,
00028 HanningWindow,
00029 BlackmanWindow,
00030 GaussianWindow,
00031 ParzenWindow,
00032 NuttallWindow,
00033 BlackmanHarrisWindow
00034 };
00035
00036 template <typename T>
00037 class Window
00038 {
00039 public:
00043 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
00044 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
00045 Window &operator=(const Window &w) {
00046 if (&w == this) return *this;
00047 m_type = w.m_type;
00048 m_size = w.m_size;
00049 encache();
00050 return *this;
00051 }
00052 virtual ~Window() { delete[] m_cache; }
00053
00054 void cut(T *src) const { cut(src, src); }
00055 void cut(T *src, T *dst) const {
00056 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
00057 }
00058
00059 T getArea() { return m_area; }
00060 T getValue(size_t i) { return m_cache[i]; }
00061
00062 WindowType getType() const { return m_type; }
00063 size_t getSize() const { return m_size; }
00064
00065
00066
00067
00068 static std::string getNameForType(WindowType type);
00069 static WindowType getTypeForName(std::string name);
00070
00071 protected:
00072 WindowType m_type;
00073 size_t m_size;
00074 T *m_cache;
00075 T m_area;
00076
00077 void encache();
00078 void cosinewin(T *, T, T, T, T);
00079 };
00080
00081 template <typename T>
00082 void Window<T>::encache()
00083 {
00084 int n = int(m_size);
00085 T *mult = new T[n];
00086 int i;
00087 for (i = 0; i < n; ++i) mult[i] = 1.0;
00088
00089 switch (m_type) {
00090
00091 case RectangularWindow:
00092 for (i = 0; i < n; ++i) {
00093 mult[i] *= 0.5;
00094 }
00095 break;
00096
00097 case BartlettWindow:
00098 for (i = 0; i < n/2; ++i) {
00099 mult[i] *= (i / T(n/2));
00100 mult[i + n/2] *= (1.0 - (i / T(n/2)));
00101 }
00102 break;
00103
00104 case HammingWindow:
00105 cosinewin(mult, 0.54, 0.46, 0.0, 0.0);
00106 break;
00107
00108 case HanningWindow:
00109 cosinewin(mult, 0.50, 0.50, 0.0, 0.0);
00110 break;
00111
00112 case BlackmanWindow:
00113 cosinewin(mult, 0.42, 0.50, 0.08, 0.0);
00114 break;
00115
00116 case GaussianWindow:
00117 for (i = 0; i < n; ++i) {
00118 mult[i] *= pow(2, - pow((i - (n-1)/2.0) / ((n-1)/2.0 / 3), 2));
00119 }
00120 break;
00121
00122 case ParzenWindow:
00123 {
00124 int N = n-1;
00125 for (i = 0; i < N/4; ++i) {
00126 T m = 2 * pow(1.0 - (T(N)/2 - i) / (T(N)/2), 3);
00127 mult[i] *= m;
00128 mult[N-i] *= m;
00129 }
00130 for (i = N/4; i <= N/2; ++i) {
00131 int wn = i - N/2;
00132 T m = 1.0 - 6 * pow(wn / (T(N)/2), 2) * (1.0 - abs(wn) / (T(N)/2));
00133 mult[i] *= m;
00134 mult[N-i] *= m;
00135 }
00136 break;
00137 }
00138
00139 case NuttallWindow:
00140 cosinewin(mult, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
00141 break;
00142
00143 case BlackmanHarrisWindow:
00144 cosinewin(mult, 0.35875, 0.48829, 0.14128, 0.01168);
00145 break;
00146 }
00147
00148 m_cache = mult;
00149
00150 m_area = 0;
00151 for (int i = 0; i < n; ++i) {
00152 m_area += m_cache[i];
00153 }
00154 m_area /= n;
00155 }
00156
00157 template <typename T>
00158 void Window<T>::cosinewin(T *mult, T a0, T a1, T a2, T a3)
00159 {
00160 int n = int(m_size);
00161 for (int i = 0; i < n; ++i) {
00162 mult[i] *= (a0
00163 - a1 * cos((2 * M_PI * i) / n)
00164 + a2 * cos((4 * M_PI * i) / n)
00165 - a3 * cos((6 * M_PI * i) / n));
00166 }
00167 }
00168
00169 template <typename T>
00170 std::string
00171 Window<T>::getNameForType(WindowType type)
00172 {
00173 switch (type) {
00174 case RectangularWindow: return "rectangular";
00175 case BartlettWindow: return "bartlett";
00176 case HammingWindow: return "hamming";
00177 case HanningWindow: return "hanning";
00178 case BlackmanWindow: return "blackman";
00179 case GaussianWindow: return "gaussian";
00180 case ParzenWindow: return "parzen";
00181 case NuttallWindow: return "nuttall";
00182 case BlackmanHarrisWindow: return "blackman-harris";
00183 }
00184
00185 std::cerr << "WARNING: Window::getNameForType: unknown type "
00186 << type << std::endl;
00187
00188 return "unknown";
00189 }
00190
00191 template <typename T>
00192 WindowType
00193 Window<T>::getTypeForName(std::string name)
00194 {
00195 if (name == "rectangular") return RectangularWindow;
00196 if (name == "bartlett") return BartlettWindow;
00197 if (name == "hamming") return HammingWindow;
00198 if (name == "hanning") return HanningWindow;
00199 if (name == "blackman") return BlackmanWindow;
00200 if (name == "gaussian") return GaussianWindow;
00201 if (name == "parzen") return ParzenWindow;
00202 if (name == "nuttall") return NuttallWindow;
00203 if (name == "blackman-harris") return BlackmanHarrisWindow;
00204
00205 std::cerr << "WARNING: Window::getTypeForName: unknown name \""
00206 << name << "\", defaulting to \"hanning\"" << std::endl;
00207
00208 return HanningWindow;
00209 }
00210
00211 #endif