diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 22 | ||||
-rw-r--r-- | common/mm_ipc.c | 151 | ||||
-rwxr-xr-x | common/mm_sound_utils.c | 368 | ||||
-rw-r--r-- | common/mm_source.c | 272 |
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; +} |