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