2 * Copyright 2018-2019 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
17 #include "wakeup_manager.h"
18 #include "wakeup_manager_main.h"
19 #include "wakeup_policy_default.h"
20 #include "wakeup_policy_external.h"
21 #include "dependency_resolver.h"
26 #include <boost/optional.hpp>
28 namespace multiassistant
33 static bool check_language_valid(string language)
36 if (0 == language.length()) {
42 static bool initialize_wakeup_event_info(mas_wakeup_event_info* wakeup_info)
48 wakeup_info->wakeup_appid = nullptr;
49 wakeup_info->wakeup_word = nullptr;
50 wakeup_info->wakeup_language = nullptr;
51 wakeup_info->wakeup_voice_id = nullptr;
52 wakeup_info->wakeup_engine = nullptr;
53 wakeup_info->wakeup_confidence_score = 0.0f;
55 wakeup_info->wakeup_start_time = 0;
56 wakeup_info->wakeup_end_time = 0L;
57 wakeup_info->wakeup_time_valid = false;
59 wakeup_info->extra_data = nullptr;
60 wakeup_info->extra_data_length = 0;
61 wakeup_info->extra_data_description = nullptr;
66 CWakeupManager::CWakeupManager(IWakeupEventObserver* wakeup_observer, ISettingValueObserver* setting_observer)
68 initialize_wakeup_event_info(&mLastWakeupEventInfo);
70 if (wakeup_observer) {
71 subscribe_wakeup_observer(wakeup_observer);
73 if (setting_observer) {
74 subscribe_setting_observer(setting_observer);
78 CWakeupManager::~CWakeupManager()
80 MWR_LOGI("Wakeup Manager is now being destroyed");
83 void CWakeupManager::initialize_wakeup_policy()
85 mWakeupPolicy.reset(new CWakeupPolicyExternal{&mPolicyEventObserver});
86 if (nullptr == mWakeupPolicy || !(mWakeupPolicy->valid())) {
87 mWakeupPolicy.reset(new CWakeupPolicyDefault{&mPolicyEventObserver});
89 /* Default Policy specific initialization */
90 CWakeupPolicyDefault *policy =
91 dynamic_cast<CWakeupPolicyDefault*>(mWakeupPolicy.get());
95 policy->set_delay(mWakeupSettings.get_wakeup_policy_delay());
96 MWR_LOGD("Setting Delay : %f", mWakeupSettings.get_wakeup_policy_delay());
97 for (const auto& assistant : mWakeupSettings.get_wakeup_policy_priority()) {
98 policy->set_assistant_priority(assistant, ++priority);
99 MWR_LOGD("Setting Priority : %d %s", priority, assistant.c_str());
105 bool CWakeupManager::initialize()
108 std::cerr << "WakeupManager Initialize" << std::endl;
110 mPolicyEventObserver.set_wakeup_manager(this);
111 mEngineEventObserver.set_wakeup_manager(this);
112 mAudioEventObserver.set_wakeup_manager(this);
113 mSettingsEventObserver.set_wakeup_manager(this);
115 mWakeupSettings.subscribe(&mSettingsEventObserver);
116 mWakeupSettings.initialize();
118 mAudioEventObserver.set_wakeup_engine_manager(&mWakeupEngineManager);
119 mAudioManager.subscribe(&mAudioEventObserver);
120 mAudioManager.initialize();
122 mWakeupEngineManager.subscribe(&mEngineEventObserver);
123 mWakeupEngineManager.initialize();
125 mAssistantConfigManager.initialize();
127 mas_dependency_plugin_proxy_interface interface;
128 interface.process_event = wakeup_manager_process_plugin_event;
129 interface.feed_audio_data = wakeup_manager_feed_audio_data;
130 interface.send_command = wakeup_manager_set_dependency_module_command;
131 interface.wakeup_assistant = wakeup_manager_wakeup_assistant;
133 dependency_resolver_initialize(interface);
135 initialize_wakeup_policy();
136 start_periodic_monitor_timer();
142 bool CWakeupManager::deinitialize()
145 std::cerr << "WakeupManager Deinitialize" << std::endl;
147 stop_periodic_monitor_timer();
148 stop_streaming_duration_timer();
150 dependency_resolver_deinitialize();
152 mAssistantConfigManager.deinitialize();
154 mWakeupEngineManager.unsubscribe(&mEngineEventObserver);
155 mWakeupEngineManager.deinitialize();
157 mAudioManager.unsubscribe(&mAudioEventObserver);
158 mAudioManager.deinitialize();
160 mWakeupSettings.deinitialize();
161 mAssistantLanguageInfo.clear();
167 void CWakeupManager::subscribe_wakeup_observer(IWakeupEventObserver *observer)
169 mWakeupObservers.push_back(observer);
172 void CWakeupManager::unsubscribe_wakeup_observer(IWakeupEventObserver *observer)
174 auto iter = find(mWakeupObservers.begin(), mWakeupObservers.end(), observer);
175 if (iter != mWakeupObservers.end()) {
176 mWakeupObservers.erase(iter);
180 void CWakeupManager::subscribe_setting_observer(ISettingValueObserver* observer)
182 mSettingObservers.push_back(observer);
185 void CWakeupManager::unsubscribe_setting_observer(ISettingValueObserver* observer)
187 auto iter = find(mSettingObservers.begin(), mSettingObservers.end(), observer);
188 if (iter != mSettingObservers.end()) {
189 mSettingObservers.erase(iter);
193 bool CWakeupManager::activate(void)
197 if (WAKEUP_MANAGER_STATE_INACTIVE != mWakeupManagerState)
200 /* Activate assistants that supports current voice input language */
201 set_language(mWakeupSettings.get_current_language());
203 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
204 if (mWakeupEngineManager.get_audio_data_required()) {
205 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
206 mAudioManager.start_recording(true);
213 bool CWakeupManager::deactivate(void)
217 if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
220 mAudioManager.stop_recording(true);
221 mRecordingByVoiceKey = false;
222 change_manager_state(WAKEUP_MANAGER_STATE_INACTIVE);
224 stop_streaming_utterance_data();
225 stop_streaming_previous_utterance_data();
226 stop_streaming_follow_up_data();
232 bool CWakeupManager::add_assistant_language(string appid, string language)
236 for (auto& info : mAssistantLanguageInfo) {
237 if(0 == info.appid.compare(appid)) {
238 info.languageList.push_back(language);
243 AssistantLanguageInfo info;
245 info.languageList.push_back(language);
246 mAssistantLanguageInfo.push_back(info);
248 if (0 == mCurrentLanguage.compare(language)) {
249 mAssistantSupportsCurrentLanguage[appid] = true;
250 if (true == mAssistantEnabled[appid]) {
251 mWakeupEngineManager.set_assistant_activated(appid, true);
258 bool CWakeupManager::add_assistant_wakeup_word(string appid, string wakeup_word, string language)
262 mWakeupEngineManager.engine_add_wakeup_word(appid, wakeup_word, language);
268 bool CWakeupManager::remove_assistant_wakeup_word(string appid, string wakeup_word, string language)
272 mWakeupEngineManager.engine_remove_wakeup_word(appid, wakeup_word, language);
278 bool CWakeupManager::add_assistant_wakeup_engine(string appid, string engine)
280 MWR_LOGI("[ENTER] %s %s", appid.c_str(), engine.c_str());
282 mWakeupEngineManager.engine_add_target_assistant(engine, appid);
288 bool CWakeupManager::set_assistant_language(string appid, string language)
290 MWR_LOGI("[ENTER] : %s, %s", appid.c_str(), language.c_str());
292 mWakeupEngineManager.set_assistant_language(appid, language);
293 mAssistantConfigManager.set_assistant_language(appid, language);
299 bool CWakeupManager::set_assistant_enabled(string appid, bool enabled)
303 mAssistantEnabled[appid] = enabled;
304 bool activated = enabled;
305 if (false == mAssistantSupportsCurrentLanguage[appid]) {
308 if (0 == appid.compare(mWakeupSettings.get_default_assistant_appid())) {
311 mWakeupEngineManager.set_assistant_activated(appid, activated);
317 bool CWakeupManager::set_default_assistant(string appid)
319 MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
321 /* Passing 'expected' as true since MAS is changing the default assistant config */
322 process_default_assistant_changed(appid, true);
324 mWakeupSettings.set_default_assistant_appid(appid);
329 bool CWakeupManager::process_default_assistant_changed(string appid, bool expected)
331 MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
333 if (mCurrentDefaultAssistant.compare(appid) == 0) {
334 MWR_LOGE("Default assistant appid not changed, ignoring...");
338 if (mWakeupManagerState == WAKEUP_MANAGER_STATE_UTTERANCE ||
339 mWakeupManagerState == WAKEUP_MANAGER_STATE_PROCESSING) {
341 stop_streaming_utterance_data();
342 stop_streaming_previous_utterance_data();
343 stop_streaming_follow_up_data();
345 mWakeupEngineManager.update_recognition_result(appid, MA_RECOGNITION_RESULT_EVENT_ERROR);
347 /* If this is an unexpected change, invalidate previous recognition process */
348 update_recognition_result(mCurrentDefaultAssistant, MA_RECOGNITION_RESULT_EVENT_ERROR);
352 /* Check if previous default assistant has to be deactivated */
353 bool activated = true;
354 if (false == mAssistantSupportsCurrentLanguage[mCurrentDefaultAssistant]) {
357 if (false == mAssistantEnabled[mCurrentDefaultAssistant]) {
360 mWakeupEngineManager.set_assistant_activated(mCurrentDefaultAssistant, activated);
362 /* New default assistant has to be activated no matter what */
363 mWakeupEngineManager.set_assistant_activated(appid, true);
365 mCurrentDefaultAssistant = appid;
371 string CWakeupManager::get_default_assistant()
373 return mWakeupSettings.get_default_assistant_appid();
376 bool CWakeupManager::get_assistant_enabled(string appid)
378 return mAssistantEnabled[appid];
381 bool CWakeupManager::set_language(string language)
384 MWR_LOGI("[ENTER] : %s", language.c_str());
386 if (check_language_valid(language)) {
387 mCurrentLanguage = language;
390 MWR_LOGE("[ERROR] Invalid language (%s)", language.c_str());
393 for (auto& info : mAssistantLanguageInfo) {
394 bool disable = false;
396 bool supported = false;
397 if (info.languageList.end() !=
398 find(info.languageList.begin(), info.languageList.end(), language)) {
401 mAssistantSupportsCurrentLanguage[info.appid] = supported;
402 /* Disable this assistant if language not supported */
403 if (!supported) disable = true;
405 /* If current language is not valid, assume all languages support it */
406 mAssistantSupportsCurrentLanguage[info.appid] = true;
409 if (false == mAssistantEnabled[info.appid]) {
412 if (0 == info.appid.compare(mWakeupSettings.get_default_assistant_appid())) {
413 /* Default Assistant should be activated no matter what */
416 mWakeupEngineManager.set_assistant_activated(info.appid, !disable);
417 std::string assistant_language;
418 int ret = mAssistantConfigManager.get_assistant_language(info.appid, assistant_language);
419 if (0 != ret || !check_language_valid(assistant_language)) {
420 mWakeupEngineManager.set_assistant_language(info.appid, language);
422 mWakeupEngineManager.set_assistant_language(info.appid, assistant_language);
430 bool CWakeupManager::get_recording_by_voice_key()
432 return mRecordingByVoiceKey;
435 void CWakeupManager::set_recording_by_voice_key(bool recording)
437 mRecordingByVoiceKey = recording;
440 STREAMING_MODE CWakeupManager::get_streaming_mode()
442 return mStreamingMode;
445 bool CWakeupManager::set_streaming_mode(STREAMING_MODE mode)
447 lock_guard<mutex> lock(mMutex);
448 mStreamingMode = mode;
452 bool CWakeupManager::change_manager_state(wakeup_manager_state_e state)
454 MWR_LOGI("[ENTER] : %d", state);
455 mWakeupManagerState = state;
456 mWakeupEngineManager.update_manager_state(state);
457 for (const auto& observer : mWakeupObservers) {
458 observer->on_wakeup_service_state_changed((ma_service_state_e)state);
463 wakeup_manager_state_e CWakeupManager::get_manager_state()
465 return mWakeupManagerState;
468 bool CWakeupManager::update_voice_feedback_state(string appid, bool state)
473 if (WAKEUP_MANAGER_STATE_LISTENING == mWakeupManagerState ||
474 WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState) {
475 change_manager_state(WAKEUP_MANAGER_STATE_VOICE_FEEDBACK);
478 if (WAKEUP_MANAGER_STATE_VOICE_FEEDBACK == mWakeupManagerState) {
479 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
487 bool CWakeupManager::set_assistant_specific_command(string appid, string command)
492 static const string voice_key_pressed{"voice_key_pressed"};
493 static const string voice_key_released{"voice_key_released"};
495 if (0 == command.compare(voice_key_pressed)) {
496 process_event(MA_PLUGIN_EVENT_VOICE_KEY_PRESSED, NULL, 0);
497 } else if (0 == command.compare(voice_key_released)) {
498 process_event(MA_PLUGIN_EVENT_VOICE_KEY_RELEASED, NULL, 0);
502 mWakeupEngineManager.engine_set_assistant_specific_command(appid, command);
508 bool CWakeupManager::set_background_volume(string appid, double ratio)
510 MWR_LOGD("[DEBUG] set background volume (%f)", ratio);
513 mAudioManager.set_background_volume(ratio);
517 bool CWakeupManager::update_recognition_result(string appid, int result)
521 stop_streaming_utterance_data();
522 stop_streaming_previous_utterance_data();
523 stop_streaming_follow_up_data();
525 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
526 mWakeupEngineManager.update_recognition_result(appid, result);
527 if (WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState ||
528 WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
529 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
535 static long long get_current_milliseconds_after_epoch()
537 auto now = chrono::steady_clock::now();
538 auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
539 /* number of milliseconds since the epoch of system_clock */
540 auto value = now_ms.time_since_epoch();
542 return value.count();
545 bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len)
547 MWR_LOGE("[ENTER] : %d", event);
548 if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
551 bool start_recording = false;
552 bool stop_recording = false;
554 boost::optional<ma_voice_key_status_e> next_voice_key_status;
555 if (MAS_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) {
556 if (STREAMING_MODE::FOLLOW_UP == mStreamingMode) {
557 MWR_LOGE("Voice key pressed, but currently streaming follow_up audio");
559 if (VOICE_KEY_SUPPORT_MODE_NONE != mCurrentVoiceKeySupportMode) {
560 start_recording = true;
563 next_voice_key_status = MA_VOICE_KEY_STATUS_PRESSED;
564 } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) {
565 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode ||
566 VOICE_KEY_SUPPORT_MODE_ALL == mCurrentVoiceKeySupportMode) {
567 stop_recording = true;
569 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH;
570 } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
571 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode) {
572 stop_recording = true;
574 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP;
577 if (start_recording) {
578 mRecordingByVoiceKey = true;
580 mAudioManager.stop_recording(true);
582 stop_streaming_utterance_data();
583 stop_streaming_previous_utterance_data();
584 stop_streaming_follow_up_data();
586 mAudioManager.clear_audio_data();
587 change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
589 /* Start recorder thread using appropriate recording device */
590 mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
591 mAudioManager.start_recording(true);
593 /* Wakeup default assistant */
594 /* TODO: apply conversation timeout for selecting assistant here */
595 mas_wakeup_event_info wakeup_info;
596 initialize_wakeup_event_info(&wakeup_info);
597 /* Make sure to use background data */
598 wakeup_info.wakeup_time_valid = true;
599 wakeup_info.wakeup_end_time = get_current_milliseconds_after_epoch();
600 wakeup_info.wakeup_engine = WAKEUP_ENGINE_VOICE_KEY;
602 std::string default_assistant_appid = mWakeupSettings.get_default_assistant_appid();
603 wakeup_info.wakeup_appid = default_assistant_appid.c_str();
604 MWR_LOGD("wakeup_appid : %s", wakeup_info.wakeup_appid);
606 set_last_wakeup_event_info(wakeup_info);
607 mWakeupEngineManager.set_selected_wakeup_info(wakeup_info);
608 for (const auto& observer : mWakeupObservers) {
609 observer->on_wakeup(wakeup_info);
612 if (stop_recording) {
613 mRecordingByVoiceKey = false;
615 stop_streaming_duration_timer();
616 mAudioManager.finalize_audio_data();
618 if (STREAMING_MODE::UTTERANCE == mStreamingMode) {
619 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
621 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
624 mAudioManager.stop_recording(true);
625 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
626 if (mWakeupEngineManager.get_audio_data_required()) {
627 /* Restart recorder thread using appropriate recording device */
628 mAudioManager.start_recording(true);
632 if (next_voice_key_status) {
633 for (const auto& observer : mWakeupObservers) {
634 observer->on_voice_key_status_changed(*next_voice_key_status);
642 vector<IWakeupEventObserver*> CWakeupManager::get_wakeup_observers()
644 return mWakeupObservers;
647 void CWakeupManager::set_last_wakeup_event_info(mas_wakeup_event_info wakeup_info)
649 mLastWakeupEventInfo = wakeup_info;
652 vector<ISettingValueObserver*> CWakeupManager::get_setting_observers()
654 return mSettingObservers;
657 static Eina_Bool streaming_duration_expired(void *data)
660 CWakeupManager *wakeup_manager = static_cast<CWakeupManager*>(data);
661 if (nullptr == wakeup_manager) return ECORE_CALLBACK_CANCEL;
663 wakeup_manager->set_streaming_duration_timer(nullptr);
665 CAudioManager *audio_manager = wakeup_manager->get_audio_manager();
666 CWakeupEngineManager *engine_manager = wakeup_manager->get_engine_manager();
668 if (nullptr == audio_manager) return ECORE_CALLBACK_CANCEL;
669 if (nullptr == engine_manager) return ECORE_CALLBACK_CANCEL;
671 switch(wakeup_manager->get_streaming_mode()) {
672 case STREAMING_MODE::UTTERANCE:
673 audio_manager->stop_streaming_current_utterance_data();
674 engine_manager->stop_streaming_current_utterance_data();
676 case STREAMING_MODE::PREVIOUS_UTTERANCE:
677 audio_manager->stop_streaming_previous_utterance_data();
679 case STREAMING_MODE::FOLLOW_UP:
680 audio_manager->stop_streaming_follow_up_data();
681 audio_manager->stop_recording(true);
682 wakeup_manager->set_recording_by_voice_key(false);
683 audio_manager->clear_audio_data();
687 wakeup_manager->set_streaming_mode(STREAMING_MODE::NONE);
689 if (WAKEUP_MANAGER_STATE_UTTERANCE == wakeup_manager->get_manager_state()) {
690 audio_manager->stop_recording(true);
691 wakeup_manager->set_recording_by_voice_key(false);
692 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
693 if (engine_manager->get_audio_data_required()) {
694 /* Restart recorder thread using appropriate recording device */
695 audio_manager->start_recording(true);
697 wakeup_manager->change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
700 return ECORE_CALLBACK_CANCEL;
703 bool CWakeupManager::start_streaming_utterance_data()
707 mAudioManager.stop_streaming_current_utterance_data();
708 mWakeupEngineManager.stop_streaming_current_utterance_data();
710 mStreamingMode = STREAMING_MODE::UTTERANCE;
712 bool streaming_by_manager = true;
713 if (false == mLastWakeupEventInfo.wakeup_time_valid) {
714 mWakeupEngineManager.start_streaming_current_utterance_data();
715 streaming_by_manager = false;
717 mAudioManager.start_streaming_current_utterance_data(mLastWakeupEventInfo.wakeup_end_time);
720 stop_streaming_duration_timer();
721 if (streaming_by_manager) {
722 start_streaming_duration_timer();
729 bool CWakeupManager::stop_streaming_utterance_data()
733 if (STREAMING_MODE::UTTERANCE != mStreamingMode) return false;
735 mAudioManager.stop_streaming_current_utterance_data();
736 mWakeupEngineManager.stop_streaming_current_utterance_data();
738 if (mStreamingDurationTimer) {
739 stop_streaming_duration_timer();
741 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
742 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
743 mAudioManager.stop_recording(true);
744 mRecordingByVoiceKey = false;
745 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
746 if (mWakeupEngineManager.get_audio_data_required()) {
747 /* Restart recorder thread using appropriate recording device */
748 mAudioManager.start_recording(true);
752 mStreamingMode = STREAMING_MODE::NONE;
758 bool CWakeupManager::start_streaming_follow_up_data()
762 mAudioManager.stop_streaming_follow_up_data();
763 mWakeupEngineManager.stop_streaming_current_utterance_data();
765 mStreamingMode = STREAMING_MODE::FOLLOW_UP;
767 /* For the follow up streaming, audio data should be recorded from now on */
768 mAudioManager.stop_recording(true);
769 mAudioManager.clear_audio_data();
770 change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
771 mAudioManager.set_recording_session(RECORDING_SESSION_FOLLOW_UP);
772 mAudioManager.start_recording(true);
774 mAudioManager.start_streaming_follow_up_data();
776 stop_streaming_duration_timer();
777 start_streaming_duration_timer();
783 bool CWakeupManager::stop_streaming_follow_up_data()
786 if (STREAMING_MODE::FOLLOW_UP != mStreamingMode) return false;
788 mAudioManager.stop_streaming_follow_up_data();
789 mWakeupEngineManager.stop_streaming_current_utterance_data();
791 if (mStreamingDurationTimer) {
792 stop_streaming_duration_timer();
795 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
796 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
797 mAudioManager.stop_recording(true);
798 mRecordingByVoiceKey = false;
799 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
800 if (mWakeupEngineManager.get_audio_data_required()) {
801 /* Restart recorder thread using appropriate recording device */
802 mAudioManager.start_recording(true);
806 mStreamingMode = STREAMING_MODE::NONE;
808 mAudioManager.clear_audio_data();
814 bool CWakeupManager::start_streaming_previous_utterance_data()
818 mAudioManager.stop_streaming_previous_utterance_data();
819 mWakeupEngineManager.stop_streaming_current_utterance_data();
821 mStreamingMode = STREAMING_MODE::PREVIOUS_UTTERANCE;
822 mAudioManager.start_streaming_previous_utterance_data();
824 stop_streaming_duration_timer();
825 start_streaming_duration_timer();
831 bool CWakeupManager::stop_streaming_previous_utterance_data()
834 if (STREAMING_MODE::PREVIOUS_UTTERANCE != mStreamingMode) return false;
836 mAudioManager.stop_streaming_previous_utterance_data();
837 mWakeupEngineManager.stop_streaming_current_utterance_data();
839 if (mStreamingDurationTimer) {
840 stop_streaming_duration_timer();
843 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
844 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
847 mStreamingMode = STREAMING_MODE::NONE;
853 bool CWakeupManager::get_audio_format(int* rate, int* channel, int* audio_type)
857 if (!audio_type || !rate || !channel) {
858 MWR_LOGE("[ERROR] Invalid parameter");
862 dependency_resolver_get_audio_format(rate, channel, audio_type);
864 MWR_LOGD("[END] rate(%d), channel(%d), audio_type(%d)", *rate, *channel, *audio_type);
868 bool CWakeupManager::get_audio_source_type(char** type)
873 MWR_LOGE("[ERROR] Invalid parameter");
877 dependency_resolver_get_audio_source_type(type);
879 MWR_LOGD("[END] type(%s)", *type);
883 bool CWakeupManager::set_wake_word_audio_require_flag(bool require)
887 mWakeupEngineManager.set_wake_word_audio_require_flag(require);
893 bool CWakeupManager::set_voice_key_tap_duration(float duration)
897 dependency_resolver_set_voice_key_tap_duration(duration);
903 bool CWakeupManager::unset_voice_key_tap_duration()
907 dependency_resolver_unset_voice_key_tap_duration();
913 bool CWakeupManager::set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE mode)
915 MWR_LOGI("Voice key support mode : %d", mode);
916 mCurrentVoiceKeySupportMode = mode;
920 CWakeupPolicy* CWakeupManager::get_wakeup_policy()
922 return mWakeupPolicy.get();
925 CWakeupEngineManager* CWakeupManager::get_engine_manager()
927 return &mWakeupEngineManager;
930 CAudioManager* CWakeupManager::get_audio_manager()
932 return &mAudioManager;
935 CWakeupSettings* CWakeupManager::get_wakeup_settings()
937 return &mWakeupSettings;
940 void CWakeupManager::feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len)
942 const std::chrono::seconds interval(5);
943 static auto last = std::chrono::steady_clock::now();
944 auto now = std::chrono::steady_clock::now();
945 if (now - last > interval) {
946 std::cerr << "Feeding Audio : " << len << std::endl;
950 mAudioManager.feed_audio_data(event, buffer, len);
953 void CWakeupManager::set_dependency_module_command(string engine_name, string command)
955 mWakeupEngineManager.engine_set_dependency_module_command(engine_name, command);
958 static Eina_Bool periodic_monitor_func(void *data)
960 std::cerr << "MAS PERIODIC HEALTH CHECK" << std::endl;
961 return ECORE_CALLBACK_RENEW;
964 void CWakeupManager::start_periodic_monitor_timer()
966 MWR_LOGI("MONITOR_TIMER START");
967 mPeriodicMonitorTimer = ecore_timer_add(
969 periodic_monitor_func, nullptr);
972 void CWakeupManager::stop_periodic_monitor_timer()
974 if (mPeriodicMonitorTimer) {
975 ecore_timer_del(mPeriodicMonitorTimer);
976 mPeriodicMonitorTimer = nullptr;
980 void CWakeupManager::start_streaming_duration_timer()
982 MWR_LOGI("DURATION_TIMER START");
983 ecore_main_loop_thread_safe_call_async([](void* data) {
984 MWR_LOGI("DURATION_TIMER START - async");
985 CWakeupManager* manager = static_cast<CWakeupManager*>(data);
986 if (!manager) return;
988 CWakeupSettings *settings = manager->get_wakeup_settings();
990 Ecore_Timer* timer = ecore_timer_add(
991 settings->get_streaming_duration_max(),
992 streaming_duration_expired, manager);
993 manager->set_streaming_duration_timer(timer);
994 MWR_LOGI("DURATION_TIMER STARTED : %p", timer);
999 void CWakeupManager::stop_streaming_duration_timer()
1001 MWR_LOGI("DURATION_TIMER STOP");
1002 if (mStreamingDurationTimer) {
1003 MWR_LOGI("DURATION_TIMER STOP - has timer");
1004 ecore_main_loop_thread_safe_call_async([](void* data) {
1005 MWR_LOGI("DURATION_TIMER STOP - async");
1006 CWakeupManager* manager = static_cast<CWakeupManager*>(data);
1007 if (!manager) return;
1009 Ecore_Timer* timer = manager->get_streaming_duration_timer();
1010 void* ret = ecore_timer_del(timer);
1011 MWR_LOGI("DURATION_TIMER EXISTS : %p %p", timer, ret);
1012 manager->set_streaming_duration_timer(nullptr);
1017 void CWakeupManager::set_streaming_duration_timer(Ecore_Timer* timer)
1019 MWR_LOGI("DURATION_TIMER SET : %p", timer);
1020 mStreamingDurationTimer = timer;
1023 Ecore_Timer* CWakeupManager::get_streaming_duration_timer()
1025 return mStreamingDurationTimer;
1028 bool CWakeupManager::CEngineEventObserver::on_wakeup_event(string engine_name, mas_wakeup_event_info wakeup_info)
1030 MWR_LOGI("[ENTER]");
1031 if (nullptr == mWakeupManager) return false;
1032 if (nullptr == wakeup_info.wakeup_appid) return false;
1034 if (0 != mWakeupManager->get_default_assistant().compare(wakeup_info.wakeup_appid)) {
1035 if (false == mWakeupManager->get_assistant_enabled(string{wakeup_info.wakeup_appid})) {
1036 MWR_LOGE("Wakeup event with deactivated appid : %s", wakeup_info.wakeup_appid);
1041 CWakeupPolicy* policy = mWakeupManager->get_wakeup_policy();
1043 policy->wakeup_candidate(wakeup_info);
1048 bool CWakeupManager::CEngineEventObserver::on_speech_status(string engine_name, mas_speech_status_e status)
1050 MWR_LOGI("[ENTER]");
1051 if (nullptr == mWakeupManager) return false;
1056 bool CWakeupManager::CEngineEventObserver::on_error(string engine_name, int error_code, string error_message)
1058 MWR_LOGI("[ENTER]");
1059 if (nullptr == mWakeupManager) return false;
1064 bool CWakeupManager::CEngineEventObserver::on_audio_data_require_status(string engine_name, bool require)
1066 MWR_LOGI("[ENTER]");
1067 if (nullptr == mWakeupManager) return false;
1068 if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManager->get_manager_state()) return false;
1070 CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1071 CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1073 if (audio_manager && engine_manager) {
1074 if (engine_manager->get_audio_data_required()) {
1075 if (mWakeupManager->get_recording_by_voice_key() != true) {
1076 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
1077 audio_manager->start_recording(true);
1080 if (mWakeupManager->get_recording_by_voice_key() != true) {
1081 audio_manager->stop_recording(true);
1088 bool CWakeupManager::CEngineEventObserver::on_streaming_audio_data(
1089 mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1091 if (nullptr == mWakeupManager) return false;
1093 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1094 for (const auto& observer : observers) {
1095 observer->on_streaming_audio_data(event, buffer, len);
1101 bool CWakeupManager::CEngineEventObserver::on_audio_streaming_data_section(
1102 ma_audio_streaming_data_section_e section)
1104 if (nullptr == mWakeupManager) return false;
1106 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1107 for (const auto& observer : observers) {
1108 observer->on_audio_streaming_data_section(section);
1114 bool CWakeupManager::CEngineEventObserver::on_wakeup_engine_command(
1115 mas_wakeup_engine_command_target_e target, string engine_name, string assistant_name, string command)
1117 if (nullptr == mWakeupManager) return false;
1119 if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_DEPENDENCY_MODULE == target) {
1120 dependency_resolver_process_wakeup_engine_command(engine_name.c_str(), command.c_str());
1123 if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_ALL_ASSISTANTS == target ||
1124 MAS_WAKEUP_ENGINE_COMMAND_TARGET_SPECIFIC_ASSISTANT == target) {
1125 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1126 for (const auto& observer : observers) {
1127 observer->on_wakeup_engine_command(target, assistant_name.c_str(), command.c_str());
1134 void CWakeupManager::CPolicyEventObserver::on_wakeup(mas_wakeup_event_info wakeup_info)
1136 if (nullptr == mWakeupManager) return;
1138 CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1139 CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1140 CWakeupSettings* settings = mWakeupManager->get_wakeup_settings();
1141 if (nullptr == audio_manager || nullptr == engine_manager || nullptr == settings) return;
1143 if (wakeup_info.wakeup_appid && strlen(wakeup_info.wakeup_appid) > 0) {
1144 mWakeupManager->set_default_assistant(wakeup_info.wakeup_appid);
1147 mWakeupManager->stop_streaming_utterance_data();
1148 mWakeupManager->stop_streaming_previous_utterance_data();
1149 mWakeupManager->stop_streaming_follow_up_data();
1150 mWakeupManager->change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
1152 mWakeupManager->set_last_wakeup_event_info(wakeup_info);
1153 engine_manager->set_selected_wakeup_info(wakeup_info);
1154 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1155 for (const auto& observer : observers) {
1156 observer->on_wakeup(wakeup_info);
1159 audio_manager->set_recording_session(RECORDING_SESSION_UTTERANCE);
1162 bool CWakeupManager::CAudioEventObserver::on_recording_audio_data(long time, void* data, int len)
1164 if (nullptr == mWakeupManager) return false;
1165 if (nullptr == mEngineManager) return false;
1167 if (false == mEngineManager->get_audio_data_required()) return false;
1169 if (mWakeupManager->get_recording_by_voice_key() != true) {
1170 /* When follow-up streaming in progress, no need to feed audio data to wakeup engines */
1171 if (STREAMING_MODE::FOLLOW_UP != mWakeupManager->get_streaming_mode()) {
1172 mEngineManager->engine_feed_audio_data(time, data, len);
1179 bool CWakeupManager::CAudioEventObserver::on_streaming_audio_data(
1180 mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1182 if (nullptr == mWakeupManager) return false;
1184 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1185 for (const auto& observer : observers) {
1186 observer->on_streaming_audio_data(event, buffer, len);
1188 if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
1189 mWakeupManager->set_streaming_mode(STREAMING_MODE::NONE);
1190 mWakeupManager->stop_streaming_duration_timer();
1196 bool CWakeupManager::CSettingsEventObserver::on_voice_input_language_changed(
1197 const char* language)
1199 if (nullptr == mWakeupManager || nullptr == language) return false;
1200 mWakeupManager->set_language(std::string(language));
1201 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1202 for (const auto& observer : observers) {
1203 observer->on_value_changed();
1208 bool CWakeupManager::CSettingsEventObserver::on_assistant_enabled_info_changed(
1209 const char* appid, bool enabled)
1211 if (nullptr == mWakeupManager || nullptr == appid) return false;
1212 mWakeupManager->set_assistant_enabled(std::string(appid), enabled);
1213 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1214 for (const auto& observer : observers) {
1215 observer->on_value_changed();
1220 bool CWakeupManager::CSettingsEventObserver::on_default_assistant_appid_changed(
1223 if (nullptr == mWakeupManager || nullptr == appid) return false;
1224 /* Passing 'expected' as false since the change was occurred outside of MAS */
1225 mWakeupManager->process_default_assistant_changed(std::string(appid), false);
1226 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1227 for (const auto& observer : observers) {
1228 observer->on_value_changed();