Skip to content

Commit cac9d81

Browse files
committed
kpb: add ams support
Add "Key-Phrase Detected" message to KPB module. Add AMS message helpers and handlers. Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
1 parent 1ba94cf commit cac9d81

2 files changed

Lines changed: 249 additions & 41 deletions

File tree

src/audio/kpb.c

Lines changed: 229 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <rtos/clk.h>
2828
#include <rtos/init.h>
2929
#include <sof/lib/memory.h>
30-
#include <sof/lib/notifier.h>
3130
#include <sof/lib/pm_runtime.h>
3231
#include <sof/lib/uuid.h>
3332
#include <sof/list.h>
@@ -47,6 +46,7 @@
4746
#include <stdbool.h>
4847
#include <stddef.h>
4948
#include <stdint.h>
49+
#include <sof/lib/notifier.h>
5050

5151
static const struct comp_driver comp_kpb;
5252

@@ -95,10 +95,17 @@ struct comp_data {
9595
uint32_t num_of_in_channels;
9696
uint32_t offsets[KPB_MAX_MICSEL_CHANNELS];
9797
struct kpb_micselector_config mic_sel;
98+
99+
#if CONFIG_AMS
100+
uint32_t kpd_uuid_id;
101+
uint32_t reg_cli_uuid_id;
102+
#endif
98103
};
99104

100105
/*! KPB private functions */
106+
#ifndef CONFIG_AMS
101107
static void kpb_event_handler(void *arg, enum notify_id type, void *event_data);
108+
#endif
102109
static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli);
103110
static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli);
104111
static enum task_state kpb_draining_task(void *arg);
@@ -130,6 +137,179 @@ static uint64_t kpb_task_deadline(void *data)
130137
return SOF_TASK_DEADLINE_ALMOST_IDLE;
131138
}
132139

140+
#if CONFIG_AMS
141+
/* AMS messages uuids*/
142+
/* Key-phrase detected uuid: 80a11122-b36c-11ed-afa1-0242ac120002 */
143+
const uint8_t ams_kpd_msg_uuid[UUID_SIZE] = {0x80, 0xa1, 0x11, 0x22, 0xb3, 0x6c,
144+
0x11, 0xed, 0xaf, 0xa1, 0x02, 0x42,
145+
0xac, 0x12, 0x00, 0x02};
146+
147+
/* Register KPB client uuid: c5d9850f-cbdd-4bf4-9c6a-43dfc5faee9f*/
148+
const uint8_t ams_reg_cli_msg_uuid[UUID_SIZE] = {0xcd, 0x59, 0x85, 0x0f, 0xdd,
149+
0xcb, 0xf4, 0x4b, 0x9c, 0x6a,
150+
0x43, 0xdf, 0xc5, 0xfa, 0xee,
151+
0x9f};
152+
153+
static void
154+
kpb_ams_kpd_notification(const struct ams_message_payload *const ams_message_payload,
155+
void *ctx)
156+
{
157+
struct kpb_client *cli_data = (struct kpb_client *)ams_message_payload->message;
158+
struct comp_dev *dev = ctx;
159+
160+
comp_dbg(dev, "kpb_ams_kpd_notification()");
161+
162+
kpb_init_draining(dev, cli_data);
163+
}
164+
165+
static void
166+
kpb_ams_register_cli_notification(const struct ams_message_payload *const ams_message_payload,
167+
void *ctx)
168+
{
169+
struct kpb_client *cli_data = (struct kpb_client *)ams_message_payload->message;
170+
struct comp_dev *dev = ctx;
171+
struct comp_data *kpb = comp_get_drvdata(dev);
172+
int ret;
173+
174+
comp_dbg(dev, "kpb_ams_register_cli_notification()");
175+
176+
ret = kpb_register_client(kpb, cli_data);
177+
if (ret)
178+
comp_err(dev, "kpb_ams_register_cli_notification(): register client error");
179+
}
180+
181+
static int kpb_register_ams_consumer(struct comp_dev *dev,
182+
const uint8_t *msg_uuid,
183+
uint32_t ams_uuid_id,
184+
ams_msg_callback_fn callback)
185+
{
186+
uint16_t mod_id, inst_id;
187+
int ret;
188+
189+
comp_dbg(dev, "kpb_register_ams_consumer()");
190+
191+
#ifdef CONFIG_IPC_MAJOR_4
192+
mod_id = IPC4_MOD_ID(dev_comp_id(dev));
193+
inst_id = IPC4_INST_ID(dev_comp_id(dev));
194+
#else
195+
/* In IPC3 case KPB could be created only once so instance id = 0 */
196+
mod_id = dev_comp_type(dev);
197+
inst_id = 0;
198+
#endif
199+
200+
ret = ams_get_message_type_id(msg_uuid, &ams_uuid_id);
201+
if (ret)
202+
return ret;
203+
204+
return ams_register_consumer(ams_uuid_id, mod_id, inst_id, callback, dev);
205+
}
206+
207+
static int kpb_unregister_ams_consumer(struct comp_dev *dev,
208+
uint32_t ams_uuid_id,
209+
ams_msg_callback_fn callback)
210+
{
211+
#ifdef CONFIG_IPC_MAJOR_4
212+
uint16_t mod_id = IPC4_MOD_ID(dev_comp_id(dev));
213+
uint16_t inst_id = IPC4_INST_ID(dev_comp_id(dev));
214+
#else
215+
/* In IPC3 case KPB could be created only once so instance id = 0 */
216+
uint16_t mod_id = dev_comp_type(dev);
217+
uint16_t inst_id = 0;
218+
#endif
219+
comp_dbg(dev, "kpb_unregister_ams_consumer()");
220+
221+
return ams_unregister_consumer(ams_uuid_id, mod_id, inst_id, callback);
222+
}
223+
224+
int kpb_register_ams_producer(const struct comp_dev *dev,
225+
struct ams_message_payload *payload,
226+
const uint8_t *msg_uuid,
227+
uint32_t ams_uuid_id)
228+
{
229+
uint16_t mod_id, inst_id;
230+
int ret;
231+
232+
comp_dbg(dev, "kpb_register_ams_producer()");
233+
234+
#ifdef CONFIG_IPC_MAJOR_4
235+
mod_id = IPC4_MOD_ID(dev_comp_id(dev));
236+
inst_id = IPC4_INST_ID(dev_comp_id(dev));
237+
#else
238+
/* In IPC3 case detector could be created only once so instance id = 0 */
239+
mod_id = dev_comp_type(dev);
240+
inst_id = 0;
241+
#endif
242+
243+
ret = ams_get_message_type_id(msg_uuid, &ams_uuid_id);
244+
if (ret)
245+
return ret;
246+
247+
ret = ams_register_producer(ams_uuid_id, mod_id, inst_id);
248+
if (ret)
249+
return ret;
250+
251+
payload->message_type_id = ams_uuid_id;
252+
payload->producer_module_id = mod_id;
253+
payload->producer_instance_id = inst_id;
254+
255+
return 0;
256+
}
257+
258+
int kpb_unregister_ams_producer(const struct comp_dev *dev,
259+
uint32_t ams_uuid_id)
260+
{
261+
#ifdef CONFIG_IPC_MAJOR_4
262+
uint16_t mod_id = IPC4_MOD_ID(dev_comp_id(dev));
263+
uint16_t inst_id = IPC4_INST_ID(dev_comp_id(dev));
264+
#else
265+
/* In IPC3 case detector could be created only once so instance id = 0 */
266+
uint16_t mod_id = dev_comp_type(dev);
267+
uint16_t inst_id = 0;
268+
#endif
269+
270+
comp_dbg(dev, "test_keyword_unregister_ams_producer()");
271+
272+
return ams_unregister_producer(ams_uuid_id, mod_id, inst_id);
273+
}
274+
275+
#else
276+
/**
277+
* \brief Main event dispatcher.
278+
* \param[in] arg - KPB component internal data.
279+
* \param[in] type - notification type
280+
* \param[in] event_data - event specific data.
281+
* \return none.
282+
*/
283+
static void kpb_event_handler(void *arg, enum notify_id type, void *event_data)
284+
{
285+
struct comp_dev *dev = arg;
286+
struct comp_data *kpb = comp_get_drvdata(dev);
287+
struct kpb_event_data *evd = event_data;
288+
struct kpb_client *cli = evd->client_data;
289+
290+
comp_info(dev, "kpb_event_handler(): received event with ID: %d ",
291+
evd->event_id);
292+
293+
switch (evd->event_id) {
294+
case KPB_EVENT_REGISTER_CLIENT:
295+
kpb_register_client(kpb, cli);
296+
break;
297+
case KPB_EVENT_UNREGISTER_CLIENT:
298+
/*TODO*/
299+
break;
300+
case KPB_EVENT_BEGIN_DRAINING:
301+
kpb_init_draining(dev, cli);
302+
break;
303+
case KPB_EVENT_STOP_DRAINING:
304+
/*TODO*/
305+
break;
306+
default:
307+
comp_err(dev, "kpb_cmd(): unsupported command");
308+
break;
309+
}
310+
}
311+
#endif /* CONFIG_AMS */
312+
133313
#ifdef __ZEPHYR__
134314

135315
static void kpb_lock(struct comp_data *kpb)
@@ -615,8 +795,23 @@ static void kpb_free(struct comp_dev *dev)
615795

616796
comp_info(dev, "kpb_free()");
617797

798+
#if CONFIG_AMS
799+
/* Unregister KPB as AMS consumer */
800+
int ret;
801+
802+
ret = kpb_unregister_ams_consumer(dev, kpb->kpd_uuid_id,
803+
kpb_ams_kpd_notification);
804+
if (ret)
805+
comp_err(dev, "kpb_free(): ams kpd error %d", ret);
806+
807+
ret = kpb_unregister_ams_consumer(dev, kpb->reg_cli_uuid_id,
808+
kpb_ams_register_cli_notification);
809+
if (ret)
810+
comp_err(dev, "kpb_free(): ams register client error %d", ret);
811+
#else
618812
/* Unregister KPB from notifications */
619813
notifier_unregister(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT);
814+
#endif/* CONFIG_AMS */
620815

621816
/* Reclaim memory occupied by history buffer */
622817
kpb_free_history_buffer(kpb->hd.c_hb);
@@ -692,6 +887,11 @@ static int kpb_params(struct comp_dev *dev,
692887
kpb->host_period_size = params->host_period_bytes;
693888
kpb->config.sampling_width = params->sample_container_bytes * 8;
694889

890+
#if CONFIG_AMS
891+
kpb->kpd_uuid_id = AMS_INVALID_MSG_TYPE;
892+
kpb->reg_cli_uuid_id = AMS_INVALID_MSG_TYPE;
893+
#endif
894+
695895
return 0;
696896
}
697897

@@ -767,14 +967,31 @@ static int kpb_prepare(struct comp_dev *dev)
767967
kpb->clients[i].r_ptr = NULL;
768968
}
769969

970+
#if CONFIG_AMS
971+
/* Register KPB as AMS consumer */
972+
ret = kpb_register_ams_consumer(dev, ams_kpd_msg_uuid, kpb->kpd_uuid_id,
973+
kpb_ams_kpd_notification);
974+
if (ret) {
975+
comp_err(dev, "kpb_prepare(): register ams consumer kpd err %d", ret);
976+
goto err;
977+
}
978+
979+
ret = kpb_register_ams_consumer(dev, ams_reg_cli_msg_uuid,
980+
kpb->reg_cli_uuid_id,
981+
kpb_ams_register_cli_notification);
982+
if (ret) {
983+
comp_err(dev, "kpb_prepare(): register ams consumer reg_cli err %d", ret);
984+
goto err;
985+
}
986+
#else
770987
/* Register KPB for notification */
771988
ret = notifier_register(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT,
772989
kpb_event_handler, 0);
773-
if (ret < 0) {
774-
kpb_free_history_buffer(kpb->hd.c_hb);
775-
kpb->hd.c_hb = NULL;
776-
return -ENOMEM;
990+
if (ret) {
991+
comp_err(dev, "kpb_prepare(): notifier_register err %d", ret);
992+
goto err;
777993
}
994+
#endif /* CONFIG_AMS */
778995

779996
#ifndef CONFIG_IPC_MAJOR_4
780997
/* Search for KPB related sinks.
@@ -850,6 +1067,11 @@ static int kpb_prepare(struct comp_dev *dev)
8501067
kpb_change_state(kpb, KPB_STATE_RUN);
8511068

8521069
return ret;
1070+
1071+
err:
1072+
kpb_free_history_buffer(kpb->hd.c_hb);
1073+
kpb->hd.c_hb = NULL;
1074+
return ret;
8531075
}
8541076

8551077
/**
@@ -912,8 +1134,10 @@ static int kpb_reset(struct comp_dev *dev)
9121134
kpb_reset_history_buffer(kpb->hd.c_hb);
9131135
}
9141136

1137+
#ifndef CONFIG_AMS
9151138
/* Unregister KPB from notifications */
9161139
notifier_unregister(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT);
1140+
#endif
9171141
/* Finally KPB is ready after reset */
9181142
kpb_change_state(kpb, KPB_STATE_PREPARING);
9191143

@@ -1417,42 +1641,6 @@ static int kpb_buffer_data(struct comp_dev *dev,
14171641
return ret;
14181642
}
14191643

1420-
/**
1421-
* \brief Main event dispatcher.
1422-
* \param[in] arg - KPB component internal data.
1423-
* \param[in] type - notification type
1424-
* \param[in] event_data - event specific data.
1425-
* \return none.
1426-
*/
1427-
static void kpb_event_handler(void *arg, enum notify_id type, void *event_data)
1428-
{
1429-
struct comp_dev *dev = arg;
1430-
struct comp_data *kpb = comp_get_drvdata(dev);
1431-
struct kpb_event_data *evd = event_data;
1432-
struct kpb_client *cli = evd->client_data;
1433-
1434-
comp_info(dev, "kpb_event_handler(): received event with ID: %d ",
1435-
evd->event_id);
1436-
1437-
switch (evd->event_id) {
1438-
case KPB_EVENT_REGISTER_CLIENT:
1439-
kpb_register_client(kpb, cli);
1440-
break;
1441-
case KPB_EVENT_UNREGISTER_CLIENT:
1442-
/*TODO*/
1443-
break;
1444-
case KPB_EVENT_BEGIN_DRAINING:
1445-
kpb_init_draining(dev, cli);
1446-
break;
1447-
case KPB_EVENT_STOP_DRAINING:
1448-
/*TODO*/
1449-
break;
1450-
default:
1451-
comp_err(dev, "kpb_cmd(): unsupported command");
1452-
break;
1453-
}
1454-
}
1455-
14561644
/**
14571645
* \brief Register clients in the system.
14581646
*

src/include/sof/audio/kpb.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,26 @@ struct kpb_micselector_config {
171171
/* channel bit set to 1 implies channel selection */
172172
uint32_t mask;
173173
};
174+
175+
#ifdef CONFIG_AMS
176+
#include <sof/lib/ams.h>
177+
178+
/* Key-phrase detected AMS message*/
179+
extern const uint8_t ams_kpd_msg_uuid[UUID_SIZE];
180+
181+
/* Register KPB client AMS message*/
182+
extern const uint8_t ams_reg_cli_msg_uuid[UUID_SIZE];
183+
184+
/* AMS message producer helpers*/
185+
int kpb_register_ams_producer(const struct comp_dev *dev,
186+
struct ams_message_payload *payload,
187+
const uint8_t *msg_uuid,
188+
uint32_t ams_uuid_id);
189+
190+
int kpb_unregister_ams_producer(const struct comp_dev *dev,
191+
uint32_t ams_uuid_id);
192+
#endif /* CONFIG_AMS */
193+
174194
#ifdef UNIT_TEST
175195
void sys_comp_kpb_init(void);
176196
#endif

0 commit comments

Comments
 (0)