6b29ada3e6a682e1325049e9622bdf041a3ac0cf
[platform/core/api/audio-io.git] / src / audio_io.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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. 
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <mm.h>
21 #include <audio_io_private.h>
22 #include <dlog.h>
23
24 #ifdef LOG_TAG
25 #undef LOG_TAG
26 #endif
27 #define LOG_TAG "TIZEN_N_AUDIO_IO"
28 /* TODO : it will be added after updating libmm-sound */
29 //#include <mm_sound_pcm_async.h>
30 /*
31 * Internal Implementation
32 */
33
34
35 /*
36 * Public Implementation
37 */
38
39 /* Audio In */
40 int audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type , audio_in_h* input)
41 {
42         return audio_in_create_private (sample_rate, channel, type, input);
43 }
44
45 int audio_in_create_loopback(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h* input)
46 {
47         return audio_in_create_private (sample_rate, channel, type, input);
48 }
49
50 int audio_in_destroy(audio_in_h input)
51 {
52         AUDIO_IO_NULL_ARG_CHECK(input);
53         audio_in_s *handle = (audio_in_s *) input;
54         int ret = MM_ERROR_NONE;
55
56         ret = mm_sound_pcm_capture_close(handle->mm_handle);
57         if (ret != MM_ERROR_NONE) {
58                 free(handle);
59                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
60         }
61         free(handle);
62
63         LOGI("[%s] mm_sound_pcm_capture_close() success",__FUNCTION__);
64         return AUDIO_IO_ERROR_NONE;
65 }
66
67 int audio_in_prepare(audio_in_h input)
68 {
69         AUDIO_IO_NULL_ARG_CHECK(input);
70         audio_in_s *handle = (audio_in_s *) input;
71         int ret = MM_ERROR_NONE;
72
73         ret = mm_sound_pcm_capture_start(handle->mm_handle);
74         if (ret != MM_ERROR_NONE) {
75                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
76         }
77
78         LOGI("[%s] mm_sound_pcm_capture_start() success",__FUNCTION__);
79         return AUDIO_IO_ERROR_NONE;
80 }
81
82 int audio_in_unprepare(audio_in_h input)
83 {
84         AUDIO_IO_NULL_ARG_CHECK(input);
85         audio_in_s *handle = (audio_in_s *) input;
86         int ret = MM_ERROR_NONE;
87
88         ret = mm_sound_pcm_capture_stop(handle->mm_handle);
89         if (ret != MM_ERROR_NONE) {
90                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
91         }
92
93         LOGI("[%s] mm_sound_pcm_capture_stop() success",__FUNCTION__);
94         return AUDIO_IO_ERROR_NONE;
95 }
96
97 int audio_in_flush(audio_in_h input)
98 {
99         AUDIO_IO_NULL_ARG_CHECK(input);
100         audio_in_s *handle = (audio_in_s *) input;
101         int ret = MM_ERROR_NONE;
102
103         ret = mm_sound_pcm_capture_flush(handle->mm_handle);
104         if (ret != MM_ERROR_NONE) {
105                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
106         }
107
108         LOGI("[%s] mm_sound_pcm_capture_flush() success",__FUNCTION__);
109         return AUDIO_IO_ERROR_NONE;
110 }
111
112 int audio_in_read(audio_in_h input, void *buffer, unsigned int length )
113 {
114         AUDIO_IO_NULL_ARG_CHECK(input);
115         AUDIO_IO_NULL_ARG_CHECK(buffer);
116         audio_in_s *handle = (audio_in_s *) input;
117         int ret = 0;
118         int result = 0;
119
120         ret = mm_sound_pcm_capture_read(handle->mm_handle, (void*) buffer, length);
121         if (ret > 0)
122                 return ret;
123
124         switch(ret)
125         {
126                 case MM_ERROR_SOUND_INVALID_STATE:
127                         result = AUDIO_IO_ERROR_INVALID_OPERATION;
128                         LOGE("[%s] (0x%08x) : Not recording started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
129                         break;
130                 default:
131                         result = __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
132                         break;
133         }
134         return result;
135 }
136
137 int audio_in_get_buffer_size(audio_in_h input, int *size)
138 {
139         AUDIO_IO_NULL_ARG_CHECK(input);
140         AUDIO_IO_NULL_ARG_CHECK(size);
141         audio_in_s *handle = (audio_in_s *) input;
142
143         *size = handle->_buffer_size;
144
145         LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
146         return AUDIO_IO_ERROR_NONE;
147 }
148
149 int audio_in_get_sample_rate(audio_in_h input, int *sample_rate)
150 {
151         AUDIO_IO_NULL_ARG_CHECK(input);
152         AUDIO_IO_NULL_ARG_CHECK(sample_rate);
153         audio_in_s *handle = (audio_in_s *) input;
154
155         *sample_rate = handle->_sample_rate;
156
157         LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
158         return AUDIO_IO_ERROR_NONE;
159 }
160
161
162 int audio_in_get_channel(audio_in_h input, audio_channel_e *channel)
163 {
164         AUDIO_IO_NULL_ARG_CHECK(input);
165         AUDIO_IO_NULL_ARG_CHECK(channel);
166         audio_in_s *handle = (audio_in_s *) input;
167
168         *channel = handle->_channel;
169
170         LOGI("[%s] channel = %d",__FUNCTION__, *channel);
171         return AUDIO_IO_ERROR_NONE;
172 }
173
174 int audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type)
175 {
176         AUDIO_IO_NULL_ARG_CHECK(input);
177         AUDIO_IO_NULL_ARG_CHECK(type);
178         audio_in_s *handle = (audio_in_s *) input;
179
180         *type = handle->_type;
181
182         LOGI("[%s] sample type = %d",__FUNCTION__, *type);
183         return AUDIO_IO_ERROR_NONE;
184 }
185
186 int audio_in_set_interrupted_cb(audio_in_h input, audio_io_interrupted_cb callback, void *user_data)
187 {
188         AUDIO_IO_NULL_ARG_CHECK(input);
189         AUDIO_IO_NULL_ARG_CHECK(callback);
190         audio_in_s *handle = (audio_in_s *) input;
191
192         handle->user_cb = callback;
193         handle->user_data = user_data;
194
195         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
196         return AUDIO_IO_ERROR_NONE;
197 }
198
199 int audio_in_unset_interrupted_cb(audio_in_h input)
200 {
201         AUDIO_IO_NULL_ARG_CHECK(input);
202         audio_in_s  * handle = (audio_in_s  *) input;
203
204         handle->user_cb = NULL;
205         handle->user_data = NULL;
206
207         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
208         return AUDIO_IO_ERROR_NONE;
209 }
210
211 int audio_in_ignore_session(audio_in_h input)
212 {
213         AUDIO_IO_NULL_ARG_CHECK(input);
214         audio_in_s  * handle = (audio_in_s  *) input;
215         int ret = 0;
216
217         ret = mm_sound_pcm_capture_ignore_session(handle->mm_handle);
218         if (ret != MM_ERROR_NONE) {
219                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
220         }
221
222         LOGI("[%s] mm_sound_pcm_capture_ignore_session() success",__FUNCTION__);
223         return AUDIO_IO_ERROR_NONE;
224 }
225
226 int audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* userdata)
227 {
228 /* TODO : it will be added after updating libmm-sound */
229         return AUDIO_IO_ERROR_NONE;
230 }
231
232 int audio_in_unset_stream_cb(audio_in_h input)
233 {
234 /* TODO : it will be added after updating libmm-sound */
235         return AUDIO_IO_ERROR_NONE;
236 }
237
238 int audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length)
239 {
240 /* TODO : it will be added after updating libmm-sound */
241         return AUDIO_IO_ERROR_NONE;
242 }
243
244 int audio_in_drop(audio_in_h input)
245 {
246 /* TODO : it will be added after updating libmm-sound */
247         return AUDIO_IO_ERROR_NONE;
248 }
249
250
251 /* Audio Out */
252 int audio_out_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, sound_type_e sound_type,  audio_out_h* output)
253 {
254         return audio_out_create_private(sample_rate, channel, type, sound_type, output);
255 }
256
257 int audio_out_destroy(audio_out_h output)
258 {
259         AUDIO_IO_NULL_ARG_CHECK(output);
260         audio_out_s *handle = (audio_out_s *) output;
261         int ret = MM_ERROR_NONE;
262
263         ret = mm_sound_pcm_play_close(handle->mm_handle);
264         if (ret != MM_ERROR_NONE) {
265                 free(handle);
266                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
267         }
268         free(handle);
269
270         LOGI("[%s] mm_sound_pcm_play_close() success",__FUNCTION__);
271         return AUDIO_IO_ERROR_NONE;
272 }
273
274 int audio_out_prepare(audio_out_h output)
275 {
276         AUDIO_IO_NULL_ARG_CHECK(output);
277         audio_out_s *handle = (audio_out_s *) output;
278         int ret = MM_ERROR_NONE;
279
280         ret = mm_sound_pcm_play_start(handle->mm_handle);
281         if (ret != MM_ERROR_NONE) {
282                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
283         }
284
285         LOGI("[%s] mm_sound_pcm_play_start() success",__FUNCTION__);
286         return AUDIO_IO_ERROR_NONE;
287 }
288
289 int audio_out_unprepare(audio_out_h output)
290 {
291         AUDIO_IO_NULL_ARG_CHECK(output);
292         audio_out_s *handle = (audio_out_s *) output;
293         int ret = MM_ERROR_NONE;
294
295         ret = mm_sound_pcm_play_stop(handle->mm_handle);
296         if (ret != MM_ERROR_NONE) {
297                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
298         }
299
300         LOGI("[%s] mm_sound_pcm_play_stop() success",__FUNCTION__);
301         return AUDIO_IO_ERROR_NONE;
302 }
303
304 int audio_out_drain(audio_out_h output)
305 {
306         AUDIO_IO_NULL_ARG_CHECK(output);
307         audio_out_s *handle = (audio_out_s *) output;
308         int ret = MM_ERROR_NONE;
309
310         ret = mm_sound_pcm_play_drain(handle->mm_handle);
311         if (ret != MM_ERROR_NONE) {
312                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
313         }
314
315         LOGI("[%s] mm_sound_pcm_play_drain() success",__FUNCTION__);
316         return AUDIO_IO_ERROR_NONE;
317 }
318
319 int audio_out_flush(audio_out_h output)
320 {
321         AUDIO_IO_NULL_ARG_CHECK(output);
322         audio_out_s *handle = (audio_out_s *) output;
323         int ret = MM_ERROR_NONE;
324
325         ret = mm_sound_pcm_play_flush(handle->mm_handle);
326         if (ret != MM_ERROR_NONE) {
327                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
328         }
329
330         LOGI("[%s] mm_sound_pcm_play_flush() success",__FUNCTION__);
331         return AUDIO_IO_ERROR_NONE;
332 }
333
334 int audio_out_write(audio_out_h output, void* buffer, unsigned int length)
335 {
336         AUDIO_IO_NULL_ARG_CHECK(output);
337         AUDIO_IO_NULL_ARG_CHECK(buffer);
338         audio_out_s *handle = (audio_out_s *) output;
339         int ret = MM_ERROR_NONE;
340
341         ret = mm_sound_pcm_play_write(handle->mm_handle, (void*) buffer, length);
342         if (ret > 0) {
343                 LOGI("[%s] (%d/%d) bytes written" ,__FUNCTION__, ret, length);
344                 return ret;
345         }
346         switch(ret)
347         {
348                 case MM_ERROR_SOUND_INVALID_STATE:
349                         ret = AUDIO_IO_ERROR_INVALID_OPERATION;
350                         LOGE("[%s] (0x%08x) : Not playing started yet.",(char*)__FUNCTION__, AUDIO_IO_ERROR_INVALID_OPERATION);
351                         break;
352                 default:
353                         ret = __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
354                         break;
355         }
356         return ret;
357 }
358
359
360 int audio_out_get_buffer_size(audio_out_h output, int *size)
361 {
362         AUDIO_IO_NULL_ARG_CHECK(output);
363         AUDIO_IO_NULL_ARG_CHECK(size);
364         audio_out_s *handle = (audio_out_s *) output;
365
366         *size = handle->_buffer_size;
367
368         LOGI("[%s] buffer size = %d",__FUNCTION__, *size);
369         return AUDIO_IO_ERROR_NONE;
370 }
371
372
373 int audio_out_get_sample_rate(audio_out_h output, int *sample_rate)
374 {
375         AUDIO_IO_NULL_ARG_CHECK(output);
376         AUDIO_IO_NULL_ARG_CHECK(sample_rate);
377         audio_out_s *handle = (audio_out_s *) output;
378
379         *sample_rate = handle->_sample_rate;
380
381         LOGI("[%s] sample rate = %d",__FUNCTION__, *sample_rate);
382         return AUDIO_IO_ERROR_NONE;
383 }
384
385
386 int audio_out_get_channel(audio_out_h output, audio_channel_e *channel)
387 {
388         AUDIO_IO_NULL_ARG_CHECK(output);
389         AUDIO_IO_NULL_ARG_CHECK(channel);
390         audio_out_s *handle = (audio_out_s *) output;
391
392         *channel = handle->_channel;
393
394         LOGI("[%s] channel = %d",__FUNCTION__, *channel);
395         return AUDIO_IO_ERROR_NONE;
396 }
397
398
399 int audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type)
400 {
401         AUDIO_IO_NULL_ARG_CHECK(output);
402         AUDIO_IO_NULL_ARG_CHECK(type);
403         audio_out_s *handle = (audio_out_s *) output;
404
405         *type = handle->_type;
406
407         LOGI("[%s] sample type = %d",__FUNCTION__, *type);
408         return AUDIO_IO_ERROR_NONE;
409 }
410
411
412 int audio_out_get_sound_type(audio_out_h output, sound_type_e *type)
413 {
414         AUDIO_IO_NULL_ARG_CHECK(output);
415         AUDIO_IO_NULL_ARG_CHECK(type);
416         audio_out_s *handle = (audio_out_s *) output;
417
418         *type = handle->_sound_type;
419
420         LOGI("[%s] sound type = %d",__FUNCTION__, *type);
421         return AUDIO_IO_ERROR_NONE;
422 }
423
424 int audio_out_set_interrupted_cb(audio_out_h output, audio_io_interrupted_cb callback, void *user_data)
425 {
426         AUDIO_IO_NULL_ARG_CHECK(output);
427         AUDIO_IO_NULL_ARG_CHECK(callback);
428         audio_out_s *handle = (audio_out_s *) output;
429
430         handle->user_cb = callback;
431         handle->user_data = user_data;
432
433         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
434         return AUDIO_IO_ERROR_NONE;
435 }
436
437 int audio_out_unset_interrupted_cb(audio_out_h output)
438 {
439         AUDIO_IO_NULL_ARG_CHECK(output);
440         audio_out_s *handle = (audio_out_s *) output;
441
442         handle->user_cb = NULL;
443         handle->user_data = NULL;
444
445         LOGI("[%s] current interrupted cb (%p) / data (%p)",__FUNCTION__, handle->user_cb, handle->user_data);
446         return AUDIO_IO_ERROR_NONE;
447 }
448
449 int audio_out_ignore_session(audio_out_h output)
450 {
451         AUDIO_IO_NULL_ARG_CHECK(output);
452         audio_out_s *handle = (audio_out_s *) output;
453         int ret = 0;
454
455         ret = mm_sound_pcm_play_ignore_session(handle->mm_handle);
456         if (ret != MM_ERROR_NONE) {
457                 return __convert_audio_io_error_code(ret, (char*)__FUNCTION__);
458         }
459         LOGI("[%s] mm_sound_pcm_play_ignore_session() success",__FUNCTION__);
460
461         return AUDIO_IO_ERROR_NONE;
462 }
463
464 int audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* userdata)
465 {
466 /* TODO : it will be added after updating libmm-sound */
467         return AUDIO_IO_ERROR_NONE;
468 }
469
470 int audio_out_unset_stream_cb(audio_out_h output)
471 {
472 /* TODO : it will be added after updating libmm-sound */
473         return AUDIO_IO_ERROR_NONE;
474 }