2 * Copyright (c) 2012, 2013 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.
16 #include <mm_player.h>
17 #include <mm_player_internal.h>
18 #include <mm_session.h>
22 #include "ttsd_main.h"
23 #include "ttsd_player.h"
24 #include "ttsd_data.h"
25 #include "ttsd_dbus.h"
29 * Internal data structure
32 #define TEMP_FILE_MAX 36
45 short bits_per_sample;
51 int uid; /** client id */
52 MMHandleType player_handle; /** mm player handle */
53 int utt_id; /** utt_id of next file */
54 ttsp_result_event_e event; /** event of callback */
60 ttsp_result_event_e event;
61 char filename[TEMP_FILE_MAX];
69 #define TEMP_FILE_PATH "/tmp"
70 #define FILE_PATH_SIZE 256
71 #define DEFAULT_FILE_SIZE 10
73 /** player init info */
74 static bool g_player_init = false;
76 /** tts engine list */
77 static GList *g_player_list;
79 /** current player information */
80 static player_s* g_playing_info;
82 /** player callback function */
83 static player_result_callback_func g_result_callback;
85 /** numbering for temp file */
86 static unsigned int g_index;
88 /** For resume when the 'Paused' state of player after end of play */
89 static bool g_pause_info;
90 static int g_paused_uid;
96 player_s* __player_get_item(int uid);
98 int __save_file(int uid, int index, sound_data_s data, char** filename);
100 int __set_and_start(player_s* player);
102 int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
104 static int msg_callback(int message, void *data, void *user_param) ;
111 int ttsd_player_init(player_result_callback_func result_cb)
113 if (NULL == result_cb) {
114 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] invalid parameter");
115 return TTSD_ERROR_INVALID_PARAMETER;
118 g_result_callback = result_cb;
120 g_playing_info = NULL;
123 g_player_init = true;
125 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
126 if (MM_ERROR_NONE != mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)) {
127 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
129 SLOG(LOG_ERROR, get_tag(), "[Player SUCCESS] mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
136 int ttsd_player_release(void)
138 if (false == g_player_init) {
139 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized");
140 return TTSD_ERROR_OPERATION_FAILED;
143 /* clear g_player_list */
144 g_playing_info = NULL;
145 g_player_init = false;
150 int ttsd_player_create_instance(int uid)
152 if (false == g_player_init) {
153 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
157 /* Check uid is duplicated */
158 if (NULL != __player_get_item(uid)) {
159 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is already registered", uid);
163 int ret = MM_ERROR_NONE;
164 MMHandleType player_handle;
166 ret = mm_player_create(&player_handle);
167 if (ret != MM_ERROR_NONE || 0 == player_handle) {
168 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_create() : %x", ret);
172 player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
174 new_client->uid = uid;
175 new_client->player_handle = player_handle;
176 new_client->utt_id = -1;
177 new_client->event = TTSP_RESULT_EVENT_FINISH;
179 SLOG(LOG_DEBUG, get_tag(), "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
181 g_player_list = g_list_append(g_player_list, new_client);
186 int ttsd_player_destroy_instance(int uid)
188 if (false == g_player_init) {
189 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
194 current = __player_get_item(uid);
195 if (NULL == current) {
196 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
200 if (NULL != g_playing_info) {
201 if (uid == g_playing_info->uid) {
202 g_playing_info = NULL;
206 MMPlayerStateType player_state;
207 mm_player_get_state(current->player_handle, &player_state);
209 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
213 switch (player_state) {
214 case MM_PLAYER_STATE_PLAYING:
215 case MM_PLAYER_STATE_PAUSED:
216 case MM_PLAYER_STATE_READY:
217 ret = mm_player_unrealize(current->player_handle);
218 if (MM_ERROR_NONE != ret) {
219 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
221 /* NO break for destroy */
223 case MM_PLAYER_STATE_NULL:
224 ret = mm_player_destroy(current->player_handle);
225 if (MM_ERROR_NONE != ret) {
226 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_destroy() : %x", ret);
235 player_s *data = NULL;
237 if (0 < g_list_length(g_player_list)) {
238 /* Get a first item */
239 iter = g_list_first(g_player_list);
241 while (NULL != iter) {
242 /* Get handle data from list */
243 data = (player_s*)iter->data;
247 if (uid == data->uid) {
248 g_player_list = g_list_remove_link(g_player_list, iter);
255 iter = g_list_next(iter);
259 SLOG(LOG_DEBUG, get_tag(), "[PLAYER Success] Destroy instance");
264 int ttsd_player_play(int uid)
266 SLOG(LOG_DEBUG, get_tag(), "[Player] start play : uid(%d)", uid );
268 if (false == g_player_init) {
269 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
273 if (NULL != g_playing_info) {
274 if (uid == g_playing_info->uid) {
275 SLOG(LOG_WARN, get_tag(), "[Player WARNING] uid(%d) has already played", g_playing_info->uid);
280 /* Check sound queue size */
281 if (0 == ttsd_data_get_sound_data_size(uid)) {
282 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
288 current = __player_get_item(uid);
289 if (NULL == current) {
290 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
294 MMPlayerStateType player_state;
295 mm_player_get_state(current->player_handle, &player_state);
297 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
299 switch (player_state) {
300 case MM_PLAYER_STATE_PLAYING:
301 SLOG(LOG_WARN, get_tag(), "[Player] Current player is playing. Do not start new sound.");
304 case MM_PLAYER_STATE_PAUSED:
305 SLOG(LOG_WARN, get_tag(), "[Player] Player is paused. Do not start new sound.");
308 case MM_PLAYER_STATE_READY:
309 SLOG(LOG_WARN, get_tag(), "[Player] Player is ready for next play. Do not start new sound.");
312 case MM_PLAYER_STATE_NULL:
315 case MM_PLAYER_STATE_NONE:
316 SLOG(LOG_WARN, get_tag(), "[Player] Player is created. Do not start new sound.");
324 ret = __set_and_start(current);
326 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
329 SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
334 int ttsd_player_next_play(int uid)
336 if (false == g_player_init) {
337 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
343 current = __player_get_item(uid);
344 if (NULL == current) {
345 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
346 g_playing_info = NULL;
350 if (NULL != g_playing_info) {
351 if (uid != g_playing_info->uid) {
352 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
356 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player do NOT exist");
360 MMPlayerStateType player_state;
361 mm_player_get_state(current->player_handle, &player_state);
363 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
367 switch (player_state) {
368 case MM_PLAYER_STATE_PLAYING:
369 case MM_PLAYER_STATE_PAUSED:
370 case MM_PLAYER_STATE_READY:
371 ret = mm_player_unrealize(current->player_handle);
372 if (MM_ERROR_NONE != ret) {
373 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
378 case MM_PLAYER_STATE_NULL:
385 /* Check sound queue size */
386 if (0 == ttsd_data_get_sound_data_size(uid)) {
387 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
388 g_playing_info = NULL;
392 ret = __set_and_start(current);
394 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
397 SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
403 int ttsd_player_stop(int uid)
405 SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
407 if (false == g_player_init) {
408 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
414 current = __player_get_item(uid);
415 if (NULL == current) {
416 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
420 /* check whether uid is current playing or not */
421 if (NULL != g_playing_info) {
422 if (uid == g_playing_info->uid) {
423 /* release current playing info */
424 g_playing_info = NULL;
427 SLOG(LOG_DEBUG, get_tag(), "[Player] No current playing");
430 current->utt_id = -1;
432 MMPlayerStateType player_state;
433 mm_player_get_state(current->player_handle, &player_state);
435 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
438 switch (player_state) {
439 case MM_PLAYER_STATE_PLAYING:
440 case MM_PLAYER_STATE_PAUSED:
441 case MM_PLAYER_STATE_READY:
442 ret = mm_player_unrealize(current->player_handle);
443 if (MM_ERROR_NONE != ret) {
444 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
449 case MM_PLAYER_STATE_NULL:
456 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
461 int ttsd_player_pause(int uid)
463 SLOG(LOG_DEBUG, get_tag(), "[Player] pause player : uid(%d)", uid );
465 if (false == g_player_init) {
466 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
472 current = __player_get_item(uid);
473 if (NULL == current) {
474 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
478 /* check whether uid is current playing or not */
479 if (NULL != g_playing_info) {
480 if (uid == g_playing_info->uid) {
481 /* release current playing info */
482 g_playing_info = NULL;
488 MMPlayerStateType player_state;
489 mm_player_get_state(current->player_handle, &player_state);
491 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
494 if (MM_PLAYER_STATE_PLAYING == player_state) {
495 ret = mm_player_pause(current->player_handle);
496 if (MM_ERROR_NONE != ret) {
497 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_pause : %x ", ret);
500 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player is NOT 'playing'");
507 int ttsd_player_resume(int uid)
509 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player : uid(%d)", uid );
511 if (false == g_player_init) {
512 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
518 current = __player_get_item(uid);
519 if (NULL == current) {
520 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
524 /* check current player */
525 if (NULL != g_playing_info)
526 g_playing_info = NULL;
529 MMPlayerStateType player_state;
530 mm_player_get_state(current->player_handle, &player_state);
532 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
535 if (MM_PLAYER_STATE_PAUSED == player_state) {
536 /* When the 'Paused' state of player after end of play */
537 if (g_pause_info == true && g_paused_uid == uid) {
538 g_playing_info = current;
540 g_pause_info = false;
543 /* Current state need load and play */
544 ret = ttsd_player_next_play(uid);
546 SLOG(LOG_ERROR, get_tag(), "[player] Fail to next play in resume function");
549 ret = mm_player_resume(current->player_handle);
550 if (MM_ERROR_NONE != ret) {
551 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_resume() : %d", ret);
554 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player");
557 g_playing_info = current;
560 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current uid is NOT paused state.");
566 int ttsd_player_get_state(int uid, ttsd_player_state_e* state)
568 if (false == g_player_init) {
569 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
574 current = __player_get_item(uid);
575 if (NULL == current) {
576 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
580 MMPlayerStateType player_state;
581 mm_player_get_state(current->player_handle, &player_state);
583 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
587 switch (player_state) {
588 case MM_PLAYER_STATE_PLAYING:
589 *state = TTSD_PLAYER_STATE_PLAYING;
591 case MM_PLAYER_STATE_PAUSED:
592 *state = TTSD_PLAYER_STATE_PAUSED;
595 case MM_PLAYER_STATE_NULL:
596 *state = TTSD_PLAYER_STATE_NULL;
599 case MM_PLAYER_STATE_READY:
601 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid);
609 int ttsd_player_get_current_client()
611 if (false == g_player_init) {
612 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
616 if (NULL != g_playing_info)
617 return g_playing_info->uid;
619 SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
624 int ttsd_player_get_current_utterance_id(int uid)
626 SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
628 if (false == g_player_init) {
629 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
635 current = __player_get_item(uid);
636 if (NULL == current) {
637 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
641 return current->utt_id;
644 int ttsd_player_all_stop()
646 if (false == g_player_init) {
647 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
651 g_playing_info = NULL;
655 player_s *data = NULL;
657 if (0 < g_list_length(g_player_list)) {
658 /* Get a first item */
659 iter = g_list_first(g_player_list);
661 while (NULL != iter) {
662 /* Get handle data from list */
663 data = (player_s*)iter->data;
666 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
667 SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
668 ttsd_player_destroy_instance(data->uid);
669 iter = g_list_next(iter);
673 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
674 /* unrealize player */
675 ret = mm_player_unrealize(data->player_handle);
676 if (MM_ERROR_NONE != ret) {
677 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
681 data->event = TTSP_RESULT_EVENT_FINISH;
685 iter = g_list_next(iter);
689 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
694 static Eina_Bool __player_next_play(void *data)
696 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
698 int* uid = (int*)data;
701 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
702 SLOG(LOG_DEBUG, get_tag(), "=====");
703 SLOG(LOG_DEBUG, get_tag(), " ");
707 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
709 if (0 != ttsd_player_next_play(*uid)) {
710 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
715 SLOG(LOG_DEBUG, get_tag(), "=====");
716 SLOG(LOG_DEBUG, get_tag(), " ");
721 static int msg_callback(int message, void *data, void *user_param)
723 user_data_s* user_data = NULL;
725 user_data = (user_data_s*)user_param;
727 if (NULL == user_data) {
728 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
732 int uid = user_data->uid;
733 int utt_id = user_data->utt_id;
735 MMMessageParamType *msg = (MMMessageParamType*)data;
738 case MM_MESSAGE_ERROR:
740 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
741 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
743 /* send error info */
744 g_result_callback(PLAYER_ERROR, uid, utt_id);
747 current = __player_get_item(uid);
748 if (NULL == current) {
749 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
751 current->event = TTSP_RESULT_EVENT_FINISH;
754 if (NULL != user_data)
757 /* check current player */
758 if (NULL != g_playing_info) {
759 if (uid == g_playing_info->uid) {
760 g_playing_info = NULL;
761 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
765 SLOG(LOG_DEBUG, get_tag(), "=====");
766 SLOG(LOG_DEBUG, get_tag(), " ");
768 break; /*MM_MESSAGE_ERROR*/
770 case MM_MESSAGE_BEGIN_OF_STREAM:
774 case MM_MESSAGE_END_OF_STREAM:
776 SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
778 if (-1 == remove(user_data->filename)) {
779 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
784 current = __player_get_item(uid);
785 if (NULL == current) {
786 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
787 if (NULL != g_playing_info) {
788 if (uid == g_playing_info->uid) {
789 g_playing_info = NULL;
790 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
793 SLOG(LOG_DEBUG, get_tag(), "=====");
794 SLOG(LOG_DEBUG, get_tag(), " ");
800 int pid = ttsd_data_get_pid(uid);
802 /* send utterence finish signal */
803 if (TTSP_RESULT_EVENT_FINISH == current->event) {
804 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
805 SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
807 SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
810 /* for sync problem */
811 MMPlayerStateType player_state;
812 mm_player_get_state(current->player_handle, &player_state);
814 if (MM_PLAYER_STATE_PAUSED == player_state) {
815 g_pause_info = true; /* The current state of player is 'Paused' */
816 g_paused_uid = uid; /* The current uid when the current state player is 'Paused' */
819 int* uid_data = (int*) g_malloc0(sizeof(int));
822 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
824 ecore_timer_add(0, __player_next_play, (void*)uid_data);
827 SLOG(LOG_DEBUG, get_tag(), "=====");
828 SLOG(LOG_DEBUG, get_tag(), " ");
830 break; /*MM_MESSAGE_END_OF_STREAM*/
832 case MM_MESSAGE_STATE_CHANGED:
835 case MM_MESSAGE_STATE_INTERRUPTED:
836 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
838 SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
840 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
842 int pid = ttsd_data_get_pid(uid);
843 /* send message to client about changing state */
844 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
846 SLOG(LOG_DEBUG, get_tag(), "=====");
847 SLOG(LOG_DEBUG, get_tag(), " ");
858 player_s* __player_get_item(int uid)
861 player_s *data = NULL;
863 if (0 < g_list_length(g_player_list)) {
864 /* Get a first item */
865 iter = g_list_first(g_player_list);
867 while (NULL != iter) {
868 /* Get handle data from list */
869 data = (player_s*)iter->data;
872 if (uid == data->uid)
876 iter = g_list_next(iter);
883 int __save_file(int uid, int index, sound_data_s data, char** filename)
886 memset(postfix, '\0', 5);
888 switch (data.audio_type) {
889 case TTSP_AUDIO_TYPE_RAW:
890 case TTSP_AUDIO_TYPE_WAV:
891 strcpy(postfix, "wav");
893 case TTSP_AUDIO_TYPE_MP3:
894 strcpy(postfix, "mp3");
896 case TTSP_AUDIO_TYPE_AMR:
897 strcpy(postfix, "amr");
900 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
904 /* make filename to save */
906 temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
908 SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
912 int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
921 fp = fopen(temp, "wb");
924 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
930 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
932 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
939 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
940 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
948 int size = fwrite(data.data, data.data_size, 1, fp);
950 size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
952 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
963 SLOG(LOG_DEBUG, get_tag(), " ");
964 SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
965 SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
970 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
972 if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
973 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
974 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
975 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
976 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
977 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
978 return TTSD_ERROR_INVALID_PARAMETER;
981 size_t bytesize = DEFAULT_FILE_SIZE;
987 /* NOT include \0(NULL) */
988 strncpy(hdr->riff, "RIFF", 4);
989 hdr->file_size = (int)(bytesize + 36);
990 strncpy(hdr->wave, "WAVE", 4);
991 strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
992 hdr->header_size = 16;
993 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
994 hdr->n_channels = channel;
995 hdr->sample_rate = (int)(sampling_rate);
996 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
997 hdr->block_align = sizeof(short);
998 hdr->bits_per_sample = sizeof(short)*8;
999 strncpy(hdr->data, "data", 4);
1000 hdr->data_size = (int)bytesize;
1005 int __set_and_start(player_s* player)
1007 /* get sound data */
1009 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
1010 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
1015 if (10000 <= g_index) {
1021 /* make sound file for mmplayer */
1022 char* sound_file = NULL;
1023 ret = __save_file(player->uid, g_index, wdata, &sound_file);
1024 if (0 != ret || NULL == sound_file) {
1025 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
1029 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
1030 user_data->uid = player->uid;
1031 user_data->utt_id = wdata.utt_id;
1032 user_data->event = wdata.event;
1033 memset(user_data->filename, 0, TEMP_FILE_MAX);
1034 strncpy( user_data->filename, sound_file, strlen(sound_file) );
1036 SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
1037 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
1038 SLOG(LOG_DEBUG, get_tag(), " ");
1041 /* set callback func */
1042 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
1043 if (MM_ERROR_NONE != ret) {
1044 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
1048 /* set playing info to mm player */
1049 char* err_attr_name = NULL;
1051 if (0 != access(sound_file, R_OK)) {
1052 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
1056 ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
1057 "profile_uri", sound_file , strlen(sound_file) + 1,
1058 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
1059 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
1062 if (MM_ERROR_NONE != ret) {
1063 if (NULL != err_attr_name) {
1064 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
1069 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
1070 ret = mm_player_ignore_session(player->player_handle);
1071 if (MM_ERROR_NONE != ret) {
1072 SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
1076 /* realize and start mm player */
1077 ret = mm_player_realize(player->player_handle);
1078 if (MM_ERROR_NONE != ret) {
1079 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
1083 ret = mm_player_start(player->player_handle);
1084 if (MM_ERROR_NONE != ret) {
1085 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
1087 mm_player_unrealize(player->player_handle);
1091 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
1092 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
1093 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
1094 * the player should send utt started event.
1096 if (TTSP_RESULT_EVENT_START == wdata.event ||
1097 (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
1099 pid = ttsd_data_get_pid(player->uid);
1101 /* send utterance start message */
1102 if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
1103 SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, player->uid, wdata.utt_id);
1106 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
1109 g_playing_info = player;
1111 if (NULL != sound_file)
1113 if (NULL != wdata.data)