Use in-class initializer for class members
[platform/core/api/audio-io.git] / src / cpp / CAudioIO.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <assert.h>
19 #include "CAudioIODef.h"
20 #include <sound_manager_internal.h>
21 #include <sys/time.h>
22 #include <string.h>
23
24 using namespace std;
25 using namespace tizen_media_audio;
26
27
28 /**
29  * class CAudioIO
30  */
31
32 CAudioIO::CAudioIO(CAudioInfo& audioInfo) :
33     mAudioInfo(audioInfo) {
34 }
35
36 void CAudioIO::setInit(bool flag) {
37     __mIsInit = flag;
38 }
39
40 bool CAudioIO::isInit() {
41     return __mIsInit;
42 }
43
44 bool CAudioIO::IsReady() {
45     return ((mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING ||
46              mState == CAudioInfo::EAudioIOState::AUDIO_IO_STATE_PAUSED));
47 }
48
49 void CAudioIO::initialize() {
50     if (__mIsInit)
51         return;
52
53     AUDIO_IO_LOGD("initialize");
54     __mIsInit = true;
55 }
56
57 void CAudioIO::finalize() {
58     if (!__mIsInit)
59         return;
60
61     AUDIO_IO_LOGD("finalize");
62     __mIsInit = false;
63 }
64
65 void CAudioIO::onStream(CPulseAudioClient* pClient, size_t length) {
66     assert(__mIsInit);
67     assert(pClient);
68     assert(length > 0);
69
70 #ifdef _AUDIO_IO_DEBUG_TIMING_
71     AUDIO_IO_LOGD("mStreamCallback.onStream(%p), pClient(%p), length(%zu)", mStreamCallback.onStream, pClient, length);
72 #endif
73
74     if (mStreamCallback.onStream)
75         mStreamCallback.onStream(length, mStreamCallback.mUserData);
76 }
77
78 void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state, bool byPolicy) {
79     assert(__mIsInit);
80     assert(state >= CAudioInfo::EAudioIOState::AUDIO_IO_STATE_NONE && state < CAudioInfo::EAudioIOState::AUDIO_IO_STATE_MAX);
81
82     mByPolicy = byPolicy;
83
84     if (mState == mStatePrev)
85         return;
86
87     static const char* state_string[] = { "NONE", "IDLE", "RUNNING", "PAUSED" };
88
89     AUDIO_IO_LOGD("previous(%s,%d) ===> current(%s,%d), by_policy(%d)",
90                   state_string[static_cast<int>(mStatePrev)],
91                   static_cast<int>(mStatePrev),
92                   state_string[static_cast<int>(mState)],
93                   static_cast<int>(mState),
94                   mByPolicy);
95
96     if (mStateChangedCallback.onStateChanged)
97         mStateChangedCallback.onStateChanged(mState, mStatePrev, mByPolicy, mStateChangedCallback.mUserData);
98 }
99
100 void CAudioIO::setState(CAudioInfo::EAudioIOState state) {
101     mStatePrev = mState;
102     mState = state;
103 }
104
105 void CAudioIO::onStateChanged(CAudioInfo::EAudioIOState state) {
106     onStateChanged(state, false);
107 }
108
109 CAudioInfo::EAudioIOState CAudioIO::getState() noexcept {
110     return mState;
111 }
112
113 void CAudioIO::prepare() {
114     if (!__mIsInit)
115         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
116 }
117
118 void CAudioIO::unprepare() {
119     if (!__mIsInit)
120         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
121 }
122
123 void CAudioIO::pause() {
124     if (!__mIsInit || !IsReady())
125         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO"); //LCOV_EXCL_LINE
126
127     AUDIO_IO_LOGD("pause");
128     mpPulseAudioClient->cork(true);
129 }
130
131 void CAudioIO::resume() {
132     if (!__mIsInit || !IsReady())
133         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO"); //LCOV_EXCL_LINE
134
135     mpPulseAudioClient->cork(false);
136 }
137
138 void CAudioIO::flush() {
139     if (!__mIsInit || !IsReady())
140         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioIO"); //LCOV_EXCL_LINE
141
142     mpPulseAudioClient->flush();
143 }
144
145 CAudioInfo& CAudioIO::getAudioInfo() {
146     if (!__mIsInit)
147         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
148
149     return mAudioInfo;
150 }
151
152 void CAudioIO::setStreamCallback(SStreamCallback callback) {
153     if (!__mIsInit)
154         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
155
156     mStreamCallback = callback;
157 }
158
159 CAudioIO::SStreamCallback CAudioIO::getStreamCallback() {
160     if (!__mIsInit)
161         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
162
163     return mStreamCallback;
164 }
165
166 void CAudioIO::setStateChangedCallback(SStateChangedCallback callback) {
167     if (!__mIsInit)
168         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
169
170     mStateChangedCallback = callback;
171 }
172
173 CAudioIO::SStateChangedCallback CAudioIO::getStateChangedCallback() {
174     if (!__mIsInit)
175         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
176
177     return mStateChangedCallback;
178 }
179
180 void CAudioIO::setStreamInfo(sound_stream_info_h stream_info) {
181     if (!stream_info)
182         THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_ARGUMENT, "stream_info is NULL"); //LCOV_EXCL_LINE
183
184     if (!__mIsInit)
185         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioIO"); //LCOV_EXCL_LINE
186
187     if (mState != CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE)
188         THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_STATE, "it is not permitted while started"); //LCOV_EXCL_LINE
189
190     int errorCode = SOUND_MANAGER_ERROR_NONE;
191     char *type = nullptr;
192     int index = -1;
193     bool avail = false;
194
195     if ((errorCode = sound_manager_is_available_stream_information(stream_info, NATIVE_API_AUDIO_IO, &avail)) != SOUND_MANAGER_ERROR_NONE)
196         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info is invalid [ret:%d]", errorCode); //LCOV_EXCL_LINE
197     if (!avail)
198         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_NOT_SUPPORTED_TYPE, "Input stream is not supported"); //LCOV_EXCL_LINE
199
200     if ((errorCode = sound_manager_get_type_from_stream_information(stream_info, &type)) != SOUND_MANAGER_ERROR_NONE)
201         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->stream_type is invalid [ret:%d]", errorCode); //LCOV_EXCL_LINE
202     if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN)
203         getAudioInfo().setAudioTypeByInputStreamType(type);
204     else
205         getAudioInfo().setAudioTypeByOutputStreamType(type);
206
207     if ((errorCode = sound_manager_get_index_from_stream_information(stream_info, &index)) != SOUND_MANAGER_ERROR_NONE)
208         THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Parameter stream_info->index is invalid [ret:%d]", errorCode); //LCOV_EXCL_LINE
209     getAudioInfo().setAudioIndex(index);
210
211     if (mDirection == CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN) {
212         int device_id;
213         int method;
214         sound_effect_method_with_reference_e method_reference;
215
216         if (sound_manager_get_effect_method(stream_info, &method) == SOUND_MANAGER_ERROR_NONE)
217             getAudioInfo().setEffectMethod(method);
218
219         if (sound_manager_get_effect_method_with_reference(stream_info, &method_reference, &device_id) == SOUND_MANAGER_ERROR_NONE)
220             getAudioInfo().setEffectMethodWithReference(method_reference, device_id);
221     }
222 }