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.priority = param->priority;
270 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
271 codec_param.param = *slotid;
272 codec_param.pid = (int)param->param;
273 codec_param.handle_route = param->handle_route;
274 codec_param.codec_wave_mutex = &codec_wave_mutex;
275 codec_param.stream_index = param->stream_index;
276 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
277 pthread_mutex_lock(&g_slot_mutex);
279 debug_msg("After Slot_mutex LOCK\n");
282 #ifdef FOCUS_INTEGRATION
284 * Register FOCUS here
287 if (param->session_type != MM_SESSION_TYPE_CALL &&
288 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
289 param->session_type != MM_SESSION_TYPE_VOIP &&
290 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
291 param->enable_session) {
293 unsigned int subs_id = 0;
295 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);
297 debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
298 pthread_mutex_unlock(&g_slot_mutex);
299 return MM_ERROR_POLICY_INTERNAL;
301 g_slots[*slotid].subs_id = subs_id;
303 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) {
304 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
305 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
306 err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
308 debug_error("mm_sound_register_focus_for_session failed [0x%x]", err);
309 pthread_mutex_unlock(&g_slot_mutex);
310 return MM_ERROR_POLICY_INTERNAL;
312 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
314 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
315 err = mm_sound_unregister_focus(param->focus_handle);
316 pthread_mutex_unlock(&g_slot_mutex);
317 return MM_ERROR_POLICY_INTERNAL;
319 g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
320 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
322 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
324 debug_warning("need to set focus watch callback");
325 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));
327 debug_error("mm_sound_set_focus_watch_callback_for_session failed [0x%x]", err);
328 pthread_mutex_unlock(&g_slot_mutex);
329 return MM_ERROR_POLICY_INTERNAL;
336 /* Codec id WAV or MP3 */
337 g_slots[*slotid].pluginid = count;
338 g_slots[*slotid].param = param->param; /* This arg is used callback data */
339 g_slots[*slotid].session_type = param->session_type;
340 g_slots[*slotid].session_options = param->session_options;
341 #ifdef FOCUS_INTEGRATION
342 g_slots[*slotid].focus_handle = param->focus_handle;
343 g_slots[*slotid].focus_wcb_id = param->focus_wcb_id;
345 g_slots[*slotid].enable_session = true;
346 g_slots[*slotid].pid = (int)param->param;
349 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
351 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
352 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
353 if (err != MM_ERROR_NONE) {
354 debug_error("Plugin create fail : 0x%08X\n", err);
355 g_slots[*slotid].status = STATUS_IDLE;
356 pthread_mutex_unlock(&g_slot_mutex);
357 debug_warning("After Slot_mutex UNLOCK\n");
358 #ifdef FOCUS_INTEGRATION
359 if (param->focus_handle) {
360 need_focus_unregister = 1;
366 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
367 if (err != MM_ERROR_NONE) {
368 debug_error("Fail to play : 0x%08X\n", err);
369 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
370 #ifdef FOCUS_INTEGRATION
371 if (param->focus_handle) {
372 need_focus_unregister = 1;
377 pthread_mutex_unlock(&g_slot_mutex);
379 debug_msg("After Slot_mutex UNLOCK\n");
383 #ifdef FOCUS_INTEGRATION
384 if(param->session_type != MM_SESSION_TYPE_CALL &&
385 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
386 param->session_type != MM_SESSION_TYPE_VOIP &&
387 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
388 param->enable_session &&
389 need_focus_unregister == 1) {
391 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) {
392 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
393 if(mm_sound_unregister_focus(param->focus_handle) || err) {
394 debug_error("focus cleaning up failed[0x%x]", err);
395 return MM_ERROR_POLICY_INTERNAL;
397 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
398 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
400 debug_error("focus watch cleaning up failed[0x%x]", err);
401 return MM_ERROR_POLICY_INTERNAL;
414 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
417 mmsound_codec_info_t info;
418 mmsound_codec_param_t codec_param;
419 int err = MM_ERROR_NONE;
425 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
427 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
431 /*The count num means codec type WAV, MP3 */
432 debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->repeat_count, param->volume, count);
434 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
435 debug_error("unsupported file type %d\n", count);
436 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
440 err = _MMSoundMgrCodecGetEmptySlot(slotid);
441 if (err != MM_ERROR_NONE || *slotid < 0) {
442 debug_error("Empty g_slot is not found\n");
446 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
447 codec_param.repeat_count = param->repeat_count;
448 codec_param.volume = param->volume;
449 codec_param.source = param->source;
450 codec_param.priority = param->priority;
451 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
452 codec_param.param = *slotid;
453 codec_param.pid = (int)param->param;
454 codec_param.handle_route = param->handle_route;
455 codec_param.codec_wave_mutex = &codec_wave_mutex;
456 codec_param.stream_index = param->stream_index;
457 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
458 pthread_mutex_lock(&g_slot_mutex);
460 debug_msg("After Slot_mutex LOCK\n");
463 /* Codec id WAV or MP3 */
464 g_slots[*slotid].pluginid = count;
465 g_slots[*slotid].param = param->param; /* This arg is used callback data */
467 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
469 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
470 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
471 if (err != MM_ERROR_NONE) {
472 debug_error("Plugin create fail : 0x%08X\n", err);
473 g_slots[*slotid].status = STATUS_IDLE;
474 pthread_mutex_unlock(&g_slot_mutex);
475 debug_warning("After Slot_mutex UNLOCK\n");
479 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
480 if (err != MM_ERROR_NONE) {
481 debug_error("Fail to play : 0x%08X\n", err);
482 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
485 pthread_mutex_unlock(&g_slot_mutex);
487 debug_msg("After Slot_mutex UNLOCK\n");
500 #define DTMF_PLUGIN_COUNT 2
501 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
505 mmsound_codec_info_t info;
506 mmsound_codec_param_t codec_param;
507 int err = MM_ERROR_NONE;
508 #ifdef FOCUS_INTEGRATION
509 int need_focus_unregister = 0;
516 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
518 codec_type = g_plugins[count].GetSupportTypes();
519 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
523 /*The count num means codec type DTMF */
524 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
526 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
527 debug_error("unsupported file type %d\n", count);
528 printf("unsupported file type %d\n", count);
529 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
534 debug_msg("Get New handle\n");
537 err = _MMSoundMgrCodecGetEmptySlot(slotid);
538 if(err != MM_ERROR_NONE || *slotid < 0)
540 debug_error("Empty g_slot is not found\n");
544 codec_param.tone = param->tone;
545 codec_param.priority = 0;
546 codec_param.volume_config = param->volume_config;
547 codec_param.repeat_count = param->repeat_count;
548 codec_param.volume = param->volume;
549 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
550 codec_param.param = *slotid;
551 codec_param.pid = (int)param->param;
552 codec_param.stream_index = param->stream_index;
553 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
555 pthread_mutex_lock(&g_slot_mutex);
557 debug_msg("After Slot_mutex LOCK\n");
560 #ifdef FOCUS_INTEGRATION
563 * Register FOCUS here
566 if (param->session_type != MM_SESSION_TYPE_CALL &&
567 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
568 param->session_type != MM_SESSION_TYPE_VOIP &&
569 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
570 param->enable_session) {
572 unsigned int subs_id = 0;
574 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);
576 debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
577 pthread_mutex_unlock(&g_slot_mutex);
578 return MM_ERROR_POLICY_INTERNAL;
580 g_slots[*slotid].subs_id = subs_id;
582 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) {
583 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
584 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
585 err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
587 debug_error("mm_sound_register_focus failed [0x%x]", err);
588 pthread_mutex_unlock(&g_slot_mutex);
589 return MM_ERROR_POLICY_INTERNAL;
591 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
593 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
594 err = mm_sound_unregister_focus(param->focus_handle);
595 pthread_mutex_unlock(&g_slot_mutex);
596 return MM_ERROR_POLICY_INTERNAL;
598 g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
599 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
601 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
603 debug_warning("need to set focus watch callback");
604 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));
606 debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
607 pthread_mutex_unlock(&g_slot_mutex);
608 return MM_ERROR_POLICY_INTERNAL;
614 g_slots[*slotid].pluginid = count;
615 g_slots[*slotid].param = param->param; /* This arg is used callback data */
616 g_slots[*slotid].session_type = param->session_type;
617 g_slots[*slotid].session_options = param->session_options;
618 #ifdef FOCUS_INTEGRATION
619 g_slots[*slotid].focus_handle= param->focus_handle;
620 g_slots[*slotid].focus_wcb_id= param->focus_wcb_id;
622 g_slots[*slotid].enable_session = param->enable_session;
623 g_slots[*slotid].pid = (int)param->param;
626 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
629 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
630 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
631 if (err != MM_ERROR_NONE) {
632 debug_error("Plugin create fail : 0x%08X\n", err);
633 g_slots[*slotid].status = STATUS_IDLE;
634 pthread_mutex_unlock(&g_slot_mutex);
635 debug_warning("After Slot_mutex UNLOCK\n");
636 #ifdef FOCUS_INTEGRATION
637 need_focus_unregister = 1;
642 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
643 if (err != MM_ERROR_NONE) {
644 debug_error("Fail to play : 0x%08X\n", err);
645 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
646 #ifdef FOCUS_INTEGRATION
647 need_focus_unregister = 1;
651 pthread_mutex_unlock(&g_slot_mutex);
653 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
655 debug_msg("After Slot_mutex UNLOCK\n")
659 #ifdef FOCUS_INTEGRATION
660 if (param->session_type != MM_SESSION_TYPE_CALL &&
661 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
662 param->session_type != MM_SESSION_TYPE_VOIP &&
663 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
664 param->enable_session &&
665 need_focus_unregister == 1) {
667 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) {
668 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
669 if(mm_sound_unregister_focus(param->focus_handle) || err) {
670 debug_error("focus cleaning up failed[0x%x]", err);
671 return MM_ERROR_POLICY_INTERNAL;
673 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
674 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
676 debug_error("focus watch cleaning up failed[0x%x]", err);
677 return MM_ERROR_POLICY_INTERNAL;
690 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
694 mmsound_codec_info_t info;
695 mmsound_codec_param_t codec_param;
696 int err = MM_ERROR_NONE;
702 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
704 codec_type = g_plugins[count].GetSupportTypes();
705 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
709 /*The count num means codec type DTMF */
710 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
712 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
713 debug_error("unsupported file type %d\n", count);
714 printf("unsupported file type %d\n", count);
715 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
720 debug_msg("Get New handle\n");
723 err = _MMSoundMgrCodecGetEmptySlot(slotid);
724 if(err != MM_ERROR_NONE || *slotid < 0)
726 debug_error("Empty g_slot is not found\n");
730 codec_param.tone = param->tone;
731 codec_param.priority = 0;
732 codec_param.repeat_count = param->repeat_count;
733 codec_param.volume = param->volume;
734 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
735 codec_param.param = *slotid;
736 codec_param.pid = (int)param->param;
737 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
738 codec_param.stream_index = param->stream_index;
739 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
741 pthread_mutex_lock(&g_slot_mutex);
743 debug_msg("After Slot_mutex LOCK\n");
745 g_slots[*slotid].pluginid = count;
746 g_slots[*slotid].param = param->param; /* This arg is used callback data */
747 g_slots[*slotid].enable_session = param->enable_session;
750 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
753 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
754 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
755 if (err != MM_ERROR_NONE) {
756 debug_error("Plugin create fail : 0x%08X\n", err);
757 g_slots[*slotid].status = STATUS_IDLE;
758 pthread_mutex_unlock(&g_slot_mutex);
759 debug_warning("After Slot_mutex UNLOCK\n");
763 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
764 if (err != MM_ERROR_NONE) {
765 debug_error("Fail to play : 0x%08X\n", err);
766 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
769 pthread_mutex_unlock(&g_slot_mutex);
771 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
773 debug_msg("After Slot_mutex UNLOCK\n");
785 int MMSoundMgrCodecStop(const int slotid)
787 int err = MM_ERROR_NONE;
789 debug_enter("(Slotid : [%d])\n", slotid);
791 if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
792 return MM_ERROR_INVALID_ARGUMENT;
795 pthread_mutex_lock (&g_slot_mutex);
797 debug_msg("After Slot_mutex LOCK\n");
799 if (g_slots[slotid].status == STATUS_IDLE) {
800 err = MM_ERROR_SOUND_INVALID_STATE;
801 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
805 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
808 err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
809 if (err != MM_ERROR_NONE) {
810 debug_error("Fail to STOP Code : 0x%08X\n", err);
812 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
814 pthread_mutex_unlock(&g_slot_mutex);
816 debug_msg("After Slot_mutex UNLOCK\n");
818 debug_leave("(err : 0x%08X)\n", err);
822 #ifdef FOCUS_INTEGRATION
823 int MMSoundMgrCodecClearFocus(int pid)
825 int err = MM_ERROR_NONE;
828 debug_enter("(pid : [%d])\n", pid);
830 pthread_mutex_lock (&g_slot_mutex);
832 for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
833 if (g_slots[slotid].pid == pid) {
834 if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
835 if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
836 g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
837 g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
838 g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
839 g_slots[slotid].enable_session ) {
840 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) {
841 err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
843 debug_error("mm_sound_release_focus failed [0x%x]", err);
845 if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
846 debug_error("Focus clean up failed [0x%x]", err);
847 err = MM_ERROR_POLICY_INTERNAL;
850 } else if (~(g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
851 err = mm_sound_unset_focus_watch_callback(g_slots[slotid].focus_wcb_id);
853 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
854 err = MM_ERROR_POLICY_INTERNAL;
859 if(mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
860 debug_error("mm_sound_remove_device_connected_callback() failed");
861 g_slots[slotid].focus_handle = 0;
862 g_slots[slotid].focus_wcb_id = 0;
863 g_slots[slotid].subs_id = 0;
869 pthread_mutex_unlock(&g_slot_mutex);
870 debug_leave("(err : 0x%08X)\n", err);
876 static int _MMSoundMgrCodecStopCallback(int param)
878 int err = MM_ERROR_NONE;
880 debug_enter("(Slot : %d)\n", param);
882 if (param < 0 || param >= MANAGER_HANDLE_MAX) {
883 debug_error ("Slot index param [%d] is invalid", param);
884 return MM_ERROR_INVALID_ARGUMENT;
887 pthread_mutex_lock(&g_slot_mutex);
888 debug_msg("[CODEC MGR] Slot_mutex lock done\n");
890 #ifdef FOCUS_INTEGRATION
892 * Unregister FOCUS here
894 debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
896 if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
897 if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
898 g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
899 g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
900 g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
901 g_slots[param].enable_session ) {
902 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) {
903 if(g_slots[param].current_focus_type != FOCUS_NONE) {
904 err = mm_sound_release_focus(g_slots[param].focus_handle, g_slots[param].current_focus_type, NULL);
906 debug_error("mm_sound_release_focus failed [0x%x]", err);
909 if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
910 debug_error("Focus clean up failed [0x%x]", err);
911 pthread_mutex_unlock(&g_slot_mutex);
912 return MM_ERROR_POLICY_INTERNAL;
914 } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
915 err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
917 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
918 pthread_mutex_unlock(&g_slot_mutex);
919 return MM_ERROR_POLICY_INTERNAL;
923 if(mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
924 debug_error("mm_sound_remove_device_connected_callback() failed");
928 __mm_sound_mgr_ipc_notify_play_file_end(param);
930 debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
931 debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
932 err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
934 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
936 memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
937 g_slots[param].status = STATUS_IDLE;
938 pthread_mutex_unlock(&g_slot_mutex);
939 debug_msg("[CODEC MGR] Slot_mutex done\n");
944 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
947 int err = MM_ERROR_NONE;
952 debug_msg("Codec slot ID : [%d]\n", *slot);
953 pthread_mutex_lock(&g_slot_mutex);
955 debug_msg("After Slot_mutex LOCK\n");
958 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
959 if (g_slots[count].status == STATUS_IDLE) {
960 g_slots[count].status = STATUS_SOUND;
964 pthread_mutex_unlock(&g_slot_mutex);
966 debug_msg("After Slot_mutex UNLOCK\n");
969 if (count < MANAGER_HANDLE_MAX) {
970 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
974 debug_warning("Handle is full handle : [%d]\n", count);
976 /* Temporal code for reset */
978 g_slots[count].status = STATUS_IDLE;
980 err = MM_ERROR_SOUND_INTERNAL;
990 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
992 int err = MM_ERROR_NONE;
994 void *getinterface = NULL;
1000 /* find emptry slot */
1001 for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
1002 if (g_plugins[count].GetSupportTypes == NULL)
1006 if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
1007 debug_critical("The plugin support type is not valid\n");
1008 return MM_ERROR_COMMON_OUT_OF_RANGE;
1011 err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
1012 if (err != MM_ERROR_NONE) {
1013 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
1016 debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
1018 err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
1019 if (err != MM_ERROR_NONE) {
1020 debug_error("Get interface fail : %x\n", err);
1023 /* If error occur, clean interface */
1024 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
1026 if (g_plugins[count].SetThreadPool)
1027 g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);