Remove unused variable for play sound
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_mgr_codec.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <pthread.h>
26
27 #include <mm_source.h>
28 #include <mm_error.h>
29 #include <mm_types.h>
30 #include <mm_debug.h>
31 #include <mm_ipc.h>
32
33 #include "include/mm_sound_mgr_common.h"
34 #include "include/mm_sound_mgr_codec.h"
35 #include "include/mm_sound_plugin_codec.h"
36 #include "include/mm_sound_thread_pool.h"
37 #include "include/mm_sound_pa_client.h"
38 #include "include/mm_sound_mgr_asm.h"
39
40
41
42 #define _ENABLE_KEYTONE /* Temporal test code */
43
44 typedef struct {
45         int (*callback)(int, void *, void *, int);      /* msg_type(pid) client callback & client data info */
46         void *param;
47         int pid;
48         void *msgcallback;
49         void *msgdata;
50         MMHandleType plughandle;
51
52         int pluginid;
53         int status;
54         int session_type;
55         int session_options;
56         int session_handle;
57
58         bool enable_session;
59  } __mmsound_mgr_codec_handle_t;
60
61 static MMSoundPluginType *g_codec_plugins = NULL;
62 static __mmsound_mgr_codec_handle_t g_slots[MANAGER_HANDLE_MAX];
63 static mmsound_codec_interface_t g_plugins[MM_SOUND_SUPPORTED_CODEC_NUM];
64 static pthread_mutex_t g_slot_mutex;
65 static pthread_mutex_t codec_wave_mutex;
66 static int _MMSoundMgrCodecStopCallback(int param);
67 static int _MMSoundMgrCodecFindKeytoneSlot(int *slotid);
68 static int _MMSoundMgrCodecGetEmptySlot(int *slotid);
69 static int _MMSoundMgrCodecFindLocaleSlot(int *slotid);
70 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin);
71
72 #define STATUS_IDLE 0
73 #define STATUS_SOUND 3
74
75 #define SOUND_SLOT_START 0
76
77
78
79 ASM_cb_result_t
80 sound_codec_asm_callback(int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
81 {
82         int slotid = (int)cb_data;
83         int result = MM_ERROR_NONE;
84         ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
85
86         debug_log("Got audio session callback msg for session_handle %d\n", handle);
87
88         switch(command)
89         {
90         case ASM_COMMAND_STOP:
91         case ASM_COMMAND_PAUSE:
92                 debug_log("Got msg from asm to Stop or Pause %d\n", command);
93                 result = MMSoundMgrCodecStop(slotid);
94                 if (result != MM_ERROR_NONE) {
95                         debug_log("result error %d\n", result);
96                 }
97                 cb_res = ASM_CB_RES_STOP;
98                 break;
99         case ASM_COMMAND_RESUME:
100         case ASM_COMMAND_PLAY:
101                 debug_log("Got msg from asm to Play or Resume %d\n", command);
102                 cb_res = ASM_CB_RES_NONE;;
103         default:
104                 break;
105         }
106         return cb_res;
107 }
108
109
110 int MMSoundMgrCodecInit(const char *targetdir)
111 {
112         int loop = 0;
113         int count = 0;
114
115         debug_enter("\n");
116
117         memset (g_slots, 0, sizeof(g_slots));
118
119         if(pthread_mutex_init(&g_slot_mutex, NULL)) {
120                 debug_error("pthread_mutex_init failed\n");
121                 return MM_ERROR_SOUND_INTERNAL;
122         }
123
124         if(pthread_mutex_init(&codec_wave_mutex, NULL)) {
125                 debug_error("pthread_mutex_init failed\n");
126                 return MM_ERROR_SOUND_INTERNAL;
127         }
128
129         for (count = 0; count < MANAGER_HANDLE_MAX; count++) {
130                 g_slots[count].status = STATUS_IDLE;
131                 g_slots[count].plughandle = 0;
132         }
133
134         if (g_codec_plugins) {
135                 debug_warning("Please Check Init twice\n");
136                 MMSoundPluginRelease(g_codec_plugins);
137         }
138
139         MMSoundPluginScan(targetdir, MM_SOUND_PLUGIN_TYPE_CODEC, &g_codec_plugins);
140
141         while (g_codec_plugins[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
142                 _MMSoundMgrCodecRegisterInterface(&g_codec_plugins[loop++]);
143         }
144
145         debug_leave("\n");
146         return MM_ERROR_NONE;
147 }
148
149 int MMSoundMgrCodecFini(void)
150 {
151         debug_enter("\n");
152
153         memset(g_plugins, 0, sizeof(mmsound_codec_interface_t) * MM_SOUND_SUPPORTED_CODEC_NUM);
154         MMSoundPluginRelease(g_codec_plugins);
155         g_codec_plugins = NULL;
156         pthread_mutex_destroy(&g_slot_mutex);
157         pthread_mutex_destroy(&codec_wave_mutex);
158         debug_leave("\n");
159         return MM_ERROR_NONE;
160 }
161
162
163 int MMSoundMgrCodecPlay(int *slotid, const mmsound_mgr_codec_param_t *param)
164 {
165         int count = 0;
166         mmsound_codec_info_t info;
167         mmsound_codec_param_t codec_param;
168         int err = MM_ERROR_NONE;
169         int errorcode = 0;
170         int need_asm_unregister = 0;
171
172 #ifdef DEBUG_DETAIL
173         debug_enter("\n");
174 #endif
175
176         for (count = 0; g_plugins[count].GetSupportTypes; count++) {
177                 /* Find codec */
178                 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
179                         break;
180         }
181
182         /*The count num means codec type WAV, MP3 */
183         debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
184
185         if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
186                 debug_error("unsupported file type %d\n", count);
187                 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
188                 goto cleanup;
189         }
190
191 #ifdef DEBUG_DETAIL
192         debug_msg("Get New handle\n");
193 #endif
194
195         err = _MMSoundMgrCodecGetEmptySlot(slotid);
196         if (err != MM_ERROR_NONE) {
197                 debug_error("Empty g_slot is not found\n");
198                 goto cleanup;
199         }
200
201         codec_param.tone = param->tone;
202         codec_param.volume_config = param->volume_config;
203         codec_param.repeat_count = param->repeat_count;
204         codec_param.volume = param->volume;
205         codec_param.source = param->source;
206         codec_param.priority = param->priority;
207         codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
208         codec_param.param = *slotid;
209         codec_param.pid = (int)param->param;
210         codec_param.handle_route = param->handle_route;
211         codec_param.codec_wave_mutex = &codec_wave_mutex;
212         codec_param.stream_index = param->stream_index;
213         strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
214         pthread_mutex_lock(&g_slot_mutex);
215 #ifdef DEBUG_DETAIL
216         debug_msg("After Slot_mutex LOCK\n");
217 #endif
218
219         /*
220          * Register ASM here
221          */
222         if (param->session_type != ASM_EVENT_CALL &&
223                 param->session_type != ASM_EVENT_VIDEOCALL &&
224                 param->session_type != ASM_EVENT_VOIP &&
225                 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
226                 param->priority != HANDLE_PRIORITY_SOLO &&
227                 param->enable_session) {
228                 if(!ASM_register_sound_ex((int)param->param, (int *)(&param->session_handle), param->session_type, ASM_STATE_NONE,
229                                                                 sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
230                         debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode);
231                         pthread_mutex_unlock(&g_slot_mutex);
232                         return MM_ERROR_POLICY_INTERNAL;
233                 }
234                 if(param->session_options) {
235                         if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) {
236                                 debug_error("ASM_set_session_option() failed 0x%x\n", errorcode);
237                         }
238                 }
239                 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
240                         debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
241                         pthread_mutex_unlock(&g_slot_mutex);
242                         if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
243                                 debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
244                         }
245                         return MM_ERROR_POLICY_INTERNAL;
246                 }
247         }
248         //
249
250         /* Codec id WAV or MP3 */
251         g_slots[*slotid].pluginid = count;
252         g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
253         g_slots[*slotid].session_type = param->session_type;
254         g_slots[*slotid].session_options = param->session_options;
255         g_slots[*slotid].session_handle = param->session_handle;
256         g_slots[*slotid].enable_session = true;
257
258         debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
259
260         err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
261         debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
262         if (err != MM_ERROR_NONE) {
263                 debug_error("Plugin create fail : 0x%08X\n", err);
264                 g_slots[*slotid].status = STATUS_IDLE;
265                 pthread_mutex_unlock(&g_slot_mutex);
266                 debug_warning("After Slot_mutex UNLOCK\n");
267                 if (param->session_handle) {
268                         need_asm_unregister = 1;
269                 }
270                 goto cleanup;
271         }
272
273         err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
274         if (err != MM_ERROR_NONE) {
275                 debug_error("Fail to play : 0x%08X\n", err);
276                 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
277                 if (param->session_handle) {
278                         need_asm_unregister = 1;
279                 }
280         }
281
282         pthread_mutex_unlock(&g_slot_mutex);
283 #ifdef DEBUG_DETAIL
284         debug_msg("After Slot_mutex UNLOCK\n");
285 #endif
286
287 cleanup:
288         if(param->session_type != ASM_EVENT_CALL &&
289                 param->session_type != ASM_EVENT_VIDEOCALL &&
290                 param->session_type != ASM_EVENT_VOIP &&
291                 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
292                 param->enable_session &&
293                 need_asm_unregister == 1) {
294                 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
295                         debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
296                 }
297                 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
298                         debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
299                         return MM_ERROR_POLICY_INTERNAL;
300                 }
301         }
302
303 #ifdef DEBUG_DETAIL
304         debug_leave("\n");
305 #endif
306
307         return err;
308 }
309
310 int MMSoundMgrCodecPlayWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
311 {
312         int count = 0;
313         mmsound_codec_info_t info;
314         mmsound_codec_param_t codec_param;
315         int err = MM_ERROR_NONE;
316         int errorcode = 0;
317
318 #ifdef DEBUG_DETAIL
319         debug_enter("\n");
320 #endif
321
322         for (count = 0; g_plugins[count].GetSupportTypes; count++) {
323                 /* Find codec */
324                 if (g_plugins[count].Parse(param->source, &info) == MM_ERROR_NONE)
325                         break;
326         }
327
328         /*The count num means codec type WAV, MP3 */
329         debug_msg("Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->repeat_count, param->volume, count);
330
331         if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
332                 debug_error("unsupported file type %d\n", count);
333                 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
334                 goto cleanup;
335         }
336
337         err = _MMSoundMgrCodecGetEmptySlot(slotid);
338         if (err != MM_ERROR_NONE) {
339                 debug_error("Empty g_slot is not found\n");
340                 goto cleanup;
341         }
342
343         codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
344         codec_param.repeat_count = param->repeat_count;
345         codec_param.volume = param->volume;
346         codec_param.source = param->source;
347         codec_param.priority = param->priority;
348         codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
349         codec_param.param = *slotid;
350         codec_param.pid = (int)param->param;
351         codec_param.handle_route = param->handle_route;
352         codec_param.codec_wave_mutex = &codec_wave_mutex;
353         codec_param.stream_index = param->stream_index;
354         strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
355         pthread_mutex_lock(&g_slot_mutex);
356 #ifdef DEBUG_DETAIL
357         debug_msg("After Slot_mutex LOCK\n");
358 #endif
359
360         /* Codec id WAV or MP3 */
361         g_slots[*slotid].pluginid = count;
362         g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
363
364         debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
365
366         err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
367         debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
368         if (err != MM_ERROR_NONE) {
369                 debug_error("Plugin create fail : 0x%08X\n", err);
370                 g_slots[*slotid].status = STATUS_IDLE;
371                 pthread_mutex_unlock(&g_slot_mutex);
372                 debug_warning("After Slot_mutex UNLOCK\n");
373                 goto cleanup;
374         }
375
376         err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
377         if (err != MM_ERROR_NONE) {
378                 debug_error("Fail to play : 0x%08X\n", err);
379                 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
380         }
381
382         pthread_mutex_unlock(&g_slot_mutex);
383 #ifdef DEBUG_DETAIL
384         debug_msg("After Slot_mutex UNLOCK\n");
385 #endif
386
387 cleanup:
388
389 #ifdef DEBUG_DETAIL
390         debug_leave("\n");
391 #endif
392
393         return err;
394
395 }
396
397 #define DTMF_PLUGIN_COUNT 2
398 int MMSoundMgrCodecPlayDtmf(int *slotid, const mmsound_mgr_codec_param_t *param)
399 {
400         int count = 0;
401         int *codec_type;
402         mmsound_codec_info_t info;
403         mmsound_codec_param_t codec_param;
404         int err = MM_ERROR_NONE;
405         int errorcode = 0;
406         int need_asm_unregister = 0;
407
408 #ifdef DEBUG_DETAIL
409         debug_enter("\n");
410 #endif
411
412         for (count = 0; g_plugins[count].GetSupportTypes; count++) {
413                 /* Find codec */
414                 codec_type = g_plugins[count].GetSupportTypes();
415                 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
416                         break;
417         }
418
419         /*The count num means codec type DTMF */
420         debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
421
422         if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
423                 debug_error("unsupported file type %d\n", count);
424                 printf("unsupported file type %d\n", count);
425                 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
426                 goto cleanup;
427         }
428
429 #ifdef DEBUG_DETAIL
430         debug_msg("Get New handle\n");
431 #endif
432
433         err = _MMSoundMgrCodecGetEmptySlot(slotid);
434         if(err != MM_ERROR_NONE)
435         {
436                 debug_error("Empty g_slot is not found\n");
437                 goto cleanup;
438         }
439
440         codec_param.tone = param->tone;
441         codec_param.priority = 0;
442         codec_param.volume_config = param->volume_config;
443         codec_param.repeat_count = param->repeat_count;
444         codec_param.volume = param->volume;
445         codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
446         codec_param.param = *slotid;
447         codec_param.pid = (int)param->param;
448         codec_param.stream_index = param->stream_index;
449         strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
450
451         pthread_mutex_lock(&g_slot_mutex);
452 #ifdef DEBUG_DETAIL
453         debug_msg("After Slot_mutex LOCK\n");
454 #endif
455
456         //
457         /*
458          * Register ASM here
459          */
460
461         if (param->session_type != ASM_EVENT_CALL &&
462                 param->session_type != ASM_EVENT_VIDEOCALL &&
463                 param->session_type != ASM_EVENT_VOIP &&
464                 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
465                 param->enable_session)  {
466                 if(!ASM_register_sound_ex((int)param->param, (int *)(&param->session_handle), param->session_type, ASM_STATE_NONE,
467                                                                 sound_codec_asm_callback, (void*)*slotid, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
468                         debug_critical("ASM_register_sound_ex() failed 0x%X\n", errorcode);
469                         pthread_mutex_unlock(&g_slot_mutex);
470                         return MM_ERROR_POLICY_INTERNAL;
471                 }
472                 if(param->session_options) {
473                         if(!ASM_set_session_option(param->session_handle, param->session_options, &errorcode)) {
474                                 debug_error("ASM_set_session_option() failed 0x%x\n", errorcode);
475                         }
476                 }
477                 if(!ASM_set_sound_state_ex(param->session_handle, param->session_type, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
478                         debug_critical("ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
479                         pthread_mutex_unlock(&g_slot_mutex);
480                         if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
481                                 debug_error("ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
482                         }
483                         return MM_ERROR_POLICY_INTERNAL;
484                 }
485         }
486
487         g_slots[*slotid].pluginid = count;
488         g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
489         g_slots[*slotid].session_type = param->session_type;
490         g_slots[*slotid].session_options = param->session_options;
491         g_slots[*slotid].session_handle = param->session_handle;
492         g_slots[*slotid].enable_session = param->enable_session;
493
494 #ifdef DEBUG_DETAIL
495         debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
496 #endif
497
498         err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
499         debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
500         if (err != MM_ERROR_NONE) {
501                 debug_error("Plugin create fail : 0x%08X\n", err);
502                 g_slots[*slotid].status = STATUS_IDLE;
503                 pthread_mutex_unlock(&g_slot_mutex);
504                 debug_warning("After Slot_mutex UNLOCK\n");
505                 need_asm_unregister = 1;
506                 goto cleanup;
507         }
508
509         err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
510         if (err != MM_ERROR_NONE) {
511                 debug_error("Fail to play : 0x%08X\n", err);
512                 g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
513                 need_asm_unregister = 1;
514         }
515
516         pthread_mutex_unlock(&g_slot_mutex);
517
518         debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
519 #ifdef DEBUG_DETAIL
520         debug_msg("After Slot_mutex UNLOCK\n")
521 #endif
522
523 cleanup:
524         if (param->session_type != ASM_EVENT_CALL &&
525                 param->session_type != ASM_EVENT_VIDEOCALL &&
526                 param->session_type != ASM_EVENT_VOIP &&
527                 param->session_type != ASM_EVENT_VOICE_RECOGNITION &&
528                 param->enable_session &&
529                 need_asm_unregister == 1) {
530                 if(!ASM_unregister_sound_ex(param->session_handle, param->session_type, &errorcode,__asm_process_message)) {
531                         debug_error("Unregister sound failed 0x%X\n", errorcode);
532                         return MM_ERROR_POLICY_INTERNAL;
533                 }
534         }
535
536 #ifdef DEBUG_DETAIL
537         debug_leave("\n");
538 #endif
539
540         return err;
541 }
542
543 MMSoundMgrCodecPlayDtmfWithStreamInfo(int *slotid, const mmsound_mgr_codec_param_t *param)
544 {
545         int count = 0;
546         int *codec_type;
547         mmsound_codec_info_t info;
548         mmsound_codec_param_t codec_param;
549         int err = MM_ERROR_NONE;
550         int errorcode = 0;
551
552 #ifdef DEBUG_DETAIL
553         debug_enter("\n");
554 #endif
555
556         for (count = 0; g_plugins[count].GetSupportTypes; count++) {
557                 /* Find codec */
558                 codec_type = g_plugins[count].GetSupportTypes();
559                 if(codec_type && (MM_SOUND_SUPPORTED_CODEC_DTMF == codec_type[0]))
560                         break;
561         }
562
563         /*The count num means codec type DTMF */
564         debug_msg("DTMF[%d] Repeat[%d] Volume[%f] plugin_codec[%d]\n", param->tone, param->repeat_count, param->volume, count);
565
566         if (g_plugins[count].GetSupportTypes == NULL) { /* Codec not found */
567                 debug_error("unsupported file type %d\n", count);
568                 printf("unsupported file type %d\n", count);
569                 err = MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
570                 goto cleanup;
571         }
572
573 #ifdef DEBUG_DETAIL
574         debug_msg("Get New handle\n");
575 #endif
576
577         err = _MMSoundMgrCodecGetEmptySlot(slotid);
578         if(err != MM_ERROR_NONE)
579         {
580                 debug_error("Empty g_slot is not found\n");
581                 goto cleanup;
582         }
583
584         codec_param.tone = param->tone;
585         codec_param.priority = 0;
586         codec_param.repeat_count = param->repeat_count;
587         codec_param.volume = param->volume;
588         codec_param.stop_cb = _MMSoundMgrCodecStopCallback;
589         codec_param.param = *slotid;
590         codec_param.pid = (int)param->param;
591         codec_param.volume_config = -1; //setting volume config to -1 since using stream info instead of volume type
592         codec_param.stream_index = param->stream_index;
593         strncpy(codec_param.stream_type, param->stream_type, MM_SOUND_STREAM_TYPE_LEN);
594
595         pthread_mutex_lock(&g_slot_mutex);
596 #ifdef DEBUG_DETAIL
597         debug_msg("After Slot_mutex LOCK\n");
598 #endif
599                 g_slots[*slotid].pluginid = count;
600                 g_slots[*slotid].param    = param->param;               /* This arg is used callback data */
601                 g_slots[*slotid].enable_session = param->enable_session;
602
603 #ifdef DEBUG_DETAIL
604                 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
605 #endif
606
607                 err = g_plugins[g_slots[*slotid].pluginid].Create(&codec_param, &info, &(g_slots[*slotid].plughandle));
608                 debug_msg("Created audio handle : [%d]\n", g_slots[*slotid].plughandle);
609                 if (err != MM_ERROR_NONE) {
610                         debug_error("Plugin create fail : 0x%08X\n", err);
611                         g_slots[*slotid].status = STATUS_IDLE;
612                         pthread_mutex_unlock(&g_slot_mutex);
613                         debug_warning("After Slot_mutex UNLOCK\n");
614                         goto cleanup;
615                 }
616
617                 err = g_plugins[g_slots[*slotid].pluginid].Play(g_slots[*slotid].plughandle);
618                 if (err != MM_ERROR_NONE) {
619                         debug_error("Fail to play : 0x%08X\n", err);
620                         g_plugins[g_slots[*slotid].pluginid].Destroy(g_slots[*slotid].plughandle);
621                 }
622
623                 pthread_mutex_unlock(&g_slot_mutex);
624
625                 debug_msg("Using Slotid : [%d] Slot Status : [%d]\n", *slotid, g_slots[*slotid].status);
626 #ifdef DEBUG_DETAIL
627                 debug_msg("After Slot_mutex UNLOCK\n");
628 #endif
629
630         cleanup:
631 #ifdef DEBUG_DETAIL
632                 debug_leave("\n");
633 #endif
634
635                 return err;
636
637 }
638
639 int MMSoundMgrCodecStop(const int slotid)
640 {
641         int err = MM_ERROR_NONE;
642
643         debug_enter("(Slotid : [%d])\n", slotid);
644
645         if (slotid < 0 || MANAGER_HANDLE_MAX <= slotid) {
646                 return MM_ERROR_INVALID_ARGUMENT;
647         }
648
649         pthread_mutex_lock (&g_slot_mutex);
650 #ifdef DEBUG_DETAIL
651         debug_msg("After Slot_mutex LOCK\n");
652 #endif
653         if (g_slots[slotid].status == STATUS_IDLE) {
654                 err = MM_ERROR_SOUND_INVALID_STATE;
655                 debug_warning("The playing slots is not found, Slot ID : [%d]\n", slotid);
656                 goto cleanup;
657         }
658 #ifdef DEBUG_DETAIL
659         debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
660 #endif
661
662         err = g_plugins[g_slots[slotid].pluginid].Stop(g_slots[slotid].plughandle);
663         if (err != MM_ERROR_NONE) {
664                 debug_error("Fail to STOP Code : 0x%08X\n", err);
665         }
666         debug_msg("Found slot, Slotid [%d] State [%d]\n", slotid, g_slots[slotid].status);
667 cleanup:
668         pthread_mutex_unlock(&g_slot_mutex);
669 #ifdef DEBUG_DETAIL
670         debug_msg("After Slot_mutex UNLOCK\n");
671 #endif
672         debug_leave("(err : 0x%08X)\n", err);
673
674         return err;
675 }
676
677 static int _MMSoundMgrCodecStopCallback(int param)
678 {
679         int err = MM_ERROR_NONE;
680
681         debug_enter("(Slot : %d)\n", param);
682
683         pthread_mutex_lock(&g_slot_mutex);
684         debug_msg("[CODEC MGR] Slot_mutex lock done\n");
685
686
687         /*
688          * Unregister ASM here
689          */
690
691         int errorcode = 0;
692         debug_msg("[CODEC MGR] enable_session %d ",g_slots[param].enable_session);
693
694         if (g_slots[param].session_handle) {
695                 if(g_slots[param].session_type != ASM_EVENT_CALL &&
696                         g_slots[param].session_type != ASM_EVENT_VIDEOCALL &&
697                         g_slots[param].session_type != ASM_EVENT_VOIP &&
698                         g_slots[param].session_type != ASM_EVENT_VOICE_RECOGNITION &&
699                         g_slots[param].enable_session ) {
700                         if(!ASM_set_sound_state_ex(g_slots[param].session_handle, g_slots[param].session_type, ASM_STATE_STOP, ASM_RESOURCE_NONE, &errorcode, __asm_process_message)) {
701                                 debug_error("[CODEC MGR] ASM_set_sound_state_ex() failed 0x%X\n", errorcode);
702                         }
703                         debug_msg("[CODEC MGR] ASM unregister\n");
704                         if(!ASM_unregister_sound_ex(g_slots[param].session_handle, g_slots[param].session_type, &errorcode, __asm_process_message)) {
705                                 debug_error("[CODEC MGR] ASM_unregister_sound_ex() failed 0x%X\n", errorcode);
706                         }
707                 }
708         }
709
710         __mm_sound_mgr_ipc_notify_play_file_end(param);
711
712         debug_msg("Client callback msg_type (instance) : [%d]\n", (int)g_slots[param].param);
713         debug_msg("Handle allocated handle : [0x%08X]\n", g_slots[param].plughandle);
714         err = g_plugins[g_slots[param].pluginid].Destroy(g_slots[param].plughandle);
715         if (err < 0 ) {
716                 debug_critical("[CODEC MGR] Fail to destroy slot number : [%d] err [0x%x]\n", param, err);
717         }
718         memset(&g_slots[param], 0, sizeof(__mmsound_mgr_codec_handle_t));
719         g_slots[param].status = STATUS_IDLE;
720         pthread_mutex_unlock(&g_slot_mutex);
721         debug_msg("[CODEC MGR] Slot_mutex done\n");
722
723         return err;
724 }
725
726 static int _MMSoundMgrCodecGetEmptySlot(int *slot)
727 {
728         int count = 0;
729         int err = MM_ERROR_NONE;
730
731 #ifdef DEBUG_DETAIL
732         debug_enter("\n");
733 #endif
734         debug_msg("Codec slot ID : [%d]\n", *slot);
735         pthread_mutex_lock(&g_slot_mutex);
736 #ifdef DEBUG_DETAIL
737         debug_msg("After Slot_mutex LOCK\n");
738 #endif
739
740         for (count = SOUND_SLOT_START; count < MANAGER_HANDLE_MAX ; count++) {
741                 if (g_slots[count].status == STATUS_IDLE) {
742                         g_slots[count].status = STATUS_SOUND;
743                         break;
744                 }
745         }
746         pthread_mutex_unlock(&g_slot_mutex);
747 #ifdef DEBUG_DETAIL
748         debug_msg("After Slot_mutex UNLOCK\n");
749 #endif
750
751         if (count < MANAGER_HANDLE_MAX) {
752                 debug_msg("New handle allocated (codec slot ID : [%d])\n", count);
753                 *slot = count;
754                 err =  MM_ERROR_NONE;
755         } else {
756                 debug_warning("Handle is full handle : [%d]\n", count);
757                 *slot = -1;
758                 /* Temporal code for reset */
759                 while(count--) {
760                         g_slots[count].status = STATUS_IDLE;
761                 }
762                 err =  MM_ERROR_SOUND_INTERNAL;
763         }
764
765 #ifdef DEBUG_DETAIL
766         debug_leave("\n");
767 #endif
768
769         return err;
770 }
771
772 static int _MMSoundMgrCodecRegisterInterface(MMSoundPluginType *plugin)
773 {
774         int err = MM_ERROR_NONE;
775         int count = 0;
776         void *getinterface = NULL;
777
778 #ifdef DEBUG_DETAIL
779         debug_enter("\n");
780 #endif
781
782         /* find emptry slot */
783         for (count = 0; count < MM_SOUND_SUPPORTED_CODEC_NUM; count++) {
784                 if (g_plugins[count].GetSupportTypes == NULL)
785                         break;
786         }
787
788         if (count == MM_SOUND_SUPPORTED_CODEC_NUM) {
789                 debug_critical("The plugin support type is not valid\n");
790                 return MM_ERROR_COMMON_OUT_OF_RANGE;
791         }
792
793         err = MMSoundPluginGetSymbol(plugin, CODEC_GET_INTERFACE_FUNC_NAME, &getinterface);
794         if (err != MM_ERROR_NONE) {
795                 debug_error("Get Symbol CODEC_GET_INTERFACE_FUNC_NAME is fail : %x\n", err);
796                 goto cleanup;
797         }
798         debug_msg("interface[%p] empty_slot[%d]\n", getinterface, count);
799
800         err = MMSoundPlugCodecCastGetInterface(getinterface)(&g_plugins[count]);
801         if (err != MM_ERROR_NONE) {
802                 debug_error("Get interface fail : %x\n", err);
803
804 cleanup:
805                 /* If error occur, clean interface */
806                 memset(&g_plugins[count], 0, sizeof(mmsound_codec_interface_t));
807         } else {
808                 if (g_plugins[count].SetThreadPool)
809                         g_plugins[count].SetThreadPool(MMSoundThreadPoolRun);
810         }
811
812 #ifdef DEBUG_DETAIL
813         debug_leave("\n");
814 #endif
815
816         return err;
817 }
818