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.
16 #include "ttsd_main.h"
18 #include "AudioStream.h"
23 static const char* FOCUS_SERVER_READY = "/tmp/.sound_server_ready";
26 AudioStream::AudioStream()
29 __focusAquired = false;
31 createSoundStreamInfo();
32 createAudioHandle(TTSE_AUDIO_TYPE_RAW_S16, 16000);
35 void AudioStream::createSoundStreamInfo()
39 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
40 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is available");
44 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is not available");
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");
55 __focusAquired = false;
56 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Create stream info");
59 AudioStream::~AudioStream()
61 __focusAquired = false;
65 destroySoundStreamInfo();
68 void AudioStream::destroySoundStreamInfo()
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");
74 __streamInfo = nullptr;
75 __focusAquired = false;
78 int AudioStream::setAudioFormat(ttse_audio_type_e type, int rate)
80 if (__audioType == type && __audioRate == rate) {
81 return TTSD_ERROR_NONE;
84 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Audio info is different. type:(%d)/(%d), rate:(%d)/(%d)",
85 __audioType, type, __audioRate, rate);
88 if (TTSD_ERROR_NONE != createAudioHandle(type, rate)) {
89 return TTSD_ERROR_OPERATION_FAILED;
96 __state = AUDIO_STATE_READY;
97 return TTSD_ERROR_NONE;
100 int AudioStream::acquireSoundFocus()
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));
106 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Success to acquire focus");
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;
115 __focusAquired = true;
116 return TTSD_ERROR_NONE;
119 int AudioStream::releaseSoundFocus()
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);
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;
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;
138 __focusAquired = false;
139 return TTSD_ERROR_NONE;
142 int AudioStream::prepareAudioOut()
145 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Audio is already prepared");
146 return TTSD_ERROR_NONE;
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;
156 __state = AUDIO_STATE_PLAY;
157 return TTSD_ERROR_NONE;
160 int AudioStream::playAudioData(char* buffer, unsigned int length)
162 if (false == __prepared) {
163 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Audio is not prepared");
164 return TTSD_ERROR_OPERATION_FAILED;
167 int ret = audio_out_write(__audioHandle, static_cast<void*>(buffer), length);
169 SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to audio write - %d", ret);
170 return TTSD_ERROR_OPERATION_FAILED;
173 return TTSD_ERROR_NONE;
176 int AudioStream::unprepareAudioOut()
178 if (false == __prepared) {
179 SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Audio is not prepared");
180 return TTSD_ERROR_NONE;
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;
190 __state = AUDIO_STATE_READY;
191 return TTSD_ERROR_NONE;
194 void AudioStream::waitForPlay()
196 __state = AUDIO_STATE_WAIT_FOR_PLAYING;
199 AudioStream::AudioState AudioStream::getState()
204 int AudioStream::createAudioHandle(ttse_audio_type_e type, int rate)
206 audio_sample_type_e sample_type;
207 if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
208 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
210 sample_type = AUDIO_SAMPLE_TYPE_U8;
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;
221 __state = AUDIO_STATE_READY;
223 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Create audio");
224 return TTSD_ERROR_NONE;
227 void AudioStream::destroyAudioHandle()
229 if (nullptr == __audioHandle) {
230 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Audio handle is not exist");
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));
238 SLOG(LOG_INFO, tts_tag(), "[AudioStream] Destroy audio");
241 __state = AUDIO_STATE_NONE;
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)
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);