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);
586 switch (player_state) {
587 case MM_PLAYER_STATE_PLAYING:
588 *state = TTSD_PLAYER_STATE_PLAYING;
590 case MM_PLAYER_STATE_PAUSED:
591 *state = TTSD_PLAYER_STATE_PAUSED;
594 case MM_PLAYER_STATE_NULL:
595 *state = TTSD_PLAYER_STATE_NULL;
598 case MM_PLAYER_STATE_READY:
600 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid);
608 int ttsd_player_get_current_client()
610 if (false == g_player_init) {
611 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
615 if (NULL != g_playing_info)
616 return g_playing_info->uid;
618 SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
623 int ttsd_player_get_current_utterance_id(int uid)
625 SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
627 if (false == g_player_init) {
628 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
634 current = __player_get_item(uid);
635 if (NULL == current) {
636 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
640 return current->utt_id;
643 int ttsd_player_all_stop()
645 if (false == g_player_init) {
646 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
650 g_playing_info = NULL;
654 player_s *data = NULL;
656 if (0 < g_list_length(g_player_list)) {
657 /* Get a first item */
658 iter = g_list_first(g_player_list);
660 while (NULL != iter) {
661 /* Get handle data from list */
662 data = (player_s*)iter->data;
665 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
666 SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
667 ttsd_player_destroy_instance(data->uid);
668 iter = g_list_next(iter);
672 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
673 /* unrealize player */
674 ret = mm_player_unrealize(data->player_handle);
675 if (MM_ERROR_NONE != ret) {
676 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
680 data->event = TTSP_RESULT_EVENT_FINISH;
684 iter = g_list_next(iter);
688 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
693 static Eina_Bool __player_next_play(void *data)
695 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
697 int* uid = (int*)data;
700 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
701 SLOG(LOG_DEBUG, get_tag(), "=====");
702 SLOG(LOG_DEBUG, get_tag(), " ");
706 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
708 if (0 != ttsd_player_next_play(*uid)) {
709 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
714 SLOG(LOG_DEBUG, get_tag(), "=====");
715 SLOG(LOG_DEBUG, get_tag(), " ");
720 static int msg_callback(int message, void *data, void *user_param)
722 user_data_s* user_data = NULL;
724 user_data = (user_data_s*)user_param;
726 if (NULL == user_data) {
727 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
731 int uid = user_data->uid;
732 int utt_id = user_data->utt_id;
734 MMMessageParamType *msg = (MMMessageParamType*)data;
737 case MM_MESSAGE_ERROR:
739 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
740 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
742 /* send error info */
743 g_result_callback(PLAYER_ERROR, uid, utt_id);
746 current = __player_get_item(uid);
747 if (NULL == current) {
748 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
750 current->event = TTSP_RESULT_EVENT_FINISH;
753 if (NULL != user_data)
756 /* check current player */
757 if (NULL != g_playing_info) {
758 if (uid == g_playing_info->uid) {
759 g_playing_info = NULL;
760 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
764 SLOG(LOG_DEBUG, get_tag(), "=====");
765 SLOG(LOG_DEBUG, get_tag(), " ");
767 break; /*MM_MESSAGE_ERROR*/
769 case MM_MESSAGE_BEGIN_OF_STREAM:
773 case MM_MESSAGE_END_OF_STREAM:
775 SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
777 if (-1 == remove(user_data->filename)) {
778 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
783 current = __player_get_item(uid);
784 if (NULL == current) {
785 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
786 if (NULL != g_playing_info) {
787 if (uid == g_playing_info->uid) {
788 g_playing_info = NULL;
789 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
792 SLOG(LOG_DEBUG, get_tag(), "=====");
793 SLOG(LOG_DEBUG, get_tag(), " ");
799 int pid = ttsd_data_get_pid(uid);
801 /* send utterence finish signal */
802 if (TTSP_RESULT_EVENT_FINISH == current->event) {
803 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
804 SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
806 SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
809 /* for sync problem */
810 MMPlayerStateType player_state;
811 mm_player_get_state(current->player_handle, &player_state);
813 if (MM_PLAYER_STATE_PAUSED == player_state) {
814 g_pause_info = true; /* The current state of player is 'Paused' */
815 g_paused_uid = uid; /* The current uid when the current state player is 'Paused' */
818 int* uid_data = (int*) g_malloc0(sizeof(int));
821 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
823 ecore_timer_add(0, __player_next_play, (void*)uid_data);
826 SLOG(LOG_DEBUG, get_tag(), "=====");
827 SLOG(LOG_DEBUG, get_tag(), " ");
829 break; /*MM_MESSAGE_END_OF_STREAM*/
831 case MM_MESSAGE_STATE_CHANGED:
834 case MM_MESSAGE_STATE_INTERRUPTED:
835 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
837 SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
839 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
841 int pid = ttsd_data_get_pid(uid);
842 /* send message to client about changing state */
843 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
845 SLOG(LOG_DEBUG, get_tag(), "=====");
846 SLOG(LOG_DEBUG, get_tag(), " ");
857 player_s* __player_get_item(int uid)
860 player_s *data = NULL;
862 if (0 < g_list_length(g_player_list)) {
863 /* Get a first item */
864 iter = g_list_first(g_player_list);
866 while (NULL != iter) {
867 /* Get handle data from list */
868 data = (player_s*)iter->data;
871 if (uid == data->uid)
875 iter = g_list_next(iter);
882 int __save_file(int uid, int index, sound_data_s data, char** filename)
885 memset(postfix, '\0', 5);
887 switch (data.audio_type) {
888 case TTSP_AUDIO_TYPE_RAW:
889 case TTSP_AUDIO_TYPE_WAV:
890 strcpy(postfix, "wav");
892 case TTSP_AUDIO_TYPE_MP3:
893 strcpy(postfix, "mp3");
895 case TTSP_AUDIO_TYPE_AMR:
896 strcpy(postfix, "amr");
899 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
903 /* make filename to save */
905 temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
907 SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
911 int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
920 fp = fopen(temp, "wb");
923 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
929 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
931 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
938 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
939 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
947 int size = fwrite(data.data, data.data_size, 1, fp);
949 size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
951 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
962 SLOG(LOG_DEBUG, get_tag(), " ");
963 SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
964 SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
969 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
971 if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
972 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
973 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
974 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
975 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
976 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
977 return TTSD_ERROR_INVALID_PARAMETER;
980 size_t bytesize = DEFAULT_FILE_SIZE;
986 /* NOT include \0(NULL) */
987 strncpy(hdr->riff, "RIFF", 4);
988 hdr->file_size = (int)(bytesize + 36);
989 strncpy(hdr->wave, "WAVE", 4);
990 strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
991 hdr->header_size = 16;
992 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
993 hdr->n_channels = channel;
994 hdr->sample_rate = (int)(sampling_rate);
995 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
996 hdr->block_align = sizeof(short);
997 hdr->bits_per_sample = sizeof(short)*8;
998 strncpy(hdr->data, "data", 4);
999 hdr->data_size = (int)bytesize;
1004 int __set_and_start(player_s* player)
1006 /* get sound data */
1008 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
1009 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
1014 if (10000 <= g_index) {
1020 /* make sound file for mmplayer */
1021 char* sound_file = NULL;
1022 ret = __save_file(player->uid, g_index, wdata, &sound_file);
1023 if (0 != ret || NULL == sound_file) {
1024 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
1028 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
1029 user_data->uid = player->uid;
1030 user_data->utt_id = wdata.utt_id;
1031 user_data->event = wdata.event;
1032 memset(user_data->filename, 0, TEMP_FILE_MAX);
1033 strncpy( user_data->filename, sound_file, strlen(sound_file) );
1035 SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
1036 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
1037 SLOG(LOG_DEBUG, get_tag(), " ");
1040 /* set callback func */
1041 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
1042 if (MM_ERROR_NONE != ret) {
1043 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
1047 /* set playing info to mm player */
1048 char* err_attr_name = NULL;
1050 if (0 != access(sound_file, R_OK)) {
1051 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
1055 ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
1056 "profile_uri", sound_file , strlen(sound_file) + 1,
1057 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
1058 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
1061 if (MM_ERROR_NONE != ret) {
1062 if (NULL != err_attr_name) {
1063 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
1068 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
1069 ret = mm_player_ignore_session(player->player_handle);
1070 if (MM_ERROR_NONE != ret) {
1071 SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
1075 /* realize and start mm player */
1076 ret = mm_player_realize(player->player_handle);
1077 if (MM_ERROR_NONE != ret) {
1078 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
1082 ret = mm_player_start(player->player_handle);
1083 if (MM_ERROR_NONE != ret) {
1084 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
1086 mm_player_unrealize(player->player_handle);
1090 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
1091 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
1092 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
1093 * the player should send utt started event.
1095 if (TTSP_RESULT_EVENT_START == wdata.event ||
1096 (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
1098 pid = ttsd_data_get_pid(player->uid);
1100 /* send utterance start message */
1101 if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
1102 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);
1105 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
1108 g_playing_info = player;
1110 if (NULL != sound_file)
1112 if (NULL != wdata.data)