3232#include <stddef.h>
3333#include <stdint.h>
3434
35+ #include <ipc4/base-config.h>
36+ #include <ipc4/header.h>
37+ #include <ipc4/module.h>
38+ #include <ipc4/notification.h>
39+
3540#include "speech.h"
3641
3742SOF_DEFINE_REG_UUID (tflmcly );
@@ -44,8 +49,67 @@ static const char * const prediction[] = TFLM_CATEGORY_DATA;
4449struct tflm_comp_data {
4550 struct comp_data_blob_handler * model_handler ;
4651 struct tf_classify tfc ;
52+ struct ipc_msg * msg ;
4753};
4854
55+ static int tflm_ipc_notification_init (struct processing_module * mod )
56+ {
57+ struct tflm_comp_data * cd = module_get_private_data (mod );
58+ struct ipc_msg msg_proto ;
59+ struct comp_dev * dev = mod -> dev ;
60+ struct comp_ipc_config * ipc_config = & dev -> ipc_config ;
61+ union ipc4_notification_header * primary =
62+ (union ipc4_notification_header * )& msg_proto .header ;
63+ struct sof_ipc4_notify_module_data * msg_module_data ;
64+ struct sof_ipc4_control_msg_payload * msg_payload ;
65+
66+ memset_s (& msg_proto , sizeof (msg_proto ), 0 , sizeof (msg_proto ));
67+ primary -> r .notif_type = SOF_IPC4_MODULE_NOTIFICATION ;
68+ primary -> r .type = SOF_IPC4_GLB_NOTIFICATION ;
69+ primary -> r .rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST ;
70+ primary -> r .msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG ;
71+ cd -> msg = ipc_msg_w_ext_init (msg_proto .header , msg_proto .extension ,
72+ sizeof (struct sof_ipc4_notify_module_data ) +
73+ sizeof (struct sof_ipc4_control_msg_payload ) +
74+ sizeof (struct sof_ipc4_ctrl_value_chan ));
75+ if (!cd -> msg ) {
76+ comp_err (dev , "Failed to initialize TFLM notification" );
77+ return - ENOMEM ;
78+ }
79+
80+ msg_module_data = (struct sof_ipc4_notify_module_data * )cd -> msg -> tx_data ;
81+ msg_module_data -> instance_id = IPC4_INST_ID (ipc_config -> id );
82+ msg_module_data -> module_id = IPC4_MOD_ID (ipc_config -> id );
83+ msg_module_data -> event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL |
84+ SOF_IPC4_SWITCH_CONTROL_PARAM_ID ;
85+ msg_module_data -> event_data_size = sizeof (struct sof_ipc4_control_msg_payload ) +
86+ sizeof (struct sof_ipc4_ctrl_value_chan );
87+
88+ msg_payload = (struct sof_ipc4_control_msg_payload * )msg_module_data -> event_data ;
89+ msg_payload -> id = 0 ;
90+ msg_payload -> num_elems = 1 ;
91+ msg_payload -> chanv [0 ].channel = 0 ;
92+
93+ comp_dbg (dev , "TFLM notification init: instance_id = 0x%08x, module_id = 0x%08x" ,
94+ msg_module_data -> instance_id , msg_module_data -> module_id );
95+ return 0 ;
96+ }
97+
98+ static void tflm_send_keyword_notification (struct processing_module * mod , uint32_t category_idx )
99+ {
100+ struct tflm_comp_data * cd = module_get_private_data (mod );
101+ struct sof_ipc4_notify_module_data * msg_module_data ;
102+ struct sof_ipc4_control_msg_payload * msg_payload ;
103+
104+ if (!cd -> msg )
105+ return ;
106+
107+ msg_module_data = (struct sof_ipc4_notify_module_data * )cd -> msg -> tx_data ;
108+ msg_payload = (struct sof_ipc4_control_msg_payload * )msg_module_data -> event_data ;
109+ msg_payload -> chanv [0 ].value = category_idx ;
110+ ipc_msg_send (cd -> msg , NULL , false);
111+ }
112+
49113__cold static int tflm_init (struct processing_module * mod )
50114{
51115 struct module_data * md = & mod -> priv ;
@@ -97,11 +161,19 @@ __cold static int tflm_init(struct processing_module *mod)
97161 goto fail ;
98162 }
99163
164+ ret = tflm_ipc_notification_init (mod );
165+ if (ret < 0 ) {
166+ comp_err (dev , "failed to init notification" );
167+ goto fail ;
168+ }
169+
100170 return ret ;
101171
102172fail :
103173 /* Passing NULL pointer to free functions is Ok */
104174 mod_data_blob_handler_free (mod , cd -> model_handler );
175+ if (cd -> msg )
176+ ipc_msg_free (cd -> msg );
105177 mod_free (mod , cd );
106178 return ret ;
107179}
@@ -112,6 +184,8 @@ __cold static int tflm_free(struct processing_module *mod)
112184
113185 assert_can_be_cold ();
114186
187+ if (cd -> msg )
188+ ipc_msg_free (cd -> msg );
115189 mod_data_blob_handler_free (mod , cd -> model_handler );
116190 mod_free (mod , cd );
117191 return 0 ;
@@ -208,9 +282,23 @@ static int tflm_process(struct processing_module *mod,
208282 }
209283
210284 /* debug - dump the output */
285+ int max_idx = 0 ;
286+ float max_score = cd -> tfc .predictions [0 ];
287+
211288 for (int i = 0 ; i < cd -> tfc .categories ; i ++ ) {
212289 comp_dbg (dev , "tf: predictions %1.3f %s" ,
213290 cd -> tfc .predictions [i ], prediction [i ]);
291+ if (cd -> tfc .predictions [i ] > max_score ) {
292+ max_score = cd -> tfc .predictions [i ];
293+ max_idx = i ;
294+ }
295+ }
296+
297+ /* Check if a keyword ("yes" or "no", category indices 2 and 3) is detected */
298+ if (max_idx >= 2 && max_score >= 0.70f ) {
299+ comp_info (dev , "TFLM keyword detected: %s (confidence %1.3f)" ,
300+ prediction [max_idx ], (double )max_score );
301+ tflm_send_keyword_notification (mod , max_idx );
214302 }
215303
216304 /* advance by one stride */
0 commit comments