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.

Statistics Download as Zip
| Branch: | Revision:

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