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 "amp_task.h"
12 #include "aos_fs.h"
13 #include "board_mgr.h"
14 #include "aos/vfs.h"
15
16 #include "uvoice_types.h"
17 #include "uvoice_event.h"
18 #include "uvoice_player.h"
19 #include "uvoice_comb.h"
20 #include "aos_pcm.h"
21 #include "aos_tts.h"
22
23 #include "quickjs.h"
24 #include "quickjs_addon_common.h"
25
26
27 #define MOD_STR "audioplayer"
28
29
30 typedef struct {
31 uvoice_player_t *player;
32 JSValue js_cb_ref;
33 int list_playing;
34 int state;
35 } audio_player_t;
36
37 typedef struct {
38 void *userdata;
39 JSValue js_cb_ref;
40 int event;
41 unsigned long timestamp;
42 } audio_player_param_t;
43
44 enum {
45 AUDIOPLAYER_STAT_STOP = 0,
46 AUDIOPLAYER_STAT_PAUSED = 1,
47 AUDIOPLAYER_STAT_PLAYING = 2,
48 AUDIOPLAYER_STAT_LIST_PLAY_BEGIN = 3,
49 AUDIOPLAYER_STAT_LIST_PLAY_END = 4,
50 AUDIOPLAYER_STAT_ERROR = 5,
51 };
52
53 enum {
54 JS_ATOM_NULL,
55 #define DEF(name, str) JS_ATOM_##name,
56 #include "quickjs-atom.h"
57 #undef DEF
58 JS_ATOM_END,
59 };
60
61 static audio_player_t *g_audioplayer;
62 static JSClassID js_audio_class_id;
63
js_get_length32(JSContext * ctx,uint32_t * pres,JSValueConst obj)64 static int js_get_length32(JSContext* ctx, uint32_t* pres,
65 JSValueConst obj)
66 {
67 JSValue len_val;
68 len_val = JS_GetProperty(ctx, obj, JS_ATOM_length);
69 if (JS_IsException(len_val)) {
70 *pres = 0;
71 return -1;
72 }
73 return JS_ToInt32(ctx, pres, len_val);
74 }
75
audioplayer_state_notify(void * arg)76 static void audioplayer_state_notify(void *arg)
77 {
78 audio_player_t *audioplayer = (audio_player_t *)arg;
79 JSValue state;
80
81 JSContext *ctx = js_get_context();
82 state = JS_NewInt32(ctx, audioplayer->state);
83
84 JSValue val = JS_Call(ctx, audioplayer->js_cb_ref, JS_UNDEFINED, 1, &state);
85 JS_FreeValue(ctx, val);
86 JS_FreeValue(ctx, state);
87 }
88
audioplayer_state_cb(uvoice_event_t * event,void * data)89 static void audioplayer_state_cb(uvoice_event_t *event, void *data)
90 {
91 audio_player_t *audioplayer = (audio_player_t *)data;
92 player_state_t state;
93 int audioplayer_state = PLAYER_STAT_IDLE;
94 int ret;
95
96 if (!audioplayer)
97 return;
98
99 if (event->type != UVOICE_EV_PLAYER)
100 return;
101
102 if (event->code == UVOICE_CODE_PLAYER_STATE) {
103 state = event->value;
104 switch (state) {
105 case PLAYER_STAT_RUNNING:
106 case PLAYER_STAT_COMPLETE:
107 case PLAYER_STAT_RESUME:
108 audioplayer_state = AUDIOPLAYER_STAT_PLAYING;
109 break;
110 case PLAYER_STAT_PAUSED:
111 audioplayer_state = AUDIOPLAYER_STAT_PAUSED;
112 break;
113 case PLAYER_STAT_STOP:
114 case PLAYER_STAT_IDLE:
115 case PLAYER_STAT_READY:
116 audioplayer_state = AUDIOPLAYER_STAT_STOP;
117 break;
118 case PLAYER_STAT_ERROR:
119 audioplayer_state = AUDIOPLAYER_STAT_ERROR;
120 break;
121 case PLAYER_STAT_LIST_PLAY_START:
122 audioplayer_state = AUDIOPLAYER_STAT_LIST_PLAY_BEGIN;
123 audioplayer->list_playing = 1;
124 break;
125 case PLAYER_STAT_LIST_PLAY_STOP:
126 audioplayer_state = AUDIOPLAYER_STAT_LIST_PLAY_END;
127 audioplayer->list_playing = 0;
128 break;
129 default:
130 return;
131 }
132 }
133
134 if (audioplayer->state == audioplayer_state) {
135 return;
136 }
137 audioplayer->state = audioplayer_state;
138
139 amp_task_schedule_call(audioplayer_state_notify, audioplayer);
140 }
141
audioplayer_play_cplt_notify(void * arg)142 static void audioplayer_play_cplt_notify(void *arg)
143 {
144 audio_player_param_t *param = (audio_player_param_t *)arg;
145 JSContext *ctx = js_get_context();
146
147 if (param == NULL) {
148 return;
149 }
150 JSValue val = JS_Call(ctx, param->js_cb_ref, JS_UNDEFINED, 0, NULL);
151 JS_FreeValue(ctx, val);
152 JS_FreeValue(ctx, param->js_cb_ref);
153
154 aos_free(param);
155 }
156
audioplayer_play_cplt_cb(uvoice_event_t * event,void * data)157 static void audioplayer_play_cplt_cb(uvoice_event_t *event, void *data)
158 {
159 audio_player_param_t *param = (audio_player_param_t *)data;
160
161 if (!param)
162 return;
163
164 if (event->type != UVOICE_EV_PLAYER)
165 return;
166
167 if (event->code == UVOICE_CODE_PLAYER_STATE &&
168 (event->value == PLAYER_STAT_COMPLETE ||
169 event->value == PLAYER_STAT_STOP) &&
170 (unsigned long)aos_now_ms() >= param->timestamp) {
171
172 uvoice_event_unregister(UVOICE_EV_PLAYER, audioplayer_play_cplt_cb, param);
173 amp_task_schedule_call(audioplayer_play_cplt_notify, param);
174 }
175 }
176
audioplayer_listplay_cplt_cb(void * data,int event)177 static void audioplayer_listplay_cplt_cb(void *data, int event)
178 {
179 audio_player_param_t *param = (audio_player_param_t *)data;
180 param->event = event;
181 amp_task_schedule_call(audioplayer_play_cplt_notify, param);
182 }
183
native_audioplayer_play(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)184 static JSValue native_audioplayer_play(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
185 {
186 audio_player_t *audioplayer = g_audioplayer;
187 audio_player_param_t *param = NULL;
188 uvoice_player_t *player;
189 char *audiosource = NULL;
190 char *source = NULL;
191 int len;
192 int is_http = 0;
193 int ret = -1;
194
195 if (!audioplayer)
196 goto out;
197
198 player = audioplayer->player;
199
200 if (!JS_IsString(argv[0]) || !JS_IsFunction(ctx, argv[1])) {
201 amp_error(MOD_STR, "parameter must be (string, function)");
202 goto out;
203 }
204
205 param = aos_malloc(sizeof(audio_player_param_t));
206 if (!param) {
207 amp_error(MOD_STR, "alloc param fail");
208 goto out;
209 }
210
211 audiosource = (char *)JS_ToCString(ctx, argv[0]);
212 if (!audiosource) {
213 amp_error(MOD_STR, "audio source null");
214 goto out;
215 }
216
217 if (!strncmp(audiosource, "http", strlen("http"))) {
218 is_http = 1;
219 source = audiosource;
220 } else {
221 source = aos_malloc(strlen(audiosource) + 4);
222 if (!source) {
223 amp_error(MOD_STR, "alloc source fail");
224 goto out;
225 }
226 snprintf(source, strlen(audiosource) + 4, "fs:%s", audiosource);
227 }
228
229 if (!JS_IsFunction(ctx, argv[1])) {
230 JS_ThrowTypeError(ctx, "not a function");
231 goto out;
232 }
233
234 param->js_cb_ref = JS_DupValue(ctx, argv[1]);
235 param->timestamp = (unsigned long)aos_now_ms();
236
237 if (comb_add_http_source(source, 0)) {
238 amp_error(MOD_STR, "add source fail");
239 JS_FreeValue(ctx, param->js_cb_ref);
240 goto out;
241 }
242
243 if (uvoice_event_register(UVOICE_EV_PLAYER,
244 audioplayer_play_cplt_cb, param)) {
245 amp_error(MOD_STR, "register event fail");
246 JS_FreeValue(ctx, param->js_cb_ref);
247 aos_free(param);
248 goto out;
249 }
250
251 ret = 0;
252
253 out:
254 if (!is_http && source) {
255 aos_free(source);
256 }
257
258 if(audiosource != NULL) {
259 JS_FreeCString(ctx, audiosource);
260 }
261
262 return JS_NewInt32(ctx, ret);
263 }
264
native_audioplayer_stop(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)265 static JSValue native_audioplayer_stop(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
266 {
267 audio_player_t *audioplayer = g_audioplayer;
268 uvoice_player_t *player;
269 int ret = -1;
270
271 if (!audioplayer)
272 goto out;
273 player = audioplayer->player;
274
275 if (player->stop()) {
276 comb_clr_http_source();
277 goto out;
278 }
279
280 player->clr_source();
281 comb_clr_http_source();
282 ret = 0;
283 out:
284 return JS_NewInt32(ctx, ret);
285 }
286
native_audioplayer_pause(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)287 static JSValue native_audioplayer_pause(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
288 {
289 audio_player_t *audioplayer = g_audioplayer;
290 uvoice_player_t *player;
291 int ret = -1;
292
293 if (!audioplayer)
294 goto out;
295 player = audioplayer->player;
296
297 if (player->pause()) {
298 amp_error(MOD_STR, "play pause fail");
299 goto out;
300 }
301
302 ret = 0;
303 out:
304 return JS_NewInt32(ctx, ret);
305 }
306
native_audioplayer_resume(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)307 static JSValue native_audioplayer_resume(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
308 {
309 audio_player_t *audioplayer = g_audioplayer;
310 uvoice_player_t *player;
311 int ret = -1;
312
313 if (!audioplayer)
314 goto out;
315 player = audioplayer->player;
316
317 if (player->resume()) {
318 amp_error(MOD_STR, "play resume fail");
319 goto out;
320 }
321 ret = 0;
322 out:
323 return JS_NewInt32(ctx, ret);
324 }
325
native_audioplayer_seekto(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)326 static JSValue native_audioplayer_seekto(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
327 {
328 audio_player_t *audioplayer = g_audioplayer;
329 uvoice_player_t *player;
330 int ret = -1;
331 int seconds;
332
333 if (!audioplayer)
334 goto out;
335 player = audioplayer->player;
336
337 if (!JS_IsNumber(argv[0])) {
338 amp_error(MOD_STR, "parameter must be (number)");
339 goto out;
340 }
341
342 JS_ToInt32(ctx, &seconds, argv[0]);
343 if (seconds < 0) {
344 amp_error(MOD_STR, "seconds %d invalid", seconds);
345 goto out;
346 }
347
348 if (player->seek(seconds)) {
349 amp_error(MOD_STR, "seek to %d fail", seconds);
350 goto out;
351 }
352 ret = 0;
353
354 out:
355 return JS_NewInt32(ctx, ret);
356 }
357
native_audioplayer_position_get(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)358 static JSValue native_audioplayer_position_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
359 {
360 audio_player_t *audioplayer = g_audioplayer;
361 uvoice_player_t *player;
362 int position = 0;
363 int ret = -1;
364
365 if (!audioplayer)
366 goto out;
367 player = audioplayer->player;
368
369 if (player->get_position(&position)) {
370 amp_error(MOD_STR, "get position fail");
371 goto out;
372 }
373
374 ret = position;
375
376 out:
377 return JS_NewInt32(ctx, ret);
378 }
379
native_audioplayer_duration_get(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)380 static JSValue native_audioplayer_duration_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
381 {
382 audio_player_t *audioplayer = g_audioplayer;
383 uvoice_player_t *player;
384 int duration = 0;
385 int ret = -1;
386
387 if (!audioplayer)
388 goto out;
389 player = audioplayer->player;
390
391 if (player->get_duration(&duration)) {
392 amp_error(MOD_STR, "get duration fail");
393 goto out;
394 }
395
396 ret = duration;
397
398 out:
399 return JS_NewInt32(ctx, ret);
400 }
401
native_audioplayer_state_get(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)402 static JSValue native_audioplayer_state_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
403 {
404 audio_player_t *audioplayer = g_audioplayer;
405 uvoice_player_t *player;
406 player_state_t state = PLAYER_STAT_IDLE;
407 int audioplayer_state;
408 int ret = -1;
409
410 if (!audioplayer)
411 goto out;
412 player = audioplayer->player;
413
414 if (player->get_state(&state)) {
415 amp_error(MOD_STR, "get player state fail");
416 goto out;
417 }
418
419 switch (state) {
420 case PLAYER_STAT_RUNNING:
421 case PLAYER_STAT_COMPLETE:
422 case PLAYER_STAT_RESUME:
423 audioplayer_state = AUDIOPLAYER_STAT_PLAYING;
424 break;
425 case PLAYER_STAT_PAUSED:
426 audioplayer_state = AUDIOPLAYER_STAT_PAUSED;
427 break;
428 case PLAYER_STAT_STOP:
429 case PLAYER_STAT_IDLE:
430 case PLAYER_STAT_READY:
431 audioplayer_state = AUDIOPLAYER_STAT_STOP;
432 break;
433 case PLAYER_STAT_ERROR:
434 audioplayer_state = AUDIOPLAYER_STAT_ERROR;
435 break;
436 case PLAYER_STAT_LIST_PLAY_START:
437 audioplayer_state = AUDIOPLAYER_STAT_LIST_PLAY_BEGIN;
438 break;
439 case PLAYER_STAT_LIST_PLAY_STOP:
440 audioplayer_state = AUDIOPLAYER_STAT_LIST_PLAY_END;
441 break;
442 default:
443 audioplayer_state = AUDIOPLAYER_STAT_STOP;
444 break;
445 }
446 ret = audioplayer_state;
447
448 out:
449 return JS_NewInt32(ctx, ret);
450 }
451
native_audioplayer_state_on(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)452 static JSValue native_audioplayer_state_on(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
453 {
454 audio_player_t *audioplayer = g_audioplayer;
455 int ret = -1;
456
457 if (!JS_IsFunction(ctx, argv[0])) {
458 amp_warn(MOD_STR, "parameter must be (function)");
459 goto out;
460 }
461
462 JSValue state_cb = argv[0];
463 if (!JS_IsFunction(ctx, state_cb)) {
464 return JS_ThrowTypeError(ctx, "not a function");
465 }
466
467 audioplayer->js_cb_ref = JS_DupValue(ctx, state_cb);
468
469 if (uvoice_event_register(UVOICE_EV_PLAYER,
470 audioplayer_state_cb, audioplayer)) {
471 amp_error(MOD_STR, "register event fail");
472 goto out;
473 }
474
475 ret = 0;
476 out:
477 return JS_NewInt32(ctx, ret);
478 }
479
native_audioplayer_volume_set(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)480 static JSValue native_audioplayer_volume_set(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
481 {
482 audio_player_t *audioplayer = g_audioplayer;
483 uvoice_player_t *player;
484 int ret = -1;
485 int volume;
486
487 if (!audioplayer)
488 goto out;
489 player = audioplayer->player;
490
491 if (!JS_IsNumber(argv[0])) {
492 amp_error(MOD_STR, "parameter must be (number)");
493 goto out;
494 }
495
496 JS_ToInt32(ctx, &volume, argv[0]);
497 if (volume < 0) {
498 amp_error(MOD_STR, "volume %d invalid", volume);
499 goto out;
500 }
501
502 if (player->set_volume(volume)) {
503 amp_error(MOD_STR, "set volume fail");
504 goto out;
505 }
506 ret = 0;
507
508 out:
509 return JS_NewInt32(ctx, ret);
510 }
511
native_audioplayer_volume_get(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)512 static JSValue native_audioplayer_volume_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
513 {
514 audio_player_t *audioplayer = g_audioplayer;
515 uvoice_player_t *player;
516 int ret = -1;
517 int volume = -1;
518
519 if (!audioplayer)
520 goto out;
521 player = audioplayer->player;
522
523 if (player->get_volume(&volume)) {
524 amp_error(MOD_STR, "get volume fail");
525 goto out;
526 }
527
528 ret = volume;
529 out:
530 return JS_NewInt32(ctx, ret);
531 }
532
native_audioplayer_play_list(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)533 static JSValue native_audioplayer_play_list(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
534 {
535 audio_player_param_t *param;
536 char *source;
537 int arr_idx;
538 int arr_cnt;
539 int i, ret = -1;
540 int error = 0;
541 struct aos_stat stat;
542 comb_source_info_t *info;
543
544 if (!JS_IsArray(ctx, argv[0]) || !JS_IsFunction(ctx, argv[1])) {
545 amp_error(MOD_STR, "parameter must be (array, function)");
546 goto out;
547 }
548
549 param = aos_malloc(sizeof(audio_player_param_t));
550 if (!param) {
551 amp_error(MOD_STR, "alloc param fail");
552 goto out;
553 }
554
555 info = aos_malloc(sizeof(comb_source_info_t));
556 if (!info) {
557 amp_error(MOD_STR, "alloc info fail");
558 aos_free(param);
559 goto out;
560 }
561 memset(info, 0, sizeof(comb_source_info_t));
562
563 js_get_length32(ctx, &arr_cnt, argv[0]);
564
565 if (arr_cnt > COMB_SOURCE_LIST_MAX) {
566 amp_error(MOD_STR, "list count out of limit");
567 aos_free(param);
568 aos_free(info);
569 goto out;
570 }
571
572 JSValue play_cb = argv[1];
573 if (!JS_IsFunction(ctx, play_cb)) {
574 return JS_ThrowTypeError(ctx, "not a function");
575 }
576 param->js_cb_ref = JS_DupValue(ctx, play_cb);
577
578 for (i = 0; i < arr_cnt; i++) {
579 JSValue str_val = JS_GetPropertyUint32(ctx, argv[0], i);
580 if (!JS_IsString(str_val)) {
581 amp_error(MOD_STR, "array element %d is not string", i);
582 JS_FreeValue(ctx, param->js_cb_ref);
583 aos_free(param);
584 aos_free(info);
585 goto out;
586 }
587 source = JS_ToCString(ctx, str_val);
588
589 if (strlen(source) >= COMB_SOURCE_PATH_LEN) {
590 amp_error(MOD_STR, "source %s path too long", source);
591 JS_FreeValue(ctx, param->js_cb_ref);
592 aos_free(param);
593 aos_free(info);
594 JS_FreeCString(ctx, source);
595 goto out;
596 }
597
598 memset(&stat, 0, sizeof(aos_stat));
599 ret = aos_stat(source, &stat);
600 if (ret < 0 || !S_ISREG(stat.st_mode)) {
601 amp_error(MOD_STR, "source %s not exist", source);
602 JS_FreeValue(ctx, param->js_cb_ref);
603 aos_free(param);
604 aos_free(info);
605 ret = -1;
606 JS_FreeCString(ctx, source);
607 goto out;
608 }
609
610 info->count++;
611 snprintf(info->sources[i], COMB_SOURCE_PATH_LEN, "%s", source);
612 JS_FreeCString(ctx, source);
613 }
614
615 info->callback = audioplayer_listplay_cplt_cb;
616 info->userdata = param;
617 if (comb_add_file_source_list(info)) {
618 error = -1;
619 }
620 aos_free(info);
621 ret = error;
622 out:
623
624 return JS_NewInt32(ctx, ret);
625 }
626
native_audioplayer_play_list_stop(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)627 static JSValue native_audioplayer_play_list_stop(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
628 {
629 comb_play_stop();
630 comb_clr_http_source();
631
632 return JS_NewInt32(ctx, 0);
633 }
634
native_audioplayer_config_parse(uvoice_player_t * player)635 static int native_audioplayer_config_parse(uvoice_player_t *player)
636 {
637 item_handle_t item_handle;
638 item_handle.handle = NULL;
639 aos_audio_dev_t *audio_dev;
640 audio_extpa_info_t pa_info;
641
642 if (board_attach_item(MODULE_AUDIO, "audio", &item_handle)) {
643 player->set_out_device(AOS_SND_DEVICE_OUT_HEADPHONE);
644 #ifdef JSE_ADVANCED_ADDON_TTS
645 aos_tts_set_out_device(AOS_SND_DEVICE_OUT_HEADPHONE);
646 #endif
647 } else {
648 audio_dev = board_get_node_by_handle(MODULE_AUDIO, &item_handle);
649 if (!audio_dev) {
650 amp_warn(MOD_STR, "get audio module fail");
651 return -1;
652 } else {
653 amp_info(MOD_STR, "out device %d, ext pa %s, pin %d, delay %d, active %d",
654 audio_dev->out_device, audio_dev->external_pa ? "enable" : "disable",
655 audio_dev->external_pa_pin, audio_dev->external_pa_delay_ms,
656 audio_dev->external_pa_active_high);
657 }
658
659 if (audio_dev->out_device >= AOS_SND_DEVICE_OUT_SPEAKER &&
660 audio_dev->out_device < AOS_SND_DEVICE_MAX) {
661 player->set_out_device(audio_dev->out_device);
662 #ifdef JSE_ADVANCED_ADDON_TTS
663 aos_tts_set_out_device(audio_dev->out_device);
664 #endif
665 } else {
666 player->set_out_device(AOS_SND_DEVICE_OUT_HEADPHONE);
667 #ifdef JSE_ADVANCED_ADDON_TTS
668 aos_tts_set_out_device(AOS_SND_DEVICE_OUT_HEADPHONE);
669 #endif
670 }
671
672 if (audio_dev->external_pa) {
673 pa_info.used = audio_dev->external_pa;
674 pa_info.active_high = audio_dev->external_pa_active_high;
675 pa_info.pin = audio_dev->external_pa_pin;
676 pa_info.delay_ms = audio_dev->external_pa_delay_ms;
677 player->set_external_pa(&pa_info);
678 }
679 }
680
681 return 0;
682 }
683
module_audioplayer_source_clean(void)684 static void module_audioplayer_source_clean(void)
685 {
686 audio_player_t *audioplayer = g_audioplayer;
687 uvoice_player_t *player;
688
689 if (!audioplayer)
690 return;
691
692 player = audioplayer->player;
693 if (!player) {
694 return;
695 }
696
697 comb_play_stop();
698 comb_clr_http_source();
699 player->stop();
700 player->clr_source();
701
702 uvoice_player_release(player);
703 aos_free(audioplayer);
704 g_audioplayer = NULL;
705 comb_deinit();
706 uvoice_free();
707 }
708
709 static JSClassDef js_audio_class = {
710 "audio",
711 };
712
713 static const JSCFunctionListEntry js_audio_funcs[] = {
714 JS_CFUNC_DEF("listPlay", 2, native_audioplayer_play_list),
715 JS_CFUNC_DEF("listPlayStop",0, native_audioplayer_play_list_stop),
716 JS_CFUNC_DEF("play", 2, native_audioplayer_play),
717 JS_CFUNC_DEF("stop", 0, native_audioplayer_stop),
718 JS_CFUNC_DEF("pause", 0, native_audioplayer_pause),
719 JS_CFUNC_DEF("resume", 0, native_audioplayer_resume),
720 JS_CFUNC_DEF("seekto", 1, native_audioplayer_seekto),
721 JS_CFUNC_DEF("getPosition", 0, native_audioplayer_position_get),
722 JS_CFUNC_DEF("getDuration", 0, native_audioplayer_duration_get),
723 JS_CFUNC_DEF("getState", 0, native_audioplayer_state_get),
724 JS_CFUNC_DEF("onState", 1, native_audioplayer_state_on),
725 JS_CFUNC_DEF("setVolume", 1, native_audioplayer_volume_set),
726 JS_CFUNC_DEF("getVolume", 0, native_audioplayer_volume_get)
727 };
728
js_audio_init(JSContext * ctx,JSModuleDef * m)729 static int js_audio_init(JSContext *ctx, JSModuleDef *m)
730 {
731 JSValue proto;
732
733 JS_NewClassID(&js_audio_class_id);
734
735 JS_NewClass(JS_GetRuntime(ctx), js_audio_class_id, &js_audio_class);
736 proto = JS_NewObject(ctx);
737 JS_SetPropertyFunctionList(ctx, proto, js_audio_funcs, countof(js_audio_funcs));
738 JS_SetClassProto(ctx, js_audio_class_id, proto);
739 return JS_SetModuleExportList(ctx, m, js_audio_funcs, countof(js_audio_funcs));
740 }
741
js_init_module_audio(JSContext * ctx,const char * module_name)742 JSModuleDef *js_init_module_audio(JSContext *ctx, const char *module_name)
743 {
744 JSModuleDef *m;
745 m = JS_NewCModule(ctx, module_name, js_audio_init);
746 if (!m)
747 return NULL;
748 JS_AddModuleExportList(ctx, m, js_audio_funcs, countof(js_audio_funcs));
749 return m;
750 }
751
752
module_audio_register(void)753 void module_audio_register(void)
754 {
755 audio_player_t *audioplayer;
756
757 uvoice_init();
758 // init audio codec
759 extern int audio_install_codec_driver();
760 audio_install_codec_driver();
761
762 comb_init();
763
764 audioplayer = aos_malloc(sizeof(audio_player_t));
765 if (!audioplayer) {
766 amp_error(MOD_STR, "alloc audio player fail");
767 return;
768 }
769 audioplayer->player = uvoice_player_create();
770 if (!audioplayer->player) {
771 amp_error(MOD_STR, "create uvoice player fail");
772 aos_free(audioplayer);
773 return;
774 }
775 native_audioplayer_config_parse(audioplayer->player);
776 audioplayer->state = -1;
777 g_audioplayer = audioplayer;
778
779 amp_module_free_register(module_audioplayer_source_clean);
780
781 amp_debug(MOD_STR, "module_audio_register");
782 JSContext *ctx = js_get_context();
783 js_init_module_audio(ctx, "AUDIOPLAYER");
784 }
785
786