/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "TrackPlayerBaseTest" #include #include #include #include "test_execution_tracer.h" using namespace android; using namespace android::media; class TrackPlayer : public TrackPlayerBase, public AudioTrack::IAudioTrackCallback { public: // methods protected in base class using TrackPlayerBase::playerPause; using TrackPlayerBase::playerSetVolume; using TrackPlayerBase::playerStart; using TrackPlayerBase::playerStop; }; class TrackPlayerBaseTest : public ::testing::TestWithParam> { public: TrackPlayerBaseTest() : mDuration(std::get<0>(GetParam())), mPulseFreq(std::get<1>(GetParam())), mChannelCount(std::get<2>(GetParam())), mSampleRate(std::get<3>(GetParam())){}; virtual void SetUp() override { mFrameCount = mDuration * mSampleRate; audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(mChannelCount); sp track = new AudioTrack(mStreamType, mSampleRate, mFormat, channelMask, mFrameCount, mFlags, nullptr /* callback */, 0 /* notificationFrames */, AUDIO_SESSION_NONE); ASSERT_EQ(track->initCheck(), NO_ERROR); mPlayer = new TrackPlayer(); mPlayer->init(track.get(), mPlayer, PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA, AUDIO_SESSION_NONE); sp playerTrack = mPlayer->mAudioTrack; ASSERT_EQ(playerTrack->initCheck(), NO_ERROR); mBufferSize = mFrameCount * playerTrack->frameSize(); mBuffer.resize(mBufferSize, 0); // populate buffer ASSERT_NE(mPulseFreq, 0); int32_t nPulseSamples = mSampleRate / mPulseFreq; int32_t pulseSize = nPulseSamples * playerTrack->frameSize(); int32_t marker = 0; while (marker + pulseSize <= mBufferSize) { memset(mBuffer.data() + marker, 127, pulseSize / 2); marker += pulseSize; } } void playBuffer() { bool blocking = true; ssize_t nbytes = mPlayer->mAudioTrack->write(mBuffer.data(), mBufferSize, blocking); EXPECT_EQ(nbytes, mBufferSize) << "Did not write all data in blocking mode"; } const double mDuration; // seconds sp mPlayer; private: const double mPulseFreq; const uint32_t mChannelCount; const uint32_t mSampleRate; const audio_format_t mFormat = AUDIO_FORMAT_PCM_16_BIT; const audio_output_flags_t mFlags = AUDIO_OUTPUT_FLAG_NONE; const audio_stream_type_t mStreamType = AUDIO_STREAM_MUSIC; int32_t mBufferSize; int32_t mFrameCount; std::vector mBuffer; }; class PlaybackTestParam : public TrackPlayerBaseTest {}; TEST_P(PlaybackTestParam, PlaybackTest) { // no-op implementation EXPECT_TRUE(mPlayer->setStartDelayMs(0).isOk()); ASSERT_EQ(mPlayer->playerStart(), NO_ERROR); ASSERT_NO_FATAL_FAILURE(playBuffer()); EXPECT_EQ(mPlayer->playerStop(), NO_ERROR); } INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PlaybackTestParam, ::testing::Values(std::make_tuple(2.5, 25.0, 2, 48000))); class ChangeVolumeTestParam : public TrackPlayerBaseTest {}; TEST_P(ChangeVolumeTestParam, ChangeVolumeTest) { float volume = 1.0f; (void)mPlayer->setPlayerVolume(volume / 2, volume); ASSERT_TRUE(mPlayer->start().isOk()); ASSERT_EQ(mPlayer->playerSetVolume(), NO_ERROR); ASSERT_NO_FATAL_FAILURE(playBuffer()); EXPECT_TRUE(mPlayer->stop().isOk()); std::vector setVol = {0.95f, 0.05f, 0.5f, 0.25f, -1.0f, 1.0f, 1.0f}; std::vector setPan = {0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.5f, -0.5f}; ASSERT_TRUE(mPlayer->start().isOk()); for (int32_t i = 0; i < setVol.size(); i++) { EXPECT_TRUE(mPlayer->setVolume(setVol[i]).isOk()); EXPECT_TRUE(mPlayer->setPan(setPan[i]).isOk()); ASSERT_NO_FATAL_FAILURE(playBuffer()); } EXPECT_TRUE(mPlayer->stop().isOk()); } INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, ChangeVolumeTestParam, ::testing::Values(std::make_tuple(1.0, 100.0, 1, 24000))); class PauseTestParam : public TrackPlayerBaseTest {}; TEST_P(PauseTestParam, PauseTest) { ASSERT_EQ(mPlayer->playerStart(), NO_ERROR); ASSERT_NO_FATAL_FAILURE(playBuffer()); ASSERT_EQ(mPlayer->playerPause(), NO_ERROR); ASSERT_EQ(mPlayer->playerStart(), NO_ERROR); ASSERT_NO_FATAL_FAILURE(playBuffer()); EXPECT_EQ(mPlayer->playerStop(), NO_ERROR); for (int32_t i = 0; i < 5; i++) { ASSERT_TRUE(mPlayer->start().isOk()); ASSERT_NO_FATAL_FAILURE(playBuffer()); ASSERT_TRUE(mPlayer->pause().isOk()); } EXPECT_TRUE(mPlayer->stop().isOk()); } INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PauseTestParam, ::testing::Values(std::make_tuple(1.0, 75.0, 2, 24000))); int main(int argc, char** argv) { android::ProcessState::self()->startThreadPool(); ::testing::InitGoogleTest(&argc, argv); ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer()); return RUN_ALL_TESTS(); }