Chris@39: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@39: /* Chris@39: This file is Copyright (c) 2012 Chris Cannam Chris@39: Chris@39: Permission is hereby granted, free of charge, to any person Chris@39: obtaining a copy of this software and associated documentation Chris@39: files (the "Software"), to deal in the Software without Chris@39: restriction, including without limitation the rights to use, copy, Chris@39: modify, merge, publish, distribute, sublicense, and/or sell copies Chris@39: of the Software, and to permit persons to whom the Software is Chris@39: furnished to do so, subject to the following conditions: Chris@39: Chris@39: The above copyright notice and this permission notice shall be Chris@39: included in all copies or substantial portions of the Software. Chris@39: Chris@39: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@39: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@39: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND Chris@39: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR Chris@39: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@39: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@39: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@39: */ Chris@39: Chris@39: #include "PeakInterpolator.h" Chris@39: Chris@39: #define BOOST_TEST_DYN_LINK Chris@39: #define BOOST_TEST_MAIN Chris@39: Chris@39: #include Chris@39: Chris@39: BOOST_AUTO_TEST_SUITE(TestPeakInterpolator) Chris@39: Chris@39: BOOST_AUTO_TEST_CASE(peakAtSample_N3) Chris@39: { Chris@46: // Peak exactly at sample index Chris@46: double data[] = { 0.0, 10.0, 0.0 }; Chris@39: PeakInterpolator p; Chris@46: // Asked to find peak at index 1, should return index 1 Chris@39: double result = p.findPeakLocation(data, 3, 1); Chris@39: BOOST_CHECK_EQUAL(result, 1.0); Chris@46: // Asked to find any peak, should return index 1 Chris@42: result = p.findPeakLocation(data, 3); Chris@42: BOOST_CHECK_EQUAL(result, 1.0); Chris@39: } Chris@39: Chris@39: BOOST_AUTO_TEST_CASE(peakAtSample_N5) Chris@39: { Chris@46: // Peak exactly at sample index Chris@46: double data[] = { 0.0, 10.0, 20.0, 10.0, 0.0 }; Chris@39: PeakInterpolator p; Chris@46: // Asked to find peak at index 2, should return index 2 Chris@39: double result = p.findPeakLocation(data, 5, 2); Chris@39: BOOST_CHECK_EQUAL(result, 2.0); Chris@46: // Asked to find any peak, should return index 2 Chris@42: result = p.findPeakLocation(data, 5); Chris@42: BOOST_CHECK_EQUAL(result, 2.0); Chris@39: } Chris@39: Chris@39: BOOST_AUTO_TEST_CASE(flat) Chris@39: { Chris@46: // No peak Chris@39: double data[] = { 1.0, 1.0, 1.0, 1.0, 1.0 }; Chris@39: PeakInterpolator p; Chris@46: // Asked to find peak at index N, should return N (no superior neighbours) Chris@39: double result = p.findPeakLocation(data, 5, 2); Chris@39: BOOST_CHECK_EQUAL(result, 2.0); Chris@46: // Asked to find any peak, should return 0 (first value as good as any) Chris@42: result = p.findPeakLocation(data, 5); Chris@42: BOOST_CHECK_EQUAL(result, 0.0); Chris@39: } Chris@39: Chris@39: BOOST_AUTO_TEST_CASE(multiPeak) Chris@39: { Chris@46: // More than one peak Chris@39: double data[] = { 1.0, 2.0, 1.0, 2.0, 1.0 }; Chris@39: PeakInterpolator p; Chris@46: // Asked to find peak at index 3, should return index 3 Chris@39: double result = p.findPeakLocation(data, 5, 3); Chris@39: BOOST_CHECK_EQUAL(result, 3.0); Chris@46: // But asked to find any peak, should return 1 (first peak) Chris@42: result = p.findPeakLocation(data, 5); Chris@42: BOOST_CHECK_EQUAL(result, 1.0); Chris@39: } Chris@39: Chris@40: BOOST_AUTO_TEST_CASE(start) Chris@40: { Chris@40: // Can't meaningfully interpolate if we're identifying element 0 Chris@46: // as the peak (nothing to its left) Chris@40: double data[] = { 1.0, 1.0, 0.0, 0.0 }; Chris@40: PeakInterpolator p; Chris@40: double result = p.findPeakLocation(data, 4, 0); Chris@40: BOOST_CHECK_EQUAL(result, 0.0); Chris@40: } Chris@40: Chris@40: BOOST_AUTO_TEST_CASE(end) Chris@40: { Chris@40: // Likewise for the final element Chris@40: double data[] = { 0.0, 0.0, 1.0, 1.0 }; Chris@40: PeakInterpolator p; Chris@40: double result = p.findPeakLocation(data, 4, 3); Chris@40: BOOST_CHECK_EQUAL(result, 3.0); Chris@46: // But when asked to find any peak, we expect idx 2 to be picked, Chris@46: // not idx 3, so that will result in interpolation Chris@42: result = p.findPeakLocation(data, 4); Chris@42: BOOST_CHECK(result > 2.0 && result < 3.0); Chris@40: } Chris@40: Chris@40: BOOST_AUTO_TEST_CASE(longHalfway) Chris@40: { Chris@46: // Peak is exactly half-way between indices Chris@40: double data[] = { 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 1.0, 1.0 }; Chris@40: PeakInterpolator p; Chris@46: // Asked to find peak for either index 3 or 4, should return 3.5 Chris@46: double result = p.findPeakLocation(data, 8, 3); Chris@40: BOOST_CHECK_EQUAL(result, 3.5); Chris@46: result = p.findPeakLocation(data, 8, 4); Chris@46: BOOST_CHECK_EQUAL(result, 3.5); Chris@46: // Likewise if asked to find any peak Chris@42: result = p.findPeakLocation(data, 8); Chris@42: BOOST_CHECK_EQUAL(result, 3.5); Chris@40: } Chris@40: Chris@40: BOOST_AUTO_TEST_CASE(shortHalfway) Chris@40: { Chris@46: // As longHalfway, but with fewer points Chris@40: double data[] = { 1.0, 2.0, 2.0, 1.0 }; Chris@40: PeakInterpolator p; Chris@40: double result = p.findPeakLocation(data, 4, 1); Chris@40: BOOST_CHECK_EQUAL(result, 1.5); Chris@42: result = p.findPeakLocation(data, 4); Chris@42: BOOST_CHECK_EQUAL(result, 1.5); Chris@40: } Chris@40: Chris@41: BOOST_AUTO_TEST_CASE(aboveHalfway) Chris@41: { Chris@46: // Peak is nearer to one index than its neighbour. (Exact position Chris@46: // depends on the peak interpolation method in use; we only know Chris@46: // that it must be beyond the half way point) Chris@41: double data[] = { 1.0, 1.5, 2.0, 1.0 }; Chris@41: PeakInterpolator p; Chris@41: double result = p.findPeakLocation(data, 4, 2); Chris@41: BOOST_CHECK(result > 1.5 && result < 2.0); Chris@42: result = p.findPeakLocation(data, 4); Chris@42: BOOST_CHECK(result > 1.5 && result < 2.0); Chris@41: } Chris@41: Chris@41: BOOST_AUTO_TEST_CASE(belowHalfway) Chris@41: { Chris@46: // Peak is nearer to one index than its neighbour. (Exact position Chris@46: // depends on the peak interpolation method in use; we only know Chris@46: // that it must be before the half way point) Chris@41: double data[] = { 1.0, 2.0, 1.5, 1.0 }; Chris@41: PeakInterpolator p; Chris@41: double result = p.findPeakLocation(data, 4, 1); Chris@41: BOOST_CHECK(result > 1.0 && result < 1.5); Chris@42: result = p.findPeakLocation(data, 4); Chris@42: BOOST_CHECK(result > 1.0 && result < 1.5); Chris@41: } Chris@41: Chris@39: BOOST_AUTO_TEST_SUITE_END() Chris@39: