xref: /aosp_15_r20/frameworks/av/services/audiopolicy/service/Spatializer.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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(&params[0], &params[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