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 < static_cast<int>(CAudioInfo::MIN_SYSTEM_SAMPLERATE) ||
281 sample_rate > static_cast<int>(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 output:%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;
794 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
795 audio_io_s* handle = nullptr;
798 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
799 "Parameters are NULL output:%p", output);
801 __check_audio_param(sample_rate, channel, type, true);
803 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
804 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
806 handle = new audio_io_s;
807 handle->audioIoHandle = new CAudioOutput(audioInfo);
808 handle->audioIoHandle->initialize();
810 AUDIO_IO_LOGD("[%p] created", handle);
812 } catch (const CAudioError& e) {
813 AUDIO_IO_LOGE("%s", e.getErrorMsg());
814 __handle_safe_free(handle, (void *)output, true);
815 return __convert_audio_io_error(e.getError());
816 } catch (const std::bad_alloc&) {
818 AUDIO_IO_LOGE("Failed to allocate handle");
819 __handle_safe_free(handle, (void *)output, true);
820 return __convert_audio_io_error(CAudioError::EError::ERROR_OUT_OF_MEMORY);
824 return AUDIO_IO_ERROR_NONE;
827 int cpp_audio_out_destroy(audio_out_h output) {
828 auto handle = static_cast<audio_io_s*>(output);
832 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
833 "Parameter is NULL output:%p", output);
834 assert(handle->audioIoHandle);
835 AUDIO_IO_LOGD("[%p]", handle);
837 /* Internal unprepare for backward compatibility */
838 handle->audioIoHandle->unprepare();
840 SAFE_FINALIZE(handle->audioIoHandle);
841 SAFE_DELETE(handle->audioIoHandle);
843 } catch (const CAudioError& e) {
844 AUDIO_IO_LOGE("%s", e.getErrorMsg());
845 return __convert_audio_io_error(e.getError());
848 AUDIO_IO_LOGD("[%p] destroyed", handle);
850 return AUDIO_IO_ERROR_NONE;
853 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
854 auto handle = static_cast<audio_io_s*>(output);
857 if (!handle || !stream_info)
858 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
859 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
860 assert(handle->audioIoHandle);
861 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
863 handle->audioIoHandle->setStreamInfo(stream_info);
864 } catch (const CAudioError& e) {
865 AUDIO_IO_LOGE("%s", e.getErrorMsg());
866 return __convert_audio_io_error(e.getError());
869 AUDIO_IO_LOGD("[%p] done", handle);
871 return AUDIO_IO_ERROR_NONE;
874 int cpp_audio_out_prepare(audio_out_h output) {
875 auto handle = static_cast<audio_io_s*>(output);
879 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
880 "Parameter is NULL output:%p", output);
881 assert(handle->audioIoHandle);
882 AUDIO_IO_LOGD("[%p]", handle);
884 handle->audioIoHandle->prepare();
885 } catch (const CAudioError& e) {
886 AUDIO_IO_LOGE("%s", e.getErrorMsg());
887 return __convert_audio_io_error(e.getError());
890 AUDIO_IO_LOGD("[%p] prepared", handle);
892 return AUDIO_IO_ERROR_NONE;
895 int cpp_audio_out_unprepare(audio_out_h output) {
896 auto handle = static_cast<audio_io_s*>(output);
900 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
901 "Parameter is NULL output:%p", output);
902 assert(handle->audioIoHandle);
903 AUDIO_IO_LOGD("[%p]", handle);
905 handle->audioIoHandle->unprepare();
906 } catch (const CAudioError& e) {
907 AUDIO_IO_LOGE("%s", e.getErrorMsg());
908 return __convert_audio_io_error(e.getError());
911 AUDIO_IO_LOGD("[%p] unprepared", handle);
913 return AUDIO_IO_ERROR_NONE;
916 int cpp_audio_out_pause(audio_out_h output) {
917 auto handle = static_cast<audio_io_s*>(output);
921 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
922 "Parameter is NULL output:%p", output);
923 assert(handle->audioIoHandle);
924 AUDIO_IO_LOGD("[%p]", handle);
926 handle->audioIoHandle->pause();
927 } catch (const CAudioError& e) {
928 AUDIO_IO_LOGE("%s", e.getErrorMsg());
929 return __convert_audio_io_error(e.getError());
932 AUDIO_IO_LOGD("[%p] paused", handle);
934 return AUDIO_IO_ERROR_NONE;
937 int cpp_audio_out_resume(audio_out_h output) {
938 auto handle = static_cast<audio_io_s*>(output);
942 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
943 "Parameter is NULL output:%p", output);
944 assert(handle->audioIoHandle);
945 AUDIO_IO_LOGD("[%p]", handle);
947 handle->audioIoHandle->resume();
948 } catch (const CAudioError& e) {
949 AUDIO_IO_LOGE("%s", e.getErrorMsg());
950 return __convert_audio_io_error(e.getError());
953 AUDIO_IO_LOGD("[%p] resumed", handle);
955 return AUDIO_IO_ERROR_NONE;
958 int cpp_audio_out_drain(audio_out_h output) {
959 auto handle = static_cast<audio_io_s*>(output);
963 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
964 "Parameter is NULL output:%p", output);
965 assert(handle->audioIoHandle);
966 AUDIO_IO_LOGD("[%p]", handle);
968 auto output_handle = dynamic_cast<CAudioOutput*>(handle->audioIoHandle);
969 if (output_handle == nullptr)
970 return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
972 output_handle->drain();
973 } catch (const CAudioError& e) {
974 AUDIO_IO_LOGE("%s", e.getErrorMsg());
975 return __convert_audio_io_error(e.getError());
978 AUDIO_IO_LOGD("[%p] drained", handle);
980 return AUDIO_IO_ERROR_NONE;
983 int cpp_audio_out_flush(audio_out_h output) {
984 auto handle = static_cast<audio_io_s*>(output);
988 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
989 "Parameter is NULL output:%p", output);
990 assert(handle->audioIoHandle);
991 AUDIO_IO_LOGD("[%p]", handle);
993 handle->audioIoHandle->flush();
994 } catch (const CAudioError& e) {
995 AUDIO_IO_LOGE("%s", e.getErrorMsg());
996 return __convert_audio_io_error(e.getError());
999 AUDIO_IO_LOGD("[%p] flushed", handle);
1001 return AUDIO_IO_ERROR_NONE;
1004 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1008 auto handle = static_cast<audio_io_s*>(output);
1009 if (!handle || !buffer)
1010 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1011 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1012 assert(handle->audioIoHandle);
1014 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1016 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1018 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1019 ret = static_cast<int>(written);
1020 #ifdef _AUDIO_IO_DEBUG_TIMING_
1021 AUDIO_IO_LOGD("written:%zu", written);
1023 } catch (const CAudioError& e) {
1024 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1025 return __convert_audio_io_error(e.getError());
1031 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1033 auto handle = static_cast<audio_io_s*>(output);
1034 if (!handle || !size)
1035 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1036 "Parameters are NULL output:%p, size:%p", output, size);
1037 assert(handle->audioIoHandle);
1039 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1041 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1043 *size = outputHandle->getBufferSize();
1044 } catch (const CAudioError& e) {
1045 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1046 return __convert_audio_io_error(e.getError());
1049 return AUDIO_IO_ERROR_NONE;
1052 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1054 auto handle = static_cast<audio_io_s*>(output);
1055 if (!handle || !sample_rate)
1056 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1057 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1058 assert(handle->audioIoHandle);
1060 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1061 } catch (const CAudioError& e) {
1062 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1063 return __convert_audio_io_error(e.getError());
1066 return AUDIO_IO_ERROR_NONE;
1069 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1071 auto handle = static_cast<audio_io_s*>(output);
1072 if (!handle || !channel)
1073 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1074 "Parameters are NULL output:%p, channel:%p", output, channel);
1075 assert(handle->audioIoHandle);
1077 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1078 } catch (const CAudioError& e) {
1079 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1080 return __convert_audio_io_error(e.getError());
1083 return AUDIO_IO_ERROR_NONE;
1086 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1088 auto handle = static_cast<audio_io_s*>(output);
1089 if (!handle || !type)
1090 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1091 "Parameters are NULL output:%p, type:%p", output, type);
1092 assert(handle->audioIoHandle);
1094 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1095 } catch (const CAudioError& e) {
1096 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1097 return __convert_audio_io_error(e.getError());
1100 return AUDIO_IO_ERROR_NONE;
1103 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1104 auto handle = static_cast<audio_io_s*>(output);
1107 if (!handle || !type)
1108 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1109 "Parameters are NULL output:%p, type:%p", output, type);
1110 assert(handle->audioIoHandle);
1112 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1113 } catch (const CAudioError& e) {
1114 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1115 return __convert_audio_io_error(e.getError());
1118 return AUDIO_IO_ERROR_NONE;
1121 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1122 auto handle = static_cast<audio_io_s*>(output);
1125 if (!handle || !callback)
1126 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1127 "Parameters are NULL output:%p, callback:%p", output, callback);
1128 assert(handle->audioIoHandle);
1129 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1131 handle->stream_callback.set(callback, user_data);
1133 auto cb = handle->audioIoHandle->getStreamCallback();
1134 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1136 handle->audioIoHandle->setStreamCallback(cb);
1137 } catch (const CAudioError& e) {
1138 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1139 return __convert_audio_io_error(e.getError());
1142 AUDIO_IO_LOGD("[%p] done", handle);
1144 return AUDIO_IO_ERROR_NONE;
1147 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1148 auto handle = static_cast<audio_io_s*>(output);
1152 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1153 "Parameters are NULL output:%p", output);
1154 assert(handle->audioIoHandle);
1155 AUDIO_IO_LOGD("[%p]", handle);
1157 handle->stream_callback.unset();
1159 auto cb = handle->audioIoHandle->getStreamCallback();
1162 handle->audioIoHandle->setStreamCallback(cb);
1163 } catch (const CAudioError& e) {
1164 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1165 return __convert_audio_io_error(e.getError());
1168 AUDIO_IO_LOGD("[%p] done", handle);
1170 return AUDIO_IO_ERROR_NONE;
1173 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1174 auto handle = static_cast<audio_io_s*>(output);
1177 if (!handle || !callback)
1178 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1179 "Parameters are NULL output:%p, callback:%p", output, callback);
1180 assert(handle->audioIoHandle);
1181 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1183 handle->state_changed_callback.set(callback, user_data);
1185 auto cb = handle->audioIoHandle->getStateChangedCallback();
1186 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1188 handle->audioIoHandle->setStateChangedCallback(cb);
1189 } catch (const CAudioError& e) {
1190 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1191 return __convert_audio_io_error(e.getError());
1194 AUDIO_IO_LOGD("[%p] done", handle);
1196 return AUDIO_IO_ERROR_NONE;
1199 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1200 auto handle = static_cast<audio_io_s*>(output);
1204 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1205 "Parameters are NULL output:%p", output);
1206 assert(handle->audioIoHandle);
1207 AUDIO_IO_LOGD("[%p]", handle);
1209 handle->state_changed_callback.unset();
1211 auto cb = handle->audioIoHandle->getStateChangedCallback();
1214 handle->audioIoHandle->setStateChangedCallback(cb);
1215 } catch (const CAudioError& e) {
1216 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1217 return __convert_audio_io_error(e.getError());
1220 AUDIO_IO_LOGD("[%p] done", handle);
1222 return AUDIO_IO_ERROR_NONE;