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>
26 #define FEATURE_MICROPHONE "http://tizen.org/feature/microphone"
29 using namespace tizen_media_audio;
34 * Name : audio_io_stream_cb_s
35 * Declaration : Keeps user callback pointer and user data for delivering an stream event
37 typedef struct audio_io_stream_cb_s {
39 audio_in_stream_cb onStream;
41 audio_io_stream_cb_s() : user_data(nullptr), onStream(nullptr) { }
43 void set(audio_in_stream_cb callback, void* userdata) {
52 } audio_io_stream_cb_s;
57 * Name : audio_io_state_changed_cb_s
58 * Declaration : Keeps user callback pointer and user data for delivering an state changed event
60 typedef struct audio_io_state_changed_cb_s {
62 audio_in_state_changed_cb onStateChanged;
64 audio_io_state_changed_cb_s() : user_data(nullptr), onStateChanged(nullptr) { }
66 void set(audio_in_state_changed_cb callback, void* userdata) {
67 onStateChanged = callback;
72 onStateChanged = nullptr;
76 } audio_io_state_changed_cb_s;
82 * Declaration : An handle of AudioIO
83 * The handle has two struct for user callback
84 * And the handle has a pointer of private audioIO object
85 * The CAudioIO is a abstract class object about Input and Output
87 typedef struct audio_io_s {
88 CAudioIO* audioIoHandle;
89 audio_io_stream_cb_s stream_callback;
90 audio_io_state_changed_cb_s state_changed_callback;
92 audio_io_s() : audioIoHandle(nullptr) { }
99 static audio_io_error_e __convert_CAudioError(CAudioError& error) {
100 switch (error.getError()) {
101 case CAudioError::EError::ERROR_NONE:
102 return AUDIO_IO_ERROR_NONE;
103 case CAudioError::EError::ERROR_INVALID_ARGUMENT:
104 case CAudioError::EError::ERROR_INVALID_HANDLE:
105 return AUDIO_IO_ERROR_INVALID_PARAMETER;
106 case CAudioError::EError::ERROR_DEVICE_NOT_OPENED:
107 return AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
108 case CAudioError::EError::ERROR_DEVICE_NOT_CLOSED:
109 return AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
110 case CAudioError::EError::ERROR_PERMISSION_DENIED:
111 return AUDIO_IO_ERROR_PERMISSION_DENIED;
112 case CAudioError::EError::ERROR_DEVICE_POLICY_RESTRICTION:
113 return AUDIO_IO_ERROR_DEVICE_POLICY_RESTRICTION;
114 case CAudioError::EError::ERROR_NOT_SUPPORTED:
115 return AUDIO_IO_ERROR_NOT_SUPPORTED;
116 case CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE:
117 return AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
118 case CAudioError::EError::ERROR_MAX:
119 case CAudioError::EError::ERROR_INTERNAL_OPERATION:
120 case CAudioError::EError::ERROR_NOT_INITIALIZED:
121 case CAudioError::EError::ERROR_FAILED_OPERATION:
122 case CAudioError::EError::ERROR_INVALID_OPERATION:
123 return AUDIO_IO_ERROR_INVALID_OPERATION;
124 case CAudioError::EError::ERROR_INVALID_STATE:
125 return AUDIO_IO_ERROR_INVALID_STATE;
126 case CAudioError::EError::ERROR_OUT_OF_MEMORY:
127 case CAudioError::EError::ERROR_INVALID_POINTER:
128 return AUDIO_IO_ERROR_INVALID_BUFFER;
129 case CAudioError::EError::ERROR_POLICY_BLOCKED:
130 case CAudioError::EError::ERROR_POLICY_INTERRUPTED:
131 case CAudioError::EError::ERROR_POLICY_DUPLICATED:
132 return AUDIO_IO_ERROR_SOUND_POLICY;
134 return AUDIO_IO_ERROR_NONE;
138 static CAudioInfo::EChannel __convert_channel_to_audio_info_channel(const audio_channel_e &src_channel) {
139 switch (src_channel) {
140 case AUDIO_CHANNEL_MONO:
141 return CAudioInfo::EChannel::CHANNEL_MONO;
142 case AUDIO_CHANNEL_STEREO:
143 return CAudioInfo::EChannel::CHANNEL_STEREO;
144 case AUDIO_CHANNEL_MULTI_3:
145 return CAudioInfo::EChannel::CHANNEL_MULTI_3;
146 case AUDIO_CHANNEL_MULTI_4:
147 return CAudioInfo::EChannel::CHANNEL_MULTI_4;
148 case AUDIO_CHANNEL_MULTI_5:
149 return CAudioInfo::EChannel::CHANNEL_MULTI_5;
150 case AUDIO_CHANNEL_MULTI_6:
151 return CAudioInfo::EChannel::CHANNEL_MULTI_6;
152 case AUDIO_CHANNEL_MULTI_7:
153 return CAudioInfo::EChannel::CHANNEL_MULTI_7;
154 case AUDIO_CHANNEL_MULTI_8:
155 return CAudioInfo::EChannel::CHANNEL_MULTI_8;
157 return CAudioInfo::EChannel::CHANNEL_MONO;
161 static audio_channel_e __convert_audio_info_channel_to_channel(const CAudioInfo::EChannel& src_channel) {
162 switch (src_channel) {
163 case CAudioInfo::EChannel::CHANNEL_MONO:
164 return AUDIO_CHANNEL_MONO;
165 case CAudioInfo::EChannel::CHANNEL_STEREO:
166 return AUDIO_CHANNEL_STEREO;
167 case CAudioInfo::EChannel::CHANNEL_MULTI_3:
168 return AUDIO_CHANNEL_MULTI_3;
169 case CAudioInfo::EChannel::CHANNEL_MULTI_4:
170 return AUDIO_CHANNEL_MULTI_4;
171 case CAudioInfo::EChannel::CHANNEL_MULTI_5:
172 return AUDIO_CHANNEL_MULTI_5;
173 case CAudioInfo::EChannel::CHANNEL_MULTI_6:
174 return AUDIO_CHANNEL_MULTI_6;
175 case CAudioInfo::EChannel::CHANNEL_MULTI_7:
176 return AUDIO_CHANNEL_MULTI_7;
177 case CAudioInfo::EChannel::CHANNEL_MULTI_8:
178 return AUDIO_CHANNEL_MULTI_8;
180 return AUDIO_CHANNEL_MONO;
184 static CAudioInfo::ESampleType __convert_sample_type_to_audio_info_sample_type(const audio_sample_type_e& src_type) {
186 case AUDIO_SAMPLE_TYPE_U8:
187 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
188 case AUDIO_SAMPLE_TYPE_S16_LE:
189 return CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
190 case AUDIO_SAMPLE_TYPE_S24_LE:
191 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE;
192 case AUDIO_SAMPLE_TYPE_S24_32_LE:
193 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE;
194 case AUDIO_SAMPLE_TYPE_S32_LE:
195 return CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE;
197 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
201 static audio_sample_type_e __convert_audio_info_sample_type_to_sample_type(const CAudioInfo::ESampleType &src_type) {
203 case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
204 return AUDIO_SAMPLE_TYPE_U8;
205 case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
206 return AUDIO_SAMPLE_TYPE_S16_LE;
207 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE:
208 return AUDIO_SAMPLE_TYPE_S24_LE;
209 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE:
210 return AUDIO_SAMPLE_TYPE_S24_32_LE;
211 case CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE:
212 return AUDIO_SAMPLE_TYPE_S32_LE;
214 return AUDIO_SAMPLE_TYPE_U8;
218 static CAudioInfo::EAudioType __convert_sound_type_to_audio_info_audio_type(const sound_type_e &src_type) {
220 case SOUND_TYPE_SYSTEM:
221 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
222 case SOUND_TYPE_NOTIFICATION:
223 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
224 case SOUND_TYPE_ALARM:
225 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
226 case SOUND_TYPE_RINGTONE:
227 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
228 case SOUND_TYPE_MEDIA:
229 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
230 case SOUND_TYPE_CALL:
231 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
232 case SOUND_TYPE_VOIP:
233 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
234 case SOUND_TYPE_VOICE:
235 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
237 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
241 static sound_type_e __convert_audio_info_audio_type_to_sound_type(const CAudioInfo::EAudioType &src_type) {
243 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
244 return SOUND_TYPE_MEDIA;
245 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
246 return SOUND_TYPE_SYSTEM;
247 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
248 return SOUND_TYPE_ALARM;
249 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
250 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
251 return SOUND_TYPE_NOTIFICATION;
252 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
253 return SOUND_TYPE_VOICE;
254 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
255 return SOUND_TYPE_RINGTONE;
256 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
257 return SOUND_TYPE_VOIP;
259 return SOUND_TYPE_MEDIA;
263 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
265 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
266 return AUDIO_IO_STATE_IDLE;
267 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
268 return AUDIO_IO_STATE_IDLE;
269 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
270 return AUDIO_IO_STATE_RUNNING;
271 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
272 return AUDIO_IO_STATE_PAUSED;
274 return AUDIO_IO_STATE_IDLE;
278 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, bool is_output) {
279 if (sample_rate < static_cast<int>(CAudioInfo::MIN_SYSTEM_SAMPLERATE) ||
280 sample_rate > static_cast<int>(CAudioInfo::MAX_SYSTEM_SAMPLERATE))
281 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
283 if (channel < AUDIO_CHANNEL_MONO ||
284 channel > ((is_output) ? AUDIO_CHANNEL_STEREO : AUDIO_CHANNEL_MULTI_8))
285 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
287 if (type < AUDIO_SAMPLE_TYPE_U8 ||
288 type > AUDIO_SAMPLE_TYPE_S32_LE)
289 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
292 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
293 return CAudioInfo(sampleRate,
294 __convert_channel_to_audio_info_channel(channel),
295 __convert_sample_type_to_audio_info_sample_type(sample_type),
296 CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA,
300 static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
301 return CAudioInfo(sampleRate,
302 __convert_channel_to_audio_info_channel(channel),
303 __convert_sample_type_to_audio_info_sample_type(sample_type),
304 __convert_sound_type_to_audio_info_audio_type(sound_type),
308 static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
309 VALID_POINTER_START(handle)
310 SAFE_FINALIZE(handle->audioIoHandle);
311 SAFE_DELETE(handle->audioIoHandle);
315 VALID_POINTER_START(obj)
317 *(audio_out_h *)obj = nullptr;
319 *(audio_in_h *)obj = nullptr;
324 * Implements CAPI functions
326 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
327 audio_io_s* handle = nullptr;
328 bool mic_enable = false;
332 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
333 "Parameters are NULL input:%p", input);
335 __check_audio_param(sample_rate, channel, type, false);
337 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
339 /* If MIC is not supported, return NOT_SUPPORTED error */
340 int ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
341 AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
342 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
343 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
345 CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
347 handle = new audio_io_s;
348 handle->audioIoHandle = new CAudioInput(audioInfo);
349 handle->audioIoHandle->initialize();
351 AUDIO_IO_LOGD("[%p] created", handle);
353 } catch (CAudioError& e) {
354 AUDIO_IO_LOGE("%s", e.getErrorMsg());
355 __handle_safe_free(handle, (void *)input, false);
356 return __convert_CAudioError(e);
357 } catch (const std::bad_alloc&) {
358 CAudioError e(CAudioError::EError::ERROR_OUT_OF_MEMORY);
359 AUDIO_IO_LOGE("Failed to allocate handle");
360 __handle_safe_free(handle, (void *)input, false);
361 return __convert_CAudioError(e);
365 return AUDIO_IO_ERROR_NONE;
368 int cpp_audio_in_destroy(audio_in_h input) {
369 auto handle = static_cast<audio_io_s*>(input);
373 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
374 "Parameters are NULL input:%p", input);
375 assert(handle->audioIoHandle);
376 AUDIO_IO_LOGD("[%p]", handle);
378 /* Internal unprepare for backward compatibility */
379 handle->audioIoHandle->unprepare();
381 SAFE_FINALIZE(handle->audioIoHandle);
382 SAFE_DELETE(handle->audioIoHandle);
384 } catch (CAudioError& e) {
385 AUDIO_IO_LOGE("%s", e.getErrorMsg());
386 return __convert_CAudioError(e);
389 AUDIO_IO_LOGD("destroyed");
391 return AUDIO_IO_ERROR_NONE;
394 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
395 auto handle = static_cast<audio_io_s*>(input);
398 if (!handle || !stream_info)
399 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
400 "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
401 assert(handle->audioIoHandle);
402 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
404 handle->audioIoHandle->setStreamInfo(stream_info);
405 } catch (CAudioError& e) {
406 AUDIO_IO_LOGE("%s", e.getErrorMsg());
407 return __convert_CAudioError(e);
410 AUDIO_IO_LOGD("[%p] done", handle);
412 return AUDIO_IO_ERROR_NONE;
415 int cpp_audio_in_prepare(audio_in_h input) {
416 auto handle = static_cast<audio_io_s*>(input);
420 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
421 "Parameters are NULL input:%p", input);
422 assert(handle->audioIoHandle);
423 AUDIO_IO_LOGD("[%p]", handle);
425 handle->audioIoHandle->prepare();
426 } catch (CAudioError& e) {
427 AUDIO_IO_LOGE("%s", e.getErrorMsg());
428 return __convert_CAudioError(e);
431 AUDIO_IO_LOGD("[%p] prepared", handle);
433 return AUDIO_IO_ERROR_NONE;
436 int cpp_audio_in_unprepare(audio_in_h input) {
437 auto handle = static_cast<audio_io_s*>(input);
441 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
442 "Parameters are NULL input:%p", input);
443 assert(handle->audioIoHandle);
444 AUDIO_IO_LOGD("[%p]", handle);
446 handle->audioIoHandle->unprepare();
447 } catch (CAudioError& e) {
448 AUDIO_IO_LOGE("%s", e.getErrorMsg());
449 return __convert_CAudioError(e);
452 AUDIO_IO_LOGD("[%p] unprepared", handle);
454 return AUDIO_IO_ERROR_NONE;
457 int cpp_audio_in_pause(audio_in_h input) {
458 auto handle = static_cast<audio_io_s*>(input);
462 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
463 "Parameters are NULL input:%p", input);
464 assert(handle->audioIoHandle);
465 AUDIO_IO_LOGD("[%p]", handle);
467 handle->audioIoHandle->pause();
468 } catch (CAudioError& e) {
469 AUDIO_IO_LOGE("%s", e.getErrorMsg());
470 return __convert_CAudioError(e);
473 AUDIO_IO_LOGD("[%p] paused", handle);
475 return AUDIO_IO_ERROR_NONE;
478 int cpp_audio_in_resume(audio_in_h input) {
479 auto handle = static_cast<audio_io_s*>(input);
483 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
484 "Parameters are NULL input:%p", input);
485 assert(handle->audioIoHandle);
486 AUDIO_IO_LOGD("[%p]", handle);
488 handle->audioIoHandle->resume();
489 } catch (CAudioError& e) {
490 AUDIO_IO_LOGE("%s", e.getErrorMsg());
491 return __convert_CAudioError(e);
494 AUDIO_IO_LOGD("[%p] resumed", handle);
496 return AUDIO_IO_ERROR_NONE;
499 int cpp_audio_in_flush(audio_in_h input) {
500 auto handle = static_cast<audio_io_s*>(input);
504 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
505 "Parameters are NULL input:%p", input);
506 assert(handle->audioIoHandle);
507 AUDIO_IO_LOGD("[%p]", handle);
509 handle->audioIoHandle->flush();
510 } catch (CAudioError& e) {
511 AUDIO_IO_LOGE("%s", e.getErrorMsg());
512 return __convert_CAudioError(e);
515 AUDIO_IO_LOGD("[%p] flushed", handle);
517 return AUDIO_IO_ERROR_NONE;
520 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
524 auto handle = static_cast<audio_io_s*>(input);
525 if (!handle || !buffer)
526 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
527 "Parameters are NULL input:%p, buffer:%p", input, buffer);
528 assert(handle->audioIoHandle);
530 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
532 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
534 auto readn = inputHandle->read(buffer, static_cast<size_t>(length));
535 ret = static_cast<int>(readn);
536 #ifdef _AUDIO_IO_DEBUG_TIMING_
537 AUDIO_IO_LOGD("readn:%zu", readn);
539 } catch (CAudioError& e) {
540 AUDIO_IO_LOGE("%s", e.getErrorMsg());
541 return __convert_CAudioError(e);
547 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
549 auto handle = static_cast<audio_io_s*>(input);
550 if (!handle || !size)
551 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
552 "Parameters are NULL input:%p, size:%p", input, size);
553 assert(handle->audioIoHandle);
555 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
557 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
559 *size = inputHandle->getBufferSize();
560 } catch (CAudioError& e) {
561 AUDIO_IO_LOGE("%s", e.getErrorMsg());
562 return __convert_CAudioError(e);
565 return AUDIO_IO_ERROR_NONE;
568 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
570 auto handle = static_cast<audio_io_s*>(input);
571 if (!handle || !sample_rate)
572 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
573 "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
574 assert(handle->audioIoHandle);
576 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
577 } catch (CAudioError& e) {
578 AUDIO_IO_LOGE("%s", e.getErrorMsg());
579 return __convert_CAudioError(e);
582 return AUDIO_IO_ERROR_NONE;
585 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
587 auto handle = static_cast<audio_io_s*>(input);
588 if (!handle || !channel)
589 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
590 "Parameters are NULL input:%p, channel:%p", input, channel);
591 assert(handle->audioIoHandle);
593 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
594 } catch (CAudioError& e) {
595 AUDIO_IO_LOGE("%s", e.getErrorMsg());
596 return __convert_CAudioError(e);
599 return AUDIO_IO_ERROR_NONE;
602 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
604 auto handle = static_cast<audio_io_s*>(input);
605 if (!handle || !type)
606 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
607 "Parameters are NULL input:%p, type:%p", input, type);
608 assert(handle->audioIoHandle);
610 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
611 } catch (CAudioError& e) {
612 AUDIO_IO_LOGE("%s", e.getErrorMsg());
613 return __convert_CAudioError(e);
616 return AUDIO_IO_ERROR_NONE;
619 static void __stream_cb_internal(size_t nbytes, void *user_data) {
620 auto audioIo = static_cast<audio_io_s*>(user_data);
623 if (audioIo->stream_callback.onStream)
624 audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
628 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
629 CAudioInfo::EAudioIOState state_prev,
632 auto audioIo = static_cast<audio_io_s*>(user_data);
635 if (audioIo->state_changed_callback.onStateChanged)
636 audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
637 __convert_state_type(state), by_policy,
638 audioIo->state_changed_callback.user_data);
642 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
643 auto handle = static_cast<audio_io_s*>(input);
646 if (!handle || !callback)
647 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
648 "Parameters are NULL input:%p, callback:%p", input, callback);
649 assert(handle->audioIoHandle);
650 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
652 handle->stream_callback.set(callback, user_data);
654 auto cb = handle->audioIoHandle->getStreamCallback();
655 cb.set(__stream_cb_internal, static_cast<void*>(handle));
657 handle->audioIoHandle->setStreamCallback(cb);
658 } catch (CAudioError& e) {
659 AUDIO_IO_LOGE("%s", e.getErrorMsg());
660 return __convert_CAudioError(e);
663 AUDIO_IO_LOGD("[%p] done", handle);
665 return AUDIO_IO_ERROR_NONE;
668 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
669 auto handle = static_cast<audio_io_s*>(input);
672 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
673 "Parameters are NULL input:%p", input);
674 assert(handle->audioIoHandle);
675 AUDIO_IO_LOGD("[%p]", handle);
677 handle->stream_callback.unset();
679 auto cb = handle->audioIoHandle->getStreamCallback();
682 handle->audioIoHandle->setStreamCallback(cb);
683 } catch (CAudioError& e) {
684 AUDIO_IO_LOGE("%s", e.getErrorMsg());
685 return __convert_CAudioError(e);
688 AUDIO_IO_LOGD("[%p] done", handle);
690 return AUDIO_IO_ERROR_NONE;
693 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
697 auto handle = static_cast<audio_io_s*>(input);
698 if (!handle || !buffer)
699 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
700 "Parameters are NULL input:%p, buffer:%p", input, buffer);
702 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
704 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
706 inputHandle->peek(buffer, &_length);
707 } catch (CAudioError& e) {
708 AUDIO_IO_LOGE("%s", e.getErrorMsg());
709 return __convert_CAudioError(e);
712 *length = (unsigned int)_length;
714 return AUDIO_IO_ERROR_NONE;
717 int cpp_audio_in_drop(audio_in_h input) {
719 auto handle = static_cast<audio_io_s*>(input);
721 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
722 "Parameters are NULL input:%p", input);
724 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
726 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
729 } catch (CAudioError& e) {
730 AUDIO_IO_LOGE("%s", e.getErrorMsg());
731 return __convert_CAudioError(e);
734 return AUDIO_IO_ERROR_NONE;
737 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
738 auto handle = static_cast<audio_io_s*>(input);
741 if (!handle || !callback)
742 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
743 "Parameters are NULL input:%p, callback:%p", input, callback);
744 assert(handle->audioIoHandle);
745 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
747 handle->state_changed_callback.set(callback, user_data);
749 auto cb = handle->audioIoHandle->getStateChangedCallback();
750 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
752 handle->audioIoHandle->setStateChangedCallback(cb);
753 } catch (CAudioError& e) {
754 AUDIO_IO_LOGE("%s", e.getErrorMsg());
755 return __convert_CAudioError(e);
758 AUDIO_IO_LOGD("[%p] done", handle);
760 return AUDIO_IO_ERROR_NONE;
763 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
764 auto handle = static_cast<audio_io_s*>(input);
768 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
769 "Parameters are NULL output:%p", input);
770 assert(handle->audioIoHandle);
771 AUDIO_IO_LOGD("[%p]", handle);
773 handle->state_changed_callback.unset();
775 auto cb = handle->audioIoHandle->getStateChangedCallback();
778 handle->audioIoHandle->setStateChangedCallback(cb);
779 } catch (CAudioError& e) {
780 AUDIO_IO_LOGE("%s", e.getErrorMsg());
781 return __convert_CAudioError(e);
784 AUDIO_IO_LOGD("[%p] done", handle);
786 return AUDIO_IO_ERROR_NONE;
793 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
794 audio_io_s* handle = nullptr;
797 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
798 "Parameters are NULL output:%p", output);
800 __check_audio_param(sample_rate, channel, type, true);
802 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
803 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
805 handle = new audio_io_s;
806 handle->audioIoHandle = new CAudioOutput(audioInfo);
807 handle->audioIoHandle->initialize();
809 AUDIO_IO_LOGD("[%p] created", handle);
811 } catch (CAudioError& e) {
812 AUDIO_IO_LOGE("%s", e.getErrorMsg());
813 __handle_safe_free(handle, (void *)output, true);
814 return __convert_CAudioError(e);
815 } catch (const std::bad_alloc&) {
816 CAudioError e(CAudioError::EError::ERROR_OUT_OF_MEMORY);
817 AUDIO_IO_LOGE("Failed to allocate handle");
818 __handle_safe_free(handle, (void *)output, true);
819 return __convert_CAudioError(e);
823 return AUDIO_IO_ERROR_NONE;
826 int cpp_audio_out_destroy(audio_out_h output) {
827 auto handle = static_cast<audio_io_s*>(output);
831 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
832 "Parameter is NULL output:%p", output);
833 assert(handle->audioIoHandle);
834 AUDIO_IO_LOGD("[%p]", handle);
836 /* Internal unprepare for backward compatibility */
837 handle->audioIoHandle->unprepare();
839 SAFE_FINALIZE(handle->audioIoHandle);
840 SAFE_DELETE(handle->audioIoHandle);
842 } catch (CAudioError& e) {
843 AUDIO_IO_LOGE("%s", e.getErrorMsg());
844 return __convert_CAudioError(e);
847 AUDIO_IO_LOGD("[%p] destroyed", handle);
849 return AUDIO_IO_ERROR_NONE;
852 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
853 auto handle = static_cast<audio_io_s*>(output);
856 if (!handle || !stream_info)
857 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
858 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
859 assert(handle->audioIoHandle);
860 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
862 handle->audioIoHandle->setStreamInfo(stream_info);
863 } catch (CAudioError& e) {
864 AUDIO_IO_LOGE("%s", e.getErrorMsg());
865 return __convert_CAudioError(e);
868 AUDIO_IO_LOGD("[%p] done", handle);
870 return AUDIO_IO_ERROR_NONE;
873 int cpp_audio_out_prepare(audio_out_h output) {
874 auto handle = static_cast<audio_io_s*>(output);
878 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
879 "Parameter is NULL output:%p", output);
880 assert(handle->audioIoHandle);
881 AUDIO_IO_LOGD("[%p]", handle);
883 handle->audioIoHandle->prepare();
884 } catch (CAudioError& e) {
885 AUDIO_IO_LOGE("%s", e.getErrorMsg());
886 return __convert_CAudioError(e);
889 AUDIO_IO_LOGD("[%p] prepared", handle);
891 return AUDIO_IO_ERROR_NONE;
894 int cpp_audio_out_unprepare(audio_out_h output) {
895 auto handle = static_cast<audio_io_s*>(output);
899 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
900 "Parameter is NULL output:%p", output);
901 assert(handle->audioIoHandle);
902 AUDIO_IO_LOGD("[%p]", handle);
904 handle->audioIoHandle->unprepare();
905 } catch (CAudioError& e) {
906 AUDIO_IO_LOGE("%s", e.getErrorMsg());
907 return __convert_CAudioError(e);
910 AUDIO_IO_LOGD("[%p] unprepared", handle);
912 return AUDIO_IO_ERROR_NONE;
915 int cpp_audio_out_pause(audio_out_h output) {
916 auto handle = static_cast<audio_io_s*>(output);
920 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
921 "Parameter is NULL output:%p", output);
922 assert(handle->audioIoHandle);
923 AUDIO_IO_LOGD("[%p]", handle);
925 handle->audioIoHandle->pause();
926 } catch (CAudioError& e) {
927 AUDIO_IO_LOGE("%s", e.getErrorMsg());
928 return __convert_CAudioError(e);
931 AUDIO_IO_LOGD("[%p] paused", handle);
933 return AUDIO_IO_ERROR_NONE;
936 int cpp_audio_out_resume(audio_out_h output) {
937 auto handle = static_cast<audio_io_s*>(output);
941 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
942 "Parameter is NULL output:%p", output);
943 assert(handle->audioIoHandle);
944 AUDIO_IO_LOGD("[%p]", handle);
946 handle->audioIoHandle->resume();
947 } catch (CAudioError& e) {
948 AUDIO_IO_LOGE("%s", e.getErrorMsg());
949 return __convert_CAudioError(e);
952 AUDIO_IO_LOGD("[%p] resumed", handle);
954 return AUDIO_IO_ERROR_NONE;
957 int cpp_audio_out_drain(audio_out_h output) {
958 auto handle = static_cast<audio_io_s*>(output);
962 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
963 "Parameter is NULL output:%p", output);
964 assert(handle->audioIoHandle);
965 AUDIO_IO_LOGD("[%p]", handle);
967 handle->audioIoHandle->drain();
968 } catch (CAudioError& e) {
969 AUDIO_IO_LOGE("%s", e.getErrorMsg());
970 return __convert_CAudioError(e);
973 AUDIO_IO_LOGD("[%p] drained", handle);
975 return AUDIO_IO_ERROR_NONE;
978 int cpp_audio_out_flush(audio_out_h output) {
979 auto handle = static_cast<audio_io_s*>(output);
983 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
984 "Parameter is NULL output:%p", output);
985 assert(handle->audioIoHandle);
986 AUDIO_IO_LOGD("[%p]", handle);
988 handle->audioIoHandle->flush();
989 } catch (CAudioError& e) {
990 AUDIO_IO_LOGE("%s", e.getErrorMsg());
991 return __convert_CAudioError(e);
994 AUDIO_IO_LOGD("[%p] flushed", handle);
996 return AUDIO_IO_ERROR_NONE;
999 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1003 auto handle = static_cast<audio_io_s*>(output);
1004 if (!handle || !buffer)
1005 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1006 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1007 assert(handle->audioIoHandle);
1009 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1011 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1013 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1014 ret = static_cast<int>(written);
1015 #ifdef _AUDIO_IO_DEBUG_TIMING_
1016 AUDIO_IO_LOGD("written:%zu", written);
1018 } catch (CAudioError& e) {
1019 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1020 return __convert_CAudioError(e);
1026 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1028 auto handle = static_cast<audio_io_s*>(output);
1029 if (!handle || !size)
1030 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1031 "Parameters are NULL output:%p, size:%p", output, size);
1032 assert(handle->audioIoHandle);
1034 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1036 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1038 *size = outputHandle->getBufferSize();
1039 } catch (CAudioError& e) {
1040 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1041 return __convert_CAudioError(e);
1044 return AUDIO_IO_ERROR_NONE;
1047 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1049 auto handle = static_cast<audio_io_s*>(output);
1050 if (!handle || !sample_rate)
1051 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1052 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1053 assert(handle->audioIoHandle);
1055 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1056 } catch (CAudioError& e) {
1057 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1058 return __convert_CAudioError(e);
1061 return AUDIO_IO_ERROR_NONE;
1064 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1066 auto handle = static_cast<audio_io_s*>(output);
1067 if (!handle || !channel)
1068 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1069 "Parameters are NULL output:%p, channel:%p", output, channel);
1070 assert(handle->audioIoHandle);
1072 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1073 } catch (CAudioError& e) {
1074 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1075 return __convert_CAudioError(e);
1078 return AUDIO_IO_ERROR_NONE;
1081 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1083 auto handle = static_cast<audio_io_s*>(output);
1084 if (!handle || !type)
1085 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1086 "Parameters are NULL output:%p, type:%p", output, type);
1087 assert(handle->audioIoHandle);
1089 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1090 } catch (CAudioError& e) {
1091 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1092 return __convert_CAudioError(e);
1095 return AUDIO_IO_ERROR_NONE;
1098 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1099 auto handle = static_cast<audio_io_s*>(output);
1102 if (!handle || !type)
1103 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1104 "Parameters are NULL output:%p, type:%p", output, type);
1105 assert(handle->audioIoHandle);
1107 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1108 } catch (CAudioError& e) {
1109 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1110 return __convert_CAudioError(e);
1113 return AUDIO_IO_ERROR_NONE;
1116 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1117 auto handle = static_cast<audio_io_s*>(output);
1120 if (!handle || !callback)
1121 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1122 "Parameters are NULL output:%p, callback:%p", output, callback);
1123 assert(handle->audioIoHandle);
1124 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1126 handle->stream_callback.set(callback, user_data);
1128 auto cb = handle->audioIoHandle->getStreamCallback();
1129 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1131 handle->audioIoHandle->setStreamCallback(cb);
1132 } catch (CAudioError& e) {
1133 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1134 return __convert_CAudioError(e);
1137 AUDIO_IO_LOGD("[%p] done", handle);
1139 return AUDIO_IO_ERROR_NONE;
1142 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1143 auto handle = static_cast<audio_io_s*>(output);
1147 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1148 "Parameters are NULL output:%p", output);
1149 assert(handle->audioIoHandle);
1150 AUDIO_IO_LOGD("[%p]", handle);
1152 handle->stream_callback.unset();
1154 auto cb = handle->audioIoHandle->getStreamCallback();
1157 handle->audioIoHandle->setStreamCallback(cb);
1158 } catch (CAudioError& e) {
1159 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1160 return __convert_CAudioError(e);
1163 AUDIO_IO_LOGD("[%p] done", handle);
1165 return AUDIO_IO_ERROR_NONE;
1168 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1169 auto handle = static_cast<audio_io_s*>(output);
1172 if (!handle || !callback)
1173 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1174 "Parameters are NULL output:%p, callback:%p", output, callback);
1175 assert(handle->audioIoHandle);
1176 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1178 handle->state_changed_callback.set(callback, user_data);
1180 auto cb = handle->audioIoHandle->getStateChangedCallback();
1181 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1183 handle->audioIoHandle->setStateChangedCallback(cb);
1184 } catch (CAudioError& e) {
1185 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1186 return __convert_CAudioError(e);
1189 AUDIO_IO_LOGD("[%p] done", handle);
1191 return AUDIO_IO_ERROR_NONE;
1194 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1195 auto handle = static_cast<audio_io_s*>(output);
1199 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1200 "Parameters are NULL output:%p", output);
1201 assert(handle->audioIoHandle);
1202 AUDIO_IO_LOGD("[%p]", handle);
1204 handle->state_changed_callback.unset();
1206 auto cb = handle->audioIoHandle->getStateChangedCallback();
1209 handle->audioIoHandle->setStateChangedCallback(cb);
1210 } catch (CAudioError& e) {
1211 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1212 return __convert_CAudioError(e);
1215 AUDIO_IO_LOGD("[%p] done", handle);
1217 return AUDIO_IO_ERROR_NONE;