1 #include <cxxtest/TestSuite.h>
2 
3 #include "audio/decoders/raw.h"
4 #include "audio/audiostream.h"
5 
6 #include "helper.h"
7 
8 class RawStreamTestSuite : public CxxTest::TestSuite
9 {
10 private:
11 	template<typename T>
readBufferTestTemplate(const int sampleRate,const int time,const bool le,const bool isStereo)12 	void readBufferTestTemplate(const int sampleRate, const int time, const bool le, const bool isStereo) {
13 		int16 *sine;
14 		Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, le, isStereo);
15 
16 		const int totalSamples = sampleRate * time * (isStereo ? 2 : 1);
17 		int16 *buffer = new int16[totalSamples];
18 		TS_ASSERT_EQUALS(s->readBuffer(buffer, totalSamples), totalSamples);
19 		TS_ASSERT_EQUALS(memcmp(sine, buffer, sizeof(int16) * totalSamples), 0);
20 		TS_ASSERT_EQUALS(s->endOfData(), true);
21 
22 		delete[] sine;
23 		delete[] buffer;
24 		delete s;
25 	}
26 
27 public:
test_read_buffer_8_bit_signed_mono()28 	void test_read_buffer_8_bit_signed_mono() {
29 		readBufferTestTemplate<int8>(11025, 2, false, false);
30 	}
31 
test_read_buffer_8_bit_signed_stereo()32 	void test_read_buffer_8_bit_signed_stereo() {
33 		readBufferTestTemplate<int8>(11025, 2, false, true);
34 	}
35 
test_read_buffer_8_bit_unsigned_mono()36 	void test_read_buffer_8_bit_unsigned_mono() {
37 		readBufferTestTemplate<uint8>(11025, 2, false, false);
38 	}
39 
test_read_buffer_16_bit_signed_be_mono()40 	void test_read_buffer_16_bit_signed_be_mono() {
41 		readBufferTestTemplate<int16>(11025, 2, false, false);
42 	}
43 
test_read_buffer_16_bit_signed_be_stereo()44 	void test_read_buffer_16_bit_signed_be_stereo() {
45 		readBufferTestTemplate<int16>(11025, 2, false, true);
46 	}
47 
test_read_buffer_16_bit_unsigned_be_mono()48 	void test_read_buffer_16_bit_unsigned_be_mono() {
49 		readBufferTestTemplate<uint16>(11025, 2, false, false);
50 	}
51 
test_read_buffer_16_bit_unsigned_be_stereo()52 	void test_read_buffer_16_bit_unsigned_be_stereo() {
53 		readBufferTestTemplate<uint16>(11025, 2, false, true);
54 	}
55 
test_read_buffer_16_bit_signed_le_mono()56 	void test_read_buffer_16_bit_signed_le_mono() {
57 		readBufferTestTemplate<int16>(11025, 2, true, false);
58 	}
59 
test_read_buffer_16_bit_signed_le_stereo()60 	void test_read_buffer_16_bit_signed_le_stereo() {
61 		readBufferTestTemplate<int16>(11025, 2, true, true);
62 	}
63 
test_read_buffer_16_bit_unsigned_le_mono()64 	void test_read_buffer_16_bit_unsigned_le_mono() {
65 		readBufferTestTemplate<uint16>(11025, 2, true, false);
66 	}
67 
test_read_buffer_16_bit_unsigned_le_stereo()68 	void test_read_buffer_16_bit_unsigned_le_stereo() {
69 		readBufferTestTemplate<uint16>(11025, 2, true, true);
70 	}
71 
72 private:
partialReadTest()73 	void partialReadTest() {
74 		const int sampleRate = 11025;
75 		const int time = 4;
76 
77 		int16 *sine;
78 		Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, false, false);
79 		int16 *buffer = new int16[sampleRate * time];
80 
81 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate), sampleRate);
82 		TS_ASSERT_EQUALS(memcmp(sine, buffer, sampleRate), 0);
83 		TS_ASSERT_EQUALS(s->endOfData(), false);
84 
85 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * 2), sampleRate * 2);
86 		TS_ASSERT_EQUALS(memcmp(sine + sampleRate, buffer, sampleRate * 2), 0);
87 		TS_ASSERT_EQUALS(s->endOfData(), false);
88 
89 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate), sampleRate);
90 		TS_ASSERT_EQUALS(memcmp(sine + sampleRate * 3, buffer, sampleRate), 0);
91 		TS_ASSERT_EQUALS(s->endOfData(), true);
92 
93 		delete[] sine;
94 		delete[] buffer;
95 		delete s;
96 	}
97 public:
test_partial_read()98 	void test_partial_read() {
99 		partialReadTest();
100 	}
101 
102 private:
readAfterEndTest()103 	void readAfterEndTest() {
104 		const int sampleRate = 11025;
105 		const int time = 1;
106 		Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
107 		int16 *buffer = new int16[sampleRate * time];
108 
109 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
110 		TS_ASSERT_EQUALS(s->endOfData(), true);
111 
112 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), 0);
113 		TS_ASSERT_EQUALS(s->endOfData(), true);
114 
115 		delete[] buffer;
116 		delete s;
117 	}
118 
119 public:
test_read_after_end()120 	void test_read_after_end() {
121 		readAfterEndTest();
122 	}
123 
124 private:
rewindTest()125 	void rewindTest() {
126 		const int sampleRate = 11025;
127 		const int time = 2;
128 		Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
129 		int16 *buffer = new int16[sampleRate * time];
130 
131 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
132 		TS_ASSERT_EQUALS(s->endOfData(), true);
133 
134 		s->rewind();
135 		TS_ASSERT_EQUALS(s->endOfData(), false);
136 
137 		TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
138 		TS_ASSERT_EQUALS(s->endOfData(), true);
139 
140 		delete[] buffer;
141 		delete s;
142 	}
143 public:
test_rewind()144 	void test_rewind() {
145 		rewindTest();
146 	}
147 
148 private:
lengthTest()149 	void lengthTest() {
150 		int sampleRate = 0;
151 		const int time = 4;
152 
153 		Audio::SeekableAudioStream *s = 0;
154 
155 		// 11025 Hz tests
156 		sampleRate = 11025;
157 		s = createSineStream<int8>(sampleRate, time, 0, false, false);
158 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
159 		delete s;
160 
161 		s = createSineStream<uint16>(sampleRate, time, 0, false, false);
162 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
163 		delete s;
164 
165 		// 48000 Hz tests
166 		sampleRate = 48000;
167 		s = createSineStream<int8>(sampleRate, time, 0, false, false);
168 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
169 		delete s;
170 
171 		s = createSineStream<uint16>(sampleRate, time, 0, true, false);
172 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
173 		delete s;
174 
175 		// 11840 Hz tests
176 		sampleRate = 11840;
177 		s = createSineStream<int8>(sampleRate, time, 0, false, false);
178 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
179 		delete s;
180 
181 		s = createSineStream<uint16>(sampleRate, time, 0, false, false);
182 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
183 		delete s;
184 
185 		// 11111 Hz tests
186 		sampleRate = 11111;
187 		s = createSineStream<int8>(sampleRate, time, 0, false, false);
188 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
189 		delete s;
190 
191 		s = createSineStream<uint16>(sampleRate, time, 0, false, false);
192 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
193 		delete s;
194 
195 		// 22050 Hz stereo test
196 		sampleRate = 22050;
197 		s = createSineStream<int8>(sampleRate, time, 0, false, true);
198 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
199 		delete s;
200 
201 		s = createSineStream<uint16>(sampleRate, time, 0, true, true);
202 		TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
203 		delete s;
204 	}
205 
206 public:
test_length()207 	void test_length() {
208 		lengthTest();
209 	}
210 
211 private:
seekTest(const int sampleRate,const int time,const bool isStereo)212 	void seekTest(const int sampleRate, const int time, const bool isStereo) {
213 		const int totalFrames = sampleRate * time * (isStereo ? 2 : 1);
214 		int readData = 0, offset = 0;
215 
216 		int16 *buffer = new int16[totalFrames];
217 		Audio::SeekableAudioStream *s = 0;
218 		int16 *sine = 0;
219 
220 		s = createSineStream<int8>(sampleRate, time, &sine, false, isStereo);
221 
222 		// Seek to 500ms
223 		const Audio::Timestamp a(0, 1, 2);
224 		offset = Audio::convertTimeToStreamPos(a, sampleRate, isStereo).totalNumberOfFrames();
225 		readData = totalFrames - offset;
226 
227 		TS_ASSERT_EQUALS(s->seek(a), true);
228 		TS_ASSERT_EQUALS(s->endOfData(), false);
229 		TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
230 		TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
231 		TS_ASSERT_EQUALS(s->endOfData(), true);
232 
233 		// Seek to 3/4 of a second
234 		const Audio::Timestamp b(0, 3, 4);
235 		offset = Audio::convertTimeToStreamPos(b, sampleRate, isStereo).totalNumberOfFrames();
236 		readData = totalFrames - offset;
237 
238 		TS_ASSERT_EQUALS(s->seek(b), true);
239 		TS_ASSERT_EQUALS(s->endOfData(), false);
240 		TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
241 		TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
242 		TS_ASSERT_EQUALS(s->endOfData(), true);
243 
244 		// Seek to the start of the stream
245 		TS_ASSERT_EQUALS(s->seek(0), true);
246 		TS_ASSERT_EQUALS(s->endOfData(), false);
247 
248 		// Seek to the mid of the stream
249 		const Audio::Timestamp c(time * 1000 / 2, 1000);
250 		offset = Audio::convertTimeToStreamPos(c, sampleRate, isStereo).totalNumberOfFrames();
251 		readData = totalFrames - offset;
252 
253 		TS_ASSERT_EQUALS(s->seek(c), true);
254 		TS_ASSERT_EQUALS(s->endOfData(), false);
255 		TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
256 		TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
257 		TS_ASSERT_EQUALS(s->endOfData(), true);
258 
259 		// Seek to the 1/4th of the last second of the stream
260 		const Audio::Timestamp d(time - 1, 1, 4);
261 		offset = Audio::convertTimeToStreamPos(d, sampleRate, isStereo).totalNumberOfFrames();
262 		readData = totalFrames - offset;
263 
264 		TS_ASSERT_EQUALS(s->seek(d), true);
265 		TS_ASSERT_EQUALS(s->endOfData(), false);
266 		TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
267 		TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
268 		TS_ASSERT_EQUALS(s->endOfData(), true);
269 
270 		// Try to seek after the end of the stream
271 		TS_ASSERT_EQUALS(s->seek(Audio::Timestamp(time, 1, 100000)), false);
272 		TS_ASSERT_EQUALS(s->endOfData(), true);
273 
274 		// Try to seek exactly at the end of the stream
275 		TS_ASSERT_EQUALS(s->seek(Audio::Timestamp(time * 1000, 1000)), true);
276 		TS_ASSERT_EQUALS(s->endOfData(), true);
277 
278 		delete[] sine;
279 		delete s;
280 		delete[] buffer;
281 	}
282 
283 public:
test_seek_mono()284 	void test_seek_mono() {
285 		seekTest(11025, 2, false);
286 	}
287 
test_seek_stereo()288 	void test_seek_stereo() {
289 		seekTest(11025, 2, true);
290 	}
291 };
292