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");
327 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
332 int __ttsd_player_next_play(int uid)
334 if (false == g_player_init) {
335 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
341 current = __player_get_item(uid);
342 if (NULL == current) {
343 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
344 g_playing_info = NULL;
348 if (NULL != g_playing_info) {
349 if (uid != g_playing_info->uid) {
350 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
354 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player do NOT exist");
358 MMPlayerStateType player_state;
359 mm_player_get_state(current->player_handle, &player_state);
361 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
365 switch (player_state) {
366 case MM_PLAYER_STATE_PLAYING:
367 case MM_PLAYER_STATE_PAUSED:
368 case MM_PLAYER_STATE_READY:
369 ret = mm_player_unrealize(current->player_handle);
370 if (MM_ERROR_NONE != ret) {
371 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
376 case MM_PLAYER_STATE_NULL:
383 /* Check sound queue size */
384 if (0 == ttsd_data_get_sound_data_size(uid)) {
385 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
386 g_playing_info = NULL;
390 ret = __set_and_start(current);
392 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
396 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
402 int ttsd_player_stop(int uid)
404 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
406 if (false == g_player_init) {
407 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
413 current = __player_get_item(uid);
414 if (NULL == current) {
415 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
419 /* check whether uid is current playing or not */
420 if (NULL != g_playing_info) {
421 if (uid == g_playing_info->uid) {
422 /* release current playing info */
423 g_playing_info = NULL;
426 SLOG(LOG_DEBUG, get_tag(), "[Player] No current playing");
429 current->utt_id = -1;
430 current->pause_after_complete = false;
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 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
461 int ttsd_player_pause(int uid)
463 SECURE_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 SECURE_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 SECURE_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 SECURE_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 (true == current->pause_after_complete) {
538 g_playing_info = current;
540 current->pause_after_complete = false;
542 /* Current state need load and play */
543 ret = __ttsd_player_next_play(uid);
545 SLOG(LOG_ERROR, get_tag(), "[player] Fail to next play in resume function");
548 ret = mm_player_resume(current->player_handle);
549 if (MM_ERROR_NONE != ret) {
550 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_resume() : %d", ret);
553 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player");
556 g_playing_info = current;
559 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current uid is NOT paused state.");
565 int ttsd_player_get_state(int uid, ttsd_player_state_e* state)
567 if (false == g_player_init) {
568 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
573 current = __player_get_item(uid);
574 if (NULL == current) {
575 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
579 MMPlayerStateType player_state;
580 mm_player_get_state(current->player_handle, &player_state);
582 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
585 switch (player_state) {
586 case MM_PLAYER_STATE_PLAYING:
587 *state = TTSD_PLAYER_STATE_PLAYING;
589 case MM_PLAYER_STATE_PAUSED:
590 *state = TTSD_PLAYER_STATE_PAUSED;
593 case MM_PLAYER_STATE_NULL:
594 *state = TTSD_PLAYER_STATE_NULL;
597 case MM_PLAYER_STATE_READY:
599 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid);
607 int ttsd_player_get_current_client()
609 if (false == g_player_init) {
610 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
614 if (NULL != g_playing_info)
615 return g_playing_info->uid;
617 SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
622 int ttsd_player_get_current_utterance_id(int uid)
624 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
626 if (false == g_player_init) {
627 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
633 current = __player_get_item(uid);
634 if (NULL == current) {
635 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
639 return current->utt_id;
642 int ttsd_player_all_stop()
644 if (false == g_player_init) {
645 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
649 g_playing_info = NULL;
653 player_s *data = NULL;
655 if (0 < g_list_length(g_player_list)) {
656 /* Get a first item */
657 iter = g_list_first(g_player_list);
659 while (NULL != iter) {
660 /* Get handle data from list */
661 data = (player_s*)iter->data;
664 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
665 SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
666 ttsd_player_destroy_instance(data->uid);
667 iter = g_list_next(iter);
671 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
672 /* unrealize player */
673 ret = mm_player_unrealize(data->player_handle);
674 if (MM_ERROR_NONE != ret) {
675 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
679 data->event = TTSP_RESULT_EVENT_FINISH;
683 iter = g_list_next(iter);
687 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
692 static Eina_Bool __player_next_play(void *data)
694 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
696 int* uid = (int*)data;
699 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
700 SLOG(LOG_DEBUG, get_tag(), "=====");
701 SLOG(LOG_DEBUG, get_tag(), " ");
705 SECURE_SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
707 if (0 != __ttsd_player_next_play(*uid)) {
708 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
713 SLOG(LOG_DEBUG, get_tag(), "=====");
714 SLOG(LOG_DEBUG, get_tag(), " ");
719 static int msg_callback(int message, void *data, void *user_param)
721 user_data_s* user_data = NULL;
723 user_data = (user_data_s*)user_param;
725 if (NULL == user_data) {
726 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
730 int uid = user_data->uid;
731 int utt_id = user_data->utt_id;
733 MMMessageParamType *msg = (MMMessageParamType*)data;
736 case MM_MESSAGE_ERROR:
738 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
739 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
741 /* send error info */
742 g_result_callback(PLAYER_ERROR, uid, utt_id);
745 current = __player_get_item(uid);
746 if (NULL == current) {
747 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
749 current->event = TTSP_RESULT_EVENT_FINISH;
752 if (NULL != user_data)
755 /* check current player */
756 if (NULL != g_playing_info) {
757 if (uid == g_playing_info->uid) {
758 g_playing_info = NULL;
759 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
763 SLOG(LOG_DEBUG, get_tag(), "=====");
764 SLOG(LOG_DEBUG, get_tag(), " ");
766 break; /*MM_MESSAGE_ERROR*/
768 case MM_MESSAGE_BEGIN_OF_STREAM:
772 case MM_MESSAGE_END_OF_STREAM:
774 SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
776 if (-1 == remove(user_data->filename)) {
777 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
782 current = __player_get_item(uid);
783 if (NULL == current) {
784 SECURE_SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
785 if (NULL != g_playing_info) {
786 if (uid == g_playing_info->uid) {
787 g_playing_info = NULL;
788 SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
791 SLOG(LOG_DEBUG, get_tag(), "=====");
792 SLOG(LOG_DEBUG, get_tag(), " ");
798 int pid = ttsd_data_get_pid(uid);
800 /* send utterence finish signal */
801 if (TTSP_RESULT_EVENT_FINISH == current->event) {
802 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
803 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
805 SECURE_SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
808 /* for sync problem */
809 MMPlayerStateType player_state;
810 mm_player_get_state(current->player_handle, &player_state);
812 if (MM_PLAYER_STATE_PAUSED == player_state) {
813 /* The current state of player is 'Paused' */
814 current->pause_after_complete = true;
817 int* uid_data = (int*) g_malloc0(sizeof(int));
820 SECURE_SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
822 ecore_timer_add(0, __player_next_play, (void*)uid_data);
825 SLOG(LOG_DEBUG, get_tag(), "=====");
826 SLOG(LOG_DEBUG, get_tag(), " ");
828 break; /*MM_MESSAGE_END_OF_STREAM*/
830 case MM_MESSAGE_STATE_CHANGED:
833 case MM_MESSAGE_STATE_INTERRUPTED:
834 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
836 SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
838 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
840 int pid = ttsd_data_get_pid(uid);
841 /* send message to client about changing state */
842 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
844 SLOG(LOG_DEBUG, get_tag(), "=====");
845 SLOG(LOG_DEBUG, get_tag(), " ");
856 player_s* __player_get_item(int uid)
859 player_s *data = NULL;
861 if (0 < g_list_length(g_player_list)) {
862 /* Get a first item */
863 iter = g_list_first(g_player_list);
865 while (NULL != iter) {
866 /* Get handle data from list */
867 data = (player_s*)iter->data;
870 if (uid == data->uid)
874 iter = g_list_next(iter);
881 int __save_file(int uid, int index, sound_data_s data, char** filename)
884 memset(postfix, '\0', 5);
886 switch (data.audio_type) {
887 case TTSP_AUDIO_TYPE_RAW:
888 case TTSP_AUDIO_TYPE_WAV:
889 strcpy(postfix, "wav");
891 case TTSP_AUDIO_TYPE_MP3:
892 strcpy(postfix, "mp3");
894 case TTSP_AUDIO_TYPE_AMR:
895 strcpy(postfix, "amr");
898 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
902 /* make filename to save */
904 temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
906 SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
910 int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
919 fp = fopen(temp, "wb");
922 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
928 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
930 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
937 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
938 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
946 int size = fwrite(data.data, data.data_size, 1, fp);
948 size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
950 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
961 SLOG(LOG_DEBUG, get_tag(), " ");
962 SECURE_SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
963 SECURE_SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
968 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
970 if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
971 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
972 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
973 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
974 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
975 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
976 return TTSD_ERROR_INVALID_PARAMETER;
979 size_t bytesize = DEFAULT_FILE_SIZE;
985 /* NOT include \0(NULL) */
986 strncpy(hdr->riff, "RIFF", 4);
987 hdr->file_size = (int)(bytesize + 36);
988 strncpy(hdr->wave, "WAVE", 4);
989 strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
990 hdr->header_size = 16;
991 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
992 hdr->n_channels = channel;
993 hdr->sample_rate = (int)(sampling_rate);
994 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
995 hdr->block_align = sizeof(short);
996 hdr->bits_per_sample = sizeof(short)*8;
997 strncpy(hdr->data, "data", 4);
998 hdr->data_size = (int)bytesize;
1003 int __set_and_start(player_s* player)
1005 /* get sound data */
1007 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
1008 SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
1013 if (10000 <= g_index) {
1019 /* make sound file for mmplayer */
1020 char* sound_file = NULL;
1021 ret = __save_file(player->uid, g_index, wdata, &sound_file);
1022 if (0 != ret || NULL == sound_file) {
1023 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
1027 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
1028 user_data->uid = player->uid;
1029 user_data->utt_id = wdata.utt_id;
1030 user_data->event = wdata.event;
1031 memset(user_data->filename, 0, TEMP_FILE_MAX);
1032 strncpy( user_data->filename, sound_file, strlen(sound_file) );
1034 SECURE_SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
1035 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
1036 SLOG(LOG_DEBUG, get_tag(), " ");
1039 /* set callback func */
1040 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
1041 if (MM_ERROR_NONE != ret) {
1042 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
1043 if (NULL != user_data) g_free(user_data);
1047 /* set playing info to mm player */
1048 char* err_attr_name = NULL;
1050 if (0 != access(sound_file, R_OK)) {
1051 SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
1052 if (NULL != user_data) g_free(user_data);
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);
1066 if (NULL != user_data) g_free(user_data);
1070 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
1071 ret = mm_player_ignore_session(player->player_handle);
1072 if (MM_ERROR_NONE != ret) {
1073 SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
1077 /* realize and start mm player */
1078 ret = mm_player_realize(player->player_handle);
1079 if (MM_ERROR_NONE != ret) {
1080 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
1082 if (NULL != user_data) g_free(user_data);
1086 ret = mm_player_start(player->player_handle);
1087 if (MM_ERROR_NONE != ret) {
1088 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
1089 mm_player_unrealize(player->player_handle);
1092 if (MM_ERROR_POLICY_BLOCKED == ret) {
1093 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Blocked to start player by policy : %x", ret);
1094 reason = TTSD_ERROR_AUDIO_POLICY_BLOCKED;
1096 reason = TTSD_ERROR_OPERATION_FAILED;
1099 if (NULL != user_data) {
1100 ttsd_data_set_error_data(user_data->uid, user_data->utt_id, reason);
1106 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
1107 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
1108 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
1109 * the player should send utt started event.
1111 if (TTSP_RESULT_EVENT_START == wdata.event ||
1112 (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
1114 pid = ttsd_data_get_pid(player->uid);
1116 /* send utterance start message */
1117 if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
1118 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);
1121 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
1124 g_playing_info = player;
1126 if (NULL != sound_file)
1128 if (NULL != wdata.data)