blob: 9f0a901b7598c4ab29a076f2865988e550b98725 [file] [log] [blame]
Eric Laurent6d607012021-07-05 11:54:40 +02001/*
2**
3** Copyright 2021, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18
19#define LOG_TAG "Spatializer"
20//#define LOG_NDEBUG 0
21#include <utils/Log.h>
22
23#include <limits.h>
24#include <stdint.h>
25#include <sys/types.h>
26
27#include <android/content/AttributionSourceState.h>
28#include <audio_utils/fixedfft.h>
29#include <cutils/bitops.h>
Eric Laurent2be8b292021-08-23 09:44:33 -070030#include <hardware/sensors.h>
Eric Laurent6d607012021-07-05 11:54:40 +020031#include <media/audiohal/EffectsFactoryHalInterface.h>
Eric Laurent8a4259f2021-09-14 16:04:00 +020032#include <media/stagefright/foundation/AHandler.h>
33#include <media/stagefright/foundation/AMessage.h>
Andy Hunga461a002022-05-17 10:36:02 -070034#include <media/MediaMetricsItem.h>
Eric Laurent8a4259f2021-09-14 16:04:00 +020035#include <media/ShmemCompat.h>
Eric Laurent6d607012021-07-05 11:54:40 +020036#include <mediautils/ServiceUtilities.h>
37#include <utils/Thread.h>
38
39#include "Spatializer.h"
40
41namespace android {
42
43using aidl_utils::statusTFromBinderStatus;
44using aidl_utils::binderStatusFromStatusT;
45using android::content::AttributionSourceState;
46using binder::Status;
Eric Laurent2be8b292021-08-23 09:44:33 -070047using media::HeadTrackingMode;
48using media::Pose3f;
Eric Laurent6d607012021-07-05 11:54:40 +020049using media::SpatializationLevel;
Eric Laurent2be8b292021-08-23 09:44:33 -070050using media::SpatializationMode;
Ytai Ben-Tsvia16a9df2021-08-05 08:57:06 -070051using media::SpatializerHeadTrackingMode;
Eric Laurent2be8b292021-08-23 09:44:33 -070052using media::SensorPoseProvider;
53
Eric Laurent2be8b292021-08-23 09:44:33 -070054using namespace std::chrono_literals;
Eric Laurent6d607012021-07-05 11:54:40 +020055
56#define VALUE_OR_RETURN_BINDER_STATUS(x) \
57 ({ auto _tmp = (x); \
58 if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
59 std::move(_tmp.value()); })
60
Andy Hunga461a002022-05-17 10:36:02 -070061audio_channel_mask_t getMaxChannelMask(std::vector<audio_channel_mask_t> masks) {
62 uint32_t maxCount = 0;
63 audio_channel_mask_t maxMask = AUDIO_CHANNEL_NONE;
64 for (auto mask : masks) {
65 const size_t count = audio_channel_count_from_out_mask(mask);
66 if (count > maxCount) {
67 maxMask = mask;
68 maxCount = count;
69 }
70 }
71 return maxMask;
72}
73
Eric Laurent6d607012021-07-05 11:54:40 +020074// ---------------------------------------------------------------------------
75
Eric Laurent8a4259f2021-09-14 16:04:00 +020076class Spatializer::EngineCallbackHandler : public AHandler {
77public:
78 EngineCallbackHandler(wp<Spatializer> spatializer)
79 : mSpatializer(spatializer) {
80 }
81
82 enum {
83 // Device state callbacks
84 kWhatOnFramesProcessed, // AudioEffect::EVENT_FRAMES_PROCESSED
85 kWhatOnHeadToStagePose, // SpatializerPoseController::Listener::onHeadToStagePose
86 kWhatOnActualModeChange, // SpatializerPoseController::Listener::onActualModeChange
Eric Laurent9c04de92022-07-20 13:49:47 +020087 kWhatOnLatencyModesChanged, // Spatializer::onSupportedLatencyModesChanged
Eric Laurent8a4259f2021-09-14 16:04:00 +020088 };
89 static constexpr const char *kNumFramesKey = "numFrames";
90 static constexpr const char *kModeKey = "mode";
91 static constexpr const char *kTranslation0Key = "translation0";
92 static constexpr const char *kTranslation1Key = "translation1";
93 static constexpr const char *kTranslation2Key = "translation2";
94 static constexpr const char *kRotation0Key = "rotation0";
95 static constexpr const char *kRotation1Key = "rotation1";
96 static constexpr const char *kRotation2Key = "rotation2";
Eric Laurent9c04de92022-07-20 13:49:47 +020097 static constexpr const char *kLatencyModesKey = "latencyModes";
98
99 class LatencyModes : public RefBase {
100 public:
101 LatencyModes(audio_io_handle_t output,
102 const std::vector<audio_latency_mode_t>& latencyModes)
103 : mOutput(output), mLatencyModes(latencyModes) {}
104 ~LatencyModes() = default;
105
106 audio_io_handle_t mOutput;
107 std::vector<audio_latency_mode_t> mLatencyModes;
108 };
Eric Laurent8a4259f2021-09-14 16:04:00 +0200109
110 void onMessageReceived(const sp<AMessage> &msg) override {
Eric Laurent9c04de92022-07-20 13:49:47 +0200111 sp<Spatializer> spatializer = mSpatializer.promote();
112 if (spatializer == nullptr) {
113 ALOGW("%s: Cannot promote spatializer", __func__);
114 return;
115 }
Eric Laurent8a4259f2021-09-14 16:04:00 +0200116 switch (msg->what()) {
117 case kWhatOnFramesProcessed: {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200118 int numFrames;
119 if (!msg->findInt32(kNumFramesKey, &numFrames)) {
120 ALOGE("%s: Cannot find num frames!", __func__);
121 return;
122 }
123 if (numFrames > 0) {
124 spatializer->calculateHeadPose();
125 }
126 } break;
127 case kWhatOnHeadToStagePose: {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200128 std::vector<float> headToStage(sHeadPoseKeys.size());
129 for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
130 if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) {
131 ALOGE("%s: Cannot find kTranslation0Key!", __func__);
132 return;
133 }
134 }
135 spatializer->onHeadToStagePoseMsg(headToStage);
136 } break;
137 case kWhatOnActualModeChange: {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200138 int mode;
Eric Laurent9c04de92022-07-20 13:49:47 +0200139 if (!msg->findInt32(kModeKey, &mode)) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200140 ALOGE("%s: Cannot find actualMode!", __func__);
141 return;
142 }
143 spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode));
144 } break;
Eric Laurent9c04de92022-07-20 13:49:47 +0200145
146 case kWhatOnLatencyModesChanged: {
147 sp<RefBase> object;
148 if (!msg->findObject(kLatencyModesKey, &object)) {
149 ALOGE("%s: Cannot find latency modes!", __func__);
150 return;
151 }
152 sp<LatencyModes> latencyModes = static_cast<LatencyModes*>(object.get());
153 spatializer->onSupportedLatencyModesChangedMsg(
154 latencyModes->mOutput, std::move(latencyModes->mLatencyModes));
155 } break;
156
Eric Laurent8a4259f2021-09-14 16:04:00 +0200157 default:
158 LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what());
159 }
160 }
161private:
162 wp<Spatializer> mSpatializer;
163};
164
165const std::vector<const char *> Spatializer::sHeadPoseKeys = {
166 Spatializer::EngineCallbackHandler::kTranslation0Key,
167 Spatializer::EngineCallbackHandler::kTranslation1Key,
168 Spatializer::EngineCallbackHandler::kTranslation2Key,
169 Spatializer::EngineCallbackHandler::kRotation0Key,
170 Spatializer::EngineCallbackHandler::kRotation1Key,
171 Spatializer::EngineCallbackHandler::kRotation2Key,
172};
173
174// ---------------------------------------------------------------------------
Eric Laurent6d607012021-07-05 11:54:40 +0200175sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) {
176 sp<Spatializer> spatializer;
177
178 sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
179 if (effectsFactoryHal == nullptr) {
180 ALOGW("%s failed to create effect factory interface", __func__);
181 return spatializer;
182 }
183
184 std::vector<effect_descriptor_t> descriptors;
185 status_t status =
Eric Laurent1c5e2e32021-08-18 18:50:28 +0200186 effectsFactoryHal->getDescriptors(FX_IID_SPATIALIZER, &descriptors);
Eric Laurent6d607012021-07-05 11:54:40 +0200187 if (status != NO_ERROR) {
188 ALOGW("%s failed to get spatializer descriptor, error %d", __func__, status);
189 return spatializer;
190 }
191 ALOG_ASSERT(!descriptors.empty(),
192 "%s getDescriptors() returned no error but empty list", __func__);
193
194 //TODO: get supported spatialization modes from FX engine or descriptor
195
196 sp<EffectHalInterface> effect;
197 status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE,
198 AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect);
199 ALOGI("%s FX create status %d effect %p", __func__, status, effect.get());
200
201 if (status == NO_ERROR && effect != nullptr) {
202 spatializer = new Spatializer(descriptors[0], callback);
Eric Laurent2be8b292021-08-23 09:44:33 -0700203 if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) {
204 spatializer.clear();
205 }
Eric Laurent6d607012021-07-05 11:54:40 +0200206 }
207
208 return spatializer;
209}
210
Eric Laurent2be8b292021-08-23 09:44:33 -0700211Spatializer::Spatializer(effect_descriptor_t engineDescriptor, SpatializerPolicyCallback* callback)
212 : mEngineDescriptor(engineDescriptor),
213 mPolicyCallback(callback) {
Eric Laurent6d607012021-07-05 11:54:40 +0200214 ALOGV("%s", __func__);
215}
216
Eric Laurent8a4259f2021-09-14 16:04:00 +0200217void Spatializer::onFirstRef() {
218 mLooper = new ALooper;
219 mLooper->setName("Spatializer-looper");
220 mLooper->start(
221 /*runOnCallingThread*/false,
222 /*canCallJava*/ false,
223 PRIORITY_AUDIO);
224
225 mHandler = new EngineCallbackHandler(this);
226 mLooper->registerHandler(mHandler);
227}
228
Eric Laurent6d607012021-07-05 11:54:40 +0200229Spatializer::~Spatializer() {
230 ALOGV("%s", __func__);
Eric Laurent8a4259f2021-09-14 16:04:00 +0200231 if (mLooper != nullptr) {
232 mLooper->stop();
233 mLooper->unregisterHandler(mHandler->id());
234 }
235 mLooper.clear();
236 mHandler.clear();
Eric Laurent6d607012021-07-05 11:54:40 +0200237}
238
Eric Laurent2be8b292021-08-23 09:44:33 -0700239status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
240 ALOGV("%s", __func__);
241
242 std::vector<bool> supportsHeadTracking;
243 status_t status = getHalParameter<false>(effect, SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED,
244 &supportsHeadTracking);
245 if (status != NO_ERROR) {
Andy Hung119dbdb2022-05-11 19:20:13 -0700246 ALOGW("%s: cannot get SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED", __func__);
Eric Laurent2be8b292021-08-23 09:44:33 -0700247 return status;
248 }
249 mSupportsHeadTracking = supportsHeadTracking[0];
250
Andy Hung119dbdb2022-05-11 19:20:13 -0700251 std::vector<media::SpatializationLevel> spatializationLevels;
252 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_LEVELS,
253 &spatializationLevels);
Eric Laurent2be8b292021-08-23 09:44:33 -0700254 if (status != NO_ERROR) {
Andy Hung119dbdb2022-05-11 19:20:13 -0700255 ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_LEVELS", __func__);
Eric Laurent2be8b292021-08-23 09:44:33 -0700256 return status;
257 }
Andy Hung119dbdb2022-05-11 19:20:13 -0700258 bool noneLevelFound = false;
259 bool activeLevelFound = false;
260 for (const auto spatializationLevel : spatializationLevels) {
261 if (!aidl_utils::isValidEnum(spatializationLevel)) {
262 ALOGW("%s: ignoring spatializationLevel:%d", __func__, (int)spatializationLevel);
263 continue;
264 }
265 if (spatializationLevel == media::SpatializationLevel::NONE) {
266 noneLevelFound = true;
267 } else {
268 activeLevelFound = true;
269 }
270 // we don't detect duplicates.
271 mLevels.emplace_back(spatializationLevel);
272 }
273 if (!noneLevelFound || !activeLevelFound) {
274 ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_LEVELS must include NONE"
275 " and another valid level", __func__);
276 return BAD_VALUE;
277 }
278
279 std::vector<media::SpatializationMode> spatializationModes;
Eric Laurent2be8b292021-08-23 09:44:33 -0700280 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES,
Andy Hung119dbdb2022-05-11 19:20:13 -0700281 &spatializationModes);
Eric Laurent2be8b292021-08-23 09:44:33 -0700282 if (status != NO_ERROR) {
Andy Hung119dbdb2022-05-11 19:20:13 -0700283 ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES", __func__);
Eric Laurent2be8b292021-08-23 09:44:33 -0700284 return status;
285 }
Andy Hung119dbdb2022-05-11 19:20:13 -0700286 for (const auto spatializationMode : spatializationModes) {
287 if (!aidl_utils::isValidEnum(spatializationMode)) {
288 ALOGW("%s: ignoring spatializationMode:%d", __func__, (int)spatializationMode);
289 continue;
290 }
291 // we don't detect duplicates.
292 mSpatializationModes.emplace_back(spatializationMode);
293 }
294 if (mSpatializationModes.empty()) {
295 ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES reports empty", __func__);
296 return BAD_VALUE;
297 }
298
299 std::vector<audio_channel_mask_t> channelMasks;
300 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS,
301 &channelMasks);
302 if (status != NO_ERROR) {
303 ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS", __func__);
304 return status;
305 }
306 for (const auto channelMask : channelMasks) {
307 if (!audio_is_channel_mask_spatialized(channelMask)) {
308 ALOGW("%s: ignoring channelMask:%#x", __func__, channelMask);
309 continue;
310 }
311 // we don't detect duplicates.
312 mChannelMasks.emplace_back(channelMask);
313 }
314 if (mChannelMasks.empty()) {
315 ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS reports empty", __func__);
316 return BAD_VALUE;
317 }
Andy Hunga461a002022-05-17 10:36:02 -0700318
319 // Currently we expose only RELATIVE_WORLD.
320 // This is a limitation of the head tracking library based on a UX choice.
321 mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::DISABLED);
322 if (mSupportsHeadTracking) {
323 mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
324 }
325 mediametrics::LogItem(mMetricsId)
326 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
327 .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)getMaxChannelMask(mChannelMasks))
328 .set(AMEDIAMETRICS_PROP_LEVELS, aidl_utils::enumsToString(mLevels))
329 .set(AMEDIAMETRICS_PROP_MODES, aidl_utils::enumsToString(mSpatializationModes))
330 .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, aidl_utils::enumsToString(mHeadTrackingModes))
331 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
332 .record();
Andy Hung119dbdb2022-05-11 19:20:13 -0700333 return NO_ERROR;
Eric Laurent2be8b292021-08-23 09:44:33 -0700334}
335
336/** Gets the channel mask, sampling rate and format set for the spatializer input. */
337audio_config_base_t Spatializer::getAudioInConfig() const {
338 std::lock_guard lock(mLock);
339 audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
340 // For now use highest supported channel count
Andy Hunga461a002022-05-17 10:36:02 -0700341 config.channel_mask = getMaxChannelMask(mChannelMasks);
Eric Laurent2be8b292021-08-23 09:44:33 -0700342 return config;
343}
344
Eric Laurent6d607012021-07-05 11:54:40 +0200345status_t Spatializer::registerCallback(
346 const sp<media::INativeSpatializerCallback>& callback) {
Eric Laurent2be8b292021-08-23 09:44:33 -0700347 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200348 if (callback == nullptr) {
349 return BAD_VALUE;
350 }
351
352 sp<IBinder> binder = IInterface::asBinder(callback);
353 status_t status = binder->linkToDeath(this);
354 if (status == NO_ERROR) {
355 mSpatializerCallback = callback;
356 }
357 ALOGV("%s status %d", __func__, status);
358 return status;
359}
360
361// IBinder::DeathRecipient
362void Spatializer::binderDied(__unused const wp<IBinder> &who) {
363 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700364 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200365 mLevel = SpatializationLevel::NONE;
366 mSpatializerCallback.clear();
367 }
368 ALOGV("%s", __func__);
369 mPolicyCallback->onCheckSpatializer();
370}
371
372// ISpatializer
373Status Spatializer::getSupportedLevels(std::vector<SpatializationLevel> *levels) {
374 ALOGV("%s", __func__);
375 if (levels == nullptr) {
376 return binderStatusFromStatusT(BAD_VALUE);
377 }
Andy Hunga461a002022-05-17 10:36:02 -0700378 // SpatializationLevel::NONE is already required from the effect or we don't load it.
Eric Laurent2be8b292021-08-23 09:44:33 -0700379 levels->insert(levels->end(), mLevels.begin(), mLevels.end());
Eric Laurent6d607012021-07-05 11:54:40 +0200380 return Status::ok();
381}
382
Eric Laurent2be8b292021-08-23 09:44:33 -0700383Status Spatializer::setLevel(SpatializationLevel level) {
Eric Laurent6d607012021-07-05 11:54:40 +0200384 ALOGV("%s level %d", __func__, (int)level);
385 if (level != SpatializationLevel::NONE
Eric Laurent2be8b292021-08-23 09:44:33 -0700386 && std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) {
Eric Laurent6d607012021-07-05 11:54:40 +0200387 return binderStatusFromStatusT(BAD_VALUE);
388 }
389 sp<media::INativeSpatializerCallback> callback;
390 bool levelChanged = false;
391 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700392 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200393 levelChanged = mLevel != level;
394 mLevel = level;
395 callback = mSpatializerCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700396
397 if (levelChanged && mEngine != nullptr) {
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200398 checkEngineState_l();
Eric Laurent2be8b292021-08-23 09:44:33 -0700399 }
Eric Laurent9249d342022-03-18 11:55:56 +0100400 checkSensorsState_l();
Eric Laurent6d607012021-07-05 11:54:40 +0200401 }
402
403 if (levelChanged) {
404 mPolicyCallback->onCheckSpatializer();
405 if (callback != nullptr) {
406 callback->onLevelChanged(level);
407 }
408 }
409 return Status::ok();
410}
411
Eric Laurent2be8b292021-08-23 09:44:33 -0700412Status Spatializer::getLevel(SpatializationLevel *level) {
Eric Laurent6d607012021-07-05 11:54:40 +0200413 if (level == nullptr) {
414 return binderStatusFromStatusT(BAD_VALUE);
415 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700416 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200417 *level = mLevel;
418 ALOGV("%s level %d", __func__, (int)*level);
419 return Status::ok();
420}
421
Eric Laurentc87402b2021-09-17 16:49:42 +0200422Status Spatializer::isHeadTrackingSupported(bool *supports) {
423 ALOGV("%s mSupportsHeadTracking %d", __func__, mSupportsHeadTracking);
424 if (supports == nullptr) {
425 return binderStatusFromStatusT(BAD_VALUE);
426 }
427 std::lock_guard lock(mLock);
428 *supports = mSupportsHeadTracking;
429 return Status::ok();
430}
431
Eric Laurent6d607012021-07-05 11:54:40 +0200432Status Spatializer::getSupportedHeadTrackingModes(
Eric Laurent2be8b292021-08-23 09:44:33 -0700433 std::vector<SpatializerHeadTrackingMode>* modes) {
434 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200435 ALOGV("%s", __func__);
436 if (modes == nullptr) {
437 return binderStatusFromStatusT(BAD_VALUE);
438 }
Andy Hunga461a002022-05-17 10:36:02 -0700439 modes->insert(modes->end(), mHeadTrackingModes.begin(), mHeadTrackingModes.end());
Eric Laurent6d607012021-07-05 11:54:40 +0200440 return Status::ok();
441}
442
Eric Laurent2be8b292021-08-23 09:44:33 -0700443Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) {
444 ALOGV("%s mode %d", __func__, (int)mode);
445
446 if (!mSupportsHeadTracking) {
447 return binderStatusFromStatusT(INVALID_OPERATION);
448 }
449 std::lock_guard lock(mLock);
450 switch (mode) {
451 case SpatializerHeadTrackingMode::OTHER:
452 return binderStatusFromStatusT(BAD_VALUE);
453 case SpatializerHeadTrackingMode::DISABLED:
454 mDesiredHeadTrackingMode = HeadTrackingMode::STATIC;
455 break;
456 case SpatializerHeadTrackingMode::RELATIVE_WORLD:
457 mDesiredHeadTrackingMode = HeadTrackingMode::WORLD_RELATIVE;
458 break;
459 case SpatializerHeadTrackingMode::RELATIVE_SCREEN:
460 mDesiredHeadTrackingMode = HeadTrackingMode::SCREEN_RELATIVE;
461 break;
462 }
463
Eric Laurent11094172022-04-05 18:27:42 +0200464 checkPoseController_l();
465 checkSensorsState_l();
Eric Laurent2be8b292021-08-23 09:44:33 -0700466
467 return Status::ok();
468}
469
470Status Spatializer::getActualHeadTrackingMode(SpatializerHeadTrackingMode *mode) {
Eric Laurent6d607012021-07-05 11:54:40 +0200471 if (mode == nullptr) {
472 return binderStatusFromStatusT(BAD_VALUE);
473 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700474 std::lock_guard lock(mLock);
475 *mode = mActualHeadTrackingMode;
Eric Laurent6d607012021-07-05 11:54:40 +0200476 ALOGV("%s mode %d", __func__, (int)*mode);
477 return Status::ok();
478}
479
Ytai Ben-Tsvia16a9df2021-08-05 08:57:06 -0700480Status Spatializer::recenterHeadTracker() {
Eric Laurent780be4a2021-09-16 10:44:24 +0200481 if (!mSupportsHeadTracking) {
482 return binderStatusFromStatusT(INVALID_OPERATION);
483 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700484 std::lock_guard lock(mLock);
485 if (mPoseController != nullptr) {
486 mPoseController->recenter();
487 }
Eric Laurent6d607012021-07-05 11:54:40 +0200488 return Status::ok();
489}
490
491Status Spatializer::setGlobalTransform(const std::vector<float>& screenToStage) {
Eric Laurent6d607012021-07-05 11:54:40 +0200492 ALOGV("%s", __func__);
Eric Laurent780be4a2021-09-16 10:44:24 +0200493 if (!mSupportsHeadTracking) {
494 return binderStatusFromStatusT(INVALID_OPERATION);
495 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700496 std::optional<Pose3f> maybePose = Pose3f::fromVector(screenToStage);
497 if (!maybePose.has_value()) {
498 ALOGW("Invalid screenToStage vector.");
499 return binderStatusFromStatusT(BAD_VALUE);
500 }
501 std::lock_guard lock(mLock);
502 if (mPoseController != nullptr) {
503 mPoseController->setScreenToStagePose(maybePose.value());
504 }
Eric Laurent6d607012021-07-05 11:54:40 +0200505 return Status::ok();
506}
507
508Status Spatializer::release() {
509 ALOGV("%s", __func__);
510 bool levelChanged = false;
511 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700512 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200513 if (mSpatializerCallback == nullptr) {
514 return binderStatusFromStatusT(INVALID_OPERATION);
515 }
516
517 sp<IBinder> binder = IInterface::asBinder(mSpatializerCallback);
518 binder->unlinkToDeath(this);
519 mSpatializerCallback.clear();
520
521 levelChanged = mLevel != SpatializationLevel::NONE;
522 mLevel = SpatializationLevel::NONE;
523 }
524
525 if (levelChanged) {
526 mPolicyCallback->onCheckSpatializer();
527 }
528 return Status::ok();
529}
530
Eric Laurent2be8b292021-08-23 09:44:33 -0700531Status Spatializer::setHeadSensor(int sensorHandle) {
532 ALOGV("%s sensorHandle %d", __func__, sensorHandle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200533 if (!mSupportsHeadTracking) {
534 return binderStatusFromStatusT(INVALID_OPERATION);
535 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700536 std::lock_guard lock(mLock);
Andy Hungba2a61a2022-05-20 12:00:28 -0700537 if (mHeadSensor != sensorHandle) {
538 mHeadSensor = sensorHandle;
539 checkPoseController_l();
540 checkSensorsState_l();
541 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700542 return Status::ok();
543}
544
545Status Spatializer::setScreenSensor(int sensorHandle) {
546 ALOGV("%s sensorHandle %d", __func__, sensorHandle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200547 if (!mSupportsHeadTracking) {
548 return binderStatusFromStatusT(INVALID_OPERATION);
549 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700550 std::lock_guard lock(mLock);
Andy Hungba2a61a2022-05-20 12:00:28 -0700551 if (mScreenSensor != sensorHandle) {
552 mScreenSensor = sensorHandle;
553 // TODO: consider a new method setHeadAndScreenSensor()
554 // because we generally set both at the same time.
555 // This will avoid duplicated work and recentering.
556 checkSensorsState_l();
557 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700558 return Status::ok();
559}
560
561Status Spatializer::setDisplayOrientation(float physicalToLogicalAngle) {
562 ALOGV("%s physicalToLogicalAngle %f", __func__, physicalToLogicalAngle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200563 if (!mSupportsHeadTracking) {
564 return binderStatusFromStatusT(INVALID_OPERATION);
565 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700566 std::lock_guard lock(mLock);
567 mDisplayOrientation = physicalToLogicalAngle;
568 if (mPoseController != nullptr) {
569 mPoseController->setDisplayOrientation(mDisplayOrientation);
570 }
Eric Laurent16ddaf42021-09-17 15:00:35 +0200571 if (mEngine != nullptr) {
572 setEffectParameter_l(
573 SPATIALIZER_PARAM_DISPLAY_ORIENTATION, std::vector<float>{physicalToLogicalAngle});
574 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700575 return Status::ok();
576}
577
578Status Spatializer::setHingeAngle(float hingeAngle) {
579 std::lock_guard lock(mLock);
580 ALOGV("%s hingeAngle %f", __func__, hingeAngle);
581 if (mEngine != nullptr) {
582 setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{hingeAngle});
583 }
584 return Status::ok();
585}
586
587Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) {
588 ALOGV("%s", __func__);
589 if (modes == nullptr) {
590 return binderStatusFromStatusT(BAD_VALUE);
591 }
592 *modes = mSpatializationModes;
593 return Status::ok();
594}
595
Eric Laurent67816e32021-09-16 15:18:40 +0200596Status Spatializer::registerHeadTrackingCallback(
597 const sp<media::ISpatializerHeadTrackingCallback>& callback) {
598 ALOGV("%s callback %p", __func__, callback.get());
599 std::lock_guard lock(mLock);
600 if (!mSupportsHeadTracking) {
601 return binderStatusFromStatusT(INVALID_OPERATION);
602 }
603 mHeadTrackingCallback = callback;
604 return Status::ok();
605}
606
Eric Laurentc87402b2021-09-17 16:49:42 +0200607Status Spatializer::setParameter(int key, const std::vector<unsigned char>& value) {
608 ALOGV("%s key %d", __func__, key);
609 std::lock_guard lock(mLock);
610 status_t status = INVALID_OPERATION;
611 if (mEngine != nullptr) {
612 status = setEffectParameter_l(key, value);
613 }
614 return binderStatusFromStatusT(status);
615}
616
617Status Spatializer::getParameter(int key, std::vector<unsigned char> *value) {
Greg Kaiserf7249f82021-09-21 07:10:12 -0700618 ALOGV("%s key %d value size %d", __func__, key,
619 (value != nullptr ? (int)value->size() : -1));
Eric Laurentc87402b2021-09-17 16:49:42 +0200620 if (value == nullptr) {
George Burgess IV22386222021-09-22 12:09:31 -0700621 return binderStatusFromStatusT(BAD_VALUE);
Eric Laurentc87402b2021-09-17 16:49:42 +0200622 }
623 std::lock_guard lock(mLock);
624 status_t status = INVALID_OPERATION;
625 if (mEngine != nullptr) {
626 ALOGV("%s key %d mEngine %p", __func__, key, mEngine.get());
627 status = getEffectParameter_l(key, value);
628 }
629 return binderStatusFromStatusT(status);
630}
631
632Status Spatializer::getOutput(int *output) {
633 ALOGV("%s", __func__);
634 if (output == nullptr) {
635 binderStatusFromStatusT(BAD_VALUE);
636 }
637 std::lock_guard lock(mLock);
638 *output = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_io_handle_t_int32_t(mOutput));
639 ALOGV("%s got output %d", __func__, *output);
640 return Status::ok();
641}
642
Eric Laurent2be8b292021-08-23 09:44:33 -0700643// SpatializerPoseController::Listener
644void Spatializer::onHeadToStagePose(const Pose3f& headToStage) {
645 ALOGV("%s", __func__);
Eric Laurent780be4a2021-09-16 10:44:24 +0200646 LOG_ALWAYS_FATAL_IF(!mSupportsHeadTracking,
647 "onHeadToStagePose() called with no head tracking support!");
648
Eric Laurent2be8b292021-08-23 09:44:33 -0700649 auto vec = headToStage.toVector();
Eric Laurent8a4259f2021-09-14 16:04:00 +0200650 LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
651 "%s invalid head to stage vector size %zu", __func__, vec.size());
Eric Laurent8a4259f2021-09-14 16:04:00 +0200652 sp<AMessage> msg =
653 new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
654 for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
655 msg->setFloat(sHeadPoseKeys[i], vec[i]);
656 }
657 msg->post();
658}
659
660void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) {
661 ALOGV("%s", __func__);
Eric Laurent67816e32021-09-16 15:18:40 +0200662 sp<media::ISpatializerHeadTrackingCallback> callback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700663 {
664 std::lock_guard lock(mLock);
Eric Laurent67816e32021-09-16 15:18:40 +0200665 callback = mHeadTrackingCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700666 if (mEngine != nullptr) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200667 setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
Eric Laurent2be8b292021-08-23 09:44:33 -0700668 }
669 }
670
671 if (callback != nullptr) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200672 callback->onHeadToSoundStagePoseUpdated(headToStage);
Eric Laurent2be8b292021-08-23 09:44:33 -0700673 }
674}
675
676void Spatializer::onActualModeChange(HeadTrackingMode mode) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200677 ALOGV("%s(%d)", __func__, (int)mode);
678 sp<AMessage> msg =
679 new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
680 msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
681 msg->post();
682}
683
684void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) {
685 ALOGV("%s(%d)", __func__, (int) mode);
Eric Laurent67816e32021-09-16 15:18:40 +0200686 sp<media::ISpatializerHeadTrackingCallback> callback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700687 SpatializerHeadTrackingMode spatializerMode;
688 {
689 std::lock_guard lock(mLock);
690 if (!mSupportsHeadTracking) {
691 spatializerMode = SpatializerHeadTrackingMode::DISABLED;
692 } else {
693 switch (mode) {
694 case HeadTrackingMode::STATIC:
695 spatializerMode = SpatializerHeadTrackingMode::DISABLED;
696 break;
697 case HeadTrackingMode::WORLD_RELATIVE:
698 spatializerMode = SpatializerHeadTrackingMode::RELATIVE_WORLD;
699 break;
700 case HeadTrackingMode::SCREEN_RELATIVE:
701 spatializerMode = SpatializerHeadTrackingMode::RELATIVE_SCREEN;
702 break;
703 default:
704 LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
705 }
706 }
707 mActualHeadTrackingMode = spatializerMode;
Eric Laurente51f80e2022-04-14 10:20:38 +0200708 if (mEngine != nullptr) {
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200709 setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
710 std::vector<SpatializerHeadTrackingMode>{spatializerMode});
711 }
Eric Laurent67816e32021-09-16 15:18:40 +0200712 callback = mHeadTrackingCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700713 }
Eric Laurente51f80e2022-04-14 10:20:38 +0200714 if (callback != nullptr) {
Eric Laurent2be8b292021-08-23 09:44:33 -0700715 callback->onHeadTrackingModeChanged(spatializerMode);
716 }
717}
718
Eric Laurent15903592022-02-24 20:44:36 +0100719status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
Eric Laurent4a872862021-10-11 17:06:47 +0200720 bool outputChanged = false;
721 sp<media::INativeSpatializerCallback> callback;
722
Eric Laurent2be8b292021-08-23 09:44:33 -0700723 {
724 std::lock_guard lock(mLock);
725 ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput);
726 if (mOutput != AUDIO_IO_HANDLE_NONE) {
727 LOG_ALWAYS_FATAL_IF(mEngine == nullptr, "%s output set without FX engine", __func__);
728 // remove FX instance
729 mEngine->setEnabled(false);
730 mEngine.clear();
Eric Laurent15903592022-02-24 20:44:36 +0100731 mPoseController.reset();
Eric Laurentee398ad2022-05-03 18:19:35 +0200732 AudioSystem::removeSupportedLatencyModesCallback(this);
Eric Laurent2be8b292021-08-23 09:44:33 -0700733 }
Eric Laurentee398ad2022-05-03 18:19:35 +0200734
Eric Laurent2be8b292021-08-23 09:44:33 -0700735 // create FX instance on output
736 AttributionSourceState attributionSource = AttributionSourceState();
737 mEngine = new AudioEffect(attributionSource);
738 mEngine->set(nullptr, &mEngineDescriptor.uuid, 0, Spatializer::engineCallback /* cbf */,
739 this /* user */, AUDIO_SESSION_OUTPUT_STAGE, output, {} /* device */,
740 false /* probe */, true /* notifyFramesProcessed */);
741 status_t status = mEngine->initCheck();
742 ALOGV("%s mEngine create status %d", __func__, (int)status);
743 if (status != NO_ERROR) {
744 return status;
745 }
746
Eric Laurent4a872862021-10-11 17:06:47 +0200747 outputChanged = mOutput != output;
Eric Laurent2be8b292021-08-23 09:44:33 -0700748 mOutput = output;
Eric Laurent11094172022-04-05 18:27:42 +0200749 mNumActiveTracks = numActiveTracks;
Eric Laurentee398ad2022-05-03 18:19:35 +0200750 AudioSystem::addSupportedLatencyModesCallback(this);
751
752 std::vector<audio_latency_mode_t> latencyModes;
753 status = AudioSystem::getSupportedLatencyModes(mOutput, &latencyModes);
754 if (status == OK) {
755 mSupportedLatencyModes = latencyModes;
756 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700757
Eric Laurent11094172022-04-05 18:27:42 +0200758 checkEngineState_l();
Eric Laurent780be4a2021-09-16 10:44:24 +0200759 if (mSupportsHeadTracking) {
Eric Laurent11094172022-04-05 18:27:42 +0200760 checkPoseController_l();
Eric Laurent9249d342022-03-18 11:55:56 +0100761 checkSensorsState_l();
Eric Laurent780be4a2021-09-16 10:44:24 +0200762 }
Eric Laurent4a872862021-10-11 17:06:47 +0200763 callback = mSpatializerCallback;
Eric Laurent6d607012021-07-05 11:54:40 +0200764 }
Eric Laurent4a872862021-10-11 17:06:47 +0200765
766 if (outputChanged && callback != nullptr) {
767 callback->onOutputChanged(output);
768 }
769
Eric Laurent6d607012021-07-05 11:54:40 +0200770 return NO_ERROR;
771}
772
773audio_io_handle_t Spatializer::detachOutput() {
Eric Laurent2be8b292021-08-23 09:44:33 -0700774 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent4a872862021-10-11 17:06:47 +0200775 sp<media::INativeSpatializerCallback> callback;
776
777 {
778 std::lock_guard lock(mLock);
779 ALOGV("%s mOutput %d", __func__, (int)mOutput);
780 if (mOutput == AUDIO_IO_HANDLE_NONE) {
781 return output;
782 }
783 // remove FX instance
784 mEngine->setEnabled(false);
785 mEngine.clear();
Eric Laurentee398ad2022-05-03 18:19:35 +0200786 AudioSystem::removeSupportedLatencyModesCallback(this);
Eric Laurent4a872862021-10-11 17:06:47 +0200787 output = mOutput;
788 mOutput = AUDIO_IO_HANDLE_NONE;
789 mPoseController.reset();
Eric Laurent4a872862021-10-11 17:06:47 +0200790 callback = mSpatializerCallback;
Eric Laurent6d607012021-07-05 11:54:40 +0200791 }
Eric Laurent4a872862021-10-11 17:06:47 +0200792
793 if (callback != nullptr) {
794 callback->onOutputChanged(AUDIO_IO_HANDLE_NONE);
795 }
Eric Laurent6d607012021-07-05 11:54:40 +0200796 return output;
797}
798
Eric Laurentee398ad2022-05-03 18:19:35 +0200799void Spatializer::onSupportedLatencyModesChanged(
800 audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) {
Eric Laurent9c04de92022-07-20 13:49:47 +0200801 ALOGV("%s output %d num modes %zu", __func__, (int)output, modes.size());
802 sp<AMessage> msg =
803 new AMessage(EngineCallbackHandler::kWhatOnLatencyModesChanged, mHandler);
804 msg->setObject(EngineCallbackHandler::kLatencyModesKey,
805 sp<EngineCallbackHandler::LatencyModes>::make(output, modes));
806 msg->post();
807}
808
809void Spatializer::onSupportedLatencyModesChangedMsg(
810 audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes) {
Eric Laurentee398ad2022-05-03 18:19:35 +0200811 std::lock_guard lock(mLock);
Eric Laurent9c04de92022-07-20 13:49:47 +0200812 ALOGV("%s output %d mOutput %d num modes %zu",
813 __func__, (int)output, (int)mOutput, modes.size());
Eric Laurentee398ad2022-05-03 18:19:35 +0200814 if (output == mOutput) {
Eric Laurent9c04de92022-07-20 13:49:47 +0200815 mSupportedLatencyModes = std::move(modes);
Eric Laurentee398ad2022-05-03 18:19:35 +0200816 checkSensorsState_l();
817 }
818}
819
Eric Laurent15903592022-02-24 20:44:36 +0100820void Spatializer::updateActiveTracks(size_t numActiveTracks) {
821 std::lock_guard lock(mLock);
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200822 if (mNumActiveTracks != numActiveTracks) {
823 mNumActiveTracks = numActiveTracks;
824 checkEngineState_l();
825 checkSensorsState_l();
826 }
Eric Laurent15903592022-02-24 20:44:36 +0100827}
828
Eric Laurent9249d342022-03-18 11:55:56 +0100829void Spatializer::checkSensorsState_l() {
Eric Laurentee398ad2022-05-03 18:19:35 +0200830 audio_latency_mode_t requestedLatencyMode = AUDIO_LATENCY_MODE_FREE;
831 bool lowLatencySupported = mSupportedLatencyModes.empty()
832 || (std::find(mSupportedLatencyModes.begin(), mSupportedLatencyModes.end(),
833 AUDIO_LATENCY_MODE_LOW) != mSupportedLatencyModes.end());
Eric Laurent9bcefc62022-07-08 13:35:46 +0200834 if (mSupportsHeadTracking && mPoseController != nullptr) {
835 if (lowLatencySupported && mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
Eric Laurent15903592022-02-24 20:44:36 +0100836 && mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
837 && mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
838 mPoseController->setHeadSensor(mHeadSensor);
Eric Laurent9249d342022-03-18 11:55:56 +0100839 mPoseController->setScreenSensor(mScreenSensor);
Eric Laurentee398ad2022-05-03 18:19:35 +0200840 requestedLatencyMode = AUDIO_LATENCY_MODE_LOW;
Eric Laurent15903592022-02-24 20:44:36 +0100841 } else {
842 mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR);
Eric Laurent9249d342022-03-18 11:55:56 +0100843 mPoseController->setScreenSensor(SpatializerPoseController::INVALID_SENSOR);
Eric Laurent15903592022-02-24 20:44:36 +0100844 }
845 }
Eric Laurentee398ad2022-05-03 18:19:35 +0200846 if (mOutput != AUDIO_IO_HANDLE_NONE) {
847 AudioSystem::setRequestedLatencyMode(mOutput, requestedLatencyMode);
848 }
Eric Laurent15903592022-02-24 20:44:36 +0100849}
850
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200851void Spatializer::checkEngineState_l() {
852 if (mEngine != nullptr) {
853 if (mLevel != SpatializationLevel::NONE && mNumActiveTracks > 0) {
854 mEngine->setEnabled(true);
855 setEffectParameter_l(SPATIALIZER_PARAM_LEVEL,
856 std::vector<SpatializationLevel>{mLevel});
857 setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
858 std::vector<SpatializerHeadTrackingMode>{mActualHeadTrackingMode});
859 } else {
860 setEffectParameter_l(SPATIALIZER_PARAM_LEVEL,
861 std::vector<SpatializationLevel>{SpatializationLevel::NONE});
862 mEngine->setEnabled(false);
863 }
864 }
865}
866
Eric Laurent11094172022-04-05 18:27:42 +0200867void Spatializer::checkPoseController_l() {
868 bool isControllerNeeded = mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
869 && mHeadSensor != SpatializerPoseController::INVALID_SENSOR;
870
871 if (isControllerNeeded && mPoseController == nullptr) {
872 mPoseController = std::make_shared<SpatializerPoseController>(
873 static_cast<SpatializerPoseController::Listener*>(this),
Eric Laurente51f80e2022-04-14 10:20:38 +0200874 10ms, std::nullopt);
Eric Laurent11094172022-04-05 18:27:42 +0200875 LOG_ALWAYS_FATAL_IF(mPoseController == nullptr,
876 "%s could not allocate pose controller", __func__);
877 mPoseController->setDisplayOrientation(mDisplayOrientation);
878 } else if (!isControllerNeeded && mPoseController != nullptr) {
879 mPoseController.reset();
880 }
881 if (mPoseController != nullptr) {
882 mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
883 }
884}
885
Eric Laurent2be8b292021-08-23 09:44:33 -0700886void Spatializer::calculateHeadPose() {
887 ALOGV("%s", __func__);
888 std::lock_guard lock(mLock);
889 if (mPoseController != nullptr) {
890 mPoseController->calculateAsync();
891 }
892}
Eric Laurent6d607012021-07-05 11:54:40 +0200893
Eric Laurent2be8b292021-08-23 09:44:33 -0700894void Spatializer::engineCallback(int32_t event, void *user, void *info) {
Eric Laurent6d607012021-07-05 11:54:40 +0200895 if (user == nullptr) {
896 return;
897 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700898 Spatializer* const me = reinterpret_cast<Spatializer *>(user);
Eric Laurent6d607012021-07-05 11:54:40 +0200899 switch (event) {
900 case AudioEffect::EVENT_FRAMES_PROCESSED: {
Eric Laurent2be8b292021-08-23 09:44:33 -0700901 int frames = info == nullptr ? 0 : *(int*)info;
Eric Laurent9249d342022-03-18 11:55:56 +0100902 ALOGV("%s frames processed %d for me %p", __func__, frames, me);
Eric Laurent8a4259f2021-09-14 16:04:00 +0200903 me->postFramesProcessedMsg(frames);
Eric Laurent2be8b292021-08-23 09:44:33 -0700904 } break;
Eric Laurent6d607012021-07-05 11:54:40 +0200905 default:
Eric Laurent9249d342022-03-18 11:55:56 +0100906 ALOGV("%s event %d", __func__, event);
Eric Laurent6d607012021-07-05 11:54:40 +0200907 break;
908 }
909}
910
Eric Laurent8a4259f2021-09-14 16:04:00 +0200911void Spatializer::postFramesProcessedMsg(int frames) {
912 sp<AMessage> msg =
913 new AMessage(EngineCallbackHandler::kWhatOnFramesProcessed, mHandler);
914 msg->setInt32(EngineCallbackHandler::kNumFramesKey, frames);
915 msg->post();
916}
917
Eric Laurent6d607012021-07-05 11:54:40 +0200918} // namespace android