summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile.am22
-rw-r--r--common/mm_ipc.c151
-rwxr-xr-xcommon/mm_sound_utils.c368
-rw-r--r--common/mm_source.c272
4 files changed, 813 insertions, 0 deletions
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644
index 0000000..5e97c1b
--- /dev/null
+++ b/common/Makefile.am
@@ -0,0 +1,22 @@
+
+lib_LTLIBRARIES = libmmfsoundcommon.la
+
+libmmfsoundcommon_la_SOURCES = mm_ipc.c \
+ mm_sound_utils.c \
+ mm_source.c
+
+#libmmfsoundcommon_la_DEPENDENCIES = $(libdir)/libmmfcommon.la
+
+libmmfsoundcommon_la_CFLAGS = -I$(srcdir)/../include \
+ $(MMCOMMON_CFLAGS) \
+ $(VCONF_CFLAGS)
+
+libmmfsoundcommon_la_LIBADD = $(MMCOMMON_LIBS) \
+ $(VCONF_LIBS)
+
+#libmmfsound_la_LDFLAGS = -version-info 1:0:1
+
+
+#For logmanager
+libmmfsoundcommon_la_CFLAGS += $(MMLOGSVR_CFLAGS) -DMMF_LOG_OWNER=0x020 -DMMF_DEBUG_PREFIX=\"MMF-SOUND\"
+libmmfsoundcommon_la_LIBADD += $(MMLOGSVR_LIBS)
diff --git a/common/mm_ipc.c b/common/mm_ipc.c
new file mode 100644
index 0000000..11a39e0
--- /dev/null
+++ b/common/mm_ipc.c
@@ -0,0 +1,151 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <aio.h>
+
+#include <mm_ipc.h>
+#include <mm_error.h>
+#include <mm_debug.h>
+
+#define FIX_PROCESS 1
+
+#include <assert.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#include <vconf.h>
+
+#define AUDIO_ROUTE_POLICY_LOCK "audio_route_policy_lock"
+#define LOCK_TIMEOUT_SEC 6
+
+EXPORT_API
+int __mm_sound_lock()
+{
+ sem_t *sem = NULL;
+ int ret;
+ int err = MM_ERROR_NONE;
+ struct timespec wait_time;
+
+ sem = sem_open(AUDIO_ROUTE_POLICY_LOCK, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED)
+ {
+ debug_error("Semaphore open Fail! (name:%s, %s)\n", AUDIO_ROUTE_POLICY_LOCK, strerror(errno));
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+retry_lock:
+ wait_time.tv_sec = (long int)(time(NULL)) + LOCK_TIMEOUT_SEC;
+ wait_time.tv_nsec = 0;
+ ret = sem_timedwait(sem, &wait_time);
+ if(ret == -1)
+ {
+ switch(errno)
+ {
+ case EINTR:
+ debug_error("Lock RETRY LOCK\n");
+ goto retry_lock;
+ break;
+ case EINVAL:
+ debug_error("Invalid semaphore\n");
+ err = MM_ERROR_SOUND_INTERNAL;
+ break;
+ case EAGAIN:
+ debug_error("EAGAIN\n");
+ err = MM_ERROR_SOUND_INTERNAL;
+ break;
+ case ETIMEDOUT:
+ debug_error("sem_wait leached %d seconds timeout.\n", LOCK_TIMEOUT_SEC);
+ {
+ //Recovery of sem_wait lock....in abnormal condition
+ int sem_value = -1;
+ if(0 == sem_getvalue(sem, &sem_value))
+ {
+ debug_error("%s sem value is %d\n",AUDIO_ROUTE_POLICY_LOCK, sem_value);
+ if(sem_value == 0)
+ {
+ ret = sem_post(sem);
+ if(ret == -1)
+ {
+ debug_error("sem_post error %s : %d\n", AUDIO_ROUTE_POLICY_LOCK, sem_value);
+ }
+ else
+ {
+ debug_error("lock recovery success...try lock again\n");
+ goto retry_lock;
+ }
+ }
+ else
+ {
+ debug_error("sem value is not 0. but failed sem_timedwait so retry.. : %s\n",AUDIO_ROUTE_POLICY_LOCK);
+ usleep(5);
+ goto retry_lock;
+ }
+ }
+ else
+ {
+ debug_error("sem_getvalue failed : %s\n",AUDIO_ROUTE_POLICY_LOCK);
+ }
+ }
+ err = MM_ERROR_SOUND_INTERNAL;
+ break;
+ }
+ }
+ sem_close(sem);
+ return err;
+}
+
+EXPORT_API
+int __mm_sound_unlock()
+{
+ sem_t *sem = NULL;
+ int ret;
+ int err = MM_ERROR_NONE;
+
+ sem = sem_open(AUDIO_ROUTE_POLICY_LOCK, O_CREAT, 0666, 1);
+ if (sem == SEM_FAILED)
+ {
+ debug_error("Semaphore open Fail! (name:%s, errno %d)\n", AUDIO_ROUTE_POLICY_LOCK, errno);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ ret = sem_post(sem);
+ if (ret == -1)
+ {
+ debug_error("UNLOCK FAIL\n");
+ err = MM_ERROR_SOUND_INTERNAL;
+ }
+
+ sem_close(sem);
+ return err;
+}
+
diff --git a/common/mm_sound_utils.c b/common/mm_sound_utils.c
new file mode 100755
index 0000000..0cae6f6
--- /dev/null
+++ b/common/mm_sound_utils.c
@@ -0,0 +1,368 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <mm_types.h>
+#include <mm_error.h>
+#include <mm_debug.h>
+#include "../include/mm_sound_private.h"
+#include "../include/mm_sound.h"
+#include "../include/mm_sound_common.h"
+#include "../include/mm_sound_utils.h"
+
+static mm_sound_route g_valid_route[] = {
+ MM_SOUND_ROUTE_OUT_SPEAKER, MM_SOUND_ROUTE_OUT_RECEIVER, MM_SOUND_ROUTE_OUT_WIRED_ACCESSORY, MM_SOUND_ROUTE_OUT_BLUETOOTH_SCO, MM_SOUND_ROUTE_OUT_BLUETOOTH_A2DP,
+ MM_SOUND_ROUTE_OUT_DOCK, MM_SOUND_ROUTE_OUT_HDMI, MM_SOUND_ROUTE_OUT_MIRRORING, MM_SOUND_ROUTE_OUT_USB_AUDIO, MM_SOUND_ROUTE_OUT_MULTIMEDIA_DOCK,
+ MM_SOUND_ROUTE_IN_MIC, MM_SOUND_ROUTE_IN_WIRED_ACCESSORY, MM_SOUND_ROUTE_IN_MIC_OUT_RECEIVER,
+ MM_SOUND_ROUTE_IN_MIC_OUT_SPEAKER, MM_SOUND_ROUTE_IN_MIC_OUT_HEADPHONE,
+ MM_SOUND_ROUTE_INOUT_HEADSET, MM_SOUND_ROUTE_INOUT_BLUETOOTH
+};
+
+#define MM_SOUND_DEFAULT_VOLUME_SYSTEM 9
+#define MM_SOUND_DEFAULT_VOLUME_NOTIFICATION 11
+#define MM_SOUND_DEFAULT_VOLUME_ALARAM 7
+#define MM_SOUND_DEFAULT_VOLUME_RINGTONE 11
+#define MM_SOUND_DEFAULT_VOLUME_MEDIA 7
+#define MM_SOUND_DEFAULT_VOLUME_CALL 4
+#define MM_SOUND_DEFAULT_VOLUME_VOIP 4
+#define MM_SOUND_DEFAULT_VOLUME_VOICE 7
+#define MM_SOUND_DEFAULT_VOLUME_ANDROID 0
+
+static char *g_volume_vconf[VOLUME_TYPE_MAX] = {
+ VCONF_KEY_VOLUME_TYPE_SYSTEM, /* VOLUME_TYPE_SYSTEM */
+ VCONF_KEY_VOLUME_TYPE_NOTIFICATION, /* VOLUME_TYPE_NOTIFICATION */
+ VCONF_KEY_VOLUME_TYPE_ALARM, /* VOLUME_TYPE_ALARM */
+ VCONF_KEY_VOLUME_TYPE_RINGTONE, /* VOLUME_TYPE_RINGTONE */
+ VCONF_KEY_VOLUME_TYPE_MEDIA, /* VOLUME_TYPE_MEDIA */
+ VCONF_KEY_VOLUME_TYPE_CALL, /* VOLUME_TYPE_CALL */
+ VCONF_KEY_VOLUME_TYPE_VOIP, /* VOLUME_TYPE_VOIP */
+ VCONF_KEY_VOLUME_TYPE_VOICE, /* VOLUME_TYPE_VOICE */
+ VCONF_KEY_VOLUME_TYPE_ANDROID /* VOLUME_TYPE_FIXED */
+};
+static char *g_volume_str[VOLUME_TYPE_MAX] = {
+ "SYSTEM",
+ "NOTIFICATION",
+ "ALARM",
+ "RINGTONE",
+ "MEDIA",
+ "CALL",
+ "VOIP",
+ "VOICE",
+ "FIXED",
+};
+
+EXPORT_API
+int _mm_sound_get_valid_route_list(mm_sound_route **route_list)
+{
+ *route_list = g_valid_route;
+
+ return (int)(sizeof(g_valid_route) / sizeof(mm_sound_route));
+}
+
+EXPORT_API
+bool _mm_sound_is_route_valid(mm_sound_route route)
+{
+ mm_sound_route *route_list = 0;
+ int route_index = 0;
+ int route_list_count = 0;
+
+ route_list_count = _mm_sound_get_valid_route_list(&route_list);
+ for (route_index = 0; route_index < route_list_count; route_index++) {
+ if (route_list[route_index] == route)
+ return 1;
+ }
+
+ return 0;
+}
+
+EXPORT_API
+void _mm_sound_get_devices_from_route(mm_sound_route route, mm_sound_device_in *device_in, mm_sound_device_out *device_out)
+{
+ if (device_in && device_out) {
+ *device_in = route & 0x00FF;
+ *device_out = route & 0xFFF00;
+ }
+}
+
+EXPORT_API
+bool _mm_sound_check_hibernation (const char *path)
+{
+ int fd = -1;
+ if (path == NULL) {
+ debug_error ("Path is null\n");
+ return false;
+ }
+
+ fd = open (path, O_RDONLY | O_CREAT, 0644);
+ if (fd != -1) {
+ debug_log ("Open [%s] success!!\n", path);
+ } else {
+ debug_error ("Can't create [%s] with errno [%d]\n", path, errno);
+ return false;
+ }
+
+ close (fd);
+ return true;
+}
+
+EXPORT_API
+int _mm_sound_volume_add_callback(volume_type_t type, void *func, void* user_data)
+{
+ if (vconf_notify_key_changed(g_volume_vconf[type], func, user_data)) {
+ debug_error ("vconf_notify_key_changed failed..\n");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_volume_remove_callback(volume_type_t type, void *func)
+{
+ if (vconf_ignore_key_changed(g_volume_vconf[type], func)) {
+ debug_error ("vconf_ignore_key_changed failed..\n");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_muteall_add_callback(void *func)
+{
+ if (vconf_notify_key_changed(VCONF_KEY_MUTE_ALL, func, NULL)) {
+ debug_error ("vconf_notify_key_changed failed..\n");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_muteall_remove_callback(void *func)
+{
+ if (vconf_ignore_key_changed(VCONF_KEY_MUTE_ALL, func)) {
+ debug_error ("vconf_ignore_key_changed failed..\n");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_volume_get_value_by_type(volume_type_t type, unsigned int *value)
+{
+ int ret = MM_ERROR_NONE;
+ int vconf_value = 0;
+
+ /* Get volume value from VCONF */
+ if (vconf_get_int(g_volume_vconf[type], &vconf_value)) {
+ debug_error ("vconf_get_int(%s) failed..\n", g_volume_vconf[type]);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ *value = vconf_value;
+ if (ret == MM_ERROR_NONE)
+ debug_log("volume_get_value %s %d", g_volume_str[type], *value);
+
+ return ret;
+}
+
+EXPORT_API
+int _mm_sound_volume_set_value_by_type(volume_type_t type, unsigned int value)
+{
+ int ret = MM_ERROR_NONE;
+ int vconf_value = 0;
+
+ vconf_value = value;
+ debug_log("volume_set_value %s %d", g_volume_str[type], value);
+
+ /* Set volume value to VCONF */
+ if ((ret = vconf_set_int(g_volume_vconf[type], vconf_value)) != 0) {
+ debug_error ("vconf_set_int(%s) failed..ret[%d]\n", g_volume_vconf[type], ret);
+ if (ret == -EPERM || ret == -EACCES)
+ return MM_ERROR_SOUND_PERMISSION_DENIED;
+ else
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+ return ret;
+}
+
+EXPORT_API
+int _mm_sound_volume_set_balance(float balance)
+{
+ /* Set balance value to VCONF */
+ if (vconf_set_dbl(VCONF_KEY_VOLUME_BALANCE, balance)) {
+ debug_error ("vconf_set_dbl(%s) failed..\n", VCONF_KEY_VOLUME_BALANCE);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_volume_get_balance(float *balance)
+{
+ double balance_value = 0;
+
+ /* Get balance value from VCONF */
+ if (vconf_get_dbl(VCONF_KEY_VOLUME_BALANCE, &balance_value)) {
+ debug_error ("vconf_get_int(%s) failed..\n", VCONF_KEY_VOLUME_BALANCE);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ *balance = balance_value;
+ debug_log("balance get value [%s]=[%f]", VCONF_KEY_VOLUME_BALANCE, *balance);
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_set_muteall(int muteall)
+{
+ /* Set muteall value to VCONF */
+ if (vconf_set_int(VCONF_KEY_MUTE_ALL, muteall)) {
+ debug_error ("vconf_set_int(%s) failed..\n", VCONF_KEY_MUTE_ALL);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_get_muteall(int *muteall)
+{
+ int muteall_value = 0;
+
+ /* Get muteall value from VCONF */
+ if (vconf_get_int(VCONF_KEY_MUTE_ALL, &muteall_value)) {
+ debug_error ("vconf_get_int(%s) failed..\n", VCONF_KEY_MUTE_ALL);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ *muteall = muteall_value;
+ debug_log("muteall get value [%s]=[%d]", VCONF_KEY_MUTE_ALL, *muteall);
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int __mm_sound_set_stereo_to_mono(int ismono)
+{
+ /* Set ismono value to VCONF */
+ if (vconf_set_int(VCONF_KEY_MONO_AUDIO, ismono)) {
+ debug_error ("vconf_set_int(%s) failed..\n", VCONF_KEY_MONO_AUDIO);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int __mm_sound_get_stereo_to_mono(int *ismono)
+{
+ int ismono_value = 0;
+
+ /* Get ismono value from VCONF */
+ if (vconf_get_int(VCONF_KEY_MONO_AUDIO, &ismono_value)) {
+ debug_error ("vconf_get_int(%s) failed..\n", VCONF_KEY_MONO_AUDIO);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ *ismono = ismono_value;
+ debug_log("ismono get value [%s]=[%d]", VCONF_KEY_MONO_AUDIO, *ismono);
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_get_earjack_type (int *type)
+{
+ int earjack_status = 0;
+
+ if (type == NULL) {
+ debug_error ("invalid parameter!!!");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* Get actual vconf value */
+ vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status);
+ debug_msg ("[%s] get status=[%d]\n", VCONFKEY_SYSMAN_EARJACK, earjack_status);
+
+ *type = (earjack_status >= 0)? earjack_status : VCONFKEY_SYSMAN_EARJACK_REMOVED;
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int _mm_sound_get_dock_type (int *type)
+{
+ int dock_status = 0;
+
+ if (type == NULL) {
+ debug_error ("invalid parameter!!!");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* Get actual vconf value */
+ vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &dock_status);
+ debug_msg ("[%s] get dock status=[%d]\n", VCONFKEY_SYSMAN_CRADLE_STATUS, dock_status);
+
+ *type = dock_status;
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+bool _mm_sound_is_recording (void)
+{
+ int capture_status = 0;
+ bool result = false;
+
+ /* Check whether audio is recording */
+ vconf_get_int(VCONFKEY_RECORDER_STATE, &capture_status);
+ if(capture_status == VCONFKEY_RECORDER_STATE_RECORDING) {
+ result = true;
+ debug_msg ("capture status=%d, result=%d", capture_status, result);
+ }
+ return result;
+}
+
+EXPORT_API
+bool _mm_sound_is_mute_policy (void)
+{
+ int setting_sound_status = true;
+
+ /* If sound is mute mode, force ringtone/notification path to headset */
+ vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &setting_sound_status);
+ debug_log ("[%s] setting_sound_status=%d\n", VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, setting_sound_status);
+
+ return !setting_sound_status;
+}
diff --git a/common/mm_source.c b/common/mm_source.c
new file mode 100644
index 0000000..059e7f4
--- /dev/null
+++ b/common/mm_source.c
@@ -0,0 +1,272 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "mm_types.h"
+#include "mm_debug.h"
+#include "mm_error.h"
+#include "mm_source.h"
+#include "mm_sound_common.h"
+
+static bool _is_drm_file(const char *filePath)
+{
+ char *p = NULL;
+
+ if(!filePath || filePath[0] == '\0') {
+ debug_error("invalid argument\n");
+ return false;
+ }
+
+ p = (char*) strrchr(filePath, '.');
+ if( p && ((strncasecmp(p, ".odf", 4) == 0) || (strncasecmp(p, ".dcf", 4) == 0) ||
+ (strncasecmp(p, ".o4a", 4) == 0) || (strncasecmp(p, ".o4v", 4) == 0))) {
+ return true;
+ }
+ return false;
+}
+
+EXPORT_API
+int mm_source_open_file(const char *filename, MMSourceType *source, int drmsupport)
+{
+ struct stat finfo = {0, };
+ int fd = -1;
+ void *mmap_buf = NULL;
+ unsigned int mediaSize,readSize,offSet=0;
+ char genStr[20];
+ int i;
+
+ if(filename == NULL) {
+ debug_error("filename is null\n");
+ return MM_ERROR_SOUND_INVALID_FILE;
+ }
+ if(drmsupport) {
+ if(_is_drm_file(filename)) {
+ debug_error("%s is DRM contents\n", filename);
+ return MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE;
+ }
+ }
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ debug_error("file [%s] open fail\n", filename);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+ if (fstat(fd, &finfo) == -1) {
+ debug_error("file [%s] get info fail\n", filename);
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ mediaSize = (unsigned int)finfo.st_size;
+
+ /* get the extension (3 characters from last including NULL)*/
+ strncpy((void *)genStr,(void *)(filename+(strlen(filename)-2)),3);
+
+#if defined(_DEBUG_VERBOS_)
+ debug_log("Open file [%s] ext[%s]\n", filename, genStr);
+#endif
+
+ if(strcasecmp (genStr, "dm") == 0) {
+ debug_msg("It is DM file going ahead with special decoding\n");
+
+ /* Vlidation of the DM file */
+ readSize = read(fd,(void*)genStr,0x8);
+ if(readSize != 0x8) {
+ debug_error("Error in Reading the file Header %x/0x8\n",readSize);
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ genStr[readSize] ='\0';
+
+ debug_msg("Header details of DM file %s\n",genStr);
+
+ if(strcasecmp (genStr, "--random") != 0) {
+ debug_error("It is not a valied DM file");
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ /*checking the Media Type */
+ readSize = lseek(fd, 0x32, SEEK_SET);
+ if(readSize != 0x32) {
+ debug_error("Error in Seeking the file to offset %x/0x32\n",readSize);
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ readSize = read(fd,(void*)genStr,0xf);
+
+ for(i=0;i<0xf;i++) {
+ if(genStr[i] == (char)0xD) {
+ genStr[i] ='\0';
+ break;
+ }
+ }
+
+ debug_msg("Header details of DM file %s\n",genStr);
+
+ /*Finding the Media Offset */
+
+ if(strcasecmp (genStr, "audio/mpeg") == 0) {
+ offSet = 0x63;
+ } else if(strcasecmp (genStr, "audio/wav") == 0) {
+ offSet = 0x62;
+ } else {
+ debug_error("It is not MP3/Wav DM file \n");
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ /*Finding the Media Size */
+ mediaSize -= (offSet + 0x28);
+
+ /*Seeking the file to start */
+ readSize = lseek(fd, 0x0, SEEK_SET);
+
+ if( readSize != 0x0) {
+ debug_error("Error in Seeking the file to offset %x/0x32\n",readSize);
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+ }
+
+ mmap_buf = mmap(0, finfo.st_size, PROT_READ, MAP_SHARED, fd,0);
+ if (mmap_buf == NULL) {
+ debug_error("MMAP fail\n");
+ close(fd);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+ source->ptr = mmap_buf+offSet;
+ source->medOffset = offSet;
+#if defined(_DEBUG_VERBOS_)
+ debug_log("source ptr[%p] med offset size[%d]\n", source->ptr, source->medOffset);
+#endif
+ source->tot_size = finfo.st_size;
+ source->cur_size = mediaSize;
+ source->type = MM_SOURCE_FILE;
+ source->fd = fd;
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_source_open_full_memory(const void *ptr, int totsize, int alloc, MMSourceType *source)
+{
+ int err = MM_ERROR_NONE;
+ if (ptr == NULL) {
+ debug_error("PTR is NULL\n");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (alloc) {
+ err = mm_source_open_memory(ptr, totsize, totsize, source);
+ } else {
+ source->ptr = (void *)ptr;
+ source->tot_size = totsize;
+ source->cur_size = totsize;
+ source->type = MM_SOURCE_MEMORY_NOTALLOC;
+ source->fd = -1;
+ }
+
+ return err;
+}
+
+EXPORT_API
+int mm_source_open_memory(const void *ptr, int totsize, int size, MMSourceType *source)
+{
+ source->ptr = (unsigned char*) malloc(totsize);
+ if (source->ptr == NULL) {
+ debug_error("memory alloc fail\n");
+ return MM_ERROR_SOUND_NO_FREE_SPACE;
+ }
+ source->tot_size = totsize;
+ source->cur_size = 0;
+ source->type = MM_SOURCE_MEMORY;
+ source->fd = -1;
+
+ return mm_source_append_memory(ptr, size, source);
+}
+
+EXPORT_API
+int mm_source_append_memory(const void *ptr, int size, MMSourceType *source)
+{
+ if (source->cur_size + size > source->tot_size) {
+ debug_error("memory too large\n");
+ return MM_ERROR_SOUND_NO_FREE_SPACE;
+ }
+
+ memcpy(source->ptr + source->cur_size, ptr, size);
+ source->cur_size += size;
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_source_close(MMSourceType *source)
+{
+ if(source == NULL) {
+ debug_critical("source is null\n");
+ return MM_ERROR_CLASS;
+ }
+
+#if defined(_DEBUG_VERBOS_)
+ debug_log("Source type = %d\n", source->type);
+#endif
+ switch(source->type)
+ {
+ case MM_SOURCE_FILE:
+ if(source->ptr != NULL) {
+ source->ptr -= source->medOffset;
+#if defined(_DEBUG_VERBOS_)
+ debug_log("Med Offset Size : %d/%d",source->medOffset,source->tot_size);
+#endif
+ if (munmap(source->ptr, source->tot_size) == -1) {
+ debug_error("MEM UNMAP fail\n\n");
+ }
+ }
+ close(source->fd);
+ break;
+
+ case MM_SOURCE_MEMORY:
+ if(source->ptr != NULL)
+ free(source->ptr);
+ break;
+
+ case MM_SOURCE_MEMORY_NOTALLOC:
+ break;
+
+ default:
+ debug_critical("Unknown Source\n");
+ break;
+ }
+ memset(source, 0, sizeof(MMSourceType));
+
+ return MM_ERROR_NONE;
+}