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 "AudioEffectTests"
19
20 #include <binder/ProcessState.h>
21 #include <gtest/gtest.h>
22 #include <media/AudioEffect.h>
23 #include <system/audio_effects/effect_hapticgenerator.h>
24 #include <system/audio_effects/effect_spatializer.h>
25 #include <system/audio_effects/effect_visualizer.h>
26
27 #include "audio_test_utils.h"
28 #include "test_execution_tracer.h"
29
30 using namespace android;
31
32 class AudioEffectCallback : public AudioEffect::IAudioEffectCallback {
33 public:
34 bool receivedFramesProcessed = false;
35
onFramesProcessed(int32_t framesProcessed)36 void onFramesProcessed(int32_t framesProcessed) override {
37 ALOGE("number of frames processed %d", framesProcessed);
38 receivedFramesProcessed = true;
39 }
40 };
41
42 static constexpr int kDefaultInputEffectPriority = -1;
43 static constexpr int kDefaultOutputEffectPriority = 0;
44
45 static const char* gPackageName = "AudioEffectTest";
46
doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7> & ports)47 bool doesDeviceSupportLowLatencyMode(std::vector<struct audio_port_v7>& ports) {
48 for (const auto& port : ports) {
49 if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_MIX) {
50 if ((port.active_config.flags.output & AUDIO_OUTPUT_FLAG_FAST) != 0) {
51 return true;
52 }
53 }
54 }
55 return false;
56 }
57
createEffect(const effect_uuid_t * type,const effect_uuid_t * uuid=nullptr,int priority=0,audio_session_t sessionId=AUDIO_SESSION_OUTPUT_MIX,const wp<AudioEffectCallback> & callback=nullptr)58 sp<AudioEffect> createEffect(const effect_uuid_t* type, const effect_uuid_t* uuid = nullptr,
59 int priority = 0, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
60 const wp<AudioEffectCallback>& callback = nullptr) {
61 std::string packageName{gPackageName};
62 AttributionSourceState attributionSource;
63 attributionSource.packageName = packageName;
64 attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
65 attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
66 attributionSource.token = sp<BBinder>::make();
67 sp<AudioEffect> effect = new AudioEffect(attributionSource);
68 effect->set(type, uuid, priority, callback, sessionId, AUDIO_IO_HANDLE_NONE, {}, false,
69 (callback != nullptr));
70 return effect;
71 }
72
isEffectExistsOnAudioSession(const effect_uuid_t * type,const effect_uuid_t * uuid,int priority,audio_session_t sessionId)73 status_t isEffectExistsOnAudioSession(const effect_uuid_t* type, const effect_uuid_t* uuid,
74 int priority, audio_session_t sessionId) {
75 sp<AudioEffect> effect = createEffect(type, uuid, priority, sessionId);
76 return effect->initCheck();
77 }
78
isEffectDefaultOnRecord(const effect_uuid_t * type,const effect_uuid_t * uuid,const sp<AudioRecord> & audioRecord)79 bool isEffectDefaultOnRecord(const effect_uuid_t* type, const effect_uuid_t* uuid,
80 const sp<AudioRecord>& audioRecord) {
81 effect_descriptor_t descriptors[AudioEffect::kMaxPreProcessing];
82 uint32_t numEffects = AudioEffect::kMaxPreProcessing;
83 status_t ret = AudioEffect::queryDefaultPreProcessing(audioRecord->getSessionId(), descriptors,
84 &numEffects);
85 if (ret != OK || numEffects > AudioEffect::kMaxPreProcessing) {
86 return false;
87 }
88 for (int i = 0; i < numEffects; i++) {
89 if ((memcmp(&descriptors[i].type, type, sizeof(effect_uuid_t)) == 0) &&
90 (memcmp(&descriptors[i].uuid, uuid, sizeof(effect_uuid_t)) == 0)) {
91 return true;
92 }
93 }
94 return false;
95 }
96
listEffectsAvailable(std::vector<effect_descriptor_t> & descriptors)97 void listEffectsAvailable(std::vector<effect_descriptor_t>& descriptors) {
98 uint32_t numEffects = 0;
99 ASSERT_EQ(NO_ERROR, AudioEffect::queryNumberEffects(&numEffects));
100 for (auto i = 0; i < numEffects; i++) {
101 effect_descriptor_t des;
102 ASSERT_EQ(NO_ERROR, AudioEffect::queryEffect(i, &des));
103 descriptors.push_back(des);
104 }
105 }
106
isPreprocessing(effect_descriptor_t & descriptor)107 bool isPreprocessing(effect_descriptor_t& descriptor) {
108 return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC);
109 }
110
isInsert(effect_descriptor_t & descriptor)111 bool isInsert(effect_descriptor_t& descriptor) {
112 return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT);
113 }
114
isAux(effect_descriptor_t & descriptor)115 bool isAux(effect_descriptor_t& descriptor) {
116 return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY);
117 }
118
isPostproc(effect_descriptor_t & descriptor)119 bool isPostproc(effect_descriptor_t& descriptor) {
120 return ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC);
121 }
122
isFastCompatible(effect_descriptor_t & descriptor)123 bool isFastCompatible(effect_descriptor_t& descriptor) {
124 return !(((descriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0) &&
125 ((descriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0));
126 }
127
isSpatializer(effect_descriptor_t & descriptor)128 bool isSpatializer(effect_descriptor_t& descriptor) {
129 return (memcmp(&descriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0);
130 }
131
isHapticGenerator(effect_descriptor_t & descriptor)132 bool isHapticGenerator(effect_descriptor_t& descriptor) {
133 return (memcmp(&descriptor.type, FX_IID_HAPTICGENERATOR, sizeof(effect_uuid_t)) == 0);
134 }
135
typeAndUuidToString(const effect_descriptor_t & desc)136 std::tuple<std::string, std::string> typeAndUuidToString(const effect_descriptor_t& desc) {
137 char type[512];
138 AudioEffect::guidToString(&desc.type, type, sizeof(type));
139 char uuid[512];
140 AudioEffect::guidToString(&desc.uuid, uuid, sizeof(uuid));
141 return std::make_tuple(type, uuid);
142 }
143
144 // UNIT TESTS
TEST(AudioEffectTest,getEffectDescriptor)145 TEST(AudioEffectTest, getEffectDescriptor) {
146 effect_uuid_t randomType = {
147 0x81781c08, 0x93dd, 0x11ec, 0xb909, {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
148 effect_uuid_t randomUuid = {
149 0x653730e1, 0x1be1, 0x438e, 0xa35a, {0xfc, 0x9b, 0xa1, 0x2a, 0x5e, 0xc9}};
150 effect_uuid_t empty = EFFECT_UUID_INITIALIZER;
151
152 effect_descriptor_t descriptor;
153 EXPECT_EQ(NAME_NOT_FOUND, AudioEffect::getEffectDescriptor(&randomUuid, &randomType,
154 EFFECT_FLAG_TYPE_MASK, &descriptor));
155
156 std::vector<effect_descriptor_t> descriptors;
157 ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
158
159 for (auto i = 0; i < descriptors.size(); i++) {
160 EXPECT_EQ(NO_ERROR,
161 AudioEffect::getEffectDescriptor(&descriptors[i].uuid, &descriptors[i].type,
162 EFFECT_FLAG_TYPE_MASK, &descriptor));
163 EXPECT_EQ(0, memcmp(&descriptor, &descriptors[i], sizeof(effect_uuid_t)));
164 }
165 // negative tests
166 if (descriptors.size() > 0) {
167 EXPECT_EQ(BAD_VALUE,
168 AudioEffect::getEffectDescriptor(&descriptors[0].uuid, &descriptors[0].type,
169 EFFECT_FLAG_TYPE_MASK, nullptr));
170 }
171 EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, nullptr,
172 EFFECT_FLAG_TYPE_PRE_PROC, &descriptor));
173 EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&empty, &randomType,
174 EFFECT_FLAG_TYPE_MASK, nullptr));
175 EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(nullptr, &randomType,
176 EFFECT_FLAG_TYPE_POST_PROC, &descriptor));
177 EXPECT_EQ(BAD_VALUE, AudioEffect::getEffectDescriptor(&randomUuid, nullptr,
178 EFFECT_FLAG_TYPE_INSERT, &descriptor));
179 }
180
TEST(AudioEffectTest,DISABLED_GetSetParameterForEffect)181 TEST(AudioEffectTest, DISABLED_GetSetParameterForEffect) {
182 sp<AudioEffect> visualizer = createEffect(SL_IID_VISUALIZATION);
183 status_t status = visualizer->initCheck();
184 ASSERT_TRUE(status == NO_ERROR || status == ALREADY_EXISTS) << "Init check error";
185 ASSERT_EQ(NO_ERROR, visualizer->setEnabled(true)) << "visualizer not enabled";
186
187 uint32_t buf32[3][sizeof(effect_param_t) / sizeof(uint32_t) + 2];
188 effect_param_t* vis_none = (effect_param_t*)(buf32[0]);
189 effect_param_t* vis_rms = (effect_param_t*)(buf32[1]);
190 effect_param_t* vis_tmp = (effect_param_t*)(buf32[2]);
191
192 // Visualizer::setMeasurementMode()
193 vis_none->psize = sizeof(uint32_t);
194 vis_none->vsize = sizeof(uint32_t);
195 *(int32_t*)vis_none->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
196 *((int32_t*)vis_none->data + 1) = MEASUREMENT_MODE_NONE;
197 EXPECT_EQ(NO_ERROR, visualizer->setParameter(vis_none))
198 << "setMeasurementMode doesn't report success";
199
200 // Visualizer::getMeasurementMode()
201 vis_tmp->psize = sizeof(uint32_t);
202 vis_tmp->vsize = sizeof(uint32_t);
203 *(int32_t*)vis_tmp->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
204 *((int32_t*)vis_tmp->data + 1) = 23;
205 EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
206 << "getMeasurementMode doesn't report success";
207 EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
208 << "target mode does not match set mode";
209
210 // Visualizer::setMeasurementModeDeferred()
211 vis_rms->psize = sizeof(uint32_t);
212 vis_rms->vsize = sizeof(uint32_t);
213 *(int32_t*)vis_rms->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
214 *((int32_t*)vis_rms->data + 1) = MEASUREMENT_MODE_PEAK_RMS;
215 EXPECT_EQ(NO_ERROR, visualizer->setParameterDeferred(vis_rms))
216 << "setMeasurementModeDeferred doesn't report success";
217
218 *((int32_t*)vis_tmp->data + 1) = 23;
219 EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
220 << "getMeasurementMode doesn't report success";
221 EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_none->data + 1))
222 << "target mode does not match set mode";
223
224 // setParameterCommit
225 EXPECT_EQ(NO_ERROR, visualizer->setParameterCommit())
226 << "setMeasurementModeCommit does not report success";
227
228 // validate Params
229 *((int32_t*)vis_tmp->data + 1) = 23;
230 EXPECT_EQ(NO_ERROR, visualizer->getParameter(vis_tmp))
231 << "getMeasurementMode doesn't report success";
232 EXPECT_EQ(*((int32_t*)vis_tmp->data + 1), *((int32_t*)vis_rms->data + 1))
233 << "target mode does not match set mode";
234 }
235
TEST(AudioEffectTest,ManageSourceDefaultEffects)236 TEST(AudioEffectTest, ManageSourceDefaultEffects) {
237 int32_t selectedEffect = -1;
238
239 const uint32_t sampleRate = 44100;
240 const audio_format_t format = AUDIO_FORMAT_PCM_16_BIT;
241 const audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_STEREO;
242 sp<AudioCapture> capture = nullptr;
243
244 std::vector<effect_descriptor_t> descriptors;
245 ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
246 for (auto i = 0; i < descriptors.size(); i++) {
247 if (isPreprocessing(descriptors[i])) {
248 capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
249 ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
250 EXPECT_EQ(NO_ERROR, capture->create());
251 EXPECT_EQ(NO_ERROR, capture->start());
252 ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
253 if (!isEffectDefaultOnRecord(&descriptors[i].type, &descriptors[i].uuid,
254 capture->getAudioRecordHandle())) {
255 selectedEffect = i;
256 EXPECT_EQ(OK, capture->stop());
257 break;
258 }
259 EXPECT_EQ(OK, capture->stop());
260 }
261 }
262 if (selectedEffect == -1) GTEST_SKIP() << " expected at least one preprocessing effect";
263
264 effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
265 effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
266 auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
267 capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
268 ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
269 EXPECT_EQ(NO_ERROR, capture->create());
270 EXPECT_EQ(NO_ERROR, capture->start());
271 ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
272 EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
273 capture->getAudioRecordHandle()))
274 << "Effect should not have been default on record. " << type;
275 EXPECT_EQ(NO_ERROR,
276 isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
277 kDefaultInputEffectPriority - 1,
278 capture->getAudioRecordHandle()->getSessionId()))
279 << "Effect should not have been added. " << type;
280 EXPECT_EQ(OK, capture->audioProcess());
281 EXPECT_EQ(OK, capture->stop());
282
283 String16 name{gPackageName};
284 audio_unique_id_t effectId;
285 status_t status = AudioEffect::addSourceDefaultEffect(type.c_str(), name, uuid.c_str(),
286 kDefaultInputEffectPriority,
287 AUDIO_SOURCE_MIC, &effectId);
288 EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << type;
289
290 capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
291 ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
292 EXPECT_EQ(NO_ERROR, capture->create());
293 EXPECT_EQ(NO_ERROR, capture->start());
294 ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
295 EXPECT_TRUE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
296 capture->getAudioRecordHandle()))
297 << "Effect should have been default on record. " << type;
298 EXPECT_EQ(ALREADY_EXISTS,
299 isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
300 kDefaultInputEffectPriority - 1,
301 capture->getAudioRecordHandle()->getSessionId()))
302 << "Effect should have been added. " << type;
303 EXPECT_EQ(OK, capture->audioProcess());
304 EXPECT_EQ(OK, capture->stop());
305
306 status = AudioEffect::removeSourceDefaultEffect(effectId);
307 EXPECT_EQ(NO_ERROR, status);
308 capture = new AudioCapture(AUDIO_SOURCE_MIC, sampleRate, format, channelMask);
309 ASSERT_NE(capture, nullptr) << "Unable to create Record Application";
310 EXPECT_EQ(NO_ERROR, capture->create());
311 EXPECT_EQ(NO_ERROR, capture->start());
312 ASSERT_NE(capture->getAudioRecordHandle(), nullptr);
313 EXPECT_FALSE(isEffectDefaultOnRecord(selectedEffectType, selectedEffectUuid,
314 capture->getAudioRecordHandle()))
315 << "Effect should not have been default on record. " << type;
316 EXPECT_EQ(NO_ERROR,
317 isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
318 kDefaultInputEffectPriority - 1,
319 capture->getAudioRecordHandle()->getSessionId()))
320 << "Effect should not have been added. " << type;
321 EXPECT_EQ(OK, capture->audioProcess());
322 EXPECT_EQ(OK, capture->stop());
323 }
324
TEST(AudioEffectTest,AuxEffectSanityTest)325 TEST(AudioEffectTest, AuxEffectSanityTest) {
326 int32_t selectedEffect = -1;
327 std::vector<effect_descriptor_t> descriptors;
328 ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
329 for (auto i = 0; i < descriptors.size(); i++) {
330 if (isAux(descriptors[i])) {
331 selectedEffect = i;
332 break;
333 }
334 }
335 if (selectedEffect == -1) GTEST_SKIP() << "expected at least one aux effect";
336 effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
337 effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
338 auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
339 String16 name{gPackageName};
340 audio_session_t sessionId =
341 (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
342 sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
343 kDefaultInputEffectPriority, sessionId);
344 EXPECT_EQ(NO_INIT, audioEffect->initCheck())
345 << "error, creating auxiliary effect (" << type << ") on session id " << (int)sessionId
346 << " successful ";
347 audio_unique_id_t id;
348 status_t status = AudioEffect::addStreamDefaultEffect(
349 type.c_str(), name, uuid.c_str(), kDefaultOutputEffectPriority, AUDIO_USAGE_MEDIA, &id);
350 if (status == NO_ERROR) {
351 EXPECT_EQ(NO_ERROR, AudioEffect::removeStreamDefaultEffect(id));
352 EXPECT_NE(NO_ERROR, status) << "error, adding auxiliary effect (" << type
353 << ") as stream default effect is successful";
354 }
355 }
356
357 class AudioPlaybackEffectTest : public ::testing::TestWithParam<bool> {
358 public:
AudioPlaybackEffectTest()359 AudioPlaybackEffectTest() : mSelectFastMode(GetParam()){};
360
361 const bool mSelectFastMode;
362
363 bool mIsFastCompatibleEffect;
364 effect_uuid_t mType;
365 effect_uuid_t mUuid;
366 std::string mTypeStr;
367 std::string mUuidStr;
368
SetUp()369 void SetUp() override {
370 if (mSelectFastMode) {
371 std::vector<struct audio_port_v7> ports;
372 ASSERT_EQ(OK, listAudioPorts(ports));
373 if (!doesDeviceSupportLowLatencyMode(ports)) {
374 GTEST_SKIP() << "device does not support low latency mode";
375 }
376 }
377
378 int32_t selectedEffect = -1;
379 std::vector<effect_descriptor_t> descriptors;
380 ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
381 for (auto i = 0; i < descriptors.size(); i++) {
382 if (isSpatializer(descriptors[i])) continue;
383 if (isHapticGenerator(descriptors[i]) && !AudioSystem::isHapticPlaybackSupported())
384 continue;
385 if (!isInsert(descriptors[i])) continue;
386 selectedEffect = i;
387 mIsFastCompatibleEffect = isFastCompatible(descriptors[i]);
388 // in fast mode, pick fast compatible effect if available
389 if (mSelectFastMode == mIsFastCompatibleEffect) break;
390 }
391 if (selectedEffect == -1) {
392 GTEST_SKIP() << "expected at least one valid effect";
393 }
394
395 mType = descriptors[selectedEffect].type;
396 mUuid = descriptors[selectedEffect].uuid;
397 std::tie(mTypeStr, mUuidStr) = typeAndUuidToString(descriptors[selectedEffect]);
398 }
399 };
400
TEST_P(AudioPlaybackEffectTest,StreamDefaultEffectTest)401 TEST_P(AudioPlaybackEffectTest, StreamDefaultEffectTest) {
402 SCOPED_TRACE(testing::Message()
403 << "\n selected effect type is :: " << mTypeStr
404 << "\n selected effect uuid is :: " << mUuidStr
405 << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
406 << "\n audio effect is fast compatible : "
407 << (mIsFastCompatibleEffect ? "yes" : "no"));
408
409 bool compatCheck = !mSelectFastMode || (mSelectFastMode && mIsFastCompatibleEffect);
410
411 // create track
412 audio_attributes_t attributes;
413 attributes.usage = AUDIO_USAGE_MEDIA;
414 attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
415 auto playback = sp<AudioPlayback>::make(
416 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
417 mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
418 AudioTrack::TRANSFER_SHARED, &attributes);
419 ASSERT_NE(nullptr, playback);
420 ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
421 EXPECT_EQ(NO_ERROR, playback->create());
422 EXPECT_EQ(NO_ERROR, playback->start());
423 EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
424 isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
425 playback->getAudioTrackHandle()->getSessionId()))
426 << "Effect should not have been added. " << mTypeStr;
427 EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
428 playback->stop();
429 playback.clear();
430
431 String16 name{gPackageName};
432 audio_unique_id_t id;
433 status_t status = AudioEffect::addStreamDefaultEffect(mTypeStr.c_str(), name, mUuidStr.c_str(),
434 kDefaultOutputEffectPriority,
435 AUDIO_USAGE_MEDIA, &id);
436 EXPECT_EQ(NO_ERROR, status) << "Adding default effect failed: " << mTypeStr;
437
438 playback = sp<AudioPlayback>::make(
439 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
440 mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
441 AudioTrack::TRANSFER_SHARED, &attributes);
442 ASSERT_NE(nullptr, playback);
443 ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
444 EXPECT_EQ(NO_ERROR, playback->create());
445 EXPECT_EQ(NO_ERROR, playback->start());
446 // If effect chosen is not compatible with the session, then effect won't be applied
447 EXPECT_EQ(compatCheck ? ALREADY_EXISTS : NO_INIT,
448 isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
449 playback->getAudioTrackHandle()->getSessionId()))
450 << "Effect should have been added. " << mTypeStr;
451 EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
452 if (mSelectFastMode) {
453 EXPECT_EQ(AUDIO_OUTPUT_FLAG_FAST,
454 playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
455 }
456 playback->stop();
457 playback.clear();
458
459 status = AudioEffect::removeStreamDefaultEffect(id);
460 EXPECT_EQ(NO_ERROR, status);
461 playback = sp<AudioPlayback>::make(
462 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
463 mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE,
464 AudioTrack::TRANSFER_SHARED, &attributes);
465 ASSERT_NE(nullptr, playback);
466 ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
467 EXPECT_EQ(NO_ERROR, playback->create());
468 EXPECT_EQ(NO_ERROR, playback->start());
469 EXPECT_EQ(compatCheck ? NO_ERROR : NO_INIT,
470 isEffectExistsOnAudioSession(&mType, &mUuid, kDefaultOutputEffectPriority - 1,
471 playback->getAudioTrackHandle()->getSessionId()))
472 << "Effect should not have been added. " << mTypeStr;
473 EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
474 playback->stop();
475 playback.clear();
476 }
477
TEST_P(AudioPlaybackEffectTest,CheckOutputFlagCompatibility)478 TEST_P(AudioPlaybackEffectTest, CheckOutputFlagCompatibility) {
479 SCOPED_TRACE(testing::Message()
480 << "\n selected effect type is :: " << mTypeStr
481 << "\n selected effect uuid is :: " << mUuidStr
482 << "\n audiotrack output flag : " << (mSelectFastMode ? "fast" : "default")
483 << "\n audio effect is fast compatible : "
484 << (mIsFastCompatibleEffect ? "yes" : "no"));
485
486 audio_attributes_t attributes;
487 attributes.usage = AUDIO_USAGE_MEDIA;
488 attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
489 audio_session_t sessionId =
490 (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
491 sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
492 sp<AudioEffect> audioEffect =
493 createEffect(&mType, &mUuid, kDefaultOutputEffectPriority, sessionId, cb);
494 ASSERT_EQ(OK, audioEffect->initCheck());
495 ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
496 auto playback = sp<AudioPlayback>::make(
497 0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_MONO,
498 mSelectFastMode ? AUDIO_OUTPUT_FLAG_FAST : AUDIO_OUTPUT_FLAG_NONE, sessionId,
499 AudioTrack::TRANSFER_SHARED, &attributes);
500 ASSERT_NE(nullptr, playback);
501 ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_1ch_8kHz_s16le.raw"));
502 EXPECT_EQ(NO_ERROR, playback->create());
503 EXPECT_EQ(NO_ERROR, playback->start());
504
505 EXPECT_EQ(ALREADY_EXISTS, isEffectExistsOnAudioSession(
506 &mType, &mUuid, kDefaultOutputEffectPriority - 1, sessionId))
507 << "Effect should have been added. " << mTypeStr;
508 if (mSelectFastMode) {
509 EXPECT_EQ(mIsFastCompatibleEffect ? AUDIO_OUTPUT_FLAG_FAST : 0,
510 playback->getAudioTrackHandle()->getFlags() & AUDIO_OUTPUT_FLAG_FAST);
511 }
512 EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
513 EXPECT_EQ(NO_ERROR, playback->getAudioTrackHandle()->attachAuxEffect(0));
514 playback->stop();
515 playback.clear();
516 EXPECT_TRUE(cb->receivedFramesProcessed)
517 << "AudioEffect frames processed callback not received";
518 }
519
520 INSTANTIATE_TEST_SUITE_P(EffectParameterizedTests, AudioPlaybackEffectTest, ::testing::Bool());
521
TEST(AudioEffectTest,TestHapticEffect)522 TEST(AudioEffectTest, TestHapticEffect) {
523 if (!AudioSystem::isHapticPlaybackSupported())
524 GTEST_SKIP() << "Haptic playback is not supported";
525 int32_t selectedEffect = -1;
526 std::vector<effect_descriptor_t> descriptors;
527 ASSERT_NO_FATAL_FAILURE(listEffectsAvailable(descriptors));
528 for (auto i = 0; i < descriptors.size(); i++) {
529 if (!isHapticGenerator(descriptors[i])) continue;
530 selectedEffect = i;
531 break;
532 }
533 if (selectedEffect == -1) GTEST_SKIP() << "expected at least one valid effect";
534
535 effect_uuid_t* selectedEffectType = &descriptors[selectedEffect].type;
536 effect_uuid_t* selectedEffectUuid = &descriptors[selectedEffect].uuid;
537 auto [type, uuid] = typeAndUuidToString(descriptors[selectedEffect]);
538
539 SCOPED_TRACE(testing::Message() << "\n selected effect type is :: " << type
540 << "\n selected effect uuid is :: " << uuid);
541
542 audio_attributes_t attributes;
543 attributes.usage = AUDIO_USAGE_MEDIA;
544 attributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
545 audio_session_t sessionId =
546 (audio_session_t)AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
547 sp<AudioEffectCallback> cb = sp<AudioEffectCallback>::make();
548 sp<AudioEffect> audioEffect = createEffect(selectedEffectType, selectedEffectUuid,
549 kDefaultOutputEffectPriority, sessionId, cb);
550 ASSERT_EQ(OK, audioEffect->initCheck());
551 ASSERT_EQ(NO_ERROR, audioEffect->setEnabled(true));
552 auto playback = sp<AudioPlayback>::make(0 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
553 AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,
554 sessionId, AudioTrack::TRANSFER_SHARED, &attributes);
555 ASSERT_NE(nullptr, playback);
556 ASSERT_EQ(NO_ERROR, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"));
557 EXPECT_EQ(NO_ERROR, playback->create());
558 EXPECT_EQ(NO_ERROR, playback->start());
559 EXPECT_TRUE(isEffectExistsOnAudioSession(selectedEffectType, selectedEffectUuid,
560 kDefaultOutputEffectPriority - 1, sessionId))
561 << "Effect should have been added. " << type;
562 EXPECT_EQ(NO_ERROR, playback->waitForConsumption());
563 playback->stop();
564 playback.clear();
565 EXPECT_TRUE(cb->receivedFramesProcessed)
566 << "AudioEffect frames processed callback not received";
567 }
568
main(int argc,char ** argv)569 int main(int argc, char** argv) {
570 android::ProcessState::self()->startThreadPool();
571 ::testing::InitGoogleTest(&argc, argv);
572 ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
573 return RUN_ALL_TESTS();
574 }
575