annotate test/TestFFT.cpp @ 75:84d1a0647ce5 tip

Split out COPYING from README
author Chris Cannam
date Fri, 06 Mar 2020 11:01:53 +0000
parents 0997774f5fdc
children
rev   line source
Chris@48 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@48 2 /*
Chris@48 3 This file is Copyright (c) 2012 Chris Cannam
Chris@48 4
Chris@48 5 Permission is hereby granted, free of charge, to any person
Chris@48 6 obtaining a copy of this software and associated documentation
Chris@48 7 files (the "Software"), to deal in the Software without
Chris@48 8 restriction, including without limitation the rights to use, copy,
Chris@48 9 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@48 10 of the Software, and to permit persons to whom the Software is
Chris@48 11 furnished to do so, subject to the following conditions:
Chris@48 12
Chris@48 13 The above copyright notice and this permission notice shall be
Chris@48 14 included in all copies or substantial portions of the Software.
Chris@48 15
Chris@48 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@48 17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@48 18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@48 19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
Chris@48 20 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@48 21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@48 22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@48 23 */
Chris@48 24
Chris@48 25 /*
Chris@48 26 This unit test suite for the Vamp SDK FFT implementation is included
Chris@48 27 here mostly for illustrative purposes!
Chris@48 28 */
Chris@48 29
Chris@48 30 #include "vamp-sdk/FFT.h"
Chris@48 31
Chris@48 32 #define BOOST_TEST_DYN_LINK
Chris@48 33 #define BOOST_TEST_MAIN
Chris@48 34
Chris@48 35 #include <boost/test/unit_test.hpp>
Chris@48 36
Chris@48 37 BOOST_AUTO_TEST_SUITE(TestFFT)
Chris@48 38
Chris@48 39 #define COMPARE_CONST(a, n) \
Chris@48 40 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
Chris@49 41 BOOST_CHECK_SMALL(a[cmp_i] - n, 1e-14); \
Chris@48 42 }
Chris@48 43
Chris@48 44 #define COMPARE_ARRAY(a, b) \
Chris@48 45 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
Chris@49 46 BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-14); \
Chris@48 47 }
Chris@48 48
Chris@48 49 BOOST_AUTO_TEST_CASE(dc)
Chris@48 50 {
Chris@48 51 // DC-only signal. The DC bin is purely real
Chris@48 52 double in[] = { 1, 1, 1, 1 };
Chris@48 53 double re[4], im[4];
Chris@48 54 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 55 BOOST_CHECK_EQUAL(re[0], 4.0);
Chris@48 56 BOOST_CHECK_EQUAL(re[1], 0.0);
Chris@48 57 BOOST_CHECK_EQUAL(re[2], 0.0);
Chris@48 58 COMPARE_CONST(im, 0.0);
Chris@48 59 double back[4];
Chris@48 60 double backim[4];
Chris@48 61 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 62 COMPARE_ARRAY(back, in);
Chris@48 63 }
Chris@48 64
Chris@48 65 BOOST_AUTO_TEST_CASE(sine)
Chris@48 66 {
Chris@48 67 // Sine. Output is purely imaginary
Chris@48 68 double in[] = { 0, 1, 0, -1 };
Chris@48 69 double re[4], im[4];
Chris@48 70 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 71 COMPARE_CONST(re, 0.0);
Chris@48 72 BOOST_CHECK_EQUAL(im[0], 0.0);
Chris@48 73 BOOST_CHECK_EQUAL(im[1], -2.0);
Chris@48 74 BOOST_CHECK_EQUAL(im[2], 0.0);
Chris@48 75 double back[4];
Chris@48 76 double backim[4];
Chris@48 77 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 78 COMPARE_ARRAY(back, in);
Chris@48 79 }
Chris@48 80
Chris@48 81 BOOST_AUTO_TEST_CASE(cosine)
Chris@48 82 {
Chris@48 83 // Cosine. Output is purely real
Chris@48 84 double in[] = { 1, 0, -1, 0 };
Chris@48 85 double re[4], im[4];
Chris@48 86 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 87 BOOST_CHECK_EQUAL(re[0], 0.0);
Chris@48 88 BOOST_CHECK_EQUAL(re[1], 2.0);
Chris@48 89 BOOST_CHECK_EQUAL(re[2], 0.0);
Chris@48 90 COMPARE_CONST(im, 0.0);
Chris@48 91 double back[4];
Chris@48 92 double backim[4];
Chris@48 93 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 94 COMPARE_ARRAY(back, in);
Chris@48 95 }
Chris@48 96
Chris@48 97 BOOST_AUTO_TEST_CASE(sineCosine)
Chris@48 98 {
Chris@48 99 // Sine and cosine mixed
Chris@48 100 double in[] = { 0.5, 1, -0.5, -1 };
Chris@48 101 double re[4], im[4];
Chris@48 102 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 103 BOOST_CHECK_EQUAL(re[0], 0.0);
Chris@49 104 BOOST_CHECK_CLOSE(re[1], 1.0, 1e-12);
Chris@48 105 BOOST_CHECK_EQUAL(re[2], 0.0);
Chris@48 106 BOOST_CHECK_EQUAL(im[0], 0.0);
Chris@49 107 BOOST_CHECK_CLOSE(im[1], -2.0, 1e-12);
Chris@48 108 BOOST_CHECK_EQUAL(im[2], 0.0);
Chris@48 109 double back[4];
Chris@48 110 double backim[4];
Chris@48 111 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 112 COMPARE_ARRAY(back, in);
Chris@48 113 }
Chris@48 114
Chris@48 115 BOOST_AUTO_TEST_CASE(nyquist)
Chris@48 116 {
Chris@48 117 double in[] = { 1, -1, 1, -1 };
Chris@48 118 double re[4], im[4];
Chris@48 119 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 120 BOOST_CHECK_EQUAL(re[0], 0.0);
Chris@48 121 BOOST_CHECK_EQUAL(re[1], 0.0);
Chris@48 122 BOOST_CHECK_EQUAL(re[2], 4.0);
Chris@48 123 COMPARE_CONST(im, 0.0);
Chris@48 124 double back[4];
Chris@48 125 double backim[4];
Chris@48 126 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 127 COMPARE_ARRAY(back, in);
Chris@48 128 }
Chris@48 129
Chris@48 130 BOOST_AUTO_TEST_CASE(dirac)
Chris@48 131 {
Chris@48 132 double in[] = { 1, 0, 0, 0 };
Chris@48 133 double re[4], im[4];
Chris@48 134 Vamp::FFT::forward(4, in, 0, re, im);
Chris@48 135 BOOST_CHECK_EQUAL(re[0], 1.0);
Chris@48 136 BOOST_CHECK_EQUAL(re[1], 1.0);
Chris@48 137 BOOST_CHECK_EQUAL(re[2], 1.0);
Chris@48 138 COMPARE_CONST(im, 0.0);
Chris@48 139 double back[4];
Chris@48 140 double backim[4];
Chris@48 141 Vamp::FFT::inverse(4, re, im, back, backim);
Chris@48 142 COMPARE_ARRAY(back, in);
Chris@48 143 }
Chris@48 144
Chris@48 145 BOOST_AUTO_TEST_CASE(forwardArrayBounds)
Chris@48 146 {
Chris@48 147 // initialise bins to something recognisable, so we can tell
Chris@48 148 // if they haven't been written
Chris@48 149 double in[] = { 1, 1, -1, -1 };
Chris@48 150 double re[] = { 999, 999, 999, 999, 999, 999 };
Chris@48 151 double im[] = { 999, 999, 999, 999, 999, 999 };
Chris@48 152 Vamp::FFT::forward(4, in, 0, re+1, im+1);
Chris@48 153 // And check we haven't overrun the arrays
Chris@48 154 BOOST_CHECK_EQUAL(re[0], 999.0);
Chris@48 155 BOOST_CHECK_EQUAL(im[0], 999.0);
Chris@48 156 BOOST_CHECK_EQUAL(re[5], 999.0);
Chris@48 157 BOOST_CHECK_EQUAL(im[5], 999.0);
Chris@48 158 }
Chris@48 159
Chris@48 160 BOOST_AUTO_TEST_CASE(inverseArrayBounds)
Chris@48 161 {
Chris@48 162 // initialise bins to something recognisable, so we can tell
Chris@48 163 // if they haven't been written
Chris@48 164 double re[] = { 0, 1, 0 };
Chris@48 165 double im[] = { 0, -2, 0 };
Chris@48 166 double outre[] = { 999, 999, 999, 999, 999, 999 };
Chris@48 167 double outim[] = { 999, 999, 999, 999, 999, 999 };
Chris@48 168 Vamp::FFT::forward(4, re, im, outre+1, outim+1);
Chris@48 169 // And check we haven't overrun the arrays
Chris@48 170 BOOST_CHECK_EQUAL(outre[0], 999.0);
Chris@48 171 BOOST_CHECK_EQUAL(outim[0], 999.0);
Chris@48 172 BOOST_CHECK_EQUAL(outre[5], 999.0);
Chris@48 173 BOOST_CHECK_EQUAL(outim[5], 999.0);
Chris@48 174 }
Chris@48 175
Chris@48 176 BOOST_AUTO_TEST_SUITE_END()
Chris@48 177