TEST_F(SoundSourceProxyTest, open) { // This test piggy-backs off of the cover-test files. for (const auto& filePath: getFilePaths()) { ASSERT_TRUE(SoundSourceProxy::isFileNameSupported(filePath)); Mixxx::AudioSourcePointer pAudioSource(openAudioSource(filePath)); ASSERT_TRUE(!pAudioSource.isNull()); EXPECT_LT(0, pAudioSource->getChannelCount()); EXPECT_LT(0, pAudioSource->getSamplingRate()); EXPECT_LT(0, pAudioSource->getFrameCount()); } }
TEST_F(SoundSourceProxyTest, open) { // This test piggy-backs off of the cover-test files. for (const auto& filePath: getFilePaths()) { ASSERT_TRUE(SoundSourceProxy::isFileNameSupported(filePath)); Mixxx::AudioSourcePointer pAudioSource(openAudioSource(filePath)); // Obtaining an AudioSource may fail for unsupported file formats, // even if the corresponding file extension is supported, e.g. // AAC vs. ALAC in .m4a files if (pAudioSource.isNull()) { // skip test file continue; } EXPECT_LT(0, pAudioSource->getChannelCount()); EXPECT_LT(0, pAudioSource->getSamplingRate()); EXPECT_LT(0, pAudioSource->getFrameCount()); } }
TEST_F(SoundSourceProxyTest, seekForward) { const SINT kReadFrameCount = 10000; // According to API documentation of op_pcm_seek(): // "...decoding after seeking may not return exactly the same // values as would be obtained by decoding the stream straight // through. However, such differences are expected to be smaller // than the loss introduced by Opus's lossy compression." // NOTE(uklotzde): The current version 0.6 of opusfile doesn't // seem to support sample accurate seeking. The differences // between the samples decoded with continuous reading and // those samples decoded after seeking are quite noticeable! const CSAMPLE kOpusSeekDecodingError = 0.2f; for (const auto& filePath: getFilePaths()) { ASSERT_TRUE(SoundSourceProxy::isFileNameSupported(filePath)); qDebug() << "Seek forward test:" << filePath; Mixxx::AudioSourcePointer pContReadSource(openAudioSource(filePath)); ASSERT_FALSE(pContReadSource.isNull()); const SINT readSampleCount = pContReadSource->frames2samples(kReadFrameCount); SampleBuffer contReadData(readSampleCount); SampleBuffer seekReadData(readSampleCount); #ifdef __FFMPEGFILE__ if (dynamic_cast<Mixxx::SoundSourceFFmpeg*>(pContReadSource.data())) { if (filePath.endsWith(".mp3")) { qDebug() << "Skip test since it will fail using SoundSourceFFmpeg"; continue; } } #endif for (SINT contFrameIndex = 0; pContReadSource->isValidFrameIndex(contFrameIndex); contFrameIndex += kReadFrameCount) { // Read next chunk of frames for Cont source without seek const SINT contReadFrameCount = pContReadSource->readSampleFrames(kReadFrameCount, &contReadData[0]); Mixxx::AudioSourcePointer pSeekReadSource(openAudioSource(filePath)); ASSERT_FALSE(pSeekReadSource.isNull()); ASSERT_EQ(pContReadSource->getChannelCount(), pSeekReadSource->getChannelCount()); ASSERT_EQ(pContReadSource->getFrameCount(), pSeekReadSource->getFrameCount()); // Seek source to next chunk and read it const SINT seekFrameIndex = pSeekReadSource->seekSampleFrame(contFrameIndex); ASSERT_EQ(contFrameIndex, seekFrameIndex); const SINT seekReadFrameCount = pSeekReadSource->readSampleFrames(kReadFrameCount, &seekReadData[0]); // content of both buffers should be equal ASSERT_EQ(contReadFrameCount, seekReadFrameCount); const SINT readSampleCount = pContReadSource->frames2samples(contReadFrameCount); for (SINT readSampleOffset = 0; readSampleOffset < readSampleCount; ++readSampleOffset) { if (filePath.endsWith(".opus")) { EXPECT_NEAR(contReadData[readSampleOffset], seekReadData[readSampleOffset], kOpusSeekDecodingError) << "Mismatch in " << filePath.toStdString() << " at seek frame index " << seekFrameIndex << "/" << pContReadSource->getMaxFrameIndex() << " for read sample offset " << readSampleOffset; } else { // NOTE(uklotzde): The comparison EXPECT_EQ might be // replaced with EXPECT_FLOAT_EQ to guarantee almost // accurate seeking. Currently EXPECT_EQ works for all // tested file formats except Opus. EXPECT_EQ(contReadData[readSampleOffset], seekReadData[readSampleOffset]) << "Mismatch in " << filePath.toStdString() << " at seek frame index " << seekFrameIndex << "/" << pContReadSource->getMaxFrameIndex() << " for read sample offset " << readSampleOffset; } } } } }