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 switch (src_channel) {
141 case AUDIO_CHANNEL_MONO:
142 return CAudioInfo::EChannel::CHANNEL_MONO;
143 case AUDIO_CHANNEL_STEREO:
144 return CAudioInfo::EChannel::CHANNEL_STEREO;
145 case AUDIO_CHANNEL_MULTI_3:
146 return CAudioInfo::EChannel::CHANNEL_MULTI_3;
147 case AUDIO_CHANNEL_MULTI_4:
148 return CAudioInfo::EChannel::CHANNEL_MULTI_4;
149 case AUDIO_CHANNEL_MULTI_5:
150 return CAudioInfo::EChannel::CHANNEL_MULTI_5;
151 case AUDIO_CHANNEL_MULTI_6:
152 return CAudioInfo::EChannel::CHANNEL_MULTI_6;
153 case AUDIO_CHANNEL_MULTI_7:
154 return CAudioInfo::EChannel::CHANNEL_MULTI_7;
155 case AUDIO_CHANNEL_MULTI_8:
156 return CAudioInfo::EChannel::CHANNEL_MULTI_8;
158 return CAudioInfo::EChannel::CHANNEL_MONO;
162 static audio_channel_e __convert_audio_info_channel_to_channel(const CAudioInfo::EChannel& src_channel) {
163 switch (src_channel) {
164 case CAudioInfo::EChannel::CHANNEL_MONO:
165 return AUDIO_CHANNEL_MONO;
166 case CAudioInfo::EChannel::CHANNEL_STEREO:
167 return AUDIO_CHANNEL_STEREO;
168 case CAudioInfo::EChannel::CHANNEL_MULTI_3:
169 return AUDIO_CHANNEL_MULTI_3;
170 case CAudioInfo::EChannel::CHANNEL_MULTI_4:
171 return AUDIO_CHANNEL_MULTI_4;
172 case CAudioInfo::EChannel::CHANNEL_MULTI_5:
173 return AUDIO_CHANNEL_MULTI_5;
174 case CAudioInfo::EChannel::CHANNEL_MULTI_6:
175 return AUDIO_CHANNEL_MULTI_6;
176 case CAudioInfo::EChannel::CHANNEL_MULTI_7:
177 return AUDIO_CHANNEL_MULTI_7;
178 case CAudioInfo::EChannel::CHANNEL_MULTI_8:
179 return AUDIO_CHANNEL_MULTI_8;
181 return AUDIO_CHANNEL_MONO;
185 static CAudioInfo::ESampleType __convert_sample_type_to_audio_info_sample_type(const audio_sample_type_e& src_type) {
187 case AUDIO_SAMPLE_TYPE_U8:
188 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
189 case AUDIO_SAMPLE_TYPE_S16_LE:
190 return CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
191 case AUDIO_SAMPLE_TYPE_S24_LE:
192 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE;
193 case AUDIO_SAMPLE_TYPE_S24_32_LE:
194 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE;
195 case AUDIO_SAMPLE_TYPE_S32_LE:
196 return CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE;
198 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
202 static audio_sample_type_e __convert_audio_info_sample_type_to_sample_type(const CAudioInfo::ESampleType &src_type) {
204 case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
205 return AUDIO_SAMPLE_TYPE_U8;
206 case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
207 return AUDIO_SAMPLE_TYPE_S16_LE;
208 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE:
209 return AUDIO_SAMPLE_TYPE_S24_LE;
210 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE:
211 return AUDIO_SAMPLE_TYPE_S24_32_LE;
212 case CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE:
213 return AUDIO_SAMPLE_TYPE_S32_LE;
215 return AUDIO_SAMPLE_TYPE_U8;
219 static CAudioInfo::EAudioType __convert_sound_type_to_audio_info_audio_type(const sound_type_e &src_type) {
221 case SOUND_TYPE_SYSTEM:
222 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
223 case SOUND_TYPE_NOTIFICATION:
224 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
225 case SOUND_TYPE_ALARM:
226 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
227 case SOUND_TYPE_RINGTONE:
228 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
229 case SOUND_TYPE_MEDIA:
230 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
231 case SOUND_TYPE_CALL:
232 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
233 case SOUND_TYPE_VOIP:
234 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
235 case SOUND_TYPE_VOICE:
236 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
238 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
242 static sound_type_e __convert_audio_info_audio_type_to_sound_type(const CAudioInfo::EAudioType &src_type) {
244 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
245 return SOUND_TYPE_MEDIA;
246 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
247 return SOUND_TYPE_SYSTEM;
248 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
249 return SOUND_TYPE_ALARM;
250 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
251 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
252 return SOUND_TYPE_NOTIFICATION;
253 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
254 return SOUND_TYPE_VOICE;
255 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
256 return SOUND_TYPE_RINGTONE;
257 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
258 return SOUND_TYPE_VOIP;
260 return SOUND_TYPE_MEDIA;
264 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
266 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
267 return AUDIO_IO_STATE_IDLE;
268 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
269 return AUDIO_IO_STATE_IDLE;
270 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
271 return AUDIO_IO_STATE_RUNNING;
272 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
273 return AUDIO_IO_STATE_PAUSED;
275 return AUDIO_IO_STATE_IDLE;
279 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, bool is_output) {
280 if (sample_rate < CAudioInfo::MIN_SYSTEM_SAMPLERATE ||
281 sample_rate > CAudioInfo::MAX_SYSTEM_SAMPLERATE)
282 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
284 if (channel < AUDIO_CHANNEL_MONO ||
285 channel > ((is_output) ? AUDIO_CHANNEL_STEREO : AUDIO_CHANNEL_MULTI_8))
286 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
288 if (type < AUDIO_SAMPLE_TYPE_U8 ||
289 type > AUDIO_SAMPLE_TYPE_S32_LE)
290 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
293 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
294 return CAudioInfo(sampleRate,
295 __convert_channel_to_audio_info_channel(channel),
296 __convert_sample_type_to_audio_info_sample_type(sample_type),
297 CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA,
301 static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
302 return CAudioInfo(sampleRate,
303 __convert_channel_to_audio_info_channel(channel),
304 __convert_sample_type_to_audio_info_sample_type(sample_type),
305 __convert_sound_type_to_audio_info_audio_type(sound_type),
309 static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
310 VALID_POINTER_START(handle)
311 SAFE_FINALIZE(handle->audioIoHandle);
312 SAFE_DELETE(handle->audioIoHandle);
316 VALID_POINTER_START(obj)
318 *(audio_out_h *)obj = nullptr;
320 *(audio_in_h *)obj = nullptr;
325 * Implements CAPI functions
327 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
328 audio_io_s* handle = nullptr;
329 bool mic_enable = false;
333 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
334 "Parameters are NULL input:%p", input);
336 __check_audio_param(sample_rate, channel, type, false);
338 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
340 /* If MIC is not supported, return NOT_SUPPORTED error */
341 int ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
342 AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
343 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
344 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
346 CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
348 handle = new audio_io_s;
349 handle->audioIoHandle = new CAudioInput(audioInfo);
350 handle->audioIoHandle->initialize();
352 AUDIO_IO_LOGD("[%p] created", handle);
354 } catch (const CAudioError& e) {
355 AUDIO_IO_LOGE("%s", e.getErrorMsg());
356 __handle_safe_free(handle, (void *)input, false);
357 return __convert_audio_io_error(e.getError());
358 } catch (const std::bad_alloc&) {
360 AUDIO_IO_LOGE("Failed to allocate handle");
361 __handle_safe_free(handle, (void *)input, false);
362 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
366 return AUDIO_IO_ERROR_NONE;
369 int cpp_audio_in_destroy(audio_in_h input) {
370 auto handle = static_cast<audio_io_s*>(input);
374 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
375 "Parameters are NULL input:%p", input);
376 assert(handle->audioIoHandle);
377 AUDIO_IO_LOGD("unpreparing [%p]", handle);
379 /* Internal unprepare for backward compatibility */
380 handle->audioIoHandle->unprepare();
382 AUDIO_IO_LOGD("try to destroy [%p]", handle);
384 SAFE_FINALIZE(handle->audioIoHandle);
385 SAFE_DELETE(handle->audioIoHandle);
387 } catch (const CAudioError& e) {
388 AUDIO_IO_LOGE("%s", e.getErrorMsg());
389 return __convert_audio_io_error(e.getError());
392 AUDIO_IO_LOGD("destroyed");
394 return AUDIO_IO_ERROR_NONE;
397 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
398 auto handle = static_cast<audio_io_s*>(input);
401 if (!handle || !stream_info)
402 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
403 "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
404 assert(handle->audioIoHandle);
405 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
407 handle->audioIoHandle->setStreamInfo(stream_info);
408 } catch (const CAudioError& e) {
409 AUDIO_IO_LOGE("%s", e.getErrorMsg());
410 return __convert_audio_io_error(e.getError());
413 AUDIO_IO_LOGD("[%p] done", handle);
415 return AUDIO_IO_ERROR_NONE;
418 int cpp_audio_in_prepare(audio_in_h input) {
419 auto handle = static_cast<audio_io_s*>(input);
423 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
424 "Parameters are NULL input:%p", input);
425 assert(handle->audioIoHandle);
426 AUDIO_IO_LOGD("[%p]", handle);
428 handle->audioIoHandle->prepare();
429 } catch (const CAudioError& e) {
430 AUDIO_IO_LOGE("%s", e.getErrorMsg());
431 return __convert_audio_io_error(e.getError());
434 AUDIO_IO_LOGD("[%p] prepared", handle);
436 return AUDIO_IO_ERROR_NONE;
439 int cpp_audio_in_unprepare(audio_in_h input) {
440 auto handle = static_cast<audio_io_s*>(input);
444 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
445 "Parameters are NULL input:%p", input);
446 assert(handle->audioIoHandle);
447 AUDIO_IO_LOGD("[%p]", handle);
449 handle->audioIoHandle->unprepare();
450 } catch (const CAudioError& e) {
451 AUDIO_IO_LOGE("%s", e.getErrorMsg());
452 return __convert_audio_io_error(e.getError());
455 AUDIO_IO_LOGD("[%p] unprepared", handle);
457 return AUDIO_IO_ERROR_NONE;
460 int cpp_audio_in_pause(audio_in_h input) {
461 auto handle = static_cast<audio_io_s*>(input);
465 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
466 "Parameters are NULL input:%p", input);
467 assert(handle->audioIoHandle);
468 AUDIO_IO_LOGD("[%p]", handle);
470 handle->audioIoHandle->pause();
471 } catch (const CAudioError& e) {
472 AUDIO_IO_LOGE("%s", e.getErrorMsg());
473 return __convert_audio_io_error(e.getError());
476 AUDIO_IO_LOGD("[%p] paused", handle);
478 return AUDIO_IO_ERROR_NONE;
481 int cpp_audio_in_resume(audio_in_h input) {
482 auto handle = static_cast<audio_io_s*>(input);
486 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
487 "Parameters are NULL input:%p", input);
488 assert(handle->audioIoHandle);
489 AUDIO_IO_LOGD("[%p]", handle);
491 handle->audioIoHandle->resume();
492 } catch (const CAudioError& e) {
493 AUDIO_IO_LOGE("%s", e.getErrorMsg());
494 return __convert_audio_io_error(e.getError());
497 AUDIO_IO_LOGD("[%p] resumed", handle);
499 return AUDIO_IO_ERROR_NONE;
502 int cpp_audio_in_flush(audio_in_h input) {
503 auto handle = static_cast<audio_io_s*>(input);
507 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
508 "Parameters are NULL input:%p", input);
509 assert(handle->audioIoHandle);
510 AUDIO_IO_LOGD("[%p]", handle);
512 handle->audioIoHandle->flush();
513 } catch (const CAudioError& e) {
514 AUDIO_IO_LOGE("%s", e.getErrorMsg());
515 return __convert_audio_io_error(e.getError());
518 AUDIO_IO_LOGD("[%p] flushed", handle);
520 return AUDIO_IO_ERROR_NONE;
523 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
527 auto handle = static_cast<audio_io_s*>(input);
528 if (!handle || !buffer)
529 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
530 "Parameters are NULL input:%p, buffer:%p", input, buffer);
531 assert(handle->audioIoHandle);
533 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
535 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
537 auto readn = inputHandle->read(buffer, static_cast<size_t>(length));
538 ret = static_cast<int>(readn);
539 #ifdef _AUDIO_IO_DEBUG_TIMING_
540 AUDIO_IO_LOGD("readn:%zu", readn);
542 } catch (const CAudioError& e) {
543 AUDIO_IO_LOGE("%s", e.getErrorMsg());
544 return __convert_audio_io_error(e.getError());
550 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
552 auto handle = static_cast<audio_io_s*>(input);
553 if (!handle || !size)
554 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
555 "Parameters are NULL input:%p, size:%p", input, size);
556 assert(handle->audioIoHandle);
558 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
560 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
562 *size = inputHandle->getBufferSize();
563 } catch (const CAudioError& e) {
564 AUDIO_IO_LOGE("%s", e.getErrorMsg());
565 return __convert_audio_io_error(e.getError());
568 return AUDIO_IO_ERROR_NONE;
571 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
573 auto handle = static_cast<audio_io_s*>(input);
574 if (!handle || !sample_rate)
575 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
576 "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
577 assert(handle->audioIoHandle);
579 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
580 } catch (const CAudioError& e) {
581 AUDIO_IO_LOGE("%s", e.getErrorMsg());
582 return __convert_audio_io_error(e.getError());
585 return AUDIO_IO_ERROR_NONE;
588 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
590 auto handle = static_cast<audio_io_s*>(input);
591 if (!handle || !channel)
592 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
593 "Parameters are NULL input:%p, channel:%p", input, channel);
594 assert(handle->audioIoHandle);
596 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
597 } catch (const CAudioError& e) {
598 AUDIO_IO_LOGE("%s", e.getErrorMsg());
599 return __convert_audio_io_error(e.getError());
602 return AUDIO_IO_ERROR_NONE;
605 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
607 auto handle = static_cast<audio_io_s*>(input);
608 if (!handle || !type)
609 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
610 "Parameters are NULL input:%p, type:%p", input, type);
611 assert(handle->audioIoHandle);
613 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
614 } catch (const CAudioError& e) {
615 AUDIO_IO_LOGE("%s", e.getErrorMsg());
616 return __convert_audio_io_error(e.getError());
619 return AUDIO_IO_ERROR_NONE;
622 static void __stream_cb_internal(size_t nbytes, void *user_data) {
623 auto audioIo = static_cast<audio_io_s*>(user_data);
626 if (audioIo->stream_callback.onStream)
627 audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
631 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
632 CAudioInfo::EAudioIOState state_prev,
635 auto audioIo = static_cast<audio_io_s*>(user_data);
638 if (audioIo->state_changed_callback.onStateChanged)
639 audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
640 __convert_state_type(state), by_policy,
641 audioIo->state_changed_callback.user_data);
645 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
646 auto handle = static_cast<audio_io_s*>(input);
649 if (!handle || !callback)
650 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
651 "Parameters are NULL input:%p, callback:%p", input, callback);
652 assert(handle->audioIoHandle);
653 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
655 handle->stream_callback.set(callback, user_data);
657 auto cb = handle->audioIoHandle->getStreamCallback();
658 cb.set(__stream_cb_internal, static_cast<void*>(handle));
660 handle->audioIoHandle->setStreamCallback(cb);
661 } catch (const CAudioError& e) {
662 AUDIO_IO_LOGE("%s", e.getErrorMsg());
663 return __convert_audio_io_error(e.getError());
666 AUDIO_IO_LOGD("[%p] done", handle);
668 return AUDIO_IO_ERROR_NONE;
671 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
672 auto handle = static_cast<audio_io_s*>(input);
675 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
676 "Parameters are NULL input:%p", input);
677 assert(handle->audioIoHandle);
678 AUDIO_IO_LOGD("[%p]", handle);
680 handle->stream_callback.unset();
682 auto cb = handle->audioIoHandle->getStreamCallback();
685 handle->audioIoHandle->setStreamCallback(cb);
686 } catch (const CAudioError& e) {
687 AUDIO_IO_LOGE("%s", e.getErrorMsg());
688 return __convert_audio_io_error(e.getError());
691 AUDIO_IO_LOGD("[%p] done", handle);
693 return AUDIO_IO_ERROR_NONE;
696 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
700 auto handle = static_cast<audio_io_s*>(input);
701 if (!handle || !buffer)
702 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
703 "Parameters are NULL input:%p, buffer:%p", input, buffer);
705 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
707 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
709 inputHandle->peek(buffer, &_length);
710 } catch (const CAudioError& e) {
711 AUDIO_IO_LOGE("%s", e.getErrorMsg());
712 return __convert_audio_io_error(e.getError());
715 *length = (unsigned int)_length;
717 return AUDIO_IO_ERROR_NONE;
720 int cpp_audio_in_drop(audio_in_h input) {
722 auto handle = static_cast<audio_io_s*>(input);
724 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
725 "Parameters are NULL input:%p", input);
727 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
729 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
732 } catch (const CAudioError& e) {
733 AUDIO_IO_LOGE("%s", e.getErrorMsg());
734 return __convert_audio_io_error(e.getError());
737 return AUDIO_IO_ERROR_NONE;
740 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
741 auto handle = static_cast<audio_io_s*>(input);
744 if (!handle || !callback)
745 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
746 "Parameters are NULL input:%p, callback:%p", input, callback);
747 assert(handle->audioIoHandle);
748 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
750 handle->state_changed_callback.set(callback, user_data);
752 auto cb = handle->audioIoHandle->getStateChangedCallback();
753 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
755 handle->audioIoHandle->setStateChangedCallback(cb);
756 } catch (const CAudioError& e) {
757 AUDIO_IO_LOGE("%s", e.getErrorMsg());
758 return __convert_audio_io_error(e.getError());
761 AUDIO_IO_LOGD("[%p] done", handle);
763 return AUDIO_IO_ERROR_NONE;
766 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
767 auto handle = static_cast<audio_io_s*>(input);
771 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
772 "Parameters are NULL input:%p", input);
773 assert(handle->audioIoHandle);
774 AUDIO_IO_LOGD("[%p]", handle);
776 handle->state_changed_callback.unset();
778 auto cb = handle->audioIoHandle->getStateChangedCallback();
781 handle->audioIoHandle->setStateChangedCallback(cb);
782 } catch (const CAudioError& e) {
783 AUDIO_IO_LOGE("%s", e.getErrorMsg());
784 return __convert_audio_io_error(e.getError());
787 AUDIO_IO_LOGD("[%p] done", handle);
789 return AUDIO_IO_ERROR_NONE;
792 int cpp_audio_in_get_volume(audio_in_h input, double *volume) {
793 auto handle = static_cast<audio_io_s*>(input);
796 if (!handle || !volume)
797 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
798 "Parameters are NULL input:%p, volume:%p", input, volume);
799 assert(handle->audioIoHandle);
800 AUDIO_IO_LOGD("[%p]", handle);
802 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
803 if (input_handle == nullptr)
804 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
806 *volume = input_handle->getVolume();
807 } catch (const CAudioError& e) {
808 AUDIO_IO_LOGE("%s", e.getErrorMsg());
809 return __convert_audio_io_error(e.getError());
812 AUDIO_IO_LOGD("[%p] done", handle);
814 return AUDIO_IO_ERROR_NONE;
817 int cpp_audio_in_set_volume(audio_in_h input, double volume) {
818 auto handle = static_cast<audio_io_s*>(input);
822 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
823 "Parameters are NULL input:%p", input);
825 if (volume < CAudioInfo::MIN_RECORD_VOLUME || volume > CAudioInfo::MAX_RECORD_VOLUME)
826 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid volume: %f", volume);
828 assert(handle->audioIoHandle);
829 AUDIO_IO_LOGD("[%p]", handle);
831 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
832 if (input_handle == nullptr)
833 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
835 input_handle->setVolume(volume);
836 } catch (const CAudioError& e) {
837 AUDIO_IO_LOGE("%s", e.getErrorMsg());
838 return __convert_audio_io_error(e.getError());
841 AUDIO_IO_LOGD("[%p] done", handle);
843 return AUDIO_IO_ERROR_NONE;
849 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
850 audio_io_s* handle = nullptr;
853 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
854 "Parameters are NULL output:%p", output);
856 __check_audio_param(sample_rate, channel, type, true);
858 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
859 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
861 handle = new audio_io_s;
862 handle->audioIoHandle = new CAudioOutput(audioInfo);
863 handle->audioIoHandle->initialize();
865 AUDIO_IO_LOGD("[%p] created", handle);
867 } catch (const CAudioError& e) {
868 AUDIO_IO_LOGE("%s", e.getErrorMsg());
869 __handle_safe_free(handle, (void *)output, true);
870 return __convert_audio_io_error(e.getError());
871 } catch (const std::bad_alloc&) {
873 AUDIO_IO_LOGE("Failed to allocate handle");
874 __handle_safe_free(handle, (void *)output, true);
875 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
879 return AUDIO_IO_ERROR_NONE;
882 int cpp_audio_out_destroy(audio_out_h output) {
883 auto handle = static_cast<audio_io_s*>(output);
887 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
888 "Parameter is NULL output:%p", output);
889 assert(handle->audioIoHandle);
890 AUDIO_IO_LOGD("unpreparing [%p]", handle);
892 /* Internal unprepare for backward compatibility */
893 handle->audioIoHandle->unprepare();
895 AUDIO_IO_LOGD("try to destroy [%p]", handle);
897 SAFE_FINALIZE(handle->audioIoHandle);
898 SAFE_DELETE(handle->audioIoHandle);
900 } catch (const CAudioError& e) {
901 AUDIO_IO_LOGE("%s", e.getErrorMsg());
902 return __convert_audio_io_error(e.getError());
905 AUDIO_IO_LOGD("destroyed");
907 return AUDIO_IO_ERROR_NONE;
910 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
911 auto handle = static_cast<audio_io_s*>(output);
914 if (!handle || !stream_info)
915 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
916 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
917 assert(handle->audioIoHandle);
918 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
920 handle->audioIoHandle->setStreamInfo(stream_info);
921 } catch (const CAudioError& e) {
922 AUDIO_IO_LOGE("%s", e.getErrorMsg());
923 return __convert_audio_io_error(e.getError());
926 AUDIO_IO_LOGD("[%p] done", handle);
928 return AUDIO_IO_ERROR_NONE;
931 int cpp_audio_out_prepare(audio_out_h output) {
932 auto handle = static_cast<audio_io_s*>(output);
936 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
937 "Parameter is NULL output:%p", output);
938 assert(handle->audioIoHandle);
939 AUDIO_IO_LOGD("[%p]", handle);
941 handle->audioIoHandle->prepare();
942 } catch (const CAudioError& e) {
943 AUDIO_IO_LOGE("%s", e.getErrorMsg());
944 return __convert_audio_io_error(e.getError());
947 AUDIO_IO_LOGD("[%p] prepared", handle);
949 return AUDIO_IO_ERROR_NONE;
952 int cpp_audio_out_unprepare(audio_out_h output) {
953 auto handle = static_cast<audio_io_s*>(output);
957 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
958 "Parameter is NULL output:%p", output);
959 assert(handle->audioIoHandle);
960 AUDIO_IO_LOGD("[%p]", handle);
962 handle->audioIoHandle->unprepare();
963 } catch (const CAudioError& e) {
964 AUDIO_IO_LOGE("%s", e.getErrorMsg());
965 return __convert_audio_io_error(e.getError());
968 AUDIO_IO_LOGD("[%p] unprepared", handle);
970 return AUDIO_IO_ERROR_NONE;
973 int cpp_audio_out_pause(audio_out_h output) {
974 auto handle = static_cast<audio_io_s*>(output);
978 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
979 "Parameter is NULL output:%p", output);
980 assert(handle->audioIoHandle);
981 AUDIO_IO_LOGD("[%p]", handle);
983 handle->audioIoHandle->pause();
984 } catch (const CAudioError& e) {
985 AUDIO_IO_LOGE("%s", e.getErrorMsg());
986 return __convert_audio_io_error(e.getError());
989 AUDIO_IO_LOGD("[%p] paused", handle);
991 return AUDIO_IO_ERROR_NONE;
994 int cpp_audio_out_resume(audio_out_h output) {
995 auto handle = static_cast<audio_io_s*>(output);
999 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1000 "Parameter is NULL output:%p", output);
1001 assert(handle->audioIoHandle);
1002 AUDIO_IO_LOGD("[%p]", handle);
1004 handle->audioIoHandle->resume();
1005 } catch (const CAudioError& e) {
1006 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1007 return __convert_audio_io_error(e.getError());
1010 AUDIO_IO_LOGD("[%p] resumed", handle);
1012 return AUDIO_IO_ERROR_NONE;
1015 int cpp_audio_out_drain(audio_out_h output) {
1016 auto handle = static_cast<audio_io_s*>(output);
1020 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1021 "Parameter is NULL output:%p", output);
1022 assert(handle->audioIoHandle);
1023 AUDIO_IO_LOGD("[%p]", handle);
1025 auto output_handle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1026 if (output_handle == nullptr)
1027 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
1029 output_handle->drain();
1030 } catch (const CAudioError& e) {
1031 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1032 return __convert_audio_io_error(e.getError());
1035 AUDIO_IO_LOGD("[%p] drained", handle);
1037 return AUDIO_IO_ERROR_NONE;
1040 int cpp_audio_out_flush(audio_out_h output) {
1041 auto handle = static_cast<audio_io_s*>(output);
1045 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1046 "Parameter is NULL output:%p", output);
1047 assert(handle->audioIoHandle);
1048 AUDIO_IO_LOGD("[%p]", handle);
1050 handle->audioIoHandle->flush();
1051 } catch (const CAudioError& e) {
1052 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1053 return __convert_audio_io_error(e.getError());
1056 AUDIO_IO_LOGD("[%p] flushed", handle);
1058 return AUDIO_IO_ERROR_NONE;
1061 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1065 auto handle = static_cast<audio_io_s*>(output);
1066 if (!handle || !buffer)
1067 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1068 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1069 assert(handle->audioIoHandle);
1071 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1073 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1075 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1076 ret = static_cast<int>(written);
1077 #ifdef _AUDIO_IO_DEBUG_TIMING_
1078 AUDIO_IO_LOGD("written:%zu", written);
1080 } catch (const CAudioError& e) {
1081 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1082 return __convert_audio_io_error(e.getError());
1088 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1090 auto handle = static_cast<audio_io_s*>(output);
1091 if (!handle || !size)
1092 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1093 "Parameters are NULL output:%p, size:%p", output, size);
1094 assert(handle->audioIoHandle);
1096 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1098 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1100 *size = outputHandle->getBufferSize();
1101 } catch (const CAudioError& e) {
1102 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1103 return __convert_audio_io_error(e.getError());
1106 return AUDIO_IO_ERROR_NONE;
1109 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1111 auto handle = static_cast<audio_io_s*>(output);
1112 if (!handle || !sample_rate)
1113 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1114 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1115 assert(handle->audioIoHandle);
1117 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1118 } catch (const CAudioError& e) {
1119 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1120 return __convert_audio_io_error(e.getError());
1123 return AUDIO_IO_ERROR_NONE;
1126 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1128 auto handle = static_cast<audio_io_s*>(output);
1129 if (!handle || !channel)
1130 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1131 "Parameters are NULL output:%p, channel:%p", output, channel);
1132 assert(handle->audioIoHandle);
1134 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1135 } catch (const CAudioError& e) {
1136 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1137 return __convert_audio_io_error(e.getError());
1140 return AUDIO_IO_ERROR_NONE;
1143 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1145 auto handle = static_cast<audio_io_s*>(output);
1146 if (!handle || !type)
1147 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1148 "Parameters are NULL output:%p, type:%p", output, type);
1149 assert(handle->audioIoHandle);
1151 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1152 } catch (const CAudioError& e) {
1153 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1154 return __convert_audio_io_error(e.getError());
1157 return AUDIO_IO_ERROR_NONE;
1160 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1161 auto handle = static_cast<audio_io_s*>(output);
1164 if (!handle || !type)
1165 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1166 "Parameters are NULL output:%p, type:%p", output, type);
1167 assert(handle->audioIoHandle);
1169 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1170 } catch (const CAudioError& e) {
1171 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1172 return __convert_audio_io_error(e.getError());
1175 return AUDIO_IO_ERROR_NONE;
1178 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1179 auto handle = static_cast<audio_io_s*>(output);
1182 if (!handle || !callback)
1183 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1184 "Parameters are NULL output:%p, callback:%p", output, callback);
1185 assert(handle->audioIoHandle);
1186 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1188 handle->stream_callback.set(callback, user_data);
1190 auto cb = handle->audioIoHandle->getStreamCallback();
1191 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1193 handle->audioIoHandle->setStreamCallback(cb);
1194 } catch (const CAudioError& e) {
1195 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1196 return __convert_audio_io_error(e.getError());
1199 AUDIO_IO_LOGD("[%p] done", handle);
1201 return AUDIO_IO_ERROR_NONE;
1204 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1205 auto handle = static_cast<audio_io_s*>(output);
1209 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1210 "Parameters are NULL output:%p", output);
1211 assert(handle->audioIoHandle);
1212 AUDIO_IO_LOGD("[%p]", handle);
1214 handle->stream_callback.unset();
1216 auto cb = handle->audioIoHandle->getStreamCallback();
1219 handle->audioIoHandle->setStreamCallback(cb);
1220 } catch (const CAudioError& e) {
1221 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1222 return __convert_audio_io_error(e.getError());
1225 AUDIO_IO_LOGD("[%p] done", handle);
1227 return AUDIO_IO_ERROR_NONE;
1230 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1231 auto handle = static_cast<audio_io_s*>(output);
1234 if (!handle || !callback)
1235 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1236 "Parameters are NULL output:%p, callback:%p", output, callback);
1237 assert(handle->audioIoHandle);
1238 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1240 handle->state_changed_callback.set(callback, user_data);
1242 auto cb = handle->audioIoHandle->getStateChangedCallback();
1243 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1245 handle->audioIoHandle->setStateChangedCallback(cb);
1246 } catch (const CAudioError& e) {
1247 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1248 return __convert_audio_io_error(e.getError());
1251 AUDIO_IO_LOGD("[%p] done", handle);
1253 return AUDIO_IO_ERROR_NONE;
1256 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1257 auto handle = static_cast<audio_io_s*>(output);
1261 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1262 "Parameters are NULL output:%p", output);
1263 assert(handle->audioIoHandle);
1264 AUDIO_IO_LOGD("[%p]", handle);
1266 handle->state_changed_callback.unset();
1268 auto cb = handle->audioIoHandle->getStateChangedCallback();
1271 handle->audioIoHandle->setStateChangedCallback(cb);
1272 } catch (const CAudioError& e) {
1273 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1274 return __convert_audio_io_error(e.getError());
1277 AUDIO_IO_LOGD("[%p] done", handle);
1279 return AUDIO_IO_ERROR_NONE;