2 * Copyright (c) 2011 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>
20 #include "ttsd_main.h"
21 #include "ttsd_player.h"
22 #include "ttsd_data.h"
23 #include "ttsd_dbus.h"
27 * Internal data structure
30 #define TEMP_FILE_MAX 36
43 short bits_per_sample;
49 int uid; /** client id */
50 MMHandleType player_handle; /** mm player handle */
51 int utt_id; /** utt_id of next file */
52 ttsp_result_event_e event; /** event of callback */
58 ttsp_result_event_e event;
59 char filename[TEMP_FILE_MAX];
67 #define TEMP_FILE_PATH "/tmp"
68 #define FILE_PATH_SIZE 256
70 /** player init info */
71 static bool g_player_init = false;
73 /** tts engine list */
74 static GList *g_player_list;
76 /** current player information */
77 static player_s* g_playing_info;
79 /** player callback function */
80 static player_result_callback_func g_result_callback;
82 /** numbering for temp file */
83 static unsigned int g_index;
90 player_s* __player_get_item(int uid);
92 int __save_file(const int uid, const int index, const sound_data_s data, char** filename);
94 int __set_and_start(player_s* player);
96 int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
98 static int msg_callback(int message, void *data, void *user_param) ;
105 int ttsd_player_init(player_result_callback_func result_cb)
107 if (NULL == result_cb) {
108 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] invalid parameter");
109 return TTSD_ERROR_INVALID_PARAMETER;
112 g_result_callback = result_cb;
114 g_playing_info = NULL;
117 g_player_init = true;
122 int ttsd_player_release(void)
124 if (false == g_player_init) {
125 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized");
126 return TTSD_ERROR_OPERATION_FAILED;
129 /* clear g_player_list */
130 g_playing_info = NULL;
131 g_player_init = false;
136 int ttsd_player_create_instance(const int uid)
138 if (false == g_player_init) {
139 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
143 /* Check uid is duplicated */
144 if (NULL != __player_get_item(uid)) {
145 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is already registered", uid);
149 int ret = MM_ERROR_NONE;
150 MMHandleType player_handle;
152 ret = mm_player_create(&player_handle);
153 if (ret != MM_ERROR_NONE || 0 == player_handle) {
154 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_create() : %x", ret);
158 player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
160 new_client->uid = uid;
161 new_client->player_handle = player_handle;
162 new_client->utt_id = -1;
163 new_client->event = TTSP_RESULT_EVENT_FINISH;
165 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
167 g_player_list = g_list_append(g_player_list, new_client);
173 int ttsd_player_destroy_instance(int uid)
175 if (false == g_player_init) {
176 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
181 current = __player_get_item(uid);
182 if (NULL == current) {
183 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
187 if (NULL != g_playing_info) {
188 if (uid == g_playing_info->uid) {
189 g_playing_info = NULL;
193 MMPlayerStateType player_state;
194 mm_player_get_state(current->player_handle, &player_state);
196 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
200 switch (player_state) {
201 case MM_PLAYER_STATE_PLAYING:
202 case MM_PLAYER_STATE_PAUSED:
203 case MM_PLAYER_STATE_READY:
204 ret = mm_player_unrealize(current->player_handle);
205 if (MM_ERROR_NONE != ret) {
206 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
208 /* NO break for destroy */
210 case MM_PLAYER_STATE_NULL:
211 ret = mm_player_destroy(current->player_handle);
212 if (MM_ERROR_NONE != ret) {
213 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_destroy() : %x", ret);
222 player_s *data = NULL;
224 if (0 < g_list_length(g_player_list)) {
225 /* Get a first item */
226 iter = g_list_first(g_player_list);
228 while (NULL != iter) {
229 /* Get handle data from list */
230 data = (player_s*)iter->data;
233 if (uid == data->uid) {
234 g_player_list = g_list_remove_link(g_player_list, iter);
242 iter = g_list_next(iter);
246 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER Success] Destroy instance");
251 int ttsd_player_play(const int uid)
253 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] start play : uid(%d)", uid );
255 if (false == g_player_init) {
256 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
260 if (NULL != g_playing_info) {
261 if (uid == g_playing_info->uid) {
262 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] uid(%d) has already played", g_playing_info->uid);
267 /* Check sound queue size */
268 if (0 == ttsd_data_get_sound_data_size(uid)) {
269 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", uid);
275 current = __player_get_item(uid);
276 if (NULL == current) {
277 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
281 MMPlayerStateType player_state;
282 mm_player_get_state(current->player_handle, &player_state);
284 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
286 switch (player_state) {
287 case MM_PLAYER_STATE_PLAYING:
288 SLOG(LOG_WARN, TAG_TTSD, "[Player] Current player is playing. Do not start new sound.");
291 case MM_PLAYER_STATE_PAUSED:
292 SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is paused. Do not start new sound.");
295 case MM_PLAYER_STATE_READY:
296 SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is ready for next play. Do not start new sound.");
299 case MM_PLAYER_STATE_NULL:
302 case MM_PLAYER_STATE_NONE:
303 SLOG(LOG_WARN, TAG_TTSD, "[Player] Player is created. Do not start new sound.");
311 ret = __set_and_start(current);
313 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to set or start mm_player");
316 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Started play and wait for played callback : uid(%d)", uid);
321 int ttsd_player_next_play(int uid)
323 if (false == g_player_init) {
324 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
330 current = __player_get_item(uid);
331 if (NULL == current) {
332 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
333 g_playing_info = NULL;
337 if (NULL != g_playing_info) {
338 if (uid != g_playing_info->uid) {
339 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
343 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player do NOT exist");
347 MMPlayerStateType player_state;
348 mm_player_get_state(current->player_handle, &player_state);
350 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] State changed : state(%d)", player_state);
354 switch (player_state) {
355 case MM_PLAYER_STATE_PLAYING:
356 case MM_PLAYER_STATE_PAUSED:
357 case MM_PLAYER_STATE_READY:
358 ret = mm_player_unrealize(current->player_handle);
359 if (MM_ERROR_NONE != ret) {
360 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
365 case MM_PLAYER_STATE_NULL:
372 /* Check sound queue size */
373 if (0 == ttsd_data_get_sound_data_size(uid)) {
374 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", uid);
375 g_playing_info = NULL;
379 ret = __set_and_start(current);
381 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to set or start mm_player");
384 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Started play and wait for played callback : uid(%d)", uid);
390 int ttsd_player_stop(const int uid)
392 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] stop player : uid(%d)", uid );
394 if (false == g_player_init) {
395 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
401 current = __player_get_item(uid);
402 if (NULL == current) {
403 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
407 /* check whether uid is current playing or not */
408 if (NULL != g_playing_info) {
409 if (uid == g_playing_info->uid) {
410 /* release current playing info */
411 g_playing_info = NULL;
414 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] No current playing");
417 current->utt_id = -1;
419 MMPlayerStateType player_state;
420 mm_player_get_state(current->player_handle, &player_state);
422 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
425 switch (player_state) {
426 case MM_PLAYER_STATE_PLAYING:
427 case MM_PLAYER_STATE_PAUSED:
428 case MM_PLAYER_STATE_READY:
429 ret = mm_player_unrealize(current->player_handle);
430 if (MM_ERROR_NONE != ret) {
431 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
436 case MM_PLAYER_STATE_NULL:
443 SLOG(LOG_DEBUG, TAG_TTSD, "[Player SUCCESS] Stop player : uid(%d)", uid);
448 int ttsd_player_pause(const int uid)
450 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] pause player : uid(%d)", uid );
452 if (false == g_player_init) {
453 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
459 current = __player_get_item(uid);
460 if (NULL == current) {
461 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
465 /* check whether uid is current playing or not */
466 if (NULL != g_playing_info) {
467 if (uid == g_playing_info->uid) {
468 /* release current playing info */
469 g_playing_info = NULL;
475 MMPlayerStateType player_state;
476 mm_player_get_state(current->player_handle, &player_state);
478 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
481 if (MM_PLAYER_STATE_PLAYING == player_state) {
482 ret = mm_player_pause(current->player_handle);
483 if (MM_ERROR_NONE != ret) {
484 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_pause : %x ", ret);
487 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current player is NOT 'playing'");
494 int ttsd_player_resume(const int uid)
496 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Resume player : uid(%d)", uid );
498 if (false == g_player_init) {
499 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
505 current = __player_get_item(uid);
506 if (NULL == current) {
507 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
511 /* check current player */
512 if (NULL != g_playing_info)
513 g_playing_info = NULL;
516 MMPlayerStateType player_state;
517 mm_player_get_state(current->player_handle, &player_state);
519 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
522 if (MM_PLAYER_STATE_PAUSED == player_state) {
523 ret = mm_player_resume(current->player_handle);
524 if (MM_ERROR_NONE != ret) {
525 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_resume() : %d", ret);
528 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] Resume player");
531 g_playing_info = current;
533 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] Current uid is NOT paused state.");
539 int ttsd_player_get_current_client()
541 if (false == g_player_init) {
542 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
546 if (NULL != g_playing_info)
547 return g_playing_info->uid;
549 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] No current player");
554 int ttsd_player_get_current_utterance_id(const int uid)
556 SLOG(LOG_DEBUG, TAG_TTSD, "[Player] get current utt id : uid(%d)", uid );
558 if (false == g_player_init) {
559 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
565 current = __player_get_item(uid);
566 if (NULL == current) {
567 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] uid(%d) is not valid", uid);
571 return current->utt_id;
574 int ttsd_player_all_stop()
576 if (false == g_player_init) {
577 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Not Initialized" );
581 g_playing_info = NULL;
585 player_s *data = NULL;
587 if (0 < g_list_length(g_player_list)) {
588 /* Get a first item */
589 iter = g_list_first(g_player_list);
591 while (NULL != iter) {
592 /* Get handle data from list */
593 data = (player_s*)iter->data;
596 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
597 SLOG(LOG_ERROR, TAG_TTSD, "[player ERROR] ttsd_player_all_stop : uid is not valid ");
598 ttsd_player_destroy_instance(data->uid);
599 iter = g_list_next(iter);
603 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
604 /* unrealize player */
605 ret = mm_player_unrealize(data->player_handle);
606 if (MM_ERROR_NONE != ret) {
607 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_unrealize() : %x", ret);
611 data->event = TTSP_RESULT_EVENT_FINISH;
615 iter = g_list_next(iter);
619 SLOG(LOG_DEBUG, TAG_TTSD, "[Player SUCCESS] player all stop!! ");
624 static Eina_Bool __player_next_play(void *data)
626 SLOG(LOG_DEBUG, TAG_TTSD, "===== PLAYER NEXT PLAY");
628 int* uid = (int*)data;
630 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid = %d", *uid);
632 if (0 != ttsd_player_next_play(*uid)) {
633 SLOG(LOG_WARN, TAG_TTSD, "[PLAYER WARNING] Fail to play next");
639 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
640 SLOG(LOG_DEBUG, TAG_TTSD, " ");
645 static int msg_callback(int message, void *data, void *user_param)
647 user_data_s* user_data;
649 user_data = (user_data_s*)user_param;
651 int uid = user_data->uid;
652 int utt_id = user_data->utt_id;
654 MMMessageParamType *msg = (MMMessageParamType*)data;
657 case MM_MESSAGE_ERROR:
659 SLOG(LOG_DEBUG, TAG_TTSD, "===== PLAYER ERROR CALLBACK");
660 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
662 /* send error info */
663 g_result_callback(PLAYER_ERROR, uid, utt_id);
666 current = __player_get_item(uid);
667 if (NULL == current) {
668 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
670 current->event = TTSP_RESULT_EVENT_FINISH;
673 if (NULL != user_data)
676 /* check current player */
677 if (NULL != g_playing_info) {
678 if (uid == g_playing_info->uid) {
679 g_playing_info = NULL;
680 SLOG(LOG_WARN, TAG_TTSD, "[PLAYER] Current Player is NOT uid(%d)", uid);
684 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
685 SLOG(LOG_DEBUG, TAG_TTSD, " ");
687 break; /*MM_MESSAGE_ERROR*/
689 case MM_MESSAGE_BEGIN_OF_STREAM:
691 SLOG(LOG_DEBUG, TAG_TTSD, "===== BEGIN OF STREAM CALLBACK");
695 current = __player_get_item(uid);
696 if (NULL == current) {
697 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER] uid(%d) is NOT valid ", uid);
701 if (TTSP_RESULT_EVENT_START == user_data->event ||
702 (TTSP_RESULT_EVENT_FINISH == current->event && TTSP_RESULT_EVENT_FINISH == user_data->event)) {
704 pid = ttsd_data_get_pid(uid);
706 /* send utterance start message */
707 if (0 == ttsdc_send_utt_start_message(pid, uid, utt_id)) {
708 SLOG(LOG_DEBUG, TAG_TTSD, "[Send SUCCESS] Send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
710 SLOG(LOG_ERROR, TAG_TTSD, "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
712 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Don't need to send Utterance Start Signal");
715 /* set current playing info */
716 current->utt_id = utt_id;
717 current->event = user_data->event;
718 g_playing_info = current;
721 ttsd_data_get_client_state(uid, &state);
723 /* for sync problem */
724 if (APP_STATE_PAUSED == state) {
725 MMPlayerStateType player_state;
726 mm_player_get_state(current->player_handle, &player_state);
728 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] Current state(%d)", player_state);
731 if (MM_PLAYER_STATE_PLAYING == player_state) {
732 ret = mm_player_pause(current->player_handle);
733 if (MM_ERROR_NONE != ret) {
734 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] fail mm_player_pause() : %x", ret);
736 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid(%d) changes 'Pause' state ", uid);
741 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
742 SLOG(LOG_DEBUG, TAG_TTSD, " ");
746 case MM_MESSAGE_END_OF_STREAM:
748 SLOG(LOG_DEBUG, TAG_TTSD, "===== END OF STREAM CALLBACK");
749 remove(user_data->filename);
753 current = __player_get_item(uid);
754 if (NULL == current) {
755 SLOG(LOG_ERROR, TAG_TTSD, "[PLAYER ERROR] uid(%d) is NOT valid", uid);
756 if (NULL != g_playing_info) {
757 if (uid == g_playing_info->uid) {
758 g_playing_info = NULL;
759 SLOG(LOG_WARN, TAG_TTSD, "[PLAYER] Current Player is NOT uid(%d)", uid);
762 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
763 SLOG(LOG_DEBUG, TAG_TTSD, " ");
767 if (NULL != user_data)
770 int pid = ttsd_data_get_pid(uid);
772 /* send utterence finish signal */
773 if (TTSP_RESULT_EVENT_FINISH == current->event) {
774 if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
775 SLOG(LOG_DEBUG, TAG_TTSD, "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
777 SLOG(LOG_ERROR, TAG_TTSD, "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
780 int* uid_data = (int*) g_malloc0(sizeof(int));
783 SLOG(LOG_DEBUG, TAG_TTSD, "[PLAYER] uid = %d", *uid_data);
785 ecore_timer_add(0, __player_next_play, (void*)uid_data);
787 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
788 SLOG(LOG_DEBUG, TAG_TTSD, " ");
790 break; /*MM_MESSAGE_END_OF_STREAM*/
792 case MM_MESSAGE_STATE_CHANGED:
795 case MM_MESSAGE_STATE_INTERRUPTED:
796 if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
798 SLOG(LOG_DEBUG, TAG_TTSD, "===== INTERRUPTED CALLBACK");
800 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
802 int pid = ttsd_data_get_pid(uid);
803 /* send message to client about changing state */
804 ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
806 SLOG(LOG_DEBUG, TAG_TTSD, "=====");
807 SLOG(LOG_DEBUG, TAG_TTSD, " ");
818 player_s* __player_get_item(int uid)
821 player_s *data = NULL;
823 if (0 < g_list_length(g_player_list)) {
824 /* Get a first item */
825 iter = g_list_first(g_player_list);
827 while (NULL != iter) {
828 /* Get handle data from list */
829 data = (player_s*)iter->data;
832 if (uid == data->uid)
836 iter = g_list_next(iter);
843 int __save_file(const int uid, const int index, const sound_data_s data, char** filename)
846 memset(postfix, 0, 5);
848 switch (data.audio_type) {
849 case TTSP_AUDIO_TYPE_RAW:
850 case TTSP_AUDIO_TYPE_WAV:
851 strncpy(postfix, "wav", strlen("wav"));
853 case TTSP_AUDIO_TYPE_MP3:
854 strncpy(postfix, "mp3", strlen("mp3"));
856 case TTSP_AUDIO_TYPE_AMR:
857 strncpy(postfix, "amr", strlen("amr"));
860 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
864 /* make filename to save */
868 snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix );
871 fp = fopen(temp, "wb");
874 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] temp file open error");
878 if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
880 if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
885 if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
886 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to write wav header to file");
892 int size = fwrite(data.data, data.data_size, 1, fp);
894 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail to write date");
901 SLOG(LOG_DEBUG, TAG_TTSD, " ");
902 SLOG(LOG_DEBUG, TAG_TTSD, "Filepath : %s ", temp);
903 SLOG(LOG_DEBUG, TAG_TTSD, "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
908 int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
910 if (hdr == NULL || nsamples <= 0 || sampling_rate <= 0 || channel <= 0) {
911 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] __init_wave_header : input parameter invalid");
912 return TTSD_ERROR_INVALID_PARAMETER;
915 size_t bytesize = nsamples;
917 strncpy(hdr->riff, "RIFF", 4);
918 hdr->file_size = (int)(bytesize + 36);
919 strncpy(hdr->wave, "WAVE", 4);
920 strncpy(hdr->fmt, "fmt ", 4);
921 hdr->header_size = 16;
922 hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
923 hdr->n_channels = channel;
924 hdr->sample_rate = (int)(sampling_rate);
925 hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
926 hdr->block_align = sizeof(short);
927 hdr->bits_per_sample = sizeof(short)*8;
928 strncpy(hdr->data, "data", 4);
929 hdr->data_size = (int)bytesize;
934 int __set_and_start(player_s* player)
938 if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
939 SLOG(LOG_WARN, TAG_TTSD, "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
944 if (65534 <= g_index) {
948 /* make sound file for mmplayer */
949 char* sound_file = NULL;
950 sound_file = (char*) g_malloc0( sizeof(char) * FILE_PATH_SIZE );
952 if (0 != __save_file(player->uid, g_index, wdata, &sound_file)) {
953 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail to make sound file");
957 user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
958 user_data->uid = player->uid;
959 user_data->utt_id = wdata.utt_id;
960 user_data->event = wdata.event;
961 memset(user_data->filename, 0, TEMP_FILE_MAX);
962 strncpy( user_data->filename, sound_file, strlen(sound_file) );
964 SLOG(LOG_DEBUG, TAG_TTSD, "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
965 user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
966 SLOG(LOG_DEBUG, TAG_TTSD, " ");
970 /* set callback func */
971 ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
972 if (MM_ERROR_NONE != ret) {
973 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
977 /* set playing info to mm player */
978 char* err_attr_name = NULL;
980 if (0 != access(sound_file, R_OK)) {
981 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail to read sound file (%s)", sound_file);
985 ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
986 "profile_uri", sound_file , strlen( sound_file ) + 1,
987 "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
988 "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
991 if (MM_ERROR_NONE != ret) {
992 if (NULL != err_attr_name) {
993 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
998 /* realize and start mm player */
999 ret = mm_player_realize(player->player_handle);
1000 if (MM_ERROR_NONE != ret) {
1001 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_realize() : %x", ret);
1005 ret = mm_player_start(player->player_handle);
1006 if (MM_ERROR_NONE != ret) {
1007 SLOG(LOG_ERROR, TAG_TTSD, "[Player ERROR] fail mm_player_start() : %x", ret);
1009 mm_player_unrealize(player->player_handle);
1013 if( NULL != sound_file ) g_free(sound_file);
1014 if( NULL != wdata.data ) g_free(wdata.data);