5 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
28 #include <mm_source.h>
33 #include <mm_session.h>
35 #include "include/mm_sound_mgr_common.h"
36 #include "include/mm_sound_mgr_codec.h"
37 #include "include/mm_sound_mgr_ipc.h"
38 #include "include/mm_sound_plugin_codec.h"
39 #include "include/mm_sound_thread_pool.h"
41 #include "../include/mm_sound_common.h"
42 #include "../include/mm_sound_focus.h"
44 #define _ENABLE_KEYTONE /* Temporal test code */
46 #define FOCUS_INTEGRATION
49 int (*callback)(int, void *, void *, int); /* msg_type(pid) client callback & client data info */
54 MMHandleType plughandle;
60 #ifdef FOCUS_INTEGRATION
64 mm_sound_focus_type_e current_focus_type;
68 } __mmsound_mgr_codec_handle_t;
70 static MMSoundPluginType *g_codec_plugins = NULL;
71 static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX];
72 static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM];
73 static pthread_mutex_t g_slot_mutex;
74 static pthread_mutex_t codec_wave_mutex;
75 static int _MMSoundMgrCodecStopCallback(int param);
76 static int _MMSoundMgrCodecGetEmptySlot(int *slotid);
77 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
80 #define STATUS_SOUND 3
82 #define SOUND_SLOT_START 0
84 #ifdef FOCUS_INTEGRATION
86 void sound_codec_focus_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
89 int slotid = (int)user_data;
90 int result = MM_ERROR_NONE;
92 debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
94 if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
95 debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
98 if (focus_state == FOCUS_IS_RELEASED) {
99 g_slots[slotid].current_focus_type = FOCUS_FOR_BOTH&(~focus_type);
100 debug_warning ("focus is released -> stop playing");
101 result = MMSoundMgrCodecStop(slotid);
102 if (result != MM_ERROR_NONE) {
103 debug_log("result error %d\n", result);
110 void sound_codec_focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e focus_state, const char *reason_for_change, const char* ext_info, void *user_data)
112 int slotid = (int)user_data;
113 int result = MM_ERROR_NONE;
115 debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
117 if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
118 debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
121 if (focus_state == FOCUS_IS_ACQUIRED) {
122 debug_warning ("focus is released -> stop playing");
123 result = MMSoundMgrCodecStop(slotid);
124 if (result != MM_ERROR_NONE) {
125 debug_log("result error %d\n", result);
133 void sound_codec_device_connected_callback(MMSoundDevice_t device, bool is_connected, void *user_data)
135 int slotid = (int)user_data;
136 int result = MM_ERROR_NONE;
137 mm_sound_device_type_e type;
139 debug_warning ("device_connected_callback called");
141 if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE) {
142 debug_error("getting device type failed");
145 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
146 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
147 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
148 case MM_SOUND_DEVICE_TYPE_HDMI:
149 case MM_SOUND_DEVICE_TYPE_MIRRORING:
150 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
152 debug_warning("sound device unplugged");
153 result = MMSoundMgrCodecStop(slotid);
154 if (result != MM_ERROR_NONE) {
155 debug_error("MMSoundMgrCodecStop error %d\n", result);
157 result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
158 if (result != MM_ERROR_NONE) {
159 debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
170 int MMSoundMgrCodecInit(const char *targetdir)
177 memset (g_slots, 0, sizeof(g_slots));
179 if(pthread_mutex_init(&g_slot_mutex, NULL)) {
180 debug_error("pthread_mutex_init failed\n");
181 return MM_ERROR_SOUND_INTERNAL;
184 if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
185 debug_error("pthread_mutex_init failed\n");
186 return MM_ERROR_SOUND_INTERNAL;
189 for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
190 g_slots[count].status = STATUS_IDLE;
191 g_slots[count].plughandle = 0;
194 if (g_codec_plugins) {
195 debug_warning("Please Check Init twice\n");
196 MMSoundPluginRelease(g_codec_plugins);
199 MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins);
200 if (g_codec_plugins) {
201 while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
202 _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]);
207 return MM_ERROR_NONE;
210 int MMSoundMgrCodecFini(void)
214 memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
215 MMSoundPluginRelease(g_codec_plugins);
216 g_codec_plugins = NULL;
217 pthread_mutex_destroy(&g_slot_mutex);
218 pthread_mutex_destroy(&codec_wave_mutex);
220 return MM_ERROR_NONE;
224 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
227 mmsound_codec_info_t info;
228 mmsound_codec_param_t codec_param;
229 int err = MM_ERROR_NONE;
230 #ifdef FOCUS_INTEGRATION
231 int need_focus_unregister = 0;
238 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
240 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
244 /*The count num means codec type WAV, MP3 */
245 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d], session(type[%d],option[%d])\n",
246 param->tone, param->repeat_count, param->volume, count, param->session_type, param->session_options);
248 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
249 debug_error("unsupported file type %d\n", count);
250 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
255 debug_msg("Get New handle\n");
258 err = _MMSoundMgrCodecGetEmptySlot(slotid);
259 if (err != MM_ERROR_NONE || *slotid < 0) {
260 debug_error("Empty g_slot is not found\n");
264 codec_param.tone = param->tone;
265 codec_param.volume_config = param->volume_config;
266 codec_param.repeat_count = param->repeat_count;
267 codec_param.volume = param->volume;
268 codec_param.source = param->source;
269 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
270 codec_param.param = *slotid;
271 codec_param.pid = (int)param->param;
272 codec_param.codec_wave_mutex = &codec_wave_mutex;
273 codec_param.stream_index = param->stream_index;
274 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
275 pthread_mutex_lock(&g_slot_mutex);
277 debug_msg("After Slot_mutex LOCK\n");
280 #ifdef FOCUS_INTEGRATION
282 * Register FOCUS here
285 if (param->session_type != MM_SESSION_TYPE_CALL &&
286 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
287 param->session_type != MM_SESSION_TYPE_VOIP &&
288 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
289 param->enable_session) {
291 unsigned int subs_id = 0;
293 err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
295 debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
296 pthread_mutex_unlock(&g_slot_mutex);
297 return MM_ERROR_POLICY_INTERNAL;
299 g_slots[*slotid].subs_id = subs_id;
301 if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
302 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
303 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
304 err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
306 debug_error("mm_sound_register_focus_for_session failed [0x%x]", err);
307 pthread_mutex_unlock(&g_slot_mutex);
308 return MM_ERROR_POLICY_INTERNAL;
310 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
312 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
313 err = mm_sound_unregister_focus(param->focus_handle);
314 pthread_mutex_unlock(&g_slot_mutex);
315 return MM_ERROR_POLICY_INTERNAL;
317 g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
318 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
320 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
322 debug_warning("need to set focus watch callback");
323 err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(¶m->focus_wcb_id));
325 debug_error("mm_sound_set_focus_watch_callback_for_session failed [0x%x]", err);
326 pthread_mutex_unlock(&g_slot_mutex);
327 return MM_ERROR_POLICY_INTERNAL;
334 /* Codec id WAV or MP3 */
335 g_slots[*slotid].pluginid = count;
336 g_slots[*slotid].param = param->param; /* This arg is used callback data */
337 g_slots[*slotid].session_type = param->session_type;
338 g_slots[*slotid].session_options = param->session_options;
339 #ifdef FOCUS_INTEGRATION
340 g_slots[*slotid].focus_handle = param->focus_handle;
341 g_slots[*slotid].focus_wcb_id = param->focus_wcb_id;
343 g_slots[*slotid].enable_session = true;
344 g_slots[*slotid].pid = (int)param->param;
347 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
349 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
350 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
351 if (err != MM_ERROR_NONE) {
352 debug_error("Plugin create fail : 0x%08X\n", err);
353 g_slots[*slotid].status = STATUS_IDLE;
354 pthread_mutex_unlock(&g_slot_mutex);
355 debug_warning("After Slot_mutex UNLOCK\n");
356 #ifdef FOCUS_INTEGRATION
357 if (param->focus_handle) {
358 need_focus_unregister = 1;
364 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
365 if (err != MM_ERROR_NONE) {
366 debug_error("Fail to play : 0x%08X\n", err);
367 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
368 #ifdef FOCUS_INTEGRATION
369 if (param->focus_handle) {
370 need_focus_unregister = 1;
375 pthread_mutex_unlock(&g_slot_mutex);
377 debug_msg("After Slot_mutex UNLOCK\n");
381 #ifdef FOCUS_INTEGRATION
382 if(param->session_type != MM_SESSION_TYPE_CALL &&
383 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
384 param->session_type != MM_SESSION_TYPE_VOIP &&
385 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
386 param->enable_session &&
387 need_focus_unregister == 1) {
389 if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
390 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
391 if(mm_sound_unregister_focus(param->focus_handle) || err) {
392 debug_error("focus cleaning up failed[0x%x]", err);
393 return MM_ERROR_POLICY_INTERNAL;
395 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
396 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
398 debug_error("focus watch cleaning up failed[0x%x]", err);
399 return MM_ERROR_POLICY_INTERNAL;
412 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
415 mmsound_codec_info_t info;
416 mmsound_codec_param_t codec_param;
417 int err = MM_ERROR_NONE;
423 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
425 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
429 /*The count num means codec type WAV, MP3 */
430 debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->repeat_count, param->volume, count);
432 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
433 debug_error("unsupported file type %d\n", count);
434 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
438 err = _MMSoundMgrCodecGetEmptySlot(slotid);
439 if (err != MM_ERROR_NONE || *slotid < 0) {
440 debug_error("Empty g_slot is not found\n");
444 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
445 codec_param.repeat_count = param->repeat_count;
446 codec_param.volume = param->volume;
447 codec_param.source = param->source;
448 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
449 codec_param.param = *slotid;
450 codec_param.pid = (int)param->param;
451 codec_param.codec_wave_mutex = &codec_wave_mutex;
452 codec_param.stream_index = param->stream_index;
453 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
454 pthread_mutex_lock(&g_slot_mutex);
456 debug_msg("After Slot_mutex LOCK\n");
459 /* Codec id WAV or MP3 */
460 g_slots[*slotid].pluginid = count;
461 g_slots[*slotid].param = param->param; /* This arg is used callback data */
463 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
465 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
466 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
467 if (err != MM_ERROR_NONE) {
468 debug_error("Plugin create fail : 0x%08X\n", err);
469 g_slots[*slotid].status = STATUS_IDLE;
470 pthread_mutex_unlock(&g_slot_mutex);
471 debug_warning("After Slot_mutex UNLOCK\n");
475 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
476 if (err != MM_ERROR_NONE) {
477 debug_error("Fail to play : 0x%08X\n", err);
478 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
481 pthread_mutex_unlock(&g_slot_mutex);
483 debug_msg("After Slot_mutex UNLOCK\n");
496 #define DTMF_PLUGIN_COUNT 2
497 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
501 mmsound_codec_info_t info;
502 mmsound_codec_param_t codec_param;
503 int err = MM_ERROR_NONE;
504 #ifdef FOCUS_INTEGRATION
505 int need_focus_unregister = 0;
512 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
514 codec_type = g_plugins[count].GetSupportTypes();
515 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
519 /*The count num means codec type DTMF */
520 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
522 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
523 debug_error("unsupported file type %d\n", count);
524 printf("unsupported file type %d\n", count);
525 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
530 debug_msg("Get New handle\n");
533 err = _MMSoundMgrCodecGetEmptySlot(slotid);
534 if(err != MM_ERROR_NONE || *slotid < 0)
536 debug_error("Empty g_slot is not found\n");
540 codec_param.tone = param->tone;
541 codec_param.volume_config = param->volume_config;
542 codec_param.repeat_count = param->repeat_count;
543 codec_param.volume = param->volume;
544 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
545 codec_param.param = *slotid;
546 codec_param.pid = (int)param->param;
547 codec_param.stream_index = param->stream_index;
548 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
550 pthread_mutex_lock(&g_slot_mutex);
552 debug_msg("After Slot_mutex LOCK\n");
555 #ifdef FOCUS_INTEGRATION
558 * Register FOCUS here
561 if (param->session_type != MM_SESSION_TYPE_CALL &&
562 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
563 param->session_type != MM_SESSION_TYPE_VOIP &&
564 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
565 param->enable_session) {
567 unsigned int subs_id = 0;
569 err = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, (mm_sound_device_connected_cb)sound_codec_device_connected_callback, (void*) *slotid, &subs_id);
571 debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
572 pthread_mutex_unlock(&g_slot_mutex);
573 return MM_ERROR_POLICY_INTERNAL;
575 g_slots[*slotid].subs_id = subs_id;
577 if ((param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
578 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
579 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
580 err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
582 debug_error("mm_sound_register_focus failed [0x%x]", err);
583 pthread_mutex_unlock(&g_slot_mutex);
584 return MM_ERROR_POLICY_INTERNAL;
586 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
588 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
589 err = mm_sound_unregister_focus(param->focus_handle);
590 pthread_mutex_unlock(&g_slot_mutex);
591 return MM_ERROR_POLICY_INTERNAL;
593 g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
594 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
596 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
598 debug_warning("need to set focus watch callback");
599 err = mm_sound_set_focus_watch_callback_for_session((int)param->param, FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(¶m->focus_wcb_id));
601 debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
602 pthread_mutex_unlock(&g_slot_mutex);
603 return MM_ERROR_POLICY_INTERNAL;
609 g_slots[*slotid].pluginid = count;
610 g_slots[*slotid].param = param->param; /* This arg is used callback data */
611 g_slots[*slotid].session_type = param->session_type;
612 g_slots[*slotid].session_options = param->session_options;
613 #ifdef FOCUS_INTEGRATION
614 g_slots[*slotid].focus_handle= param->focus_handle;
615 g_slots[*slotid].focus_wcb_id= param->focus_wcb_id;
617 g_slots[*slotid].enable_session = param->enable_session;
618 g_slots[*slotid].pid = (int)param->param;
621 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
624 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
625 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
626 if (err != MM_ERROR_NONE) {
627 debug_error("Plugin create fail : 0x%08X\n", err);
628 g_slots[*slotid].status = STATUS_IDLE;
629 pthread_mutex_unlock(&g_slot_mutex);
630 debug_warning("After Slot_mutex UNLOCK\n");
631 #ifdef FOCUS_INTEGRATION
632 need_focus_unregister = 1;
637 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
638 if (err != MM_ERROR_NONE) {
639 debug_error("Fail to play : 0x%08X\n", err);
640 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
641 #ifdef FOCUS_INTEGRATION
642 need_focus_unregister = 1;
646 pthread_mutex_unlock(&g_slot_mutex);
648 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
650 debug_msg("After Slot_mutex UNLOCK\n")
654 #ifdef FOCUS_INTEGRATION
655 if (param->session_type != MM_SESSION_TYPE_CALL &&
656 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
657 param->session_type != MM_SESSION_TYPE_VOIP &&
658 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
659 param->enable_session &&
660 need_focus_unregister == 1) {
662 if (param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS || param->session_type == MM_SESSION_TYPE_ALARM || param->session_type == MM_SESSION_TYPE_NOTIFY || param->session_type == MM_SESSION_TYPE_EMERGENCY) {
663 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
664 if(mm_sound_unregister_focus(param->focus_handle) || err) {
665 debug_error("focus cleaning up failed[0x%x]", err);
666 return MM_ERROR_POLICY_INTERNAL;
668 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
669 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
671 debug_error("focus watch cleaning up failed[0x%x]", err);
672 return MM_ERROR_POLICY_INTERNAL;
685 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
689 mmsound_codec_info_t info;
690 mmsound_codec_param_t codec_param;
691 int err = MM_ERROR_NONE;
697 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
699 codec_type = g_plugins[count].GetSupportTypes();
700 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
704 /*The count num means codec type DTMF */
705 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
707 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
708 debug_error("unsupported file type %d\n", count);
709 printf("unsupported file type %d\n", count);
710 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
715 debug_msg("Get New handle\n");
718 err = _MMSoundMgrCodecGetEmptySlot(slotid);
719 if(err != MM_ERROR_NONE || *slotid < 0)
721 debug_error("Empty g_slot is not found\n");
725 codec_param.tone = param->tone;
726 codec_param.repeat_count = param->repeat_count;
727 codec_param.volume = param->volume;
728 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
729 codec_param.param = *slotid;
730 codec_param.pid = (int)param->param;
731 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
732 codec_param.stream_index = param->stream_index;
733 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
735 pthread_mutex_lock(&g_slot_mutex);
737 debug_msg("After Slot_mutex LOCK\n");
739 g_slots[*slotid].pluginid = count;
740 g_slots[*slotid].param = param->param; /* This arg is used callback data */
741 g_slots[*slotid].enable_session = param->enable_session;
744 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
747 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
748 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
749 if (err != MM_ERROR_NONE) {
750 debug_error("Plugin create fail : 0x%08X\n", err);
751 g_slots[*slotid].status = STATUS_IDLE;
752 pthread_mutex_unlock(&g_slot_mutex);
753 debug_warning("After Slot_mutex UNLOCK\n");
757 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
758 if (err != MM_ERROR_NONE) {
759 debug_error("Fail to play : 0x%08X\n", err);
760 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
763 pthread_mutex_unlock(&g_slot_mutex);
765 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
767 debug_msg("After Slot_mutex UNLOCK\n");
779 int MMSoundMgrCodecStop(const int slotid)
781 int err = MM_ERROR_NONE;
783 debug_enter("(Slotid : [%d])\n", slotid);
785 if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
786 return MM_ERROR_INVALID_ARGUMENT;
789 pthread_mutex_lock (&g_slot_mutex);
791 debug_msg("After Slot_mutex LOCK\n");
793 if (g_slots[slotid].status == STATUS_IDLE) {
794 err = MM_ERROR_SOUND_INVALID_STATE;
795 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
799 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
802 err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
803 if (err != MM_ERROR_NONE) {
804 debug_error("Fail to STOP Code : 0x%08X\n", err);
806 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
808 pthread_mutex_unlock(&g_slot_mutex);
810 debug_msg("After Slot_mutex UNLOCK\n");
812 debug_leave("(err : 0x%08X)\n", err);
816 #ifdef FOCUS_INTEGRATION
817 int MMSoundMgrCodecClearFocus(int pid)
819 int err = MM_ERROR_NONE;
822 debug_enter("(pid : [%d])\n", pid);
824 pthread_mutex_lock (&g_slot_mutex);
826 for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
827 if (g_slots[slotid].pid == pid) {
828 if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
829 if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
830 g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
831 g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
832 g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
833 g_slots[slotid].enable_session ) {
834 if ((g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[slotid].session_type == MM_SESSION_TYPE_ALARM || g_slots[slotid].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[slotid].session_type == MM_SESSION_TYPE_EMERGENCY) {
835 err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
837 debug_error("mm_sound_release_focus failed [0x%x]", err);
839 if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
840 debug_error("Focus clean up failed [0x%x]", err);
841 err = MM_ERROR_POLICY_INTERNAL;
844 } else if (~(g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
845 err = mm_sound_unset_focus_watch_callback(g_slots[slotid].focus_wcb_id);
847 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
848 err = MM_ERROR_POLICY_INTERNAL;
853 if(mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
854 debug_error("mm_sound_remove_device_connected_callback() failed");
855 g_slots[slotid].focus_handle = 0;
856 g_slots[slotid].focus_wcb_id = 0;
857 g_slots[slotid].subs_id = 0;
863 pthread_mutex_unlock(&g_slot_mutex);
864 debug_leave("(err : 0x%08X)\n", err);
870 static int _MMSoundMgrCodecStopCallback(int param)
872 int err = MM_ERROR_NONE;
874 debug_enter("(Slot : %d)\n", param);
876 if (param < 0 || param >= MANAGER_HANDLE_MAX) {
877 debug_error ("Slot index param [%d] is invalid", param);
878 return MM_ERROR_INVALID_ARGUMENT;
881 pthread_mutex_lock(&g_slot_mutex);
882 debug_msg("[CODEC MGR] Slot_mutex lock done\n");
884 #ifdef FOCUS_INTEGRATION
886 * Unregister FOCUS here
888 debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
890 if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
891 if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
892 g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
893 g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
894 g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
895 g_slots[param].enable_session ) {
896 if ((g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS) || g_slots[param].session_type == MM_SESSION_TYPE_ALARM || g_slots[param].session_type == MM_SESSION_TYPE_NOTIFY || g_slots[param].session_type == MM_SESSION_TYPE_EMERGENCY) {
897 if(g_slots[param].current_focus_type != FOCUS_NONE) {
898 err = mm_sound_release_focus(g_slots[param].focus_handle, g_slots[param].current_focus_type, NULL);
900 debug_error("mm_sound_release_focus failed [0x%x]", err);
903 if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
904 debug_error("Focus clean up failed [0x%x]", err);
905 pthread_mutex_unlock(&g_slot_mutex);
906 return MM_ERROR_POLICY_INTERNAL;
908 } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
909 err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
911 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
912 pthread_mutex_unlock(&g_slot_mutex);
913 return MM_ERROR_POLICY_INTERNAL;
917 if(mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
918 debug_error("mm_sound_remove_device_connected_callback() failed");
922 __mm_sound_mgr_ipc_notify_play_file_end(param);
924 debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
925 debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
926 err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
928 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
930 memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
931 g_slots[param].status = STATUS_IDLE;
932 pthread_mutex_unlock(&g_slot_mutex);
933 debug_msg("[CODEC MGR] Slot_mutex done\n");
938 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
941 int err = MM_ERROR_NONE;
946 debug_msg("Codec slot ID : [%d]\n", *slot);
947 pthread_mutex_lock(&g_slot_mutex);
949 debug_msg("After Slot_mutex LOCK\n");
952 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
953 if (g_slots[count].status == STATUS_IDLE) {
954 g_slots[count].status = STATUS_SOUND;
958 pthread_mutex_unlock(&g_slot_mutex);
960 debug_msg("After Slot_mutex UNLOCK\n");
963 if (count < MANAGER_HANDLE_MAX) {
964 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
968 debug_warning("Handle is full handle : [%d]\n", count);
970 /* Temporal code for reset */
972 g_slots[count].status = STATUS_IDLE;
974 err = MM_ERROR_SOUND_INTERNAL;
984 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
986 int err = MM_ERROR_NONE;
988 void *getinterface = NULL;
994 /* find emptry slot */
995 for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
996 if (g_plugins[count].GetSupportTypes == NULL)
1000 if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
1001 debug_critical("The plugin support type is not valid\n");
1002 return MM_ERROR_COMMON_OUT_OF_RANGE;
1005 err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
1006 if (err != MM_ERROR_NONE) {
1007 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
1010 debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
1012 err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
1013 if (err != MM_ERROR_NONE) {
1014 debug_error("Get interface fail : %x\n", err);
1017 /* If error occur, clean interface */
1018 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
1020 if (g_plugins[count].SetThreadPool)
1021 g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);