Stop recording when sound focus is acquired by other process
authorJi-hoon Lee <dalton.lee@samsung.com>
Mon, 9 Sep 2019 05:36:50 +0000 (14:36 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Mon, 9 Sep 2019 05:36:53 +0000 (14:36 +0900)
Change-Id: I2f0f62a09ad3aab531bd3e34a72d097882b37425

plugins/wakeup-manager/inc/wakeup_audio_manager.h
plugins/wakeup-manager/src/wakeup_audio_manager.cpp
plugins/wakeup-manager/src/wakeup_manager.cpp

index fdff003..2b38a77 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <audio_io.h>
 #include <sound_manager.h>
+#include <sound_manager_internal.h>
 
 namespace multiassistant
 {
@@ -65,11 +66,13 @@ public:
        int initialize();
        int deinitialize();
 
+       void sound_focus_changed();
+
        void subscribe(IAudioEventObserver *observer);
        void unsubscribe(IAudioEventObserver *observer);
 
-       void start_recording();
-       void stop_recording();
+       void start_recording(bool proactive);
+       void stop_recording(bool proactive);
 
        void set_recording_session(recording_session session);
 
@@ -88,7 +91,6 @@ public:
 
        void change_system_volume();
        void recover_system_volume();
-
 private:
        void add_audio_data(wakeup_speech_data& data, long time);
        void notify_audio_data_recording(long time, void* data, int len);
@@ -96,6 +98,10 @@ private:
        void streaming_previous_audio_data_thread_func();
        void streaming_audio_data_thread_func(long start_time);
 
+       int mSoundFocusWatchId{0};
+       bool mRecordingRequired{false};
+       bool mIsRecording{false};
+
        vector<IAudioEventObserver*> mObservers;
 
        thread mStreamingThread;
index 327190e..2b6ae0f 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <algorithm>
 
+#include <Ecore.h>
+
 namespace multiassistant
 {
 namespace wakeup
@@ -37,16 +39,63 @@ CAudioManager::CAudioManager(IAudioEventObserver *observer) : CAudioManager()
        subscribe(observer);
 }
 
+void recording_focus_state_watch_cb(int id, sound_stream_focus_mask_e focus_mask,
+       sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason,
+       const char *extra_info, void *user_data)
+{
+       MWR_LOGD("[Recorder] focus_mask : %d, focus_state : %d, reason : %d, [%s]",
+               focus_mask, focus_state, reason, extra_info);
+
+       if (nullptr == user_data) return;
+
+       /* The API description states that calling sound_manager_get_current_recording_focus()
+               function inside sound_stream_focus_state_watch_cb() function is prohibited */
+       ecore_main_loop_thread_safe_call_async(
+               [](void* data) {
+                       CAudioManager *manager = static_cast<CAudioManager*>(data);
+                       if (manager) {
+                               manager->sound_focus_changed();
+                       }
+               }, user_data);
+}
+
 int CAudioManager::initialize(void)
 {
+       sound_manager_add_focus_state_watch_cb(SOUND_STREAM_FOCUS_FOR_RECORDING,
+               recording_focus_state_watch_cb, this, &mSoundFocusWatchId);
        return 0;
 }
 
 int CAudioManager::deinitialize(void)
 {
+       sound_manager_remove_focus_state_watch_cb(mSoundFocusWatchId);
+
        return 0;
 }
 
+void CAudioManager::sound_focus_changed()
+{
+       sound_stream_focus_change_reason_e acquired_by;
+       int sound_behavior;
+       char* extra_info;
+       int focus = sound_manager_get_current_recording_focus(&acquired_by, &sound_behavior, &extra_info);
+       MWR_LOGD("[Recorder] sound focus has changed : %d %d %d %s", focus,
+               (SOUND_MANAGER_ERROR_NO_DATA != focus ? acquired_by : -1),
+               (SOUND_MANAGER_ERROR_NO_DATA != focus ? sound_behavior : -1),
+               (SOUND_MANAGER_ERROR_NO_DATA != focus ? extra_info : ""));
+       if (SOUND_MANAGER_ERROR_NO_DATA == focus) {
+               if (mRecordingRequired && !mIsRecording) {
+                       MWR_LOGD("[Recorder] Currently no other process has acquired sound focus, start recording");
+                       start_recording(false);
+               }
+       } else {
+               if (mIsRecording) {
+                       MWR_LOGW("[Recorder] Sound focus acquired by other process, stop recording");
+                       stop_recording(false);
+               }
+       }
+}
+
 void CAudioManager::subscribe(IAudioEventObserver *observer)
 {
        mObservers.push_back(observer);
@@ -60,16 +109,34 @@ void CAudioManager::unsubscribe(IAudioEventObserver *observer)
        }
 }
 
-void CAudioManager::stop_recording()
+void CAudioManager::stop_recording(bool proactive)
 {
        dependency_resolver_stop_recording();
+       if (proactive) {
+               mRecordingRequired = false;
+       }
+       mIsRecording = false;
 }
 
-void CAudioManager::start_recording()
+void CAudioManager::start_recording(bool proactive)
 {
-       stop_recording();
+       if (mIsRecording) {
+               stop_recording(false);
+       }
+       if (proactive) {
+               mRecordingRequired = true;
+       }
 
-       dependency_resolver_start_recording();
+       sound_stream_focus_change_reason_e acquired_by;
+       int sound_behavior;
+       char* extra_info;
+       if (SOUND_MANAGER_ERROR_NO_DATA == sound_manager_get_current_recording_focus(&acquired_by, &sound_behavior, &extra_info)) {
+               MWR_LOGD("[Recorder] Currently no other process has acquired sound focus, start recording");
+               dependency_resolver_start_recording();
+               mIsRecording = true;
+       } else {
+               MWR_LOGW("[Recorder] Currently sound focus is acquired by other process, skip recording");
+       }
 }
 
 void CAudioManager::set_recording_session(recording_session session)
index 4ef1b30..c765d16 100644 (file)
@@ -163,7 +163,7 @@ bool CWakeupManager::activate(void)
        change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
        if (mWakeupEngineManager.get_audio_data_required()) {
                mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
-               mAudioManager.start_recording();
+               mAudioManager.start_recording(true);
        }
 
        MWR_LOGD("[END]");
@@ -177,7 +177,7 @@ bool CWakeupManager::deactivate(void)
        if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
                return false;
 
-       mAudioManager.stop_recording();
+       mAudioManager.stop_recording(true);
        change_manager_state(WAKEUP_MANAGER_STATE_INACTIVE);
 
        MWR_LOGD("[END]");
@@ -382,7 +382,7 @@ bool CWakeupManager::process_event(ma_plugin_event_e event, void* data, int len)
        // LOCK REQUIRED
        if (MA_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) {
                if (mVoiceKeyPressed != true) {
-                       mAudioManager.stop_recording();
+                       mAudioManager.stop_recording(true);
 
                        stop_streaming_utterance_data();
                        stop_streaming_previous_utterance_data();
@@ -395,7 +395,7 @@ bool CWakeupManager::process_event(ma_plugin_event_e event, void* data, int len)
 
                        /* Start recorder thread using appropriate recording device */
                        mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
-                       mAudioManager.start_recording();
+                       mAudioManager.start_recording(true);
 
                        /* Wakeup default assistant */
                        /* TODO: apply conversation timeout for selecting assistant here */
@@ -423,11 +423,11 @@ bool CWakeupManager::process_event(ma_plugin_event_e event, void* data, int len)
 
                        if (mWakeupEngineManager.get_audio_data_required()) {
                                /* Restart recorder thread using appropriate recording device */
-                               mAudioManager.stop_recording();
+                               mAudioManager.stop_recording(true);
                                mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
-                               mAudioManager.start_recording();
+                               mAudioManager.start_recording(true);
                        } else {
-                               mAudioManager.stop_recording();
+                               mAudioManager.stop_recording(true);
                        }
                }
        } else if (MA_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
@@ -557,11 +557,11 @@ bool CWakeupManager::start_streaming_follow_up_data()
        mStreamingMode = STREAMING_MODE::FOLLOW_UP;
 
        /* For the follow up streaming, audio data should be recorded from now on */
-       mAudioManager.stop_recording();
+       mAudioManager.stop_recording(true);
        mAudioManager.clear_audio_data();
        change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
        mAudioManager.set_recording_session(RECORDING_SESSION_FOLLOW_UP);
-       mAudioManager.start_recording();
+       mAudioManager.start_recording(true);
 
        mAudioManager.start_streaming_follow_up_data();
 
@@ -598,10 +598,10 @@ bool CWakeupManager::stop_streaming_follow_up_data()
 
        mStreamingMode = STREAMING_MODE::NONE;
 
-       mAudioManager.stop_recording();
+       mAudioManager.stop_recording(true);
        mAudioManager.clear_audio_data();
        mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
-       mAudioManager.start_recording();
+       mAudioManager.start_recording(true);
 
        MWR_LOGD("[END]");
        return true;
@@ -750,11 +750,11 @@ bool CWakeupManager::CEngineEventObserver::on_audio_data_require_status(string e
                if (engine_manager->get_audio_data_required()) {
                        if (mWakeupManager->get_voice_key_pressed() != true) {
                                audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
-                               audio_manager->start_recording();
+                               audio_manager->start_recording(true);
                        }
                } else {
                        if (mWakeupManager->get_voice_key_pressed() != true) {
-                               audio_manager->stop_recording();
+                               audio_manager->stop_recording(true);
                        }
                }
        }