annotate base/Window.h @ 298:255e431ae3d4

* Key detector: when returning key strengths, use the peak value of the three underlying chromagram correlations (from 36-bin chromagram) corresponding to each key, instead of the mean. Rationale: This is the same method as used when returning the key value, and it's nice to have the same results in both returned value and plot. The peak performed better than the sum with a simple test set of triads, so it seems reasonable to change the plot to match the key output rather than the other way around. * FFT: kiss_fftr returns only the non-conjugate bins, synthesise the rest rather than leaving them (perhaps dangerously) undefined. Fixes an uninitialised data error in chromagram that could cause garbage results from key detector. * Constant Q: remove precalculated values again, I reckon they're not proving such a good tradeoff.
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 05 Jun 2009 15:12:39 +0000
parents 9c403afdd9e9
children e5907ae6de17
rev   line source
c@225 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@225 2
c@225 3 /*
c@225 4 QM DSP library
c@225 5 Centre for Digital Music, Queen Mary, University of London.
c@225 6 This file Copyright 2006 Chris Cannam.
c@225 7 All rights reserved.
c@225 8 */
c@225 9
c@225 10 #ifndef _WINDOW_H_
c@225 11 #define _WINDOW_H_
c@225 12
c@225 13 #include <cmath>
c@225 14 #include <iostream>
c@225 15 #include <map>
c@225 16
c@225 17 enum WindowType {
c@225 18 RectangularWindow,
c@225 19 BartlettWindow,
c@225 20 HammingWindow,
c@225 21 HanningWindow,
c@225 22 BlackmanWindow,
c@225 23 GaussianWindow,
c@225 24 ParzenWindow
c@225 25 };
c@225 26
c@225 27 template <typename T>
c@225 28 class Window
c@225 29 {
c@225 30 public:
c@225 31 /**
c@225 32 * Construct a windower of the given type.
c@225 33 */
c@225 34 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }
c@225 35 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); }
c@225 36 Window &operator=(const Window &w) {
c@225 37 if (&w == this) return *this;
c@225 38 m_type = w.m_type;
c@225 39 m_size = w.m_size;
c@225 40 encache();
c@225 41 return *this;
c@225 42 }
c@251 43 virtual ~Window() { delete[] m_cache; }
c@225 44
c@225 45 void cut(T *src) const { cut(src, src); }
c@280 46 void cut(const T *src, T *dst) const {
c@225 47 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i];
c@225 48 }
c@225 49
c@225 50 WindowType getType() const { return m_type; }
c@225 51 size_t getSize() const { return m_size; }
c@225 52
c@225 53 protected:
c@225 54 WindowType m_type;
c@225 55 size_t m_size;
c@225 56 T *m_cache;
c@225 57
c@225 58 void encache();
c@225 59 };
c@225 60
c@225 61 template <typename T>
c@225 62 void Window<T>::encache()
c@225 63 {
c@225 64 size_t n = m_size;
c@225 65 T *mult = new T[n];
c@225 66 size_t i;
c@225 67 for (i = 0; i < n; ++i) mult[i] = 1.0;
c@225 68
c@225 69 switch (m_type) {
c@225 70
c@225 71 case RectangularWindow:
c@225 72 for (i = 0; i < n; ++i) {
c@225 73 mult[i] = mult[i] * 0.5;
c@225 74 }
c@225 75 break;
c@225 76
c@225 77 case BartlettWindow:
c@225 78 for (i = 0; i < n/2; ++i) {
c@225 79 mult[i] = mult[i] * (i / T(n/2));
c@225 80 mult[i + n/2] = mult[i + n/2] * (1.0 - (i / T(n/2)));
c@225 81 }
c@225 82 break;
c@225 83
c@225 84 case HammingWindow:
c@225 85 for (i = 0; i < n; ++i) {
c@225 86 mult[i] = mult[i] * (0.54 - 0.46 * cos(2 * M_PI * i / n));
c@225 87 }
c@225 88 break;
c@225 89
c@225 90 case HanningWindow:
c@225 91 for (i = 0; i < n; ++i) {
c@225 92 mult[i] = mult[i] * (0.50 - 0.50 * cos(2 * M_PI * i / n));
c@225 93 }
c@225 94 break;
c@225 95
c@225 96 case BlackmanWindow:
c@225 97 for (i = 0; i < n; ++i) {
c@225 98 mult[i] = mult[i] * (0.42 - 0.50 * cos(2 * M_PI * i / n)
c@225 99 + 0.08 * cos(4 * M_PI * i / n));
c@225 100 }
c@225 101 break;
c@225 102
c@225 103 case GaussianWindow:
c@225 104 for (i = 0; i < n; ++i) {
c@225 105 mult[i] = mult[i] * exp((-1.0 / (n*n)) * ((T(2*i) - n) *
c@225 106 (T(2*i) - n)));
c@225 107 }
c@225 108 break;
c@225 109
c@225 110 case ParzenWindow:
c@225 111 for (i = 0; i < n; ++i) {
c@225 112 mult[i] = mult[i] * (1.0 - fabs((T(2*i) - n) / T(n + 1)));
c@225 113 }
c@225 114 break;
c@225 115 }
c@225 116
c@225 117 m_cache = mult;
c@225 118 }
c@225 119
c@225 120 #endif