To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / test / TestFFT.cpp @ 48:1343ecde267e

History | View | Annotate | Download (5.86 KB)

1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
/*
3
  This file is Copyright (c) 2012 Chris Cannam
4
  
5
  Permission is hereby granted, free of charge, to any person
6
  obtaining a copy of this software and associated documentation
7
  files (the "Software"), to deal in the Software without
8
  restriction, including without limitation the rights to use, copy,
9
  modify, merge, publish, distribute, sublicense, and/or sell copies
10
  of the Software, and to permit persons to whom the Software is
11
  furnished to do so, subject to the following conditions:
12

13
  The above copyright notice and this permission notice shall be
14
  included in all copies or substantial portions of the Software.
15

16
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
20
  ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21
  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
*/
24

    
25
/*
26
  This unit test suite for the Vamp SDK FFT implementation is included
27
  here mostly for illustrative purposes!
28
*/
29

    
30
#include "vamp-sdk/FFT.h"
31

    
32
#define BOOST_TEST_DYN_LINK
33
#define BOOST_TEST_MAIN
34

    
35
#include <boost/test/unit_test.hpp>
36

    
37
BOOST_AUTO_TEST_SUITE(TestFFT)
38

    
39
#define COMPARE_CONST(a, n) \
40
    for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
41
        BOOST_CHECK_EQUAL(a[cmp_i] + 1.1, n + 1.1); \
42
    }
43

    
44
#define COMPARE_ARRAY(a, b)                                                \
45
    for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
46
        BOOST_CHECK_EQUAL(a[cmp_i] + 1.1, b[cmp_i] + 1.1); \
47
    }
48

    
49
BOOST_AUTO_TEST_CASE(dc)
50
{
51
    // DC-only signal. The DC bin is purely real
52
    double in[] = { 1, 1, 1, 1 };
53
    double re[4], im[4];
54
    Vamp::FFT::forward(4, in, 0, re, im);
55
    BOOST_CHECK_EQUAL(re[0], 4.0);
56
    BOOST_CHECK_EQUAL(re[1], 0.0);
57
    BOOST_CHECK_EQUAL(re[2], 0.0);
58
    COMPARE_CONST(im, 0.0);
59
    double back[4];
60
    double backim[4];
61
    Vamp::FFT::inverse(4, re, im, back, backim);
62
    COMPARE_ARRAY(back, in);
63
}
64

    
65
BOOST_AUTO_TEST_CASE(sine)
66
{
67
    // Sine. Output is purely imaginary
68
    double in[] = { 0, 1, 0, -1 };
69
    double re[4], im[4];
70
    Vamp::FFT::forward(4, in, 0, re, im);
71
    COMPARE_CONST(re, 0.0);
72
    BOOST_CHECK_EQUAL(im[0], 0.0);
73
    BOOST_CHECK_EQUAL(im[1], -2.0);
74
    BOOST_CHECK_EQUAL(im[2], 0.0);
75
    double back[4];
76
    double backim[4];
77
    Vamp::FFT::inverse(4, re, im, back, backim);
78
    COMPARE_ARRAY(back, in);
79
}
80

    
81
BOOST_AUTO_TEST_CASE(cosine)
82
{
83
    // Cosine. Output is purely real
84
    double in[] = { 1, 0, -1, 0 };
85
    double re[4], im[4];
86
    Vamp::FFT::forward(4, in, 0, re, im);
87
    BOOST_CHECK_EQUAL(re[0], 0.0);
88
    BOOST_CHECK_EQUAL(re[1], 2.0);
89
    BOOST_CHECK_EQUAL(re[2], 0.0);
90
    COMPARE_CONST(im, 0.0);
91
    double back[4];
92
    double backim[4];
93
    Vamp::FFT::inverse(4, re, im, back, backim);
94
    COMPARE_ARRAY(back, in);
95
}
96
        
97
BOOST_AUTO_TEST_CASE(sineCosine)
98
{
99
    // Sine and cosine mixed
100
    double in[] = { 0.5, 1, -0.5, -1 };
101
    double re[4], im[4];
102
    Vamp::FFT::forward(4, in, 0, re, im);
103
    BOOST_CHECK_EQUAL(re[0], 0.0);
104
    BOOST_CHECK_EQUAL(re[1], 1.0);
105
    BOOST_CHECK_EQUAL(re[2], 0.0);
106
    BOOST_CHECK_EQUAL(im[0], 0.0);
107
    BOOST_CHECK_EQUAL(im[1], -2.0);
108
    BOOST_CHECK_EQUAL(im[2], 0.0);
109
    double back[4];
110
    double backim[4];
111
    Vamp::FFT::inverse(4, re, im, back, backim);
112
    COMPARE_ARRAY(back, in);
113
}
114

    
115
BOOST_AUTO_TEST_CASE(sineCosineDC)
116
{
117
    // Sine and cosine mixed
118
    double in[] = { 0.5, 1.0, -0.5, -1.0 };
119
    double re[4], im[4];
120
    Vamp::FFT::forward(4, in, 0, re, im);
121
    BOOST_CHECK_EQUAL(re[0], 0.0);
122
    BOOST_CHECK_EQUAL(re[1], 1.0);
123
    BOOST_CHECK_EQUAL(re[2], 0.0);
124
    BOOST_CHECK_EQUAL(im[0], 0.0);
125
    BOOST_CHECK_EQUAL(im[1], -2.0);
126
    BOOST_CHECK_EQUAL(im[2], 0.0);
127
    double back[4];
128
    double backim[4];
129
    Vamp::FFT::inverse(4, re, im, back, backim);
130
    COMPARE_ARRAY(back, in);
131
}
132

    
133
BOOST_AUTO_TEST_CASE(nyquist)
134
{
135
    double in[] = { 1, -1, 1, -1 };
136
    double re[4], im[4];
137
    Vamp::FFT::forward(4, in, 0, re, im);
138
    BOOST_CHECK_EQUAL(re[0], 0.0);
139
    BOOST_CHECK_EQUAL(re[1], 0.0);
140
    BOOST_CHECK_EQUAL(re[2], 4.0);
141
    COMPARE_CONST(im, 0.0);
142
    double back[4];
143
    double backim[4];
144
    Vamp::FFT::inverse(4, re, im, back, backim);
145
    COMPARE_ARRAY(back, in);
146
}
147

    
148
BOOST_AUTO_TEST_CASE(dirac)
149
{
150
    double in[] = { 1, 0, 0, 0 };
151
    double re[4], im[4];
152
    Vamp::FFT::forward(4, in, 0, re, im);
153
    BOOST_CHECK_EQUAL(re[0], 1.0);
154
    BOOST_CHECK_EQUAL(re[1], 1.0);
155
    BOOST_CHECK_EQUAL(re[2], 1.0);
156
    COMPARE_CONST(im, 0.0);
157
    double back[4];
158
    double backim[4];
159
    Vamp::FFT::inverse(4, re, im, back, backim);
160
    COMPARE_ARRAY(back, in);
161
}
162

    
163
BOOST_AUTO_TEST_CASE(forwardArrayBounds)
164
{
165
    // initialise bins to something recognisable, so we can tell
166
    // if they haven't been written
167
    double in[] = { 1, 1, -1, -1 };
168
    double re[] = { 999, 999, 999, 999, 999, 999 };
169
    double im[] = { 999, 999, 999, 999, 999, 999 };
170
    Vamp::FFT::forward(4, in, 0, re+1, im+1);
171
    // And check we haven't overrun the arrays
172
    BOOST_CHECK_EQUAL(re[0], 999.0);
173
    BOOST_CHECK_EQUAL(im[0], 999.0);
174
    BOOST_CHECK_EQUAL(re[5], 999.0);
175
    BOOST_CHECK_EQUAL(im[5], 999.0);
176
}
177

    
178
BOOST_AUTO_TEST_CASE(inverseArrayBounds)
179
{
180
    // initialise bins to something recognisable, so we can tell
181
    // if they haven't been written
182
    double re[] = { 0, 1, 0 };
183
    double im[] = { 0, -2, 0 };
184
    double outre[] = { 999, 999, 999, 999, 999, 999 };
185
    double outim[] = { 999, 999, 999, 999, 999, 999 };
186
    Vamp::FFT::forward(4, re, im, outre+1, outim+1);
187
    // And check we haven't overrun the arrays
188
    BOOST_CHECK_EQUAL(outre[0], 999.0);
189
    BOOST_CHECK_EQUAL(outim[0], 999.0);
190
    BOOST_CHECK_EQUAL(outre[5], 999.0);
191
    BOOST_CHECK_EQUAL(outim[5], 999.0);
192
}
193

    
194
BOOST_AUTO_TEST_SUITE_END()
195