static const char* FOCUS_SERVER_READY = "/tmp/.focus_server_ready";
-AudioStream::AudioStream()
+AudioStream::AudioStream():
+ __audioHandle(nullptr),
+ __audioType(TTSE_AUDIO_TYPE_RAW_S16),
+ __audioRate(16000),
+ __prepared(false),
+ __streamInfo(nullptr),
+ __focusAquired(false),
+ __state(AUDIO_STATE_NONE)
{
- __prepared = false;
- __focusAquired = false;
-
createSoundStreamInfo();
- createAudioHandle(TTSE_AUDIO_TYPE_RAW_S16, 16000);
-}
-
-void AudioStream::createSoundStreamInfo()
-{
- int cnt = 0;
- while (1) {
- if (0 == access(FOCUS_SERVER_READY, F_OK)) {
- SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is available");
- break;
- } else {
- if (0 == cnt++ % 10)
- SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is not available");
- usleep(50000);
- }
- }
-
- int ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __focusStateChangedCallback, this, &__streamInfo);
- if (SOUND_MANAGER_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create stream info");
- return;
- }
-
- __focusAquired = false;
- SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Create stream info");
+ createAudioHandle(__audioType, __audioRate);
}
AudioStream::~AudioStream()
int AudioStream::acquireSoundFocus()
{
+ if (isAudioHandleValid() == false) {
+ int ret = createAudioHandle(__audioType, __audioRate);
+ if (TTSD_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create the audio handle. ret(%s)", get_error_message(ret));
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ if (isStreamInfoValid() == false) {
+ int ret = createSoundStreamInfo();
+ if (TTSD_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create the stream info. ret(%s)", get_error_message(ret));
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
int ret = sound_manager_acquire_focus(__streamInfo, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, nullptr);
if (SOUND_MANAGER_ERROR_NONE != ret) {
SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to acquire focus. ret(%s)", get_error_message(ret));
int AudioStream::releaseSoundFocus()
{
- sound_stream_focus_state_e focusState = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
+ if (isStreamInfoValid() == false) {
+ SLOG(LOG_INFO, tts_tag(), "[AudioStream] Handle is not created. No focus acquired");
+ return TTSD_ERROR_NONE;
+ }
+
+ sound_stream_focus_state_e focusState = SOUND_STREAM_FOCUS_STATE_RELEASED;
int ret = sound_manager_get_focus_state(__streamInfo, &focusState, nullptr);
if (SOUND_MANAGER_ERROR_NONE != ret) {
SLOG(LOG_WARN, tts_tag(), "[AudioStream] Fail to get focus state: %d", ret);
return TTSD_ERROR_NONE;
}
+ if (isAudioHandleValid() == false) {
+ int ret = createAudioHandle(__audioType, __audioRate);
+ if (TTSD_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create the audio handle. ret(%s)", get_error_message(ret));
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
int ret = audio_out_prepare(__audioHandle);
if (AUDIO_IO_ERROR_NONE != ret) {
SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to prepare audio : %d", ret);
return TTSD_ERROR_OPERATION_FAILED;
}
+ if (isAudioHandleValid() == false) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Handle is not created");
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+
int ret = audio_out_write(__audioHandle, static_cast<void*>(buffer), length);
if (0 > ret) {
SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to audio write - %d", ret);
return TTSD_ERROR_NONE;
}
+ if (isAudioHandleValid() == false) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Handle is not created. No prepared handle.");
+ return TTSD_ERROR_NONE;
+ }
+
int ret = audio_out_unprepare(__audioHandle);
if (AUDIO_IO_ERROR_NONE != ret) {
SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to prepare audio : %d", ret);
return TTSD_ERROR_NONE;
}
+bool AudioStream::isAudioHandleValid()
+{
+ if (__audioHandle == nullptr) {
+ return false;
+ }
+
+ return true;
+}
+
+bool AudioStream::isStreamInfoValid()
+{
+ if (__streamInfo == nullptr) {
+ return false;
+ }
+
+ return true;
+}
+
void AudioStream::waitForPlay()
{
__state = AUDIO_STATE_WAIT_FOR_PLAYING;
__state = AUDIO_STATE_NONE;
}
+int AudioStream::createSoundStreamInfo()
+{
+ int cnt = 0;
+ while (1) {
+ if (0 == access(FOCUS_SERVER_READY, F_OK)) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is available");
+ break;
+ } else {
+ if (0 == cnt++ % 10)
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] focus server is not available");
+ usleep(50000);
+ }
+ }
+
+ int ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __focusStateChangedCallback, this, &__streamInfo);
+ if (SOUND_MANAGER_ERROR_NONE != ret || __streamInfo == nullptr) {
+ SLOG(LOG_ERROR, tts_tag(), "[AudioStream] Fail to create stream info(%d/%s)", ret, get_error_message(ret));
+ __streamInfo = nullptr;
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+
+ __focusAquired = false;
+ SLOG(LOG_DEBUG, tts_tag(), "[AudioStream] Create stream info");
+ return TTSD_ERROR_NONE;
+}
+
void AudioStream::__focusStateChangedCallback(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask,
sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason_for_change,
int sound_behavior, const char *extra_info, void *user_data)
}
BackgroundVolume::BackgroundVolume(long long int duckingDuration):
- __duckingDuration(duckingDuration), __mediaStream(nullptr), __notificationStream(nullptr), __alarmStream(nullptr),
- __postponedRecoverTimer(nullptr), __postponedModifyTimer(nullptr)
+ __duckingDuration(duckingDuration),
+ __mediaStream(nullptr),
+ __notificationStream(nullptr),
+ __alarmStream(nullptr),
+ __volumeRatio(0.0),
+ __isVolumeDucked(false),
+ __changeVolumeTime(chrono::steady_clock::now()),
+ __postponedRecoverTimer(nullptr),
+ __postponedModifyTimer(nullptr)
{
- int ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, nullptr, &__mediaStream);
- if (SOUND_MANAGER_ERROR_NONE != ret)
- SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for type media, ret(%d)", ret);
-
- ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, nullptr, &__notificationStream);
- if (SOUND_MANAGER_ERROR_NONE != ret)
- SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for notification type, ret(%d)", ret);
-
- ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, nullptr, &__alarmStream);
- if (SOUND_MANAGER_ERROR_NONE != ret)
- SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for alarm type, ret(%d)", ret);
-
- __isVolumeDucked = false;
- __volumeRatio = 0.0;
+ int ret = createHandles();
+ if (TTSD_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, tts_tag(), "[BackgroundVolume] Fail to create handles.");
+ }
}
BackgroundVolume::~BackgroundVolume()
void BackgroundVolume::activateDuckingAll(unsigned int duration, double ratio)
{
+ if (false == isDuckingHandleValid()) {
+ SLOG(LOG_WARN, tts_tag(), "[BackgroundVolume] There are some invalid handles. Try to recreate the hnadles");
+ int ret = createHandles();
+ if (TTSD_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, tts_tag(), "[BackgroundVolume] Fail to create handles. Skip ducking activation.");
+ return;
+ }
+ }
+
activateDucking(SOUND_STREAM_TYPE_MEDIA, duration, ratio);
activateDucking(SOUND_STREAM_TYPE_NOTIFICATION, duration, ratio);
activateDucking(SOUND_STREAM_TYPE_ALARM, duration, ratio);
void BackgroundVolume::deactivateDuckingAll()
{
+ if (false == isDuckingHandleValid()) {
+ SLOG(LOG_WARN, tts_tag(), "[BackgroundVolume] There are some invalid handles. Skip ducking deactivation.");
+ return;
+ }
+
deactivateDucking(SOUND_STREAM_TYPE_MEDIA);
deactivateDucking(SOUND_STREAM_TYPE_NOTIFICATION);
deactivateDucking(SOUND_STREAM_TYPE_ALARM);
}
}
+int BackgroundVolume::createHandles()
+{
+ SLOG(LOG_INFO, tts_tag(), "[BackgroundVolume] Create ducking handles");
+
+ if (nullptr == __mediaStream) {
+ int ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, nullptr, &__mediaStream);
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for type media, ret(%d/%s)", ret, get_error_message(ret));
+ __mediaStream = nullptr;
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ if (nullptr == __notificationStream) {
+ int ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, nullptr, &__notificationStream);
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for notification type, ret(%d/%s)", ret, get_error_message(ret));
+ __notificationStream = nullptr;
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ if (nullptr == __alarmStream) {
+ int ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, nullptr, &__alarmStream);
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[BackgroundVolume] Fail to create stream ducking for alarm type, ret(%d/%s)", ret, get_error_message(ret));
+ __alarmStream = nullptr;
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ return TTSD_ERROR_NONE;
+}
+
+bool BackgroundVolume::isDuckingHandleValid()
+{
+ if (__mediaStream == nullptr || __notificationStream == nullptr || __alarmStream == nullptr) {
+ return false;
+ }
+
+ return true;
+}
+
sound_stream_ducking_h BackgroundVolume::getStreamDuckingHandle(sound_stream_type_e type)
{
switch (type)