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 */
55 bool pause_after_complete; /** For resume when the 'Paused' state of player after end callback */
61 ttsp_result_event_e event;
62 char filename[TEMP_FILE_MAX];
70 #define TEMP_FILE_PATH "/tmp"
71 #define FILE_PATH_SIZE 256
72 #define DEFAULT_FILE_SIZE 10
74 /** player init info */
75 static bool g_player_init = false;
77 /** tts engine list */
78 static GList *g_player_list;
80 /** current player information */
81 static player_s* g_playing_info;
83 /** player callback function */
84 static player_result_callback_func g_result_callback;
86 /** numbering for temp file */
87 static unsigned int g_index;
92 player_s* __player_get_item(int uid);
94 int __save_file(int uid, int index, sound_data_s data, char** filename);
96 int __set_and_start(player_s* player);
98 int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
100 static int msg_callback(int message, void *data, void *user_param) ;
107 int ttsd_player_init(player_result_callback_func result_cb)
109 if (NULL == result_cb) {
110 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] invalid parameter");
111 return TTSD_ERROR_INVALID_PARAMETER;
114 g_result_callback = result_cb;
116 g_playing_info = NULL;
119 g_player_init = true;
121 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
122 if (MM_ERROR_NONE != mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)) {
123 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
125 SLOG(LOG_ERROR, get_tag(), "[Player SUCCESS] mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
132 int ttsd_player_release(void)
134 if (false == g_player_init) {
135 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized");
136 return TTSD_ERROR_OPERATION_FAILED;
139 /* clear g_player_list */
140 g_playing_info = NULL;
141 g_player_init = false;
146 int ttsd_player_create_instance(int uid)
148 if (false == g_player_init) {
149 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
153 /* Check uid is duplicated */
154 if (NULL != __player_get_item(uid)) {
155 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is already registered", uid);
159 int ret = MM_ERROR_NONE;
160 MMHandleType player_handle;
162 ret = mm_player_create(&player_handle);
163 if (ret != MM_ERROR_NONE || 0 == player_handle) {
164 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_create() : %x", ret);
168 player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
170 new_client->uid = uid;
171 new_client->player_handle = player_handle;
172 new_client->utt_id = -1;
173 new_client->event = TTSP_RESULT_EVENT_FINISH;
174 new_client->pause_after_complete = false;
176 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
178 g_player_list = g_list_append(g_player_list, new_client);
183 int ttsd_player_destroy_instance(int uid)
185 if (false == g_player_init) {
186 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
191 current = __player_get_item(uid);
192 if (NULL == current) {
193 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
197 if (NULL != g_playing_info) {
198 if (uid == g_playing_info->uid) {
199 g_playing_info = NULL;
203 MMPlayerStateType player_state;
204 mm_player_get_state(current->player_handle, &player_state);
206 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
210 switch (player_state) {
211 case MM_PLAYER_STATE_PLAYING:
212 case MM_PLAYER_STATE_PAUSED:
213 case MM_PLAYER_STATE_READY:
214 ret = mm_player_unrealize(current->player_handle);
215 if (MM_ERROR_NONE != ret) {
216 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
218 /* NO break for destroy */
220 case MM_PLAYER_STATE_NULL:
221 ret = mm_player_destroy(current->player_handle);
222 if (MM_ERROR_NONE != ret) {
223 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_destroy() : %x", ret);
232 player_s *data = NULL;
234 if (0 < g_list_length(g_player_list)) {
235 /* Get a first item */
236 iter = g_list_first(g_player_list);
238 while (NULL != iter) {
239 /* Get handle data from list */
240 data = (player_s*)iter->data;
244 if (uid == data->uid) {
245 g_player_list = g_list_remove_link(g_player_list, iter);
252 iter = g_list_next(iter);
256 SLOG(LOG_DEBUG, get_tag(), "[PLAYER Success] Destroy instance");
261 int ttsd_player_play(int uid)
263 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] start play : uid(%d)", uid );
265 if (false == g_player_init) {
266 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
270 if (NULL != g_playing_info) {
271 if (uid == g_playing_info->uid) {
272 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] uid(%d) has already played", g_playing_info->uid);
277 /* Check sound queue size */
278 if (0 == ttsd_data_get_sound_data_size(uid)) {
279 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
285 current = __player_get_item(uid);
286 if (NULL == current) {
287 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
291 MMPlayerStateType player_state;
292 mm_player_get_state(current->player_handle, &player_state);
294 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
296 switch (player_state) {
297 case MM_PLAYER_STATE_PLAYING:
298 SLOG(LOG_WARN, get_tag(), "[Player] Current player is playing. Do not start new sound.");
301 case MM_PLAYER_STATE_PAUSED:
302 SLOG(LOG_WARN, get_tag(), "[Player] Player is paused. Do not start new sound.");
305 case MM_PLAYER_STATE_READY:
306 SLOG(LOG_WARN, get_tag(), "[Player] Player is ready for next play. Do not start new sound.");
309 case MM_PLAYER_STATE_NULL:
312 case MM_PLAYER_STATE_NONE:
313 SLOG(LOG_WARN, get_tag(), "[Player] Player is created. Do not start new sound.");
321 ret = __set_and_start(current);
323 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
326 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
331 int __ttsd_player_next_play(int uid)
333 if (false == g_player_init) {
334 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
340 current = __player_get_item(uid);
341 if (NULL == current) {
342 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
343 g_playing_info = NULL;
347 if (NULL != g_playing_info) {
348 if (uid != g_playing_info->uid) {
349 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
353 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player do NOT exist");
357 MMPlayerStateType player_state;
358 mm_player_get_state(current->player_handle, &player_state);
360 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
364 switch (player_state) {
365 case MM_PLAYER_STATE_PLAYING:
366 case MM_PLAYER_STATE_PAUSED:
367 case MM_PLAYER_STATE_READY:
368 ret = mm_player_unrealize(current->player_handle);
369 if (MM_ERROR_NONE != ret) {
370 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
375 case MM_PLAYER_STATE_NULL:
382 /* Check sound queue size */
383 if (0 == ttsd_data_get_sound_data_size(uid)) {
384 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
385 g_playing_info = NULL;
389 ret = __set_and_start(current);
391 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
394 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
400 int ttsd_player_stop(int uid)
402 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
404 if (false == g_player_init) {
405 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
411 current = __player_get_item(uid);
412 if (NULL == current) {
413 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
417 /* check whether uid is current playing or not */
418 if (NULL != g_playing_info) {
419 if (uid == g_playing_info->uid) {
420 /* release current playing info */
421 g_playing_info = NULL;
424 SLOG(LOG_DEBUG, get_tag(), "[Player] No current playing");
427 current->utt_id = -1;
428 current->pause_after_complete = false;
430 MMPlayerStateType player_state;
431 mm_player_get_state(current->player_handle, &player_state);
433 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
436 switch (player_state) {
437 case MM_PLAYER_STATE_PLAYING:
438 case MM_PLAYER_STATE_PAUSED:
439 case MM_PLAYER_STATE_READY:
440 ret = mm_player_unrealize(current->player_handle);
441 if (MM_ERROR_NONE != ret) {
442 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
447 case MM_PLAYER_STATE_NULL:
454 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
459 int ttsd_player_pause(int uid)
461 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] pause player : uid(%d)", uid );
463 if (false == g_player_init) {
464 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
470 current = __player_get_item(uid);
471 if (NULL == current) {
472 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
476 /* check whether uid is current playing or not */
477 if (NULL != g_playing_info) {
478 if (uid == g_playing_info->uid) {
479 /* release current playing info */
480 g_playing_info = NULL;
486 MMPlayerStateType player_state;
487 mm_player_get_state(current->player_handle, &player_state);
489 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
492 if (MM_PLAYER_STATE_PLAYING == player_state) {
493 ret = mm_player_pause(current->player_handle);
494 if (MM_ERROR_NONE != ret) {
495 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_pause : %x ", ret);
498 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player is NOT 'playing'");
505 int ttsd_player_resume(int uid)
507 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player : uid(%d)", uid );
509 if (false == g_player_init) {
510 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
516 current = __player_get_item(uid);
517 if (NULL == current) {
518 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
522 /* check current player */
523 if (NULL != g_playing_info)
524 g_playing_info = NULL;
527 MMPlayerStateType player_state;
528 mm_player_get_state(current->player_handle, &player_state);
530 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
533 if (MM_PLAYER_STATE_PAUSED == player_state) {
534 /* When the 'Paused' state of player after end of play */
535 if (true == current->pause_after_complete) {
536 g_playing_info = current;
538 current->pause_after_complete = false;
540 /* Current state need load and play */
541 ret = __ttsd_player_next_play(uid);
543 SLOG(LOG_ERROR, get_tag(), "[player] Fail to next play in resume function");
546 ret = mm_player_resume(current->player_handle);
547 if (MM_ERROR_NONE != ret) {
548 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_resume() : %d", ret);
551 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player");
554 g_playing_info = current;
557 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current uid is NOT paused state.");
563 int ttsd_player_get_state(int uid, ttsd_player_state_e* state)
565 if (false == g_player_init) {
566 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
571 current = __player_get_item(uid);
572 if (NULL == current) {
573 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
577 MMPlayerStateType player_state;
578 mm_player_get_state(current->player_handle, &player_state);
580 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
583 switch (player_state) {
584 case MM_PLAYER_STATE_PLAYING:
585 *state = TTSD_PLAYER_STATE_PLAYING;
587 case MM_PLAYER_STATE_PAUSED:
588 *state = TTSD_PLAYER_STATE_PAUSED;
591 case MM_PLAYER_STATE_NULL:
592 *state = TTSD_PLAYER_STATE_NULL;
595 case MM_PLAYER_STATE_READY:
597 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid);
605 int ttsd_player_get_current_client()
607 if (false == g_player_init) {
608 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
612 if (NULL != g_playing_info)
613 return g_playing_info->uid;
615 SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
620 int ttsd_player_get_current_utterance_id(int uid)
622 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
624 if (false == g_player_init) {
625 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
631 current = __player_get_item(uid);
632 if (NULL == current) {
633 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
637 return current->utt_id;
640 int ttsd_player_all_stop()
642 if (false == g_player_init) {
643 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
647 g_playing_info = NULL;
651 player_s *data = NULL;
653 if (0 < g_list_length(g_player_list)) {
654 /* Get a first item */
655 iter = g_list_first(g_player_list);
657 while (NULL != iter) {
658 /* Get handle data from list */
659 data = (player_s*)iter->data;
662 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
663 SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
664 ttsd_player_destroy_instance(data->uid);
665 iter = g_list_next(iter);
669 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
670 /* unrealize player */
671 ret = mm_player_unrealize(data->player_handle);
672 if (MM_ERROR_NONE != ret) {
673 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
677 data->event = TTSP_RESULT_EVENT_FINISH;
681 iter = g_list_next(iter);
685 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
690 static Eina_Bool __player_next_play(void *data)
692 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
694 int* uid = (int*)data;
697 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
698 SLOG(LOG_DEBUG, get_tag(), "=====");
699 SLOG(LOG_DEBUG, get_tag(), " ");
703 SECURE_SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
705 if (0 != __ttsd_player_next_play(*uid)) {
706 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
711 SLOG(LOG_DEBUG, get_tag(), "=====");
712 SLOG(LOG_DEBUG, get_tag(), " ");
717 static int msg_callback(int message, void *data, void *user_param)
719 user_data_s* user_data = NULL;
721 user_data = (user_data_s*)user_param;
723 if (NULL == user_data) {
724 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
728 int uid = user_data->uid;
729 int utt_id = user_data->utt_id;
731 MMMessageParamType *msg = (MMMessageParamType*)data;
734 case MM_MESSAGE_ERROR:
736 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
737 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
739 /* send error info */
740 g_result_callback(PLAYER_ERROR, uid, utt_id);
743 current = __player_get_item(uid);
744 if (NULL == current) {
745 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
747 current->event = TTSP_RESULT_EVENT_FINISH;
750 if (NULL != user_data)
753 /* check current player */
754 if (NULL != g_playing_info) {
755 if (uid == g_playing_info->uid) {
756 g_playing_info = NULL;
757 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
761 SLOG(LOG_DEBUG, get_tag(), "=====");
762 SLOG(LOG_DEBUG, get_tag(), " ");
764 break; /*MM_MESSAGE_ERROR*/
766 case MM_MESSAGE_BEGIN_OF_STREAM:
770 case MM_MESSAGE_END_OF_STREAM:
772 SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
774 if (-1 == remove(user_data->filename)) {
775 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
780 current = __player_get_item(uid);
781 if (NULL == current) {
782 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
783 if (NULL != g_playing_info) {
784 if (uid == g_playing_info->uid) {
785 g_playing_info = NULL;
786 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
789 SLOG(LOG_DEBUG, get_tag(), "=====");
790 SLOG(LOG_DEBUG, get_tag(), " ");
796 int pid = ttsd_data_get_pid(uid);
798 /* send utterence finish signal */
799 if (TTSP_RESULT_EVENT_FINISH == current->event) {
800 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
801 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
803 SECURE_SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
806 /* for sync problem */
807 MMPlayerStateType player_state;
808 mm_player_get_state(current->player_handle, &player_state);
810 if (MM_PLAYER_STATE_PAUSED == player_state) {
811 /* The current state of player is 'Paused' */
812 current->pause_after_complete = true;
815 int* uid_data = (int*) g_malloc0(sizeof(int));
818 SECURE_SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
820 ecore_timer_add(0, __player_next_play, (void*)uid_data);
823 SLOG(LOG_DEBUG, get_tag(), "=====");
824 SLOG(LOG_DEBUG, get_tag(), " ");
826 break; /*MM_MESSAGE_END_OF_STREAM*/
828 case MM_MESSAGE_STATE_CHANGED:
831 case MM_MESSAGE_STATE_INTERRUPTED:
832 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
834 SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
836 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
838 int pid = ttsd_data_get_pid(uid);
839 /* send message to client about changing state */
840 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
842 SLOG(LOG_DEBUG, get_tag(), "=====");
843 SLOG(LOG_DEBUG, get_tag(), " ");
854 player_s* __player_get_item(int uid)
857 player_s *data = NULL;
859 if (0 < g_list_length(g_player_list)) {
860 /* Get a first item */
861 iter = g_list_first(g_player_list);
863 while (NULL != iter) {
864 /* Get handle data from list */
865 data = (player_s*)iter->data;
868 if (uid == data->uid)
872 iter = g_list_next(iter);
879 int __save_file(int uid, int index, sound_data_s data, char** filename)
882 memset(postfix, '\0', 5);
884 switch (data.audio_type) {
885 case TTSP_AUDIO_TYPE_RAW:
886 case TTSP_AUDIO_TYPE_WAV:
887 strcpy(postfix, "wav");
889 case TTSP_AUDIO_TYPE_MP3:
890 strcpy(postfix, "mp3");
892 case TTSP_AUDIO_TYPE_AMR:
893 strcpy(postfix, "amr");
896 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
900 /* make filename to save */
902 temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
904 SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
908 int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
917 fp = fopen(temp, "wb");
920 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
926 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
928 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
935 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
936 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
944 int size = fwrite(data.data, data.data_size, 1, fp);
946 size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
948 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
959 SLOG(LOG_DEBUG, get_tag(), " ");
960 SECURE_SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
961 SECURE_SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
966 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
968 if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
969 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
970 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
971 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
972 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
973 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
974 return TTSD_ERROR_INVALID_PARAMETER;
977 size_t bytesize = DEFAULT_FILE_SIZE;
983 /* NOT include \0(NULL) */
984 strncpy(hdr->riff, "RIFF", 4);
985 hdr->file_size = (int)(bytesize + 36);
986 strncpy(hdr->wave, "WAVE", 4);
987 strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
988 hdr->header_size = 16;
989 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
990 hdr->n_channels = channel;
991 hdr->sample_rate = (int)(sampling_rate);
992 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
993 hdr->block_align = sizeof(short);
994 hdr->bits_per_sample = sizeof(short)*8;
995 strncpy(hdr->data, "data", 4);
996 hdr->data_size = (int)bytesize;
1001 int __set_and_start(player_s* player)
1003 /* get sound data */
1005 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
1006 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
1011 if (10000 <= g_index) {
1017 /* make sound file for mmplayer */
1018 char* sound_file = NULL;
1019 ret = __save_file(player->uid, g_index, wdata, &sound_file);
1020 if (0 != ret || NULL == sound_file) {
1021 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
1025 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
1026 user_data->uid = player->uid;
1027 user_data->utt_id = wdata.utt_id;
1028 user_data->event = wdata.event;
1029 memset(user_data->filename, 0, TEMP_FILE_MAX);
1030 strncpy( user_data->filename, sound_file, strlen(sound_file) );
1032 SECURE_SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
1033 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
1034 SLOG(LOG_DEBUG, get_tag(), " ");
1037 /* set callback func */
1038 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
1039 if (MM_ERROR_NONE != ret) {
1040 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
1044 /* set playing info to mm player */
1045 char* err_attr_name = NULL;
1047 if (0 != access(sound_file, R_OK)) {
1048 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
1052 ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
1053 "profile_uri", sound_file , strlen(sound_file) + 1,
1054 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
1055 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
1058 if (MM_ERROR_NONE != ret) {
1059 if (NULL != err_attr_name) {
1060 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
1065 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
1066 ret = mm_player_ignore_session(player->player_handle);
1067 if (MM_ERROR_NONE != ret) {
1068 SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
1072 /* realize and start mm player */
1073 ret = mm_player_realize(player->player_handle);
1074 if (MM_ERROR_NONE != ret) {
1075 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
1079 ret = mm_player_start(player->player_handle);
1080 if (MM_ERROR_NONE != ret) {
1081 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
1083 mm_player_unrealize(player->player_handle);
1087 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
1088 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
1089 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
1090 * the player should send utt started event.
1092 if (TTSP_RESULT_EVENT_START == wdata.event ||
1093 (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
1095 pid = ttsd_data_get_pid(player->uid);
1097 /* send utterance start message */
1098 if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
1099 SECURE_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);
1102 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
1105 g_playing_info = player;
1107 if (NULL != sound_file)
1109 if (NULL != wdata.data)