/* Copyright (C) 2014 Carl Hetherington This file is part of DCP-o-matic. DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . */ /** @file test/audio_buffers_test.cc * @brief Test AudioBuffers class. * @ingroup selfcontained */ #include #include #include "lib/audio_buffers.h" using std::pow; static float tolerance = 1e-3; static float random_float () { return float (rand ()) / RAND_MAX; } static void random_fill (AudioBuffers& buffers) { for (int i = 0; i < buffers.frames(); ++i) { for (int j = 0; j < buffers.channels(); ++j) { buffers.data(j)[i] = random_float (); } } } static void random_check (AudioBuffers& buffers, int from, int frames) { for (int i = from; i < (from + frames); ++i) { for (int j = 0; j < buffers.channels(); ++j) { BOOST_CHECK_CLOSE (buffers.data(j)[i], random_float (), tolerance); } } } /** Basic setup */ BOOST_AUTO_TEST_CASE (audio_buffers_setup_test) { AudioBuffers buffers (4, 9155); BOOST_CHECK (buffers.data ()); for (int i = 0; i < 4; ++i) { BOOST_CHECK (buffers.data (i)); } BOOST_CHECK_EQUAL (buffers.channels(), 4); BOOST_CHECK_EQUAL (buffers.frames(), 9155); } /** Extending some buffers */ BOOST_AUTO_TEST_CASE (audio_buffers_extend_test) { AudioBuffers buffers (3, 150); srand (1); random_fill (buffers); /* Extend */ buffers.set_frames (299); srand (1); random_check (buffers, 0, 150); /* New space should be silent */ for (int i = 150; i < 299; ++i) { for (int c = 0; c < 3; ++c) { BOOST_CHECK_EQUAL (buffers.data(c)[i], 0); } } } /** make_silent() */ BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_test) { AudioBuffers buffers (9, 9933); srand (2); random_fill (buffers); buffers.make_silent (); for (int i = 0; i < 9933; ++i) { for (int c = 0; c < 9; ++c) { BOOST_CHECK_EQUAL (buffers.data(c)[i], 0); } } } /** make_silent (int c) */ BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_channel_test) { AudioBuffers buffers (9, 9933); srand (3); random_fill (buffers); buffers.make_silent (4); srand (3); for (int i = 0; i < 9933; ++i) { for (int c = 0; c < 9; ++c) { if (c == 4) { random_float (); BOOST_CHECK_EQUAL (buffers.data(c)[i], 0); } else { BOOST_CHECK_CLOSE (buffers.data(c)[i], random_float (), tolerance); } } } } /** make_silent (int from, int frames) */ BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_part_test) { AudioBuffers buffers (9, 9933); srand (4); random_fill (buffers); buffers.make_silent (145, 833); srand (4); for (int i = 0; i < 145; ++i) { for (int c = 0; c < 9; ++c) { BOOST_CHECK_EQUAL (buffers.data(c)[i], random_float ()); } } for (int i = 145; i < (145 + 833); ++i) { for (int c = 0; c < 9; ++c) { random_float (); BOOST_CHECK_EQUAL (buffers.data(c)[i], 0); } } for (int i = (145 + 833); i < 9933; ++i) { for (int c = 0; c < 9; ++c) { BOOST_CHECK_EQUAL (buffers.data(c)[i], random_float ()); } } } /* apply_gain */ BOOST_AUTO_TEST_CASE (audio_buffers_apply_gain) { AudioBuffers buffers (2, 417315); srand (9); random_fill (buffers); buffers.apply_gain (5.4); srand (9); for (int i = 0; i < 417315; ++i) { for (int c = 0; c < 2; ++c) { BOOST_CHECK_CLOSE (buffers.data(c)[i], random_float() * pow (10, 5.4 / 20), tolerance); } } } /* copy_from */ BOOST_AUTO_TEST_CASE (audio_buffers_copy_from) { AudioBuffers a (5, 63711); AudioBuffers b (5, 12345); srand (42); random_fill (a); srand (99); random_fill (b); a.copy_from (&b, 517, 233, 194); /* Re-seed a's generator and check the numbers that came from it */ /* First part; not copied-over */ srand (42); random_check (a, 0, 194); /* Second part; copied-over (just burn generator a's numbers) */ for (int i = 0; i < (517 * 5); ++i) { random_float (); } /* Third part; not copied-over */ random_check (a, 194 + 517, a.frames() - 194 - 517); /* Re-seed b's generator and check the numbers that came from it */ srand (99); /* First part; burn */ for (int i = 0; i < 194 * 5; ++i) { random_float (); } /* Second part; copied */ random_check (b, 194, 517); } /* move */ BOOST_AUTO_TEST_CASE (audio_buffers_move) { AudioBuffers buffers (7, 65536); srand (84); random_fill (buffers); int const from = 888; int const to = 666; int const frames = 444; buffers.move (frames, from, to); /* Re-seed and check the un-moved parts */ srand (84); random_check (buffers, 0, to); /* Burn a few */ for (int i = 0; i < (from - to + frames) * 7; ++i) { random_float (); } random_check (buffers, from + frames, 65536 - frames - from); /* Re-seed and check the moved part */ srand (84); /* Burn a few */ for (int i = 0; i < from * 7; ++i) { random_float (); } random_check (buffers, to, frames); } /** accumulate_channel */ BOOST_AUTO_TEST_CASE (audio_buffers_accumulate_channel) { AudioBuffers a (3, 256); srand (38); random_fill (a); AudioBuffers b (3, 256); random_fill (b); a.accumulate_channel (&b, 2, 1, 1.2); srand (38); for (int i = 0; i < 256; ++i) { for (int c = 0; c < 3; ++c) { float const A = random_float (); if (c == 1) { BOOST_CHECK_CLOSE (a.data(c)[i], A + b.data(2)[i] * 1.2, tolerance); } else { BOOST_CHECK_CLOSE (a.data(c)[i], A, tolerance); } } } } /** accumulate_frames */ BOOST_AUTO_TEST_CASE (audio_buffers_accumulate_frames) { AudioBuffers a (3, 256); srand (38); random_fill (a); AudioBuffers b (3, 256); random_fill (b); a.accumulate_frames (&b, 129, 91, 44); srand (38); for (int i = 0; i < 256; ++i) { for (int c = 0; c < 3; ++c) { float const A = random_float (); if (i < 44 || i >= (44 + 129)) { BOOST_CHECK_CLOSE (a.data(c)[i], A, tolerance); } else { BOOST_CHECK_CLOSE (a.data(c)[i], A + b.data(c)[i + 91 - 44], tolerance); } } } } BOOST_AUTO_TEST_CASE (audio_buffers_data) { AudioBuffers a (94, 512); for (int i = 0; i < 94; ++i) { BOOST_CHECK_EQUAL (a.data()[i], a.data(i)); } a.set_frames (2048); for (int i = 0; i < 94; ++i) { BOOST_CHECK_EQUAL (a.data()[i], a.data(i)); } } BOOST_AUTO_TEST_CASE (audio_buffers_trim_start) { AudioBuffers a (13, 999); srand (55); random_fill (a); a.trim_start (101); srand (55); /* Burn the first 101 numbers in the sequence */ for (int i = 0; i < 101 * 13; ++i) { random_float (); } for (int i = 0; i < (999 - 101); ++i) { for (int j = 0; j < 13; ++j) { BOOST_CHECK_CLOSE (a.data(j)[i], random_float(), tolerance); } } } BOOST_AUTO_TEST_CASE(audio_buffers_set_channels_lower) { AudioBuffers buffers(9, 9933); srand(4); random_fill(buffers); buffers.set_channels(4); BOOST_REQUIRE_EQUAL(buffers.channels(), 4); srand(4); for (int i = 0; i < 9933; ++i) { for (int c = 0; c < 4; ++c) { BOOST_CHECK_EQUAL(buffers.data(c)[i], random_float()); } for (int c = 4; c < 9; ++c) { random_float(); } } } BOOST_AUTO_TEST_CASE(audio_buffers_set_channels_higher) { AudioBuffers buffers(9, 9933); srand(4); random_fill(buffers); buffers.set_channels(13); BOOST_REQUIRE_EQUAL(buffers.channels(), 13); srand(4); for (int i = 0; i < 9933; ++i) { for (int c = 0; c < 9; ++c) { BOOST_CHECK_EQUAL(buffers.data(c)[i], random_float()); } for (int c = 9; c < 13; ++c) { BOOST_CHECK_EQUAL(buffers.data(c)[i], 0); } } }