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());
283 if (mWakeupSettings.get_multiple_mode()) {
284 vector<string> assistants = mWakeupSettings.get_enabled_assistants();
285 auto iter = find(assistants.begin(), assistants.end(), appid);
286 if (iter != assistants.end())
289 if (0 == appid.compare(mWakeupSettings.get_default_assistant_appid()))
294 mWakeupEngineManager.engine_add_target_assistant(engine, appid);
300 bool CWakeupManager::set_assistant_language(string appid, string language)
302 MWR_LOGI("[ENTER] : %s, %s", appid.c_str(), language.c_str());
304 mWakeupEngineManager.set_assistant_language(appid, language);
305 mAssistantConfigManager.set_assistant_language(appid, language);
311 bool CWakeupManager::set_assistant_enabled(string appid, bool enabled)
315 mAssistantEnabled[appid] = enabled;
316 bool activated = enabled;
317 if (false == mAssistantSupportsCurrentLanguage[appid]) {
320 if (0 == appid.compare(mWakeupSettings.get_default_assistant_appid())) {
323 mWakeupEngineManager.set_assistant_activated(appid, activated);
329 bool CWakeupManager::set_default_assistant(string appid)
331 MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
333 /* Passing 'expected' as true since MAS is changing the default assistant config */
334 process_default_assistant_changed(appid, true);
336 mWakeupSettings.set_default_assistant_appid(appid);
341 bool CWakeupManager::process_default_assistant_changed(string appid, bool expected)
343 MWR_LOGE("[ENTER] %s %s", appid.c_str(), mCurrentDefaultAssistant.c_str());
345 if (mCurrentDefaultAssistant.compare(appid) == 0) {
346 MWR_LOGE("Default assistant appid not changed, ignoring...");
350 if (mWakeupManagerState == WAKEUP_MANAGER_STATE_UTTERANCE ||
351 mWakeupManagerState == WAKEUP_MANAGER_STATE_PROCESSING) {
353 stop_streaming_utterance_data();
354 stop_streaming_previous_utterance_data();
355 stop_streaming_follow_up_data();
357 mWakeupEngineManager.update_recognition_result(appid, MA_RECOGNITION_RESULT_EVENT_ERROR);
359 /* If this is an unexpected change, invalidate previous recognition process */
360 update_recognition_result(mCurrentDefaultAssistant, MA_RECOGNITION_RESULT_EVENT_ERROR);
364 /* Check if previous default assistant has to be deactivated */
365 bool activated = true;
366 if (false == mAssistantSupportsCurrentLanguage[mCurrentDefaultAssistant]) {
369 if (false == mAssistantEnabled[mCurrentDefaultAssistant]) {
372 mWakeupEngineManager.set_assistant_activated(mCurrentDefaultAssistant, activated);
374 /* New default assistant has to be activated no matter what */
375 mWakeupEngineManager.set_assistant_activated(appid, true);
377 mCurrentDefaultAssistant = appid;
383 string CWakeupManager::get_default_assistant()
385 return mWakeupSettings.get_default_assistant_appid();
388 bool CWakeupManager::get_assistant_enabled(string appid)
390 return mAssistantEnabled[appid];
393 bool CWakeupManager::set_language(string language)
396 MWR_LOGI("[ENTER] : %s", language.c_str());
398 if (check_language_valid(language)) {
399 mCurrentLanguage = language;
402 MWR_LOGE("[ERROR] Invalid language (%s)", language.c_str());
405 for (auto& info : mAssistantLanguageInfo) {
406 bool disable = false;
408 bool supported = false;
409 if (info.languageList.end() !=
410 find(info.languageList.begin(), info.languageList.end(), language)) {
413 mAssistantSupportsCurrentLanguage[info.appid] = supported;
414 /* Disable this assistant if language not supported */
415 if (!supported) disable = true;
417 /* If current language is not valid, assume all languages support it */
418 mAssistantSupportsCurrentLanguage[info.appid] = true;
421 if (false == mAssistantEnabled[info.appid]) {
424 if (0 == info.appid.compare(mWakeupSettings.get_default_assistant_appid())) {
425 /* Default Assistant should be activated no matter what */
428 mWakeupEngineManager.set_assistant_activated(info.appid, !disable);
429 std::string assistant_language;
430 int ret = mAssistantConfigManager.get_assistant_language(info.appid, assistant_language);
431 if (0 != ret || !check_language_valid(assistant_language)) {
432 mWakeupEngineManager.set_assistant_language(info.appid, language);
434 mWakeupEngineManager.set_assistant_language(info.appid, assistant_language);
442 bool CWakeupManager::get_recording_by_voice_key()
444 return mRecordingByVoiceKey;
447 void CWakeupManager::set_recording_by_voice_key(bool recording)
449 mRecordingByVoiceKey = recording;
452 STREAMING_MODE CWakeupManager::get_streaming_mode()
454 return mStreamingMode;
457 bool CWakeupManager::set_streaming_mode(STREAMING_MODE mode)
459 lock_guard<mutex> lock(mMutex);
460 mStreamingMode = mode;
464 bool CWakeupManager::change_manager_state(wakeup_manager_state_e state)
466 MWR_LOGI("[ENTER] : %d", state);
467 mWakeupManagerState = state;
468 mWakeupEngineManager.update_manager_state(state);
469 for (const auto& observer : mWakeupObservers) {
470 observer->on_wakeup_service_state_changed((ma_service_state_e)state);
475 wakeup_manager_state_e CWakeupManager::get_manager_state()
477 return mWakeupManagerState;
480 bool CWakeupManager::update_voice_feedback_state(string appid, bool state)
485 if (WAKEUP_MANAGER_STATE_LISTENING == mWakeupManagerState ||
486 WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState) {
487 change_manager_state(WAKEUP_MANAGER_STATE_VOICE_FEEDBACK);
490 if (WAKEUP_MANAGER_STATE_VOICE_FEEDBACK == mWakeupManagerState) {
491 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
499 bool CWakeupManager::set_assistant_specific_command(string appid, string command)
504 static const string voice_key_pressed{"voice_key_pressed"};
505 static const string voice_key_released{"voice_key_released"};
507 if (0 == command.compare(voice_key_pressed)) {
508 process_event(MA_PLUGIN_EVENT_VOICE_KEY_PRESSED, NULL, 0);
509 } else if (0 == command.compare(voice_key_released)) {
510 process_event(MA_PLUGIN_EVENT_VOICE_KEY_RELEASED, NULL, 0);
514 mWakeupEngineManager.engine_set_assistant_specific_command(appid, command);
520 bool CWakeupManager::set_background_volume(string appid, double ratio)
522 MWR_LOGD("[DEBUG] set background volume (%f)", ratio);
525 mAudioManager.set_background_volume(ratio);
529 bool CWakeupManager::update_recognition_result(string appid, int result)
533 stop_streaming_utterance_data();
534 stop_streaming_previous_utterance_data();
535 stop_streaming_follow_up_data();
537 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
538 mWakeupEngineManager.update_recognition_result(appid, result);
539 if (WAKEUP_MANAGER_STATE_PROCESSING == mWakeupManagerState ||
540 WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
541 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
547 static long long get_current_milliseconds_after_epoch()
549 auto now = chrono::steady_clock::now();
550 auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
551 /* number of milliseconds since the epoch of system_clock */
552 auto value = now_ms.time_since_epoch();
554 return value.count();
557 bool CWakeupManager::process_plugin_event(mas_plugin_event_e event, void* data, int len)
559 MWR_LOGE("[ENTER] : %d", event);
560 if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManagerState)
563 bool start_recording = false;
564 bool stop_recording = false;
566 boost::optional<ma_voice_key_status_e> next_voice_key_status;
567 if (MAS_PLUGIN_EVENT_VOICE_KEY_PRESSED == event) {
568 if (STREAMING_MODE::FOLLOW_UP == mStreamingMode) {
569 MWR_LOGE("Voice key pressed, but currently streaming follow_up audio");
571 if (VOICE_KEY_SUPPORT_MODE_NONE != mCurrentVoiceKeySupportMode) {
572 start_recording = true;
575 next_voice_key_status = MA_VOICE_KEY_STATUS_PRESSED;
576 } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH == event) {
577 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode ||
578 VOICE_KEY_SUPPORT_MODE_ALL == mCurrentVoiceKeySupportMode) {
579 stop_recording = true;
581 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_PUSH;
582 } else if (MAS_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP == event) {
583 if (VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK == mCurrentVoiceKeySupportMode) {
584 stop_recording = true;
586 next_voice_key_status = MA_VOICE_KEY_STATUS_RELEASED_AFTER_TAP;
589 if (start_recording) {
590 mRecordingByVoiceKey = true;
592 mAudioManager.stop_recording(true);
594 stop_streaming_utterance_data();
595 stop_streaming_previous_utterance_data();
596 stop_streaming_follow_up_data();
598 mAudioManager.clear_audio_data();
599 change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
601 /* Start recorder thread using appropriate recording device */
602 mAudioManager.set_recording_session(RECORDING_SESSION_UTTERANCE);
603 mAudioManager.start_recording(true);
605 /* Wakeup default assistant */
606 /* TODO: apply conversation timeout for selecting assistant here */
607 mas_wakeup_event_info wakeup_info;
608 initialize_wakeup_event_info(&wakeup_info);
609 /* Make sure to use background data */
610 wakeup_info.wakeup_time_valid = true;
611 wakeup_info.wakeup_end_time = get_current_milliseconds_after_epoch();
612 wakeup_info.wakeup_engine = WAKEUP_ENGINE_VOICE_KEY;
614 std::string default_assistant_appid = mWakeupSettings.get_default_assistant_appid();
615 wakeup_info.wakeup_appid = default_assistant_appid.c_str();
616 MWR_LOGD("wakeup_appid : %s", wakeup_info.wakeup_appid);
618 set_last_wakeup_event_info(wakeup_info);
619 mWakeupEngineManager.set_selected_wakeup_info(wakeup_info);
620 for (const auto& observer : mWakeupObservers) {
621 observer->on_wakeup(wakeup_info);
624 if (stop_recording) {
625 mRecordingByVoiceKey = false;
627 stop_streaming_duration_timer();
628 mAudioManager.finalize_audio_data();
630 if (STREAMING_MODE::UTTERANCE == mStreamingMode) {
631 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
633 change_manager_state(WAKEUP_MANAGER_STATE_LISTENING);
636 mAudioManager.stop_recording(true);
637 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
638 if (mWakeupEngineManager.get_audio_data_required()) {
639 /* Restart recorder thread using appropriate recording device */
640 mAudioManager.start_recording(true);
644 if (next_voice_key_status) {
645 for (const auto& observer : mWakeupObservers) {
646 observer->on_voice_key_status_changed(*next_voice_key_status);
654 vector<IWakeupEventObserver*> CWakeupManager::get_wakeup_observers()
656 return mWakeupObservers;
659 void CWakeupManager::set_last_wakeup_event_info(mas_wakeup_event_info wakeup_info)
661 mLastWakeupEventInfo = wakeup_info;
664 vector<ISettingValueObserver*> CWakeupManager::get_setting_observers()
666 return mSettingObservers;
669 static Eina_Bool streaming_duration_expired(void *data)
672 CWakeupManager *wakeup_manager = static_cast<CWakeupManager*>(data);
673 if (nullptr == wakeup_manager) return ECORE_CALLBACK_CANCEL;
675 wakeup_manager->set_streaming_duration_timer(nullptr);
677 CAudioManager *audio_manager = wakeup_manager->get_audio_manager();
678 CWakeupEngineManager *engine_manager = wakeup_manager->get_engine_manager();
680 if (nullptr == audio_manager) return ECORE_CALLBACK_CANCEL;
681 if (nullptr == engine_manager) return ECORE_CALLBACK_CANCEL;
683 switch(wakeup_manager->get_streaming_mode()) {
684 case STREAMING_MODE::UTTERANCE:
685 audio_manager->stop_streaming_current_utterance_data();
686 engine_manager->stop_streaming_current_utterance_data();
688 case STREAMING_MODE::PREVIOUS_UTTERANCE:
689 audio_manager->stop_streaming_previous_utterance_data();
691 case STREAMING_MODE::FOLLOW_UP:
692 audio_manager->stop_streaming_follow_up_data();
693 audio_manager->stop_recording(true);
694 wakeup_manager->set_recording_by_voice_key(false);
695 audio_manager->clear_audio_data();
699 wakeup_manager->set_streaming_mode(STREAMING_MODE::NONE);
701 if (WAKEUP_MANAGER_STATE_UTTERANCE == wakeup_manager->get_manager_state()) {
702 audio_manager->stop_recording(true);
703 wakeup_manager->set_recording_by_voice_key(false);
704 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
705 if (engine_manager->get_audio_data_required()) {
706 /* Restart recorder thread using appropriate recording device */
707 audio_manager->start_recording(true);
709 wakeup_manager->change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
712 return ECORE_CALLBACK_CANCEL;
715 bool CWakeupManager::start_streaming_utterance_data()
719 mAudioManager.stop_streaming_current_utterance_data();
720 mWakeupEngineManager.stop_streaming_current_utterance_data();
722 mStreamingMode = STREAMING_MODE::UTTERANCE;
724 bool streaming_by_manager = true;
725 if (false == mLastWakeupEventInfo.wakeup_time_valid) {
726 mWakeupEngineManager.start_streaming_current_utterance_data();
727 streaming_by_manager = false;
729 mAudioManager.start_streaming_current_utterance_data(mLastWakeupEventInfo.wakeup_end_time);
732 stop_streaming_duration_timer();
733 if (streaming_by_manager) {
734 start_streaming_duration_timer();
741 bool CWakeupManager::stop_streaming_utterance_data()
745 if (STREAMING_MODE::UTTERANCE != mStreamingMode) return false;
747 mAudioManager.stop_streaming_current_utterance_data();
748 mWakeupEngineManager.stop_streaming_current_utterance_data();
750 if (mStreamingDurationTimer) {
751 stop_streaming_duration_timer();
753 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
754 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
755 mAudioManager.stop_recording(true);
756 mRecordingByVoiceKey = false;
757 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
758 if (mWakeupEngineManager.get_audio_data_required()) {
759 /* Restart recorder thread using appropriate recording device */
760 mAudioManager.start_recording(true);
764 mStreamingMode = STREAMING_MODE::NONE;
770 bool CWakeupManager::start_streaming_follow_up_data()
774 mAudioManager.stop_streaming_follow_up_data();
775 mWakeupEngineManager.stop_streaming_current_utterance_data();
777 mStreamingMode = STREAMING_MODE::FOLLOW_UP;
779 /* For the follow up streaming, audio data should be recorded from now on */
780 mAudioManager.stop_recording(true);
781 mAudioManager.clear_audio_data();
782 change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
783 mAudioManager.set_recording_session(RECORDING_SESSION_FOLLOW_UP);
784 mAudioManager.start_recording(true);
786 mAudioManager.start_streaming_follow_up_data();
788 stop_streaming_duration_timer();
789 start_streaming_duration_timer();
795 bool CWakeupManager::stop_streaming_follow_up_data()
798 if (STREAMING_MODE::FOLLOW_UP != mStreamingMode) return false;
800 mAudioManager.stop_streaming_follow_up_data();
801 mWakeupEngineManager.stop_streaming_current_utterance_data();
803 if (mStreamingDurationTimer) {
804 stop_streaming_duration_timer();
807 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
808 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
809 mAudioManager.stop_recording(true);
810 mRecordingByVoiceKey = false;
811 mAudioManager.set_recording_session(RECORDING_SESSION_WAKE_WORD);
812 if (mWakeupEngineManager.get_audio_data_required()) {
813 /* Restart recorder thread using appropriate recording device */
814 mAudioManager.start_recording(true);
818 mStreamingMode = STREAMING_MODE::NONE;
820 mAudioManager.clear_audio_data();
826 bool CWakeupManager::start_streaming_previous_utterance_data()
830 mAudioManager.stop_streaming_previous_utterance_data();
831 mWakeupEngineManager.stop_streaming_current_utterance_data();
833 mStreamingMode = STREAMING_MODE::PREVIOUS_UTTERANCE;
834 mAudioManager.start_streaming_previous_utterance_data();
836 stop_streaming_duration_timer();
837 start_streaming_duration_timer();
843 bool CWakeupManager::stop_streaming_previous_utterance_data()
846 if (STREAMING_MODE::PREVIOUS_UTTERANCE != mStreamingMode) return false;
848 mAudioManager.stop_streaming_previous_utterance_data();
849 mWakeupEngineManager.stop_streaming_current_utterance_data();
851 if (mStreamingDurationTimer) {
852 stop_streaming_duration_timer();
855 if (WAKEUP_MANAGER_STATE_UTTERANCE == mWakeupManagerState) {
856 change_manager_state(WAKEUP_MANAGER_STATE_PROCESSING);
859 mStreamingMode = STREAMING_MODE::NONE;
865 bool CWakeupManager::get_audio_format(int* rate, int* channel, int* audio_type)
869 if (!audio_type || !rate || !channel) {
870 MWR_LOGE("[ERROR] Invalid parameter");
874 dependency_resolver_get_audio_format(rate, channel, audio_type);
876 MWR_LOGD("[END] rate(%d), channel(%d), audio_type(%d)", *rate, *channel, *audio_type);
880 bool CWakeupManager::get_audio_source_type(char** type)
885 MWR_LOGE("[ERROR] Invalid parameter");
889 dependency_resolver_get_audio_source_type(type);
891 MWR_LOGD("[END] type(%s)", *type);
895 bool CWakeupManager::set_wake_word_audio_require_flag(bool require)
899 mWakeupEngineManager.set_wake_word_audio_require_flag(require);
905 bool CWakeupManager::set_voice_key_tap_duration(float duration)
909 dependency_resolver_set_voice_key_tap_duration(duration);
915 bool CWakeupManager::unset_voice_key_tap_duration()
919 dependency_resolver_unset_voice_key_tap_duration();
925 bool CWakeupManager::set_voice_key_support_mode(VOICE_KEY_SUPPORT_MODE mode)
927 MWR_LOGI("Voice key support mode : %d", mode);
928 mCurrentVoiceKeySupportMode = mode;
930 char* support_mode = NULL;
933 case VOICE_KEY_SUPPORT_MODE_NONE:
934 support_mode = strdup("none");
936 case VOICE_KEY_SUPPORT_MODE_PUSH_TO_TALK:
937 support_mode = strdup("push_to_talk");
939 case VOICE_KEY_SUPPORT_MODE_TAP_TO_TALK:
940 support_mode = strdup("tap_to_talk");
942 case VOICE_KEY_SUPPORT_MODE_ALL:
943 support_mode = strdup("all");
946 support_mode = strdup("none");
950 dependency_resolver_set_voice_key_support_mode(support_mode);
958 CWakeupPolicy* CWakeupManager::get_wakeup_policy()
960 return mWakeupPolicy.get();
963 CWakeupEngineManager* CWakeupManager::get_engine_manager()
965 return &mWakeupEngineManager;
968 CAudioManager* CWakeupManager::get_audio_manager()
970 return &mAudioManager;
973 CWakeupSettings* CWakeupManager::get_wakeup_settings()
975 return &mWakeupSettings;
978 void CWakeupManager::feed_audio_data(mas_speech_streaming_event_e event, void* buffer, int len)
980 const std::chrono::seconds interval(5);
981 static auto last = std::chrono::steady_clock::now();
982 auto now = std::chrono::steady_clock::now();
983 if (now - last > interval) {
984 std::cerr << "Feeding Audio : " << len << std::endl;
988 mAudioManager.feed_audio_data(event, buffer, len);
991 void CWakeupManager::set_dependency_module_command(string engine_name, string command)
993 mWakeupEngineManager.engine_set_dependency_module_command(engine_name, command);
996 static Eina_Bool periodic_monitor_func(void *data)
998 std::cerr << "MAS PERIODIC HEALTH CHECK" << std::endl;
999 return ECORE_CALLBACK_RENEW;
1002 void CWakeupManager::start_periodic_monitor_timer()
1004 MWR_LOGI("MONITOR_TIMER START");
1005 mPeriodicMonitorTimer = ecore_timer_add(
1007 periodic_monitor_func, nullptr);
1010 void CWakeupManager::stop_periodic_monitor_timer()
1012 if (mPeriodicMonitorTimer) {
1013 ecore_timer_del(mPeriodicMonitorTimer);
1014 mPeriodicMonitorTimer = nullptr;
1018 void CWakeupManager::start_streaming_duration_timer()
1020 MWR_LOGI("DURATION_TIMER START");
1021 ecore_main_loop_thread_safe_call_async([](void* data) {
1022 MWR_LOGI("DURATION_TIMER START - async");
1023 CWakeupManager* manager = static_cast<CWakeupManager*>(data);
1024 if (!manager) return;
1026 CWakeupSettings *settings = manager->get_wakeup_settings();
1028 Ecore_Timer* timer = ecore_timer_add(
1029 settings->get_streaming_duration_max(),
1030 streaming_duration_expired, manager);
1031 manager->set_streaming_duration_timer(timer);
1032 MWR_LOGI("DURATION_TIMER STARTED : %p", timer);
1037 void CWakeupManager::stop_streaming_duration_timer()
1039 MWR_LOGI("DURATION_TIMER STOP");
1040 if (mStreamingDurationTimer) {
1041 MWR_LOGI("DURATION_TIMER STOP - has timer");
1042 ecore_main_loop_thread_safe_call_async([](void* data) {
1043 MWR_LOGI("DURATION_TIMER STOP - async");
1044 CWakeupManager* manager = static_cast<CWakeupManager*>(data);
1045 if (!manager) return;
1047 Ecore_Timer* timer = manager->get_streaming_duration_timer();
1048 void* ret = ecore_timer_del(timer);
1049 MWR_LOGI("DURATION_TIMER EXISTS : %p %p", timer, ret);
1050 manager->set_streaming_duration_timer(nullptr);
1055 void CWakeupManager::set_streaming_duration_timer(Ecore_Timer* timer)
1057 MWR_LOGI("DURATION_TIMER SET : %p", timer);
1058 mStreamingDurationTimer = timer;
1061 Ecore_Timer* CWakeupManager::get_streaming_duration_timer()
1063 return mStreamingDurationTimer;
1066 bool CWakeupManager::CEngineEventObserver::on_wakeup_event(string engine_name, mas_wakeup_event_info wakeup_info)
1068 MWR_LOGI("[ENTER]");
1069 if (nullptr == mWakeupManager) return false;
1070 if (nullptr == wakeup_info.wakeup_appid) return false;
1072 if (0 != mWakeupManager->get_default_assistant().compare(wakeup_info.wakeup_appid)) {
1073 if (false == mWakeupManager->get_assistant_enabled(string{wakeup_info.wakeup_appid})) {
1074 MWR_LOGE("Wakeup event with deactivated appid : %s", wakeup_info.wakeup_appid);
1079 CWakeupPolicy* policy = mWakeupManager->get_wakeup_policy();
1081 policy->wakeup_candidate(wakeup_info);
1086 bool CWakeupManager::CEngineEventObserver::on_speech_status(string engine_name, mas_speech_status_e status)
1088 MWR_LOGI("[ENTER]");
1089 if (nullptr == mWakeupManager) return false;
1094 bool CWakeupManager::CEngineEventObserver::on_error(string engine_name, int error_code, string error_message)
1096 MWR_LOGI("[ENTER]");
1097 if (nullptr == mWakeupManager) return false;
1102 bool CWakeupManager::CEngineEventObserver::on_audio_data_require_status(string engine_name, bool require)
1104 MWR_LOGI("[ENTER]");
1105 if (nullptr == mWakeupManager) return false;
1106 if (WAKEUP_MANAGER_STATE_INACTIVE == mWakeupManager->get_manager_state()) return false;
1108 CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1109 CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1111 if (audio_manager && engine_manager) {
1112 if (engine_manager->get_audio_data_required()) {
1113 if (mWakeupManager->get_recording_by_voice_key() != true) {
1114 audio_manager->set_recording_session(RECORDING_SESSION_WAKE_WORD);
1115 audio_manager->start_recording(true);
1118 if (mWakeupManager->get_recording_by_voice_key() != true) {
1119 audio_manager->stop_recording(true);
1126 bool CWakeupManager::CEngineEventObserver::on_streaming_audio_data(
1127 mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1129 if (nullptr == mWakeupManager) return false;
1131 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1132 for (const auto& observer : observers) {
1133 observer->on_streaming_audio_data(event, buffer, len);
1139 bool CWakeupManager::CEngineEventObserver::on_audio_streaming_data_section(
1140 ma_audio_streaming_data_section_e section)
1142 if (nullptr == mWakeupManager) return false;
1144 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1145 for (const auto& observer : observers) {
1146 observer->on_audio_streaming_data_section(section);
1152 bool CWakeupManager::CEngineEventObserver::on_wakeup_engine_command(
1153 mas_wakeup_engine_command_target_e target, string engine_name, string assistant_name, string command)
1155 if (nullptr == mWakeupManager) return false;
1157 if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_DEPENDENCY_MODULE == target) {
1158 dependency_resolver_process_wakeup_engine_command(engine_name.c_str(), command.c_str());
1161 if (MAS_WAKEUP_ENGINE_COMMAND_TARGET_ALL_ASSISTANTS == target ||
1162 MAS_WAKEUP_ENGINE_COMMAND_TARGET_SPECIFIC_ASSISTANT == target) {
1163 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1164 for (const auto& observer : observers) {
1165 observer->on_wakeup_engine_command(target, assistant_name.c_str(), command.c_str());
1172 void CWakeupManager::CPolicyEventObserver::on_wakeup(mas_wakeup_event_info wakeup_info)
1174 if (nullptr == mWakeupManager) return;
1176 CAudioManager *audio_manager = mWakeupManager->get_audio_manager();
1177 CWakeupEngineManager *engine_manager = mWakeupManager->get_engine_manager();
1178 CWakeupSettings* settings = mWakeupManager->get_wakeup_settings();
1179 if (nullptr == audio_manager || nullptr == engine_manager || nullptr == settings) return;
1181 if (wakeup_info.wakeup_appid && strlen(wakeup_info.wakeup_appid) > 0) {
1182 mWakeupManager->set_default_assistant(wakeup_info.wakeup_appid);
1185 mWakeupManager->stop_streaming_utterance_data();
1186 mWakeupManager->stop_streaming_previous_utterance_data();
1187 mWakeupManager->stop_streaming_follow_up_data();
1188 mWakeupManager->change_manager_state(WAKEUP_MANAGER_STATE_UTTERANCE);
1190 mWakeupManager->set_last_wakeup_event_info(wakeup_info);
1191 engine_manager->set_selected_wakeup_info(wakeup_info);
1192 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1193 for (const auto& observer : observers) {
1194 observer->on_wakeup(wakeup_info);
1197 audio_manager->set_recording_session(RECORDING_SESSION_UTTERANCE);
1200 bool CWakeupManager::CAudioEventObserver::on_recording_audio_data(long time, void* data, int len)
1202 if (nullptr == mWakeupManager) return false;
1203 if (nullptr == mEngineManager) return false;
1205 if (false == mEngineManager->get_audio_data_required()) return false;
1207 if (mWakeupManager->get_recording_by_voice_key() != true) {
1208 /* When follow-up streaming in progress, no need to feed audio data to wakeup engines */
1209 if (STREAMING_MODE::FOLLOW_UP != mWakeupManager->get_streaming_mode()) {
1210 mEngineManager->engine_feed_audio_data(time, data, len);
1217 bool CWakeupManager::CAudioEventObserver::on_streaming_audio_data(
1218 mas_speech_streaming_event_e event, void* buffer, unsigned int len)
1220 if (nullptr == mWakeupManager) return false;
1222 vector<IWakeupEventObserver*> observers = mWakeupManager->get_wakeup_observers();
1223 for (const auto& observer : observers) {
1224 observer->on_streaming_audio_data(event, buffer, len);
1226 if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
1227 mWakeupManager->set_streaming_mode(STREAMING_MODE::NONE);
1228 mWakeupManager->stop_streaming_duration_timer();
1234 bool CWakeupManager::CSettingsEventObserver::on_voice_input_language_changed(
1235 const char* language)
1237 if (nullptr == mWakeupManager || nullptr == language) return false;
1238 mWakeupManager->set_language(std::string(language));
1239 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1240 for (const auto& observer : observers) {
1241 observer->on_value_changed();
1246 bool CWakeupManager::CSettingsEventObserver::on_assistant_enabled_info_changed(
1247 const char* appid, bool enabled)
1249 if (nullptr == mWakeupManager || nullptr == appid) return false;
1250 mWakeupManager->set_assistant_enabled(std::string(appid), enabled);
1251 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1252 for (const auto& observer : observers) {
1253 if (mWakeupManager->get_wakeup_settings()->get_multiple_mode())
1254 observer->on_loaded_wakeup_engine_changed();
1256 observer->on_value_changed();
1261 bool CWakeupManager::CSettingsEventObserver::on_default_assistant_appid_changed(
1264 if (nullptr == mWakeupManager || nullptr == appid) return false;
1265 /* Passing 'expected' as false since the change was occurred outside of MAS */
1266 mWakeupManager->process_default_assistant_changed(std::string(appid), false);
1267 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1268 for (const auto& observer : observers) {
1269 if (mWakeupManager->get_wakeup_settings()->get_multiple_mode())
1270 observer->on_value_changed();
1272 observer->on_loaded_wakeup_engine_changed();
1277 bool CWakeupManager::CSettingsEventObserver::on_multiple_mode_changed()
1279 if (nullptr == mWakeupManager) return false;
1280 vector<ISettingValueObserver*> observers = mWakeupManager->get_setting_observers();
1281 for (const auto& observer : observers) {
1282 observer->on_loaded_wakeup_engine_changed();