- Fix process callbakc handling during export
[ardour.git] / libs / audiographer / tests / sr_converter_test.cc
1 #include "utils.h"
2 #include "audiographer/sr_converter.h"
3
4 using namespace AudioGrapher;
5
6 class SampleRateConverterTest : public CppUnit::TestFixture
7 {
8   CPPUNIT_TEST_SUITE (SampleRateConverterTest);
9   CPPUNIT_TEST (testNoConversion);
10   CPPUNIT_TEST (testUpsampleLength);
11   CPPUNIT_TEST (testDownsampleLength);
12   CPPUNIT_TEST (testRespectsEndOfInput);
13   CPPUNIT_TEST_SUITE_END ();
14
15   public:
16         void setUp()
17         {
18                 frames = 128;
19                 random_data = TestUtils::init_random_data(frames);
20                 sink.reset (new AppendingVectorSink<float>());
21                 grabber.reset (new ProcessContextGrabber<float>());
22                 converter.reset (new SampleRateConverter (1));
23         }
24
25         void tearDown()
26         {
27                 delete [] random_data;
28         }
29
30         void testNoConversion()
31         {
32                 assert (frames % 2 == 0);
33                 nframes_t const half_frames = frames / 2;
34                 nframes_t frames_output = 0;
35                 
36                 converter->init (44100, 44100);
37                 converter->add_output (sink);
38                 
39                 ProcessContext<float> c (random_data, half_frames, 1);
40                 converter->process (c);
41                 ProcessContext<float> c2 (&random_data[half_frames], half_frames, 1);
42                 c2.set_flag (ProcessContext<float>::EndOfInput);
43                 converter->process (c2);
44                 
45                 frames_output = sink->get_data().size();
46                 CPPUNIT_ASSERT_EQUAL (frames, frames_output);
47                 
48                 CPPUNIT_ASSERT (TestUtils::array_equals (random_data, sink->get_array(), frames));
49         }
50
51         void testUpsampleLength()
52         {
53                 assert (frames % 2 == 0);
54                 nframes_t const half_frames = frames / 2;
55                 nframes_t frames_output = 0;
56                 
57                 converter->init (44100, 88200);
58                 converter->allocate_buffers (half_frames);
59                 converter->add_output (sink);
60                 
61                 ProcessContext<float> c (random_data, half_frames, 1);
62                 converter->process (c);
63                 ProcessContext<float> c2 (&random_data[half_frames], half_frames, 1);
64                 c2.set_flag (ProcessContext<float>::EndOfInput);
65                 converter->process (c2);
66
67                 frames_output = sink->get_data().size();
68                 nframes_t tolerance = 3;
69                 CPPUNIT_ASSERT (2 * frames - tolerance < frames_output && frames_output < 2 * frames + tolerance);
70         }
71
72         void testDownsampleLength()
73         {
74                 assert (frames % 2 == 0);
75                 nframes_t const half_frames = frames / 2;
76                 nframes_t frames_output = 0;
77                 
78                 converter->init (88200, 44100);
79                 converter->allocate_buffers (half_frames);
80                 converter->add_output (sink);
81                 
82                 ProcessContext<float> c (random_data, half_frames, 1);
83                 converter->process (c);
84                 ProcessContext<float> c2 (&random_data[half_frames], half_frames, 1);
85                 c2.set_flag (ProcessContext<float>::EndOfInput);
86                 converter->process (c2);
87                 
88                 frames_output = sink->get_data().size();
89                 nframes_t tolerance = 3;
90                 CPPUNIT_ASSERT (half_frames - tolerance < frames_output && frames_output < half_frames + tolerance);
91         }
92         
93         void testRespectsEndOfInput()
94         {
95                 assert (frames % 2 == 0);
96                 nframes_t const half_frames = frames / 2;
97                 
98                 converter->init (44100, 48000);
99                 converter->allocate_buffers (half_frames);
100                 converter->add_output (grabber);
101                 
102                 ProcessContext<float> c (random_data, half_frames, 1);
103                 converter->process (c);
104                 ProcessContext<float> c2 (&random_data[half_frames], half_frames / 2, 1);
105                 c2.set_flag (ProcessContext<float>::EndOfInput);
106                 converter->process (c2);
107                 
108                 for (std::list<ProcessContext<float> >::iterator it = grabber->contexts.begin(); it != grabber->contexts.end(); ++it) {
109                         std::list<ProcessContext<float> >::iterator next = it; ++next;
110                         if (next == grabber->contexts.end()) {
111                                 CPPUNIT_ASSERT (it->has_flag (ProcessContext<float>::EndOfInput));
112                         } else {
113                                 CPPUNIT_ASSERT (!it->has_flag (ProcessContext<float>::EndOfInput));
114                         }
115                 }
116         }
117         
118
119   private:
120         boost::shared_ptr<SampleRateConverter > converter;
121         boost::shared_ptr<AppendingVectorSink<float> > sink;
122         boost::shared_ptr<ProcessContextGrabber<float> > grabber;
123
124         float * random_data;
125         nframes_t frames;
126 };
127
128 CPPUNIT_TEST_SUITE_REGISTRATION (SampleRateConverterTest);
129