Fix the prevent issue
[platform/core/uifw/tts.git] / server / ttsd_player.cpp
1 /*
2 *  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
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 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14
15 #include <mm_types.h>
16 #include <mm_player.h>
17 #include <mm_error.h>
18 #include <Ecore.h>
19
20 #include "ttsd_main.h"
21 #include "ttsd_player.h"
22 #include "ttsd_data.h"
23 #include "ttsd_dbus.h"
24
25
26 /*
27 * Internal data structure
28 */
29
30 #define TEMP_FILE_MAX   36
31
32 typedef struct {
33         char    riff[4];
34         int     file_size;
35         char    wave[4];
36         char    fmt[4];
37         int     header_size;
38         short   sample_format;
39         short   n_channels;
40         int     sample_rate;
41         int     bytes_per_second;
42         short   block_align;
43         short   bits_per_sample;
44         char    data[4];
45         int     data_size;
46 } WavHeader;
47
48 typedef struct {
49         int             uid;            /** client id */
50         MMHandleType    player_handle;  /** mm player handle */
51         int             utt_id;         /** utt_id of next file */
52         ttsp_result_event_e event;      /** event of callback */
53 } player_s;
54
55 typedef struct {
56         int  uid;
57         int  utt_id;
58         ttsp_result_event_e event;
59         char filename[TEMP_FILE_MAX];
60 } user_data_s;
61
62
63 /*
64 * static data
65 */
66
67 #define TEMP_FILE_PATH  "/tmp"
68 #define FILE_PATH_SIZE  256
69
70 /** player init info */
71 static bool g_player_init = false;
72
73 /** tts engine list */
74 static GList *g_player_list;
75
76 /** current player information */
77 static player_s* g_playing_info;
78
79 /** player callback function */
80 static player_result_callback_func g_result_callback;
81
82 /** numbering for temp file */
83 static unsigned int g_index;              
84
85
86 /*
87 * Internal Interfaces 
88 */
89
90 player_s* __player_get_item(int uid);
91
92 int __save_file(const int uid, const int index, const sound_data_s data, char** filename);
93
94 int __set_and_start(player_s* player);
95
96 int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
97
98 static int msg_callback(int message, void *data, void *user_param) ;
99
100
101 /*
102 * Player Interfaces 
103 */
104
105 int ttsd_player_init(player_result_callback_func result_cb)
106 {
107         if (NULL == result_cb) {
108                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] invalid parameter");
109                 return TTSD_ERROR_INVALID_PARAMETER;
110         }
111
112         g_result_callback = result_cb;
113
114         g_playing_info = NULL;
115         
116         g_index = 1;
117         g_player_init = true;
118
119         return 0;
120 }
121
122 int ttsd_player_release(void)
123 {
124         if (false == g_player_init) {
125                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized");
126                 return TTSD_ERROR_OPERATION_FAILED;
127         }
128
129         /* clear g_player_list */
130         g_playing_info = NULL;
131         g_player_init = false;
132
133         return 0;
134 }
135
136 int ttsd_player_create_instance(const int uid)
137 {
138         if (false == g_player_init) {
139                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
140                 return -1;
141         }
142         
143         /* Check uid is duplicated */
144         if (NULL != __player_get_item(uid)) {
145                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is already registered", uid); 
146                 return -1;
147         }
148
149         int ret = MM_ERROR_NONE; 
150         MMHandleType player_handle;
151         
152         ret = mm_player_create(&player_handle);
153         if (ret != MM_ERROR_NONE || 0 == player_handle) {
154                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_create() : %x", ret);
155                 return -2;
156         }
157
158         player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
159
160         new_client->uid = uid;
161         new_client->player_handle = player_handle;
162         new_client->utt_id = -1;
163         new_client->event = TTSP_RESULT_EVENT_FINISH;
164         
165         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
166
167         g_player_list = g_list_append(g_player_list, new_client);
168
169         return 0;
170 }
171
172
173 int ttsd_player_destroy_instance(int uid)
174 {
175         if (false == g_player_init) {
176                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
177                 return -1;
178         }
179
180         player_s* current;
181         current = __player_get_item(uid);
182         if (NULL == current) {
183                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
184                 return -1;
185         }
186
187         if (NULL != g_playing_info) {
188                 if (uid == g_playing_info->uid) {
189                         g_playing_info = NULL;
190                 }
191         }
192
193         MMPlayerStateType player_state;
194         mm_player_get_state(current->player_handle, &player_state);
195
196         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
197
198         int ret = -1;
199         /* destroy player */
200         switch (player_state) {
201                 case MM_PLAYER_STATE_PLAYING:
202                 case MM_PLAYER_STATE_PAUSED:
203                 case MM_PLAYER_STATE_READY:
204                         ret = mm_player_unrealize(current->player_handle);
205                         if (MM_ERROR_NONE != ret) {
206                                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
207                         } 
208                         /* NO break for destroy */
209
210                 case MM_PLAYER_STATE_NULL:
211                         ret = mm_player_destroy(current->player_handle);
212                         if (MM_ERROR_NONE != ret) {
213                                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_destroy() : %x", ret);
214                         } 
215                         break;
216
217                 default:
218                         break;
219         }
220                 
221         GList *iter = NULL;
222         player_s *data = NULL;
223
224         if (0 < g_list_length(g_player_list)) {
225                 /* Get a first item */
226                 iter = g_list_first(g_player_list);
227
228                 while (NULL != iter) {
229                         /* Get handle data from list */
230                         data = (player_s*)iter->data;
231
232                         if (NULL != data) {
233                                 /* compare uid */
234                                 if (uid == data->uid) {
235                                         g_player_list = g_list_remove_link(g_player_list, iter);                                
236                                         g_free(data);
237                                         break;
238                                 }
239                         }
240                                 
241                         /* Get next item */
242                         iter = g_list_next(iter);
243                 }
244         }
245
246         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER Success] Destroy instance");
247
248         return 0;
249 }
250
251 int ttsd_player_play(const int uid)
252 {
253         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] start play : uid(%d)", uid );
254
255         if (false == g_player_init) {
256                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
257                 return -1;
258         }
259
260         if (NULL != g_playing_info) {
261                 if (uid == g_playing_info->uid) {
262                         SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] uid(%d) has already played", g_playing_info->uid); 
263                         return 0;
264                 }
265         }
266
267         /* Check sound queue size */
268         if (0 == ttsd_data_get_sound_data_size(uid)) {
269                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", uid); 
270                 return -1;
271         }
272
273         /* Check uid */
274         player_s* current;
275         current = __player_get_item(uid);
276         if (NULL == current) {
277                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
278                 return -1;
279         }
280
281         MMPlayerStateType player_state;
282         mm_player_get_state(current->player_handle, &player_state);
283
284         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
285
286         switch (player_state) {
287                 case MM_PLAYER_STATE_PLAYING:
288                         SLOG(LOG_WARN, TAG_TTSD, "[Player] Current player is playing. Do not start new sound.");
289                         return 0;
290
291                 case MM_PLAYER_STATE_PAUSED:
292                         SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is paused. Do not start new sound.");
293                         return -1;
294
295                 case MM_PLAYER_STATE_READY:
296                         SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is ready for next play. Do not start new sound.");
297                         return -1;
298
299                 case MM_PLAYER_STATE_NULL:
300                         break;
301
302                 case MM_PLAYER_STATE_NONE:
303                         SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is created. Do not start new sound.");
304                         return -1;
305
306                 default:
307                         return -1;
308         }
309
310         int ret;
311         ret = __set_and_start(current);
312         if (0 != ret) {
313                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to set or start mm_player");
314         }
315
316         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Started play and wait for played callback : uid(%d)", uid);
317
318         return 0;
319 }
320
321 int ttsd_player_next_play(int uid)
322 {
323         if (false == g_player_init) {
324                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
325                 return -1;
326         }
327
328         /* Check uid */
329         player_s* current;
330         current = __player_get_item(uid);
331         if (NULL == current) {
332                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
333                 g_playing_info = NULL;
334                 return -1;
335         }
336
337         if (NULL != g_playing_info) {
338                 if (uid != g_playing_info->uid) {
339                         SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid); 
340                         return 0;
341                 }
342         } else {
343                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player do NOT exist"); 
344                 return -1;
345         }
346
347         MMPlayerStateType player_state;
348         mm_player_get_state(current->player_handle, &player_state);
349
350         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
351
352         int ret = -1;
353         /* stop player */
354         switch (player_state) {
355                 case MM_PLAYER_STATE_PLAYING:
356                 case MM_PLAYER_STATE_PAUSED:
357                 case MM_PLAYER_STATE_READY:
358                         ret = mm_player_unrealize(current->player_handle);
359                         if (MM_ERROR_NONE != ret) {
360                                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
361                                 return -1;
362                         } 
363                         break;
364
365                 case MM_PLAYER_STATE_NULL:
366                         break;
367
368                 default:
369                         break;
370         }
371
372         /* Check sound queue size */
373         if (0 == ttsd_data_get_sound_data_size(uid)) {
374                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", uid); 
375                 g_playing_info = NULL;
376                 return -1;
377         }
378
379         ret = __set_and_start(current);
380         if (0 != ret) {
381                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to set or start mm_player");
382         }
383
384         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Started play and wait for played callback : uid(%d)", uid);
385
386         return 0;
387 }
388
389
390 int ttsd_player_stop(const int uid)
391 {
392         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] stop player : uid(%d)", uid );
393
394         if (false == g_player_init) {
395                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
396                 return -1;
397         }
398
399         /* Check uid */
400         player_s* current;
401         current = __player_get_item(uid);
402         if (NULL == current) {
403                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
404                 return -1;
405         }
406
407         /* check whether uid is current playing or not */
408         if (NULL != g_playing_info) {
409                 if (uid == g_playing_info->uid) {
410                         /* release current playing info */
411                         g_playing_info = NULL;
412                 }
413         } else {
414                 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] No current playing"); 
415         }
416
417         current->utt_id = -1;
418
419         MMPlayerStateType player_state;
420         mm_player_get_state(current->player_handle, &player_state);
421
422         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
423
424         int ret = -1;
425         switch (player_state) {
426                 case MM_PLAYER_STATE_PLAYING:
427                 case MM_PLAYER_STATE_PAUSED:
428                 case MM_PLAYER_STATE_READY:
429                         ret = mm_player_unrealize(current->player_handle);
430                         if (MM_ERROR_NONE != ret) {
431                                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
432                                 return -1;
433                         } 
434                         break;
435
436                 case MM_PLAYER_STATE_NULL:
437                         break;
438                 
439                 default:
440                         break;
441         }
442
443         SLOG(LOG_DEBUG, TAG_TTSD, "[Player SUCCESS] Stop player : uid(%d)", uid);
444
445         return 0;
446 }
447
448 int ttsd_player_pause(const int uid)
449 {
450         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] pause player : uid(%d)", uid );
451
452         if (false == g_player_init) {
453                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
454                 return -1;
455         }
456
457         /* Check uid */
458         player_s* current;
459         current = __player_get_item(uid);
460         if (NULL == current) {
461                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid); 
462                 return -1;
463         }
464
465         /* check whether uid is current playing or not */
466         if (NULL != g_playing_info) {
467                 if (uid == g_playing_info->uid) {
468                         /* release current playing info */
469                         g_playing_info = NULL;
470                 } else {
471                         /* error case */
472                 }
473         }
474
475         MMPlayerStateType player_state;
476         mm_player_get_state(current->player_handle, &player_state);
477
478         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
479
480         int ret = 0;
481         if (MM_PLAYER_STATE_PLAYING == player_state) {
482                 ret = mm_player_pause(current->player_handle);
483                 if (MM_ERROR_NONE != ret) {
484                         SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_pause : %x ", ret);
485                 }
486         } else {
487                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player is NOT 'playing'");
488         }
489         
490
491         return 0;
492 }
493
494 int ttsd_player_resume(const int uid)
495 {
496         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Resume player : uid(%d)", uid );
497
498         if (false == g_player_init) {
499                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
500                 return -1;
501         }
502
503         /* Check id */
504         player_s* current;
505         current = __player_get_item(uid);
506         if (NULL == current) {
507                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
508                 return -1;
509         }
510
511         /* check current player */
512         if (NULL != g_playing_info) 
513                 g_playing_info = NULL;
514
515         
516         MMPlayerStateType player_state;
517         mm_player_get_state(current->player_handle, &player_state);
518
519         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
520
521         int ret = -1;
522         if (MM_PLAYER_STATE_PAUSED == player_state) {
523                 ret = mm_player_resume(current->player_handle);
524                 if (MM_ERROR_NONE != ret) {
525                         SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_resume() : %d", ret);
526                         return -1;
527                 } else {
528                         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Resume player");
529                 }
530
531                 g_playing_info = current;
532         } else {
533                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current uid is NOT paused state.");
534         }
535
536         return 0;
537 }
538
539 int ttsd_player_get_current_client()
540 {
541         if (false == g_player_init) {
542                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
543                 return -1;
544         }
545
546         if (NULL != g_playing_info) 
547                 return g_playing_info->uid;
548
549         SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] No current player"); 
550
551         return 0;
552 }
553
554 int ttsd_player_get_current_utterance_id(const int uid)
555 {
556         SLOG(LOG_DEBUG, TAG_TTSD, "[Player] get current utt id : uid(%d)", uid );
557
558         if (false == g_player_init) {
559                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
560                 return -1;
561         }
562
563         /* Check uid */
564         player_s* current;
565         current = __player_get_item(uid);
566         if (NULL == current) {
567                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid); 
568                 return -1;
569         }
570
571         return current->utt_id;
572 }
573
574 int ttsd_player_all_stop()
575 {
576         if (false == g_player_init) {
577                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
578                 return -1;
579         }
580
581         g_playing_info = NULL;
582
583         int ret = -1;
584         GList *iter = NULL;
585         player_s *data = NULL;
586
587         if (0 < g_list_length(g_player_list)) {
588                 /* Get a first item */
589                 iter = g_list_first(g_player_list);
590
591                 while (NULL != iter) {
592                         /* Get handle data from list */
593                         data = (player_s*)iter->data;
594
595                         app_state_e state;
596                         if (0 > ttsd_data_get_client_state(data->uid, &state)) {
597                                 SLOG(LOG_ERROR, TAG_TTSD, "[player ERROR] ttsd_player_all_stop : uid is not valid ");
598                                 ttsd_player_destroy_instance(data->uid);
599                                 iter = g_list_next(iter);
600                                 continue;
601                         }
602
603                         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
604                                 /* unrealize player */
605                                 ret = mm_player_unrealize(data->player_handle);
606                                 if (MM_ERROR_NONE != ret) {
607                                         SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
608                                 } 
609
610                                 data->utt_id = -1;
611                                 data->event = TTSP_RESULT_EVENT_FINISH;
612                         }
613                         
614                         /* Get next item */
615                         iter = g_list_next(iter);
616                 }
617         }
618
619         SLOG(LOG_DEBUG, TAG_TTSD, "[Player SUCCESS] player all stop!! ");
620
621         return 0;
622 }
623
624 static Eina_Bool __player_next_play(void *data)
625 {
626         SLOG(LOG_DEBUG, TAG_TTSD, "===== PLAYER NEXT PLAY");
627
628         int* uid = (int*)data;
629
630         if (NULL == uid) {
631                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid is NULL");
632                 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
633                 SLOG(LOG_DEBUG, TAG_TTSD, "  ");
634                 return EINA_FALSE;
635         }
636
637         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid = %d", *uid);
638         
639         if (0 != ttsd_player_next_play(*uid)) {
640                 SLOG(LOG_WARN, TAG_TTSD, "[PLAYER WARNING] Fail to play next");
641         }
642
643         free(uid);
644
645         SLOG(LOG_DEBUG, TAG_TTSD, "=====");
646         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
647
648         return EINA_FALSE;
649 }
650
651 static int msg_callback(int message, void *data, void *user_param) 
652 {
653         user_data_s* user_data;
654
655         user_data = (user_data_s*)user_param;
656
657         int uid = user_data->uid;
658         int utt_id = user_data->utt_id;
659
660         MMMessageParamType *msg = (MMMessageParamType*)data;
661
662         switch (message) {
663         case MM_MESSAGE_ERROR:
664                 {
665                         SLOG(LOG_DEBUG, TAG_TTSD, "===== PLAYER ERROR CALLBACK");
666                         SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
667
668                         /* send error info */
669                         g_result_callback(PLAYER_ERROR, uid, utt_id);
670
671                         player_s* current;
672                         current = __player_get_item(uid);
673                         if (NULL == current) {
674                                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid(%d) is NOT valid ", uid); 
675                         } else {
676                                 current->event = TTSP_RESULT_EVENT_FINISH;
677                         }
678
679                         if (NULL != user_data) 
680                                 g_free(user_data);
681
682                         /* check current player */
683                         if (NULL != g_playing_info) {
684                                 if (uid == g_playing_info->uid) {
685                                         g_playing_info = NULL;
686                                         SLOG(LOG_WARN, TAG_TTSD, "[PLAYER] Current Player is NOT uid(%d)", uid);
687                                 }
688                         }
689
690                         SLOG(LOG_DEBUG, TAG_TTSD, "=====");
691                         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
692                 }
693                 break;  /*MM_MESSAGE_ERROR*/
694
695         case MM_MESSAGE_BEGIN_OF_STREAM:
696                 {
697                         SLOG(LOG_DEBUG, TAG_TTSD, "===== BEGIN OF STREAM CALLBACK");
698
699                         /* Check uid */
700                         player_s* current;
701                         current = __player_get_item(uid);
702                         if (NULL == current) {
703                                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER] uid(%d) is NOT valid ", uid);
704                                 return -1;
705                         }
706
707                         if (TTSP_RESULT_EVENT_START == user_data->event ||
708                             (TTSP_RESULT_EVENT_FINISH == current->event && TTSP_RESULT_EVENT_FINISH == user_data->event)) {
709                                 int pid;
710                                 pid = ttsd_data_get_pid(uid);
711
712                                 /* send utterance start message */
713                                 if (0 == ttsdc_send_utt_start_message(pid, uid, utt_id)) {
714                                         SLOG(LOG_DEBUG, TAG_TTSD, "[Send SUCCESS] Send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
715                                 } else 
716                                         SLOG(LOG_ERROR, TAG_TTSD, "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
717                         } else {
718                                 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Don't need to send Utterance Start Signal");
719                         }
720
721                         /* set current playing info */
722                         current->utt_id = utt_id;
723                         current->event = user_data->event;
724                         g_playing_info = current;
725
726                         app_state_e state;
727                         if (0 != ttsd_data_get_client_state(uid, &state)) {
728                                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid is not valid : %d", uid);
729                                 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
730                                 SLOG(LOG_DEBUG, TAG_TTSD, "  ");
731                                 break;
732                         }
733
734                         /* for sync problem */
735                         if (APP_STATE_PAUSED == state) {
736                                 MMPlayerStateType player_state;
737                                 mm_player_get_state(current->player_handle, &player_state);
738
739                                 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
740
741                                 int ret = 0;
742                                 if (MM_PLAYER_STATE_PLAYING == player_state) {
743                                         ret = mm_player_pause(current->player_handle);
744                                         if (MM_ERROR_NONE != ret) {
745                                                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] fail mm_player_pause() : %x", ret);
746                                         } else {
747                                                 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid(%d) changes 'Pause' state ", uid);
748                                         }
749                                 }
750                         }
751
752                         SLOG(LOG_DEBUG, TAG_TTSD, "=====");
753                         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
754                 }
755                 break;
756
757         case MM_MESSAGE_END_OF_STREAM:
758                 {
759                         SLOG(LOG_DEBUG, TAG_TTSD, "===== END OF STREAM CALLBACK");
760
761                         if (NULL == user_data) 
762                                 break;
763
764                         remove(user_data->filename);
765
766                         /* Check uid */
767                         player_s* current;
768                         current = __player_get_item(uid);
769                         if (NULL == current) {
770                                 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid(%d) is NOT valid", uid); 
771                                 if (NULL != g_playing_info) {
772                                         if (uid == g_playing_info->uid) {
773                                                 g_playing_info = NULL;
774                                                 SLOG(LOG_WARN, TAG_TTSD, "[PLAYER] Current Player is NOT uid(%d)", uid);
775                                         }
776                                 }
777                                 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
778                                 SLOG(LOG_DEBUG, TAG_TTSD, "  ");
779                                 return -1;
780                         }
781
782                         g_free(user_data);
783
784                         int pid = ttsd_data_get_pid(uid);
785
786                         /* send utterence finish signal */
787                         if (TTSP_RESULT_EVENT_FINISH == current->event) {
788                                 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
789                                         SLOG(LOG_DEBUG, TAG_TTSD, "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
790                                 else 
791                                         SLOG(LOG_ERROR, TAG_TTSD, "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
792                         }
793
794                         int* uid_data = (int*) g_malloc0(sizeof(int));
795                         *uid_data = uid;
796
797                         SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid = %d", *uid_data);
798
799                         ecore_timer_add(0, __player_next_play, (void*)uid_data);
800
801                         SLOG(LOG_DEBUG, TAG_TTSD, "=====");
802                         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
803                 }
804                 break;  /*MM_MESSAGE_END_OF_STREAM*/
805
806         case MM_MESSAGE_STATE_CHANGED:
807                 break;
808
809         case MM_MESSAGE_STATE_INTERRUPTED:
810                 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
811
812                         SLOG(LOG_DEBUG, TAG_TTSD, "===== INTERRUPTED CALLBACK");
813
814                         ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
815
816                         int pid = ttsd_data_get_pid(uid);
817                         /* send message to client about changing state */
818                         ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
819
820                         SLOG(LOG_DEBUG, TAG_TTSD, "=====");
821                         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
822                 }
823                 break;
824
825         default:
826                 break;
827         }
828
829         return TRUE;
830 }
831
832 player_s* __player_get_item(int uid)
833 {
834         GList *iter = NULL;
835         player_s *data = NULL;
836
837         if (0 < g_list_length(g_player_list)) {
838                 /* Get a first item */
839                 iter = g_list_first(g_player_list);
840
841                 while (NULL != iter) {
842                         /* Get handle data from list */
843                         data = (player_s*)iter->data;
844
845                         /* compare uid */
846                         if (uid == data->uid)   
847                                 return data;
848
849                         /* Get next item */
850                         iter = g_list_next(iter);
851                 }
852         }
853
854         return NULL;
855 }
856
857 int __save_file(const int uid, const int index, const sound_data_s data, char** filename)
858 {
859         char postfix[5];
860         memset(postfix, '\0', 5);
861
862         switch (data.audio_type) {
863         case TTSP_AUDIO_TYPE_RAW:
864         case TTSP_AUDIO_TYPE_WAV:
865                 strcpy(postfix, "wav");
866                 break;
867         case TTSP_AUDIO_TYPE_MP3:
868                 strcpy(postfix, "mp3");
869                 break;
870         case TTSP_AUDIO_TYPE_AMR:
871                 strcpy(postfix, "amr");
872                 break;
873         default:
874                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type); 
875                 return -1;
876         }
877
878         /* make filename to save */
879         char* temp;
880         temp = *filename;
881
882         snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix );
883
884         FILE* fp;
885         fp = fopen(temp, "wb");
886
887         if (fp == NULL) {
888                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] temp file open error");
889                 return -1;
890         }
891
892         if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
893                 WavHeader header;
894                 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
895                         fclose(fp);
896                         return -1;
897                 }
898
899                 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
900                         SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to write wav header to file");
901                         fclose(fp);
902                         return -1;
903                 }
904         }
905
906         int size = fwrite(data.data, data.data_size, 1,  fp);
907         if (size <= 0) {
908                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail to write date");
909                 fclose(fp);
910                 return -1;
911         } 
912
913         fclose(fp);
914         
915         SLOG(LOG_DEBUG, TAG_TTSD, " ");
916         SLOG(LOG_DEBUG, TAG_TTSD, "Filepath : %s ", temp);
917         SLOG(LOG_DEBUG, TAG_TTSD, "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
918
919         return 0;
920 }
921
922 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
923 {
924         if (hdr == NULL || nsamples <= 0 || sampling_rate <= 0 || channel <= 0) {
925                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] __init_wave_header : input parameter invalid");
926                 return TTSD_ERROR_INVALID_PARAMETER;
927         }
928
929         size_t bytesize = nsamples;
930
931         strncpy(hdr->riff, "RIFF", 4);
932         hdr->file_size = (int)(bytesize  + 36);
933         strncpy(hdr->wave, "WAVE", 4);
934         strncpy(hdr->fmt, "fmt ", 4);
935         hdr->header_size = 16;
936         hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
937         hdr->n_channels = channel;
938         hdr->sample_rate = (int)(sampling_rate);
939         hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
940         hdr->block_align =  sizeof(short);
941         hdr->bits_per_sample = sizeof(short)*8;
942         strncpy(hdr->data, "data", 4);
943         hdr->data_size = (int)bytesize;
944
945         return 0;
946 }
947
948 int __set_and_start(player_s* player)
949 {
950         /* get sound data */
951         sound_data_s wdata;
952         if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
953                 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", player->uid); 
954                 return -1;
955         }
956
957         g_index++;
958         if (10000 <= g_index)   {
959                 g_index = 1;
960         }
961
962         /* make sound file for mmplayer */
963         char* sound_file = NULL;
964         sound_file = (char*) g_malloc0( sizeof(char) * FILE_PATH_SIZE );
965
966         if (0 != __save_file(player->uid, g_index, wdata, &sound_file)) {
967                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to make sound file");
968                 return -1;
969         }
970         
971         user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
972         user_data->uid = player->uid;
973         user_data->utt_id = wdata.utt_id;
974         user_data->event = wdata.event;
975         memset(user_data->filename, 0, TEMP_FILE_MAX); 
976         strncpy( user_data->filename, sound_file, strlen(sound_file) );
977
978         SLOG(LOG_DEBUG, TAG_TTSD, "Info : uid(%d), utt(%d), filename(%s) , event(%d)", 
979                 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
980         SLOG(LOG_DEBUG, TAG_TTSD, " ");
981
982         int ret;
983         
984         /* set callback func */
985         ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
986         if (MM_ERROR_NONE != ret) {
987                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
988                 return -1;
989         }
990
991         /* set playing info to mm player */
992         char* err_attr_name = NULL;
993
994         if (0 != access(sound_file, R_OK)) {
995                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail to read sound file (%s)", sound_file);
996                 return -1;
997         }
998         
999         ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
1000                 "profile_uri", sound_file , strlen( sound_file ) + 1,
1001                 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
1002                 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
1003                 NULL );
1004
1005         if (MM_ERROR_NONE != ret) {
1006                 if (NULL != err_attr_name) {
1007                         SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
1008                 }
1009                 return -1;
1010         }
1011
1012         /* realize and start mm player */ 
1013         ret = mm_player_realize(player->player_handle);
1014         if (MM_ERROR_NONE != ret) {
1015                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_realize() : %x", ret);
1016                 return -2;
1017         }
1018
1019         ret = mm_player_start(player->player_handle);
1020         if (MM_ERROR_NONE != ret) {
1021                 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_start() : %x", ret);
1022
1023                 mm_player_unrealize(player->player_handle);
1024                 return -3;
1025         }
1026
1027         if( NULL != sound_file )        g_free(sound_file);
1028         if( NULL != wdata.data )        g_free(wdata.data);
1029
1030         return 0;
1031 }
1032
1033