To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
The primary repository for this project is hosted at https://github.com/cannam/constant-q-cpp/ .
This repository is a read-only copy which is updated automatically every hour.
root / test / TestWindow.cpp
History | View | Annotate | Download (4.68 KB)
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
|---|---|
| 2 |
|
| 3 |
#include "dsp/Window.h" |
| 4 |
#include "dsp/KaiserWindow.h" |
| 5 |
#include "dsp/SincWindow.h" |
| 6 |
|
| 7 |
#include <iostream> |
| 8 |
|
| 9 |
#define BOOST_TEST_DYN_LINK
|
| 10 |
#define BOOST_TEST_MAIN
|
| 11 |
|
| 12 |
#include <boost/test/unit_test.hpp> |
| 13 |
|
| 14 |
BOOST_AUTO_TEST_SUITE(TestWindow) |
| 15 |
|
| 16 |
using std::cout;
|
| 17 |
using std::endl;
|
| 18 |
|
| 19 |
#define COMPARE_ARRAY(a, b) \
|
| 20 |
for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ |
| 21 |
BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-4); \ |
| 22 |
} |
| 23 |
|
| 24 |
void
|
| 25 |
testSymmetric(double *d, int n) |
| 26 |
{
|
| 27 |
for (int i = 0; i <= n/2; ++i) { |
| 28 |
BOOST_CHECK_CLOSE(d[i], d[n-i-1], 1e-10); |
| 29 |
} |
| 30 |
} |
| 31 |
|
| 32 |
BOOST_AUTO_TEST_CASE(periodic) |
| 33 |
{
|
| 34 |
// We can't actually test whether a function is periodic, given
|
| 35 |
// only one cycle of it! But we can make sure that all but the
|
| 36 |
// first sample is symmetric, which is what a symmetric window
|
| 37 |
// becomes when generated in periodic mode
|
| 38 |
double d[9]; |
| 39 |
for (int n = 8; n <= 9; ++n) { |
| 40 |
for (int wt = (int)FirstWindow; wt <= (int)LastWindow; ++wt) { |
| 41 |
for (int i = 0; i < n; ++i) d[i] = 1.0; |
| 42 |
Window<double> w((WindowType)wt, n);
|
| 43 |
w.cut(d); |
| 44 |
testSymmetric(d + 1, n - 1); |
| 45 |
} |
| 46 |
} |
| 47 |
} |
| 48 |
|
| 49 |
template <int N> |
| 50 |
void testWindow(WindowType type, const double expected[N]) |
| 51 |
{
|
| 52 |
double d[N];
|
| 53 |
for (int i = 0; i < N; ++i) d[i] = 1.0; |
| 54 |
Window<double> w(type, N);
|
| 55 |
w.cut(d); |
| 56 |
COMPARE_ARRAY(d, expected); |
| 57 |
|
| 58 |
double d0[N], d1[N];
|
| 59 |
for (int i = 0; i < N; ++i) d0[i] = 0.5 + (1.0 / (N * 2)) * (i + 1); |
| 60 |
w.cut(d0, d1); |
| 61 |
for (int i = 0; i < N; ++i) { |
| 62 |
BOOST_CHECK_SMALL(d1[i] - d0[i] * expected[i], 1e-4); |
| 63 |
} |
| 64 |
} |
| 65 |
|
| 66 |
BOOST_AUTO_TEST_CASE(bartlett) |
| 67 |
{
|
| 68 |
double e1[] = { 1 }; |
| 69 |
testWindow<1>(BartlettWindow, e1);
|
| 70 |
|
| 71 |
double e2[] = { 0, 0 }; |
| 72 |
testWindow<2>(BartlettWindow, e2);
|
| 73 |
|
| 74 |
double e3[] = { 0, 2./3., 2./3. }; |
| 75 |
testWindow<3>(BartlettWindow, e3);
|
| 76 |
|
| 77 |
double e4[] = { 0, 1./2., 1., 1./2. }; |
| 78 |
testWindow<4>(BartlettWindow, e4);
|
| 79 |
|
| 80 |
double e5[] = { 0, 1./2., 1., 1., 1./2. }; |
| 81 |
testWindow<5>(BartlettWindow, e5);
|
| 82 |
|
| 83 |
double e6[] = { 0, 1./3., 2./3., 1., 2./3., 1./3. }; |
| 84 |
testWindow<6>(BartlettWindow, e6);
|
| 85 |
} |
| 86 |
|
| 87 |
BOOST_AUTO_TEST_CASE(hamming) |
| 88 |
{
|
| 89 |
double e1[] = { 1 }; |
| 90 |
testWindow<1>(HammingWindow, e1);
|
| 91 |
|
| 92 |
double e10[] = {
|
| 93 |
0.0800, 0.1679, 0.3979, 0.6821, 0.9121, |
| 94 |
1.0000, 0.9121, 0.6821, 0.3979, 0.1679 |
| 95 |
}; |
| 96 |
testWindow<10>(HammingWindow, e10);
|
| 97 |
} |
| 98 |
|
| 99 |
BOOST_AUTO_TEST_CASE(hann) |
| 100 |
{
|
| 101 |
double e1[] = { 1 }; |
| 102 |
testWindow<1>(HanningWindow, e1);
|
| 103 |
|
| 104 |
double e10[] = {
|
| 105 |
0, 0.0955, 0.3455, 0.6545, 0.9045, |
| 106 |
1.0000, 0.9045, 0.6545, 0.3455, 0.0955, |
| 107 |
}; |
| 108 |
testWindow<10>(HanningWindow, e10);
|
| 109 |
} |
| 110 |
|
| 111 |
BOOST_AUTO_TEST_CASE(blackman) |
| 112 |
{
|
| 113 |
double e1[] = { 1 }; |
| 114 |
testWindow<1>(BlackmanWindow, e1);
|
| 115 |
|
| 116 |
double e10[] = {
|
| 117 |
0, 0.0402, 0.2008, 0.5098, 0.8492, |
| 118 |
1.0000, 0.8492, 0.5098, 0.2008, 0.0402, |
| 119 |
}; |
| 120 |
testWindow<10>(BlackmanWindow, e10);
|
| 121 |
} |
| 122 |
|
| 123 |
BOOST_AUTO_TEST_CASE(blackmanHarris) |
| 124 |
{
|
| 125 |
double e1[] = { 1 }; |
| 126 |
testWindow<1>(BlackmanHarrisWindow, e1);
|
| 127 |
|
| 128 |
double e10[] = {
|
| 129 |
0.0001, 0.0110, 0.1030, 0.3859, 0.7938, |
| 130 |
1.0000, 0.7938, 0.3859, 0.1030, 0.0110, |
| 131 |
}; |
| 132 |
testWindow<10>(BlackmanHarrisWindow, e10);
|
| 133 |
} |
| 134 |
|
| 135 |
BOOST_AUTO_TEST_CASE(kaiser_4_10) |
| 136 |
{
|
| 137 |
double d[10]; |
| 138 |
for (int i = 0; i < 10; ++i) d[i] = 1.0; |
| 139 |
double e[] = {
|
| 140 |
0.0885, 0.2943, 0.5644, 0.8216, 0.9789, |
| 141 |
0.9789, 0.8216, 0.5644, 0.2943, 0.0885 |
| 142 |
}; |
| 143 |
KaiserWindow::Parameters p; |
| 144 |
p.length = 10;
|
| 145 |
p.beta = 4;
|
| 146 |
KaiserWindow k(p); |
| 147 |
k.cut(d); |
| 148 |
COMPARE_ARRAY(d, e); |
| 149 |
} |
| 150 |
|
| 151 |
BOOST_AUTO_TEST_CASE(kaiser_2p5_11) |
| 152 |
{
|
| 153 |
double d[11]; |
| 154 |
for (int i = 0; i < 11; ++i) d[i] = 1.0; |
| 155 |
double e[] = {
|
| 156 |
0.3040, 0.5005, 0.6929, 0.8546, 0.9622, |
| 157 |
1.0000, 0.9622, 0.8546, 0.6929, 0.5005, 0.3040 |
| 158 |
}; |
| 159 |
KaiserWindow::Parameters p; |
| 160 |
p.length = 11;
|
| 161 |
p.beta = 2.5; |
| 162 |
KaiserWindow k(p); |
| 163 |
k.cut(d); |
| 164 |
COMPARE_ARRAY(d, e); |
| 165 |
} |
| 166 |
|
| 167 |
//!!! todo: tests for kaiser with attenuation and bandwidth parameters
|
| 168 |
|
| 169 |
template <int N> |
| 170 |
void testSinc(double p, const double expected[N]) |
| 171 |
{
|
| 172 |
double d[N];
|
| 173 |
for (int i = 0; i < N; ++i) d[i] = 1.0; |
| 174 |
SincWindow w(N, p); |
| 175 |
w.cut(d); |
| 176 |
COMPARE_ARRAY(d, expected); |
| 177 |
|
| 178 |
double d0[N], d1[N];
|
| 179 |
for (int i = 0; i < N; ++i) d0[i] = 0.5 + (1.0 / (N * 2)) * (i + 1); |
| 180 |
w.cut(d0, d1); |
| 181 |
for (int i = 0; i < N; ++i) { |
| 182 |
BOOST_CHECK_SMALL(d1[i] - d0[i] * expected[i], 1e-4); |
| 183 |
} |
| 184 |
} |
| 185 |
|
| 186 |
BOOST_AUTO_TEST_CASE(sinc) |
| 187 |
{
|
| 188 |
double e1[] = { 0, 0, 1, 0, 0 }; |
| 189 |
testSinc<5>(1, e1); |
| 190 |
|
| 191 |
double e2[] = { 0, 0, 1, 0, 0 }; |
| 192 |
testSinc<5>(2, e2); |
| 193 |
|
| 194 |
double e3[] = { -0.2122, 0.0, 0.6366, 1.0, 0.6366, 0, -0.2122 }; |
| 195 |
testSinc<7>(4, e3); |
| 196 |
|
| 197 |
double e4[] = { -0.2122, 0, 0.6366, 1, 0.6366, 0 }; |
| 198 |
testSinc<6>(4, e4); |
| 199 |
} |
| 200 |
|
| 201 |
BOOST_AUTO_TEST_SUITE_END() |
| 202 |
|