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_NDEBUG 0
18 #define LOG_TAG "AudioTrackTests"
19
20 #include <binder/ProcessState.h>
21 #include <gtest/gtest.h>
22
23 #include "audio_test_utils.h"
24 #include "test_execution_tracer.h"
25
26 using namespace android;
27
28 // Test that the basic constructor returns an object that doesn't crash
29 // on stop() or destruction.
30
TEST(AudioTrackTestBasic,EmptyAudioTrack)31 TEST(AudioTrackTestBasic, EmptyAudioTrack) {
32 AttributionSourceState attributionSource;
33 attributionSource.packageName = "AudioTrackTest";
34 attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
35 attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
36 attributionSource.token = sp<BBinder>::make();
37 const auto at = sp<AudioTrack>::make(attributionSource);
38
39 EXPECT_EQ(NO_INIT, at->initCheck());
40 EXPECT_EQ(true, at->stopped());
41
42 // ensure we do not crash.
43 at->stop();
44 }
45
TEST(AudioTrackTest,TestPlayTrack)46 TEST(AudioTrackTest, TestPlayTrack) {
47 const auto ap = sp<AudioPlayback>::make(44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
48 AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
49 AUDIO_SESSION_NONE, AudioTrack::TRANSFER_OBTAIN);
50 ASSERT_NE(nullptr, ap);
51 ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
52 << "Unable to open Resource";
53 EXPECT_EQ(OK, ap->create()) << "track creation failed";
54 EXPECT_EQ(OK, ap->start()) << "audio track start failed";
55 EXPECT_EQ(OK, ap->onProcess());
56 ap->stop();
57 }
58
TEST(AudioTrackTest,TestSeek)59 TEST(AudioTrackTest, TestSeek) {
60 const auto ap = sp<AudioPlayback>::make(
61 44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO);
62 ASSERT_NE(nullptr, ap);
63 ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
64 << "Unable to open Resource";
65 EXPECT_EQ(OK, ap->create()) << "track creation failed";
66 EXPECT_EQ(OK, ap->start()) << "audio track start failed";
67 EXPECT_EQ(OK, ap->onProcess(true));
68 ap->stop();
69 }
70
TEST(AudioTrackTest,OffloadOrDirectPlayback)71 TEST(AudioTrackTest, OffloadOrDirectPlayback) {
72 audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
73 info.sample_rate = 44100;
74 info.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
75 info.format = AUDIO_FORMAT_MP3;
76 info.stream_type = AUDIO_STREAM_MUSIC;
77 info.bit_rate = 192;
78 info.duration_us = 120 * 1000000; // 120 sec
79
80 audio_config_base_t config = {/* .sample_rate = */ info.sample_rate,
81 /* .channel_mask = */ info.channel_mask,
82 /* .format = */ AUDIO_FORMAT_PCM_16_BIT};
83 audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
84 attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
85 attributes.usage = AUDIO_USAGE_MEDIA;
86 attributes.flags = AUDIO_FLAG_NONE;
87
88 if (!AudioTrack::isDirectOutputSupported(config, attributes) &&
89 AUDIO_OFFLOAD_NOT_SUPPORTED == AudioSystem::getOffloadSupport(info)) {
90 GTEST_SKIP() << "offload or direct playback is not supported";
91 }
92 sp<AudioPlayback> ap = nullptr;
93 if (AUDIO_OFFLOAD_NOT_SUPPORTED != AudioSystem::getOffloadSupport(info)) {
94 ap = sp<AudioPlayback>::make(info.sample_rate, info.format, info.channel_mask,
95 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, AUDIO_SESSION_NONE,
96 AudioTrack::TRANSFER_OBTAIN, nullptr, &info);
97 } else {
98 ap = sp<AudioPlayback>::make(config.sample_rate, config.format, config.channel_mask,
99 AUDIO_OUTPUT_FLAG_DIRECT, AUDIO_SESSION_NONE,
100 AudioTrack::TRANSFER_OBTAIN);
101 }
102 ASSERT_NE(nullptr, ap);
103 EXPECT_EQ(OK, ap->create()) << "track creation failed";
104 audio_dual_mono_mode_t mode;
105 if (OK != ap->getAudioTrackHandle()->getDualMonoMode(&mode)) {
106 std::cerr << "no dual mono presentation is available" << std::endl;
107 }
108 if (OK != ap->getAudioTrackHandle()->setDualMonoMode(AUDIO_DUAL_MONO_MODE_LR)) {
109 std::cerr << "no dual mono presentation is available" << std::endl;
110 } else {
111 EXPECT_EQ(OK, ap->getAudioTrackHandle()->getDualMonoMode(&mode));
112 EXPECT_EQ(AUDIO_DUAL_MONO_MODE_LR, mode);
113 }
114 float leveldB;
115 if (OK != ap->getAudioTrackHandle()->getAudioDescriptionMixLevel(&leveldB)) {
116 std::cerr << "Audio Description mixing is unavailable" << std::endl;
117 }
118 if (OK != ap->getAudioTrackHandle()->setAudioDescriptionMixLevel(3.14f)) {
119 std::cerr << "Audio Description mixing is unavailable" << std::endl;
120 } else {
121 EXPECT_EQ(OK, ap->getAudioTrackHandle()->getAudioDescriptionMixLevel(&leveldB));
122 EXPECT_EQ(3.14f, leveldB);
123 }
124 AudioPlaybackRate audioRate;
125 audioRate = ap->getAudioTrackHandle()->getPlaybackRate();
126 std::cerr << "playback speed :: " << audioRate.mSpeed << std::endl
127 << "playback pitch :: " << audioRate.mPitch << std::endl;
128 audioRate.mSpeed = 2.0f;
129 audioRate.mPitch = 2.0f;
130 audioRate.mStretchMode = AUDIO_TIMESTRETCH_STRETCH_VOICE;
131 audioRate.mFallbackMode = AUDIO_TIMESTRETCH_FALLBACK_MUTE;
132 EXPECT_TRUE(isAudioPlaybackRateValid(audioRate));
133 if (OK != ap->getAudioTrackHandle()->setPlaybackRate(audioRate)) {
134 std::cerr << "unable to set playback rate parameters" << std::endl;
135 } else {
136 AudioPlaybackRate audioRateLocal;
137 audioRateLocal = ap->getAudioTrackHandle()->getPlaybackRate();
138 EXPECT_TRUE(isAudioPlaybackRateEqual(audioRate, audioRateLocal));
139 }
140 ap->stop();
141 }
142
TEST(AudioTrackTest,TestAudioCbNotifier)143 TEST(AudioTrackTest, TestAudioCbNotifier) {
144 const auto ap = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
145 AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_FAST,
146 AUDIO_SESSION_NONE, AudioTrack::TRANSFER_SHARED);
147 ASSERT_NE(nullptr, ap);
148 ASSERT_EQ(OK, ap->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
149 << "Unable to open Resource";
150 EXPECT_EQ(OK, ap->create()) << "track creation failed";
151 EXPECT_EQ(BAD_VALUE, ap->getAudioTrackHandle()->addAudioDeviceCallback(nullptr));
152 sp<OnAudioDeviceUpdateNotifier> cb = sp<OnAudioDeviceUpdateNotifier>::make();
153 sp<OnAudioDeviceUpdateNotifier> cbOld = sp<OnAudioDeviceUpdateNotifier>::make();
154 EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cbOld));
155 EXPECT_EQ(INVALID_OPERATION, ap->getAudioTrackHandle()->addAudioDeviceCallback(cbOld));
156 EXPECT_EQ(OK, ap->getAudioTrackHandle()->addAudioDeviceCallback(cb));
157 EXPECT_EQ(OK, ap->start()) << "audio track start failed";
158 EXPECT_EQ(OK, ap->onProcess());
159 EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
160 const auto [oldAudioIo, oldDeviceIds] = cbOld->getLastPortAndDevices();
161 EXPECT_EQ(AUDIO_IO_HANDLE_NONE, oldAudioIo);
162 EXPECT_TRUE(oldDeviceIds.empty());
163 const auto [audioIo, deviceIds] = cb->getLastPortAndDevices();
164 EXPECT_NE(AUDIO_IO_HANDLE_NONE, audioIo);
165 EXPECT_FALSE(deviceIds.empty());
166 EXPECT_EQ(audioIo, ap->getAudioTrackHandle()->getOutput());
167 DeviceIdVector routedDeviceIds = ap->getAudioTrackHandle()->getRoutedDeviceIds();
168 EXPECT_TRUE(areDeviceIdsEqual(routedDeviceIds, deviceIds));
169 String8 keys;
170 keys = ap->getAudioTrackHandle()->getParameters(keys);
171 if (!keys.empty()) {
172 std::cerr << "track parameters :: " << keys << std::endl;
173 }
174 EXPECT_TRUE(checkPatchPlayback(audioIo, deviceIds));
175 EXPECT_EQ(BAD_VALUE, ap->getAudioTrackHandle()->removeAudioDeviceCallback(nullptr));
176 EXPECT_EQ(INVALID_OPERATION, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cbOld));
177 EXPECT_EQ(OK, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cb));
178 ap->stop();
179 }
180
181 class AudioTrackCreateTest
182 : public ::testing::TestWithParam<std::tuple<uint32_t, audio_format_t, audio_channel_mask_t,
183 audio_output_flags_t, audio_session_t>> {
184 public:
AudioTrackCreateTest()185 AudioTrackCreateTest()
186 : mSampleRate(std::get<0>(GetParam())),
187 mFormat(std::get<1>(GetParam())),
188 mChannelMask(std::get<2>(GetParam())),
189 mFlags(std::get<3>(GetParam())),
190 mSessionId(std::get<4>(GetParam())){};
191
192 const uint32_t mSampleRate;
193 const audio_format_t mFormat;
194 const audio_channel_mask_t mChannelMask;
195 const audio_output_flags_t mFlags;
196 const audio_session_t mSessionId;
197
198 sp<AudioPlayback> mAP;
199
SetUp()200 virtual void SetUp() override {
201 mAP = sp<AudioPlayback>::make(mSampleRate, mFormat, mChannelMask, mFlags,
202 mSessionId);
203 ASSERT_NE(nullptr, mAP);
204 ASSERT_EQ(OK, mAP->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
205 << "Unable to open Resource";
206 ASSERT_EQ(OK, mAP->create()) << "track creation failed";
207 }
208
TearDown()209 virtual void TearDown() override {
210 if (mAP) mAP->stop();
211 }
212 };
213
TEST_P(AudioTrackCreateTest,TestCreateTrack)214 TEST_P(AudioTrackCreateTest, TestCreateTrack) {
215 EXPECT_EQ(mFormat, mAP->getAudioTrackHandle()->format());
216 EXPECT_EQ(audio_channel_count_from_out_mask(mChannelMask),
217 mAP->getAudioTrackHandle()->channelCount());
218 if (mSampleRate != 0) EXPECT_EQ(mSampleRate, mAP->getAudioTrackHandle()->getSampleRate());
219 if (mSessionId != AUDIO_SESSION_NONE)
220 EXPECT_EQ(mSessionId, mAP->getAudioTrackHandle()->getSessionId());
221 EXPECT_EQ(mSampleRate, mAP->getAudioTrackHandle()->getOriginalSampleRate());
222 EXPECT_EQ(OK, mAP->start()) << "audio track start failed";
223 EXPECT_EQ(OK, mAP->onProcess());
224 }
225
226 // sampleRate, format, channelMask, flags, sessionId
227 INSTANTIATE_TEST_SUITE_P(
228 AudioTrackParameterizedTest, AudioTrackCreateTest,
229 ::testing::Combine(::testing::Values(48000), ::testing::Values(AUDIO_FORMAT_PCM_16_BIT),
230 ::testing::Values(AUDIO_CHANNEL_OUT_STEREO),
231 ::testing::Values(AUDIO_OUTPUT_FLAG_NONE,
232 AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_FAST,
233 AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_FAST,
234 AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
235 ::testing::Values(AUDIO_SESSION_NONE)));
236
main(int argc,char ** argv)237 int main(int argc, char** argv) {
238 android::ProcessState::self()->startThreadPool();
239 ::testing::InitGoogleTest(&argc, argv);
240 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
241 return RUN_ALL_TESTS();
242 }
243