13
0
livetrax/libs/audiographer/tests/general/sample_format_converter_test.cc
Paul Davis b35518e212 switch from boost::{shared,weak}_ptr to std::{shared,weak}_ptr
This is mostly a simple lexical search+replace but the absence of operator< for
std::weak_ptr<T> leads to some complications, particularly with Evoral::Sequence
and ExportPortChannel.
2023-03-24 14:19:15 -06:00

215 lines
7.1 KiB
C++

#include "tests/utils.h"
#include "audiographer/general/sample_format_converter.h"
using namespace AudioGrapher;
class SampleFormatConverterTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE (SampleFormatConverterTest);
CPPUNIT_TEST (testInit);
CPPUNIT_TEST (testFrameCount);
CPPUNIT_TEST (testFloat);
CPPUNIT_TEST (testInt32);
CPPUNIT_TEST (testInt24);
CPPUNIT_TEST (testInt16);
CPPUNIT_TEST (testUint8);
CPPUNIT_TEST (testChannelCount);
CPPUNIT_TEST_SUITE_END ();
public:
void setUp()
{
samples = 128;
random_data = TestUtils::init_random_data(samples, 1.0);
}
void tearDown()
{
delete [] random_data;
}
void testInit()
{
// Float never uses dithering and should always use full 32 bits of data
std::shared_ptr<SampleFormatConverter<float> > f_converter (new SampleFormatConverter<float>(1));
f_converter->init (samples, D_Tri, 32); // Doesn't throw
CPPUNIT_ASSERT_THROW (f_converter->init (samples, D_Tri, 24), Exception);
CPPUNIT_ASSERT_THROW (f_converter->init (samples, D_Tri, 48), Exception);
/* Test that too large data widths throw.
We are fine with unnecessarily narrow data widths */
std::shared_ptr<SampleFormatConverter<int32_t> > i_converter (new SampleFormatConverter<int32_t>(1));
i_converter->init (samples, D_Tri, 32); // Doesn't throw
i_converter->init (samples, D_Tri, 24); // Doesn't throw
i_converter->init (samples, D_Tri, 8); // Doesn't throw
i_converter->init (samples, D_Tri, 16); // Doesn't throw
CPPUNIT_ASSERT_THROW (i_converter->init (samples, D_Tri, 48), Exception);
std::shared_ptr<SampleFormatConverter<int16_t> > i16_converter (new SampleFormatConverter<int16_t>(1));
i16_converter->init (samples, D_Tri, 16); // Doesn't throw
i16_converter->init (samples, D_Tri, 8); // Doesn't throw
CPPUNIT_ASSERT_THROW (i16_converter->init (samples, D_Tri, 32), Exception);
CPPUNIT_ASSERT_THROW (i16_converter->init (samples, D_Tri, 48), Exception);
std::shared_ptr<SampleFormatConverter<uint8_t> > ui_converter (new SampleFormatConverter<uint8_t>(1));
ui_converter->init (samples, D_Tri, 8); // Doesn't throw
ui_converter->init (samples, D_Tri, 4); // Doesn't throw
CPPUNIT_ASSERT_THROW (ui_converter->init (samples, D_Tri, 16), Exception);
}
void testFrameCount()
{
std::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
std::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
converter->init (samples, D_Tri, 32);
converter->add_output (sink);
samplecnt_t samples_output = 0;
{
ProcessContext<float> pc(random_data, samples / 2, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples / 2, samples_output);
}
{
ProcessContext<float> pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
}
{
ProcessContext<float> pc(random_data, samples + 1, 1);
CPPUNIT_ASSERT_THROW(converter->process (pc), Exception);
}
}
void testFloat()
{
std::shared_ptr<SampleFormatConverter<float> > converter (new SampleFormatConverter<float>(1));
std::shared_ptr<VectorSink<float> > sink (new VectorSink<float>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 32);
converter->add_output (sink);
converter->set_clip_floats (false);
ProcessContext<float> const pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_equals(sink->get_array(), random_data, samples));
// Make sure a few samples are < -1.0 and > 1.0
random_data[10] = -1.5;
random_data[20] = 1.5;
converter->set_clip_floats (true);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), samples));
for (samplecnt_t i = 0; i < samples; ++i) {
// fp comparison needs a bit of tolerance, 1.01 << 1.5
CPPUNIT_ASSERT(sink->get_data()[i] < 1.01);
CPPUNIT_ASSERT(sink->get_data()[i] > -1.01);
}
}
void testInt32()
{
std::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
std::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 32);
converter->add_output (sink);
ProcessContext<float> pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), samples));
}
void testInt24()
{
std::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
std::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 24);
converter->add_output (sink);
ProcessContext<float> pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), samples));
}
void testInt16()
{
std::shared_ptr<SampleFormatConverter<int16_t> > converter (new SampleFormatConverter<int16_t>(1));
std::shared_ptr<VectorSink<int16_t> > sink (new VectorSink<int16_t>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 16);
converter->add_output (sink);
ProcessContext<float> pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), samples));
}
void testUint8()
{
std::shared_ptr<SampleFormatConverter<uint8_t> > converter (new SampleFormatConverter<uint8_t>(1));
std::shared_ptr<VectorSink<uint8_t> > sink (new VectorSink<uint8_t>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 8);
converter->add_output (sink);
ProcessContext<float> pc(random_data, samples, 1);
converter->process (pc);
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (samples, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), samples));
}
void testChannelCount()
{
std::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(3));
std::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
samplecnt_t samples_output = 0;
converter->init(samples, D_Tri, 32);
converter->add_output (sink);
ProcessContext<float> pc(random_data, 4, 1);
CPPUNIT_ASSERT_THROW (converter->process (pc), Exception);
samplecnt_t new_sample_count = samples - (samples % 3);
converter->process (ProcessContext<float> (pc.data(), new_sample_count, 3));
samples_output = sink->get_data().size();
CPPUNIT_ASSERT_EQUAL (new_sample_count, samples_output);
CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), pc.samples()));
}
private:
float * random_data;
samplecnt_t samples;
};
CPPUNIT_TEST_SUITE_REGISTRATION (SampleFormatConverterTest);