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