Chris@51: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@51: /* Chris@51: This file is Copyright (c) 2012 Chris Cannam Chris@51: Chris@51: Permission is hereby granted, free of charge, to any person Chris@51: obtaining a copy of this software and associated documentation Chris@51: files (the "Software"), to deal in the Software without Chris@51: restriction, including without limitation the rights to use, copy, Chris@51: modify, merge, publish, distribute, sublicense, and/or sell copies Chris@51: of the Software, and to permit persons to whom the Software is Chris@51: furnished to do so, subject to the following conditions: Chris@51: Chris@51: The above copyright notice and this permission notice shall be Chris@51: included in all copies or substantial portions of the Software. Chris@51: Chris@51: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@51: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@51: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND Chris@51: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR Chris@51: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@51: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@51: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@51: */ Chris@51: Chris@51: #include "Cepstrum.h" Chris@51: Chris@51: #define BOOST_TEST_DYN_LINK Chris@51: #define BOOST_TEST_MAIN Chris@51: Chris@51: #include Chris@51: Chris@51: BOOST_AUTO_TEST_SUITE(TestCepstrum) Chris@51: Chris@51: BOOST_AUTO_TEST_CASE(cosine) Chris@51: { Chris@51: // input format is re0, im0, re1, im1... Chris@51: float in[] = { 0,0, 10,0, 0,0 }; Chris@51: double out[4]; Chris@51: double mm = Cepstrum(4).process(in, out); Chris@51: BOOST_CHECK_SMALL(out[0] - (-4.5), 1e-10); Chris@51: BOOST_CHECK_EQUAL(out[1], 0); Chris@51: BOOST_CHECK_SMALL(out[2] - (-5.5), 1e-10); Chris@51: BOOST_CHECK_EQUAL(out[3], 0); Chris@51: BOOST_CHECK_EQUAL(mm, 10.0/3.0); Chris@51: } Chris@51: Chris@51: BOOST_AUTO_TEST_CASE(symmetry) Chris@51: { Chris@51: // Cepstrum output bins 1..n-1 are symmetric about bin n/2 Chris@51: float in[] = { 1,2,3,4,5,6,7,8,9,10 }; Chris@51: double out[8]; Chris@51: double mm = Cepstrum(8).process(in, out); Chris@51: BOOST_CHECK_SMALL(out[1] - out[7], 1e-14); Chris@51: BOOST_CHECK_SMALL(out[2] - out[6], 1e-14); Chris@51: BOOST_CHECK_SMALL(out[3] - out[5], 1e-14); Chris@73: double mmcheck = 0; Chris@73: for (int i = 0; i < 5; ++i) { Chris@73: mmcheck += sqrt(in[i*2] * in[i*2] + in[i*2+1] * in[i*2+1]); Chris@73: } Chris@73: mmcheck /= 5; Chris@73: BOOST_CHECK_EQUAL(mm, mmcheck); Chris@51: } Chris@51: Chris@51: BOOST_AUTO_TEST_CASE(oneHarmonic) Chris@51: { Chris@51: // input format is re0, im0, re1, im1, re2, im2 Chris@51: // freq for bin i is i * samplerate / n Chris@51: // freqs: 0 sr/n 2sr/n 3sr/n 4sr/n 5sr/n 6sr/n 7sr/n sr/2 Chris@51: float in[] = { 0,0, 0,0, 10,0, 0,0, 10,0, 0,0, 10,0, 0,0, 0,0 }; Chris@51: double out[16]; Chris@51: double mm = Cepstrum(16).process(in, out); Chris@51: BOOST_CHECK_EQUAL(mm, 30.0/9.0); Chris@51: // peak is at 8 Chris@51: BOOST_CHECK(out[8] > 0); Chris@51: // odd bins are all zero Chris@51: BOOST_CHECK_EQUAL(out[1], 0); Chris@51: BOOST_CHECK_EQUAL(out[3], 0); Chris@51: BOOST_CHECK_EQUAL(out[5], 0); Chris@51: BOOST_CHECK_EQUAL(out[7], 0); Chris@51: BOOST_CHECK_EQUAL(out[9], 0); Chris@51: BOOST_CHECK_EQUAL(out[11], 0); Chris@51: BOOST_CHECK_EQUAL(out[13], 0); Chris@51: BOOST_CHECK_EQUAL(out[15], 0); Chris@51: // the rest are negative Chris@51: BOOST_CHECK(out[0] < 0); Chris@51: BOOST_CHECK(out[2] < 0); Chris@51: BOOST_CHECK(out[4] < 0); Chris@51: BOOST_CHECK(out[6] < 0); Chris@51: BOOST_CHECK(out[10] < 0); Chris@51: BOOST_CHECK(out[12] < 0); Chris@51: BOOST_CHECK(out[14] < 0); Chris@51: } Chris@51: Chris@51: BOOST_AUTO_TEST_SUITE_END() Chris@51: