blob: 23de0c00dde7e5ee015ecc30b8058321fd014918 [file] [log] [blame]
Eric Laurent6d607012021-07-05 11:54:40 +02001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_MEDIA_SPATIALIZER_H
18#define ANDROID_MEDIA_SPATIALIZER_H
19
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +000020#include <android-base/stringprintf.h>
Eric Laurent6d607012021-07-05 11:54:40 +020021#include <android/media/BnEffect.h>
22#include <android/media/BnSpatializer.h>
Eric Laurent6d607012021-07-05 11:54:40 +020023#include <android/media/SpatializationLevel.h>
Eric Laurent2be8b292021-08-23 09:44:33 -070024#include <android/media/SpatializationMode.h>
25#include <android/media/SpatializerHeadTrackingMode.h>
Mikhail Naganovf53e1822022-12-18 02:48:14 +000026#include <android/media/audio/common/AudioLatencyMode.h>
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +000027#include <audio_utils/SimpleLog.h>
28#include <math.h>
29#include <media/AudioEffect.h>
Andy Hunga367cb22023-01-30 11:58:44 -080030#include <media/VectorRecorder.h>
Eric Laurent2be8b292021-08-23 09:44:33 -070031#include <media/audiohal/EffectHalInterface.h>
Eric Laurent8a4259f2021-09-14 16:04:00 +020032#include <media/stagefright/foundation/ALooper.h>
Eric Laurent1c5e2e32021-08-18 18:50:28 +020033#include <system/audio_effects/effect_spatializer.h>
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +000034#include <string>
Eric Laurent6d607012021-07-05 11:54:40 +020035
Eric Laurent2be8b292021-08-23 09:44:33 -070036#include "SpatializerPoseController.h"
Eric Laurent6d607012021-07-05 11:54:40 +020037
38namespace android {
39
40
41// ----------------------------------------------------------------------------
42
43/**
44 * A callback interface from the Spatializer object or its parent AudioPolicyService.
45 * This is implemented by the audio policy service hosting the Spatializer to perform
46 * actions needed when a state change inside the Spatializer requires some audio system
47 * changes that cannot be performed by the Spatializer. For instance opening or closing a
48 * spatializer output stream when the spatializer is enabled or disabled
49 */
50class SpatializerPolicyCallback {
51public:
52 /** Called when a stage change occurs that requires the parent audio policy service to take
53 * some action.
54 */
55 virtual void onCheckSpatializer() = 0;
56
57 virtual ~SpatializerPolicyCallback() = default;
58};
59/**
60 * The Spatializer class implements all functional controlling the multichannel spatializer
61 * with head tracking implementation in the native audio service: audio policy and audio flinger.
62 * It presents an AIDL interface available to the java audio service to discover the availability
63 * of the feature and options, control its state and register an active head tracking sensor.
64 * It maintains the current state of the platform spatializer and applies the stored parameters
65 * when the spatializer engine is created and enabled.
66 * Based on the requested spatializer level, it will request the creation of a specialized output
67 * mixer to the audio policy service which will in turn notify the Spatializer of the output
68 * stream on which a spatializer engine should be created, configured and enabled.
69 * The spatializer also hosts the head tracking management logic. This logic receives the
70 * desired head tracking mode and selected head tracking sensor, registers a sensor event listener
71 * and derives the compounded head pose information to the spatializer engine.
72 *
73 * Workflow:
74 * - Initialization: when the audio policy service starts, it checks if a spatializer effect
75 * engine exists and if the audio policy manager reports a dedicated spatializer output profile.
76 * If both conditions are met, a Spatializer object is created
77 * - Capabilities discovery: AudioService will call AudioSystem::canBeSpatialized() and if true,
78 * acquire an ISpatializer interface with AudioSystem::getSpatializer(). This interface
79 * will be used to query the implementation capabilities and configure the spatializer.
80 * - Enabling: when ISpatializer::setLevel() sets a level different from NONE the spatializer
81 * is considered enabled. The audio policy callback onCheckSpatializer() is called. This
82 * triggers a request to audio policy manager to open a spatialization output stream and a
83 * spatializer mixer is created in audio flinger. When an output is returned by audio policy
84 * manager, Spatializer::attachOutput() is called which creates and enables the spatializer
85 * stage engine on the specified output.
86 * - Disabling: when the spatialization level is set to NONE, the spatializer is considered
87 * disabled. The audio policy callback onCheckSpatializer() is called. This triggers a call
88 * to Spatializer::detachOutput() and the spatializer engine is released. Then a request is
89 * made to audio policy manager to release and close the spatializer output stream and the
90 * spatializer mixer thread is destroyed.
91 */
Eric Laurent2be8b292021-08-23 09:44:33 -070092class Spatializer : public media::BnSpatializer,
Atneya Nair20e6cc82022-05-17 20:12:37 -040093 public AudioEffect::IAudioEffectCallback,
Eric Laurent2be8b292021-08-23 09:44:33 -070094 public IBinder::DeathRecipient,
Eric Laurentee398ad2022-05-03 18:19:35 +020095 private SpatializerPoseController::Listener,
96 public virtual AudioSystem::SupportedLatencyModesCallback {
Eric Laurent2be8b292021-08-23 09:44:33 -070097 public:
Eric Laurent6d607012021-07-05 11:54:40 +020098 static sp<Spatializer> create(SpatializerPolicyCallback *callback);
99
100 ~Spatializer() override;
101
Eric Laurent8a4259f2021-09-14 16:04:00 +0200102 /** RefBase */
103 void onFirstRef();
104
Eric Laurent6d607012021-07-05 11:54:40 +0200105 /** ISpatializer, see ISpatializer.aidl */
106 binder::Status release() override;
107 binder::Status getSupportedLevels(std::vector<media::SpatializationLevel>* levels) override;
108 binder::Status setLevel(media::SpatializationLevel level) override;
109 binder::Status getLevel(media::SpatializationLevel *level) override;
Eric Laurentc87402b2021-09-17 16:49:42 +0200110 binder::Status isHeadTrackingSupported(bool *supports);
Eric Laurent6d607012021-07-05 11:54:40 +0200111 binder::Status getSupportedHeadTrackingModes(
Ytai Ben-Tsvia16a9df2021-08-05 08:57:06 -0700112 std::vector<media::SpatializerHeadTrackingMode>* modes) override;
113 binder::Status setDesiredHeadTrackingMode(
114 media::SpatializerHeadTrackingMode mode) override;
115 binder::Status getActualHeadTrackingMode(
116 media::SpatializerHeadTrackingMode* mode) override;
117 binder::Status recenterHeadTracker() override;
Eric Laurent6d607012021-07-05 11:54:40 +0200118 binder::Status setGlobalTransform(const std::vector<float>& screenToStage) override;
Eric Laurent2be8b292021-08-23 09:44:33 -0700119 binder::Status setHeadSensor(int sensorHandle) override;
120 binder::Status setScreenSensor(int sensorHandle) override;
121 binder::Status setDisplayOrientation(float physicalToLogicalAngle) override;
122 binder::Status setHingeAngle(float hingeAngle) override;
Andy Hung2490b2d2023-03-09 20:45:36 -0800123 binder::Status setFoldState(bool folded) override;
Eric Laurent2be8b292021-08-23 09:44:33 -0700124 binder::Status getSupportedModes(std::vector<media::SpatializationMode>* modes) override;
Eric Laurent67816e32021-09-16 15:18:40 +0200125 binder::Status registerHeadTrackingCallback(
126 const sp<media::ISpatializerHeadTrackingCallback>& callback) override;
Eric Laurentc87402b2021-09-17 16:49:42 +0200127 binder::Status setParameter(int key, const std::vector<unsigned char>& value) override;
128 binder::Status getParameter(int key, std::vector<unsigned char> *value) override;
129 binder::Status getOutput(int *output);
Eric Laurent6d607012021-07-05 11:54:40 +0200130
131 /** IBinder::DeathRecipient. Listen to the death of the INativeSpatializerCallback. */
132 virtual void binderDied(const wp<IBinder>& who);
133
Eric Laurentee398ad2022-05-03 18:19:35 +0200134 /** SupportedLatencyModesCallback */
135 void onSupportedLatencyModesChanged(
136 audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) override;
137
Eric Laurent6d607012021-07-05 11:54:40 +0200138 /** Registers a INativeSpatializerCallback when a client is attached to this Spatializer
139 * by audio policy service.
140 */
141 status_t registerCallback(const sp<media::INativeSpatializerCallback>& callback);
142
Eric Laurent2be8b292021-08-23 09:44:33 -0700143 status_t loadEngineConfiguration(sp<EffectHalInterface> effect);
144
Eric Laurent6d607012021-07-05 11:54:40 +0200145 /** Level getter for use by local classes. */
Eric Laurent2be8b292021-08-23 09:44:33 -0700146 media::SpatializationLevel getLevel() const { std::lock_guard lock(mLock); return mLevel; }
Eric Laurent6d607012021-07-05 11:54:40 +0200147
148 /** Called by audio policy service when the special output mixer dedicated to spatialization
149 * is opened and the spatializer engine must be created.
150 */
Eric Laurent15903592022-02-24 20:44:36 +0100151 status_t attachOutput(audio_io_handle_t output, size_t numActiveTracks);
Eric Laurent6d607012021-07-05 11:54:40 +0200152 /** Called by audio policy service when the special output mixer dedicated to spatialization
153 * is closed and the spatializer engine must be release.
154 */
155 audio_io_handle_t detachOutput();
156 /** Returns the output stream the spatializer is attached to. */
Eric Laurent2be8b292021-08-23 09:44:33 -0700157 audio_io_handle_t getOutput() const { std::lock_guard lock(mLock); return mOutput; }
Eric Laurent6d607012021-07-05 11:54:40 +0200158
Eric Laurent15903592022-02-24 20:44:36 +0100159 void updateActiveTracks(size_t numActiveTracks);
160
Eric Laurent6d607012021-07-05 11:54:40 +0200161 /** Gets the channel mask, sampling rate and format set for the spatializer input. */
Eric Laurent2be8b292021-08-23 09:44:33 -0700162 audio_config_base_t getAudioInConfig() const;
Eric Laurent6d607012021-07-05 11:54:40 +0200163
Eric Laurent8a4259f2021-09-14 16:04:00 +0200164 void calculateHeadPose();
165
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000166 /** Convert fields in Spatializer and sub-modules to a string. Disable thread-safety-analysis
167 * here because we want to dump mutex guarded members even try_lock failed to provide as much
168 * information as possible for debugging purpose. */
169 std::string toString(unsigned level) const NO_THREAD_SAFETY_ANALYSIS;
170
171 static std::string toString(audio_latency_mode_t mode) {
Andy Hung4bd53e72022-11-17 17:21:45 -0800172 // We convert to the AIDL type to print (eventually the legacy type will be removed).
Mikhail Naganovf53e1822022-12-18 02:48:14 +0000173 const auto result = legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode);
174 return result.has_value() ?
175 media::audio::common::toString(*result) : "unknown_latency_mode";
Andy Hung4bd53e72022-11-17 17:21:45 -0800176 }
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000177
Andy Hung8aa43c02022-09-13 18:53:06 -0700178 // If the Spatializer is not created, we send the status for metrics purposes.
179 // OK: Spatializer not expected to be created.
180 // NO_INIT: Spatializer creation failed.
181 static void sendEmptyCreateSpatializerMetricWithStatus(status_t status);
182
Eric Laurent6d607012021-07-05 11:54:40 +0200183private:
Eric Laurent6d607012021-07-05 11:54:40 +0200184 Spatializer(effect_descriptor_t engineDescriptor,
185 SpatializerPolicyCallback *callback);
186
Eric Laurent6d607012021-07-05 11:54:40 +0200187 static void engineCallback(int32_t event, void* user, void *info);
188
Eric Laurent2be8b292021-08-23 09:44:33 -0700189 // From VirtualizerStageController::Listener
190 void onHeadToStagePose(const media::Pose3f& headToStage) override;
191 void onActualModeChange(media::HeadTrackingMode mode) override;
192
Eric Laurent8a4259f2021-09-14 16:04:00 +0200193 void onHeadToStagePoseMsg(const std::vector<float>& headToStage);
194 void onActualModeChangeMsg(media::HeadTrackingMode mode);
Eric Laurent9c04de92022-07-20 13:49:47 +0200195 void onSupportedLatencyModesChangedMsg(
196 audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes);
Eric Laurent8a4259f2021-09-14 16:04:00 +0200197
Eric Laurent2be8b292021-08-23 09:44:33 -0700198 static constexpr int kMaxEffectParamValues = 10;
199 /**
200 * Get a parameter from spatializer engine by calling the effect HAL command method directly.
201 * To be used when the engine instance mEngine is not yet created in the effect framework.
202 * When MULTI_VALUES is false, the expected reply is only one value of type T.
203 * When MULTI_VALUES is true, the expected reply is made of a number (of type T) indicating
204 * how many values are returned, followed by this number for values of type T.
205 */
206 template<bool MULTI_VALUES, typename T>
207 status_t getHalParameter(sp<EffectHalInterface> effect, uint32_t type,
208 std::vector<T> *values) {
209 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits");
210
211 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1];
212 uint32_t reply[sizeof(effect_param_t) / sizeof(uint32_t) + 2 + kMaxEffectParamValues];
213
214 effect_param_t *p = (effect_param_t *)cmd;
215 p->psize = sizeof(uint32_t);
216 if (MULTI_VALUES) {
217 p->vsize = (kMaxEffectParamValues + 1) * sizeof(T);
218 } else {
219 p->vsize = sizeof(T);
220 }
221 *(uint32_t *)p->data = type;
222 uint32_t replySize = sizeof(effect_param_t) + p->psize + p->vsize;
223
224 status_t status = effect->command(EFFECT_CMD_GET_PARAM,
225 sizeof(effect_param_t) + sizeof(uint32_t), cmd,
226 &replySize, reply);
227 if (status != NO_ERROR) {
228 return status;
229 }
230 if (p->status != NO_ERROR) {
231 return p->status;
232 }
233 if (replySize <
234 sizeof(effect_param_t) + sizeof(uint32_t) + (MULTI_VALUES ? 2 : 1) * sizeof(T)) {
235 return BAD_VALUE;
236 }
237
238 T *params = (T *)((uint8_t *)reply + sizeof(effect_param_t) + sizeof(uint32_t));
239 int numParams = 1;
240 if (MULTI_VALUES) {
241 numParams = (int)*params++;
242 }
243 if (numParams > kMaxEffectParamValues) {
244 return BAD_VALUE;
245 }
Eric Laurentc87402b2021-09-17 16:49:42 +0200246 (*values).clear();
Eric Laurent2be8b292021-08-23 09:44:33 -0700247 std::copy(&params[0], &params[numParams], back_inserter(*values));
248 return NO_ERROR;
249 }
250
251 /**
252 * Set a parameter to spatializer engine by calling setParameter on mEngine AudioEffect object.
253 * It is possible to pass more than one value of type T according to the parameter type
254 * according to values vector size.
255 */
256 template<typename T>
257 status_t setEffectParameter_l(uint32_t type, const std::vector<T>& values) REQUIRES(mLock) {
258 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits");
259
260 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values.size()];
261 effect_param_t *p = (effect_param_t *)cmd;
262 p->psize = sizeof(uint32_t);
263 p->vsize = sizeof(T) * values.size();
264 *(uint32_t *)p->data = type;
265 memcpy((uint32_t *)p->data + 1, values.data(), sizeof(T) * values.size());
266
Eric Laurentc87402b2021-09-17 16:49:42 +0200267 status_t status = mEngine->setParameter(p);
268 if (status != NO_ERROR) {
269 return status;
270 }
271 if (p->status != NO_ERROR) {
272 return p->status;
273 }
274 return NO_ERROR;
275 }
276
277 /**
278 * Get a parameter from spatializer engine by calling getParameter on AudioEffect object.
279 * It is possible to read more than one value of type T according to the parameter type
280 * by specifying values vector size.
281 */
282 template<typename T>
283 status_t getEffectParameter_l(uint32_t type, std::vector<T> *values) REQUIRES(mLock) {
284 static_assert(sizeof(T) <= sizeof(uint32_t), "The size of T must less than 32 bits");
285
286 uint32_t cmd[sizeof(effect_param_t) / sizeof(uint32_t) + 1 + values->size()];
287 effect_param_t *p = (effect_param_t *)cmd;
288 p->psize = sizeof(uint32_t);
289 p->vsize = sizeof(T) * values->size();
290 *(uint32_t *)p->data = type;
291
292 status_t status = mEngine->getParameter(p);
293
294 if (status != NO_ERROR) {
295 return status;
296 }
297 if (p->status != NO_ERROR) {
298 return p->status;
299 }
300
301 int numValues = std::min(p->vsize / sizeof(T), values->size());
302 (*values).clear();
303 T *retValues = (T *)((uint8_t *)p->data + sizeof(uint32_t));
304 std::copy(&retValues[0], &retValues[numValues], back_inserter(*values));
305
306 return NO_ERROR;
Eric Laurent2be8b292021-08-23 09:44:33 -0700307 }
308
Atneya Nair20e6cc82022-05-17 20:12:37 -0400309 virtual void onFramesProcessed(int32_t framesProcessed) override;
Eric Laurent8a4259f2021-09-14 16:04:00 +0200310
Eric Laurent9249d342022-03-18 11:55:56 +0100311 /**
312 * Checks if head and screen sensors must be actively monitored based on
313 * spatializer state and playback activity and configures the pose controller
314 * accordingly.
315 */
316 void checkSensorsState_l() REQUIRES(mLock);
Eric Laurent15903592022-02-24 20:44:36 +0100317
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200318 /**
Eric Laurent11094172022-04-05 18:27:42 +0200319 * Checks if the head pose controller should be created or destroyed according
320 * to desired head tracking mode.
321 */
322 void checkPoseController_l() REQUIRES(mLock);
323
324 /**
Eric Laurent7ea0d1b2022-04-01 14:23:44 +0200325 * Checks if the spatializer effect should be enabled based on
326 * playback activity and requested level.
327 */
328 void checkEngineState_l() REQUIRES(mLock);
329
Eric Laurentbdecc052022-10-21 11:28:32 +0200330 /**
331 * Reset head tracking mode and recenter pose in engine: Called when the head tracking
332 * is disabled.
333 */
334 void resetEngineHeadPose_l() REQUIRES(mLock);
335
Eric Laurent6d607012021-07-05 11:54:40 +0200336 /** Effect engine descriptor */
337 const effect_descriptor_t mEngineDescriptor;
338 /** Callback interface to parent audio policy service */
Andy Hunga461a002022-05-17 10:36:02 -0700339 SpatializerPolicyCallback* const mPolicyCallback;
340
341 /** Currently there is only one version of the spatializer running */
Andy Hung8aa43c02022-09-13 18:53:06 -0700342 static constexpr const char* kDefaultMetricsId =
343 AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "0";
344 const std::string mMetricsId = kDefaultMetricsId;
Eric Laurent6d607012021-07-05 11:54:40 +0200345
346 /** Mutex protecting internal state */
Eric Laurent2be8b292021-08-23 09:44:33 -0700347 mutable std::mutex mLock;
Eric Laurent6d607012021-07-05 11:54:40 +0200348
349 /** Client AudioEffect for the engine */
350 sp<AudioEffect> mEngine GUARDED_BY(mLock);
351 /** Output stream the spatializer mixer thread is attached to */
352 audio_io_handle_t mOutput GUARDED_BY(mLock) = AUDIO_IO_HANDLE_NONE;
Eric Laurent6d607012021-07-05 11:54:40 +0200353
354 /** Callback interface to the client (AudioService) controlling this`Spatializer */
355 sp<media::INativeSpatializerCallback> mSpatializerCallback GUARDED_BY(mLock);
356
Eric Laurent67816e32021-09-16 15:18:40 +0200357 /** Callback interface for head tracking */
358 sp<media::ISpatializerHeadTrackingCallback> mHeadTrackingCallback GUARDED_BY(mLock);
359
Eric Laurent6d607012021-07-05 11:54:40 +0200360 /** Requested spatialization level */
361 media::SpatializationLevel mLevel GUARDED_BY(mLock) = media::SpatializationLevel::NONE;
Eric Laurent6d607012021-07-05 11:54:40 +0200362
Eric Laurent2be8b292021-08-23 09:44:33 -0700363 /** Control logic for head-tracking, etc. */
364 std::shared_ptr<SpatializerPoseController> mPoseController GUARDED_BY(mLock);
365
366 /** Last requested head tracking mode */
367 media::HeadTrackingMode mDesiredHeadTrackingMode GUARDED_BY(mLock)
368 = media::HeadTrackingMode::STATIC;
369
370 /** Last-reported actual head-tracking mode. */
371 media::SpatializerHeadTrackingMode mActualHeadTrackingMode GUARDED_BY(mLock)
372 = media::SpatializerHeadTrackingMode::DISABLED;
373
374 /** Selected Head pose sensor */
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700375 int32_t mHeadSensor GUARDED_BY(mLock) = SpatializerPoseController::INVALID_SENSOR;
Eric Laurent2be8b292021-08-23 09:44:33 -0700376
377 /** Selected Screen pose sensor */
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700378 int32_t mScreenSensor GUARDED_BY(mLock) = SpatializerPoseController::INVALID_SENSOR;
Eric Laurent2be8b292021-08-23 09:44:33 -0700379
380 /** Last display orientation received */
Andy Hung2490b2d2023-03-09 20:45:36 -0800381 float mDisplayOrientation GUARDED_BY(mLock) = 0.f; // aligned to natural up orientation.
382
383 /** Last folded state */
384 bool mFoldedState GUARDED_BY(mLock) = false; // foldable: true means folded.
385
386 /** Last hinge angle */
387 float mHingeAngle GUARDED_BY(mLock) = 0.f; // foldable: 0.f is closed, M_PI flat open.
Eric Laurent2be8b292021-08-23 09:44:33 -0700388
389 std::vector<media::SpatializationLevel> mLevels;
Andy Hunga461a002022-05-17 10:36:02 -0700390 std::vector<media::SpatializerHeadTrackingMode> mHeadTrackingModes;
Eric Laurent2be8b292021-08-23 09:44:33 -0700391 std::vector<media::SpatializationMode> mSpatializationModes;
392 std::vector<audio_channel_mask_t> mChannelMasks;
393 bool mSupportsHeadTracking;
Eric Laurent8a4259f2021-09-14 16:04:00 +0200394
395 // Looper thread for mEngine callbacks
396 class EngineCallbackHandler;
397
398 sp<ALooper> mLooper;
399 sp<EngineCallbackHandler> mHandler;
400
Eric Laurent15903592022-02-24 20:44:36 +0100401 size_t mNumActiveTracks GUARDED_BY(mLock) = 0;
Eric Laurentee398ad2022-05-03 18:19:35 +0200402 std::vector<audio_latency_mode_t> mSupportedLatencyModes GUARDED_BY(mLock);
Eric Laurent15903592022-02-24 20:44:36 +0100403
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000404 static const std::vector<const char*> sHeadPoseKeys;
Eric Laurent6d607012021-07-05 11:54:40 +0200405
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000406 // Local log for command messages.
407 static constexpr int mMaxLocalLogLine = 10;
408 SimpleLog mLocalLog{mMaxLocalLogLine};
409
410 /**
411 * @brief Calculate and record sensor data.
412 * Dump to local log with max/average pose angle every mPoseRecordThreshold.
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000413 */
Shunkai Yaodc8f52d2022-08-25 00:44:04 +0000414 // Record one log line per second (up to mMaxLocalLogLine) to capture most recent sensor data.
Andy Hunga367cb22023-01-30 11:58:44 -0800415 media::VectorRecorder mPoseRecorder GUARDED_BY(mLock) {
Andy Hunga69459c2023-02-27 13:36:23 -0800416 6 /* vectorSize */, std::chrono::seconds(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */};
Shunkai Yaodc8f52d2022-08-25 00:44:04 +0000417 // Record one log line per minute (up to mMaxLocalLogLine) to capture durable sensor data.
Andy Hunga367cb22023-01-30 11:58:44 -0800418 media::VectorRecorder mPoseDurableRecorder GUARDED_BY(mLock) {
Andy Hunga69459c2023-02-27 13:36:23 -0800419 6 /* vectorSize */, std::chrono::minutes(1), mMaxLocalLogLine, { 3 } /* delimiterIdx */};
Shunkai Yaoafc0c2e2022-07-22 18:42:27 +0000420}; // Spatializer
Eric Laurent6d607012021-07-05 11:54:40 +0200421
422}; // namespace android
423
424#endif // ANDROID_MEDIA_SPATIALIZER_H