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("[%p]", handle);
379 /* Internal unprepare for backward compatibility */
380 handle->audioIoHandle->unprepare();
382 SAFE_FINALIZE(handle->audioIoHandle);
383 SAFE_DELETE(handle->audioIoHandle);
385 } catch (const CAudioError& e) {
386 AUDIO_IO_LOGE("%s", e.getErrorMsg());
387 return __convert_audio_io_error(e.getError());
390 AUDIO_IO_LOGD("destroyed");
392 return AUDIO_IO_ERROR_NONE;
395 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
396 auto handle = static_cast<audio_io_s*>(input);
399 if (!handle || !stream_info)
400 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
401 "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
402 assert(handle->audioIoHandle);
403 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
405 handle->audioIoHandle->setStreamInfo(stream_info);
406 } catch (const CAudioError& e) {
407 AUDIO_IO_LOGE("%s", e.getErrorMsg());
408 return __convert_audio_io_error(e.getError());
411 AUDIO_IO_LOGD("[%p] done", handle);
413 return AUDIO_IO_ERROR_NONE;
416 int cpp_audio_in_prepare(audio_in_h input) {
417 auto handle = static_cast<audio_io_s*>(input);
421 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
422 "Parameters are NULL input:%p", input);
423 assert(handle->audioIoHandle);
424 AUDIO_IO_LOGD("[%p]", handle);
426 handle->audioIoHandle->prepare();
427 } catch (const CAudioError& e) {
428 AUDIO_IO_LOGE("%s", e.getErrorMsg());
429 return __convert_audio_io_error(e.getError());
432 AUDIO_IO_LOGD("[%p] prepared", handle);
434 return AUDIO_IO_ERROR_NONE;
437 int cpp_audio_in_unprepare(audio_in_h input) {
438 auto handle = static_cast<audio_io_s*>(input);
442 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
443 "Parameters are NULL input:%p", input);
444 assert(handle->audioIoHandle);
445 AUDIO_IO_LOGD("[%p]", handle);
447 handle->audioIoHandle->unprepare();
448 } catch (const CAudioError& e) {
449 AUDIO_IO_LOGE("%s", e.getErrorMsg());
450 return __convert_audio_io_error(e.getError());
453 AUDIO_IO_LOGD("[%p] unprepared", handle);
455 return AUDIO_IO_ERROR_NONE;
458 int cpp_audio_in_pause(audio_in_h input) {
459 auto handle = static_cast<audio_io_s*>(input);
463 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
464 "Parameters are NULL input:%p", input);
465 assert(handle->audioIoHandle);
466 AUDIO_IO_LOGD("[%p]", handle);
468 handle->audioIoHandle->pause();
469 } catch (const CAudioError& e) {
470 AUDIO_IO_LOGE("%s", e.getErrorMsg());
471 return __convert_audio_io_error(e.getError());
474 AUDIO_IO_LOGD("[%p] paused", handle);
476 return AUDIO_IO_ERROR_NONE;
479 int cpp_audio_in_resume(audio_in_h input) {
480 auto handle = static_cast<audio_io_s*>(input);
484 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
485 "Parameters are NULL input:%p", input);
486 assert(handle->audioIoHandle);
487 AUDIO_IO_LOGD("[%p]", handle);
489 handle->audioIoHandle->resume();
490 } catch (const CAudioError& e) {
491 AUDIO_IO_LOGE("%s", e.getErrorMsg());
492 return __convert_audio_io_error(e.getError());
495 AUDIO_IO_LOGD("[%p] resumed", handle);
497 return AUDIO_IO_ERROR_NONE;
500 int cpp_audio_in_flush(audio_in_h input) {
501 auto handle = static_cast<audio_io_s*>(input);
505 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
506 "Parameters are NULL input:%p", input);
507 assert(handle->audioIoHandle);
508 AUDIO_IO_LOGD("[%p]", handle);
510 handle->audioIoHandle->flush();
511 } catch (const CAudioError& e) {
512 AUDIO_IO_LOGE("%s", e.getErrorMsg());
513 return __convert_audio_io_error(e.getError());
516 AUDIO_IO_LOGD("[%p] flushed", handle);
518 return AUDIO_IO_ERROR_NONE;
521 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
525 auto handle = static_cast<audio_io_s*>(input);
526 if (!handle || !buffer)
527 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
528 "Parameters are NULL input:%p, buffer:%p", input, buffer);
529 assert(handle->audioIoHandle);
531 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
533 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
535 auto readn = inputHandle->read(buffer, static_cast<size_t>(length));
536 ret = static_cast<int>(readn);
537 #ifdef _AUDIO_IO_DEBUG_TIMING_
538 AUDIO_IO_LOGD("readn:%zu", readn);
540 } catch (const CAudioError& e) {
541 AUDIO_IO_LOGE("%s", e.getErrorMsg());
542 return __convert_audio_io_error(e.getError());
548 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
550 auto handle = static_cast<audio_io_s*>(input);
551 if (!handle || !size)
552 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
553 "Parameters are NULL input:%p, size:%p", input, size);
554 assert(handle->audioIoHandle);
556 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
558 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
560 *size = inputHandle->getBufferSize();
561 } catch (const CAudioError& e) {
562 AUDIO_IO_LOGE("%s", e.getErrorMsg());
563 return __convert_audio_io_error(e.getError());
566 return AUDIO_IO_ERROR_NONE;
569 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
571 auto handle = static_cast<audio_io_s*>(input);
572 if (!handle || !sample_rate)
573 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
574 "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
575 assert(handle->audioIoHandle);
577 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
578 } catch (const CAudioError& e) {
579 AUDIO_IO_LOGE("%s", e.getErrorMsg());
580 return __convert_audio_io_error(e.getError());
583 return AUDIO_IO_ERROR_NONE;
586 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
588 auto handle = static_cast<audio_io_s*>(input);
589 if (!handle || !channel)
590 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
591 "Parameters are NULL input:%p, channel:%p", input, channel);
592 assert(handle->audioIoHandle);
594 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
595 } catch (const CAudioError& e) {
596 AUDIO_IO_LOGE("%s", e.getErrorMsg());
597 return __convert_audio_io_error(e.getError());
600 return AUDIO_IO_ERROR_NONE;
603 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
605 auto handle = static_cast<audio_io_s*>(input);
606 if (!handle || !type)
607 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
608 "Parameters are NULL input:%p, type:%p", input, type);
609 assert(handle->audioIoHandle);
611 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
612 } catch (const CAudioError& e) {
613 AUDIO_IO_LOGE("%s", e.getErrorMsg());
614 return __convert_audio_io_error(e.getError());
617 return AUDIO_IO_ERROR_NONE;
620 static void __stream_cb_internal(size_t nbytes, void *user_data) {
621 auto audioIo = static_cast<audio_io_s*>(user_data);
624 if (audioIo->stream_callback.onStream)
625 audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
629 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
630 CAudioInfo::EAudioIOState state_prev,
633 auto audioIo = static_cast<audio_io_s*>(user_data);
636 if (audioIo->state_changed_callback.onStateChanged)
637 audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
638 __convert_state_type(state), by_policy,
639 audioIo->state_changed_callback.user_data);
643 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
644 auto handle = static_cast<audio_io_s*>(input);
647 if (!handle || !callback)
648 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
649 "Parameters are NULL input:%p, callback:%p", input, callback);
650 assert(handle->audioIoHandle);
651 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
653 handle->stream_callback.set(callback, user_data);
655 auto cb = handle->audioIoHandle->getStreamCallback();
656 cb.set(__stream_cb_internal, static_cast<void*>(handle));
658 handle->audioIoHandle->setStreamCallback(cb);
659 } catch (const CAudioError& e) {
660 AUDIO_IO_LOGE("%s", e.getErrorMsg());
661 return __convert_audio_io_error(e.getError());
664 AUDIO_IO_LOGD("[%p] done", handle);
666 return AUDIO_IO_ERROR_NONE;
669 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
670 auto handle = static_cast<audio_io_s*>(input);
673 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
674 "Parameters are NULL input:%p", input);
675 assert(handle->audioIoHandle);
676 AUDIO_IO_LOGD("[%p]", handle);
678 handle->stream_callback.unset();
680 auto cb = handle->audioIoHandle->getStreamCallback();
683 handle->audioIoHandle->setStreamCallback(cb);
684 } catch (const CAudioError& e) {
685 AUDIO_IO_LOGE("%s", e.getErrorMsg());
686 return __convert_audio_io_error(e.getError());
689 AUDIO_IO_LOGD("[%p] done", handle);
691 return AUDIO_IO_ERROR_NONE;
694 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
698 auto handle = static_cast<audio_io_s*>(input);
699 if (!handle || !buffer)
700 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
701 "Parameters are NULL input:%p, buffer:%p", input, buffer);
703 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
705 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
707 inputHandle->peek(buffer, &_length);
708 } catch (const CAudioError& e) {
709 AUDIO_IO_LOGE("%s", e.getErrorMsg());
710 return __convert_audio_io_error(e.getError());
713 *length = (unsigned int)_length;
715 return AUDIO_IO_ERROR_NONE;
718 int cpp_audio_in_drop(audio_in_h input) {
720 auto handle = static_cast<audio_io_s*>(input);
722 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
723 "Parameters are NULL input:%p", input);
725 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
727 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL"); // LCOV_EXCL_LINE
730 } catch (const CAudioError& e) {
731 AUDIO_IO_LOGE("%s", e.getErrorMsg());
732 return __convert_audio_io_error(e.getError());
735 return AUDIO_IO_ERROR_NONE;
738 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
739 auto handle = static_cast<audio_io_s*>(input);
742 if (!handle || !callback)
743 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
744 "Parameters are NULL input:%p, callback:%p", input, callback);
745 assert(handle->audioIoHandle);
746 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
748 handle->state_changed_callback.set(callback, user_data);
750 auto cb = handle->audioIoHandle->getStateChangedCallback();
751 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
753 handle->audioIoHandle->setStateChangedCallback(cb);
754 } catch (const CAudioError& e) {
755 AUDIO_IO_LOGE("%s", e.getErrorMsg());
756 return __convert_audio_io_error(e.getError());
759 AUDIO_IO_LOGD("[%p] done", handle);
761 return AUDIO_IO_ERROR_NONE;
764 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
765 auto handle = static_cast<audio_io_s*>(input);
769 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
770 "Parameters are NULL input:%p", input);
771 assert(handle->audioIoHandle);
772 AUDIO_IO_LOGD("[%p]", handle);
774 handle->state_changed_callback.unset();
776 auto cb = handle->audioIoHandle->getStateChangedCallback();
779 handle->audioIoHandle->setStateChangedCallback(cb);
780 } catch (const CAudioError& e) {
781 AUDIO_IO_LOGE("%s", e.getErrorMsg());
782 return __convert_audio_io_error(e.getError());
785 AUDIO_IO_LOGD("[%p] done", handle);
787 return AUDIO_IO_ERROR_NONE;
790 int cpp_audio_in_get_volume(audio_in_h input, double *volume) {
791 auto handle = static_cast<audio_io_s*>(input);
794 if (!handle || !volume)
795 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
796 "Parameters are NULL input:%p, volume:%p", input, volume);
797 assert(handle->audioIoHandle);
798 AUDIO_IO_LOGD("[%p]", handle);
800 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
801 if (input_handle == nullptr)
802 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
804 *volume = input_handle->getVolume();
805 } catch (const CAudioError& e) {
806 AUDIO_IO_LOGE("%s", e.getErrorMsg());
807 return __convert_audio_io_error(e.getError());
810 AUDIO_IO_LOGD("[%p] done", handle);
812 return AUDIO_IO_ERROR_NONE;
815 int cpp_audio_in_set_volume(audio_in_h input, double volume) {
816 auto handle = static_cast<audio_io_s*>(input);
820 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
821 "Parameters are NULL input:%p", input);
823 if (volume < CAudioInfo::MIN_RECORD_VOLUME || volume > CAudioInfo::MAX_RECORD_VOLUME)
824 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid volume: %f", volume);
826 assert(handle->audioIoHandle);
827 AUDIO_IO_LOGD("[%p]", handle);
829 auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
830 if (input_handle == nullptr)
831 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
833 input_handle->setVolume(volume);
834 } catch (const CAudioError& e) {
835 AUDIO_IO_LOGE("%s", e.getErrorMsg());
836 return __convert_audio_io_error(e.getError());
839 AUDIO_IO_LOGD("[%p] done", handle);
841 return AUDIO_IO_ERROR_NONE;
847 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
848 audio_io_s* handle = nullptr;
851 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
852 "Parameters are NULL output:%p", output);
854 __check_audio_param(sample_rate, channel, type, true);
856 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
857 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
859 handle = new audio_io_s;
860 handle->audioIoHandle = new CAudioOutput(audioInfo);
861 handle->audioIoHandle->initialize();
863 AUDIO_IO_LOGD("[%p] created", handle);
865 } catch (const CAudioError& e) {
866 AUDIO_IO_LOGE("%s", e.getErrorMsg());
867 __handle_safe_free(handle, (void *)output, true);
868 return __convert_audio_io_error(e.getError());
869 } catch (const std::bad_alloc&) {
871 AUDIO_IO_LOGE("Failed to allocate handle");
872 __handle_safe_free(handle, (void *)output, true);
873 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
877 return AUDIO_IO_ERROR_NONE;
880 int cpp_audio_out_destroy(audio_out_h output) {
881 auto handle = static_cast<audio_io_s*>(output);
885 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
886 "Parameter is NULL output:%p", output);
887 assert(handle->audioIoHandle);
888 AUDIO_IO_LOGD("[%p]", handle);
890 /* Internal unprepare for backward compatibility */
891 handle->audioIoHandle->unprepare();
893 SAFE_FINALIZE(handle->audioIoHandle);
894 SAFE_DELETE(handle->audioIoHandle);
896 } catch (const CAudioError& e) {
897 AUDIO_IO_LOGE("%s", e.getErrorMsg());
898 return __convert_audio_io_error(e.getError());
901 AUDIO_IO_LOGD("[%p] destroyed", handle);
903 return AUDIO_IO_ERROR_NONE;
906 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
907 auto handle = static_cast<audio_io_s*>(output);
910 if (!handle || !stream_info)
911 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
912 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
913 assert(handle->audioIoHandle);
914 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
916 handle->audioIoHandle->setStreamInfo(stream_info);
917 } catch (const CAudioError& e) {
918 AUDIO_IO_LOGE("%s", e.getErrorMsg());
919 return __convert_audio_io_error(e.getError());
922 AUDIO_IO_LOGD("[%p] done", handle);
924 return AUDIO_IO_ERROR_NONE;
927 int cpp_audio_out_prepare(audio_out_h output) {
928 auto handle = static_cast<audio_io_s*>(output);
932 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
933 "Parameter is NULL output:%p", output);
934 assert(handle->audioIoHandle);
935 AUDIO_IO_LOGD("[%p]", handle);
937 handle->audioIoHandle->prepare();
938 } catch (const CAudioError& e) {
939 AUDIO_IO_LOGE("%s", e.getErrorMsg());
940 return __convert_audio_io_error(e.getError());
943 AUDIO_IO_LOGD("[%p] prepared", handle);
945 return AUDIO_IO_ERROR_NONE;
948 int cpp_audio_out_unprepare(audio_out_h output) {
949 auto handle = static_cast<audio_io_s*>(output);
953 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
954 "Parameter is NULL output:%p", output);
955 assert(handle->audioIoHandle);
956 AUDIO_IO_LOGD("[%p]", handle);
958 handle->audioIoHandle->unprepare();
959 } catch (const CAudioError& e) {
960 AUDIO_IO_LOGE("%s", e.getErrorMsg());
961 return __convert_audio_io_error(e.getError());
964 AUDIO_IO_LOGD("[%p] unprepared", handle);
966 return AUDIO_IO_ERROR_NONE;
969 int cpp_audio_out_pause(audio_out_h output) {
970 auto handle = static_cast<audio_io_s*>(output);
974 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
975 "Parameter is NULL output:%p", output);
976 assert(handle->audioIoHandle);
977 AUDIO_IO_LOGD("[%p]", handle);
979 handle->audioIoHandle->pause();
980 } catch (const CAudioError& e) {
981 AUDIO_IO_LOGE("%s", e.getErrorMsg());
982 return __convert_audio_io_error(e.getError());
985 AUDIO_IO_LOGD("[%p] paused", handle);
987 return AUDIO_IO_ERROR_NONE;
990 int cpp_audio_out_resume(audio_out_h output) {
991 auto handle = static_cast<audio_io_s*>(output);
995 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
996 "Parameter is NULL output:%p", output);
997 assert(handle->audioIoHandle);
998 AUDIO_IO_LOGD("[%p]", handle);
1000 handle->audioIoHandle->resume();
1001 } catch (const CAudioError& e) {
1002 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1003 return __convert_audio_io_error(e.getError());
1006 AUDIO_IO_LOGD("[%p] resumed", handle);
1008 return AUDIO_IO_ERROR_NONE;
1011 int cpp_audio_out_drain(audio_out_h output) {
1012 auto handle = static_cast<audio_io_s*>(output);
1016 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1017 "Parameter is NULL output:%p", output);
1018 assert(handle->audioIoHandle);
1019 AUDIO_IO_LOGD("[%p]", handle);
1021 auto output_handle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
1022 if (output_handle == nullptr)
1023 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
1025 output_handle->drain();
1026 } catch (const CAudioError& e) {
1027 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1028 return __convert_audio_io_error(e.getError());
1031 AUDIO_IO_LOGD("[%p] drained", handle);
1033 return AUDIO_IO_ERROR_NONE;
1036 int cpp_audio_out_flush(audio_out_h output) {
1037 auto handle = static_cast<audio_io_s*>(output);
1041 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1042 "Parameter is NULL output:%p", output);
1043 assert(handle->audioIoHandle);
1044 AUDIO_IO_LOGD("[%p]", handle);
1046 handle->audioIoHandle->flush();
1047 } catch (const CAudioError& e) {
1048 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1049 return __convert_audio_io_error(e.getError());
1052 AUDIO_IO_LOGD("[%p] flushed", handle);
1054 return AUDIO_IO_ERROR_NONE;
1057 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1061 auto handle = static_cast<audio_io_s*>(output);
1062 if (!handle || !buffer)
1063 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1064 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1065 assert(handle->audioIoHandle);
1067 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1069 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1071 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1072 ret = static_cast<int>(written);
1073 #ifdef _AUDIO_IO_DEBUG_TIMING_
1074 AUDIO_IO_LOGD("written:%zu", written);
1076 } catch (const CAudioError& e) {
1077 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1078 return __convert_audio_io_error(e.getError());
1084 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1086 auto handle = static_cast<audio_io_s*>(output);
1087 if (!handle || !size)
1088 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1089 "Parameters are NULL output:%p, size:%p", output, size);
1090 assert(handle->audioIoHandle);
1092 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1094 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1096 *size = outputHandle->getBufferSize();
1097 } catch (const CAudioError& e) {
1098 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1099 return __convert_audio_io_error(e.getError());
1102 return AUDIO_IO_ERROR_NONE;
1105 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1107 auto handle = static_cast<audio_io_s*>(output);
1108 if (!handle || !sample_rate)
1109 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1110 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1111 assert(handle->audioIoHandle);
1113 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1114 } catch (const CAudioError& e) {
1115 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1116 return __convert_audio_io_error(e.getError());
1119 return AUDIO_IO_ERROR_NONE;
1122 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1124 auto handle = static_cast<audio_io_s*>(output);
1125 if (!handle || !channel)
1126 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1127 "Parameters are NULL output:%p, channel:%p", output, channel);
1128 assert(handle->audioIoHandle);
1130 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1131 } catch (const CAudioError& e) {
1132 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1133 return __convert_audio_io_error(e.getError());
1136 return AUDIO_IO_ERROR_NONE;
1139 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1141 auto handle = static_cast<audio_io_s*>(output);
1142 if (!handle || !type)
1143 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1144 "Parameters are NULL output:%p, type:%p", output, type);
1145 assert(handle->audioIoHandle);
1147 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1148 } catch (const CAudioError& e) {
1149 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1150 return __convert_audio_io_error(e.getError());
1153 return AUDIO_IO_ERROR_NONE;
1156 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1157 auto handle = static_cast<audio_io_s*>(output);
1160 if (!handle || !type)
1161 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1162 "Parameters are NULL output:%p, type:%p", output, type);
1163 assert(handle->audioIoHandle);
1165 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1166 } catch (const CAudioError& e) {
1167 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1168 return __convert_audio_io_error(e.getError());
1171 return AUDIO_IO_ERROR_NONE;
1174 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1175 auto handle = static_cast<audio_io_s*>(output);
1178 if (!handle || !callback)
1179 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1180 "Parameters are NULL output:%p, callback:%p", output, callback);
1181 assert(handle->audioIoHandle);
1182 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1184 handle->stream_callback.set(callback, user_data);
1186 auto cb = handle->audioIoHandle->getStreamCallback();
1187 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1189 handle->audioIoHandle->setStreamCallback(cb);
1190 } catch (const CAudioError& e) {
1191 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1192 return __convert_audio_io_error(e.getError());
1195 AUDIO_IO_LOGD("[%p] done", handle);
1197 return AUDIO_IO_ERROR_NONE;
1200 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1201 auto handle = static_cast<audio_io_s*>(output);
1205 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1206 "Parameters are NULL output:%p", output);
1207 assert(handle->audioIoHandle);
1208 AUDIO_IO_LOGD("[%p]", handle);
1210 handle->stream_callback.unset();
1212 auto cb = handle->audioIoHandle->getStreamCallback();
1215 handle->audioIoHandle->setStreamCallback(cb);
1216 } catch (const CAudioError& e) {
1217 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1218 return __convert_audio_io_error(e.getError());
1221 AUDIO_IO_LOGD("[%p] done", handle);
1223 return AUDIO_IO_ERROR_NONE;
1226 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1227 auto handle = static_cast<audio_io_s*>(output);
1230 if (!handle || !callback)
1231 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1232 "Parameters are NULL output:%p, callback:%p", output, callback);
1233 assert(handle->audioIoHandle);
1234 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1236 handle->state_changed_callback.set(callback, user_data);
1238 auto cb = handle->audioIoHandle->getStateChangedCallback();
1239 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1241 handle->audioIoHandle->setStateChangedCallback(cb);
1242 } catch (const CAudioError& e) {
1243 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1244 return __convert_audio_io_error(e.getError());
1247 AUDIO_IO_LOGD("[%p] done", handle);
1249 return AUDIO_IO_ERROR_NONE;
1252 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1253 auto handle = static_cast<audio_io_s*>(output);
1257 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1258 "Parameters are NULL output:%p", output);
1259 assert(handle->audioIoHandle);
1260 AUDIO_IO_LOGD("[%p]", handle);
1262 handle->state_changed_callback.unset();
1264 auto cb = handle->audioIoHandle->getStateChangedCallback();
1267 handle->audioIoHandle->setStateChangedCallback(cb);
1268 } catch (const CAudioError& e) {
1269 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1270 return __convert_audio_io_error(e.getError());
1273 AUDIO_IO_LOGD("[%p] done", handle);
1275 return AUDIO_IO_ERROR_NONE;