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