summaryrefslogtreecommitdiff
path: root/libs/audiographer/tests/general/sr_converter_test.cc
blob: b2b7193ff68c408622958ee67da352109d0facff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "tests/utils.h"

#include "audiographer/general/sr_converter.h"

using namespace AudioGrapher;

class SampleRateConverterTest : public CppUnit::TestFixture
{
  CPPUNIT_TEST_SUITE (SampleRateConverterTest);
  CPPUNIT_TEST (testNoConversion);
  CPPUNIT_TEST (testUpsampleLength);
  CPPUNIT_TEST (testDownsampleLength);
  CPPUNIT_TEST (testRespectsEndOfInput);
  CPPUNIT_TEST_SUITE_END ();

  public:
	void setUp()
	{
		samples = 128;
		random_data = TestUtils::init_random_data(samples);
		sink.reset (new AppendingVectorSink<float>());
		grabber.reset (new ProcessContextGrabber<float>());
		converter.reset (new SampleRateConverter (1));
	}

	void tearDown()
	{
		delete [] random_data;
	}

	void testNoConversion()
	{
		assert (samples % 2 == 0);
		samplecnt_t const half_samples = samples / 2;
		samplecnt_t samples_output = 0;

		converter->init (44100, 44100);
		converter->add_output (sink);

		ProcessContext<float> c (random_data, half_samples, 1);
		converter->process (c);
		ProcessContext<float> c2 (&random_data[half_samples], half_samples, 1);
		c2.set_flag (ProcessContext<float>::EndOfInput);
		converter->process (c2);

		samples_output = sink->get_data().size();
		CPPUNIT_ASSERT_EQUAL (samples, samples_output);

		CPPUNIT_ASSERT (TestUtils::array_equals (random_data, sink->get_array(), samples));
	}

	void testUpsampleLength()
	{
		assert (samples % 2 == 0);
		samplecnt_t const half_samples = samples / 2;
		samplecnt_t samples_output = 0;

		converter->init (44100, 88200);
		converter->allocate_buffers (half_samples);
		converter->add_output (sink);

		ProcessContext<float> c (random_data, half_samples, 1);
		converter->process (c);
		ProcessContext<float> c2 (&random_data[half_samples], half_samples, 1);
		c2.set_flag (ProcessContext<float>::EndOfInput);
		converter->process (c2);

		samples_output = sink->get_data().size();
		samplecnt_t tolerance = 3;
		CPPUNIT_ASSERT (2 * samples - tolerance < samples_output && samples_output < 2 * samples + tolerance);
	}

	void testDownsampleLength()
	{
		assert (samples % 2 == 0);
		samplecnt_t const half_samples = samples / 2;
		samplecnt_t samples_output = 0;

		converter->init (88200, 44100);
		converter->allocate_buffers (half_samples);
		converter->add_output (sink);

		ProcessContext<float> c (random_data, half_samples, 1);
		converter->process (c);
		ProcessContext<float> c2 (&random_data[half_samples], half_samples, 1);
		c2.set_flag (ProcessContext<float>::EndOfInput);
		converter->process (c2);

		samples_output = sink->get_data().size();
		samplecnt_t tolerance = 3;
		CPPUNIT_ASSERT (half_samples - tolerance < samples_output && samples_output < half_samples + tolerance);
	}

	void testRespectsEndOfInput()
	{
		assert (samples % 2 == 0);
		samplecnt_t const half_samples = samples / 2;

		converter->init (44100, 48000);
		converter->allocate_buffers (half_samples);
		converter->add_output (grabber);

		ProcessContext<float> c (random_data, half_samples, 1);
		converter->process (c);
		ProcessContext<float> c2 (&random_data[half_samples], half_samples / 2, 1);
		c2.set_flag (ProcessContext<float>::EndOfInput);
		converter->process (c2);

		for (std::list<ProcessContext<float> >::iterator it = grabber->contexts.begin(); it != grabber->contexts.end(); ++it) {
			std::list<ProcessContext<float> >::iterator next = it; ++next;
			if (next == grabber->contexts.end()) {
				CPPUNIT_ASSERT (it->has_flag (ProcessContext<float>::EndOfInput));
			} else {
				CPPUNIT_ASSERT (!it->has_flag (ProcessContext<float>::EndOfInput));
			}
		}
	}


  private:
	boost::shared_ptr<SampleRateConverter > converter;
	boost::shared_ptr<AppendingVectorSink<float> > sink;
	boost::shared_ptr<ProcessContextGrabber<float> > grabber;

	float * random_data;
	samplecnt_t samples;
};

CPPUNIT_TEST_SUITE_REGISTRATION (SampleRateConverterTest);