1 /*
2 * Copyright (c) 2024-2025 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 "NapiAudioEffectMgr"
17 #endif
18
19 #include "napi_audio_effect_manager.h"
20 #include "napi_audio_error.h"
21 #include "napi_param_utils.h"
22 #include "napi_audio_enum.h"
23 #include "audio_errors.h"
24 #include "audio_manager_log.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
28 using namespace std;
29 using namespace HiviewDFX;
30 static __thread napi_ref g_effectMgrConstructor = nullptr;
31
NapiAudioEffectMgr()32 NapiAudioEffectMgr::NapiAudioEffectMgr()
33 : env_(nullptr), audioEffectMngr_(nullptr) {}
34
35 NapiAudioEffectMgr::~NapiAudioEffectMgr() = default;
36
Destructor(napi_env env,void * nativeObject,void * finalizeHint)37 void NapiAudioEffectMgr::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
38 {
39 if (nativeObject != nullptr) {
40 auto obj = static_cast<NapiAudioEffectMgr *>(nativeObject);
41 ObjectRefMap<NapiAudioEffectMgr>::DecreaseRef(obj);
42 }
43 AUDIO_INFO_LOG("Destructor is successful");
44 }
45
Construct(napi_env env,napi_callback_info info)46 napi_value NapiAudioEffectMgr::Construct(napi_env env, napi_callback_info info)
47 {
48 AUDIO_DEBUG_LOG("Construct");
49 napi_status status;
50 napi_value result = nullptr;
51 NapiParamUtils::GetUndefinedValue(env);
52
53 size_t argc = ARGS_TWO;
54 napi_value argv[ARGS_TWO] = {0};
55 napi_value thisVar = nullptr;
56 void *data = nullptr;
57 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
58 unique_ptr<NapiAudioEffectMgr> napiEffectMgr = make_unique<NapiAudioEffectMgr>();
59 CHECK_AND_RETURN_RET_LOG(napiEffectMgr != nullptr, result, "No memory");
60
61 napiEffectMgr->env_ = env;
62 napiEffectMgr->audioEffectMngr_ = AudioEffectManager::GetInstance();
63 napiEffectMgr->cachedClientId_ = getpid();
64 ObjectRefMap<NapiAudioEffectMgr>::Insert(napiEffectMgr.get());
65
66 status = napi_wrap(env, thisVar, static_cast<void*>(napiEffectMgr.get()),
67 NapiAudioEffectMgr::Destructor, nullptr, nullptr);
68 if (status != napi_ok) {
69 ObjectRefMap<NapiAudioEffectMgr>::Erase(napiEffectMgr.get());
70 return result;
71 }
72 napiEffectMgr.release();
73 return thisVar;
74 }
75
Init(napi_env env,napi_value exports)76 napi_value NapiAudioEffectMgr::Init(napi_env env, napi_value exports)
77 {
78 napi_status status;
79 napi_value constructor;
80 napi_value result = nullptr;
81 const int32_t refCount = ARGS_ONE;
82 napi_get_undefined(env, &result);
83
84 napi_property_descriptor audio_effect_mgr_properties[] = {
85
86 DECLARE_NAPI_FUNCTION("getSupportedAudioEffectProperty", GetSupportedAudioEffectProperty),
87 DECLARE_NAPI_FUNCTION("getAudioEffectProperty", GetAudioEffectProperty),
88 DECLARE_NAPI_FUNCTION("setAudioEffectProperty", SetAudioEffectProperty),
89
90 };
91
92 status = napi_define_class(env, AUDIO_EFFECT_MGR_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct, nullptr,
93 sizeof(audio_effect_mgr_properties) / sizeof(audio_effect_mgr_properties[PARAM0]),
94 audio_effect_mgr_properties, &constructor);
95 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
96
97 status = napi_create_reference(env, constructor, refCount, &g_effectMgrConstructor);
98 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
99 status = napi_set_named_property(env, exports, AUDIO_EFFECT_MGR_NAPI_CLASS_NAME.c_str(), constructor);
100 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
101 return exports;
102 }
103
CreateEffectManagerWrapper(napi_env env)104 napi_value NapiAudioEffectMgr::CreateEffectManagerWrapper(napi_env env)
105 {
106 napi_status status;
107 napi_value result = nullptr;
108 napi_value constructor;
109
110 status = napi_get_reference_value(env, g_effectMgrConstructor, &constructor);
111 if (status != napi_ok) {
112 AUDIO_ERR_LOG("Failed in CreateEffectManagerWrapper, %{public}d", status);
113 goto fail;
114 }
115 status = napi_new_instance(env, constructor, PARAM0, nullptr, &result);
116 if (status != napi_ok) {
117 AUDIO_ERR_LOG("napi_new_instance failed, status:%{public}d", status);
118 goto fail;
119 }
120 return result;
121
122 fail:
123 napi_get_undefined(env, &result);
124 return result;
125 }
126
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)127 NapiAudioEffectMgr* NapiAudioEffectMgr::GetParamWithSync(const napi_env &env, napi_callback_info info,
128 size_t &argc, napi_value *args)
129 {
130 napi_status status;
131 NapiAudioEffectMgr *napiEffectMgr = nullptr;
132 napi_value jsThis = nullptr;
133 status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
134 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
135 "GetParamWithSync fail to napi_get_cb_info");
136
137 status = napi_unwrap(env, jsThis, (void **)&napiEffectMgr);
138 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
139 CHECK_AND_RETURN_RET_LOG(napiEffectMgr != nullptr && napiEffectMgr->audioEffectMngr_ !=
140 nullptr, napiEffectMgr, "GetParamWithSync fail to napi_unwrap");
141 return napiEffectMgr;
142 }
143
GetSupportedAudioEffectProperty(napi_env env,napi_callback_info info)144 napi_value NapiAudioEffectMgr::GetSupportedAudioEffectProperty(napi_env env, napi_callback_info info)
145 {
146 napi_value result = nullptr;
147 size_t argc = PARAM0;
148 auto *napiEffectMgr = GetParamWithSync(env, info, argc, nullptr);
149 CHECK_AND_RETURN_RET_LOG(argc == PARAM0 && napiEffectMgr != nullptr && napiEffectMgr->audioEffectMngr_ != nullptr,
150 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM,
151 "incorrect parameter types: The type of options must be empty"), "argcCount invalid");
152
153 AudioEffectPropertyArrayV3 propertyArray = {};
154 int32_t ret = napiEffectMgr->audioEffectMngr_->GetSupportedAudioEffectProperty(propertyArray);
155 CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, NapiAudioError::ThrowErrorAndReturn(env, ret,
156 "interface operation failed"), "get support audio effect property failure!");
157
158 napi_status status = NapiParamUtils::SetEffectProperty(env, propertyArray, result);
159 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
160 NAPI_ERR_SYSTEM, "Combining property data fail"), "fill support effect property failed");
161
162 return result;
163 }
164
GetAudioEffectProperty(napi_env env,napi_callback_info info)165 napi_value NapiAudioEffectMgr::GetAudioEffectProperty(napi_env env, napi_callback_info info)
166 {
167 napi_value result = nullptr;
168 size_t argc = PARAM0;
169 auto *napiEffectMgr = GetParamWithSync(env, info, argc, nullptr);
170 CHECK_AND_RETURN_RET_LOG(argc == PARAM0 && napiEffectMgr != nullptr && napiEffectMgr->audioEffectMngr_ != nullptr,
171 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM,
172 "incorrect parameter types: The type of options must be empty"), "argcCount invalid");
173
174 AudioEffectPropertyArrayV3 propertyArray = {};
175 int32_t ret = napiEffectMgr->audioEffectMngr_->GetAudioEffectProperty(propertyArray);
176 CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, NapiAudioError::ThrowErrorAndReturn(env, ret,
177 "interface operation failed"), "get audio enhance property failure!");
178
179 napi_status status = NapiParamUtils::SetEffectProperty(env, propertyArray, result);
180 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
181 NAPI_ERR_SYSTEM, "combining property data fail"), "fill effect property failed");
182
183 return result;
184 }
185
SetAudioEffectProperty(napi_env env,napi_callback_info info)186 napi_value NapiAudioEffectMgr::SetAudioEffectProperty(napi_env env, napi_callback_info info)
187 {
188 napi_value result = nullptr;
189 size_t argc = ARGS_ONE;
190 napi_value args[ARGS_ONE] = {};
191 auto *napiEffectMgr = GetParamWithSync(env, info, argc, args);
192 CHECK_AND_RETURN_RET_LOG(argc == ARGS_ONE && napiEffectMgr != nullptr &&
193 napiEffectMgr->audioEffectMngr_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
194 NAPI_ERR_INPUT_INVALID,
195 "parameter verification failed: mandatory parameters are left unspecified"), "argcCount invalid");
196
197 napi_valuetype valueType = napi_undefined;
198 napi_typeof(env, args[PARAM0], &valueType);
199 CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
200 NAPI_ERR_INPUT_INVALID,
201 "incorrect parameter types: The type of options must be array"), "invaild valueType");
202
203 AudioEffectPropertyArrayV3 propertyArray = {};
204 napi_status status = NapiParamUtils::GetEffectPropertyArray(env, propertyArray, args[PARAM0]);
205 CHECK_AND_RETURN_RET_LOG(propertyArray.property.size() > 0,
206 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
207 "parameter verification failed: mandatory parameters are left unspecified"), "status or arguments error");
208
209 CHECK_AND_RETURN_RET_LOG(status == napi_ok,
210 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
211 "parameter verification failed: mandatory parameters are left unspecified"), "status or arguments error");
212
213 int32_t ret = napiEffectMgr->audioEffectMngr_->SetAudioEffectProperty(propertyArray);
214 CHECK_AND_RETURN_RET_LOG(ret == AUDIO_OK, NapiAudioError::ThrowErrorAndReturn(env, ret,
215 "interface operation failed"), "set audio effect property failure!");
216
217 return result;
218 }
219
220 } // namespace AudioStandard
221 } // namespace OHOS
222