blob: ddc08c1a83d2bd20c3f1a9f200ba559253dd1b87 [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>
Eric Laurent2be8b292021-08-23 09:44:33 -070028#include <android/sensor.h>
Eric Laurent6d607012021-07-05 11:54:40 +020029#include <audio_utils/fixedfft.h>
30#include <cutils/bitops.h>
Eric Laurent2be8b292021-08-23 09:44:33 -070031#include <hardware/sensors.h>
Eric Laurent6d607012021-07-05 11:54:40 +020032#include <media/audiohal/EffectsFactoryHalInterface.h>
Eric Laurent8a4259f2021-09-14 16:04:00 +020033#include <media/stagefright/foundation/AHandler.h>
34#include <media/stagefright/foundation/AMessage.h>
35#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
61#define RETURN_IF_BINDER_ERROR(x) \
62 { \
63 binder::Status _tmp = (x); \
64 if (!_tmp.isOk()) return _tmp; \
65 }
66
67// ---------------------------------------------------------------------------
68
Eric Laurent8a4259f2021-09-14 16:04:00 +020069class Spatializer::EngineCallbackHandler : public AHandler {
70public:
71 EngineCallbackHandler(wp<Spatializer> spatializer)
72 : mSpatializer(spatializer) {
73 }
74
75 enum {
76 // Device state callbacks
77 kWhatOnFramesProcessed, // AudioEffect::EVENT_FRAMES_PROCESSED
78 kWhatOnHeadToStagePose, // SpatializerPoseController::Listener::onHeadToStagePose
79 kWhatOnActualModeChange, // SpatializerPoseController::Listener::onActualModeChange
80 };
81 static constexpr const char *kNumFramesKey = "numFrames";
82 static constexpr const char *kModeKey = "mode";
83 static constexpr const char *kTranslation0Key = "translation0";
84 static constexpr const char *kTranslation1Key = "translation1";
85 static constexpr const char *kTranslation2Key = "translation2";
86 static constexpr const char *kRotation0Key = "rotation0";
87 static constexpr const char *kRotation1Key = "rotation1";
88 static constexpr const char *kRotation2Key = "rotation2";
89
90 void onMessageReceived(const sp<AMessage> &msg) override {
91 switch (msg->what()) {
92 case kWhatOnFramesProcessed: {
93 sp<Spatializer> spatializer = mSpatializer.promote();
94 if (spatializer == nullptr) {
95 ALOGW("%s: Cannot promote spatializer", __func__);
96 return;
97 }
98 int numFrames;
99 if (!msg->findInt32(kNumFramesKey, &numFrames)) {
100 ALOGE("%s: Cannot find num frames!", __func__);
101 return;
102 }
103 if (numFrames > 0) {
104 spatializer->calculateHeadPose();
105 }
106 } break;
107 case kWhatOnHeadToStagePose: {
108 sp<Spatializer> spatializer = mSpatializer.promote();
109 if (spatializer == nullptr) {
110 ALOGW("%s: Cannot promote spatializer", __func__);
111 return;
112 }
113 std::vector<float> headToStage(sHeadPoseKeys.size());
114 for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
115 if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) {
116 ALOGE("%s: Cannot find kTranslation0Key!", __func__);
117 return;
118 }
119 }
120 spatializer->onHeadToStagePoseMsg(headToStage);
121 } break;
122 case kWhatOnActualModeChange: {
123 sp<Spatializer> spatializer = mSpatializer.promote();
124 if (spatializer == nullptr) {
125 ALOGW("%s: Cannot promote spatializer", __func__);
126 return;
127 }
128 int mode;
129 if (!msg->findInt32(EngineCallbackHandler::kModeKey, &mode)) {
130 ALOGE("%s: Cannot find actualMode!", __func__);
131 return;
132 }
133 spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode));
134 } break;
135 default:
136 LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what());
137 }
138 }
139private:
140 wp<Spatializer> mSpatializer;
141};
142
143const std::vector<const char *> Spatializer::sHeadPoseKeys = {
144 Spatializer::EngineCallbackHandler::kTranslation0Key,
145 Spatializer::EngineCallbackHandler::kTranslation1Key,
146 Spatializer::EngineCallbackHandler::kTranslation2Key,
147 Spatializer::EngineCallbackHandler::kRotation0Key,
148 Spatializer::EngineCallbackHandler::kRotation1Key,
149 Spatializer::EngineCallbackHandler::kRotation2Key,
150};
151
152// ---------------------------------------------------------------------------
Eric Laurent6d607012021-07-05 11:54:40 +0200153sp<Spatializer> Spatializer::create(SpatializerPolicyCallback *callback) {
154 sp<Spatializer> spatializer;
155
156 sp<EffectsFactoryHalInterface> effectsFactoryHal = EffectsFactoryHalInterface::create();
157 if (effectsFactoryHal == nullptr) {
158 ALOGW("%s failed to create effect factory interface", __func__);
159 return spatializer;
160 }
161
162 std::vector<effect_descriptor_t> descriptors;
163 status_t status =
Eric Laurent1c5e2e32021-08-18 18:50:28 +0200164 effectsFactoryHal->getDescriptors(FX_IID_SPATIALIZER, &descriptors);
Eric Laurent6d607012021-07-05 11:54:40 +0200165 if (status != NO_ERROR) {
166 ALOGW("%s failed to get spatializer descriptor, error %d", __func__, status);
167 return spatializer;
168 }
169 ALOG_ASSERT(!descriptors.empty(),
170 "%s getDescriptors() returned no error but empty list", __func__);
171
172 //TODO: get supported spatialization modes from FX engine or descriptor
173
174 sp<EffectHalInterface> effect;
175 status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE,
176 AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect);
177 ALOGI("%s FX create status %d effect %p", __func__, status, effect.get());
178
179 if (status == NO_ERROR && effect != nullptr) {
180 spatializer = new Spatializer(descriptors[0], callback);
Eric Laurent2be8b292021-08-23 09:44:33 -0700181 if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) {
182 spatializer.clear();
183 }
Eric Laurent6d607012021-07-05 11:54:40 +0200184 }
185
186 return spatializer;
187}
188
Eric Laurent2be8b292021-08-23 09:44:33 -0700189Spatializer::Spatializer(effect_descriptor_t engineDescriptor, SpatializerPolicyCallback* callback)
190 : mEngineDescriptor(engineDescriptor),
191 mPolicyCallback(callback) {
Eric Laurent6d607012021-07-05 11:54:40 +0200192 ALOGV("%s", __func__);
193}
194
Eric Laurent8a4259f2021-09-14 16:04:00 +0200195void Spatializer::onFirstRef() {
196 mLooper = new ALooper;
197 mLooper->setName("Spatializer-looper");
198 mLooper->start(
199 /*runOnCallingThread*/false,
200 /*canCallJava*/ false,
201 PRIORITY_AUDIO);
202
203 mHandler = new EngineCallbackHandler(this);
204 mLooper->registerHandler(mHandler);
205}
206
Eric Laurent6d607012021-07-05 11:54:40 +0200207Spatializer::~Spatializer() {
208 ALOGV("%s", __func__);
Eric Laurent8a4259f2021-09-14 16:04:00 +0200209 if (mLooper != nullptr) {
210 mLooper->stop();
211 mLooper->unregisterHandler(mHandler->id());
212 }
213 mLooper.clear();
214 mHandler.clear();
Eric Laurent6d607012021-07-05 11:54:40 +0200215}
216
Eric Laurent2be8b292021-08-23 09:44:33 -0700217status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
218 ALOGV("%s", __func__);
219
220 std::vector<bool> supportsHeadTracking;
221 status_t status = getHalParameter<false>(effect, SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED,
222 &supportsHeadTracking);
223 if (status != NO_ERROR) {
224 return status;
225 }
226 mSupportsHeadTracking = supportsHeadTracking[0];
227
228 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_LEVELS, &mLevels);
229 if (status != NO_ERROR) {
230 return status;
231 }
232 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES,
233 &mSpatializationModes);
234 if (status != NO_ERROR) {
235 return status;
236 }
237 status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS,
238 &mChannelMasks);
239 if (status != NO_ERROR) {
240 return status;
241 }
242 return NO_ERROR;
243}
244
245/** Gets the channel mask, sampling rate and format set for the spatializer input. */
246audio_config_base_t Spatializer::getAudioInConfig() const {
247 std::lock_guard lock(mLock);
248 audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
249 // For now use highest supported channel count
250 uint32_t maxCount = 0;
251 for ( auto mask : mChannelMasks) {
252 if (audio_channel_count_from_out_mask(mask) > maxCount) {
253 config.channel_mask = mask;
254 }
255 }
256 return config;
257}
258
Eric Laurent6d607012021-07-05 11:54:40 +0200259status_t Spatializer::registerCallback(
260 const sp<media::INativeSpatializerCallback>& callback) {
Eric Laurent2be8b292021-08-23 09:44:33 -0700261 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200262 if (callback == nullptr) {
263 return BAD_VALUE;
264 }
265
266 sp<IBinder> binder = IInterface::asBinder(callback);
267 status_t status = binder->linkToDeath(this);
268 if (status == NO_ERROR) {
269 mSpatializerCallback = callback;
270 }
271 ALOGV("%s status %d", __func__, status);
272 return status;
273}
274
275// IBinder::DeathRecipient
276void Spatializer::binderDied(__unused const wp<IBinder> &who) {
277 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700278 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200279 mLevel = SpatializationLevel::NONE;
280 mSpatializerCallback.clear();
281 }
282 ALOGV("%s", __func__);
283 mPolicyCallback->onCheckSpatializer();
284}
285
286// ISpatializer
287Status Spatializer::getSupportedLevels(std::vector<SpatializationLevel> *levels) {
288 ALOGV("%s", __func__);
289 if (levels == nullptr) {
290 return binderStatusFromStatusT(BAD_VALUE);
291 }
Eric Laurent6d607012021-07-05 11:54:40 +0200292 levels->push_back(SpatializationLevel::NONE);
Eric Laurent2be8b292021-08-23 09:44:33 -0700293 levels->insert(levels->end(), mLevels.begin(), mLevels.end());
Eric Laurent6d607012021-07-05 11:54:40 +0200294 return Status::ok();
295}
296
Eric Laurent2be8b292021-08-23 09:44:33 -0700297Status Spatializer::setLevel(SpatializationLevel level) {
Eric Laurent6d607012021-07-05 11:54:40 +0200298 ALOGV("%s level %d", __func__, (int)level);
299 if (level != SpatializationLevel::NONE
Eric Laurent2be8b292021-08-23 09:44:33 -0700300 && std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) {
Eric Laurent6d607012021-07-05 11:54:40 +0200301 return binderStatusFromStatusT(BAD_VALUE);
302 }
303 sp<media::INativeSpatializerCallback> callback;
304 bool levelChanged = false;
305 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700306 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200307 levelChanged = mLevel != level;
308 mLevel = level;
309 callback = mSpatializerCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700310
311 if (levelChanged && mEngine != nullptr) {
312 setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
313 }
Eric Laurent6d607012021-07-05 11:54:40 +0200314 }
315
316 if (levelChanged) {
317 mPolicyCallback->onCheckSpatializer();
318 if (callback != nullptr) {
319 callback->onLevelChanged(level);
320 }
321 }
322 return Status::ok();
323}
324
Eric Laurent2be8b292021-08-23 09:44:33 -0700325Status Spatializer::getLevel(SpatializationLevel *level) {
Eric Laurent6d607012021-07-05 11:54:40 +0200326 if (level == nullptr) {
327 return binderStatusFromStatusT(BAD_VALUE);
328 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700329 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200330 *level = mLevel;
331 ALOGV("%s level %d", __func__, (int)*level);
332 return Status::ok();
333}
334
335Status Spatializer::getSupportedHeadTrackingModes(
Eric Laurent2be8b292021-08-23 09:44:33 -0700336 std::vector<SpatializerHeadTrackingMode>* modes) {
337 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200338 ALOGV("%s", __func__);
339 if (modes == nullptr) {
340 return binderStatusFromStatusT(BAD_VALUE);
341 }
Eric Laurent6d607012021-07-05 11:54:40 +0200342
Eric Laurent2be8b292021-08-23 09:44:33 -0700343 modes->push_back(SpatializerHeadTrackingMode::DISABLED);
344 if (mSupportsHeadTracking) {
345 if (mHeadSensor != nullptr) {
346 modes->push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
347 if (mScreenSensor != nullptr) {
348 modes->push_back(SpatializerHeadTrackingMode::RELATIVE_SCREEN);
349 }
350 }
Eric Laurent6d607012021-07-05 11:54:40 +0200351 }
352 return Status::ok();
353}
354
Eric Laurent2be8b292021-08-23 09:44:33 -0700355Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) {
356 ALOGV("%s mode %d", __func__, (int)mode);
357
358 if (!mSupportsHeadTracking) {
359 return binderStatusFromStatusT(INVALID_OPERATION);
360 }
361 std::lock_guard lock(mLock);
362 switch (mode) {
363 case SpatializerHeadTrackingMode::OTHER:
364 return binderStatusFromStatusT(BAD_VALUE);
365 case SpatializerHeadTrackingMode::DISABLED:
366 mDesiredHeadTrackingMode = HeadTrackingMode::STATIC;
367 break;
368 case SpatializerHeadTrackingMode::RELATIVE_WORLD:
369 mDesiredHeadTrackingMode = HeadTrackingMode::WORLD_RELATIVE;
370 break;
371 case SpatializerHeadTrackingMode::RELATIVE_SCREEN:
372 mDesiredHeadTrackingMode = HeadTrackingMode::SCREEN_RELATIVE;
373 break;
374 }
375
376 if (mPoseController != nullptr) {
377 mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
378 }
379
380 return Status::ok();
381}
382
383Status Spatializer::getActualHeadTrackingMode(SpatializerHeadTrackingMode *mode) {
Eric Laurent6d607012021-07-05 11:54:40 +0200384 if (mode == nullptr) {
385 return binderStatusFromStatusT(BAD_VALUE);
386 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700387 std::lock_guard lock(mLock);
388 *mode = mActualHeadTrackingMode;
Eric Laurent6d607012021-07-05 11:54:40 +0200389 ALOGV("%s mode %d", __func__, (int)*mode);
390 return Status::ok();
391}
392
Ytai Ben-Tsvia16a9df2021-08-05 08:57:06 -0700393Status Spatializer::recenterHeadTracker() {
Eric Laurent780be4a2021-09-16 10:44:24 +0200394 if (!mSupportsHeadTracking) {
395 return binderStatusFromStatusT(INVALID_OPERATION);
396 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700397 std::lock_guard lock(mLock);
398 if (mPoseController != nullptr) {
399 mPoseController->recenter();
400 }
Eric Laurent6d607012021-07-05 11:54:40 +0200401 return Status::ok();
402}
403
404Status Spatializer::setGlobalTransform(const std::vector<float>& screenToStage) {
Eric Laurent6d607012021-07-05 11:54:40 +0200405 ALOGV("%s", __func__);
Eric Laurent780be4a2021-09-16 10:44:24 +0200406 if (!mSupportsHeadTracking) {
407 return binderStatusFromStatusT(INVALID_OPERATION);
408 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700409 std::optional<Pose3f> maybePose = Pose3f::fromVector(screenToStage);
410 if (!maybePose.has_value()) {
411 ALOGW("Invalid screenToStage vector.");
412 return binderStatusFromStatusT(BAD_VALUE);
413 }
414 std::lock_guard lock(mLock);
415 if (mPoseController != nullptr) {
416 mPoseController->setScreenToStagePose(maybePose.value());
417 }
Eric Laurent6d607012021-07-05 11:54:40 +0200418 return Status::ok();
419}
420
421Status Spatializer::release() {
422 ALOGV("%s", __func__);
423 bool levelChanged = false;
424 {
Eric Laurent2be8b292021-08-23 09:44:33 -0700425 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200426 if (mSpatializerCallback == nullptr) {
427 return binderStatusFromStatusT(INVALID_OPERATION);
428 }
429
430 sp<IBinder> binder = IInterface::asBinder(mSpatializerCallback);
431 binder->unlinkToDeath(this);
432 mSpatializerCallback.clear();
433
434 levelChanged = mLevel != SpatializationLevel::NONE;
435 mLevel = SpatializationLevel::NONE;
436 }
437
438 if (levelChanged) {
439 mPolicyCallback->onCheckSpatializer();
440 }
441 return Status::ok();
442}
443
Eric Laurent2be8b292021-08-23 09:44:33 -0700444Status Spatializer::setHeadSensor(int sensorHandle) {
445 ALOGV("%s sensorHandle %d", __func__, sensorHandle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200446 if (!mSupportsHeadTracking) {
447 return binderStatusFromStatusT(INVALID_OPERATION);
448 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700449 std::lock_guard lock(mLock);
450 if (sensorHandle == ASENSOR_INVALID) {
451 mHeadSensor = nullptr;
452 } else {
453 mHeadSensor = VALUE_OR_RETURN_BINDER_STATUS(getSensorFromHandle(sensorHandle));
454 }
455 if (mPoseController != nullptr) {
456 mPoseController->setHeadSensor(mHeadSensor);
457 }
458 return Status::ok();
459}
460
461Status Spatializer::setScreenSensor(int sensorHandle) {
462 ALOGV("%s sensorHandle %d", __func__, sensorHandle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200463 if (!mSupportsHeadTracking) {
464 return binderStatusFromStatusT(INVALID_OPERATION);
465 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700466 std::lock_guard lock(mLock);
467 if (sensorHandle == ASENSOR_INVALID) {
468 mScreenSensor = nullptr;
469 } else {
470 mScreenSensor = VALUE_OR_RETURN_BINDER_STATUS(getSensorFromHandle(sensorHandle));
471 }
472 if (mPoseController != nullptr) {
473 mPoseController->setScreenSensor(mScreenSensor);
474 }
475 return Status::ok();
476}
477
478Status Spatializer::setDisplayOrientation(float physicalToLogicalAngle) {
479 ALOGV("%s physicalToLogicalAngle %f", __func__, physicalToLogicalAngle);
Eric Laurent780be4a2021-09-16 10:44:24 +0200480 if (!mSupportsHeadTracking) {
481 return binderStatusFromStatusT(INVALID_OPERATION);
482 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700483 std::lock_guard lock(mLock);
484 mDisplayOrientation = physicalToLogicalAngle;
485 if (mPoseController != nullptr) {
486 mPoseController->setDisplayOrientation(mDisplayOrientation);
487 }
Eric Laurent16ddaf42021-09-17 15:00:35 +0200488 if (mEngine != nullptr) {
489 setEffectParameter_l(
490 SPATIALIZER_PARAM_DISPLAY_ORIENTATION, std::vector<float>{physicalToLogicalAngle});
491 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700492 return Status::ok();
493}
494
495Status Spatializer::setHingeAngle(float hingeAngle) {
496 std::lock_guard lock(mLock);
497 ALOGV("%s hingeAngle %f", __func__, hingeAngle);
498 if (mEngine != nullptr) {
499 setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{hingeAngle});
500 }
501 return Status::ok();
502}
503
504Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) {
505 ALOGV("%s", __func__);
506 if (modes == nullptr) {
507 return binderStatusFromStatusT(BAD_VALUE);
508 }
509 *modes = mSpatializationModes;
510 return Status::ok();
511}
512
Eric Laurent67816e32021-09-16 15:18:40 +0200513Status Spatializer::registerHeadTrackingCallback(
514 const sp<media::ISpatializerHeadTrackingCallback>& callback) {
515 ALOGV("%s callback %p", __func__, callback.get());
516 std::lock_guard lock(mLock);
517 if (!mSupportsHeadTracking) {
518 return binderStatusFromStatusT(INVALID_OPERATION);
519 }
520 mHeadTrackingCallback = callback;
521 return Status::ok();
522}
523
Eric Laurent2be8b292021-08-23 09:44:33 -0700524// SpatializerPoseController::Listener
525void Spatializer::onHeadToStagePose(const Pose3f& headToStage) {
526 ALOGV("%s", __func__);
Eric Laurent780be4a2021-09-16 10:44:24 +0200527 LOG_ALWAYS_FATAL_IF(!mSupportsHeadTracking,
528 "onHeadToStagePose() called with no head tracking support!");
529
Eric Laurent2be8b292021-08-23 09:44:33 -0700530 auto vec = headToStage.toVector();
Eric Laurent8a4259f2021-09-14 16:04:00 +0200531 LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
532 "%s invalid head to stage vector size %zu", __func__, vec.size());
533
534 sp<AMessage> msg =
535 new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
536 for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
537 msg->setFloat(sHeadPoseKeys[i], vec[i]);
538 }
539 msg->post();
540}
541
542void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) {
543 ALOGV("%s", __func__);
Eric Laurent67816e32021-09-16 15:18:40 +0200544 sp<media::ISpatializerHeadTrackingCallback> callback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700545 {
546 std::lock_guard lock(mLock);
Eric Laurent67816e32021-09-16 15:18:40 +0200547 callback = mHeadTrackingCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700548 if (mEngine != nullptr) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200549 setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
Eric Laurent2be8b292021-08-23 09:44:33 -0700550 }
551 }
552
553 if (callback != nullptr) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200554 callback->onHeadToSoundStagePoseUpdated(headToStage);
Eric Laurent2be8b292021-08-23 09:44:33 -0700555 }
556}
557
558void Spatializer::onActualModeChange(HeadTrackingMode mode) {
Eric Laurent8a4259f2021-09-14 16:04:00 +0200559 ALOGV("%s(%d)", __func__, (int)mode);
560 sp<AMessage> msg =
561 new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
562 msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
563 msg->post();
564}
565
566void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) {
567 ALOGV("%s(%d)", __func__, (int) mode);
Eric Laurent67816e32021-09-16 15:18:40 +0200568 sp<media::ISpatializerHeadTrackingCallback> callback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700569 SpatializerHeadTrackingMode spatializerMode;
570 {
571 std::lock_guard lock(mLock);
572 if (!mSupportsHeadTracking) {
573 spatializerMode = SpatializerHeadTrackingMode::DISABLED;
574 } else {
575 switch (mode) {
576 case HeadTrackingMode::STATIC:
577 spatializerMode = SpatializerHeadTrackingMode::DISABLED;
578 break;
579 case HeadTrackingMode::WORLD_RELATIVE:
580 spatializerMode = SpatializerHeadTrackingMode::RELATIVE_WORLD;
581 break;
582 case HeadTrackingMode::SCREEN_RELATIVE:
583 spatializerMode = SpatializerHeadTrackingMode::RELATIVE_SCREEN;
584 break;
585 default:
586 LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
587 }
588 }
589 mActualHeadTrackingMode = spatializerMode;
Eric Laurent67816e32021-09-16 15:18:40 +0200590 callback = mHeadTrackingCallback;
Eric Laurent2be8b292021-08-23 09:44:33 -0700591 }
592 if (callback != nullptr) {
593 callback->onHeadTrackingModeChanged(spatializerMode);
594 }
595}
596
597/* static */
598ConversionResult<ASensorRef> Spatializer::getSensorFromHandle(int handle) {
599 ASensorManager* sensorManager =
600 ASensorManager_getInstanceForPackage("headtracker");
601 if (!sensorManager) {
602 ALOGE("Failed to get a sensor manager");
603 return base::unexpected(NO_INIT);
604 }
605 ASensorList sensorList;
606 int numSensors = ASensorManager_getSensorList(sensorManager, &sensorList);
607 for (int i = 0; i < numSensors; ++i) {
608 if (ASensor_getHandle(sensorList[i]) == handle) {
609 return sensorList[i];
610 }
611 }
612 return base::unexpected(BAD_VALUE);
613}
614
Eric Laurent6d607012021-07-05 11:54:40 +0200615status_t Spatializer::attachOutput(audio_io_handle_t output) {
Eric Laurent2be8b292021-08-23 09:44:33 -0700616 std::shared_ptr<SpatializerPoseController> poseController;
617 {
618 std::lock_guard lock(mLock);
619 ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput);
620 if (mOutput != AUDIO_IO_HANDLE_NONE) {
621 LOG_ALWAYS_FATAL_IF(mEngine == nullptr, "%s output set without FX engine", __func__);
622 // remove FX instance
623 mEngine->setEnabled(false);
624 mEngine.clear();
625 }
626 // create FX instance on output
627 AttributionSourceState attributionSource = AttributionSourceState();
628 mEngine = new AudioEffect(attributionSource);
629 mEngine->set(nullptr, &mEngineDescriptor.uuid, 0, Spatializer::engineCallback /* cbf */,
630 this /* user */, AUDIO_SESSION_OUTPUT_STAGE, output, {} /* device */,
631 false /* probe */, true /* notifyFramesProcessed */);
632 status_t status = mEngine->initCheck();
633 ALOGV("%s mEngine create status %d", __func__, (int)status);
634 if (status != NO_ERROR) {
635 return status;
636 }
637
638 setEffectParameter_l(SPATIALIZER_PARAM_LEVEL,
639 std::vector<SpatializationLevel>{mLevel});
640 setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
641 std::vector<SpatializerHeadTrackingMode>{mActualHeadTrackingMode});
642
643 mEngine->setEnabled(true);
644 mOutput = output;
645
Eric Laurent780be4a2021-09-16 10:44:24 +0200646 if (mSupportsHeadTracking) {
647 mPoseController = std::make_shared<SpatializerPoseController>(
648 static_cast<SpatializerPoseController::Listener*>(this), 10ms, 50ms);
649 LOG_ALWAYS_FATAL_IF(mPoseController == nullptr,
650 "%s could not allocate pose controller", __func__);
Eric Laurent2be8b292021-08-23 09:44:33 -0700651
Eric Laurent780be4a2021-09-16 10:44:24 +0200652 mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
653 mPoseController->setHeadSensor(mHeadSensor);
654 mPoseController->setScreenSensor(mScreenSensor);
655 mPoseController->setDisplayOrientation(mDisplayOrientation);
656 poseController = mPoseController;
657 }
Eric Laurent6d607012021-07-05 11:54:40 +0200658 }
Eric Laurent780be4a2021-09-16 10:44:24 +0200659 if (poseController != nullptr) {
660 poseController->waitUntilCalculated();
661 }
Eric Laurent6d607012021-07-05 11:54:40 +0200662 return NO_ERROR;
663}
664
665audio_io_handle_t Spatializer::detachOutput() {
Eric Laurent2be8b292021-08-23 09:44:33 -0700666 std::lock_guard lock(mLock);
Eric Laurent6d607012021-07-05 11:54:40 +0200667 ALOGV("%s mOutput %d", __func__, (int)mOutput);
Eric Laurent2be8b292021-08-23 09:44:33 -0700668 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent6d607012021-07-05 11:54:40 +0200669 if (mOutput == AUDIO_IO_HANDLE_NONE) {
Eric Laurent2be8b292021-08-23 09:44:33 -0700670 return output;
Eric Laurent6d607012021-07-05 11:54:40 +0200671 }
672 // remove FX instance
673 mEngine->setEnabled(false);
674 mEngine.clear();
Eric Laurent2be8b292021-08-23 09:44:33 -0700675 output = mOutput;
Eric Laurent6d607012021-07-05 11:54:40 +0200676 mOutput = AUDIO_IO_HANDLE_NONE;
Eric Laurent2be8b292021-08-23 09:44:33 -0700677 mPoseController.reset();
Eric Laurent6d607012021-07-05 11:54:40 +0200678 return output;
679}
680
Eric Laurent2be8b292021-08-23 09:44:33 -0700681void Spatializer::calculateHeadPose() {
682 ALOGV("%s", __func__);
683 std::lock_guard lock(mLock);
684 if (mPoseController != nullptr) {
685 mPoseController->calculateAsync();
686 }
687}
Eric Laurent6d607012021-07-05 11:54:40 +0200688
Eric Laurent2be8b292021-08-23 09:44:33 -0700689void Spatializer::engineCallback(int32_t event, void *user, void *info) {
Eric Laurent6d607012021-07-05 11:54:40 +0200690 if (user == nullptr) {
691 return;
692 }
Eric Laurent2be8b292021-08-23 09:44:33 -0700693 Spatializer* const me = reinterpret_cast<Spatializer *>(user);
Eric Laurent6d607012021-07-05 11:54:40 +0200694 switch (event) {
695 case AudioEffect::EVENT_FRAMES_PROCESSED: {
Eric Laurent2be8b292021-08-23 09:44:33 -0700696 int frames = info == nullptr ? 0 : *(int*)info;
Eric Laurent6d607012021-07-05 11:54:40 +0200697 ALOGD("%s frames processed %d for me %p", __func__, frames, me);
Eric Laurent8a4259f2021-09-14 16:04:00 +0200698 me->postFramesProcessedMsg(frames);
Eric Laurent2be8b292021-08-23 09:44:33 -0700699 } break;
Eric Laurent6d607012021-07-05 11:54:40 +0200700 default:
701 ALOGD("%s event %d", __func__, event);
702 break;
703 }
704}
705
Eric Laurent8a4259f2021-09-14 16:04:00 +0200706void Spatializer::postFramesProcessedMsg(int frames) {
707 sp<AMessage> msg =
708 new AMessage(EngineCallbackHandler::kWhatOnFramesProcessed, mHandler);
709 msg->setInt32(EngineCallbackHandler::kNumFramesKey, frames);
710 msg->post();
711}
712
Eric Laurent6d607012021-07-05 11:54:40 +0200713} // namespace android