Window.h

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
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     // The names used by these functions are un-translated, for use in
00066     // e.g. XML I/O.  Use Preferences::getPropertyValueLabel if you
00067     // want translated names for use in the user interface.
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

Generated on Wed Feb 20 15:45:30 2008 for SonicVisualiser by  doxygen 1.5.1