1 #include "tests/utils.h"
3 #include "audiographer/general/sample_format_converter.h"
5 using namespace AudioGrapher;
7 class SampleFormatConverterTest : public CppUnit::TestFixture
9 CPPUNIT_TEST_SUITE (SampleFormatConverterTest);
10 CPPUNIT_TEST (testInit);
11 CPPUNIT_TEST (testFrameCount);
12 CPPUNIT_TEST (testFloat);
13 CPPUNIT_TEST (testInt32);
14 CPPUNIT_TEST (testInt24);
15 CPPUNIT_TEST (testInt16);
16 CPPUNIT_TEST (testUint8);
17 CPPUNIT_TEST (testChannelCount);
18 CPPUNIT_TEST_SUITE_END ();
24 random_data = TestUtils::init_random_data(frames, 1.0);
29 delete [] random_data;
34 // Float never uses dithering and should always use full 32 bits of data
35 boost::shared_ptr<SampleFormatConverter<float> > f_converter (new SampleFormatConverter<float>(1));
36 f_converter->init (frames, D_Tri, 32); // Doesn't throw
37 CPPUNIT_ASSERT_THROW (f_converter->init (frames, D_Tri, 24), Exception);
38 CPPUNIT_ASSERT_THROW (f_converter->init (frames, D_Tri, 48), Exception);
40 /* Test that too large data widths throw.
41 We are fine with unnecessarily narrow data widths */
43 boost::shared_ptr<SampleFormatConverter<int32_t> > i_converter (new SampleFormatConverter<int32_t>(1));
44 i_converter->init (frames, D_Tri, 32); // Doesn't throw
45 i_converter->init (frames, D_Tri, 24); // Doesn't throw
46 i_converter->init (frames, D_Tri, 8); // Doesn't throw
47 i_converter->init (frames, D_Tri, 16); // Doesn't throw
48 CPPUNIT_ASSERT_THROW (i_converter->init (frames, D_Tri, 48), Exception);
50 boost::shared_ptr<SampleFormatConverter<int16_t> > i16_converter (new SampleFormatConverter<int16_t>(1));
51 i16_converter->init (frames, D_Tri, 16); // Doesn't throw
52 i16_converter->init (frames, D_Tri, 8); // Doesn't throw
53 CPPUNIT_ASSERT_THROW (i16_converter->init (frames, D_Tri, 32), Exception);
54 CPPUNIT_ASSERT_THROW (i16_converter->init (frames, D_Tri, 48), Exception);
56 boost::shared_ptr<SampleFormatConverter<uint8_t> > ui_converter (new SampleFormatConverter<uint8_t>(1));
57 ui_converter->init (frames, D_Tri, 8); // Doesn't throw
58 ui_converter->init (frames, D_Tri, 4); // Doesn't throw
59 CPPUNIT_ASSERT_THROW (ui_converter->init (frames, D_Tri, 16), Exception);
64 boost::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
65 boost::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
67 converter->init (frames, D_Tri, 32);
68 converter->add_output (sink);
69 framecnt_t frames_output = 0;
72 ProcessContext<float> pc(random_data, frames / 2, 1);
73 converter->process (pc);
74 frames_output = sink->get_data().size();
75 CPPUNIT_ASSERT_EQUAL (frames / 2, frames_output);
79 ProcessContext<float> pc(random_data, frames, 1);
80 converter->process (pc);
81 frames_output = sink->get_data().size();
82 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
86 ProcessContext<float> pc(random_data, frames + 1, 1);
87 CPPUNIT_ASSERT_THROW(converter->process (pc), Exception);
93 boost::shared_ptr<SampleFormatConverter<float> > converter (new SampleFormatConverter<float>(1));
94 boost::shared_ptr<VectorSink<float> > sink (new VectorSink<float>());
95 framecnt_t frames_output = 0;
97 converter->init(frames, D_Tri, 32);
98 converter->add_output (sink);
100 converter->set_clip_floats (false);
101 ProcessContext<float> const pc(random_data, frames, 1);
102 converter->process (pc);
103 frames_output = sink->get_data().size();
104 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
105 CPPUNIT_ASSERT (TestUtils::array_equals(sink->get_array(), random_data, frames));
107 // Make sure a few samples are < -1.0 and > 1.0
108 random_data[10] = -1.5;
109 random_data[20] = 1.5;
111 converter->set_clip_floats (true);
112 converter->process (pc);
113 frames_output = sink->get_data().size();
114 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
115 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), frames));
117 for (framecnt_t i = 0; i < frames; ++i) {
118 // fp comparison needs a bit of tolerance, 1.01 << 1.5
119 CPPUNIT_ASSERT(sink->get_data()[i] < 1.01);
120 CPPUNIT_ASSERT(sink->get_data()[i] > -1.01);
126 boost::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
127 boost::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
128 framecnt_t frames_output = 0;
130 converter->init(frames, D_Tri, 32);
131 converter->add_output (sink);
133 ProcessContext<float> pc(random_data, frames, 1);
134 converter->process (pc);
135 frames_output = sink->get_data().size();
136 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
137 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), frames));
142 boost::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(1));
143 boost::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
144 framecnt_t frames_output = 0;
146 converter->init(frames, D_Tri, 24);
147 converter->add_output (sink);
149 ProcessContext<float> pc(random_data, frames, 1);
150 converter->process (pc);
151 frames_output = sink->get_data().size();
152 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
153 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), frames));
158 boost::shared_ptr<SampleFormatConverter<int16_t> > converter (new SampleFormatConverter<int16_t>(1));
159 boost::shared_ptr<VectorSink<int16_t> > sink (new VectorSink<int16_t>());
160 framecnt_t frames_output = 0;
162 converter->init(frames, D_Tri, 16);
163 converter->add_output (sink);
165 ProcessContext<float> pc(random_data, frames, 1);
166 converter->process (pc);
167 frames_output = sink->get_data().size();
168 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
169 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), frames));
174 boost::shared_ptr<SampleFormatConverter<uint8_t> > converter (new SampleFormatConverter<uint8_t>(1));
175 boost::shared_ptr<VectorSink<uint8_t> > sink (new VectorSink<uint8_t>());
176 framecnt_t frames_output = 0;
178 converter->init(frames, D_Tri, 8);
179 converter->add_output (sink);
181 ProcessContext<float> pc(random_data, frames, 1);
182 converter->process (pc);
183 frames_output = sink->get_data().size();
184 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
185 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), frames));
188 void testChannelCount()
190 boost::shared_ptr<SampleFormatConverter<int32_t> > converter (new SampleFormatConverter<int32_t>(3));
191 boost::shared_ptr<VectorSink<int32_t> > sink (new VectorSink<int32_t>());
192 framecnt_t frames_output = 0;
194 converter->init(frames, D_Tri, 32);
195 converter->add_output (sink);
197 ProcessContext<float> pc(random_data, 4, 1);
198 CPPUNIT_ASSERT_THROW (converter->process (pc), Exception);
200 framecnt_t new_frame_count = frames - (frames % 3);
201 converter->process (ProcessContext<float> (pc.data(), new_frame_count, 3));
202 frames_output = sink->get_data().size();
203 CPPUNIT_ASSERT_EQUAL (new_frame_count, frames_output);
204 CPPUNIT_ASSERT (TestUtils::array_filled(sink->get_array(), pc.frames()));
213 CPPUNIT_TEST_SUITE_REGISTRATION (SampleFormatConverterTest);