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 case CAudioError::EError::ERROR_INVALID_SAMPLERATE:
106 case CAudioError::EError::ERROR_INVALID_CHANNEL:
107 case CAudioError::EError::ERROR_INVALID_FORMAT:
108 return AUDIO_IO_ERROR_INVALID_PARAMETER;
109 case CAudioError::EError::ERROR_DEVICE_NOT_OPENED:
110 return AUDIO_IO_ERROR_DEVICE_NOT_OPENED;
111 case CAudioError::EError::ERROR_DEVICE_NOT_CLOSED:
112 return AUDIO_IO_ERROR_DEVICE_NOT_CLOSED;
113 case CAudioError::EError::ERROR_PERMISSION_DENIED:
114 return AUDIO_IO_ERROR_PERMISSION_DENIED;
115 case CAudioError::EError::ERROR_DEVICE_POLICY_RESTRICTION:
116 return AUDIO_IO_ERROR_DEVICE_POLICY_RESTRICTION;
117 case CAudioError::EError::ERROR_NOT_SUPPORTED:
118 return AUDIO_IO_ERROR_NOT_SUPPORTED;
119 case CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE:
120 return AUDIO_IO_ERROR_NOT_SUPPORTED_TYPE;
121 case CAudioError::EError::ERROR_MAX:
122 case CAudioError::EError::ERROR_INTERNAL_OPERATION:
123 case CAudioError::EError::ERROR_NOT_INITIALIZED:
124 case CAudioError::EError::ERROR_FAILED_OPERATION:
125 case CAudioError::EError::ERROR_INVALID_OPERATION:
126 return AUDIO_IO_ERROR_INVALID_OPERATION;
127 case CAudioError::EError::ERROR_INVALID_STATE:
128 return AUDIO_IO_ERROR_INVALID_STATE;
129 case CAudioError::EError::ERROR_OUT_OF_MEMORY:
130 case CAudioError::EError::ERROR_INVALID_POINTER:
131 return AUDIO_IO_ERROR_INVALID_BUFFER;
132 case CAudioError::EError::ERROR_POLICY_BLOCKED:
133 case CAudioError::EError::ERROR_POLICY_INTERRUPTED:
134 case CAudioError::EError::ERROR_POLICY_DUPLICATED:
135 return AUDIO_IO_ERROR_SOUND_POLICY;
137 return AUDIO_IO_ERROR_NONE;
141 static CAudioInfo::EChannel __convert_channel_to_audio_info_channel(const audio_channel_e &src_channel) {
142 switch (src_channel) {
143 case AUDIO_CHANNEL_MONO:
144 return CAudioInfo::EChannel::CHANNEL_MONO;
145 case AUDIO_CHANNEL_STEREO:
146 return CAudioInfo::EChannel::CHANNEL_STEREO;
147 case AUDIO_CHANNEL_MULTI_3:
148 return CAudioInfo::EChannel::CHANNEL_MULTI_3;
149 case AUDIO_CHANNEL_MULTI_4:
150 return CAudioInfo::EChannel::CHANNEL_MULTI_4;
151 case AUDIO_CHANNEL_MULTI_5:
152 return CAudioInfo::EChannel::CHANNEL_MULTI_5;
153 case AUDIO_CHANNEL_MULTI_6:
154 return CAudioInfo::EChannel::CHANNEL_MULTI_6;
155 case AUDIO_CHANNEL_MULTI_7:
156 return CAudioInfo::EChannel::CHANNEL_MULTI_7;
157 case AUDIO_CHANNEL_MULTI_8:
158 return CAudioInfo::EChannel::CHANNEL_MULTI_8;
160 return CAudioInfo::EChannel::CHANNEL_MONO;
164 static audio_channel_e __convert_audio_info_channel_to_channel(const CAudioInfo::EChannel& src_channel) {
165 switch (src_channel) {
166 case CAudioInfo::EChannel::CHANNEL_MONO:
167 return AUDIO_CHANNEL_MONO;
168 case CAudioInfo::EChannel::CHANNEL_STEREO:
169 return AUDIO_CHANNEL_STEREO;
170 case CAudioInfo::EChannel::CHANNEL_MULTI_3:
171 return AUDIO_CHANNEL_MULTI_3;
172 case CAudioInfo::EChannel::CHANNEL_MULTI_4:
173 return AUDIO_CHANNEL_MULTI_4;
174 case CAudioInfo::EChannel::CHANNEL_MULTI_5:
175 return AUDIO_CHANNEL_MULTI_5;
176 case CAudioInfo::EChannel::CHANNEL_MULTI_6:
177 return AUDIO_CHANNEL_MULTI_6;
178 case CAudioInfo::EChannel::CHANNEL_MULTI_7:
179 return AUDIO_CHANNEL_MULTI_7;
180 case CAudioInfo::EChannel::CHANNEL_MULTI_8:
181 return AUDIO_CHANNEL_MULTI_8;
183 return AUDIO_CHANNEL_MONO;
187 static CAudioInfo::ESampleType __convert_sample_type_to_audio_info_sample_type(const audio_sample_type_e& src_type) {
189 case AUDIO_SAMPLE_TYPE_U8:
190 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
191 case AUDIO_SAMPLE_TYPE_S16_LE:
192 return CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE;
193 case AUDIO_SAMPLE_TYPE_S24_LE:
194 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE;
195 case AUDIO_SAMPLE_TYPE_S24_32_LE:
196 return CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE;
197 case AUDIO_SAMPLE_TYPE_S32_LE:
198 return CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE;
200 return CAudioInfo::ESampleType::SAMPLE_TYPE_U8;
204 static audio_sample_type_e __convert_audio_info_sample_type_to_sample_type(const CAudioInfo::ESampleType &src_type) {
206 case CAudioInfo::ESampleType::SAMPLE_TYPE_U8:
207 return AUDIO_SAMPLE_TYPE_U8;
208 case CAudioInfo::ESampleType::SAMPLE_TYPE_S16_LE:
209 return AUDIO_SAMPLE_TYPE_S16_LE;
210 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_LE:
211 return AUDIO_SAMPLE_TYPE_S24_LE;
212 case CAudioInfo::ESampleType::SAMPLE_TYPE_S24_32_LE:
213 return AUDIO_SAMPLE_TYPE_S24_32_LE;
214 case CAudioInfo::ESampleType::SAMPLE_TYPE_S32_LE:
215 return AUDIO_SAMPLE_TYPE_S32_LE;
217 return AUDIO_SAMPLE_TYPE_U8;
221 static CAudioInfo::EAudioType __convert_sound_type_to_audio_info_audio_type(const sound_type_e &src_type) {
223 case SOUND_TYPE_SYSTEM:
224 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
225 case SOUND_TYPE_NOTIFICATION:
226 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION;
227 case SOUND_TYPE_ALARM:
228 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM;
229 case SOUND_TYPE_RINGTONE:
230 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP;
231 case SOUND_TYPE_MEDIA:
232 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
233 case SOUND_TYPE_CALL:
234 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM;
235 case SOUND_TYPE_VOIP:
236 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP;
237 case SOUND_TYPE_VOICE:
238 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION;
240 return CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA;
244 static sound_type_e __convert_audio_info_audio_type_to_sound_type(const CAudioInfo::EAudioType &src_type) {
246 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_MEDIA:
247 return SOUND_TYPE_MEDIA;
248 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_SYSTEM:
249 return SOUND_TYPE_SYSTEM;
250 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_ALARM:
251 return SOUND_TYPE_ALARM;
252 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_NOTIFICATION:
253 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_EMERGENCY:
254 return SOUND_TYPE_NOTIFICATION;
255 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOICE_INFORMATION:
256 return SOUND_TYPE_VOICE;
257 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_RINGTONE_VOIP:
258 return SOUND_TYPE_RINGTONE;
259 case CAudioInfo::EAudioType::AUDIO_OUT_TYPE_VOIP:
260 return SOUND_TYPE_VOIP;
262 return SOUND_TYPE_MEDIA;
266 static audio_io_state_e __convert_state_type(const CAudioInfo::EAudioIOState src_state) {
268 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE:
269 return AUDIO_IO_STATE_IDLE;
270 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE:
271 return AUDIO_IO_STATE_IDLE;
272 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING:
273 return AUDIO_IO_STATE_RUNNING;
274 case CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED:
275 return AUDIO_IO_STATE_PAUSED;
277 return AUDIO_IO_STATE_IDLE;
281 static void __check_audio_param(int sample_rate, audio_channel_e channel, audio_sample_type_e type, bool is_output) {
282 if (sample_rate < static_cast<int>(CAudioInfo::MIN_SYSTEM_SAMPLERATE) ||
283 sample_rate > static_cast<int>(CAudioInfo::MAX_SYSTEM_SAMPLERATE))
284 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample rate :%d", sample_rate);
286 if (channel < AUDIO_CHANNEL_MONO ||
287 channel > ((is_output) ? AUDIO_CHANNEL_STEREO : AUDIO_CHANNEL_MULTI_8))
288 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid channel :%d", channel);
290 if (type < AUDIO_SAMPLE_TYPE_U8 ||
291 type > AUDIO_SAMPLE_TYPE_S32_LE)
292 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid sample type :%d", type);
295 static CAudioInfo __generate_audio_input_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type) {
296 return CAudioInfo(sampleRate,
297 __convert_channel_to_audio_info_channel(channel),
298 __convert_sample_type_to_audio_info_sample_type(sample_type),
299 CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA,
303 static CAudioInfo __generate_audio_output_info(int sampleRate, audio_channel_e channel, audio_sample_type_e sample_type, sound_type_e sound_type) {
304 return CAudioInfo(sampleRate,
305 __convert_channel_to_audio_info_channel(channel),
306 __convert_sample_type_to_audio_info_sample_type(sample_type),
307 __convert_sound_type_to_audio_info_audio_type(sound_type),
311 static void __handle_safe_free(audio_io_s* handle, void *obj, bool is_output) {
312 VALID_POINTER_START(handle)
313 SAFE_FINALIZE(handle->audioIoHandle);
314 SAFE_DELETE(handle->audioIoHandle);
318 VALID_POINTER_START(obj)
320 *(audio_out_h *)obj = nullptr;
322 *(audio_in_h *)obj = nullptr;
327 * Implements CAPI functions
329 int cpp_audio_in_create(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_in_h *input) {
330 audio_io_s* handle = nullptr;
331 bool mic_enable = false;
335 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
336 "Parameters are NULL input:%p", input);
338 __check_audio_param(sample_rate, channel, type, false);
340 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
342 /* If MIC is not supported, return NOT_SUPPORTED error */
343 int ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
344 AUDIO_IO_LOGD("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
345 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
346 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "System doesn't support microphone!");
348 CAudioInfo audioInfo = __generate_audio_input_info(sample_rate, channel, type);
350 handle = new audio_io_s;
351 handle->audioIoHandle = new CAudioInput(audioInfo);
352 handle->audioIoHandle->initialize();
354 AUDIO_IO_LOGD("[%p] created", handle);
356 } catch (CAudioError& e) {
357 AUDIO_IO_LOGE("%s", e.getErrorMsg());
358 __handle_safe_free(handle, (void *)input, false);
359 return __convert_CAudioError(e);
360 } catch (const std::bad_alloc&) {
361 CAudioError e(CAudioError::EError::ERROR_OUT_OF_MEMORY);
362 AUDIO_IO_LOGE("Failed to allocate handle");
363 __handle_safe_free(handle, (void *)input, false);
364 return __convert_CAudioError(e);
368 return AUDIO_IO_ERROR_NONE;
371 int cpp_audio_in_destroy(audio_in_h input) {
372 auto handle = static_cast<audio_io_s*>(input);
376 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
377 "Parameters are NULL input:%p", input);
378 assert(handle->audioIoHandle);
379 AUDIO_IO_LOGD("[%p]", handle);
381 /* Internal unprepare for backward compatibility */
382 handle->audioIoHandle->unprepare();
384 SAFE_FINALIZE(handle->audioIoHandle);
385 SAFE_DELETE(handle->audioIoHandle);
387 } catch (CAudioError& e) {
388 AUDIO_IO_LOGE("%s", e.getErrorMsg());
389 return __convert_CAudioError(e);
392 AUDIO_IO_LOGD("destroyed");
394 return AUDIO_IO_ERROR_NONE;
397 int cpp_audio_in_set_sound_stream_info(audio_in_h input, sound_stream_info_h stream_info) {
398 auto handle = static_cast<audio_io_s*>(input);
401 if (!handle || !stream_info)
402 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
403 "Parameters are NULL input:%p, stream_info:%p", input, stream_info);
404 assert(handle->audioIoHandle);
405 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
407 handle->audioIoHandle->setStreamInfo(stream_info);
408 } catch (CAudioError& e) {
409 AUDIO_IO_LOGE("%s", e.getErrorMsg());
410 return __convert_CAudioError(e);
413 AUDIO_IO_LOGD("[%p] done", handle);
415 return AUDIO_IO_ERROR_NONE;
418 int cpp_audio_in_prepare(audio_in_h input) {
419 auto handle = static_cast<audio_io_s*>(input);
423 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
424 "Parameters are NULL input:%p", input);
425 assert(handle->audioIoHandle);
426 AUDIO_IO_LOGD("[%p]", handle);
428 handle->audioIoHandle->prepare();
429 } catch (CAudioError& e) {
430 AUDIO_IO_LOGE("%s", e.getErrorMsg());
431 return __convert_CAudioError(e);
434 AUDIO_IO_LOGD("[%p] prepared", handle);
436 return AUDIO_IO_ERROR_NONE;
439 int cpp_audio_in_unprepare(audio_in_h input) {
440 auto handle = static_cast<audio_io_s*>(input);
444 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
445 "Parameters are NULL input:%p", input);
446 assert(handle->audioIoHandle);
447 AUDIO_IO_LOGD("[%p]", handle);
449 handle->audioIoHandle->unprepare();
450 } catch (CAudioError& e) {
451 AUDIO_IO_LOGE("%s", e.getErrorMsg());
452 return __convert_CAudioError(e);
455 AUDIO_IO_LOGD("[%p] unprepared", handle);
457 return AUDIO_IO_ERROR_NONE;
460 int cpp_audio_in_pause(audio_in_h input) {
461 auto handle = static_cast<audio_io_s*>(input);
465 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
466 "Parameters are NULL input:%p", input);
467 assert(handle->audioIoHandle);
468 AUDIO_IO_LOGD("[%p]", handle);
470 handle->audioIoHandle->pause();
471 } catch (CAudioError& e) {
472 AUDIO_IO_LOGE("%s", e.getErrorMsg());
473 return __convert_CAudioError(e);
476 AUDIO_IO_LOGD("[%p] paused", handle);
478 return AUDIO_IO_ERROR_NONE;
481 int cpp_audio_in_resume(audio_in_h input) {
482 auto handle = static_cast<audio_io_s*>(input);
486 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
487 "Parameters are NULL input:%p", input);
488 assert(handle->audioIoHandle);
489 AUDIO_IO_LOGD("[%p]", handle);
491 handle->audioIoHandle->resume();
492 } catch (CAudioError& e) {
493 AUDIO_IO_LOGE("%s", e.getErrorMsg());
494 return __convert_CAudioError(e);
497 AUDIO_IO_LOGD("[%p] resumed", handle);
499 return AUDIO_IO_ERROR_NONE;
502 int cpp_audio_in_flush(audio_in_h input) {
503 auto handle = static_cast<audio_io_s*>(input);
507 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
508 "Parameters are NULL input:%p", input);
509 assert(handle->audioIoHandle);
510 AUDIO_IO_LOGD("[%p]", handle);
512 handle->audioIoHandle->flush();
513 } catch (CAudioError& e) {
514 AUDIO_IO_LOGE("%s", e.getErrorMsg());
515 return __convert_CAudioError(e);
518 AUDIO_IO_LOGD("[%p] flushed", handle);
520 return AUDIO_IO_ERROR_NONE;
523 int cpp_audio_in_read(audio_in_h input, void *buffer, unsigned int length) {
527 auto handle = static_cast<audio_io_s*>(input);
528 if (!handle || !buffer)
529 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
530 "Parameters are NULL input:%p, buffer:%p", input, buffer);
531 assert(handle->audioIoHandle);
533 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
535 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
537 auto readn = inputHandle->read(buffer, static_cast<size_t>(length));
538 ret = static_cast<int>(readn);
539 #ifdef _AUDIO_IO_DEBUG_TIMING_
540 AUDIO_IO_LOGD("readn:%zu", readn);
542 } catch (CAudioError& e) {
543 AUDIO_IO_LOGE("%s", e.getErrorMsg());
544 return __convert_CAudioError(e);
550 int cpp_audio_in_get_buffer_size(audio_in_h input, int *size) {
552 auto handle = static_cast<audio_io_s*>(input);
553 if (!handle || !size)
554 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
555 "Parameters are NULL input:%p, size:%p", input, size);
556 assert(handle->audioIoHandle);
558 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
560 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
562 *size = inputHandle->getBufferSize();
563 } catch (CAudioError& e) {
564 AUDIO_IO_LOGE("%s", e.getErrorMsg());
565 return __convert_CAudioError(e);
568 return AUDIO_IO_ERROR_NONE;
571 int cpp_audio_in_get_sample_rate(audio_in_h input, int *sample_rate) {
573 auto handle = static_cast<audio_io_s*>(input);
574 if (!handle || !sample_rate)
575 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
576 "Parameters are NULL input:%p, sample_rate:%p", input, sample_rate);
577 assert(handle->audioIoHandle);
579 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
580 } catch (CAudioError& e) {
581 AUDIO_IO_LOGE("%s", e.getErrorMsg());
582 return __convert_CAudioError(e);
585 return AUDIO_IO_ERROR_NONE;
588 int cpp_audio_in_get_channel(audio_in_h input, audio_channel_e *channel) {
590 auto handle = static_cast<audio_io_s*>(input);
591 if (!handle || !channel)
592 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
593 "Parameters are NULL input:%p, channel:%p", input, channel);
594 assert(handle->audioIoHandle);
596 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
597 } catch (CAudioError& e) {
598 AUDIO_IO_LOGE("%s", e.getErrorMsg());
599 return __convert_CAudioError(e);
602 return AUDIO_IO_ERROR_NONE;
605 int cpp_audio_in_get_sample_type(audio_in_h input, audio_sample_type_e *type) {
607 auto handle = static_cast<audio_io_s*>(input);
608 if (!handle || !type)
609 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
610 "Parameters are NULL input:%p, type:%p", input, type);
611 assert(handle->audioIoHandle);
613 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
614 } catch (CAudioError& e) {
615 AUDIO_IO_LOGE("%s", e.getErrorMsg());
616 return __convert_CAudioError(e);
619 return AUDIO_IO_ERROR_NONE;
622 static void __stream_cb_internal(size_t nbytes, void *user_data) {
623 auto audioIo = static_cast<audio_io_s*>(user_data);
626 if (audioIo->stream_callback.onStream)
627 audioIo->stream_callback.onStream(audioIo, nbytes, audioIo->stream_callback.user_data);
631 static void __state_changed_cb_internal(CAudioInfo::EAudioIOState state,
632 CAudioInfo::EAudioIOState state_prev,
635 auto audioIo = static_cast<audio_io_s*>(user_data);
638 if (audioIo->state_changed_callback.onStateChanged)
639 audioIo->state_changed_callback.onStateChanged(audioIo, __convert_state_type(state_prev),
640 __convert_state_type(state), by_policy,
641 audioIo->state_changed_callback.user_data);
645 int cpp_audio_in_set_stream_cb(audio_in_h input, audio_in_stream_cb callback, void* user_data) {
646 auto handle = static_cast<audio_io_s*>(input);
649 if (!handle || !callback)
650 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
651 "Parameters are NULL input:%p, callback:%p", input, callback);
652 assert(handle->audioIoHandle);
653 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
655 handle->stream_callback.set(callback, user_data);
657 auto cb = handle->audioIoHandle->getStreamCallback();
658 cb.set(__stream_cb_internal, static_cast<void*>(handle));
660 handle->audioIoHandle->setStreamCallback(cb);
661 } catch (CAudioError& e) {
662 AUDIO_IO_LOGE("%s", e.getErrorMsg());
663 return __convert_CAudioError(e);
666 AUDIO_IO_LOGD("[%p] done", handle);
668 return AUDIO_IO_ERROR_NONE;
671 int cpp_audio_in_unset_stream_cb(audio_in_h input) {
672 auto handle = static_cast<audio_io_s*>(input);
675 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
676 "Parameters are NULL input:%p", input);
677 assert(handle->audioIoHandle);
678 AUDIO_IO_LOGD("[%p]", handle);
680 handle->stream_callback.unset();
682 auto cb = handle->audioIoHandle->getStreamCallback();
685 handle->audioIoHandle->setStreamCallback(cb);
686 } catch (CAudioError& e) {
687 AUDIO_IO_LOGE("%s", e.getErrorMsg());
688 return __convert_CAudioError(e);
691 AUDIO_IO_LOGD("[%p] done", handle);
693 return AUDIO_IO_ERROR_NONE;
696 int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *length) {
700 auto handle = static_cast<audio_io_s*>(input);
701 if (!handle || !buffer)
702 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
703 "Parameters are NULL input:%p, buffer:%p", input, buffer);
705 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
707 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
709 inputHandle->peek(buffer, &_length);
710 } catch (CAudioError& e) {
711 AUDIO_IO_LOGE("%s", e.getErrorMsg());
712 return __convert_CAudioError(e);
715 *length = (unsigned int)_length;
717 return AUDIO_IO_ERROR_NONE;
720 int cpp_audio_in_drop(audio_in_h input) {
722 auto handle = static_cast<audio_io_s*>(input);
724 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
725 "Parameters are NULL input:%p", input);
727 auto inputHandle = static_cast<CAudioInput*>(handle->audioIoHandle);
729 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
732 } catch (CAudioError& e) {
733 AUDIO_IO_LOGE("%s", e.getErrorMsg());
734 return __convert_CAudioError(e);
737 return AUDIO_IO_ERROR_NONE;
740 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data) {
741 auto handle = static_cast<audio_io_s*>(input);
744 if (!handle || !callback)
745 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
746 "Parameters are NULL input:%p, callback:%p", input, callback);
747 assert(handle->audioIoHandle);
748 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
750 handle->state_changed_callback.set(callback, user_data);
752 auto cb = handle->audioIoHandle->getStateChangedCallback();
753 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
755 handle->audioIoHandle->setStateChangedCallback(cb);
756 } catch (CAudioError& e) {
757 AUDIO_IO_LOGE("%s", e.getErrorMsg());
758 return __convert_CAudioError(e);
761 AUDIO_IO_LOGD("[%p] done", handle);
763 return AUDIO_IO_ERROR_NONE;
766 int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
767 auto handle = static_cast<audio_io_s*>(input);
771 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
772 "Parameters are NULL output:%p", input);
773 assert(handle->audioIoHandle);
774 AUDIO_IO_LOGD("[%p]", handle);
776 handle->state_changed_callback.unset();
778 auto cb = handle->audioIoHandle->getStateChangedCallback();
781 handle->audioIoHandle->setStateChangedCallback(cb);
782 } catch (CAudioError& e) {
783 AUDIO_IO_LOGE("%s", e.getErrorMsg());
784 return __convert_CAudioError(e);
787 AUDIO_IO_LOGD("[%p] done", handle);
789 return AUDIO_IO_ERROR_NONE;
796 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output) {
797 audio_io_s* handle = nullptr;
800 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
801 "Parameters are NULL output:%p", output);
803 __check_audio_param(sample_rate, channel, type, true);
805 AUDIO_IO_LOGD("samplerate:[%d] channel:[0x%x] sample_type:[0x%x]", sample_rate, channel, type);
806 CAudioInfo audioInfo = __generate_audio_output_info(sample_rate, channel, type, SOUND_TYPE_MEDIA);
808 handle = new audio_io_s;
809 handle->audioIoHandle = new CAudioOutput(audioInfo);
810 handle->audioIoHandle->initialize();
812 AUDIO_IO_LOGD("[%p] created", handle);
814 } catch (CAudioError& e) {
815 AUDIO_IO_LOGE("%s", e.getErrorMsg());
816 __handle_safe_free(handle, (void *)output, true);
817 return __convert_CAudioError(e);
818 } catch (const std::bad_alloc&) {
819 CAudioError e(CAudioError::EError::ERROR_OUT_OF_MEMORY);
820 AUDIO_IO_LOGE("Failed to allocate handle");
821 __handle_safe_free(handle, (void *)output, true);
822 return __convert_CAudioError(e);
826 return AUDIO_IO_ERROR_NONE;
829 int cpp_audio_out_destroy(audio_out_h output) {
830 auto handle = static_cast<audio_io_s*>(output);
834 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
835 "Parameter is NULL output:%p", output);
836 assert(handle->audioIoHandle);
837 AUDIO_IO_LOGD("[%p]", handle);
839 /* Internal unprepare for backward compatibility */
840 handle->audioIoHandle->unprepare();
842 SAFE_FINALIZE(handle->audioIoHandle);
843 SAFE_DELETE(handle->audioIoHandle);
845 } catch (CAudioError& e) {
846 AUDIO_IO_LOGE("%s", e.getErrorMsg());
847 return __convert_CAudioError(e);
850 AUDIO_IO_LOGD("[%p] destroyed", handle);
852 return AUDIO_IO_ERROR_NONE;
855 int cpp_audio_out_set_sound_stream_info(audio_out_h output, sound_stream_info_h stream_info) {
856 auto handle = static_cast<audio_io_s*>(output);
859 if (!handle || !stream_info)
860 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
861 "Parameters are NULL output:%p, stream_info:%p", output, stream_info);
862 assert(handle->audioIoHandle);
863 AUDIO_IO_LOGD("[%p], stream_info:[%p]", handle, stream_info);
865 handle->audioIoHandle->setStreamInfo(stream_info);
866 } catch (CAudioError& e) {
867 AUDIO_IO_LOGE("%s", e.getErrorMsg());
868 return __convert_CAudioError(e);
871 AUDIO_IO_LOGD("[%p] done", handle);
873 return AUDIO_IO_ERROR_NONE;
876 int cpp_audio_out_prepare(audio_out_h output) {
877 auto handle = static_cast<audio_io_s*>(output);
881 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
882 "Parameter is NULL output:%p", output);
883 assert(handle->audioIoHandle);
884 AUDIO_IO_LOGD("[%p]", handle);
886 handle->audioIoHandle->prepare();
887 } catch (CAudioError& e) {
888 AUDIO_IO_LOGE("%s", e.getErrorMsg());
889 return __convert_CAudioError(e);
892 AUDIO_IO_LOGD("[%p] prepared", handle);
894 return AUDIO_IO_ERROR_NONE;
897 int cpp_audio_out_unprepare(audio_out_h output) {
898 auto handle = static_cast<audio_io_s*>(output);
902 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
903 "Parameter is NULL output:%p", output);
904 assert(handle->audioIoHandle);
905 AUDIO_IO_LOGD("[%p]", handle);
907 handle->audioIoHandle->unprepare();
908 } catch (CAudioError& e) {
909 AUDIO_IO_LOGE("%s", e.getErrorMsg());
910 return __convert_CAudioError(e);
913 AUDIO_IO_LOGD("[%p] unprepared", handle);
915 return AUDIO_IO_ERROR_NONE;
918 int cpp_audio_out_pause(audio_out_h output) {
919 auto handle = static_cast<audio_io_s*>(output);
923 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
924 "Parameter is NULL output:%p", output);
925 assert(handle->audioIoHandle);
926 AUDIO_IO_LOGD("[%p]", handle);
928 handle->audioIoHandle->pause();
929 } catch (CAudioError& e) {
930 AUDIO_IO_LOGE("%s", e.getErrorMsg());
931 return __convert_CAudioError(e);
934 AUDIO_IO_LOGD("[%p] paused", handle);
936 return AUDIO_IO_ERROR_NONE;
939 int cpp_audio_out_resume(audio_out_h output) {
940 auto handle = static_cast<audio_io_s*>(output);
944 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
945 "Parameter is NULL output:%p", output);
946 assert(handle->audioIoHandle);
947 AUDIO_IO_LOGD("[%p]", handle);
949 handle->audioIoHandle->resume();
950 } catch (CAudioError& e) {
951 AUDIO_IO_LOGE("%s", e.getErrorMsg());
952 return __convert_CAudioError(e);
955 AUDIO_IO_LOGD("[%p] resumed", handle);
957 return AUDIO_IO_ERROR_NONE;
960 int cpp_audio_out_drain(audio_out_h output) {
961 auto handle = static_cast<audio_io_s*>(output);
965 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
966 "Parameter is NULL output:%p", output);
967 assert(handle->audioIoHandle);
968 AUDIO_IO_LOGD("[%p]", handle);
970 handle->audioIoHandle->drain();
971 } catch (CAudioError& e) {
972 AUDIO_IO_LOGE("%s", e.getErrorMsg());
973 return __convert_CAudioError(e);
976 AUDIO_IO_LOGD("[%p] drained", handle);
978 return AUDIO_IO_ERROR_NONE;
981 int cpp_audio_out_flush(audio_out_h output) {
982 auto handle = static_cast<audio_io_s*>(output);
986 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
987 "Parameter is NULL output:%p", output);
988 assert(handle->audioIoHandle);
989 AUDIO_IO_LOGD("[%p]", handle);
991 handle->audioIoHandle->flush();
992 } catch (CAudioError& e) {
993 AUDIO_IO_LOGE("%s", e.getErrorMsg());
994 return __convert_CAudioError(e);
997 AUDIO_IO_LOGD("[%p] flushed", handle);
999 return AUDIO_IO_ERROR_NONE;
1002 int cpp_audio_out_write(audio_out_h output, void *buffer, unsigned int length) {
1006 auto handle = static_cast<audio_io_s*>(output);
1007 if (!handle || !buffer)
1008 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1009 "Parameter is NULL output:%p, buffer:%p", output, buffer);
1010 assert(handle->audioIoHandle);
1012 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1014 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1016 auto written = outputHandle->write(buffer, static_cast<size_t>(length));
1017 ret = static_cast<int>(written);
1018 #ifdef _AUDIO_IO_DEBUG_TIMING_
1019 AUDIO_IO_LOGD("written:%zu", written);
1021 } catch (CAudioError& e) {
1022 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1023 return __convert_CAudioError(e);
1029 int cpp_audio_out_get_buffer_size(audio_out_h output, int *size) {
1031 auto handle = static_cast<audio_io_s*>(output);
1032 if (!handle || !size)
1033 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1034 "Parameters are NULL output:%p, size:%p", output, size);
1035 assert(handle->audioIoHandle);
1037 auto outputHandle = static_cast<CAudioOutput*>(handle->audioIoHandle);
1039 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_HANDLE, "Handle is NULL");
1041 *size = outputHandle->getBufferSize();
1042 } catch (CAudioError& e) {
1043 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1044 return __convert_CAudioError(e);
1047 return AUDIO_IO_ERROR_NONE;
1050 int cpp_audio_out_get_sample_rate(audio_out_h output, int *sample_rate) {
1052 auto handle = static_cast<audio_io_s*>(output);
1053 if (!handle || !sample_rate)
1054 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1055 "Parameters are NULL output:%p, sample_rate:%p", output, sample_rate);
1056 assert(handle->audioIoHandle);
1058 *sample_rate = handle->audioIoHandle->getAudioInfo().getSampleRate();
1059 } catch (CAudioError& e) {
1060 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1061 return __convert_CAudioError(e);
1064 return AUDIO_IO_ERROR_NONE;
1067 int cpp_audio_out_get_channel(audio_out_h output, audio_channel_e *channel) {
1069 auto handle = static_cast<audio_io_s*>(output);
1070 if (!handle || !channel)
1071 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1072 "Parameters are NULL output:%p, channel:%p", output, channel);
1073 assert(handle->audioIoHandle);
1075 *channel = __convert_audio_info_channel_to_channel(handle->audioIoHandle->getAudioInfo().getChannel());
1076 } catch (CAudioError& e) {
1077 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1078 return __convert_CAudioError(e);
1081 return AUDIO_IO_ERROR_NONE;
1084 int cpp_audio_out_get_sample_type(audio_out_h output, audio_sample_type_e *type) {
1086 auto handle = static_cast<audio_io_s*>(output);
1087 if (!handle || !type)
1088 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1089 "Parameters are NULL output:%p, type:%p", output, type);
1090 assert(handle->audioIoHandle);
1092 *type = __convert_audio_info_sample_type_to_sample_type(handle->audioIoHandle->getAudioInfo().getSampleType());
1093 } catch (CAudioError& e) {
1094 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1095 return __convert_CAudioError(e);
1098 return AUDIO_IO_ERROR_NONE;
1101 int cpp_audio_out_get_sound_type(audio_out_h output, sound_type_e *type) {
1102 auto handle = static_cast<audio_io_s*>(output);
1105 if (!handle || !type)
1106 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1107 "Parameters are NULL output:%p, type:%p", output, type);
1108 assert(handle->audioIoHandle);
1110 *type = __convert_audio_info_audio_type_to_sound_type(handle->audioIoHandle->getAudioInfo().getAudioType());
1111 } catch (CAudioError& e) {
1112 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1113 return __convert_CAudioError(e);
1116 return AUDIO_IO_ERROR_NONE;
1119 int cpp_audio_out_set_stream_cb(audio_out_h output, audio_out_stream_cb callback, void* user_data) {
1120 auto handle = static_cast<audio_io_s*>(output);
1123 if (!handle || !callback)
1124 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1125 "Parameters are NULL output:%p, callback:%p", output, callback);
1126 assert(handle->audioIoHandle);
1127 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1129 handle->stream_callback.set(callback, user_data);
1131 auto cb = handle->audioIoHandle->getStreamCallback();
1132 cb.set(__stream_cb_internal, static_cast<void*>(handle));
1134 handle->audioIoHandle->setStreamCallback(cb);
1135 } catch (CAudioError& e) {
1136 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1137 return __convert_CAudioError(e);
1140 AUDIO_IO_LOGD("[%p] done", handle);
1142 return AUDIO_IO_ERROR_NONE;
1145 int cpp_audio_out_unset_stream_cb(audio_out_h output) {
1146 auto handle = static_cast<audio_io_s*>(output);
1150 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1151 "Parameters are NULL output:%p", output);
1152 assert(handle->audioIoHandle);
1153 AUDIO_IO_LOGD("[%p]", handle);
1155 handle->stream_callback.unset();
1157 auto cb = handle->audioIoHandle->getStreamCallback();
1160 handle->audioIoHandle->setStreamCallback(cb);
1161 } catch (CAudioError& e) {
1162 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1163 return __convert_CAudioError(e);
1166 AUDIO_IO_LOGD("[%p] done", handle);
1168 return AUDIO_IO_ERROR_NONE;
1171 int cpp_audio_out_set_state_changed_cb(audio_out_h output, audio_in_state_changed_cb callback, void* user_data) {
1172 auto handle = static_cast<audio_io_s*>(output);
1175 if (!handle || !callback)
1176 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1177 "Parameters are NULL output:%p, callback:%p", output, callback);
1178 assert(handle->audioIoHandle);
1179 AUDIO_IO_LOGD("[%p], callback:[%p], user_data:[%p]", handle, callback, user_data);
1181 handle->state_changed_callback.set(callback, user_data);
1183 auto cb = handle->audioIoHandle->getStateChangedCallback();
1184 cb.set(__state_changed_cb_internal, static_cast<void*>(handle));
1186 handle->audioIoHandle->setStateChangedCallback(cb);
1187 } catch (CAudioError& e) {
1188 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1189 return __convert_CAudioError(e);
1192 AUDIO_IO_LOGD("[%p] done", handle);
1194 return AUDIO_IO_ERROR_NONE;
1197 int cpp_audio_out_unset_state_changed_cb(audio_out_h output) {
1198 auto handle = static_cast<audio_io_s*>(output);
1202 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
1203 "Parameters are NULL output:%p", output);
1204 assert(handle->audioIoHandle);
1205 AUDIO_IO_LOGD("[%p]", handle);
1207 handle->state_changed_callback.unset();
1209 auto cb = handle->audioIoHandle->getStateChangedCallback();
1212 handle->audioIoHandle->setStateChangedCallback(cb);
1213 } catch (CAudioError& e) {
1214 AUDIO_IO_LOGE("%s", e.getErrorMsg());
1215 return __convert_CAudioError(e);
1218 AUDIO_IO_LOGD("[%p] done", handle);
1220 return AUDIO_IO_ERROR_NONE;