4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <mm_source.h>
32 #include <mm_session.h>
34 #include "include/mm_sound_mgr_common.h"
35 #include "include/mm_sound_mgr_codec.h"
36 #include "include/mm_sound_mgr_ipc.h"
37 #include "include/mm_sound_plugin_codec.h"
38 #include "include/mm_sound_thread_pool.h"
39 #include "include/mm_sound_pa_client.h"
40 #include "../include/mm_sound_focus.h"
44 #define _ENABLE_KEYTONE /* Temporal test code */
47 int (*callback)(int, void *, void *, int); /* msg_type(pid) client callback & client data info */
52 MMHandleType plughandle;
62 } __mmsound_mgr_codec_handle_t;
64 static MMSoundPluginType *g_codec_plugins = NULL;
65 static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX];
66 static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM];
67 static pthread_mutex_t g_slot_mutex;
68 static pthread_mutex_t codec_wave_mutex;
69 static int _MMSoundMgrCodecStopCallback(int param);
70 static int _MMSoundMgrCodecGetEmptySlot(int *slotid);
71 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
74 #define STATUS_SOUND 3
76 #define SOUND_SLOT_START 0
78 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, const char *additional_info, void *user_data)
81 int slotid = (int)user_data;
82 int result = MM_ERROR_NONE;
84 debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
86 if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
87 debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
90 if (focus_state == FOCUS_IS_RELEASED) {
91 debug_warning ("focus is released -> stop playing");
92 result = MMSoundMgrCodecStop(slotid);
93 if (result != MM_ERROR_NONE) {
94 debug_log("result error %d\n", result);
101 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* additional_info, void *user_data)
103 int slotid = (int)user_data;
104 int result = MM_ERROR_NONE;
106 debug_warning ("focus callback called -> focus_stae(%d), reasoun_for_change(%s)", focus_state, reason_for_change ? reason_for_change : "N/A");
108 if(g_slots[slotid].session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE){
109 debug_warning ("session option is UNINTERRUPTIBLE, nothing to do with focus");
112 if (focus_state == FOCUS_IS_ACQUIRED) {
113 debug_warning ("focus is released -> stop playing");
114 result = MMSoundMgrCodecStop(slotid);
115 if (result != MM_ERROR_NONE) {
116 debug_log("result error %d\n", result);
123 int MMSoundMgrCodecInit(const char *targetdir)
130 memset (g_slots, 0, sizeof(g_slots));
132 if(pthread_mutex_init(&g_slot_mutex, NULL)) {
133 debug_error("pthread_mutex_init failed\n");
134 return MM_ERROR_SOUND_INTERNAL;
137 if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
138 debug_error("pthread_mutex_init failed\n");
139 return MM_ERROR_SOUND_INTERNAL;
142 for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
143 g_slots[count].status = STATUS_IDLE;
144 g_slots[count].plughandle = 0;
147 if (g_codec_plugins) {
148 debug_warning("Please Check Init twice\n");
149 MMSoundPluginRelease(g_codec_plugins);
152 MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins);
154 while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
155 _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]);
159 return MM_ERROR_NONE;
162 int MMSoundMgrCodecFini(void)
166 memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
167 MMSoundPluginRelease(g_codec_plugins);
168 g_codec_plugins = NULL;
169 pthread_mutex_destroy(&g_slot_mutex);
170 pthread_mutex_destroy(&codec_wave_mutex);
172 return MM_ERROR_NONE;
176 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
179 mmsound_codec_info_t info;
180 mmsound_codec_param_t codec_param;
181 int err = MM_ERROR_NONE;
182 int need_focus_unregister = 0;
188 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
190 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
194 /*The count num means codec type WAV, MP3 */
195 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
197 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
198 debug_error("unsupported file type %d\n", count);
199 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
204 debug_msg("Get New handle\n");
207 err = _MMSoundMgrCodecGetEmptySlot(slotid);
208 if (err != MM_ERROR_NONE) {
209 debug_error("Empty g_slot is not found\n");
213 codec_param.tone = param->tone;
214 codec_param.volume_config = param->volume_config;
215 codec_param.repeat_count = param->repeat_count;
216 codec_param.volume = param->volume;
217 codec_param.source = param->source;
218 codec_param.priority = param->priority;
219 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
220 codec_param.param = *slotid;
221 codec_param.pid = (int)param->param;
222 codec_param.handle_route = param->handle_route;
223 codec_param.codec_wave_mutex = &codec_wave_mutex;
224 codec_param.stream_index = param->stream_index;
225 strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
226 pthread_mutex_lock(&g_slot_mutex);
228 debug_msg("After Slot_mutex LOCK\n");
232 * Register FOCUS here
235 if (param->session_type != MM_SESSION_TYPE_CALL &&
236 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
237 param->session_type != MM_SESSION_TYPE_VOIP &&
238 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
239 param->priority != HANDLE_PRIORITY_SOLO &&
240 param->enable_session) {
242 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) {
243 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
244 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
245 err = mm_sound_register_focus(param->focus_handle, "media", sound_codec_focus_callback, (void*)*slotid);
247 debug_error("mm_sound_register_focus failed [0x%x]", err);
248 pthread_mutex_unlock(&g_slot_mutex);
249 return MM_ERROR_POLICY_INTERNAL;
251 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
253 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
254 err = mm_sound_unregister_focus(param->focus_handle);
255 pthread_mutex_unlock(&g_slot_mutex);
256 return MM_ERROR_POLICY_INTERNAL;
258 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
260 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
262 debug_warning("need to set focus watch callback");
263 err = mm_sound_set_focus_watch_callback(FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(¶m->focus_wcb_id));
265 debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
266 err = mm_sound_unregister_focus(param->focus_handle);
267 pthread_mutex_unlock(&g_slot_mutex);
268 return MM_ERROR_POLICY_INTERNAL;
274 /* Codec id WAV or MP3 */
275 g_slots[*slotid].pluginid = count;
276 g_slots[*slotid].param = param->param; /* This arg is used callback data */
277 g_slots[*slotid].session_type = param->session_type;
278 g_slots[*slotid].session_options = param->session_options;
279 g_slots[*slotid].focus_handle = param->focus_handle;
280 g_slots[*slotid].focus_wcb_id = param->focus_wcb_id;
281 g_slots[*slotid].enable_session = true;
282 g_slots[*slotid].pid = (int)param->param;
284 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
286 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
287 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
288 if (err != MM_ERROR_NONE) {
289 debug_error("Plugin create fail : 0x%08X\n", err);
290 g_slots[*slotid].status = STATUS_IDLE;
291 pthread_mutex_unlock(&g_slot_mutex);
292 debug_warning("After Slot_mutex UNLOCK\n");
293 if (param->focus_handle) {
294 need_focus_unregister = 1;
299 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
300 if (err != MM_ERROR_NONE) {
301 debug_error("Fail to play : 0x%08X\n", err);
302 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
303 if (param->focus_handle) {
304 need_focus_unregister = 1;
308 pthread_mutex_unlock(&g_slot_mutex);
310 debug_msg("After Slot_mutex UNLOCK\n");
314 if(param->session_type != MM_SESSION_TYPE_CALL &&
315 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
316 param->session_type != MM_SESSION_TYPE_VOIP &&
317 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
318 param->enable_session &&
319 need_focus_unregister == 1) {
321 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) {
322 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
323 if(mm_sound_unregister_focus(param->focus_handle) || err) {
324 debug_error("focus cleaning up failed[0x%x]", err);
325 return MM_ERROR_POLICY_INTERNAL;
327 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
328 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
330 debug_error("focus watch cleaning up failed[0x%x]", err);
331 return MM_ERROR_POLICY_INTERNAL;
343 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
346 mmsound_codec_info_t info;
347 mmsound_codec_param_t codec_param;
348 int err = MM_ERROR_NONE;
354 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
356 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
360 /*The count num means codec type WAV, MP3 */
361 debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->repeat_count, param->volume, count);
363 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
364 debug_error("unsupported file type %d\n", count);
365 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
369 err = _MMSoundMgrCodecGetEmptySlot(slotid);
370 if (err != MM_ERROR_NONE) {
371 debug_error("Empty g_slot is not found\n");
375 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
376 codec_param.repeat_count = param->repeat_count;
377 codec_param.volume = param->volume;
378 codec_param.source = param->source;
379 codec_param.priority = param->priority;
380 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
381 codec_param.param = *slotid;
382 codec_param.pid = (int)param->param;
383 codec_param.handle_route = param->handle_route;
384 codec_param.codec_wave_mutex = &codec_wave_mutex;
385 codec_param.stream_index = param->stream_index;
386 strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
387 pthread_mutex_lock(&g_slot_mutex);
389 debug_msg("After Slot_mutex LOCK\n");
392 /* Codec id WAV or MP3 */
393 g_slots[*slotid].pluginid = count;
394 g_slots[*slotid].param = param->param; /* This arg is used callback data */
396 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
398 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
399 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
400 if (err != MM_ERROR_NONE) {
401 debug_error("Plugin create fail : 0x%08X\n", err);
402 g_slots[*slotid].status = STATUS_IDLE;
403 pthread_mutex_unlock(&g_slot_mutex);
404 debug_warning("After Slot_mutex UNLOCK\n");
408 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
409 if (err != MM_ERROR_NONE) {
410 debug_error("Fail to play : 0x%08X\n", err);
411 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
414 pthread_mutex_unlock(&g_slot_mutex);
416 debug_msg("After Slot_mutex UNLOCK\n");
429 #define DTMF_PLUGIN_COUNT 2
430 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
434 mmsound_codec_info_t info;
435 mmsound_codec_param_t codec_param;
436 int err = MM_ERROR_NONE;
437 int need_focus_unregister = 0;
443 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
445 codec_type = g_plugins[count].GetSupportTypes();
446 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
450 /*The count num means codec type DTMF */
451 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
453 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
454 debug_error("unsupported file type %d\n", count);
455 printf("unsupported file type %d\n", count);
456 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
461 debug_msg("Get New handle\n");
464 err = _MMSoundMgrCodecGetEmptySlot(slotid);
465 if(err != MM_ERROR_NONE)
467 debug_error("Empty g_slot is not found\n");
471 codec_param.tone = param->tone;
472 codec_param.priority = 0;
473 codec_param.volume_config = param->volume_config;
474 codec_param.repeat_count = param->repeat_count;
475 codec_param.volume = param->volume;
476 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
477 codec_param.param = *slotid;
478 codec_param.pid = (int)param->param;
479 codec_param.stream_index = param->stream_index;
480 strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
482 pthread_mutex_lock(&g_slot_mutex);
484 debug_msg("After Slot_mutex LOCK\n");
489 * Register FOCUS here
492 if (param->session_type != MM_SESSION_TYPE_CALL &&
493 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
494 param->session_type != MM_SESSION_TYPE_VOIP &&
495 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
496 param->enable_session) {
498 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) {
499 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
500 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
501 err = mm_sound_register_focus(param->focus_handle, "media", sound_codec_focus_callback, (void*)*slotid);
503 debug_error("mm_sound_register_focus failed [0x%x]", err);
504 pthread_mutex_unlock(&g_slot_mutex);
505 return MM_ERROR_POLICY_INTERNAL;
507 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
509 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
510 err = mm_sound_unregister_focus(param->focus_handle);
511 pthread_mutex_unlock(&g_slot_mutex);
512 return MM_ERROR_POLICY_INTERNAL;
514 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
516 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
518 debug_warning("need to set focus watch callback");
519 err = mm_sound_set_focus_watch_callback(FOCUS_FOR_BOTH, sound_codec_focus_watch_callback, (void*)*slotid, (int *)(¶m->focus_wcb_id));
521 debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
522 err = mm_sound_unregister_focus(param->focus_handle);
523 pthread_mutex_unlock(&g_slot_mutex);
524 return MM_ERROR_POLICY_INTERNAL;
529 g_slots[*slotid].pluginid = count;
530 g_slots[*slotid].param = param->param; /* This arg is used callback data */
531 g_slots[*slotid].session_type = param->session_type;
532 g_slots[*slotid].session_options = param->session_options;
533 g_slots[*slotid].focus_handle= param->focus_handle;
534 g_slots[*slotid].focus_wcb_id= param->focus_wcb_id;
535 g_slots[*slotid].enable_session = param->enable_session;
536 g_slots[*slotid].pid = (int)param->param;
539 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
542 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
543 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
544 if (err != MM_ERROR_NONE) {
545 debug_error("Plugin create fail : 0x%08X\n", err);
546 g_slots[*slotid].status = STATUS_IDLE;
547 pthread_mutex_unlock(&g_slot_mutex);
548 debug_warning("After Slot_mutex UNLOCK\n");
549 need_focus_unregister = 1;
553 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
554 if (err != MM_ERROR_NONE) {
555 debug_error("Fail to play : 0x%08X\n", err);
556 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
557 need_focus_unregister = 1;
560 pthread_mutex_unlock(&g_slot_mutex);
562 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
564 debug_msg("After Slot_mutex UNLOCK\n")
568 if (param->session_type != MM_SESSION_TYPE_CALL &&
569 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
570 param->session_type != MM_SESSION_TYPE_VOIP &&
571 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
572 param->enable_session &&
573 need_focus_unregister == 1) {
575 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) {
576 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
577 if(mm_sound_unregister_focus(param->focus_handle) || err) {
578 debug_error("focus cleaning up failed[0x%x]", err);
579 return MM_ERROR_POLICY_INTERNAL;
581 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
582 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
584 debug_error("focus watch cleaning up failed[0x%x]", err);
585 return MM_ERROR_POLICY_INTERNAL;
597 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
601 mmsound_codec_info_t info;
602 mmsound_codec_param_t codec_param;
603 int err = MM_ERROR_NONE;
609 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
611 codec_type = g_plugins[count].GetSupportTypes();
612 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
616 /*The count num means codec type DTMF */
617 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
619 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
620 debug_error("unsupported file type %d\n", count);
621 printf("unsupported file type %d\n", count);
622 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
627 debug_msg("Get New handle\n");
630 err = _MMSoundMgrCodecGetEmptySlot(slotid);
631 if(err != MM_ERROR_NONE)
633 debug_error("Empty g_slot is not found\n");
637 codec_param.tone = param->tone;
638 codec_param.priority = 0;
639 codec_param.repeat_count = param->repeat_count;
640 codec_param.volume = param->volume;
641 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
642 codec_param.param = *slotid;
643 codec_param.pid = (int)param->param;
644 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
645 codec_param.stream_index = param->stream_index;
646 strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
648 pthread_mutex_lock(&g_slot_mutex);
650 debug_msg("After Slot_mutex LOCK\n");
652 g_slots[*slotid].pluginid = count;
653 g_slots[*slotid].param = param->param; /* This arg is used callback data */
654 g_slots[*slotid].enable_session = param->enable_session;
657 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
660 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
661 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
662 if (err != MM_ERROR_NONE) {
663 debug_error("Plugin create fail : 0x%08X\n", err);
664 g_slots[*slotid].status = STATUS_IDLE;
665 pthread_mutex_unlock(&g_slot_mutex);
666 debug_warning("After Slot_mutex UNLOCK\n");
670 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
671 if (err != MM_ERROR_NONE) {
672 debug_error("Fail to play : 0x%08X\n", err);
673 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
676 pthread_mutex_unlock(&g_slot_mutex);
678 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
680 debug_msg("After Slot_mutex UNLOCK\n");
692 int MMSoundMgrCodecStop(const int slotid)
694 int err = MM_ERROR_NONE;
696 debug_enter("(Slotid : [%d])\n", slotid);
698 if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
699 return MM_ERROR_INVALID_ARGUMENT;
702 pthread_mutex_lock (&g_slot_mutex);
704 debug_msg("After Slot_mutex LOCK\n");
706 if (g_slots[slotid].status == STATUS_IDLE) {
707 err = MM_ERROR_SOUND_INVALID_STATE;
708 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
712 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
715 err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
716 if (err != MM_ERROR_NONE) {
717 debug_error("Fail to STOP Code : 0x%08X\n", err);
719 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
721 pthread_mutex_unlock(&g_slot_mutex);
723 debug_msg("After Slot_mutex UNLOCK\n");
725 debug_leave("(err : 0x%08X)\n", err);
730 int MMSoundMgrCodecClearFocus(int pid)
732 int err = MM_ERROR_NONE;
735 debug_enter("(pid : [%d])\n", pid);
737 pthread_mutex_lock (&g_slot_mutex);
739 for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
740 if (g_slots[slotid].pid == pid) {
741 if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
742 if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
743 g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
744 g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
745 g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
746 g_slots[slotid].enable_session ) {
747 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) {
748 err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
750 debug_error("mm_sound_release_focus failed [0x%x]", err);
752 if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
753 debug_error("Focus clean up failed [0x%x]", err);
754 err = MM_ERROR_POLICY_INTERNAL;
757 } else if (~(g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
758 err = mm_sound_unset_focus_watch_callback(g_slots[slotid].focus_wcb_id);
760 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
761 err = MM_ERROR_POLICY_INTERNAL;
766 g_slots[slotid].focus_handle = 0;
767 g_slots[slotid].focus_wcb_id = 0;
773 pthread_mutex_unlock(&g_slot_mutex);
774 debug_leave("(err : 0x%08X)\n", err);
780 static int _MMSoundMgrCodecStopCallback(int param)
782 int err = MM_ERROR_NONE;
784 debug_enter("(Slot : %d)\n", param);
786 pthread_mutex_lock(&g_slot_mutex);
787 debug_msg("[CODEC MGR] Slot_mutex lock done\n");
791 * Unregister FOCUS here
793 debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
795 if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
796 if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
797 g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
798 g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
799 g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
800 g_slots[param].enable_session ) {
801 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) {
802 err = mm_sound_release_focus(g_slots[param].focus_handle, FOCUS_FOR_BOTH, NULL);
804 debug_error("mm_sound_release_focus failed [0x%x]", err);
806 if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
807 debug_error("Focus clean up failed [0x%x]", err);
808 pthread_mutex_unlock(&g_slot_mutex);
809 return MM_ERROR_POLICY_INTERNAL;
811 } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
812 err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
814 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
815 pthread_mutex_unlock(&g_slot_mutex);
816 return MM_ERROR_POLICY_INTERNAL;
822 __mm_sound_mgr_ipc_notify_play_file_end(param);
824 debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
825 debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
826 err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
828 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
830 memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
831 g_slots[param].status = STATUS_IDLE;
832 pthread_mutex_unlock(&g_slot_mutex);
833 debug_msg("[CODEC MGR] Slot_mutex done\n");
838 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
841 int err = MM_ERROR_NONE;
846 debug_msg("Codec slot ID : [%d]\n", *slot);
847 pthread_mutex_lock(&g_slot_mutex);
849 debug_msg("After Slot_mutex LOCK\n");
852 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
853 if (g_slots[count].status == STATUS_IDLE) {
854 g_slots[count].status = STATUS_SOUND;
858 pthread_mutex_unlock(&g_slot_mutex);
860 debug_msg("After Slot_mutex UNLOCK\n");
863 if (count < MANAGER_HANDLE_MAX) {
864 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
868 debug_warning("Handle is full handle : [%d]\n", count);
870 /* Temporal code for reset */
872 g_slots[count].status = STATUS_IDLE;
874 err = MM_ERROR_SOUND_INTERNAL;
884 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
886 int err = MM_ERROR_NONE;
888 void *getinterface = NULL;
894 /* find emptry slot */
895 for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
896 if (g_plugins[count].GetSupportTypes == NULL)
900 if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
901 debug_critical("The plugin support type is not valid\n");
902 return MM_ERROR_COMMON_OUT_OF_RANGE;
905 err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
906 if (err != MM_ERROR_NONE) {
907 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
910 debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
912 err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
913 if (err != MM_ERROR_NONE) {
914 debug_error("Get interface fail : %x\n", err);
917 /* If error occur, clean interface */
918 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
920 if (g_plugins[count].SetThreadPool)
921 g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);