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(const int uid, const int index, const 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(const 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);
187 int ttsd_player_destroy_instance(int uid)
189 if (false == g_player_init) {
190 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
195 current = __player_get_item(uid);
196 if (NULL == current) {
197 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
201 if (NULL != g_playing_info) {
202 if (uid == g_playing_info->uid) {
203 g_playing_info = NULL;
207 MMPlayerStateType player_state;
208 mm_player_get_state(current->player_handle, &player_state);
210 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
214 switch (player_state) {
215 case MM_PLAYER_STATE_PLAYING:
216 case MM_PLAYER_STATE_PAUSED:
217 case MM_PLAYER_STATE_READY:
218 ret = mm_player_unrealize(current->player_handle);
219 if (MM_ERROR_NONE != ret) {
220 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
222 /* NO break for destroy */
224 case MM_PLAYER_STATE_NULL:
225 ret = mm_player_destroy(current->player_handle);
226 if (MM_ERROR_NONE != ret) {
227 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_destroy() : %x", ret);
236 player_s *data = NULL;
238 if (0 < g_list_length(g_player_list)) {
239 /* Get a first item */
240 iter = g_list_first(g_player_list);
242 while (NULL != iter) {
243 /* Get handle data from list */
244 data = (player_s*)iter->data;
248 if (uid == data->uid) {
249 g_player_list = g_list_remove_link(g_player_list, iter);
256 iter = g_list_next(iter);
260 SLOG(LOG_DEBUG, get_tag(), "[PLAYER Success] Destroy instance");
265 int ttsd_player_play(const int uid)
267 SLOG(LOG_DEBUG, get_tag(), "[Player] start play : uid(%d)", uid );
269 if (false == g_player_init) {
270 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
274 if (NULL != g_playing_info) {
275 if (uid == g_playing_info->uid) {
276 SLOG(LOG_WARN, get_tag(), "[Player WARNING] uid(%d) has already played", g_playing_info->uid);
281 /* Check sound queue size */
282 if (0 == ttsd_data_get_sound_data_size(uid)) {
283 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
289 current = __player_get_item(uid);
290 if (NULL == current) {
291 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
295 MMPlayerStateType player_state;
296 mm_player_get_state(current->player_handle, &player_state);
298 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
300 switch (player_state) {
301 case MM_PLAYER_STATE_PLAYING:
302 SLOG(LOG_WARN, get_tag(), "[Player] Current player is playing. Do not start new sound.");
305 case MM_PLAYER_STATE_PAUSED:
306 SLOG(LOG_WARN, get_tag(), "[Player] Player is paused. Do not start new sound.");
309 case MM_PLAYER_STATE_READY:
310 SLOG(LOG_WARN, get_tag(), "[Player] Player is ready for next play. Do not start new sound.");
313 case MM_PLAYER_STATE_NULL:
316 case MM_PLAYER_STATE_NONE:
317 SLOG(LOG_WARN, get_tag(), "[Player] Player is created. Do not start new sound.");
325 ret = __set_and_start(current);
327 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
330 SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
335 int ttsd_player_next_play(int uid)
337 if (false == g_player_init) {
338 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
344 current = __player_get_item(uid);
345 if (NULL == current) {
346 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
347 g_playing_info = NULL;
351 if (NULL != g_playing_info) {
352 if (uid != g_playing_info->uid) {
353 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
357 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player do NOT exist");
361 MMPlayerStateType player_state;
362 mm_player_get_state(current->player_handle, &player_state);
364 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
368 switch (player_state) {
369 case MM_PLAYER_STATE_PLAYING:
370 case MM_PLAYER_STATE_PAUSED:
371 case MM_PLAYER_STATE_READY:
372 ret = mm_player_unrealize(current->player_handle);
373 if (MM_ERROR_NONE != ret) {
374 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
379 case MM_PLAYER_STATE_NULL:
386 /* Check sound queue size */
387 if (0 == ttsd_data_get_sound_data_size(uid)) {
388 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
389 g_playing_info = NULL;
393 ret = __set_and_start(current);
395 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
398 SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
404 int ttsd_player_stop(const int uid)
406 SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
408 if (false == g_player_init) {
409 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
415 current = __player_get_item(uid);
416 if (NULL == current) {
417 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
421 /* check whether uid is current playing or not */
422 if (NULL != g_playing_info) {
423 if (uid == g_playing_info->uid) {
424 /* release current playing info */
425 g_playing_info = NULL;
428 SLOG(LOG_DEBUG, get_tag(), "[Player] No current playing");
431 current->utt_id = -1;
433 MMPlayerStateType player_state;
434 mm_player_get_state(current->player_handle, &player_state);
436 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
439 switch (player_state) {
440 case MM_PLAYER_STATE_PLAYING:
441 case MM_PLAYER_STATE_PAUSED:
442 case MM_PLAYER_STATE_READY:
443 ret = mm_player_unrealize(current->player_handle);
444 if (MM_ERROR_NONE != ret) {
445 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
450 case MM_PLAYER_STATE_NULL:
457 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
462 int ttsd_player_pause(const int uid)
464 SLOG(LOG_DEBUG, get_tag(), "[Player] pause player : uid(%d)", uid );
466 if (false == g_player_init) {
467 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
473 current = __player_get_item(uid);
474 if (NULL == current) {
475 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
479 /* check whether uid is current playing or not */
480 if (NULL != g_playing_info) {
481 if (uid == g_playing_info->uid) {
482 /* release current playing info */
483 g_playing_info = NULL;
489 MMPlayerStateType player_state;
490 mm_player_get_state(current->player_handle, &player_state);
492 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
495 if (MM_PLAYER_STATE_PLAYING == player_state) {
496 ret = mm_player_pause(current->player_handle);
497 if (MM_ERROR_NONE != ret) {
498 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_pause : %x ", ret);
501 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player is NOT 'playing'");
508 int ttsd_player_resume(const int uid)
510 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player : uid(%d)", uid );
512 if (false == g_player_init) {
513 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
519 current = __player_get_item(uid);
520 if (NULL == current) {
521 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
525 /* check current player */
526 if (NULL != g_playing_info)
527 g_playing_info = NULL;
530 MMPlayerStateType player_state;
531 mm_player_get_state(current->player_handle, &player_state);
533 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
536 if (MM_PLAYER_STATE_PAUSED == player_state) {
537 /* When the 'Paused' state of player after end of play */
538 if (g_pause_info == true && g_paused_uid == uid) {
539 g_playing_info = current;
541 g_pause_info = false;
544 /* Current state need load and play */
545 ret = ttsd_player_next_play(uid);
547 SLOG(LOG_ERROR, get_tag(), "[player] Fail to next play in resume function");
550 ret = mm_player_resume(current->player_handle);
551 if (MM_ERROR_NONE != ret) {
552 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_resume() : %d", ret);
555 SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player");
558 g_playing_info = current;
561 SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current uid is NOT paused state.");
567 int ttsd_player_get_current_client()
569 if (false == g_player_init) {
570 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
574 if (NULL != g_playing_info)
575 return g_playing_info->uid;
577 SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
582 int ttsd_player_get_current_utterance_id(const int uid)
584 SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
586 if (false == g_player_init) {
587 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
593 current = __player_get_item(uid);
594 if (NULL == current) {
595 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
599 return current->utt_id;
602 int ttsd_player_all_stop()
604 if (false == g_player_init) {
605 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
609 g_playing_info = NULL;
613 player_s *data = NULL;
615 if (0 < g_list_length(g_player_list)) {
616 /* Get a first item */
617 iter = g_list_first(g_player_list);
619 while (NULL != iter) {
620 /* Get handle data from list */
621 data = (player_s*)iter->data;
624 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
625 SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
626 ttsd_player_destroy_instance(data->uid);
627 iter = g_list_next(iter);
631 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
632 /* unrealize player */
633 ret = mm_player_unrealize(data->player_handle);
634 if (MM_ERROR_NONE != ret) {
635 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
639 data->event = TTSP_RESULT_EVENT_FINISH;
643 iter = g_list_next(iter);
647 SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
652 static Eina_Bool __player_next_play(void *data)
654 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
656 int* uid = (int*)data;
659 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
660 SLOG(LOG_DEBUG, get_tag(), "=====");
661 SLOG(LOG_DEBUG, get_tag(), " ");
665 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
667 if (0 != ttsd_player_next_play(*uid)) {
668 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
673 SLOG(LOG_DEBUG, get_tag(), "=====");
674 SLOG(LOG_DEBUG, get_tag(), " ");
679 static int msg_callback(int message, void *data, void *user_param)
681 user_data_s* user_data = NULL;
683 user_data = (user_data_s*)user_param;
685 if (NULL == user_data) {
686 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
690 int uid = user_data->uid;
691 int utt_id = user_data->utt_id;
693 MMMessageParamType *msg = (MMMessageParamType*)data;
696 case MM_MESSAGE_ERROR:
698 SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
699 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
701 /* send error info */
702 g_result_callback(PLAYER_ERROR, uid, utt_id);
705 current = __player_get_item(uid);
706 if (NULL == current) {
707 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
709 current->event = TTSP_RESULT_EVENT_FINISH;
712 if (NULL != user_data)
715 /* check current player */
716 if (NULL != g_playing_info) {
717 if (uid == g_playing_info->uid) {
718 g_playing_info = NULL;
719 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
723 SLOG(LOG_DEBUG, get_tag(), "=====");
724 SLOG(LOG_DEBUG, get_tag(), " ");
726 break; /*MM_MESSAGE_ERROR*/
728 case MM_MESSAGE_BEGIN_OF_STREAM:
732 case MM_MESSAGE_END_OF_STREAM:
734 SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
736 if (-1 == remove(user_data->filename)) {
737 SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
742 current = __player_get_item(uid);
743 if (NULL == current) {
744 SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
745 if (NULL != g_playing_info) {
746 if (uid == g_playing_info->uid) {
747 g_playing_info = NULL;
748 SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
751 SLOG(LOG_DEBUG, get_tag(), "=====");
752 SLOG(LOG_DEBUG, get_tag(), " ");
758 int pid = ttsd_data_get_pid(uid);
760 /* send utterence finish signal */
761 if (TTSP_RESULT_EVENT_FINISH == current->event) {
762 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
763 SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
765 SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
768 /* for sync problem */
769 MMPlayerStateType player_state;
770 mm_player_get_state(current->player_handle, &player_state);
772 if (MM_PLAYER_STATE_PAUSED == player_state) {
773 g_pause_info = true; /* The current state of player is 'Paused' */
774 g_paused_uid = uid; /* The current uid when the current state player is 'Paused' */
777 int* uid_data = (int*) g_malloc0(sizeof(int));
780 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
782 ecore_timer_add(0, __player_next_play, (void*)uid_data);
785 SLOG(LOG_DEBUG, get_tag(), "=====");
786 SLOG(LOG_DEBUG, get_tag(), " ");
788 break; /*MM_MESSAGE_END_OF_STREAM*/
790 case MM_MESSAGE_STATE_CHANGED:
793 case MM_MESSAGE_STATE_INTERRUPTED:
794 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
796 SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
798 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
800 int pid = ttsd_data_get_pid(uid);
801 /* send message to client about changing state */
802 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
804 SLOG(LOG_DEBUG, get_tag(), "=====");
805 SLOG(LOG_DEBUG, get_tag(), " ");
816 player_s* __player_get_item(int uid)
819 player_s *data = NULL;
821 if (0 < g_list_length(g_player_list)) {
822 /* Get a first item */
823 iter = g_list_first(g_player_list);
825 while (NULL != iter) {
826 /* Get handle data from list */
827 data = (player_s*)iter->data;
830 if (uid == data->uid)
834 iter = g_list_next(iter);
841 int __save_file(const int uid, const int index, const sound_data_s data, char** filename)
844 memset(postfix, '\0', 5);
846 switch (data.audio_type) {
847 case TTSP_AUDIO_TYPE_RAW:
848 case TTSP_AUDIO_TYPE_WAV:
849 strcpy(postfix, "wav");
851 case TTSP_AUDIO_TYPE_MP3:
852 strcpy(postfix, "mp3");
854 case TTSP_AUDIO_TYPE_AMR:
855 strcpy(postfix, "amr");
858 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
862 /* make filename to save */
864 temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
866 SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
870 int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
879 fp = fopen(temp, "wb");
882 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
888 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
890 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
897 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
898 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
906 int size = fwrite(data.data, data.data_size, 1, fp);
908 size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
910 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
921 SLOG(LOG_DEBUG, get_tag(), " ");
922 SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
923 SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
928 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
930 if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
931 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
932 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
933 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
934 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
935 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
936 return TTSD_ERROR_INVALID_PARAMETER;
939 size_t bytesize = DEFAULT_FILE_SIZE;
945 /* NOT include \0(NULL) */
946 strncpy(hdr->riff, "RIFF", 4);
947 hdr->file_size = (int)(bytesize + 36);
948 strncpy(hdr->wave, "WAVE", 4);
949 strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
950 hdr->header_size = 16;
951 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
952 hdr->n_channels = channel;
953 hdr->sample_rate = (int)(sampling_rate);
954 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
955 hdr->block_align = sizeof(short);
956 hdr->bits_per_sample = sizeof(short)*8;
957 strncpy(hdr->data, "data", 4);
958 hdr->data_size = (int)bytesize;
963 int __set_and_start(player_s* player)
967 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
968 SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
973 if (10000 <= g_index) {
979 /* make sound file for mmplayer */
980 char* sound_file = NULL;
981 ret = __save_file(player->uid, g_index, wdata, &sound_file);
982 if (0 != ret || NULL == sound_file) {
983 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
987 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
988 user_data->uid = player->uid;
989 user_data->utt_id = wdata.utt_id;
990 user_data->event = wdata.event;
991 memset(user_data->filename, 0, TEMP_FILE_MAX);
992 strncpy( user_data->filename, sound_file, strlen(sound_file) );
994 SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
995 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
996 SLOG(LOG_DEBUG, get_tag(), " ");
999 /* set callback func */
1000 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
1001 if (MM_ERROR_NONE != ret) {
1002 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
1006 /* set playing info to mm player */
1007 char* err_attr_name = NULL;
1009 if (0 != access(sound_file, R_OK)) {
1010 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
1014 ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
1015 "profile_uri", sound_file , strlen(sound_file) + 1,
1016 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
1017 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
1020 if (MM_ERROR_NONE != ret) {
1021 if (NULL != err_attr_name) {
1022 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
1027 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
1028 ret = mm_player_ignore_session(player->player_handle);
1029 if (MM_ERROR_NONE != ret) {
1030 SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
1034 /* realize and start mm player */
1035 ret = mm_player_realize(player->player_handle);
1036 if (MM_ERROR_NONE != ret) {
1037 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
1041 ret = mm_player_start(player->player_handle);
1042 if (MM_ERROR_NONE != ret) {
1043 SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
1045 mm_player_unrealize(player->player_handle);
1049 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
1050 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
1051 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
1052 * the player should send utt started event.
1054 if (TTSP_RESULT_EVENT_START == wdata.event ||
1055 (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
1057 pid = ttsd_data_get_pid(player->uid);
1059 /* send utterance start message */
1060 if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
1061 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);
1064 SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
1067 g_playing_info = player;
1069 if (NULL != sound_file)
1071 if (NULL != wdata.data)