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 @ 66:7ad142c710c6

History | View | Annotate | Download (5.37 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_SMALL(a[cmp_i] - n, 1e-14);                                \
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_SMALL(a[cmp_i] - b[cmp_i], 1e-14);                        \
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_CLOSE(re[1], 1.0, 1e-12);
105
    BOOST_CHECK_EQUAL(re[2], 0.0);
106
    BOOST_CHECK_EQUAL(im[0], 0.0);
107
    BOOST_CHECK_CLOSE(im[1], -2.0, 1e-12);
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(nyquist)
116
{
117
    double in[] = { 1, -1, 1, -1 };
118
    double re[4], im[4];
119
    Vamp::FFT::forward(4, in, 0, re, im);
120
    BOOST_CHECK_EQUAL(re[0], 0.0);
121
    BOOST_CHECK_EQUAL(re[1], 0.0);
122
    BOOST_CHECK_EQUAL(re[2], 4.0);
123
    COMPARE_CONST(im, 0.0);
124
    double back[4];
125
    double backim[4];
126
    Vamp::FFT::inverse(4, re, im, back, backim);
127
    COMPARE_ARRAY(back, in);
128
}
129

    
130
BOOST_AUTO_TEST_CASE(dirac)
131
{
132
    double in[] = { 1, 0, 0, 0 };
133
    double re[4], im[4];
134
    Vamp::FFT::forward(4, in, 0, re, im);
135
    BOOST_CHECK_EQUAL(re[0], 1.0);
136
    BOOST_CHECK_EQUAL(re[1], 1.0);
137
    BOOST_CHECK_EQUAL(re[2], 1.0);
138
    COMPARE_CONST(im, 0.0);
139
    double back[4];
140
    double backim[4];
141
    Vamp::FFT::inverse(4, re, im, back, backim);
142
    COMPARE_ARRAY(back, in);
143
}
144

    
145
BOOST_AUTO_TEST_CASE(forwardArrayBounds)
146
{
147
    // initialise bins to something recognisable, so we can tell
148
    // if they haven't been written
149
    double in[] = { 1, 1, -1, -1 };
150
    double re[] = { 999, 999, 999, 999, 999, 999 };
151
    double im[] = { 999, 999, 999, 999, 999, 999 };
152
    Vamp::FFT::forward(4, in, 0, re+1, im+1);
153
    // And check we haven't overrun the arrays
154
    BOOST_CHECK_EQUAL(re[0], 999.0);
155
    BOOST_CHECK_EQUAL(im[0], 999.0);
156
    BOOST_CHECK_EQUAL(re[5], 999.0);
157
    BOOST_CHECK_EQUAL(im[5], 999.0);
158
}
159

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

    
176
BOOST_AUTO_TEST_SUITE_END()
177