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.
21 #include "CAudioIODef.h"
22 #include <sound_manager_internal.h>
25 using namespace tizen_media_audio;
31 CAudioIO::CAudioIO() :
32 mpPulseAudioClient(NULL),
33 __mMutex(PTHREAD_MUTEX_INITIALIZER),
34 __mCondMutex(PTHREAD_MUTEX_INITIALIZER),
35 __mCond(PTHREAD_COND_INITIALIZER),
37 mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_MAX;
38 mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
39 mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
43 CAudioIO::CAudioIO(CAudioInfo& audioInfo) :
44 mpPulseAudioClient(NULL),
45 __mMutex(PTHREAD_MUTEX_INITIALIZER),
46 __mCondMutex(PTHREAD_MUTEX_INITIALIZER),
47 __mCond(PTHREAD_COND_INITIALIZER),
49 mAudioInfo = audioInfo;
50 mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_MAX;
51 mState = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
52 mStatePrev = CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE;
56 CAudioIO::~CAudioIO() {
59 void CAudioIO::setInit(bool flag) {
63 bool CAudioIO::isInit() {
67 bool CAudioIO::IsReady() {
68 return ((mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING ||
69 mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED)? true : false);
72 void CAudioIO::internalLock() {
73 if (__mIsInit == false)
74 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
76 if (pthread_mutex_lock(&__mMutex) != 0)
77 THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
79 #ifdef _AUDIO_IO_DEBUG_TIMING_
80 AUDIO_IO_LOGD(COLOR_RED "%p LOCKED" COLOR_END, &__mMutex);
84 void CAudioIO::internalUnlock() {
85 if (__mIsInit == false)
86 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
88 if (pthread_mutex_unlock(&__mMutex) != 0)
89 THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
91 #ifdef _AUDIO_IO_DEBUG_TIMING_
92 AUDIO_IO_LOGD(COLOR_GREEN "%p UNLOCKED" COLOR_END, &__mMutex);
96 void CAudioIO::internalWait() {
97 if (__mIsInit == false)
98 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
100 #ifdef _AUDIO_IO_DEBUG_TIMING_
101 AUDIO_IO_LOGD(COLOR_RED "WAIT" COLOR_END);
104 pthread_mutex_lock(&__mCondMutex);
105 pthread_cond_wait(&__mCond, &__mCondMutex);
106 pthread_mutex_unlock(&__mCondMutex);
109 void CAudioIO::internalSignal() {
110 if (__mIsInit == false)
111 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
113 #ifdef _AUDIO_IO_DEBUG_TIMING_
114 AUDIO_IO_LOGD(COLOR_GREEN "SIGNAL" COLOR_END);
117 pthread_mutex_lock(&__mCondMutex);
118 pthread_cond_signal(&__mCond);
119 pthread_mutex_unlock(&__mCondMutex);
122 void CAudioIO::initialize() {
123 if (__mIsInit == true)
126 AUDIO_IO_LOGD("initialize");
128 int ret = pthread_mutex_init(&__mMutex, NULL);
130 THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_mutex_init()");
132 ret = pthread_cond_init(&__mCond, NULL);
134 THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pthread_cond_init()");
139 void CAudioIO::finalize() {
140 if (__mIsInit == false)
143 AUDIO_IO_LOGD("finalize");
145 bool error_occured = false;
146 int ret = pthread_mutex_destroy(&__mMutex);
148 AUDIO_IO_LOGE("Failed pthread_mutex_destroy(%p) errno:%d", &__mMutex, ret);
149 error_occured = true;
152 ret = pthread_mutex_destroy(&__mCondMutex);
154 AUDIO_IO_LOGE("Failed cond pthread_mutex_destroy(%p) errno:%d", &__mCondMutex, ret);
155 error_occured = true;
158 ret = pthread_cond_destroy(&__mCond);
160 AUDIO_IO_LOGE("Failed pthread_cond_destroy(%p) errno:%d", &__mCond, ret);
161 error_occured = true;
165 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Finalize Failed");
170 void CAudioIO::onStream(CPulseAudioClient* pClient, size_t length) {
171 assert(__mIsInit == true);
172 assert(pClient != NULL);
175 #ifdef _AUDIO_IO_DEBUG_TIMING_
176 AUDIO_IO_LOGD("mStreamCallback.onStream(%p), pClient(%p), length(%zu)", mStreamCallback.onStream, pClient, length);
179 if (mStreamCallback.onStream != NULL)
180 mStreamCallback.onStream(length, mStreamCallback.mUserData);
183 void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy) {
184 assert(__mIsInit == true);
185 assert(state >= CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE && state < CAudioInfo::EAudioIOState::AUDIO_IO_STATE_MAX);
189 mByPolicy = byPolicy;
191 if (mState == mStatePrev)
194 const char* state_string[] = { "NONE", "IDLE", "RUNNING", "PAUSED" };
196 AUDIO_IO_LOGD("previous(%s,%d) ===> current(%s,%d), by_policy(%d)",
197 state_string[static_cast<int>(mStatePrev)],
198 static_cast<int>(mStatePrev),
199 state_string[static_cast<int>(mState)],
200 static_cast<int>(mState),
203 if (mStateChangedCallback.onStateChanged != NULL)
204 mStateChangedCallback.onStateChanged(mState, mStatePrev, mByPolicy, mStateChangedCallback.mUserData);
207 void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state) {
208 onStateChanged(state, false);
211 CAudioInfo::EAudioIOState CAudioIO::getState() {
215 void CAudioIO::prepare() {
216 if (__mIsInit == false)
217 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
220 void CAudioIO::unprepare() {
221 if (__mIsInit == false)
222 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
225 void CAudioIO::pause() {
226 if (__mIsInit == false || IsReady() == false)
227 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
231 AUDIO_IO_LOGD("pause");
232 mpPulseAudioClient->cork(true);
234 } catch (CAudioError& e) {
240 void CAudioIO::resume() {
241 if (__mIsInit == false || IsReady() == false)
242 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
246 AUDIO_IO_LOGD("resume");
247 mpPulseAudioClient->cork(false);
249 } catch (CAudioError& e) {
255 void CAudioIO::drain() {
256 if (__mIsInit == false || IsReady() == false)
257 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
260 if (mpPulseAudioClient->isInThread()) {
261 mpPulseAudioClient->drain();
264 mpPulseAudioClient->drain();
267 } catch (CAudioError& e) {
268 if (!mpPulseAudioClient->isInThread())
274 void CAudioIO::flush() {
275 if (__mIsInit == false || IsReady() == false)
276 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO");
279 if (mpPulseAudioClient->isInThread()) {
280 mpPulseAudioClient->flush();
283 mpPulseAudioClient->flush();
286 } catch (CAudioError& e) {
287 if (!mpPulseAudioClient->isInThread())
293 CAudioInfo& CAudioIO::getAudioInfo() {
294 if (__mIsInit == false)
295 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
300 void CAudioIO::setStreamCallback(SStreamCallback callback) {
301 if (__mIsInit == false)
302 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
304 mStreamCallback = callback;
307 CAudioIO::SStreamCallback CAudioIO::getStreamCallback() {
308 if (__mIsInit == false)
309 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
311 return mStreamCallback;
314 void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) {
315 if (__mIsInit == false)
316 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
318 mStateChangedCallback = callback;
321 CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() {
322 if (__mIsInit == false)
323 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
325 return mStateChangedCallback;
328 void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) {
329 if (stream_info == NULL)
330 THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_ARGUMENT, "stream_info is NULL");
332 if (__mIsInit == false)
333 THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO");
336 if (mState != CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE)
337 THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_STATE, "it is not permitted while started");
339 int errorCode = SOUND_MANAGER_ERROR_NONE;
340 CAudioInfo::EAudioType audioType = CAudioInfo::EAudioType::AUDIO_IN_TYPE_MEDIA;
345 if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE)
346 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode);
348 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Input stream is not supported");
350 if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE)
351 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode);
352 if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN)
353 getAudioInfo().convertInputStreamType2AudioType(type, &audioType);
355 getAudioInfo().convertOutputStreamType2AudioType(type, &audioType);
356 getAudioInfo().setAudioType(audioType);
358 if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE)
359 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode);
360 getAudioInfo().setAudioIndex(index);
362 } catch (CAudioError& e) {