2 * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
4 * This program is licensed under the terms and conditions of the
5 * Apache License, version 2.0. The full text of the Apache License is at
6 * http://www.apache.org/licenses/LICENSE-2.0
10 * @brief Sound Sample APP
11 * Test use with which sound is sounded
25 #include <Ecore_Evas.h>
29 //#include "app_log.h"
31 #include "ico_apf_ecore.h"
32 #include "ico_apf_log.h"
33 #include "soundsample.h"
35 /*============================================================================*/
36 /* Define fixed parameters */
37 /*============================================================================*/
38 //#define WIDTH (700) /* Background width */
39 //#define HEIGHT (934) /* Background height */
40 //#define WIDTH (400) /* Background width */
41 //#define HEIGHT (400) /* Background height */
42 #define WIDTH (600) /* Background width */
43 #define HEIGHT (600) /* Background height */
45 //#define LOG_NAME "/home/rpf/var/log/uifw/audioTP.log"
46 #define LOG_NAME "/tmp/ico-app-soundsample.log"
47 //#define CONFIG_FILE "/home/rpf/src/app/audioTP/soundsample_config.txt"
48 #define CONFIG_FILE "/opt/apps/org.tizen.ico.app-soundsample/res/soundsample_config.txt"
50 #define MAX_BUTTON_NUM 3
51 #define MAX_DRAW_LEM 20
53 #define GROUP_DATA "data"
54 #define KEY_WAVFILE_PATH "wavfile_path"
55 #define KEY_SERVER_IP "server_ip"
56 #define KEY_DEVICE_NAME "device_name"
57 #define KEY_VOLUME1 "volume1"
58 #define KEY_VOLUME2 "volume2"
59 #define KEY_APP_NAME "app_name"
60 #define KEY_STREAM_NAME "stream_name"
62 /*============================================================================*/
63 /* Define data types */
64 /*============================================================================*/
75 Evas_Coord w; /* width */
76 Evas_Coord h; /* height */
81 char name[255]; /* font name */
82 Evas_Font_Size size; /* font size */
87 Evas_Coord x; /* X position */
88 Evas_Coord y; /* Y position */
91 struct object_text_val_t
93 struct color_val_t color;
94 struct size_val_t size;
95 struct font_val_t font;
101 struct object_figure_val_t
103 struct color_val_t color;
104 struct size_val_t size;
105 struct pos_val_t pos;
109 /*============================================================================*/
110 /* Function prototype for static(internal) functions */
111 /*============================================================================*/
112 static void _canvas_resize_cb(Ecore_Evas *ee);
113 static void _on_destroy(Ecore_Evas *ee __UNUSED__);
114 static Eina_Bool _timer_cb(void *data);
115 static void _on_mousedown1(void *data, Evas *evas, Evas_Object *o,
117 static void _on_mousedown2(void *data, Evas *evas, Evas_Object *o,
119 static void _on_mousedown3(void *data, Evas *evas, Evas_Object *o,
121 static int start_audio(void);
122 static Eina_Bool stop_audio(void *data, Ecore_Fd_Handler *fd_handler);
123 static void rcv_event(int event_num);
124 static void send_event_req(int event_num);
125 static void recv_event_res(int ret);
126 static void chg_state(int state_num);
127 static void conf_check_gerror(char *para_num, GError ** error);
128 static int read_config(void);
129 static void draw_text(Evas_Object *obj, struct object_text_val_t *text);
130 static void draw_figr(Evas_Object *obj, struct object_figure_val_t *figr);
132 /*============================================================================*/
133 /* Tables and Valiables */
134 /*============================================================================*/
135 extern int pulse_main(struct audio_config_t *, int);
138 static int StateNum = STATE_STOP;
139 static Evas_Object *State_text;
141 /* file descriptor */
142 static int Filedes[2];
143 static int Filedes2[2];
145 /* Child process ID */
146 static pid_t ChPid = 0;
149 static struct audio_config_t AudioConfig = {
150 NULL, NULL, NULL, -1, -1, NULL, NULL
153 static struct object_text_val_t ButtonText[MAX_BUTTON_NUM] = {
154 {{255, 0, 0, 255}, {180, 50}, {"Sans", 48}, {15 + 12, 70}, "START", NULL},
155 {{0, 255, 0, 255}, {180, 50}, {"Sans", 48}, {210 + 24, 70}, "STOP", NULL},
156 {{0, 0, 255, 255}, {180, 50}, {"Sans", 48}, {405 + 12, 70}, "PAUSE", NULL}
159 static struct object_figure_val_t ButtonFigr[MAX_BUTTON_NUM] = {
160 {{255, 0, 0, 100}, {180, 95}, {15, 120}, (void *) _on_mousedown1},
161 {{0, 255, 0, 100}, {180, 95}, {210, 120}, (void *) _on_mousedown2},
162 {{0, 0, 255, 100}, {180, 95}, {405, 120}, (void *) _on_mousedown3}
165 static struct object_figure_val_t BgFigr = {
166 {255, 255, 255, 255}, {WIDTH, HEIGHT}, {0, 0}, NULL
169 static struct object_text_val_t TimeText = {
170 {0, 0, 0, 255}, {150, 50}, {"Sans", 24}, {0, 0}, {}, (void *) _timer_cb
173 static struct object_text_val_t StateInfoText = {
174 {0, 0, 0, 255}, {150, 50}, {"Sans", 48}, {140, 300}, "STATE : STOP", NULL
177 static struct object_text_val_t AppNameText = {
178 {0, 0, 0, 255}, {150, 50}, {"Sans", 32}, {25, 440}, "App Name : ", NULL
181 static struct object_text_val_t StreamNameText = {
182 {0, 0, 0, 255}, {150, 50}, {"Sans", 32}, {25, 480}, "Stream Name : ",
186 static struct object_text_val_t PidText = {
187 {0, 0, 0, 255}, {150, 50}, {"Sans", 36}, {50, 530}, "PID : ", NULL
190 static Ecore_Evas *ee;
191 static Evas_Object *text, *bg;
192 static char ssndtype[32];
194 static const char commands[] =
196 "\tm - impose a minumum size to the window\n"
197 "\tx - impose a maximum size to the window\n"
198 "\tb - impose a base size to the window\n"
199 "\ts - impose a step size (different than 1 px) to the window\n"
200 "\th - print help\n";
203 /* to inform current window's size */
204 static void _canvas_resize_cb(Ecore_Evas *ee)
209 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
210 snprintf(buf, sizeof(buf), "%s %d x %d", ssndtype, w, h);
211 evas_object_text_text_set(text, buf);
212 evas_object_move(text, 50, 25);
213 evas_object_resize(bg, w, h);
216 static void _on_destroy(Ecore_Evas *ee __UNUSED__)
218 ecore_main_loop_quit();
221 static Eina_Bool _timer_cb(void *data)
227 date = localtime(&timer);
228 sprintf(str, "%s", asctime(date));
229 evas_object_text_text_set((Evas_Object *) data, str);
234 static void _on_mousedown1(void *data, Evas *evas, Evas_Object *o,
237 uim_debug("_on_mousedown1: Enter");
238 uim_debug("Input event : START");
240 rcv_event(START_REQ);
242 uim_debug("_on_mousedown1: Leave");
245 static void _on_mousedown2(void *data, Evas *evas, Evas_Object *o,
248 uim_debug("_on_mousedown2: Enter");
249 uim_debug("Input event : STOP");
253 uim_debug("_on_mousedown2: Leave");
256 static void _on_mousedown3(void *data, Evas *evas, Evas_Object *o,
259 uim_debug("_on_mousedown3: Enter");
260 uim_debug("Input event : PAUSE");
262 rcv_event(PAUSE_REQ);
264 uim_debug("_on_mousedown3: Leave");
267 static int start_audio(void)
269 uim_debug("start_audio: Enter");
273 signal(SIGCLD, SIG_IGN);
275 if ((ChPid = fork()) < 0) {
276 uim_debug("Err fork");
279 else if (ChPid == 0) {
280 /* Processing of child processes to start */
284 uim_debug("Voice response : START");
285 ret = pulse_main(&AudioConfig, Filedes[0]);
286 uim_debug("Voice response : END");
288 uim_debug("pulse_main: ret = [%d]", ret);
293 /* Termination of child processes */
297 /* Processing of parent process */
298 uim_debug("Child process: ChPid = [%d]", ChPid);
300 uim_debug("start_audio: Leave");
305 static Eina_Bool stop_audio(void *data, Ecore_Fd_Handler *fd_handler)
307 uim_debug("stop_audio: Enter");
310 memset(buff, 0x00, sizeof(buff));
312 /* Reading from a pipe */
313 read(Filedes2[0], buff, sizeof(buff));
314 uim_debug("buff :%s", buff);
316 if (atoi(buff) != 0) {
317 uim_debug("pulse_main Err: ret= [%d]", atoi(buff));
322 chg_state(STATE_STOP);
324 /* Process id initialization */
327 uim_debug("stop_audio: Leave");
329 return ECORE_CALLBACK_RENEW;
332 static void rcv_event(int event_num)
334 uim_debug("rcv_event: Enter");
343 send_event_req(event_num);
345 chg_state(STATE_STOP);
350 send_event_req(event_num);
352 chg_state(STATE_PAUSE);
356 uim_debug("Not receive: StateNum = [%d],event_num = [%d]",
357 StateNum, event_num);
366 /* Voice reproduction start */
370 chg_state(STATE_START);
373 uim_debug("start_audio Err: ret= [%d]", ret);
379 uim_debug("Not receive: StateNum = [%d],event_num = [%d]",
380 StateNum, event_num);
390 send_event_req(event_num);
392 chg_state(STATE_STOP);
397 send_event_req(event_num);
399 chg_state(STATE_START);
403 uim_debug("Not receive: StateNum = [%d],event_num = [%d]",
404 StateNum, event_num);
411 uim_debug("Not support StateNum: StateNum = [%d]", StateNum);
415 uim_debug("rcv_event: Leave");
418 static void send_event_req(int event_num)
420 uim_debug("send_event_req: Enter");
423 memset(msg, 0x00, sizeof(msg));
425 snprintf(msg, sizeof(msg), "%d", event_num);
426 uim_debug("msg = %s", msg);
428 write(Filedes[1], msg, strlen(msg) + 1);
429 uim_debug("send_event_req: Leave");
432 static void recv_event_res(int ret)
434 uim_debug("recv_event_res: Enter");
437 memset(msg, 0x00, sizeof(msg));
439 snprintf(msg, sizeof(msg), "%d", ret);
440 uim_debug("msg = %s", msg);
442 write(Filedes2[1], msg, strlen(msg) + 1);
443 uim_debug("recv_event_res: Leave");
446 static void chg_state(int state_num)
448 uim_debug("chg_state: Enter");
449 uim_debug("chg_state state_num = [%d]", state_num);
451 char buf[ICO_UXF_MAX_PROCESS_NAME + 1];
452 memset(buf, 0x00, sizeof(buf));
456 snprintf(buf, sizeof(buf), "%s", "STATE : START");
457 evas_object_text_text_set(State_text, buf);
458 StateNum = state_num;
462 snprintf(buf, sizeof(buf), "%s", "STATE : STOP");
463 evas_object_text_text_set(State_text, buf);
464 StateNum = state_num;
468 snprintf(buf, sizeof(buf), "%s", "STATE : PAUSE");
469 evas_object_text_text_set(State_text, buf);
470 StateNum = state_num;
474 uim_debug("Not support State: state_num = [%d]", state_num);
478 uim_debug("chg_state StateNum = [%d]", StateNum);
479 uim_debug("chg_state: Leave");
482 static void conf_check_gerror(char *para_num, GError ** error)
484 uim_debug("conf_check_gerror: Enter");
486 if (*error != NULL) {
487 uim_debug("Config [%s] : %s", para_num, (*error)->message);
489 g_clear_error(error);
491 uim_debug("conf_check_gerror: Leave");
494 static int read_config(void)
496 uim_debug("read_config: Enter");
500 GError *error = NULL;
502 keyfile = g_key_file_new();
503 flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
504 if (!g_key_file_load_from_file(keyfile, CONFIG_FILE, flags, &error)) {
505 conf_check_gerror(CONFIG_FILE, &error);
506 g_key_file_free(keyfile);
510 AudioConfig.wavfile_path = g_key_file_get_string(keyfile, GROUP_DATA,
513 if ((error) || (strlen(AudioConfig.wavfile_path) <= 0)) {
514 uim_debug("No config data [%s]", KEY_WAVFILE_PATH);
515 conf_check_gerror(KEY_WAVFILE_PATH, &error);
516 g_key_file_free(keyfile);
520 AudioConfig.server_ip = g_key_file_get_string(keyfile, GROUP_DATA,
521 KEY_SERVER_IP, &error);
522 if ((error) || (strlen(AudioConfig.server_ip) <= 0)) {
523 uim_debug("No config data [%s]", KEY_SERVER_IP);
524 conf_check_gerror(KEY_SERVER_IP, &error);
525 AudioConfig.server_ip = NULL;
528 AudioConfig.device_name = g_key_file_get_string(keyfile, GROUP_DATA,
529 KEY_DEVICE_NAME, &error);
530 if ((error) || (strlen(AudioConfig.device_name) <= 0)) {
531 uim_debug("No config data [%s]", KEY_DEVICE_NAME);
532 conf_check_gerror(KEY_DEVICE_NAME, &error);
533 AudioConfig.device_name = NULL;
536 AudioConfig.volume1 = g_key_file_get_integer(keyfile, GROUP_DATA,
537 KEY_VOLUME1, &error);
539 uim_debug("No config data [%s]", KEY_VOLUME1);
540 conf_check_gerror(KEY_VOLUME1, &error);
541 AudioConfig.volume1 = -1;
544 AudioConfig.volume2 = g_key_file_get_integer(keyfile, GROUP_DATA,
545 KEY_VOLUME2, &error);
547 uim_debug("No config data [%s]", KEY_VOLUME2);
548 conf_check_gerror(KEY_VOLUME2, &error);
549 AudioConfig.volume2 = -1;
552 AudioConfig.app_name = g_key_file_get_string(keyfile, GROUP_DATA,
553 KEY_APP_NAME, &error);
554 if ((error) || (strlen(AudioConfig.app_name) <= 0)) {
555 uim_debug("No config data [%s]", KEY_APP_NAME);
556 conf_check_gerror(KEY_APP_NAME, &error);
557 AudioConfig.app_name = "TP_PulseAudio";
560 AudioConfig.stream_name = g_key_file_get_string(keyfile, GROUP_DATA,
561 KEY_STREAM_NAME, &error);
562 if ((error) || (strlen(AudioConfig.stream_name) <= 0)) {
563 uim_debug("No config data [%s]", KEY_STREAM_NAME);
564 conf_check_gerror(KEY_DEVICE_NAME, &error);
565 AudioConfig.stream_name = "Pri0";
568 uim_debug("read_config: Leave");
572 static void draw_text(Evas_Object *obj, struct object_text_val_t *text)
574 uim_debug("draw_text: Enter");
576 evas_object_color_set(obj, text->color.r, text->color.g, text->color.b,
578 evas_object_resize(obj, text->size.w, text->size.h);
579 evas_object_text_font_set(obj, text->font.name, text->font.size);
580 evas_object_move(obj, text->pos.x, text->pos.y);
581 evas_object_show(obj);
582 evas_object_text_text_set(obj, text->text);
584 uim_debug("draw_text: Leave");
587 static void draw_figr(Evas_Object *obj, struct object_figure_val_t *figr)
589 uim_debug("draw_figr: Enter");
591 evas_object_color_set(obj, figr->color.r, figr->color.g, figr->color.b,
593 evas_object_resize(obj, figr->size.w, figr->size.h);
594 evas_object_move(obj, figr->pos.x, figr->pos.y);
595 evas_object_show(obj);
597 uim_debug("draw_figr: Leave");
600 static void res_callback(ico_apf_resource_notify_info_t *info,
606 ("##==> Callbacked! evt=%d res=%d id=%d bid=%d appid=%s dev=%s "
607 "user_data=%d", info->state, info->resid, info->id, info->bid,
608 info->appid, info->device, (int) user_data);
610 switch (info->state) {
611 case ICO_APF_RESOURCE_STATE_ACQUIRED:
612 case ICO_APF_RESOURCE_STATE_DEPRIVED:
613 case ICO_APF_RESOURCE_STATE_WAITTING:
614 case ICO_APF_RESOURCE_STATE_RELEASED:
615 if (info->resid == ICO_APF_RESID_INT_SOUND) {
617 ico_apf_resource_reply_int_sound_mode(info->device, info->id,
619 uim_debug("##==> callback reply int_sound(%s,%d,1) = %d",
620 info->device, info->id, ret);
624 ico_apf_resource_reply_sound_mode(info->device, info->id, 1);
625 uim_debug("##==> callback reply sound(%s,%d,1) = %d",
626 info->device, info->id, ret);
635 int main(int argc, char *argv[])
640 /* Log output setup */
641 if (ico_apf_get_app_id(0, appid) == ICO_APP_CTL_E_NONE) {
642 ico_apf_log_open(appid);
645 uim_debug("main: Enter");
648 Evas_Object *app_name_text;
649 Evas_Object *stream_name_text;
650 Evas_Object *pid_text;
651 Evas_Object *button_text[MAX_BUTTON_NUM];
652 Evas_Object *button_figr[MAX_BUTTON_NUM];
653 Evas_Object *time_text;
658 /* get resource control option */
661 for (i = 1; i < argc; i++) {
662 if (argv[i][0] == '-') {
663 if (strcasecmp(argv[i], "-basesound") == 0) {
664 getsound = 1; /* get base sound */
665 strcpy(ssndtype, "BasecSound");
667 else if (strcasecmp(argv[i], "-intsound") == 0) {
668 getsound = 2; /* get interrupt sound */
669 strcpy(ssndtype, "IntSound");
671 else if (strncasecmp(argv[i], "-int=", 5) == 0) {
672 getsound = strtol(&argv[i][5], (char **) 0, 0);
673 getsound += 2; /* get interrupt sound */
674 sprintf(ssndtype, "IntSound.%d", getsound - 2);
679 StateNum = STATE_STOP;
681 memset(buf, 0x00, sizeof(buf));
682 memset(buf2, 0x00, sizeof(buf));
684 if (pipe(Filedes) == -1) {
685 uim_debug("Err pipe Filedes");
689 if (pipe(Filedes2) == -1) {
690 uim_debug("Err pipe Filedes2");
694 if (read_config() == -1) {
695 uim_debug("Err Config Read NG");
699 uim_debug("AudioConfig.wavfile_path = [%s]", AudioConfig.wavfile_path);
700 uim_debug("AudioConfig.server_ip = [%s]", AudioConfig.server_ip);
701 uim_debug("AudioConfig.device_name = [%s]", AudioConfig.device_name);
702 uim_debug("AudioConfig.volume1 = [%d]", AudioConfig.volume1);
703 uim_debug("AudioConfig.volume2 = [%d]", AudioConfig.volume2);
704 uim_debug("AudioConfig.app_name = [%s]", AudioConfig.app_name);
705 uim_debug("AudioConfig.stream_name = [%s]", AudioConfig.stream_name);
707 if (!ecore_evas_init()) {
712 /* initialize resource control for Ecore */
713 if (ico_apf_ecore_init(NULL) != ICO_APF_E_NONE) {
714 uim_debug("ico_apf_ecore_init() Error");
715 ecore_evas_shutdown();
719 /* set resource request callback */
720 ico_apf_resource_set_event_cb(res_callback, NULL);
722 /* acquire a right to display a screen */
724 ico_apf_resource_get_sound_mode(NULL, 0, 0);
727 ico_apf_resource_get_int_sound_mode(NULL, getsound - 2, 0);
731 /* this will give you a window with an Evas canvas under the first
732 * engine available */
733 ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, "frame=0");
738 ecore_evas_callback_delete_request_set(ee, _on_destroy);
739 ecore_evas_title_set(ee, "Ecore_Evas window sizes example");
740 ecore_evas_callback_resize_set(ee, _canvas_resize_cb);
743 evas = ecore_evas_get(ee);
745 /* Background painting */
746 bg = evas_object_rectangle_add(evas);
747 draw_figr(bg, &BgFigr);
749 evas_object_focus_set(bg, EINA_TRUE);
751 /* App Name drawing */
752 app_name_text = evas_object_text_add(evas);
753 draw_text(app_name_text, &AppNameText);
755 if (strlen(AudioConfig.app_name) > MAX_DRAW_LEM) {
756 snprintf(buf2, MAX_DRAW_LEM, "%s", AudioConfig.app_name);
757 snprintf(buf, sizeof(buf), "%s%s...", "App name : ", buf2);
760 snprintf(buf, sizeof(buf), "%s%s", "App name : ",
761 AudioConfig.app_name);
764 evas_object_text_text_set(app_name_text, buf);
767 text = evas_object_text_add(evas);
768 evas_object_color_set(text, 255, 0, 0, 255);
769 evas_object_resize(text, 150, 50);
770 evas_object_text_font_set(text, "Sans", 20);
771 evas_object_show(text);
773 /* Stream Name drawing */
774 stream_name_text = evas_object_text_add(evas);
775 draw_text(stream_name_text, &StreamNameText);
777 if (strlen(AudioConfig.stream_name) > MAX_DRAW_LEM) {
778 snprintf(buf2, MAX_DRAW_LEM, "%s", AudioConfig.stream_name);
779 snprintf(buf, sizeof(buf), "%s%s...", "Stream name : ", buf2);
782 snprintf(buf, sizeof(buf), "%s%s", "Stream name : ",
783 AudioConfig.stream_name);
786 evas_object_text_text_set(stream_name_text, buf);
789 pid_text = evas_object_text_add(evas);
790 draw_text(pid_text, &PidText);
791 snprintf(buf, sizeof(buf), "%s%d", "PID : ", getpid());
792 evas_object_text_text_set(pid_text, buf);
794 /* Sound condition drawing */
795 State_text = evas_object_text_add(evas);
796 draw_text(State_text, &StateInfoText);
798 /** Button drawing */
799 for (i = 0; i < MAX_BUTTON_NUM; i++) {
800 /* Button name drawing */
801 button_text[i] = evas_object_text_add(evas);
802 draw_text(button_text[i], &ButtonText[i]);
804 /* Button Frame drawing */
805 button_figr[i] = evas_object_rectangle_add(evas);
806 draw_figr(button_figr[i], &ButtonFigr[i]);
808 /* Callback function entry */
809 evas_object_event_callback_add(button_figr[i],
810 EVAS_CALLBACK_MOUSE_DOWN,
811 (Evas_Object_Event_Cb) (ButtonFigr[i].
816 /* Drawing of the current time */
817 time_text = evas_object_text_add(evas);
818 draw_text(time_text, &TimeText);
820 /* Timer callback function entry */
821 ecore_timer_add(0.1, (Ecore_Task_Cb) (TimeText.func), time_text);
823 /* File descriptor to monitor callback function entry */
824 ecore_main_fd_handler_add(Filedes2[0], ECORE_FD_READ, stop_audio, NULL,
827 _canvas_resize_cb(ee);
828 fprintf(stdout, commands);
829 ecore_main_loop_begin();
831 ico_apf_ecore_term();
834 ecore_evas_shutdown();
842 if ((ChPid > 0) && (kill(ChPid, 0) != EOF)) {
843 kill(ChPid, SIGKILL);
844 uim_debug("END Process ChPid = [%d]", ChPid);
846 uim_debug("main: Leave");
852 "You got to have at least one Evas engine built and linked up"
853 " to ecore-evas for this example to run properly.\n");
854 ecore_evas_shutdown();