2 * Copyright (c) 2015 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.
20 #include "cpp_audio_io.h"
22 #include "CAudioIODef.h"
24 #include <system_info.h>
27 #define FEATURE_MICROPHONE "http://tizen.org/feature/microphone"
30 using namespace tizen_media_audio;
35 * Name : audio_io_stream_cb_s
36 * Declaration : Keeps user callback pointer and user data for delivering an stream event
38 typedef struct audio_io_stream_cb_s {
40 audio_in_stream_cb onStream;
42 audio_io_stream_cb_s() : user_data(nullptr), onStream(nullptr) { }
44 void set(audio_in_stream_cb callback, void* userdata) {
53 } audio_io_stream_cb_s;
58 * Name : audio_io_state_changed_cb_s
59 * Declaration : Keeps user callback pointer and user data for delivering an state changed event
61 typedef struct audio_io_state_changed_cb_s {
63 audio_in_state_changed_cb onStateChanged;
65 audio_io_state_changed_cb_s() : user_data(nullptr), onStateChanged(nullptr) { }
67 void set(audio_in_state_changed_cb callback, void* userdata) {
68 onStateChanged = callback;
73 onStateChanged = nullptr;
77 } audio_io_state_changed_cb_s;
83 * Declaration : An handle of AudioIO
84 * The handle has two struct for user callback
85 * And the handle has a pointer of private audioIO object
86 * The CAudioIO is a abstract class object about Input and Output
88 typedef struct audio_io_s {
89 CAudioIO* audioIoHandle;
90 audio_io_stream_cb_s stream_callback;
91 audio_io_state_changed_cb_s state_changed_callback;
93 audio_io_s() : audioIoHandle(nullptr) { }
100 static audio_io_error_e __convert_audio_io_error(CAudioError::EError error) {
102 case CAudioError::EError::ERROR_NONE:
103 return AUDIO_IO_ERROR_NONE;
104 case CAudioError::EError::ERROR_INVALID_ARGUMENT:
105 case CAudioError::EError::ERROR_INVALID_HANDLE:
106 return AUDIO_IO_ERROR_INVALID_PARAMETER;
107 case CAudioError::EError::ERROR_DEVICE_NOT_OPENED:
108 return AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
109 case CAudioError::EError::ERROR_DEVICE_NOT_CLOSED:
110 return AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
111 case CAudioError::EError::ERROR_PERMISSION_DENIED:
112 return AUDIO_IO_ERROR_PERMISSION_DENIED;
113 case CAudioError::EError::ERROR_DEVICE_POLICY_RESTRICTION:
114 return AUDIO_IO_ERROR_DEVICE_POLICY_RESTRICTION;
115 case CAudioError::EError::ERROR_NOT_SUPPORTED:
116 return AUDIO_IO_ERROR_NOT_SUPPORTED;
117 case CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE:
118 return AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
119 case CAudioError::EError::ERROR_MAX:
120 case CAudioError::EError::ERROR_INTERNAL_OPERATION:
121 case CAudioError::EError::ERROR_NOT_INITIALIZED:
122 case CAudioError::EError::ERROR_FAILED_OPERATION:
123 case CAudioError::EError::ERROR_INVALID_OPERATION:
124 return AUDIO_IO_ERROR_INVALID_OPERATION;
125 case CAudioError::EError::ERROR_INVALID_STATE:
126 return AUDIO_IO_ERROR_INVALID_STATE;
127 case CAudioError::EError::ERROR_OUT_OF_MEMORY:
128 case CAudioError::EError::ERROR_INVALID_POINTER:
129 return AUDIO_IO_ERROR_INVALID_BUFFER;
130 case CAudioError::EError::ERROR_POLICY_BLOCKED:
131 case CAudioError::EError::ERROR_POLICY_INTERRUPTED:
132 case CAudioError::EError::ERROR_POLICY_DUPLICATED:
133 return AUDIO_IO_ERROR_SOUND_POLICY;
135 return AUDIO_IO_ERROR_NONE;
139 static CAudioInfo::EChannel __convert_channel_to_audio_info_channel(const audio_channel_e &src_channel) {
140 if (src_channel < AUDIO_CHANNEL_MONO ||
141 src_channel > AUDIO_CHANNEL_MULTI_16)
142 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid src_channel:%d", src_channel);
144 return static_cast<CAudioInfo::EChannel>(src_channel - AUDIO_CHANNEL_MONO + 1);
147 static audio_channel_e __convert_audio_info_channel_to_channel(const CAudioInfo::EChannel& src_channel) {
148 if (src_channel < CAudioInfo::EChannel::CHANNEL_MONO ||
149 src_channel >= CAudioInfo::EChannel::CHANNEL_MAX)
150 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid src_channel:%d", static_cast<int>(src_channel));
152 return static_cast<audio_channel_e>(static_cast<int>(src_channel) + AUDIO_CHANNEL_MONO - 1);
155 static CAudioInfo::ESampleType __convert_sample_type_to_audio_info_sample_type(const audio_sample_type_e& src_type) {
156 if (src_type < AUDIO_SAMPLE_TYPE_U8 ||
157 src_type > AUDIO_SAMPLE_TYPE_S32_LE)
158 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid src_type:%d", src_type);
160 return static_cast<CAudioInfo::ESampleType>(static_cast<int>(src_type) - AUDIO_SAMPLE_TYPE_U8 + 1);
163 static audio_sample_type_e __convert_audio_info_sample_type_to_sample_type(const CAudioInfo::ESampleType &src_type) {
164 if (src_type < CAudioInfo::ESampleType::SAMPLE_TYPE_U8 ||
165 src_type >= CAudioInfo::ESampleType::SAMPLE_TYPE_MAX)
166 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid src_type:%d", static_cast<int>(src_type));
168 return static_cast<audio_sample_type_e>(static_cast<int>(src_type) + AUDIO_SAMPLE_TYPE_U8 - 1);
171 static CAudioInfo::EAudioType __convert_sound_type_to_audio_info_audio_type(const sound_type_e &src_type) {
173 case SOUND_TYPE_SYSTEM:
174 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
175 case SOUND_TYPE_NOTIFICATION:
176 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
177 case SOUND_TYPE_ALARM:
178 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
179 case SOUND_TYPE_RINGTONE:
180 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
181 case SOUND_TYPE_MEDIA:
182 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
183 case SOUND_TYPE_CALL:
184 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
185 case SOUND_TYPE_VOIP:
186 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
187 case SOUND_TYPE_VOICE:
188 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
190 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
194 static sound_type_e __convert_audio_info_audio_type_to_sound_type(const CAudioInfo::EAudioType &src_type) {
196 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
197 return SOUND_TYPE_MEDIA;
198 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
199 return SOUND_TYPE_SYSTEM;
200 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
201 return SOUND_TYPE_ALARM;
202 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
203 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
204 return SOUND_TYPE_NOTIFICATION;
205 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
206 return SOUND_TYPE_VOICE;
207 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
208 return SOUND_TYPE_RINGTONE;
209 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
210 return SOUND_TYPE_VOIP;
212 return SOUND_TYPE_MEDIA;
216 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
218 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
219 return AUDIO_IO_STATE_IDLE;
220 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
221 return AUDIO_IO_STATE_IDLE;
222 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
223 return AUDIO_IO_STATE_RUNNING;
224 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
225 return AUDIO_IO_STATE_PAUSED;
227 return AUDIO_IO_STATE_IDLE;
231 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, bool is_output) {
232 if (sample_rate < CAudioInfo::MIN_SYSTEM_SAMPLERATE ||
233 sample_rate > CAudioInfo::MAX_SYSTEM_SAMPLERATE)
234 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
236 if (channel < AUDIO_CHANNEL_MONO ||
237 channel > ((is_output) ? AUDIO_CHANNEL_STEREO : AUDIO_CHANNEL_MULTI_16))
238 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
240 if (type < AUDIO_SAMPLE_TYPE_U8 ||
241 type > AUDIO_SAMPLE_TYPE_S32_LE)
242 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :0x%x", type);
245 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
246 return CAudioInfo(sampleRate,
247 __convert_channel_to_audio_info_channel(channel),
248 __convert_sample_type_to_audio_info_sample_type(sample_type),
249 CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA,
253 static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
254 return CAudioInfo(sampleRate,
255 __convert_channel_to_audio_info_channel(channel),
256 __convert_sample_type_to_audio_info_sample_type(sample_type),
257 __convert_sound_type_to_audio_info_audio_type(sound_type),
261 static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
262 VALID_POINTER_START(handle)
263 SAFE_FINALIZE(handle->audioIoHandle);
264 SAFE_DELETE(handle->audioIoHandle);
268 VALID_POINTER_START(obj)
270 *(audio_out_h *)obj = nullptr;
272 *(audio_in_h *)obj = nullptr;
277 * Implements CAPI functions
279 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
280 audio_io_s* handle = nullptr;
281 bool mic_enable = false;
285 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
286 "Parameters are NULL input:%p", input);
288 __check_audio_param(sample_rate, channel, type, false);
290 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
292 /* If MIC is not supported, return NOT_SUPPORTED error */
293 int ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
294 AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
295 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
296 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
298 CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
300 handle = new audio_io_s;
301 handle->audioIoHandle = new CAudioInput(audioInfo);
302 handle->audioIoHandle->initialize();
304 AUDIO_IO_LOGD("[%p] created", handle);
306 } catch (const CAudioError& e) {
307 AUDIO_IO_LOGE("%s", e.getErrorMsg());
308 __handle_safe_free(handle, (void *)input, false);
309 return __convert_audio_io_error(e.getError());
310 } catch (const std::bad_alloc&) {
312 AUDIO_IO_LOGE("Failed to allocate handle");
313 __handle_safe_free(handle, (void *)input, false);
314 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
318 return AUDIO_IO_ERROR_NONE;
321 int cpp_audio_in_destroy(audio_in_h input) {
322 auto handle = static_cast<audio_io_s*>(input);
326 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
327 "Parameters are NULL input:%p", input);
328 assert(handle->audioIoHandle);
329 AUDIO_IO_LOGD("unpreparing [%p]", handle);
331 /* Internal unprepare for backward compatibility */
332 handle->audioIoHandle->unprepare();
334 AUDIO_IO_LOGD("try to destroy [%p]", handle);
336 SAFE_FINALIZE(handle->audioIoHandle);
337 SAFE_DELETE(handle->audioIoHandle);
339 } catch (const CAudioError& e) {
340 AUDIO_IO_LOGE("%s", e.getErrorMsg());
341 return __convert_audio_io_error(e.getError());
344 AUDIO_IO_LOGD("destroyed");
346 return AUDIO_IO_ERROR_NONE;
349 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
350 auto handle = static_cast<audio_io_s*>(input);
353 if (!handle || !stream_info)
354 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
355 "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
356 assert(handle->audioIoHandle);
357 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
359 handle->audioIoHandle->setStreamInfo(stream_info);
360 } catch (const CAudioError& e) {
361 AUDIO_IO_LOGE("%s", e.getErrorMsg());
362 return __convert_audio_io_error(e.getError());
365 AUDIO_IO_LOGD("[%p] done", handle);
367 return AUDIO_IO_ERROR_NONE;
370 int cpp_audio_in_prepare(audio_in_h input) {
371 auto handle = static_cast<audio_io_s*>(input);
375 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
376 "Parameters are NULL input:%p", input);
377 assert(handle->audioIoHandle);
378 AUDIO_IO_LOGD("[%p]", handle);
380 handle->audioIoHandle->prepare();
381 } catch (const CAudioError& e) {
382 AUDIO_IO_LOGE("%s", e.getErrorMsg());
383 return __convert_audio_io_error(e.getError());
386 AUDIO_IO_LOGD("[%p] prepared", handle);
388 return AUDIO_IO_ERROR_NONE;
391 int cpp_audio_in_unprepare(audio_in_h input) {
392 auto handle = static_cast<audio_io_s*>(input);
396 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
397 "Parameters are NULL input:%p", input);
398 assert(handle->audioIoHandle);
399 AUDIO_IO_LOGD("[%p]", handle);
401 handle->audioIoHandle->unprepare();
402 } catch (const CAudioError& e) {
403 AUDIO_IO_LOGE("%s", e.getErrorMsg());
404 return __convert_audio_io_error(e.getError());
407 AUDIO_IO_LOGD("[%p] unprepared", handle);
409 return AUDIO_IO_ERROR_NONE;
412 int cpp_audio_in_pause(audio_in_h input) {
413 auto handle = static_cast<audio_io_s*>(input);
417 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
418 "Parameters are NULL input:%p", input);
419 assert(handle->audioIoHandle);
420 AUDIO_IO_LOGD("[%p]", handle);
422 handle->audioIoHandle->pause();
423 } catch (const CAudioError& e) {
424 AUDIO_IO_LOGE("%s", e.getErrorMsg());
425 return __convert_audio_io_error(e.getError());
428 AUDIO_IO_LOGD("[%p] paused", handle);
430 return AUDIO_IO_ERROR_NONE;
433 int cpp_audio_in_resume(audio_in_h input) {
434 auto handle = static_cast<audio_io_s*>(input);
438 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
439 "Parameters are NULL input:%p", input);
440 assert(handle->audioIoHandle);
441 AUDIO_IO_LOGD("[%p]", handle);
443 handle->audioIoHandle->resume();
444 } catch (const CAudioError& e) {
445 AUDIO_IO_LOGE("%s", e.getErrorMsg());
446 return __convert_audio_io_error(e.getError());
449 AUDIO_IO_LOGD("[%p] resumed", handle);
451 return AUDIO_IO_ERROR_NONE;
454 int cpp_audio_in_flush(audio_in_h input) {
455 auto handle = static_cast<audio_io_s*>(input);
459 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
460 "Parameters are NULL input:%p", input);
461 assert(handle->audioIoHandle);
462 AUDIO_IO_LOGD("[%p]", handle);
464 handle->audioIoHandle->flush();
465 } catch (const CAudioError& e) {
466 AUDIO_IO_LOGE("%s", e.getErrorMsg());
467 return __convert_audio_io_error(e.getError());
470 AUDIO_IO_LOGD("[%p] flushed", handle);
472 return AUDIO_IO_ERROR_NONE;
475 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
479 auto handle = static_cast<audio_io_s*>(input);
480 if (!handle || !buffer)
481 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
482 "Parameters are NULL input:%p, buffer:%p", input, buffer);
483 assert(handle->audioIoHandle);
485 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
487 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
489 auto readn = inputHandle->read(buffer, static_cast<size_t>(length));
490 ret = static_cast<int>(readn);
491 #ifdef _AUDIO_IO_DEBUG_TIMING_
492 AUDIO_IO_LOGD("readn:%zu", readn);
494 } catch (const CAudioError& e) {
495 AUDIO_IO_LOGE("%s", e.getErrorMsg());
496 return __convert_audio_io_error(e.getError());
502 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
504 auto handle = static_cast<audio_io_s*>(input);
505 if (!handle || !size)
506 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
507 "Parameters are NULL input:%p, size:%p", input, size);
508 assert(handle->audioIoHandle);
510 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
512 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
514 *size = inputHandle->getBufferSize();
515 } catch (const CAudioError& e) {
516 AUDIO_IO_LOGE("%s", e.getErrorMsg());
517 return __convert_audio_io_error(e.getError());
520 return AUDIO_IO_ERROR_NONE;
523 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
525 auto handle = static_cast<audio_io_s*>(input);
526 if (!handle || !sample_rate)
527 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
528 "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
529 assert(handle->audioIoHandle);
531 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
532 } catch (const CAudioError& e) {
533 AUDIO_IO_LOGE("%s", e.getErrorMsg());
534 return __convert_audio_io_error(e.getError());
537 return AUDIO_IO_ERROR_NONE;
540 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
542 auto handle = static_cast<audio_io_s*>(input);
543 if (!handle || !channel)
544 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
545 "Parameters are NULL input:%p, channel:%p", input, channel);
546 assert(handle->audioIoHandle);
548 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
549 } catch (const CAudioError& e) {
550 AUDIO_IO_LOGE("%s", e.getErrorMsg());
551 return __convert_audio_io_error(e.getError());
554 return AUDIO_IO_ERROR_NONE;
557 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
559 auto handle = static_cast<audio_io_s*>(input);
560 if (!handle || !type)
561 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
562 "Parameters are NULL input:%p, type:%p", input, type);
563 assert(handle->audioIoHandle);
565 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
566 } catch (const CAudioError& e) {
567 AUDIO_IO_LOGE("%s", e.getErrorMsg());
568 return __convert_audio_io_error(e.getError());
571 return AUDIO_IO_ERROR_NONE;
574 static void __stream_cb_internal(size_t nbytes, void *user_data) {
575 auto audioIo = static_cast<audio_io_s*>(user_data);
578 if (audioIo->stream_callback.onStream)
579 audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
583 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
584 CAudioInfo::EAudioIOState state_prev,
587 auto audioIo = static_cast<audio_io_s*>(user_data);
590 if (audioIo->state_changed_callback.onStateChanged)
591 audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
592 __convert_state_type(state), by_policy,
593 audioIo->state_changed_callback.user_data);
597 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
598 auto handle = static_cast<audio_io_s*>(input);
601 if (!handle || !callback)
602 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
603 "Parameters are NULL input:%p, callback:%p", input, callback);
604 assert(handle->audioIoHandle);
605 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
607 handle->stream_callback.set(callback, user_data);
609 auto cb = handle->audioIoHandle->getStreamCallback();
610 cb.set(__stream_cb_internal, static_cast<void*>(handle));
612 handle->audioIoHandle->setStreamCallback(cb);
613 } catch (const CAudioError& e) {
614 AUDIO_IO_LOGE("%s", e.getErrorMsg());
615 return __convert_audio_io_error(e.getError());
618 AUDIO_IO_LOGD("[%p] done", handle);
620 return AUDIO_IO_ERROR_NONE;
623 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
624 auto handle = static_cast<audio_io_s*>(input);
627 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
628 "Parameters are NULL input:%p", input);
629 assert(handle->audioIoHandle);
630 AUDIO_IO_LOGD("[%p]", handle);
632 handle->stream_callback.unset();
634 auto cb = handle->audioIoHandle->getStreamCallback();
637 handle->audioIoHandle->setStreamCallback(cb);
638 } catch (const CAudioError& e) {
639 AUDIO_IO_LOGE("%s", e.getErrorMsg());
640 return __convert_audio_io_error(e.getError());
643 AUDIO_IO_LOGD("[%p] done", handle);
645 return AUDIO_IO_ERROR_NONE;
648 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
652 auto handle = static_cast<audio_io_s*>(input);
653 if (!handle || !buffer)
654 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
655 "Parameters are NULL input:%p, buffer:%p", input, buffer);
657 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
659 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
661 inputHandle->peek(buffer, &_length);
662 } catch (const CAudioError& e) {
663 AUDIO_IO_LOGE("%s", e.getErrorMsg());
664 return __convert_audio_io_error(e.getError());
667 *length = (unsigned int)_length;
669 return AUDIO_IO_ERROR_NONE;
672 int cpp_audio_in_drop(audio_in_h input) {
674 auto handle = static_cast<audio_io_s*>(input);
676 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
677 "Parameters are NULL input:%p", input);
679 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
681 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
684 } catch (const CAudioError& e) {
685 AUDIO_IO_LOGE("%s", e.getErrorMsg());
686 return __convert_audio_io_error(e.getError());
689 return AUDIO_IO_ERROR_NONE;
692 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
693 auto handle = static_cast<audio_io_s*>(input);
696 if (!handle || !callback)
697 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
698 "Parameters are NULL input:%p, callback:%p", input, callback);
699 assert(handle->audioIoHandle);
700 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
702 handle->state_changed_callback.set(callback, user_data);
704 auto cb = handle->audioIoHandle->getStateChangedCallback();
705 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
707 handle->audioIoHandle->setStateChangedCallback(cb);
708 } catch (const CAudioError& e) {
709 AUDIO_IO_LOGE("%s", e.getErrorMsg());
710 return __convert_audio_io_error(e.getError());
713 AUDIO_IO_LOGD("[%p] done", handle);
715 return AUDIO_IO_ERROR_NONE;
718 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
719 auto handle = static_cast<audio_io_s*>(input);
723 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
724 "Parameters are NULL input:%p", input);
725 assert(handle->audioIoHandle);
726 AUDIO_IO_LOGD("[%p]", handle);
728 handle->state_changed_callback.unset();
730 auto cb = handle->audioIoHandle->getStateChangedCallback();
733 handle->audioIoHandle->setStateChangedCallback(cb);
734 } catch (const CAudioError& e) {
735 AUDIO_IO_LOGE("%s", e.getErrorMsg());
736 return __convert_audio_io_error(e.getError());
739 AUDIO_IO_LOGD("[%p] done", handle);
741 return AUDIO_IO_ERROR_NONE;
744 int cpp_audio_in_get_volume(audio_in_h input, double *volume) {
745 auto handle = static_cast<audio_io_s*>(input);
748 if (!handle || !volume)
749 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
750 "Parameters are NULL input:%p, volume:%p", input, volume);
751 assert(handle->audioIoHandle);
752 AUDIO_IO_LOGD("[%p]", handle);
754 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
755 if (input_handle == nullptr)
756 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
758 *volume = input_handle->getVolume();
759 } catch (const CAudioError& e) {
760 AUDIO_IO_LOGE("%s", e.getErrorMsg());
761 return __convert_audio_io_error(e.getError());
764 AUDIO_IO_LOGD("[%p] done", handle);
766 return AUDIO_IO_ERROR_NONE;
769 int cpp_audio_in_set_volume(audio_in_h input, double volume) {
770 auto handle = static_cast<audio_io_s*>(input);
774 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
775 "Parameters are NULL input:%p", input);
777 if (volume < CAudioInfo::MIN_RECORD_VOLUME || volume > CAudioInfo::MAX_RECORD_VOLUME)
778 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid volume: %f", volume);
780 assert(handle->audioIoHandle);
781 AUDIO_IO_LOGD("[%p]", handle);
783 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
784 if (input_handle == nullptr)
785 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
787 input_handle->setVolume(volume);
788 } catch (const CAudioError& e) {
789 AUDIO_IO_LOGE("%s", e.getErrorMsg());
790 return __convert_audio_io_error(e.getError());
793 AUDIO_IO_LOGD("[%p] done", handle);
795 return AUDIO_IO_ERROR_NONE;
801 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
802 audio_io_s* handle = nullptr;
805 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
806 "Parameters are NULL output:%p", output);
808 __check_audio_param(sample_rate, channel, type, true);
810 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
811 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
813 handle = new audio_io_s;
814 handle->audioIoHandle = new CAudioOutput(audioInfo);
815 handle->audioIoHandle->initialize();
817 AUDIO_IO_LOGD("[%p] created", handle);
819 } catch (const CAudioError& e) {
820 AUDIO_IO_LOGE("%s", e.getErrorMsg());
821 __handle_safe_free(handle, (void *)output, true);
822 return __convert_audio_io_error(e.getError());
823 } catch (const std::bad_alloc&) {
825 AUDIO_IO_LOGE("Failed to allocate handle");
826 __handle_safe_free(handle, (void *)output, true);
827 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
831 return AUDIO_IO_ERROR_NONE;
834 int cpp_audio_out_destroy(audio_out_h output) {
835 auto handle = static_cast<audio_io_s*>(output);
839 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
840 "Parameter is NULL output:%p", output);
841 assert(handle->audioIoHandle);
842 AUDIO_IO_LOGD("unpreparing [%p]", handle);
844 /* Internal unprepare for backward compatibility */
845 handle->audioIoHandle->unprepare();
847 AUDIO_IO_LOGD("try to destroy [%p]", handle);
849 SAFE_FINALIZE(handle->audioIoHandle);
850 SAFE_DELETE(handle->audioIoHandle);
852 } catch (const CAudioError& e) {
853 AUDIO_IO_LOGE("%s", e.getErrorMsg());
854 return __convert_audio_io_error(e.getError());
857 AUDIO_IO_LOGD("destroyed");
859 return AUDIO_IO_ERROR_NONE;
862 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
863 auto handle = static_cast<audio_io_s*>(output);
866 if (!handle || !stream_info)
867 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
868 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
869 assert(handle->audioIoHandle);
870 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
872 handle->audioIoHandle->setStreamInfo(stream_info);
873 } catch (const CAudioError& e) {
874 AUDIO_IO_LOGE("%s", e.getErrorMsg());
875 return __convert_audio_io_error(e.getError());
878 AUDIO_IO_LOGD("[%p] done", handle);
880 return AUDIO_IO_ERROR_NONE;
883 int cpp_audio_out_prepare(audio_out_h output) {
884 auto handle = static_cast<audio_io_s*>(output);
888 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
889 "Parameter is NULL output:%p", output);
890 assert(handle->audioIoHandle);
891 AUDIO_IO_LOGD("[%p]", handle);
893 handle->audioIoHandle->prepare();
894 } catch (const CAudioError& e) {
895 AUDIO_IO_LOGE("%s", e.getErrorMsg());
896 return __convert_audio_io_error(e.getError());
899 AUDIO_IO_LOGD("[%p] prepared", handle);
901 return AUDIO_IO_ERROR_NONE;
904 int cpp_audio_out_unprepare(audio_out_h output) {
905 auto handle = static_cast<audio_io_s*>(output);
909 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
910 "Parameter is NULL output:%p", output);
911 assert(handle->audioIoHandle);
912 AUDIO_IO_LOGD("[%p]", handle);
914 handle->audioIoHandle->unprepare();
915 } catch (const CAudioError& e) {
916 AUDIO_IO_LOGE("%s", e.getErrorMsg());
917 return __convert_audio_io_error(e.getError());
920 AUDIO_IO_LOGD("[%p] unprepared", handle);
922 return AUDIO_IO_ERROR_NONE;
925 int cpp_audio_out_pause(audio_out_h output) {
926 auto handle = static_cast<audio_io_s*>(output);
930 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
931 "Parameter is NULL output:%p", output);
932 assert(handle->audioIoHandle);
933 AUDIO_IO_LOGD("[%p]", handle);
935 handle->audioIoHandle->pause();
936 } catch (const CAudioError& e) {
937 AUDIO_IO_LOGE("%s", e.getErrorMsg());
938 return __convert_audio_io_error(e.getError());
941 AUDIO_IO_LOGD("[%p] paused", handle);
943 return AUDIO_IO_ERROR_NONE;
946 int cpp_audio_out_resume(audio_out_h output) {
947 auto handle = static_cast<audio_io_s*>(output);
951 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
952 "Parameter is NULL output:%p", output);
953 assert(handle->audioIoHandle);
954 AUDIO_IO_LOGD("[%p]", handle);
956 handle->audioIoHandle->resume();
957 } catch (const CAudioError& e) {
958 AUDIO_IO_LOGE("%s", e.getErrorMsg());
959 return __convert_audio_io_error(e.getError());
962 AUDIO_IO_LOGD("[%p] resumed", handle);
964 return AUDIO_IO_ERROR_NONE;
967 int cpp_audio_out_drain(audio_out_h output) {
968 auto handle = static_cast<audio_io_s*>(output);
972 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
973 "Parameter is NULL output:%p", output);
974 assert(handle->audioIoHandle);
975 AUDIO_IO_LOGD("[%p]", handle);
977 auto output_handle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
978 if (output_handle == nullptr)
979 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
981 output_handle->drain();
982 } catch (const CAudioError& e) {
983 AUDIO_IO_LOGE("%s", e.getErrorMsg());
984 return __convert_audio_io_error(e.getError());
987 AUDIO_IO_LOGD("[%p] drained", handle);
989 return AUDIO_IO_ERROR_NONE;
992 int cpp_audio_out_flush(audio_out_h output) {
993 auto handle = static_cast<audio_io_s*>(output);
997 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
998 "Parameter is NULL output:%p", output);
999 assert(handle->audioIoHandle);
1000 AUDIO_IO_LOGD("[%p]", handle);
1002 handle->audioIoHandle->flush();
1003 } catch (const CAudioError& e) {
1004 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1005 return __convert_audio_io_error(e.getError());
1008 AUDIO_IO_LOGD("[%p] flushed", handle);
1010 return AUDIO_IO_ERROR_NONE;
1013 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1017 auto handle = static_cast<audio_io_s*>(output);
1018 if (!handle || !buffer)
1019 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1020 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1021 assert(handle->audioIoHandle);
1023 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1025 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1027 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1028 ret = static_cast<int>(written);
1029 #ifdef _AUDIO_IO_DEBUG_TIMING_
1030 AUDIO_IO_LOGD("written:%zu", written);
1032 } catch (const CAudioError& e) {
1033 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1034 return __convert_audio_io_error(e.getError());
1040 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1042 auto handle = static_cast<audio_io_s*>(output);
1043 if (!handle || !size)
1044 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1045 "Parameters are NULL output:%p, size:%p", output, size);
1046 assert(handle->audioIoHandle);
1048 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1050 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1052 *size = outputHandle->getBufferSize();
1053 } catch (const CAudioError& e) {
1054 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1055 return __convert_audio_io_error(e.getError());
1058 return AUDIO_IO_ERROR_NONE;
1061 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1063 auto handle = static_cast<audio_io_s*>(output);
1064 if (!handle || !sample_rate)
1065 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1066 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1067 assert(handle->audioIoHandle);
1069 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1070 } catch (const CAudioError& e) {
1071 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1072 return __convert_audio_io_error(e.getError());
1075 return AUDIO_IO_ERROR_NONE;
1078 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1080 auto handle = static_cast<audio_io_s*>(output);
1081 if (!handle || !channel)
1082 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1083 "Parameters are NULL output:%p, channel:%p", output, channel);
1084 assert(handle->audioIoHandle);
1086 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1087 } catch (const CAudioError& e) {
1088 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1089 return __convert_audio_io_error(e.getError());
1092 return AUDIO_IO_ERROR_NONE;
1095 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1097 auto handle = static_cast<audio_io_s*>(output);
1098 if (!handle || !type)
1099 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1100 "Parameters are NULL output:%p, type:%p", output, type);
1101 assert(handle->audioIoHandle);
1103 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1104 } catch (const CAudioError& e) {
1105 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1106 return __convert_audio_io_error(e.getError());
1109 return AUDIO_IO_ERROR_NONE;
1112 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1113 auto handle = static_cast<audio_io_s*>(output);
1116 if (!handle || !type)
1117 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1118 "Parameters are NULL output:%p, type:%p", output, type);
1119 assert(handle->audioIoHandle);
1121 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1122 } catch (const CAudioError& e) {
1123 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1124 return __convert_audio_io_error(e.getError());
1127 return AUDIO_IO_ERROR_NONE;
1130 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1131 auto handle = static_cast<audio_io_s*>(output);
1134 if (!handle || !callback)
1135 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1136 "Parameters are NULL output:%p, callback:%p", output, callback);
1137 assert(handle->audioIoHandle);
1138 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1140 handle->stream_callback.set(callback, user_data);
1142 auto cb = handle->audioIoHandle->getStreamCallback();
1143 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1145 handle->audioIoHandle->setStreamCallback(cb);
1146 } catch (const CAudioError& e) {
1147 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1148 return __convert_audio_io_error(e.getError());
1151 AUDIO_IO_LOGD("[%p] done", handle);
1153 return AUDIO_IO_ERROR_NONE;
1156 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1157 auto handle = static_cast<audio_io_s*>(output);
1161 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1162 "Parameters are NULL output:%p", output);
1163 assert(handle->audioIoHandle);
1164 AUDIO_IO_LOGD("[%p]", handle);
1166 handle->stream_callback.unset();
1168 auto cb = handle->audioIoHandle->getStreamCallback();
1171 handle->audioIoHandle->setStreamCallback(cb);
1172 } catch (const CAudioError& e) {
1173 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1174 return __convert_audio_io_error(e.getError());
1177 AUDIO_IO_LOGD("[%p] done", handle);
1179 return AUDIO_IO_ERROR_NONE;
1182 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1183 auto handle = static_cast<audio_io_s*>(output);
1186 if (!handle || !callback)
1187 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1188 "Parameters are NULL output:%p, callback:%p", output, callback);
1189 assert(handle->audioIoHandle);
1190 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1192 handle->state_changed_callback.set(callback, user_data);
1194 auto cb = handle->audioIoHandle->getStateChangedCallback();
1195 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1197 handle->audioIoHandle->setStateChangedCallback(cb);
1198 } catch (const CAudioError& e) {
1199 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1200 return __convert_audio_io_error(e.getError());
1203 AUDIO_IO_LOGD("[%p] done", handle);
1205 return AUDIO_IO_ERROR_NONE;
1208 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1209 auto handle = static_cast<audio_io_s*>(output);
1213 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1214 "Parameters are NULL output:%p", output);
1215 assert(handle->audioIoHandle);
1216 AUDIO_IO_LOGD("[%p]", handle);
1218 handle->state_changed_callback.unset();
1220 auto cb = handle->audioIoHandle->getStateChangedCallback();
1223 handle->audioIoHandle->setStateChangedCallback(cb);
1224 } catch (const CAudioError& e) {
1225 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1226 return __convert_audio_io_error(e.getError());
1229 AUDIO_IO_LOGD("[%p] done", handle);
1231 return AUDIO_IO_ERROR_NONE;