1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "TrackPlayerBaseTest"
18 
19 #include <binder/ProcessState.h>
20 #include <gtest/gtest.h>
21 #include <media/TrackPlayerBase.h>
22 
23 #include "test_execution_tracer.h"
24 
25 using namespace android;
26 using namespace android::media;
27 
28 class TrackPlayer : public TrackPlayerBase, public AudioTrack::IAudioTrackCallback {
29   public:
30     // methods protected in base class
31     using TrackPlayerBase::playerPause;
32     using TrackPlayerBase::playerSetVolume;
33     using TrackPlayerBase::playerStart;
34     using TrackPlayerBase::playerStop;
35 };
36 
37 class TrackPlayerBaseTest
38     : public ::testing::TestWithParam<std::tuple<double, double, uint32_t, uint32_t>> {
39   public:
TrackPlayerBaseTest()40     TrackPlayerBaseTest()
41         : mDuration(std::get<0>(GetParam())),
42           mPulseFreq(std::get<1>(GetParam())),
43           mChannelCount(std::get<2>(GetParam())),
44           mSampleRate(std::get<3>(GetParam())){};
45 
SetUp()46     virtual void SetUp() override {
47         mFrameCount = mDuration * mSampleRate;
48         audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(mChannelCount);
49         sp<AudioTrack> track = new AudioTrack(mStreamType, mSampleRate, mFormat, channelMask,
50                                               mFrameCount, mFlags, nullptr /* callback */,
51                                               0 /* notificationFrames */, AUDIO_SESSION_NONE);
52         ASSERT_EQ(track->initCheck(), NO_ERROR);
53 
54         mPlayer = new TrackPlayer();
55         mPlayer->init(track.get(), mPlayer, PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA,
56                       AUDIO_SESSION_NONE);
57         sp<AudioTrack> playerTrack = mPlayer->mAudioTrack;
58         ASSERT_EQ(playerTrack->initCheck(), NO_ERROR);
59 
60         mBufferSize = mFrameCount * playerTrack->frameSize();
61         mBuffer.resize(mBufferSize, 0);
62 
63         // populate buffer
64         ASSERT_NE(mPulseFreq, 0);
65         int32_t nPulseSamples = mSampleRate / mPulseFreq;
66         int32_t pulseSize = nPulseSamples * playerTrack->frameSize();
67 
68         int32_t marker = 0;
69         while (marker + pulseSize <= mBufferSize) {
70             memset(mBuffer.data() + marker, 127, pulseSize / 2);
71             marker += pulseSize;
72         }
73     }
74 
playBuffer()75     void playBuffer() {
76         bool blocking = true;
77         ssize_t nbytes = mPlayer->mAudioTrack->write(mBuffer.data(), mBufferSize, blocking);
78         EXPECT_EQ(nbytes, mBufferSize) << "Did not write all data in blocking mode";
79     }
80 
81     const double mDuration;  // seconds
82     sp<TrackPlayer> mPlayer;
83 
84   private:
85     const double mPulseFreq;
86     const uint32_t mChannelCount;
87     const uint32_t mSampleRate;
88 
89     const audio_format_t mFormat = AUDIO_FORMAT_PCM_16_BIT;
90     const audio_output_flags_t mFlags = AUDIO_OUTPUT_FLAG_NONE;
91     const audio_stream_type_t mStreamType = AUDIO_STREAM_MUSIC;
92 
93     int32_t mBufferSize;
94     int32_t mFrameCount;
95     std::vector<uint8_t> mBuffer;
96 };
97 
98 class PlaybackTestParam : public TrackPlayerBaseTest {};
99 
TEST_P(PlaybackTestParam,PlaybackTest)100 TEST_P(PlaybackTestParam, PlaybackTest) {
101     // no-op implementation
102     EXPECT_TRUE(mPlayer->setStartDelayMs(0).isOk());
103 
104     ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
105     ASSERT_NO_FATAL_FAILURE(playBuffer());
106     EXPECT_EQ(mPlayer->playerStop(), NO_ERROR);
107 }
108 
109 INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PlaybackTestParam,
110                          ::testing::Values(std::make_tuple(2.5, 25.0, 2, 48000)));
111 
112 class ChangeVolumeTestParam : public TrackPlayerBaseTest {};
113 
TEST_P(ChangeVolumeTestParam,ChangeVolumeTest)114 TEST_P(ChangeVolumeTestParam, ChangeVolumeTest) {
115     float volume = 1.0f;
116     (void)mPlayer->setPlayerVolume(volume / 2, volume);
117 
118     ASSERT_TRUE(mPlayer->start().isOk());
119     ASSERT_EQ(mPlayer->playerSetVolume(), NO_ERROR);
120 
121     ASSERT_NO_FATAL_FAILURE(playBuffer());
122 
123     EXPECT_TRUE(mPlayer->stop().isOk());
124 
125     std::vector<float> setVol = {0.95f, 0.05f, 0.5f, 0.25f, -1.0f, 1.0f, 1.0f};
126     std::vector<float> setPan = {0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.5f, -0.5f};
127 
128     ASSERT_TRUE(mPlayer->start().isOk());
129 
130     for (int32_t i = 0; i < setVol.size(); i++) {
131         EXPECT_TRUE(mPlayer->setVolume(setVol[i]).isOk());
132         EXPECT_TRUE(mPlayer->setPan(setPan[i]).isOk());
133         ASSERT_NO_FATAL_FAILURE(playBuffer());
134     }
135     EXPECT_TRUE(mPlayer->stop().isOk());
136 }
137 
138 INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, ChangeVolumeTestParam,
139                          ::testing::Values(std::make_tuple(1.0, 100.0, 1, 24000)));
140 
141 class PauseTestParam : public TrackPlayerBaseTest {};
142 
TEST_P(PauseTestParam,PauseTest)143 TEST_P(PauseTestParam, PauseTest) {
144     ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
145     ASSERT_NO_FATAL_FAILURE(playBuffer());
146 
147     ASSERT_EQ(mPlayer->playerPause(), NO_ERROR);
148     ASSERT_EQ(mPlayer->playerStart(), NO_ERROR);
149 
150     ASSERT_NO_FATAL_FAILURE(playBuffer());
151 
152     EXPECT_EQ(mPlayer->playerStop(), NO_ERROR);
153 
154     for (int32_t i = 0; i < 5; i++) {
155         ASSERT_TRUE(mPlayer->start().isOk());
156         ASSERT_NO_FATAL_FAILURE(playBuffer());
157         ASSERT_TRUE(mPlayer->pause().isOk());
158     }
159     EXPECT_TRUE(mPlayer->stop().isOk());
160 }
161 
162 INSTANTIATE_TEST_SUITE_P(TrackPlayerTest, PauseTestParam,
163                          ::testing::Values(std::make_tuple(1.0, 75.0, 2, 24000)));
164 
main(int argc,char ** argv)165 int main(int argc, char** argv) {
166     android::ProcessState::self()->startThreadPool();
167     ::testing::InitGoogleTest(&argc, argv);
168     ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
169     return RUN_ALL_TESTS();
170 }
171