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:
147 case MM_SOUND_DEVICE_TYPE_HDMI:
148 case MM_SOUND_DEVICE_TYPE_MIRRORING:
149 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
151 debug_warning("sound device unplugged");
152 result = MMSoundMgrCodecStop(slotid);
153 if (result != MM_ERROR_NONE) {
154 debug_error("MMSoundMgrCodecStop error %d\n", result);
156 result = mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id);
157 if (result != MM_ERROR_NONE) {
158 debug_error("mm_sound_remove_device_connected_callback error %d\n", result);
169 int MMSoundMgrCodecInit(const char *targetdir)
176 memset (g_slots, 0, sizeof(g_slots));
178 if(pthread_mutex_init(&g_slot_mutex, NULL)) {
179 debug_error("pthread_mutex_init failed\n");
180 return MM_ERROR_SOUND_INTERNAL;
183 if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
184 debug_error("pthread_mutex_init failed\n");
185 return MM_ERROR_SOUND_INTERNAL;
188 for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
189 g_slots[count].status = STATUS_IDLE;
190 g_slots[count].plughandle = 0;
193 if (g_codec_plugins) {
194 debug_warning("Please Check Init twice\n");
195 MMSoundPluginRelease(g_codec_plugins);
198 MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins);
199 if (g_codec_plugins) {
200 while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
201 _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]);
206 return MM_ERROR_NONE;
209 int MMSoundMgrCodecFini(void)
213 memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
214 MMSoundPluginRelease(g_codec_plugins);
215 g_codec_plugins = NULL;
216 pthread_mutex_destroy(&g_slot_mutex);
217 pthread_mutex_destroy(&codec_wave_mutex);
219 return MM_ERROR_NONE;
223 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
226 mmsound_codec_info_t info;
227 mmsound_codec_param_t codec_param;
228 int err = MM_ERROR_NONE;
229 #ifdef FOCUS_INTEGRATION
230 int need_focus_unregister = 0;
237 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
239 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
243 /*The count num means codec type WAV, MP3 */
244 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
246 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
247 debug_error("unsupported file type %d\n", count);
248 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
253 debug_msg("Get New handle\n");
256 err = _MMSoundMgrCodecGetEmptySlot(slotid);
257 if (err != MM_ERROR_NONE || *slotid < 0) {
258 debug_error("Empty g_slot is not found\n");
262 codec_param.tone = param->tone;
263 codec_param.volume_config = param->volume_config;
264 codec_param.repeat_count = param->repeat_count;
265 codec_param.volume = param->volume;
266 codec_param.source = param->source;
267 codec_param.priority = param->priority;
268 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
269 codec_param.param = *slotid;
270 codec_param.pid = (int)param->param;
271 codec_param.handle_route = param->handle_route;
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.priority = param->priority;
449 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
450 codec_param.param = *slotid;
451 codec_param.pid = (int)param->param;
452 codec_param.handle_route = param->handle_route;
453 codec_param.codec_wave_mutex = &codec_wave_mutex;
454 codec_param.stream_index = param->stream_index;
455 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
456 pthread_mutex_lock(&g_slot_mutex);
458 debug_msg("After Slot_mutex LOCK\n");
461 /* Codec id WAV or MP3 */
462 g_slots[*slotid].pluginid = count;
463 g_slots[*slotid].param = param->param; /* This arg is used callback data */
465 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
467 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
468 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
469 if (err != MM_ERROR_NONE) {
470 debug_error("Plugin create fail : 0x%08X\n", err);
471 g_slots[*slotid].status = STATUS_IDLE;
472 pthread_mutex_unlock(&g_slot_mutex);
473 debug_warning("After Slot_mutex UNLOCK\n");
477 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
478 if (err != MM_ERROR_NONE) {
479 debug_error("Fail to play : 0x%08X\n", err);
480 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
483 pthread_mutex_unlock(&g_slot_mutex);
485 debug_msg("After Slot_mutex UNLOCK\n");
498 #define DTMF_PLUGIN_COUNT 2
499 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
503 mmsound_codec_info_t info;
504 mmsound_codec_param_t codec_param;
505 int err = MM_ERROR_NONE;
506 #ifdef FOCUS_INTEGRATION
507 int need_focus_unregister = 0;
514 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
516 codec_type = g_plugins[count].GetSupportTypes();
517 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
521 /*The count num means codec type DTMF */
522 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
524 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
525 debug_error("unsupported file type %d\n", count);
526 printf("unsupported file type %d\n", count);
527 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
532 debug_msg("Get New handle\n");
535 err = _MMSoundMgrCodecGetEmptySlot(slotid);
536 if(err != MM_ERROR_NONE || *slotid < 0)
538 debug_error("Empty g_slot is not found\n");
542 codec_param.tone = param->tone;
543 codec_param.priority = 0;
544 codec_param.volume_config = param->volume_config;
545 codec_param.repeat_count = param->repeat_count;
546 codec_param.volume = param->volume;
547 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
548 codec_param.param = *slotid;
549 codec_param.pid = (int)param->param;
550 codec_param.stream_index = param->stream_index;
551 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
553 pthread_mutex_lock(&g_slot_mutex);
555 debug_msg("After Slot_mutex LOCK\n");
558 #ifdef FOCUS_INTEGRATION
561 * Register FOCUS here
564 if (param->session_type != MM_SESSION_TYPE_CALL &&
565 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
566 param->session_type != MM_SESSION_TYPE_VOIP &&
567 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
568 param->enable_session) {
570 unsigned int subs_id = 0;
572 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);
574 debug_error("mm_sound_add_device_connected_callback failed [0x%x]", err);
575 pthread_mutex_unlock(&g_slot_mutex);
576 return MM_ERROR_POLICY_INTERNAL;
578 g_slots[*slotid].subs_id = subs_id;
580 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) {
581 debug_warning("session option is PAUSE_OTHERS -> acquire focus");
582 err = mm_sound_focus_get_id((int *)(¶m->focus_handle));
583 err = mm_sound_register_focus_for_session(param->focus_handle, (int)param->param, "media", sound_codec_focus_callback, (void*)*slotid);
585 debug_error("mm_sound_register_focus failed [0x%x]", err);
586 pthread_mutex_unlock(&g_slot_mutex);
587 return MM_ERROR_POLICY_INTERNAL;
589 err = mm_sound_acquire_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
591 debug_error("mm_sound_acquire_focus failed [0x%x]", err);
592 err = mm_sound_unregister_focus(param->focus_handle);
593 pthread_mutex_unlock(&g_slot_mutex);
594 return MM_ERROR_POLICY_INTERNAL;
596 g_slots[*slotid].current_focus_type = FOCUS_FOR_BOTH;
597 } else if (param->session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
599 debug_warning("session option is UNINTERRUPTIBLE, nothing to do with focus");
601 debug_warning("need to set focus watch callback");
602 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));
604 debug_error("mm_sound_set_focus_watch_callback failed [0x%x]", err);
605 pthread_mutex_unlock(&g_slot_mutex);
606 return MM_ERROR_POLICY_INTERNAL;
612 g_slots[*slotid].pluginid = count;
613 g_slots[*slotid].param = param->param; /* This arg is used callback data */
614 g_slots[*slotid].session_type = param->session_type;
615 g_slots[*slotid].session_options = param->session_options;
616 #ifdef FOCUS_INTEGRATION
617 g_slots[*slotid].focus_handle= param->focus_handle;
618 g_slots[*slotid].focus_wcb_id= param->focus_wcb_id;
620 g_slots[*slotid].enable_session = param->enable_session;
621 g_slots[*slotid].pid = (int)param->param;
624 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
627 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
628 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
629 if (err != MM_ERROR_NONE) {
630 debug_error("Plugin create fail : 0x%08X\n", err);
631 g_slots[*slotid].status = STATUS_IDLE;
632 pthread_mutex_unlock(&g_slot_mutex);
633 debug_warning("After Slot_mutex UNLOCK\n");
634 #ifdef FOCUS_INTEGRATION
635 need_focus_unregister = 1;
640 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
641 if (err != MM_ERROR_NONE) {
642 debug_error("Fail to play : 0x%08X\n", err);
643 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
644 #ifdef FOCUS_INTEGRATION
645 need_focus_unregister = 1;
649 pthread_mutex_unlock(&g_slot_mutex);
651 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
653 debug_msg("After Slot_mutex UNLOCK\n")
657 #ifdef FOCUS_INTEGRATION
658 if (param->session_type != MM_SESSION_TYPE_CALL &&
659 param->session_type != MM_SESSION_TYPE_VIDEOCALL &&
660 param->session_type != MM_SESSION_TYPE_VOIP &&
661 param->session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
662 param->enable_session &&
663 need_focus_unregister == 1) {
665 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) {
666 err = mm_sound_release_focus(param->focus_handle, FOCUS_FOR_BOTH, NULL);
667 if(mm_sound_unregister_focus(param->focus_handle) || err) {
668 debug_error("focus cleaning up failed[0x%x]", err);
669 return MM_ERROR_POLICY_INTERNAL;
671 } else if (~(param->session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
672 err = mm_sound_unset_focus_watch_callback(param->focus_wcb_id);
674 debug_error("focus watch cleaning up failed[0x%x]", err);
675 return MM_ERROR_POLICY_INTERNAL;
688 int MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
692 mmsound_codec_info_t info;
693 mmsound_codec_param_t codec_param;
694 int err = MM_ERROR_NONE;
700 for (count = 0; g_plugins[count].GetSupportTypes; count++) {
702 codec_type = g_plugins[count].GetSupportTypes();
703 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
707 /*The count num means codec type DTMF */
708 debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
710 if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
711 debug_error("unsupported file type %d\n", count);
712 printf("unsupported file type %d\n", count);
713 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
718 debug_msg("Get New handle\n");
721 err = _MMSoundMgrCodecGetEmptySlot(slotid);
722 if(err != MM_ERROR_NONE || *slotid < 0)
724 debug_error("Empty g_slot is not found\n");
728 codec_param.tone = param->tone;
729 codec_param.priority = 0;
730 codec_param.repeat_count = param->repeat_count;
731 codec_param.volume = param->volume;
732 codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
733 codec_param.param = *slotid;
734 codec_param.pid = (int)param->param;
735 codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
736 codec_param.stream_index = param->stream_index;
737 MMSOUND_STRNCPY(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
739 pthread_mutex_lock(&g_slot_mutex);
741 debug_msg("After Slot_mutex LOCK\n");
743 g_slots[*slotid].pluginid = count;
744 g_slots[*slotid].param = param->param; /* This arg is used callback data */
745 g_slots[*slotid].enable_session = param->enable_session;
748 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
751 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
752 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
753 if (err != MM_ERROR_NONE) {
754 debug_error("Plugin create fail : 0x%08X\n", err);
755 g_slots[*slotid].status = STATUS_IDLE;
756 pthread_mutex_unlock(&g_slot_mutex);
757 debug_warning("After Slot_mutex UNLOCK\n");
761 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
762 if (err != MM_ERROR_NONE) {
763 debug_error("Fail to play : 0x%08X\n", err);
764 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
767 pthread_mutex_unlock(&g_slot_mutex);
769 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
771 debug_msg("After Slot_mutex UNLOCK\n");
783 int MMSoundMgrCodecStop(const int slotid)
785 int err = MM_ERROR_NONE;
787 debug_enter("(Slotid : [%d])\n", slotid);
789 if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
790 return MM_ERROR_INVALID_ARGUMENT;
793 pthread_mutex_lock (&g_slot_mutex);
795 debug_msg("After Slot_mutex LOCK\n");
797 if (g_slots[slotid].status == STATUS_IDLE) {
798 err = MM_ERROR_SOUND_INVALID_STATE;
799 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
803 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
806 err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
807 if (err != MM_ERROR_NONE) {
808 debug_error("Fail to STOP Code : 0x%08X\n", err);
810 debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
812 pthread_mutex_unlock(&g_slot_mutex);
814 debug_msg("After Slot_mutex UNLOCK\n");
816 debug_leave("(err : 0x%08X)\n", err);
820 #ifdef FOCUS_INTEGRATION
821 int MMSoundMgrCodecClearFocus(int pid)
823 int err = MM_ERROR_NONE;
826 debug_enter("(pid : [%d])\n", pid);
828 pthread_mutex_lock (&g_slot_mutex);
830 for (slotid = 0 ; slotid < MANAGER_HANDLE_MAX ; slotid++) {
831 if (g_slots[slotid].pid == pid) {
832 if (g_slots[slotid].focus_handle || g_slots[slotid].focus_wcb_id) {
833 if(g_slots[slotid].session_type != MM_SESSION_TYPE_CALL &&
834 g_slots[slotid].session_type != MM_SESSION_TYPE_VIDEOCALL &&
835 g_slots[slotid].session_type != MM_SESSION_TYPE_VOIP &&
836 g_slots[slotid].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
837 g_slots[slotid].enable_session ) {
838 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) {
839 err = mm_sound_release_focus(g_slots[slotid].focus_handle, FOCUS_FOR_BOTH, NULL);
841 debug_error("mm_sound_release_focus failed [0x%x]", err);
843 if(mm_sound_unregister_focus(g_slots[slotid].focus_handle) || err) {
844 debug_error("Focus clean up failed [0x%x]", err);
845 err = MM_ERROR_POLICY_INTERNAL;
848 } else if (~(g_slots[slotid].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
849 err = mm_sound_unset_focus_watch_callback(g_slots[slotid].focus_wcb_id);
851 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
852 err = MM_ERROR_POLICY_INTERNAL;
857 if(mm_sound_remove_device_connected_callback(g_slots[slotid].subs_id) != MM_ERROR_NONE)
858 debug_error("mm_sound_remove_device_connected_callback() failed");
859 g_slots[slotid].focus_handle = 0;
860 g_slots[slotid].focus_wcb_id = 0;
861 g_slots[slotid].subs_id = 0;
867 pthread_mutex_unlock(&g_slot_mutex);
868 debug_leave("(err : 0x%08X)\n", err);
874 static int _MMSoundMgrCodecStopCallback(int param)
876 int err = MM_ERROR_NONE;
878 debug_enter("(Slot : %d)\n", param);
880 if (param < 0 || param >= MANAGER_HANDLE_MAX) {
881 debug_error ("Slot index param [%d] is invalid", param);
882 return MM_ERROR_INVALID_ARGUMENT;
885 pthread_mutex_lock(&g_slot_mutex);
886 debug_msg("[CODEC MGR] Slot_mutex lock done\n");
888 #ifdef FOCUS_INTEGRATION
890 * Unregister FOCUS here
892 debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
894 if (g_slots[param].focus_handle || g_slots[param].focus_wcb_id) {
895 if(g_slots[param].session_type != MM_SESSION_TYPE_CALL &&
896 g_slots[param].session_type != MM_SESSION_TYPE_VIDEOCALL &&
897 g_slots[param].session_type != MM_SESSION_TYPE_VOIP &&
898 g_slots[param].session_type != MM_SESSION_TYPE_VOICE_RECOGNITION &&
899 g_slots[param].enable_session ) {
900 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) {
901 if(g_slots[param].current_focus_type != FOCUS_NONE) {
902 err = mm_sound_release_focus(g_slots[param].focus_handle, g_slots[param].current_focus_type, NULL);
904 debug_error("mm_sound_release_focus failed [0x%x]", err);
907 if(mm_sound_unregister_focus(g_slots[param].focus_handle) || err) {
908 debug_error("Focus clean up failed [0x%x]", err);
909 pthread_mutex_unlock(&g_slot_mutex);
910 return MM_ERROR_POLICY_INTERNAL;
912 } else if (~(g_slots[param].session_options & MM_SESSION_OPTION_PAUSE_OTHERS)) {
913 err = mm_sound_unset_focus_watch_callback(g_slots[param].focus_wcb_id);
915 debug_error("mm_sound_unset_focus_watch_callback failed [0x%x]", err);
916 pthread_mutex_unlock(&g_slot_mutex);
917 return MM_ERROR_POLICY_INTERNAL;
921 if(mm_sound_remove_device_connected_callback(g_slots[param].subs_id) != MM_ERROR_NONE)
922 debug_error("mm_sound_remove_device_connected_callback() failed");
926 __mm_sound_mgr_ipc_notify_play_file_end(param);
928 debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
929 debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
930 err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
932 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
934 memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
935 g_slots[param].status = STATUS_IDLE;
936 pthread_mutex_unlock(&g_slot_mutex);
937 debug_msg("[CODEC MGR] Slot_mutex done\n");
942 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
945 int err = MM_ERROR_NONE;
950 debug_msg("Codec slot ID : [%d]\n", *slot);
951 pthread_mutex_lock(&g_slot_mutex);
953 debug_msg("After Slot_mutex LOCK\n");
956 for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
957 if (g_slots[count].status == STATUS_IDLE) {
958 g_slots[count].status = STATUS_SOUND;
962 pthread_mutex_unlock(&g_slot_mutex);
964 debug_msg("After Slot_mutex UNLOCK\n");
967 if (count < MANAGER_HANDLE_MAX) {
968 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
972 debug_warning("Handle is full handle : [%d]\n", count);
974 /* Temporal code for reset */
976 g_slots[count].status = STATUS_IDLE;
978 err = MM_ERROR_SOUND_INTERNAL;
988 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
990 int err = MM_ERROR_NONE;
992 void *getinterface = NULL;
998 /* find emptry slot */
999 for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
1000 if (g_plugins[count].GetSupportTypes == NULL)
1004 if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
1005 debug_critical("The plugin support type is not valid\n");
1006 return MM_ERROR_COMMON_OUT_OF_RANGE;
1009 err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
1010 if (err != MM_ERROR_NONE) {
1011 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
1014 debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
1016 err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
1017 if (err != MM_ERROR_NONE) {
1018 debug_error("Get interface fail : %x\n", err);
1021 /* If error occur, clean interface */
1022 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
1024 if (g_plugins[count].SetThreadPool)
1025 g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);