@@ -81,6 +81,7 @@ class llm_task {
8181 int count_frames_ = 0 ;
8282 long long last_trigger_time_ms_ = -1e9 ;
8383 long long frame_index_global_ = 0 ;
84+ int last_btn_204_state = -1 ;
8485
8586public:
8687 inline const std::string &model () const
@@ -294,9 +295,9 @@ class llm_task {
294295#undef CONFIG_AUTO_SET_SHERPA
295296
296297#define CONFIG_AUTO_SET_AXERA (obj, key ) \
297- if (config_body.contains(#key)) \
298+ if (config_body.contains(#key)) \
298299 axera_config_.key = config_body[#key]; \
299- else if (obj.contains(#key)) \
300+ else if (obj.contains(#key)) \
300301 axera_config_.key = obj[#key];
301302
302303#define OPTS_AUTO_SET (obj, key ) \
@@ -537,9 +538,27 @@ class llm_task {
537538 }
538539 }
539540
540- void trigger ()
541+ void trigger_wakeup ()
541542 {
542- if (out_callback_) out_callback_ (" " , true );
543+ if (enwake_audio_ && (!wake_wav_file_.empty ()) && play_awake_wav) {
544+ play_awake_wav (wake_wav_file_);
545+ }
546+ if (out_callback_) {
547+ if (enoutput_json_)
548+ out_callback_ (" {\" reason\" :\" button_204\" }" , true );
549+ else
550+ out_callback_ (" " , true );
551+ }
552+ }
553+
554+ void set_btn_204_state (int state)
555+ {
556+ last_btn_204_state = state;
557+ }
558+
559+ int get_btn_204_state ()
560+ {
561+ return last_btn_204_state;
543562 }
544563
545564 bool delete_model ()
@@ -790,6 +809,40 @@ class llm_kws : public StackFlow {
790809 llm_task_obj->sys_pcm_on_data ((*next_data));
791810 }
792811
812+ void task_buttons_data (const std::weak_ptr<llm_task> llm_task_obj_weak,
813+ const std::weak_ptr<llm_channel_obj> llm_channel_weak, const std::string &object,
814+ const std::string &data)
815+ {
816+ auto llm_task_obj = llm_task_obj_weak.lock ();
817+ auto llm_channel = llm_channel_weak.lock ();
818+ if (!(llm_task_obj && llm_channel)) {
819+ return ;
820+ }
821+ if (data.empty () || (data == " None" )) return ;
822+
823+ try {
824+ std::string user_msg = sample_unescapeString (data);
825+ nlohmann::json btn_json = nlohmann::json::parse (user_msg);
826+
827+ if (btn_json.contains (" code" ) && btn_json.contains (" vale" )) {
828+ int current_code = btn_json[" code" ];
829+ int current_vale = btn_json[" vale" ];
830+
831+ if (current_vale == 204 ) {
832+ int last_code = llm_task_obj->get_btn_204_state ();
833+
834+ if (last_code == 0 && current_code == 1 ) {
835+ llm_task_obj->trigger_wakeup ();
836+ }
837+
838+ llm_task_obj->set_btn_204_state (current_code);
839+ }
840+ }
841+ } catch (const std::exception &e) {
842+ SLOGE (" Button data JSON parse error: %s" , e.what ());
843+ }
844+ }
845+
793846 int setup (const std::string &work_id, const std::string &object, const std::string &data) override
794847 {
795848 nlohmann::json error_body;
@@ -836,6 +889,17 @@ class llm_kws : public StackFlow {
836889 llm_channel->subscriber_work_id (" " , std::bind (&llm_kws::task_user_data, this , _llm_task_obj,
837890 std::weak_ptr<llm_channel_obj>(llm_channel),
838891 std::placeholders::_1, std::placeholders::_2));
892+ } else if (input.find (" buttons_thread" ) != std::string::npos) {
893+ std::string socket_url = " ipc:///tmp/llm/ec_prox.event.socket" ;
894+ auto business_logic = std::bind (
895+ &llm_kws::task_buttons_data, this , std::weak_ptr<llm_task>(llm_task_obj),
896+ std::weak_ptr<llm_channel_obj>(llm_channel), std::placeholders::_1, std::placeholders::_2);
897+
898+ llm_channel->subscriber (
899+ socket_url, [llm_channel, business_logic](StackFlows::pzmq *p,
900+ const std::shared_ptr<StackFlows::pzmq_data> &d) {
901+ llm_channel->subscriber_event_call (business_logic, p, d);
902+ });
839903 }
840904 }
841905 llm_task_[work_id_num] = llm_task_obj;
@@ -851,6 +915,94 @@ class llm_kws : public StackFlow {
851915 }
852916 }
853917
918+ void link (const std::string &work_id, const std::string &object, const std::string &data) override
919+ {
920+ SLOGI (" llm_kws::link:%s" , data.c_str ());
921+ int ret = 0 ;
922+ nlohmann::json error_body;
923+
924+ int work_id_num = sample_get_work_id_num (work_id);
925+ if (llm_task_.find (work_id_num) == llm_task_.end ()) {
926+ error_body[" code" ] = -6 ;
927+ error_body[" message" ] = " Unit Does Not Exist" ;
928+ send (" None" , " None" , error_body, work_id);
929+ return ;
930+ }
931+
932+ auto llm_channel = get_channel (work_id);
933+ auto llm_task_obj = llm_task_[work_id_num];
934+
935+ if (data.find (" sys" ) != std::string::npos) {
936+ if (audio_url_.empty ()) audio_url_ = unit_call (" audio" , " cap" , data);
937+
938+ std::weak_ptr<llm_task> _llm_task_obj = llm_task_obj;
939+ llm_channel->subscriber (audio_url_, [_llm_task_obj](pzmq *_pzmq, const std::shared_ptr<pzmq_data> &raw) {
940+ if (auto p = _llm_task_obj.lock ()) p->sys_pcm_on_data (raw->string ());
941+ });
942+
943+ llm_task_obj->audio_flage_ = true ;
944+ llm_task_obj->inputs_ .push_back (data);
945+ } else if (data.find (" buttons_thread" ) != std::string::npos) {
946+ std::string socket_url = " ipc:///tmp/llm/ec_prox.event.socket" ;
947+ auto business_logic =
948+ std::bind (&llm_kws::task_buttons_data, this , std::weak_ptr<llm_task>(llm_task_obj),
949+ std::weak_ptr<llm_channel_obj>(llm_channel), std::placeholders::_1, std::placeholders::_2);
950+
951+ llm_channel->subscriber (
952+ socket_url,
953+ [llm_channel, business_logic](StackFlows::pzmq *p, const std::shared_ptr<StackFlows::pzmq_data> &d) {
954+ llm_channel->subscriber_event_call (business_logic, p, d);
955+ });
956+
957+ llm_task_obj->inputs_ .push_back (data);
958+ } else {
959+ error_body[" code" ] = -22 ;
960+ error_body[" message" ] = " unsupported link target" ;
961+ send (" None" , " None" , error_body, work_id);
962+ return ;
963+ }
964+
965+ if (ret) {
966+ error_body[" code" ] = -20 ;
967+ error_body[" message" ] = " link false" ;
968+ send (" None" , " None" , error_body, work_id);
969+ return ;
970+ }
971+ send (" None" , " None" , LLM_NO_ERROR, work_id);
972+ }
973+
974+ void unlink (const std::string &work_id, const std::string &object, const std::string &data) override
975+ {
976+ SLOGI (" llm_kws::unlink:%s" , data.c_str ());
977+ nlohmann::json error_body;
978+
979+ int work_id_num = sample_get_work_id_num (work_id);
980+ if (llm_task_.find (work_id_num) == llm_task_.end ()) {
981+ error_body[" code" ] = -6 ;
982+ error_body[" message" ] = " Unit Does Not Exist" ;
983+ send (" None" , " None" , error_body, work_id);
984+ return ;
985+ }
986+
987+ auto llm_channel = get_channel (work_id);
988+ auto llm_task_obj = llm_task_[work_id_num];
989+
990+ llm_channel->stop_subscriber_work_id (data);
991+
992+ for (auto it = llm_task_obj->inputs_ .begin (); it != llm_task_obj->inputs_ .end ();) {
993+ if (*it == data)
994+ it = llm_task_obj->inputs_ .erase (it);
995+ else
996+ ++it;
997+ }
998+
999+ if (data.find (" sys" ) != std::string::npos) {
1000+ llm_task_obj->audio_flage_ = false ;
1001+ }
1002+
1003+ send (" None" , " None" , LLM_NO_ERROR, work_id);
1004+ }
1005+
8541006 void taskinfo (const std::string &work_id, const std::string &object, const std::string &data) override
8551007 {
8561008 SLOGI (" llm_kws::taskinfo:%s" , data.c_str ());
@@ -937,7 +1089,7 @@ class llm_kws : public StackFlow {
9371089 _zmq.send_data (out);
9381090 return LLM_NONE;
9391091 }
940- llm_task_[work_id_num]->trigger ();
1092+ llm_task_[work_id_num]->trigger_wakeup ();
9411093 return LLM_NONE;
9421094 }
9431095
0 commit comments