1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 #include <stdarg.h>
7 
8 #include "amp_config.h"
9 #include "aos_system.h"
10 #include "amp_defines.h"
11 #include "be_inl.h"
12 #include "aos_pcm.h"
13 #include "aos_tts.h"
14 
15 
16 #define MOD_STR        "TTS"
17 
18 static int tts_js_cb_ref = 0;
19 
native_tts_event_callback(aos_tts_event_t event,char * content)20 static void native_tts_event_callback(aos_tts_event_t event, char *content)
21 {
22 	duk_context *ctx;
23     if (tts_js_cb_ref == 0) {
24 		return;
25     }
26     ctx = be_get_context();
27     be_push_ref(ctx, tts_js_cb_ref);
28 	duk_push_int(ctx, event);
29     if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) {
30         amp_console("%s", duk_safe_to_stacktrace(ctx, -1));
31     }
32     duk_pop(ctx);
33     duk_gc(ctx, 0);
34 }
35 
native_tts_play(duk_context * ctx)36 static duk_ret_t native_tts_play(duk_context *ctx)
37 {
38     int ret = -1;
39     int encode_type;
40     char *text;
41 
42     if (!duk_is_string(ctx, 0)||  !duk_is_number(ctx, 1)) {
43         amp_error(MOD_STR, "parameter must be (string, num)");
44         goto out;
45     }
46 
47     text = (char *)duk_get_string(ctx, 0);
48     if (!text) {
49         amp_error(MOD_STR, "text null");
50         goto out;
51     }
52 
53     encode_type = duk_get_number(ctx, 1);
54     if (encode_type < 0) {
55         amp_error(MOD_STR, "encode type invalid");
56         goto out;
57     }
58 
59     if (aos_tts_is_playing()) {
60         amp_warn(MOD_STR, "tts is playing, ignore");
61         goto out;
62     }
63 
64     ret = aos_tts_play(text, encode_type);
65     if (ret != 0) {
66         amp_error(MOD_STR, "tts play failed");
67         goto out;
68     }
69 
70 out:
71     duk_push_int(ctx, ret);
72     return 1;
73 }
74 
native_tts_stop(duk_context * ctx)75 static duk_ret_t native_tts_stop(duk_context *ctx)
76 {
77     int ret = -1;
78 
79     ret = aos_tts_stop();
80     if (ret != 0) {
81         amp_error(MOD_STR, "tts stop failed");
82         goto out;
83     }
84 
85 out:
86     duk_push_int(ctx, ret);
87     return 1;
88 }
89 
native_tts_state_get(duk_context * ctx)90 static duk_ret_t native_tts_state_get(duk_context *ctx)
91 {
92     int state = -1;
93     aos_tts_state_get(&state);
94     duk_push_int(ctx, state);
95     return 1;
96 }
97 
native_tts_volume_set(duk_context * ctx)98 static duk_ret_t native_tts_volume_set(duk_context *ctx)
99 {
100     int ret = -1;
101     int volume;
102 
103     if (!duk_is_number(ctx, 0)) {
104         amp_error(MOD_STR, "parameter must be (number)");
105         goto out;
106     }
107 
108     volume = duk_get_int(ctx, 0);
109     if (volume < 0) {
110         amp_error(MOD_STR, "volume invalid");
111         goto out;
112     }
113 
114     ret = aos_tts_volume_set(volume);
115     if (ret != 0) {
116         amp_error(MOD_STR, "set tts volume failed");
117         goto out;
118     }
119 
120 out:
121     duk_push_int(ctx, ret);
122     return 1;
123 }
124 
native_tts_volume_get(duk_context * ctx)125 static duk_ret_t native_tts_volume_get(duk_context *ctx)
126 {
127     int volume = -1;
128     aos_tts_volume_get(&volume);
129     duk_push_int(ctx, volume);
130     return 1;
131 }
132 
native_tts_pitch_set(duk_context * ctx)133 static duk_ret_t native_tts_pitch_set(duk_context *ctx)
134 {
135     int ret = -1;
136     int pitch;
137 
138     if (!duk_is_number(ctx, 0)) {
139         amp_error(MOD_STR, "parameter must be (number)");
140         goto out;
141     }
142 
143     pitch = duk_get_int(ctx, 0);
144     if (pitch < 0) {
145         amp_error(MOD_STR, "pitch invalid");
146         goto out;
147     }
148 
149     ret = aos_tts_pitch_set(pitch);
150     if (ret != 0) {
151         amp_error(MOD_STR, "set tts pitch failed");
152         goto out;
153     }
154 
155 out:
156     duk_push_int(ctx, ret);
157     return 1;
158 }
159 
native_tts_speed_set(duk_context * ctx)160 static duk_ret_t native_tts_speed_set(duk_context *ctx)
161 {
162     int ret = -1;
163     int speed;
164 
165     if (!duk_is_number(ctx, 0)) {
166         amp_error(MOD_STR, "parameter must be (number)\n");
167         goto out;
168     }
169 
170     speed = duk_get_int(ctx, 0);
171     if (speed < 0) {
172         amp_error(MOD_STR, "speed invalid");
173         goto out;
174     }
175 
176     ret = aos_tts_speed_set(speed);
177     if (ret != 0) {
178         amp_error(MOD_STR, "set tts speed failed");
179         goto out;
180     }
181 
182 out:
183     duk_push_int(ctx, ret);
184     return 1;
185 }
186 
native_tts_speed_get(duk_context * ctx)187 static duk_ret_t native_tts_speed_get(duk_context *ctx)
188 {
189     int speed = -1;
190     aos_tts_speed_get(&speed);
191     duk_push_int(ctx, speed);
192     return 1;
193 }
194 
native_tts_event_on(duk_context * ctx)195 static duk_ret_t native_tts_event_on(duk_context *ctx)
196 {
197     int ret = -1;
198 
199     if (!duk_is_function(ctx, 0)) {
200         amp_warn(MOD_STR, "parameter must be (function)");
201         goto out;
202     }
203 
204     duk_dup(ctx, 0);
205     tts_js_cb_ref = be_ref(ctx);
206 
207     ret = 0;
208 out:
209     duk_push_int(ctx, ret);
210     return 1;
211 }
212 
native_tts_source_clean(void)213 static void native_tts_source_clean(void)
214 {
215     if (aos_tts_is_playing()) {
216         aos_tts_stop();
217     }
218     aos_tts_deinit();
219     tts_js_cb_ref = 0;
220 }
221 
module_tts_register(void)222 void module_tts_register(void)
223 {
224     duk_context *ctx = be_get_context();
225 
226     aos_tts_init(native_tts_event_callback);
227 
228     amp_module_free_register(native_tts_source_clean);
229 
230     duk_push_object(ctx);
231 
232     AMP_ADD_FUNCTION("play",    native_tts_play, 2);
233     AMP_ADD_FUNCTION("stop",    native_tts_stop, 0);
234     AMP_ADD_FUNCTION("getState",   native_tts_state_get, 1);
235     AMP_ADD_FUNCTION("onState",    native_tts_event_on, 1);
236     AMP_ADD_FUNCTION("setVolume",  native_tts_volume_set, 1);
237 	AMP_ADD_FUNCTION("getVolume",  native_tts_volume_get, 1);
238     AMP_ADD_FUNCTION("setPitch",   native_tts_pitch_set, 1);
239     AMP_ADD_FUNCTION("setSpeed",   native_tts_speed_set, 1);
240 	AMP_ADD_FUNCTION("getSpeed",   native_tts_speed_get, 1);
241 
242     duk_put_prop_string(ctx, -2, "TTS");
243 }
244 
245