Rearrange code to stop all client
[platform/core/uifw/tts.git] / server / AudioStream.cpp
1 /*
2 *  Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dlog.h>
15
16 #include "ttsd_main.h"
17
18 #include "AudioStream.h"
19
20 using namespace std;
21
22
23 static const char* FOCUS_SERVER_READY = "/tmp/.sound_server_ready";
24
25
26 AudioStream::AudioStream()
27 {
28         __prepared = false;
29         __focusAquired = false;
30
31         createSoundStreamInfo();
32         createAudioHandle(TTSE_AUDIO_TYPE_RAW_S16, 16000);
33 }
34
35 void AudioStream::createSoundStreamInfo()
36 {
37         int cnt = 0;
38         while (1) {
39                 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
40                         SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is available");
41                         break;
42                 } else {
43                         if (0 == cnt++ % 10)
44                                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is not available");
45                         usleep(50000);
46                 }
47         }
48
49         int ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __focusStateChangedCallback, this, &__streamInfo);
50         if (SOUND_MANAGER_ERROR_NONE != ret) {
51                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create stream info");
52                 return;
53         }
54
55         __focusAquired = false;
56         SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Create stream info");
57 }
58
59 AudioStream::~AudioStream()
60 {
61         __focusAquired = false;
62
63         unprepareAudioOut();
64         destroyAudioHandle();
65         destroySoundStreamInfo();
66 }
67
68 void AudioStream::destroySoundStreamInfo()
69 {
70         int ret = sound_manager_destroy_stream_information(__streamInfo);
71         if (SOUND_MANAGER_ERROR_NONE != ret) {
72                 SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to destroy stream info");
73         }
74         __streamInfo = nullptr;
75         __focusAquired = false;
76 }
77
78 int AudioStream::setAudioFormat(ttse_audio_type_e type, int rate)
79 {
80         if (__audioType == type && __audioRate == rate) {
81                 return TTSD_ERROR_NONE;
82         }
83
84         SLOG(LOG_INFO, tts_tag(), "[AudioStream] Audio info is different. type:(%d)/(%d), rate:(%d)/(%d)",
85                         __audioType, type, __audioRate, rate);
86
87         destroyAudioHandle();
88         if (TTSD_ERROR_NONE != createAudioHandle(type, rate)) {
89                 return TTSD_ERROR_OPERATION_FAILED;
90         }
91
92         if (__focusAquired) {
93                 acquireSoundFocus();
94         }
95
96         __state = AUDIO_STATE_READY;
97         return TTSD_ERROR_NONE;
98 }
99
100 int AudioStream::acquireSoundFocus()
101 {
102         int ret = sound_manager_acquire_focus(__streamInfo, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, nullptr);
103         if (SOUND_MANAGER_ERROR_NONE != ret) {
104                 SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to acquire focus. ret(%s)", get_error_message(ret));
105         } else {
106                 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Success to acquire focus");
107         }
108
109         ret = audio_out_set_sound_stream_info(__audioHandle, __streamInfo);
110         if (AUDIO_IO_ERROR_NONE != ret) {
111                 SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to set stream info. ret(%s)", get_error_message(ret));
112                 return TTSD_ERROR_OPERATION_FAILED;
113         }
114
115         __focusAquired = true;
116         return TTSD_ERROR_NONE;
117 }
118
119 int AudioStream::releaseSoundFocus()
120 {
121         sound_stream_focus_state_e focusState = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
122         int ret = sound_manager_get_focus_state(__streamInfo, &focusState, nullptr);
123         if (SOUND_MANAGER_ERROR_NONE != ret) {
124                 SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to get focus state: %d", ret);
125         }
126
127         if (SOUND_STREAM_FOCUS_STATE_ACQUIRED != focusState) {
128                 SLOG(LOG_INFO, tts_tag(), "[AudioStream] This handle has no focus");
129                 return TTSD_ERROR_NONE;
130         }
131
132         ret = sound_manager_release_focus(__streamInfo, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, nullptr);
133         if (SOUND_MANAGER_ERROR_NONE != ret) {
134                 SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to release focus");
135                 return TTSD_ERROR_OPERATION_FAILED;
136         }
137
138         __focusAquired = false;
139         return TTSD_ERROR_NONE;
140 }
141
142 int AudioStream::prepareAudioOut()
143 {
144         if (__prepared) {
145                 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Audio is already prepared");
146                 return TTSD_ERROR_NONE;
147         }
148
149         int ret = audio_out_prepare(__audioHandle);
150         if (AUDIO_IO_ERROR_NONE != ret) {
151                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to prepare audio : %d", ret);
152                 return TTSD_ERROR_OPERATION_FAILED;
153         }
154
155         __prepared = true;
156         __state = AUDIO_STATE_PLAY;
157         return TTSD_ERROR_NONE;
158 }
159
160 int AudioStream::playAudioData(char* buffer, unsigned int length)
161 {
162         if (false == __prepared) {
163                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Audio is not prepared");
164                 return TTSD_ERROR_OPERATION_FAILED;
165         }
166
167         int ret = audio_out_write(__audioHandle, static_cast<void*>(buffer), length);
168         if (0 > ret) {
169                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to audio write - %d", ret);
170                 return TTSD_ERROR_OPERATION_FAILED;
171         }
172
173         return TTSD_ERROR_NONE;
174 }
175
176 int AudioStream::unprepareAudioOut()
177 {
178         if (false == __prepared) {
179                 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Audio is not prepared");
180                 return TTSD_ERROR_NONE;
181         }
182
183         int ret = audio_out_unprepare(__audioHandle);
184         if (AUDIO_IO_ERROR_NONE != ret) {
185                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to prepare audio : %d", ret);
186                 return TTSD_ERROR_OPERATION_FAILED;
187         }
188
189         __prepared = false;
190         __state = AUDIO_STATE_READY;
191         return TTSD_ERROR_NONE;
192 }
193
194 void AudioStream::waitForPlay()
195 {
196         __state = AUDIO_STATE_WAIT_FOR_PLAYING;
197 }
198
199 AudioStream::AudioState AudioStream::getState()
200 {
201         return __state;
202 }
203
204 int AudioStream::createAudioHandle(ttse_audio_type_e type, int rate)
205 {
206         audio_sample_type_e sample_type;
207         if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
208                 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
209         } else {
210                 sample_type = AUDIO_SAMPLE_TYPE_U8;
211         }
212
213         int ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &__audioHandle);
214         if (AUDIO_IO_ERROR_NONE != ret) {
215                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create audio out handle. ret(%s)", get_error_message(ret));
216                 return TTSD_ERROR_OPERATION_FAILED;
217         }
218
219         __audioType = type;
220         __audioRate = rate;
221         __state = AUDIO_STATE_READY;
222
223         SLOG(LOG_INFO, tts_tag(), "[AudioStream] Create audio");
224         return TTSD_ERROR_NONE;
225 }
226
227 void AudioStream::destroyAudioHandle()
228 {
229         if (nullptr == __audioHandle) {
230                 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Audio handle is not exist");
231                 return;
232         }
233
234         int ret = audio_out_destroy(__audioHandle);
235         if (AUDIO_IO_ERROR_NONE != ret) {
236                 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to destroy audio out handle. ret(%s)", get_error_message(ret));
237         } else {
238                 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Destroy audio");
239         }
240
241         __state = AUDIO_STATE_NONE;
242 }
243
244 void AudioStream::__focusStateChangedCallback(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask,
245                 sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason_for_change,
246                 int sound_behavior, const char *extra_info, void *user_data)
247 {
248         SLOG(LOG_INFO, tts_tag(), "[AudioStream] focus state changed to (%d) with reason(%d) and extra info(%s)",
249                         (int)focus_state, (int)reason_for_change, extra_info);
250 }