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 
16 #ifndef SOUNDPOOL_NAPI_H
17 #define SOUNDPOOL_NAPI_H
18 
19 #include "napi/native_api.h"
20 #include "napi/native_node_api.h"
21 #include "common_napi.h"
22 #include "media_dfx.h"
23 #include "soundpool_callback_napi.h"
24 
25 namespace OHOS {
26 namespace Media {
27 using RetInfo = std::pair<int32_t, std::string>;
28 const int PARAM0 = 0;
29 const int PARAM1 = 1;
30 const int PARAM2 = 2;
31 const int PARAM3 = 3;
32 const int PARAM4 = 4;
33 const int MAX_PARAM = 5;
34 
35 struct SoundPoolAsyncContext;
36 
37 class SoundPoolNapi {
38 public:
39     __attribute__((visibility("default"))) static napi_value Init(napi_env env, napi_value exports);
40 
41 private:
SoundPoolNapi()42     SoundPoolNapi() {}
43     ~SoundPoolNapi();
44     static napi_value Constructor(napi_env env, napi_callback_info info);
45     static void Destructor(napi_env env, void *nativeObject, void *finalize);
46 
47     /**
48      * createSoundPool(maxStreams: number, audioRenderInfo: audio.AudioRendererInfo,
49      *     callback: AsyncCallback<SoundPool>): void
50      *
51      * createSoundPool(maxStreams: number, audioRenderInfo: audio.AudioRendererInfo): Promise<SoundPool>
52      */
53     static napi_value JsCreateSoundPool(napi_env env, napi_callback_info info);
54 
55     /**
56      * load(uri: string, callback: AsyncCallback<number>): void
57      * load(uri: string): Promise<number>
58      *
59      * or
60      *
61      * load(fd: number, offset: number, length: number, callback: AsyncCallback<number>): void
62      * load(fd: number, offset: number, length: number): Promise<number>
63      */
64     static napi_value JsLoad(napi_env env, napi_callback_info info);
65 
66     /**
67      * play(soundID: number, params?: PlayParameters): Promise<number>
68      * play(soundID: number, callback: AsyncCallback<number>): void
69      * play(soundID: number, params: PlayParameters, callback: AsyncCallback<number>): void
70      */
71     static napi_value JsPlay(napi_env env, napi_callback_info info);
72 
73     /**
74      * stop(streamID: number, callback: AsyncCallback<void>): void
75      * stop(streamID: number): Promise<void>
76      */
77     static napi_value JsStop(napi_env env, napi_callback_info info);
78 
79     /**
80      * setLoop(streamID: number, loop: number, callback: AsyncCallback<void>): void
81      * setLoop(streamID: number, loop: number): Promise<void>
82      */
83     static napi_value JsSetLoop(napi_env env, napi_callback_info info);
84 
85     /**
86      * setPriority(streamID: number, priority: number, callback: AsyncCallback<void>): void
87      * setPriority(streamID: number, priority: number): Promise<void>
88      */
89     static napi_value JsSetPriority(napi_env env, napi_callback_info info);
90 
91     /**
92      * setRate(streamID: number, rate: audio.AudioRendererRate, callback: AsyncCallback<void>): void
93      * setRate(streamID: number, rate: audio.AudioRendererRate): Promise<void>
94      */
95     static napi_value JsSetRate(napi_env env, napi_callback_info info);
96 
97     /**
98      * setVolume(streamID: number, leftVolume: number, rightVolume: number, callback: AsyncCallback<void>): void
99      * setVolume(streamID: number, leftVolume: number, rightVolume: number): Promise<void>
100      */
101     static napi_value JsSetVolume(napi_env env, napi_callback_info info);
102 
103     /**
104      * unload(soundID: number, callback: AsyncCallback<void>): void
105      * unload(soundID: number): Promise<void>
106      */
107     static napi_value JsUnload(napi_env env, napi_callback_info info);
108 
109     /**
110      * release(callback: AsyncCallback<void>): void
111      * release(): Promise<void>
112      */
113     static napi_value JsRelease(napi_env env, napi_callback_info info);
114 
115     /**
116      *
117      * on(type: 'loadCompleted', callback: Callback<number>): void
118      * off(type: 'loadCompleted'): void
119      *
120      * on(type: 'playFinished', callback: Callback<void>): void
121      * off(type: 'playFinished'): void
122      *
123      * on(type: 'error', callback: ErrorCallback): void
124      * off(type: 'error'): void
125      *
126      */
127     static napi_value JsSetOnCallback(napi_env env, napi_callback_info info);
128     static napi_value JsClearOnCallback(napi_env env, napi_callback_info info);
129     // Use to get soundpool instance.
130     static SoundPoolNapi* GetJsInstanceAndArgs(napi_env env, napi_callback_info info,
131         size_t &argCount, napi_value *args);
132     static napi_status GetJsInstanceWithParameter(napi_env env, napi_value *argv);
133     int32_t ParserLoadOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
134         napi_env env, napi_value *argv, size_t argCount);
135     int32_t ParserPlayOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
136         napi_env env, napi_value *argv, size_t argCount);
137     int32_t ParserRateOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
138     napi_env env, napi_value *argv);
139     int32_t ParserVolumeOptionFromJs(std::unique_ptr<SoundPoolAsyncContext> &asyncCtx,
140     napi_env env, napi_value *argv);
141     bool GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result);
142 
143     void ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add = "");
144     void SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref);
145     void CancelCallbackReference(const std::string &callbackName);
146     void CancelCallback(std::shared_ptr<ISoundPoolCallback> callback);
147 
148     static thread_local napi_ref constructor_;
149     static int32_t maxStreams;
150     static AudioStandard::AudioRendererInfo rendererInfo;
151 
152     napi_env env_ = nullptr;
153     std::shared_ptr<ISoundPool> soundPool_;
154     std::shared_ptr<ISoundPoolCallback> callbackNapi_;
155     std::map<std::string, std::shared_ptr<AutoRef>> eventCbMap_;
156 };
157 
158 struct SoundPoolAsyncContext : public MediaAsyncContext {
SoundPoolAsyncContextSoundPoolAsyncContext159     explicit SoundPoolAsyncContext(napi_env env) : MediaAsyncContext(env) {}
160     ~SoundPoolAsyncContext() = default;
161     void SoundPoolAsyncSignError(int32_t errCode, const std::string &operate,
162         const std::string &param, const std::string &add = "");
163     SoundPoolNapi *napi = nullptr;
164     std::shared_ptr<ISoundPool> soundPool_;
165     std::shared_ptr<ISoundPoolCallback> callbackNapi_;
166     std::string url_ = "";
167     int32_t fd_ = 0;
168     int64_t offset_ = 0;
169     int64_t length_ = 0;
170     int32_t soundId_ = 0;
171     PlayParams playParameters_;
172     int32_t streamId_ = 0;
173     int32_t loop_ = 0;
174     int32_t priority_ = 0;
175     float leftVolume_ = 0.0f;
176     float rightVolume_ = 0.0f;
177     AudioStandard::AudioRendererRate renderRate_ = AudioStandard::AudioRendererRate::RENDER_RATE_NORMAL;
178 };
179 } // namespace Media
180 } // namespace OHOS
181 #endif // SOUNDPOOL_NAPI_H