Chris@39
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@39
|
2 /*
|
Chris@39
|
3 This file is Copyright (c) 2012 Chris Cannam
|
Chris@39
|
4
|
Chris@39
|
5 Permission is hereby granted, free of charge, to any person
|
Chris@39
|
6 obtaining a copy of this software and associated documentation
|
Chris@39
|
7 files (the "Software"), to deal in the Software without
|
Chris@39
|
8 restriction, including without limitation the rights to use, copy,
|
Chris@39
|
9 modify, merge, publish, distribute, sublicense, and/or sell copies
|
Chris@39
|
10 of the Software, and to permit persons to whom the Software is
|
Chris@39
|
11 furnished to do so, subject to the following conditions:
|
Chris@39
|
12
|
Chris@39
|
13 The above copyright notice and this permission notice shall be
|
Chris@39
|
14 included in all copies or substantial portions of the Software.
|
Chris@39
|
15
|
Chris@39
|
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Chris@39
|
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Chris@39
|
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Chris@39
|
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
Chris@39
|
20 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
Chris@39
|
21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Chris@39
|
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Chris@39
|
23 */
|
Chris@39
|
24
|
Chris@39
|
25 #include "PeakInterpolator.h"
|
Chris@39
|
26
|
Chris@39
|
27 #define BOOST_TEST_DYN_LINK
|
Chris@39
|
28 #define BOOST_TEST_MAIN
|
Chris@39
|
29
|
Chris@39
|
30 #include <boost/test/unit_test.hpp>
|
Chris@39
|
31
|
Chris@39
|
32 BOOST_AUTO_TEST_SUITE(TestPeakInterpolator)
|
Chris@39
|
33
|
Chris@39
|
34 BOOST_AUTO_TEST_CASE(peakAtSample_N3)
|
Chris@39
|
35 {
|
Chris@46
|
36 // Peak exactly at sample index
|
Chris@46
|
37 double data[] = { 0.0, 10.0, 0.0 };
|
Chris@39
|
38 PeakInterpolator p;
|
Chris@46
|
39 // Asked to find peak at index 1, should return index 1
|
Chris@39
|
40 double result = p.findPeakLocation(data, 3, 1);
|
Chris@39
|
41 BOOST_CHECK_EQUAL(result, 1.0);
|
Chris@46
|
42 // Asked to find any peak, should return index 1
|
Chris@42
|
43 result = p.findPeakLocation(data, 3);
|
Chris@42
|
44 BOOST_CHECK_EQUAL(result, 1.0);
|
Chris@39
|
45 }
|
Chris@39
|
46
|
Chris@39
|
47 BOOST_AUTO_TEST_CASE(peakAtSample_N5)
|
Chris@39
|
48 {
|
Chris@46
|
49 // Peak exactly at sample index
|
Chris@46
|
50 double data[] = { 0.0, 10.0, 20.0, 10.0, 0.0 };
|
Chris@39
|
51 PeakInterpolator p;
|
Chris@46
|
52 // Asked to find peak at index 2, should return index 2
|
Chris@39
|
53 double result = p.findPeakLocation(data, 5, 2);
|
Chris@39
|
54 BOOST_CHECK_EQUAL(result, 2.0);
|
Chris@46
|
55 // Asked to find any peak, should return index 2
|
Chris@42
|
56 result = p.findPeakLocation(data, 5);
|
Chris@42
|
57 BOOST_CHECK_EQUAL(result, 2.0);
|
Chris@39
|
58 }
|
Chris@39
|
59
|
Chris@39
|
60 BOOST_AUTO_TEST_CASE(flat)
|
Chris@39
|
61 {
|
Chris@46
|
62 // No peak
|
Chris@39
|
63 double data[] = { 1.0, 1.0, 1.0, 1.0, 1.0 };
|
Chris@39
|
64 PeakInterpolator p;
|
Chris@46
|
65 // Asked to find peak at index N, should return N (no superior neighbours)
|
Chris@39
|
66 double result = p.findPeakLocation(data, 5, 2);
|
Chris@39
|
67 BOOST_CHECK_EQUAL(result, 2.0);
|
Chris@46
|
68 // Asked to find any peak, should return 0 (first value as good as any)
|
Chris@42
|
69 result = p.findPeakLocation(data, 5);
|
Chris@42
|
70 BOOST_CHECK_EQUAL(result, 0.0);
|
Chris@39
|
71 }
|
Chris@39
|
72
|
Chris@39
|
73 BOOST_AUTO_TEST_CASE(multiPeak)
|
Chris@39
|
74 {
|
Chris@46
|
75 // More than one peak
|
Chris@39
|
76 double data[] = { 1.0, 2.0, 1.0, 2.0, 1.0 };
|
Chris@39
|
77 PeakInterpolator p;
|
Chris@46
|
78 // Asked to find peak at index 3, should return index 3
|
Chris@39
|
79 double result = p.findPeakLocation(data, 5, 3);
|
Chris@39
|
80 BOOST_CHECK_EQUAL(result, 3.0);
|
Chris@46
|
81 // But asked to find any peak, should return 1 (first peak)
|
Chris@42
|
82 result = p.findPeakLocation(data, 5);
|
Chris@42
|
83 BOOST_CHECK_EQUAL(result, 1.0);
|
Chris@39
|
84 }
|
Chris@39
|
85
|
Chris@40
|
86 BOOST_AUTO_TEST_CASE(start)
|
Chris@40
|
87 {
|
Chris@40
|
88 // Can't meaningfully interpolate if we're identifying element 0
|
Chris@46
|
89 // as the peak (nothing to its left)
|
Chris@40
|
90 double data[] = { 1.0, 1.0, 0.0, 0.0 };
|
Chris@40
|
91 PeakInterpolator p;
|
Chris@40
|
92 double result = p.findPeakLocation(data, 4, 0);
|
Chris@40
|
93 BOOST_CHECK_EQUAL(result, 0.0);
|
Chris@40
|
94 }
|
Chris@40
|
95
|
Chris@40
|
96 BOOST_AUTO_TEST_CASE(end)
|
Chris@40
|
97 {
|
Chris@40
|
98 // Likewise for the final element
|
Chris@40
|
99 double data[] = { 0.0, 0.0, 1.0, 1.0 };
|
Chris@40
|
100 PeakInterpolator p;
|
Chris@40
|
101 double result = p.findPeakLocation(data, 4, 3);
|
Chris@40
|
102 BOOST_CHECK_EQUAL(result, 3.0);
|
Chris@46
|
103 // But when asked to find any peak, we expect idx 2 to be picked,
|
Chris@46
|
104 // not idx 3, so that will result in interpolation
|
Chris@42
|
105 result = p.findPeakLocation(data, 4);
|
Chris@42
|
106 BOOST_CHECK(result > 2.0 && result < 3.0);
|
Chris@40
|
107 }
|
Chris@40
|
108
|
Chris@40
|
109 BOOST_AUTO_TEST_CASE(longHalfway)
|
Chris@40
|
110 {
|
Chris@46
|
111 // Peak is exactly half-way between indices
|
Chris@40
|
112 double data[] = { 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 1.0, 1.0 };
|
Chris@40
|
113 PeakInterpolator p;
|
Chris@46
|
114 // Asked to find peak for either index 3 or 4, should return 3.5
|
Chris@46
|
115 double result = p.findPeakLocation(data, 8, 3);
|
Chris@40
|
116 BOOST_CHECK_EQUAL(result, 3.5);
|
Chris@46
|
117 result = p.findPeakLocation(data, 8, 4);
|
Chris@46
|
118 BOOST_CHECK_EQUAL(result, 3.5);
|
Chris@46
|
119 // Likewise if asked to find any peak
|
Chris@42
|
120 result = p.findPeakLocation(data, 8);
|
Chris@42
|
121 BOOST_CHECK_EQUAL(result, 3.5);
|
Chris@40
|
122 }
|
Chris@40
|
123
|
Chris@40
|
124 BOOST_AUTO_TEST_CASE(shortHalfway)
|
Chris@40
|
125 {
|
Chris@46
|
126 // As longHalfway, but with fewer points
|
Chris@40
|
127 double data[] = { 1.0, 2.0, 2.0, 1.0 };
|
Chris@40
|
128 PeakInterpolator p;
|
Chris@40
|
129 double result = p.findPeakLocation(data, 4, 1);
|
Chris@40
|
130 BOOST_CHECK_EQUAL(result, 1.5);
|
Chris@42
|
131 result = p.findPeakLocation(data, 4);
|
Chris@42
|
132 BOOST_CHECK_EQUAL(result, 1.5);
|
Chris@40
|
133 }
|
Chris@40
|
134
|
Chris@41
|
135 BOOST_AUTO_TEST_CASE(aboveHalfway)
|
Chris@41
|
136 {
|
Chris@46
|
137 // Peak is nearer to one index than its neighbour. (Exact position
|
Chris@46
|
138 // depends on the peak interpolation method in use; we only know
|
Chris@46
|
139 // that it must be beyond the half way point)
|
Chris@41
|
140 double data[] = { 1.0, 1.5, 2.0, 1.0 };
|
Chris@41
|
141 PeakInterpolator p;
|
Chris@41
|
142 double result = p.findPeakLocation(data, 4, 2);
|
Chris@41
|
143 BOOST_CHECK(result > 1.5 && result < 2.0);
|
Chris@42
|
144 result = p.findPeakLocation(data, 4);
|
Chris@42
|
145 BOOST_CHECK(result > 1.5 && result < 2.0);
|
Chris@41
|
146 }
|
Chris@41
|
147
|
Chris@41
|
148 BOOST_AUTO_TEST_CASE(belowHalfway)
|
Chris@41
|
149 {
|
Chris@46
|
150 // Peak is nearer to one index than its neighbour. (Exact position
|
Chris@46
|
151 // depends on the peak interpolation method in use; we only know
|
Chris@46
|
152 // that it must be before the half way point)
|
Chris@41
|
153 double data[] = { 1.0, 2.0, 1.5, 1.0 };
|
Chris@41
|
154 PeakInterpolator p;
|
Chris@41
|
155 double result = p.findPeakLocation(data, 4, 1);
|
Chris@41
|
156 BOOST_CHECK(result > 1.0 && result < 1.5);
|
Chris@42
|
157 result = p.findPeakLocation(data, 4);
|
Chris@42
|
158 BOOST_CHECK(result > 1.0 && result < 1.5);
|
Chris@41
|
159 }
|
Chris@41
|
160
|
Chris@39
|
161 BOOST_AUTO_TEST_SUITE_END()
|
Chris@39
|
162
|