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 #ifndef ANDROID_MEDIA_SPATIALIZER_H 18 #define ANDROID_MEDIA_SPATIALIZER_H 19 20 #include <android-base/stringprintf.h> 21 #include <android/media/BnEffect.h> 22 #include <android/media/BnSpatializer.h> 23 #include <android/media/audio/common/AudioLatencyMode.h> 24 #include <android/media/audio/common/HeadTracking.h> 25 #include <android/media/audio/common/Spatialization.h> 26 #include <audio_utils/mutex.h> 27 #include <audio_utils/SimpleLog.h> 28 #include <math.h> 29 #include <media/AudioEffect.h> 30 #include <media/MediaMetricsItem.h> 31 #include <media/audiohal/EffectsFactoryHalInterface.h> 32 #include <media/VectorRecorder.h> 33 #include <media/audiohal/EffectHalInterface.h> 34 #include <media/stagefright/foundation/ALooper.h> 35 #include <system/audio_effects/effect_spatializer.h> 36 #include <string> 37 #include <unordered_set> 38 39 #include "SpatializerPoseController.h" 40 41 namespace android { 42 43 44 // ---------------------------------------------------------------------------- 45 46 /** 47 * A callback interface from the Spatializer object or its parent AudioPolicyService. 48 * This is implemented by the audio policy service hosting the Spatializer to perform 49 * actions needed when a state change inside the Spatializer requires some audio system 50 * changes that cannot be performed by the Spatializer. For instance opening or closing a 51 * spatializer output stream when the spatializer is enabled or disabled 52 */ 53 class SpatializerPolicyCallback { 54 public: 55 /** Called when a stage change occurs that requires the parent audio policy service to take 56 * some action. 57 */ 58 virtual void onCheckSpatializer() = 0; 59 60 virtual ~SpatializerPolicyCallback() = default; 61 }; 62 /** 63 * The Spatializer class implements all functional controlling the multichannel spatializer 64 * with head tracking implementation in the native audio service: audio policy and audio flinger. 65 * It presents an AIDL interface available to the java audio service to discover the availability 66 * of the feature and options, control its state and register an active head tracking sensor. 67 * It maintains the current state of the platform spatializer and applies the stored parameters 68 * when the spatializer engine is created and enabled. 69 * Based on the requested spatializer level, it will request the creation of a specialized output 70 * mixer to the audio policy service which will in turn notify the Spatializer of the output 71 * stream on which a spatializer engine should be created, configured and enabled. 72 * The spatializer also hosts the head tracking management logic. This logic receives the 73 * desired head tracking mode and selected head tracking sensor, registers a sensor event listener 74 * and derives the compounded head pose information to the spatializer engine. 75 * 76 * Workflow: 77 * - Initialization: when the audio policy service starts, it checks if a spatializer effect 78 * engine exists and if the audio policy manager reports a dedicated spatializer output profile. 79 * If both conditions are met, a Spatializer object is created 80 * - Capabilities discovery: AudioService will call AudioSystem::canBeSpatialized() and if true, 81 * acquire an ISpatializer interface with AudioSystem::getSpatializer(). This interface 82 * will be used to query the implementation capabilities and configure the spatializer. 83 * - Enabling: when ISpatializer::setLevel() sets a level different from NONE the spatializer 84 * is considered enabled. The audio policy callback onCheckSpatializer() is called. This 85 * triggers a request to audio policy manager to open a spatialization output stream and a 86 * spatializer mixer is created in audio flinger. When an output is returned by audio policy 87 * manager, Spatializer::attachOutput() is called which creates and enables the spatializer 88 * stage engine on the specified output. 89 * - Disabling: when the spatialization level is set to NONE, the spatializer is considered 90 * disabled. The audio policy callback onCheckSpatializer() is called. This triggers a call 91 * to Spatializer::detachOutput() and the spatializer engine is released. Then a request is 92 * made to audio policy manager to release and close the spatializer output stream and the 93 * spatializer mixer thread is destroyed. 94 */ 95 class Spatializer : public media::BnSpatializer, 96 public AudioEffect::IAudioEffectCallback, 97 public IBinder::DeathRecipient, 98 private SpatializerPoseController::Listener, 99 public virtual AudioSystem::SupportedLatencyModesCallback { 100 public: 101 static sp<Spatializer> create(SpatializerPolicyCallback* callback, 102 const sp<EffectsFactoryHalInterface>& effectsFactoryHal); 103 104 ~Spatializer() override; 105 106 /** RefBase */ 107 void onFirstRef(); 108 109 /** ISpatializer, see ISpatializer.aidl */ 110 binder::Status release() override; 111 binder::Status getSupportedLevels( 112 std::vector<media::audio::common::Spatialization::Level>* levels) override; 113 binder::Status setLevel(media::audio::common::Spatialization::Level level) override; 114 binder::Status getLevel(media::audio::common::Spatialization::Level *level) override; 115 binder::Status isHeadTrackingSupported(bool *supports); 116 binder::Status getSupportedHeadTrackingModes( 117 std::vector<media::audio::common::HeadTracking::Mode>* modes) override; 118 binder::Status setDesiredHeadTrackingMode( 119 media::audio::common::HeadTracking::Mode mode) override; 120 binder::Status getActualHeadTrackingMode( 121 media::audio::common::HeadTracking::Mode* mode) override; 122 binder::Status recenterHeadTracker() override; 123 binder::Status setGlobalTransform(const std::vector<float>& screenToStage) override; 124 binder::Status setHeadSensor(int sensorHandle) override; 125 binder::Status setScreenSensor(int sensorHandle) override; 126 binder::Status setDisplayOrientation(float physicalToLogicalAngle) override; 127 binder::Status setHingeAngle(float hingeAngle) override; 128 binder::Status setFoldState(bool folded) override; 129 binder::Status getSupportedModes( 130 std::vector<media::audio::common::Spatialization::Mode>* modes) override; 131 binder::Status registerHeadTrackingCallback( 132 const sp<media::ISpatializerHeadTrackingCallback>& callback) override; 133 binder::Status setParameter(int key, const std::vector<unsigned char>& value) override; 134 binder::Status getParameter(int key, std::vector<unsigned char> *value) override; 135 binder::Status getOutput(int *output); 136 binder::Status getSpatializedChannelMasks(std::vector<int>* masks) override; 137 138 /** IBinder::DeathRecipient. Listen to the death of the INativeSpatializerCallback. */ 139 virtual void binderDied(const wp<IBinder>& who); 140 141 /** SupportedLatencyModesCallback */ 142 void onSupportedLatencyModesChanged( 143 audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) override; 144 145 /** Registers a INativeSpatializerCallback when a client is attached to this Spatializer 146 * by audio policy service. 147 */ 148 status_t registerCallback(const sp<media::INativeSpatializerCallback>& callback); 149 150 status_t loadEngineConfiguration(sp<EffectHalInterface> effect); 151 152 /** Level getter for use by local classes. */ getLevel()153 media::audio::common::Spatialization::Level getLevel() const { 154 audio_utils::lock_guard lock(mMutex); 155 return mLevel; 156 } 157 158 /** For test only */ 159 std::unordered_set<media::audio::common::HeadTracking::ConnectionMode> getSupportedHeadtrackingConnectionModes()160 getSupportedHeadtrackingConnectionModes() const { 161 return mSupportedHeadtrackingConnectionModes; 162 } 163 164 /** For test only */ getHeadtrackingConnectionMode()165 media::audio::common::HeadTracking::ConnectionMode getHeadtrackingConnectionMode() const { 166 return mHeadtrackingConnectionMode; 167 } 168 169 /** For test only */ getSupportedLatencyModes()170 std::vector<audio_latency_mode_t> getSupportedLatencyModes() const { 171 audio_utils::lock_guard lock(mMutex); 172 return mSupportedLatencyModes; 173 } 174 175 /** For test only */ getOrderedLowLatencyModes()176 std::vector<audio_latency_mode_t> getOrderedLowLatencyModes() const { 177 return mOrderedLowLatencyModes; 178 } 179 180 /** For test only */ getRequestedLatencyMode()181 audio_latency_mode_t getRequestedLatencyMode() const { 182 audio_utils::lock_guard lock(mMutex); 183 return mRequestedLatencyMode; 184 } 185 186 /** Called by audio policy service when the special output mixer dedicated to spatialization 187 * is opened and the spatializer engine must be created. 188 */ 189 status_t attachOutput(audio_io_handle_t output, 190 const std::vector<audio_channel_mask_t>& activeTracksMasks); 191 /** Called by audio policy service when the special output mixer dedicated to spatialization 192 * is closed and the spatializer engine must be release. 193 */ 194 audio_io_handle_t detachOutput(); 195 /** Returns the output stream the spatializer is attached to. */ getOutput()196 audio_io_handle_t getOutput() const { audio_utils::lock_guard lock(mMutex); return mOutput; } 197 198 /** For test only */ setOutput(audio_io_handle_t output)199 void setOutput(audio_io_handle_t output) { 200 audio_utils::lock_guard lock(mMutex); 201 mOutput = output; 202 } 203 204 void updateActiveTracks(const std::vector<audio_channel_mask_t>& activeTracksMasks); 205 206 /** Gets the channel mask, sampling rate and format set for the spatializer input. */ 207 audio_config_base_t getAudioInConfig() const; 208 209 void calculateHeadPose(); 210 211 /** Convert fields in Spatializer and sub-modules to a string. Disable thread-safety-analysis 212 * here because we want to dump mutex guarded members even try_lock failed to provide as much 213 * information as possible for debugging purpose. */ 214 std::string toString(unsigned level) const NO_THREAD_SAFETY_ANALYSIS; 215 toString(audio_latency_mode_t mode)216 static std::string toString(audio_latency_mode_t mode) { 217 // We convert to the AIDL type to print (eventually the legacy type will be removed). 218 const auto result = legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode); 219 return result.has_value() ? 220 media::audio::common::toString(*result) : "unknown_latency_mode"; 221 } 222 223 // If the Spatializer is not created, we send the status for metrics purposes. 224 // OK: Spatializer not expected to be created. 225 // NO_INIT: Spatializer creation failed. 226 static void sendEmptyCreateSpatializerMetricWithStatus(status_t status); 227 228 /** Made public for test only */ 229 void onSupportedLatencyModesChangedMsg( 230 audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes); 231 232 // Made public for test only 233 /** 234 * Returns true if there exists an immersive channel mask in the vector. 235 * 236 * Example of a non-immersive channel mask such as AUDIO_CHANNEL_OUT_STEREO 237 * versus an immersive channel mask such as AUDIO_CHANNEL_OUT_5POINT1. 238 */ 239 static bool containsImmersiveChannelMask( 240 const std::vector<audio_channel_mask_t>& masks); 241 242 private: 243 Spatializer(effect_descriptor_t engineDescriptor, 244 SpatializerPolicyCallback *callback); 245 246 static void engineCallback(int32_t event, void* user, void *info); 247 248 // From VirtualizerStageController::Listener 249 void onHeadToStagePose(const media::Pose3f& headToStage) override; 250 void onActualModeChange(media::HeadTrackingMode mode) override; 251 252 void onHeadToStagePoseMsg(const std::vector<float>& headToStage); 253 void onActualModeChangeMsg(media::HeadTrackingMode mode); 254 255 static constexpr int kMaxEffectParamValues = 10; 256 /** 257 * Get a parameter from spatializer engine by calling the effect HAL command method directly. 258 * To be used when the engine instance mEngine is not yet created in the effect framework. 259 * When MULTI_VALUES is false, the expected reply is only one value of type T. 260 * When MULTI_VALUES is true, the expected reply is made of a number (of type T) indicating 261 * how many values are returned, followed by this number for values of type T. 262 */ 263 template<bool MULTI_VALUES, typename T> getHalParameter(sp<EffectHalInterface> effect,uint32_t type,std::vector<T> * values)264 status_t getHalParameter(sp<EffectHalInterface> effect, uint32_t type, 265 std::vector<T> *values) { 266 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits"); 267 268 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1]; 269 uint32_t reply[sizeof(effect_param_t) / sizeof(uint32_t) + 2 + kMaxEffectParamValues]; 270 271 effect_param_t *p = (effect_param_t *)cmd; 272 p->psize = sizeof(uint32_t); 273 if (MULTI_VALUES) { 274 p->vsize = (kMaxEffectParamValues + 1) * sizeof(T); 275 } else { 276 p->vsize = sizeof(T); 277 } 278 *(uint32_t *)p->data = type; 279 uint32_t replySize = sizeof(effect_param_t) + p->psize + p->vsize; 280 281 status_t status = effect->command(EFFECT_CMD_GET_PARAM, 282 sizeof(effect_param_t) + sizeof(uint32_t), cmd, 283 &replySize, reply); 284 if (status != NO_ERROR) { 285 return status; 286 } 287 if (p->status != NO_ERROR) { 288 return p->status; 289 } 290 if (replySize < 291 sizeof(effect_param_t) + sizeof(uint32_t) + (MULTI_VALUES ? 2 : 1) * sizeof(T)) { 292 return BAD_VALUE; 293 } 294 295 T *params = (T *)((uint8_t *)reply + sizeof(effect_param_t) + sizeof(uint32_t)); 296 int numParams = 1; 297 if (MULTI_VALUES) { 298 numParams = (int)*params++; 299 } 300 if (numParams > kMaxEffectParamValues) { 301 return BAD_VALUE; 302 } 303 (*values).clear(); 304 std::copy(¶ms[0], ¶ms[numParams], back_inserter(*values)); 305 return NO_ERROR; 306 } 307 308 /** 309 * Set a parameter to spatializer engine by calling setParameter on mEngine AudioEffect object. 310 * It is possible to pass more than one value of type T according to the parameter type 311 * according to values vector size. 312 */ 313 template<typename T> setEffectParameter_l(uint32_t type,const std::vector<T> & values)314 status_t setEffectParameter_l(uint32_t type, const std::vector<T>& values) REQUIRES(mMutex) { 315 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits"); 316 317 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values.size()]; 318 effect_param_t *p = (effect_param_t *)cmd; 319 p->psize = sizeof(uint32_t); 320 p->vsize = sizeof(T) * values.size(); 321 *(uint32_t *)p->data = type; 322 memcpy((uint32_t *)p->data + 1, values.data(), sizeof(T) * values.size()); 323 324 status_t status = mEngine->setParameter(p); 325 if (status != NO_ERROR) { 326 return status; 327 } 328 if (p->status != NO_ERROR) { 329 return p->status; 330 } 331 return NO_ERROR; 332 } 333 334 /** 335 * Set a parameter to spatializer engine by calling setParameter on mEngine AudioEffect object. 336 * The variant is for compound parameters with two values of different base types 337 */ 338 template<typename P1, typename P2> setEffectParameter_l(uint32_t type,const P1 val1,const P2 val2)339 status_t setEffectParameter_l(uint32_t type, const P1 val1, const P2 val2) REQUIRES(mMutex) { 340 static_assert(sizeof(P1) <= sizeof(uint32_t), "The size of P1 must less than 32 bits"); 341 static_assert(sizeof(P2) <= sizeof(uint32_t), "The size of P2 must less than 32 bits"); 342 343 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 3]; 344 effect_param_t *p = (effect_param_t *)cmd; 345 p->psize = sizeof(uint32_t); 346 p->vsize = 2 * sizeof(uint32_t); 347 *(uint32_t *)p->data = type; 348 *((uint32_t *)p->data + 1) = static_cast<uint32_t>(val1); 349 *((uint32_t *)p->data + 2) = static_cast<uint32_t>(val2); 350 351 status_t status = mEngine->setParameter(p); 352 if (status != NO_ERROR) { 353 return status; 354 } 355 if (p->status != NO_ERROR) { 356 return p->status; 357 } 358 return NO_ERROR; 359 } 360 361 /** 362 * Get a parameter from spatializer engine by calling getParameter on AudioEffect object. 363 * It is possible to read more than one value of type T according to the parameter type 364 * by specifying values vector size. 365 */ 366 template<typename T> getEffectParameter_l(uint32_t type,std::vector<T> * values)367 status_t getEffectParameter_l(uint32_t type, std::vector<T> *values) REQUIRES(mMutex) { 368 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits"); 369 370 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values->size()]; 371 effect_param_t *p = (effect_param_t *)cmd; 372 p->psize = sizeof(uint32_t); 373 p->vsize = sizeof(T) * values->size(); 374 *(uint32_t *)p->data = type; 375 376 status_t status = mEngine->getParameter(p); 377 378 if (status != NO_ERROR) { 379 return status; 380 } 381 if (p->status != NO_ERROR) { 382 return p->status; 383 } 384 385 int numValues = std::min(p->vsize / sizeof(T), values->size()); 386 (*values).clear(); 387 T *retValues = (T *)((uint8_t *)p->data + sizeof(uint32_t)); 388 std::copy(&retValues[0], &retValues[numValues], back_inserter(*values)); 389 390 return NO_ERROR; 391 } 392 393 /** 394 * Get a parameter from spatializer engine by calling getParameter on AudioEffect object. 395 * The variant is for compound parameters with two values of different base types 396 */ 397 template<typename P1, typename P2> getEffectParameter_l(uint32_t type,P1 * val1,P2 * val2)398 status_t getEffectParameter_l(uint32_t type, P1 *val1, P2 *val2) REQUIRES(mMutex) { 399 static_assert(sizeof(P1) <= sizeof(uint32_t), "The size of P1 must less than 32 bits"); 400 static_assert(sizeof(P2) <= sizeof(uint32_t), "The size of P2 must less than 32 bits"); 401 402 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 3]; 403 effect_param_t *p = (effect_param_t *)cmd; 404 p->psize = sizeof(uint32_t); 405 p->vsize = 2 * sizeof(uint32_t); 406 *(uint32_t *)p->data = type; 407 408 status_t status = mEngine->getParameter(p); 409 410 if (status != NO_ERROR) { 411 return status; 412 } 413 if (p->status != NO_ERROR) { 414 return p->status; 415 } 416 *val1 = static_cast<P1>(*((uint32_t *)p->data + 1)); 417 *val2 = static_cast<P2>(*((uint32_t *)p->data + 2)); 418 return NO_ERROR; 419 } 420 421 virtual void onFramesProcessed(int32_t framesProcessed) override; 422 423 /** 424 * Checks if head and screen sensors must be actively monitored based on 425 * spatializer state and playback activity and configures the pose controller 426 * accordingly. 427 */ 428 void checkSensorsState_l() REQUIRES(mMutex); 429 430 /** 431 * Checks if the head pose controller should be created or destroyed according 432 * to desired head tracking mode. 433 */ 434 void checkPoseController_l() REQUIRES(mMutex); 435 436 /** 437 * Checks if the spatializer effect should be enabled based on 438 * playback activity and requested level. 439 */ 440 void checkEngineState_l() REQUIRES(mMutex); 441 442 /** 443 * Reset head tracking mode and recenter pose in engine: Called when the head tracking 444 * is disabled. 445 */ 446 void resetEngineHeadPose_l() REQUIRES(mMutex); 447 448 /** Read bluetooth.core.le.dsa_transport_preference property and populate the ordered list of 449 * preferred low latency modes in mOrderedLowLatencyModes. 450 */ 451 void loadOrderedLowLatencyModes(); 452 453 /** 454 * Sort mSupportedLatencyModes list according to the preference order stored in 455 * mOrderedLowLatencyModes. 456 * Note: Because MODE_FREE is not in mOrderedLowLatencyModes, it will always be at 457 * the end of the list. 458 */ 459 void sortSupportedLatencyModes_l() REQUIRES(mMutex); 460 461 /** 462 * Called after enabling head tracking in the spatializer engine to indicate which 463 * connection mode should be used among those supported. The selection depends on 464 * currently supported latency modes reported by the audio HAL. 465 * When the connection mode is direct to the sensor, the sensor ID is also communicated 466 * to the spatializer engine. 467 */ 468 void setEngineHeadtrackingConnectionMode_l() REQUIRES(mMutex); 469 470 /** 471 * Select the desired head tracking connection mode for the spatializer engine among the list 472 * stored in mSupportedHeadtrackingConnectionModes at init time. 473 * Also returns the desired low latency mode according to selected connection mode. 474 */ 475 audio_latency_mode_t selectHeadtrackingConnectionMode_l() REQUIRES(mMutex); 476 477 /** 478 * Indicates if current conditions are compatible with head tracking. 479 */ 480 bool shouldUseHeadTracking_l() const REQUIRES(mMutex); 481 482 /** Effect engine descriptor */ 483 const effect_descriptor_t mEngineDescriptor; 484 /** Callback interface to parent audio policy service */ 485 SpatializerPolicyCallback* const mPolicyCallback; 486 487 /** Currently there is only one version of the spatializer running */ 488 static constexpr const char* kDefaultMetricsId = 489 AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "0"; 490 const std::string mMetricsId = kDefaultMetricsId; 491 492 /** Mutex protecting internal state */ 493 mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kSpatializer_Mutex}; 494 495 /** Client AudioEffect for the engine */ 496 sp<AudioEffect> mEngine GUARDED_BY(mMutex); 497 /** Output stream the spatializer mixer thread is attached to */ 498 audio_io_handle_t mOutput GUARDED_BY(mMutex) = AUDIO_IO_HANDLE_NONE; 499 500 /** Callback interface to the client (AudioService) controlling this`Spatializer */ 501 sp<media::INativeSpatializerCallback> mSpatializerCallback GUARDED_BY(mMutex); 502 503 /** Callback interface for head tracking */ 504 sp<media::ISpatializerHeadTrackingCallback> mHeadTrackingCallback GUARDED_BY(mMutex); 505 506 /** Requested spatialization level */ 507 media::audio::common::Spatialization::Level mLevel GUARDED_BY(mMutex) = 508 media::audio::common::Spatialization::Level::NONE; 509 510 /** Control logic for head-tracking, etc. */ 511 std::shared_ptr<SpatializerPoseController> mPoseController GUARDED_BY(mMutex); 512 513 /** Last requested head tracking mode */ 514 media::HeadTrackingMode mDesiredHeadTrackingMode GUARDED_BY(mMutex) 515 = media::HeadTrackingMode::STATIC; 516 517 /** Last-reported actual head-tracking mode. */ 518 media::audio::common::HeadTracking::Mode mActualHeadTrackingMode GUARDED_BY(mMutex) 519 = media::audio::common::HeadTracking::Mode::DISABLED; 520 521 /** Selected Head pose sensor */ 522 int32_t mHeadSensor GUARDED_BY(mMutex) = SpatializerPoseController::INVALID_SENSOR; 523 524 /** Selected Screen pose sensor */ 525 int32_t mScreenSensor GUARDED_BY(mMutex) = SpatializerPoseController::INVALID_SENSOR; 526 527 /** Last display orientation received */ 528 float mDisplayOrientation GUARDED_BY(mMutex) = 0.f; // aligned to natural up orientation. 529 530 /** Last folded state */ 531 bool mFoldedState GUARDED_BY(mMutex) = false; // foldable: true means folded. 532 533 /** Last hinge angle */ 534 float mHingeAngle GUARDED_BY(mMutex) = 0.f; // foldable: 0.f is closed, M_PI flat open. 535 536 std::vector<media::audio::common::Spatialization::Level> mLevels; 537 std::vector<media::audio::common::HeadTracking::Mode> mHeadTrackingModes; 538 std::vector<media::audio::common::Spatialization::Mode> mSpatializationModes; 539 std::vector<audio_channel_mask_t> mChannelMasks; 540 std::vector<audio_channel_mask_t> mSpatializedChannelMasks; 541 bool mSupportsHeadTracking; 542 543 /** List of supported head tracking connection modes reported by the spatializer. 544 * If the list is empty, the spatializer does not support any optional connection 545 * mode and mode HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED is assumed. 546 * This is set in the factory constructor and can be accessed without mutex. 547 */ 548 std::unordered_set<media::audio::common::HeadTracking::ConnectionMode> 549 mSupportedHeadtrackingConnectionModes; 550 /** Selected HT connection mode when several modes are supported by the spatializer */ 551 media::audio::common::HeadTracking::ConnectionMode mHeadtrackingConnectionMode = 552 media::audio::common::HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED; 553 554 // Looper thread for mEngine callbacks 555 class EngineCallbackHandler; 556 557 sp<ALooper> mLooper; 558 sp<EngineCallbackHandler> mHandler; 559 560 std::vector<audio_channel_mask_t> mActiveTracksMasks GUARDED_BY(mMutex); 561 std::vector<audio_latency_mode_t> mSupportedLatencyModes GUARDED_BY(mMutex); 562 /** preference order for low latency modes according to persist.bluetooth.hid.transport */ 563 std::vector<audio_latency_mode_t> mOrderedLowLatencyModes; 564 565 audio_latency_mode_t mRequestedLatencyMode GUARDED_BY(mMutex) = AUDIO_LATENCY_MODE_FREE; 566 567 /** string to latency mode map used to parse bluetooth.core.le.dsa_transport_preference */ 568 static const std::map<std::string, audio_latency_mode_t> sStringToLatencyModeMap; 569 static const std::vector<const char*> sHeadPoseKeys; 570 571 // Local log for command messages. 572 static constexpr int mMaxLocalLogLine = 10; 573 SimpleLog mLocalLog{mMaxLocalLogLine}; 574 575 /** 576 * @brief Calculate and record sensor data. 577 * Dump to local log with max/average pose angle every mPoseRecordThreshold. 578 */ 579 // Record one log line per second (up to mMaxLocalLogLine) to capture most recent sensor data. GUARDED_BY(mMutex)580 media::VectorRecorder mPoseRecorder GUARDED_BY(mMutex) { 581 6 /* vectorSize */, std::chrono::seconds(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */}; 582 // Record one log line per minute (up to mMaxLocalLogLine) to capture durable sensor data. GUARDED_BY(mMutex)583 media::VectorRecorder mPoseDurableRecorder GUARDED_BY(mMutex) { 584 6 /* vectorSize */, std::chrono::minutes(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */}; 585 }; // Spatializer 586 587 }; // namespace android 588 589 #endif // ANDROID_MEDIA_SPATIALIZER_H 590