1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef LOG_TAG
16 #define LOG_TAG "HeadTracker"
17 #endif
18 
19 #include "audio_head_tracker.h"
20 #include "audio_effect_log.h"
21 #include "audio_errors.h"
22 
23 namespace OHOS {
24 namespace AudioStandard {
25 #ifdef SENSOR_ENABLE
26 HeadPostureData HeadTracker::headPostureData_ = {1, 1.0, 0.0, 0.0, 0.0};
27 std::mutex HeadTracker::headTrackerMutex_;
28 
29 const uint32_t ORDER_ONE = 1;
30 const uint32_t HP_DATA_PRINT_COUNT = 60; // Print once per second
31 
HeadPostureDataProcCb(SensorEvent * event)32 void HeadTracker::HeadPostureDataProcCb(SensorEvent *event)
33 {
34     std::lock_guard<std::mutex> lock(headTrackerMutex_);
35 
36     if (event == nullptr) {
37         AUDIO_ERR_LOG("Audio HeadTracker Sensor event is nullptr!");
38         return;
39     }
40 
41     if (event[0].data == nullptr) {
42         AUDIO_ERR_LOG("Audio HeadTracker Sensor event[0].data is nullptr!");
43         return;
44     }
45 
46     if (event[0].dataLen < sizeof(HeadPostureData)) {
47         AUDIO_ERR_LOG("Event dataLen less than head posture data size, event.dataLen:%{public}u", event[0].dataLen);
48         return;
49     }
50     HeadPostureData *headPostureDataTmp = reinterpret_cast<HeadPostureData *>(event[0].data);
51     headPostureData_.order = headPostureDataTmp->order;
52     headPostureData_.w = headPostureDataTmp->w;
53     headPostureData_.x = headPostureDataTmp->x;
54     headPostureData_.y = headPostureDataTmp->y;
55     headPostureData_.z = headPostureDataTmp->z;
56     if (headPostureData_.order % HP_DATA_PRINT_COUNT == ORDER_ONE) {
57         AUDIO_DEBUG_LOG("Head posture data of order %{public}d received", headPostureData_.order);
58     }
59 }
60 
HeadTracker()61 HeadTracker::HeadTracker()
62 {
63     AUDIO_INFO_LOG("HeadTracker created!");
64 }
65 
~HeadTracker()66 HeadTracker::~HeadTracker()
67 {
68     AUDIO_INFO_LOG("HeadTracker destroyed!");
69 }
70 
SensorInit()71 int32_t HeadTracker::SensorInit()
72 {
73     sensorUser_.callback = HeadPostureDataProcCb;
74     return SubscribeSensor(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_);
75 }
76 
SensorSetConfig(int32_t spatializerEngineState)77 int32_t HeadTracker::SensorSetConfig(int32_t spatializerEngineState)
78 {
79     int32_t ret;
80     switch (spatializerEngineState) {
81         case NONE_SPATIALIZER_ENGINE:
82             AUDIO_ERR_LOG("system has no spatializer engine!");
83             ret = ERROR;
84             break;
85         case ARM_SPATIALIZER_ENGINE:
86             AUDIO_INFO_LOG("system uses arm spatializer engine!");
87             ret = SetBatch(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_,
88                 sensorSamplingInterval_, sensorSamplingInterval_);
89             break;
90         case DSP_SPATIALIZER_ENGINE:
91             AUDIO_INFO_LOG("system uses dsp spatializer engine!");
92             ret = SetBatch(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_,
93                 sensorSamplingInterval_, sensorSamplingInterval_ * 2); // 2 * sampling for DSP
94             break;
95         default:
96             AUDIO_ERR_LOG("spatializerEngineState error!");
97             ret = ERROR;
98             break;
99     }
100     return ret;
101 }
102 
SensorActive()103 int32_t HeadTracker::SensorActive()
104 {
105     return ActivateSensor(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_);
106 }
107 
SensorDeactive()108 int32_t HeadTracker::SensorDeactive()
109 {
110     return DeactivateSensor(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_);
111 }
112 
SensorUnsubscribe()113 int32_t HeadTracker::SensorUnsubscribe()
114 {
115     return UnsubscribeSensor(SENSOR_TYPE_ID_HEADPOSTURE, &sensorUser_);
116 }
117 
GetHeadPostureData()118 HeadPostureData HeadTracker::GetHeadPostureData()
119 {
120     std::lock_guard<std::mutex> lock(headTrackerMutex_);
121     return headPostureData_;
122 }
123 
SetHeadPostureData(HeadPostureData headPostureData)124 void HeadTracker::SetHeadPostureData(HeadPostureData headPostureData)
125 {
126     std::lock_guard<std::mutex> lock(headTrackerMutex_);
127     headPostureData_ = headPostureData;
128 }
129 #endif
130 }  // namespace AudioStandard
131 }  // namespace OHOS