2010-02-03 10:36:14 +00:00
|
|
|
#include <cxxtest/TestSuite.h>
|
|
|
|
|
2011-02-09 01:09:01 +00:00
|
|
|
#include "audio/decoders/raw.h"
|
2010-02-03 10:36:14 +00:00
|
|
|
|
2010-02-06 16:41:27 +00:00
|
|
|
#include "helper.h"
|
2010-02-03 10:36:14 +00:00
|
|
|
|
|
|
|
class RawStreamTestSuite : public CxxTest::TestSuite
|
|
|
|
{
|
2010-02-03 17:03:46 +00:00
|
|
|
private:
|
|
|
|
template<typename T>
|
2011-11-06 13:19:17 +00:00
|
|
|
void readBufferTestTemplate(const int sampleRate, const int time, const bool le, const bool isStereo) {
|
2010-02-03 15:25:06 +00:00
|
|
|
int16 *sine;
|
2011-11-06 13:19:17 +00:00
|
|
|
Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, le, isStereo);
|
2010-02-03 10:36:14 +00:00
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
const int totalSamples = sampleRate * time * (isStereo ? 2 : 1);
|
|
|
|
int16 *buffer = new int16[totalSamples];
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, totalSamples), totalSamples);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(sine, buffer, sizeof(int16) * totalSamples), 0);
|
2010-02-03 15:25:06 +00:00
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
2010-02-03 10:36:14 +00:00
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
delete[] sine;
|
|
|
|
delete[] buffer;
|
|
|
|
delete s;
|
2010-02-03 10:36:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
public:
|
|
|
|
void test_read_buffer_8_bit_signed_mono() {
|
|
|
|
readBufferTestTemplate<int8>(11025, 2, false, false);
|
|
|
|
}
|
2010-02-03 16:02:25 +00:00
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
void test_read_buffer_8_bit_signed_stereo() {
|
|
|
|
readBufferTestTemplate<int8>(11025, 2, false, true);
|
2010-02-03 16:02:25 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
void test_read_buffer_8_bit_unsigned_mono() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<uint8>(11025, 2, false, false);
|
2010-02-03 10:36:14 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
void test_read_buffer_16_bit_signed_be_mono() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<int16>(11025, 2, false, false);
|
2010-02-03 15:25:06 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 16:02:25 +00:00
|
|
|
void test_read_buffer_16_bit_signed_be_stereo() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<int16>(11025, 2, false, true);
|
2010-02-03 16:02:25 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
void test_read_buffer_16_bit_unsigned_be_mono() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<uint16>(11025, 2, false, false);
|
2010-02-03 10:36:14 +00:00
|
|
|
}
|
2010-02-03 15:24:24 +00:00
|
|
|
|
2010-02-09 15:23:03 +00:00
|
|
|
void test_read_buffer_16_bit_unsigned_be_stereo() {
|
|
|
|
readBufferTestTemplate<uint16>(11025, 2, false, true);
|
|
|
|
}
|
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
void test_read_buffer_16_bit_signed_le_mono() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<int16>(11025, 2, true, false);
|
2010-02-03 15:25:06 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 15:23:03 +00:00
|
|
|
void test_read_buffer_16_bit_signed_le_stereo() {
|
|
|
|
readBufferTestTemplate<int16>(11025, 2, true, true);
|
|
|
|
}
|
|
|
|
|
2010-02-03 15:25:06 +00:00
|
|
|
void test_read_buffer_16_bit_unsigned_le_mono() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<uint16>(11025, 2, true, false);
|
2010-02-03 15:24:24 +00:00
|
|
|
}
|
2010-02-03 15:44:43 +00:00
|
|
|
|
2010-02-03 16:02:25 +00:00
|
|
|
void test_read_buffer_16_bit_unsigned_le_stereo() {
|
2010-02-03 17:03:46 +00:00
|
|
|
readBufferTestTemplate<uint16>(11025, 2, true, true);
|
2010-02-03 16:02:25 +00:00
|
|
|
}
|
|
|
|
|
2010-02-09 15:23:03 +00:00
|
|
|
private:
|
2011-11-06 13:19:17 +00:00
|
|
|
void partialReadTest() {
|
2010-02-03 15:45:08 +00:00
|
|
|
const int sampleRate = 11025;
|
|
|
|
const int time = 4;
|
|
|
|
|
|
|
|
int16 *sine;
|
2011-11-06 13:19:17 +00:00
|
|
|
Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, &sine, false, false);
|
2010-02-03 15:45:08 +00:00
|
|
|
int16 *buffer = new int16[sampleRate * time];
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate), sampleRate);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(sine, buffer, sampleRate), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * 2), sampleRate * 2);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(sine + sampleRate, buffer, sampleRate * 2), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate), sampleRate);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(sine + sampleRate * 3, buffer, sampleRate), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
delete[] sine;
|
|
|
|
delete[] buffer;
|
|
|
|
delete s;
|
|
|
|
}
|
2010-02-09 15:23:03 +00:00
|
|
|
public:
|
|
|
|
void test_partial_read() {
|
2011-11-06 13:19:17 +00:00
|
|
|
partialReadTest();
|
2010-02-09 15:23:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2011-11-06 13:19:17 +00:00
|
|
|
void readAfterEndTest() {
|
2010-02-03 15:45:08 +00:00
|
|
|
const int sampleRate = 11025;
|
|
|
|
const int time = 1;
|
2010-02-03 16:02:25 +00:00
|
|
|
Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 15:45:08 +00:00
|
|
|
int16 *buffer = new int16[sampleRate * time];
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
delete[] buffer;
|
|
|
|
delete s;
|
|
|
|
}
|
|
|
|
|
2010-02-09 15:23:03 +00:00
|
|
|
public:
|
|
|
|
void test_read_after_end() {
|
2011-11-06 13:19:17 +00:00
|
|
|
readAfterEndTest();
|
2010-02-09 15:23:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2011-11-06 13:19:17 +00:00
|
|
|
void rewindTest() {
|
2010-02-03 15:44:43 +00:00
|
|
|
const int sampleRate = 11025;
|
|
|
|
const int time = 2;
|
2011-11-06 13:19:17 +00:00
|
|
|
Audio::SeekableAudioStream *s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 15:44:43 +00:00
|
|
|
int16 *buffer = new int16[sampleRate * time];
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
s->rewind();
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, sampleRate * time), sampleRate * time);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
delete[] buffer;
|
|
|
|
delete s;
|
|
|
|
}
|
2010-02-09 15:23:03 +00:00
|
|
|
public:
|
|
|
|
void test_rewind() {
|
2011-11-06 13:19:17 +00:00
|
|
|
rewindTest();
|
2010-02-09 15:23:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2011-11-06 13:19:17 +00:00
|
|
|
void lengthTest() {
|
2010-02-03 16:02:04 +00:00
|
|
|
int sampleRate = 0;
|
2010-02-03 15:45:29 +00:00
|
|
|
const int time = 4;
|
|
|
|
|
|
|
|
Audio::SeekableAudioStream *s = 0;
|
|
|
|
|
2010-02-03 16:02:04 +00:00
|
|
|
// 11025 Hz tests
|
|
|
|
sampleRate = 11025;
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<uint16>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
|
|
|
// 48000 Hz tests
|
|
|
|
sampleRate = 48000;
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<uint16>(sampleRate, time, 0, true, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
|
|
|
// 11840 Hz tests
|
|
|
|
sampleRate = 11840;
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<uint16>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:04 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
|
|
|
// 11111 Hz tests
|
|
|
|
sampleRate = 11111;
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:25 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<uint16>(sampleRate, time, 0, false, false);
|
2010-02-03 16:02:25 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
|
|
|
// 22050 Hz stereo test
|
|
|
|
sampleRate = 22050;
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, 0, false, true);
|
2010-02-03 15:45:29 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<uint16>(sampleRate, time, 0, true, true);
|
2010-02-03 15:45:29 +00:00
|
|
|
TS_ASSERT_EQUALS(s->getLength().totalNumberOfFrames(), sampleRate * time);
|
|
|
|
delete s;
|
|
|
|
}
|
2010-02-03 16:57:46 +00:00
|
|
|
|
2010-02-09 15:23:03 +00:00
|
|
|
public:
|
|
|
|
void test_length() {
|
2011-11-06 13:19:17 +00:00
|
|
|
lengthTest();
|
2010-02-09 15:23:03 +00:00
|
|
|
}
|
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
private:
|
2011-11-06 13:19:17 +00:00
|
|
|
void seekTest(const int sampleRate, const int time, const bool isStereo) {
|
2010-02-03 16:57:46 +00:00
|
|
|
const int totalFrames = sampleRate * time * (isStereo ? 2 : 1);
|
|
|
|
int readData = 0, offset = 0;
|
|
|
|
|
|
|
|
int16 *buffer = new int16[totalFrames];
|
|
|
|
Audio::SeekableAudioStream *s = 0;
|
|
|
|
int16 *sine = 0;
|
|
|
|
|
2011-11-06 13:19:17 +00:00
|
|
|
s = createSineStream<int8>(sampleRate, time, &sine, false, isStereo);
|
2010-02-03 16:57:46 +00:00
|
|
|
|
|
|
|
// Seek to 500ms
|
|
|
|
const Audio::Timestamp a(0, 1, 2);
|
2010-02-03 17:03:46 +00:00
|
|
|
offset = Audio::convertTimeToStreamPos(a, sampleRate, isStereo).totalNumberOfFrames();
|
2010-02-03 16:57:46 +00:00
|
|
|
readData = totalFrames - offset;
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->seek(a), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
// Seek to 3/4 of a second
|
|
|
|
const Audio::Timestamp b(0, 3, 4);
|
2010-02-03 17:03:46 +00:00
|
|
|
offset = Audio::convertTimeToStreamPos(b, sampleRate, isStereo).totalNumberOfFrames();
|
2010-02-03 16:57:46 +00:00
|
|
|
readData = totalFrames - offset;
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->seek(b), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
// Seek to the start of the stream
|
|
|
|
TS_ASSERT_EQUALS(s->seek(0), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
|
|
|
|
// Seek to the mid of the stream
|
|
|
|
const Audio::Timestamp c(time * 1000 / 2, 1000);
|
2010-02-03 17:03:46 +00:00
|
|
|
offset = Audio::convertTimeToStreamPos(c, sampleRate, isStereo).totalNumberOfFrames();
|
2010-02-03 16:57:46 +00:00
|
|
|
readData = totalFrames - offset;
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->seek(c), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
// Seek to the 1/4th of the last second of the stream
|
|
|
|
const Audio::Timestamp d(time - 1, 1, 4);
|
2010-02-03 17:03:46 +00:00
|
|
|
offset = Audio::convertTimeToStreamPos(d, sampleRate, isStereo).totalNumberOfFrames();
|
2010-02-03 16:57:46 +00:00
|
|
|
readData = totalFrames - offset;
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS(s->seek(d), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), false);
|
|
|
|
TS_ASSERT_EQUALS(s->readBuffer(buffer, readData), readData);
|
|
|
|
TS_ASSERT_EQUALS(memcmp(buffer, sine + offset, readData * sizeof(int16)), 0);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
// Try to seek after the end of the stream
|
2010-02-08 21:25:10 +00:00
|
|
|
TS_ASSERT_EQUALS(s->seek(Audio::Timestamp(time, 1, 100000)), false);
|
2010-02-03 16:57:46 +00:00
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
// Try to seek exactly at the end of the stream
|
|
|
|
TS_ASSERT_EQUALS(s->seek(Audio::Timestamp(time * 1000, 1000)), true);
|
|
|
|
TS_ASSERT_EQUALS(s->endOfData(), true);
|
|
|
|
|
|
|
|
delete[] sine;
|
|
|
|
delete s;
|
|
|
|
delete[] buffer;
|
|
|
|
}
|
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
public:
|
|
|
|
void test_seek_mono() {
|
2011-11-06 13:19:17 +00:00
|
|
|
seekTest(11025, 2, false);
|
2010-02-03 17:03:46 +00:00
|
|
|
}
|
2010-02-03 16:57:46 +00:00
|
|
|
|
2010-02-03 17:03:46 +00:00
|
|
|
void test_seek_stereo() {
|
2011-11-06 13:19:17 +00:00
|
|
|
seekTest(11025, 2, true);
|
2010-02-03 16:57:46 +00:00
|
|
|
}
|
2010-02-03 10:36:14 +00:00
|
|
|
};
|