2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "audio_io_private.h"
23 /* TODO : it will be added after updating libmm-sound */
24 //#include <mm_sound_pcm_async.h>
30 #define LOG_TAG "TIZEN_N_AUDIO_IO"
32 * Internal Implementation
34 int __convert_audio_io_error_code(int code, char *func_name)
36 int ret = AUDIO_IO_ERROR_INVALID_OPERATION;
37 char* msg = "AUDIO_IO_ERROR_INVALID_OPERATION";
42 ret = AUDIO_IO_ERROR_NONE;
43 msg = "AUDIO_IO_ERROR_NONE";
45 case MM_ERROR_INVALID_ARGUMENT:
46 case MM_ERROR_SOUND_DEVICE_INVALID_SAMPLERATE:
47 case MM_ERROR_SOUND_DEVICE_INVALID_CHANNEL:
48 case MM_ERROR_SOUND_DEVICE_INVALID_FORMAT:
49 ret = AUDIO_IO_ERROR_INVALID_PARAMETER;
50 msg = "AUDIO_IO_ERROR_INVALID_PARAMETER";
52 case MM_ERROR_SOUND_DEVICE_NOT_OPENED:
53 ret = AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
54 msg = "AUDIO_IO_ERROR_DEVICE_NOT_OPENED";
56 case MM_ERROR_SOUND_PERMISSION_DENIED:
57 ret = AUDIO_IO_ERROR_PERMISSION_DENIED;
58 msg = "AUDIO_IO_ERROR_PERMISSION_DENIED";
60 case MM_ERROR_SOUND_INTERNAL:
61 ret = AUDIO_IO_ERROR_INVALID_OPERATION;
62 msg = "AUDIO_IO_ERROR_INVALID_OPERATION";
64 case MM_ERROR_SOUND_INVALID_POINTER:
65 ret = AUDIO_IO_ERROR_INVALID_BUFFER;
66 msg = "AUDIO_IO_ERROR_INVALID_BUFFER";
68 case MM_ERROR_POLICY_BLOCKED:
69 case MM_ERROR_POLICY_INTERRUPTED:
70 case MM_ERROR_POLICY_INTERNAL:
71 case MM_ERROR_POLICY_DUPLICATED:
72 ret = AUDIO_IO_ERROR_SOUND_POLICY;
73 msg = "AUDIO_IO_ERROR_SOUND_POLICY";
76 LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
80 int __check_parameter(int sample_rate, audio_channel_e channel, audio_sample_type_e type)
82 if(sample_rate<8000 || sample_rate > 48000) {
83 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample rate (8000~48000Hz) : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,sample_rate);
84 return AUDIO_IO_ERROR_INVALID_PARAMETER;
86 if (channel < AUDIO_CHANNEL_MONO || channel > AUDIO_CHANNEL_STEREO) {
87 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid audio channel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,channel);
88 return AUDIO_IO_ERROR_INVALID_PARAMETER;
90 if (type < AUDIO_SAMPLE_TYPE_U8 || type > AUDIO_SAMPLE_TYPE_S16_LE) {
91 LOGE("[%s] AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample typel : %d",__FUNCTION__, AUDIO_IO_ERROR_INVALID_PARAMETER,type);
92 return AUDIO_IO_ERROR_INVALID_PARAMETER;
94 return AUDIO_IO_ERROR_NONE;
97 audio_io_interrupted_code_e __translate_interrupted_code (int code)
99 audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
103 case MM_MSG_CODE_INTERRUPTED_BY_CALL_END:
104 case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END:
105 case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END:
106 case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END:
107 e = AUDIO_IO_INTERRUPTED_COMPLETED;
110 case MM_MSG_CODE_INTERRUPTED_BY_MEDIA:
111 case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP:
112 e = AUDIO_IO_INTERRUPTED_BY_MEDIA;
115 case MM_MSG_CODE_INTERRUPTED_BY_CALL_START:
116 e = AUDIO_IO_INTERRUPTED_BY_CALL;
119 case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG:
120 e = AUDIO_IO_INTERRUPTED_BY_EARJACK_UNPLUG;
123 case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT:
124 e = AUDIO_IO_INTERRUPTED_BY_RESOURCE_CONFLICT;
127 case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START:
128 e = AUDIO_IO_INTERRUPTED_BY_ALARM;
131 case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START:
132 e = AUDIO_IO_INTERRUPTED_BY_NOTIFICATION;
135 case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START:
136 e = AUDIO_IO_INTERRUPTED_BY_EMERGENCY;
139 case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA:
140 e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_MEDIA;
143 case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_CANCELED:
144 e = AUDIO_IO_INTERRUPTED_BY_RESUMABLE_CANCELED;
151 int __mm_sound_pcm_capture_msg_cb (int message, void *param, void *user_param)
153 audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
154 audio_in_s *handle = (audio_in_s *) user_param;
155 MMMessageParamType *msg = (MMMessageParamType*)param;
157 LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
159 if (handle->user_cb == NULL) {
160 LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
164 if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
165 e = __translate_interrupted_code (msg->code);
166 } else if (message == MM_MESSAGE_SOUND_PCM_CAPTURE_RESTRICTED) {
167 /* TODO : handling restricted code is needed */
168 /* e = _translate_restricted_code (msg->code); */
171 handle->user_cb (e, handle->user_data);
176 static int __mm_sound_pcm_playback_msg_cb (int message, void *param, void *user_param)
178 audio_io_interrupted_code_e e = AUDIO_IO_INTERRUPTED_COMPLETED;
179 audio_out_s *handle = (audio_out_s *) user_param;
180 MMMessageParamType *msg = (MMMessageParamType*)param;
182 LOGI("[%s] Got message type : 0x%x with code : %d" ,__FUNCTION__, message, msg->code);
184 if (handle->user_cb == NULL) {
185 LOGI("[%s] No interrupt callback is set. Skip this" ,__FUNCTION__);
189 if (message == MM_MESSAGE_SOUND_PCM_INTERRUPTED) {
190 e = __translate_interrupted_code (msg->code);
193 handle->user_cb (e, handle->user_data);
198 /* TODO : it will be added after updating libmm-sound */
199 //static int __audio_in_stream_cb (void* p, int nbytes, void* userdata)
204 //static int __audio_out_stream_cb (void* p, int nbytes, void* userdata)
211 int audio_in_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input)
214 audio_in_s *handle = NULL;
216 /* input condition check */
217 AUDIO_IO_NULL_ARG_CHECK(input);
218 if(__check_parameter(sample_rate, channel, type) != AUDIO_IO_ERROR_NONE)
219 return AUDIO_IO_ERROR_INVALID_PARAMETER;
221 /* Create Handle & Fill information */
222 if ((handle = (audio_in_s*)malloc( sizeof(audio_in_s))) == NULL) {
223 LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY);
224 return AUDIO_IO_ERROR_OUT_OF_MEMORY;
226 memset(handle, 0, sizeof(audio_in_s));
230 if ((ret = mm_sound_pcm_capture_open( &handle->mm_handle,sample_rate, channel, type)) < 0) {
231 LOGE("mm_sound_pcm_capture_open_ex() failed [0x%x]", ret);
234 LOGI("mm_sound_pcm_capture_open_ex() success");
236 handle->_buffer_size = ret; /* return by pcm_open */
237 handle->_sample_rate = sample_rate;
238 handle->_channel = channel;
239 handle->_type = type;
241 /* Set message interrupt callback */
242 if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_capture_msg_cb, handle)) < 0) {
243 LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret);
246 LOGI("mm_sound_pcm_set_message_callback() success");
249 *input = (audio_in_h)handle;
251 return AUDIO_IO_ERROR_NONE;
256 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
259 int audio_in_set_callback_private(audio_in_h input, audio_in_stream_cb callback, void* userdata)
261 /* TODO : it will be added after updating libmm-sound */
263 return AUDIO_IO_ERROR_NONE;
266 int audio_out_create_private(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type, audio_out_h* output)
268 audio_out_s *handle = NULL;
271 /* input condition check */
272 AUDIO_IO_NULL_ARG_CHECK(output);
273 if(__check_parameter(sample_rate, channel, type)!=AUDIO_IO_ERROR_NONE)
274 return AUDIO_IO_ERROR_INVALID_PARAMETER;
275 if(sound_type < SOUND_TYPE_SYSTEM || sound_type > SOUND_TYPE_CALL) {
276 LOGE("ERROR : AUDIO_IO_ERROR_INVALID_PARAMETER(0x%08x) : Invalid sample sound type : %d",
277 AUDIO_IO_ERROR_INVALID_PARAMETER,sound_type );
278 return AUDIO_IO_ERROR_INVALID_PARAMETER;
281 /* Create Handle & Fill information */
282 if ((handle = (audio_out_s*)malloc( sizeof(audio_out_s))) == NULL) {
283 LOGE("ERROR : AUDIO_IO_ERROR_OUT_OF_MEMORY(0x%08x)", AUDIO_IO_ERROR_OUT_OF_MEMORY);
284 return AUDIO_IO_ERROR_OUT_OF_MEMORY;
286 memset(handle, 0 , sizeof(audio_out_s));
289 if ((ret = mm_sound_pcm_play_open(&handle->mm_handle,sample_rate, channel, type, sound_type)) < 0) {
290 LOGE("mm_sound_pcm_play_open() failed [0x%x]", ret);
293 LOGI("mm_sound_pcm_play_open() success");
296 handle->_buffer_size = ret; /* return by pcm_open */
297 handle->_sample_rate = sample_rate;
298 handle->_channel = channel;
299 handle->_type = type;
300 handle->_sound_type = sound_type;
302 /* Set message interrupt callback */
303 if ((ret = mm_sound_pcm_set_message_callback(handle->mm_handle, __mm_sound_pcm_playback_msg_cb, handle)) < 0) {
304 LOGE("mm_sound_pcm_set_message_callback() failed [0x%x]", ret);
307 LOGI("mm_sound_pcm_set_message_callback() success");
310 *output = (audio_out_h)handle;
312 return AUDIO_IO_ERROR_NONE;
317 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
320 int audio_out_set_callback_private(audio_out_h output, audio_out_stream_cb callback, void* userdata)
322 /* TODO : it will be added after updating libmm-sound */
324 return AUDIO_IO_ERROR_NONE;