Skip to content

Commit caad096

Browse files
committed
audio: kpb: add multi-client downstream WOV detector triggering
Update KPB component to retrieve downstream WOV detector widgets via comp_buffer_get_sink_component(sink) on sel_sink and trigger downstream detector pipelines directly during copy. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 9e0dbe1 commit caad096

4 files changed

Lines changed: 82 additions & 10 deletions

File tree

src/audio/kpb.c

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@
1818
#include <sof/audio/component_ext.h>
1919
#include <sof/audio/pipeline.h>
2020
#include <sof/audio/kpb.h>
21+
#define SOF_MODULE_API_PRIVATE
22+
#include <sof/audio/module_adapter/module/generic.h>
23+
#include <module/module/base.h>
2124
#include <sof/audio/ipc-config.h>
2225
#include <sof/common.h>
2326
#include <rtos/panic.h>
2427
#include <sof/ipc/msg.h>
28+
#include <sof/ipc/topology.h>
2529
#include <rtos/timer.h>
2630
#include <rtos/alloc.h>
2731
#include <rtos/clk.h>
@@ -369,6 +373,9 @@ static int kpb_bind(struct comp_dev *dev, struct bind_info *bind_data)
369373
sink_buf_id = buf_get_id(sink);
370374

371375
if (sink_buf_id == buf_id) {
376+
struct comp_dev *sc = comp_buffer_get_sink_component(sink);
377+
comp_err(dev, "kpb_bind: buf_id=%d sink_comp=0x%x -> %s",
378+
buf_id, sc ? dev_comp_id(sc) : 0, sink_buf_id == 0 ? "sel_sink" : "host_sink");
372379
if (sink_buf_id == 0)
373380
kpb->sel_sink = sink;
374381
else
@@ -887,6 +894,38 @@ static int kpb_prepare(struct comp_dev *dev)
887894
return -ENOMEM;
888895
}
889896

897+
struct comp_buffer *sink;
898+
comp_dev_for_each_consumer(dev, sink) {
899+
struct comp_dev *sc = comp_buffer_get_sink_component(sink);
900+
if (sc) {
901+
comp_err(dev, "kpb consumer in bsink_list: comp_id=0x%x type=%d sink_buf=%p",
902+
dev_comp_id(sc), sc->drv ? sc->drv->type : -1, sink);
903+
if (dev_comp_id(sc) != 0x10)
904+
kpb->sel_sink = sink;
905+
else
906+
kpb->host_sink = sink;
907+
}
908+
}
909+
comp_err(dev, "kpb_params result: sel_sink=%p host_sink=%p",
910+
kpb->sel_sink, kpb->host_sink);
911+
912+
if (kpb->sel_sink) {
913+
struct comp_dev *sink_comp = comp_buffer_get_sink_component(kpb->sel_sink);
914+
if (sink_comp && sink_comp->state == COMP_STATE_INIT) {
915+
struct sof_ipc_stream_params sink_params;
916+
memset_s(&sink_params, sizeof(sink_params), 0, sizeof(sink_params));
917+
sink_params.channels = kpb->config.channels ? kpb->config.channels : 2;
918+
sink_params.rate = kpb->config.sampling_freq ? kpb->config.sampling_freq : 16000;
919+
sink_params.sample_container_bytes = 4;
920+
sink_params.sample_valid_bytes = 4;
921+
sink_params.frame_fmt = SOF_IPC_FRAME_S32_LE;
922+
comp_params(sink_comp, &sink_params);
923+
comp_prepare(sink_comp);
924+
}
925+
}
926+
927+
kpb_change_state(kpb, KPB_STATE_RUN);
928+
890929
#ifndef CONFIG_IPC_MAJOR_4
891930
/* Search for KPB related sinks.
892931
* NOTE! We assume here that channel selector component device
@@ -936,10 +975,36 @@ static int kpb_prepare(struct comp_dev *dev)
936975
}
937976
#endif /* CONFIG_IPC_MAJOR_4 */
938977

978+
if (!kpb->sel_sink || !kpb->host_sink) {
979+
struct comp_buffer *sink;
980+
981+
comp_dev_for_each_consumer(dev, sink) {
982+
if (!kpb->sel_sink)
983+
kpb->sel_sink = sink;
984+
else if (!kpb->host_sink)
985+
kpb->host_sink = sink;
986+
}
987+
}
988+
939989
if (!kpb->sel_sink) {
940990
comp_err(dev, "could not find sink: sel_sink %p",
941991
kpb->sel_sink);
942992
ret = -EIO;
993+
} else {
994+
struct comp_dev *sink_comp = comp_buffer_get_sink_component(kpb->sel_sink);
995+
if (sink_comp && sink_comp->state == COMP_STATE_INIT) {
996+
struct sof_ipc_stream_params sink_params;
997+
memset_s(&sink_params, sizeof(sink_params), 0, sizeof(sink_params));
998+
sink_params.channels = kpb->config.channels ? kpb->config.channels : 2;
999+
sink_params.rate = kpb->config.sampling_freq ? kpb->config.sampling_freq : 16000;
1000+
sink_params.sample_container_bytes = 4;
1001+
sink_params.sample_valid_bytes = 4;
1002+
sink_params.frame_fmt = SOF_IPC_FRAME_S32_LE;
1003+
comp_params(sink_comp, &sink_params);
1004+
comp_prepare(sink_comp);
1005+
comp_info(dev, "kpb_prepare: prepared downstream sink_comp %d in state %d",
1006+
dev_comp_id(sink_comp), sink_comp->state);
1007+
}
9431008
}
9441009

9451010
kpb->sync_draining_mode = true;
@@ -1234,19 +1299,16 @@ static int kpb_copy(struct comp_dev *dev)
12341299
sink = kpb->sel_sink;
12351300
ret = PPL_STATUS_PATH_STOP;
12361301

1302+
comp_err(dev, "kpb_copy: source_buf=%p sel_sink=%p avail=%u",
1303+
source, sink, audio_stream_get_avail_bytes(&source->stream));
1304+
12371305
if (!sink) {
12381306
comp_err(dev, "no sink.");
12391307
ret = -EINVAL;
12401308
break;
12411309
}
12421310

1243-
/* Discard data if sink is not active */
1244-
if (comp_buffer_get_sink_component(sink)->state != COMP_STATE_ACTIVE) {
1245-
copy_bytes = audio_stream_get_avail_bytes(&source->stream);
1246-
comp_update_buffer_consume(source, copy_bytes);
1247-
comp_dbg(dev, "KD not active, dropping %zu bytes...", copy_bytes);
1248-
break;
1249-
}
1311+
/* Allow downstream WOV detector copy regardless of state */
12501312

12511313
/* Validate sink */
12521314
if (!audio_stream_get_wptr(&sink->stream)) {
@@ -1313,6 +1375,15 @@ static int kpb_copy(struct comp_dev *dev)
13131375
else
13141376
comp_update_buffer_produce(sink, produced_bytes);
13151377

1378+
struct comp_dev *wov_comp = sink ? comp_buffer_get_sink_component(sink) : NULL;
1379+
if (wov_comp) {
1380+
comp_err(dev, "kpb_copy: produced=%u bytes, triggering wov=0x%x",
1381+
copy_bytes, dev_comp_id(wov_comp));
1382+
comp_copy(wov_comp);
1383+
} else {
1384+
comp_err(dev, "kpb_copy: downstream sink_comp returned NULL!");
1385+
}
1386+
13161387
comp_update_buffer_consume(source, copy_bytes);
13171388

13181389
break;

src/audio/kpb.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "KPB"
33
uuid = UUIDREG_STR_KPB4
44
affinity_mask = "0x1"
5-
instance_count = "1"
5+
instance_count = "4"
66
domain_types = "0"
77
load_type = "0"
88
module_type = "0xB"

src/include/sof/audio/kpb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#endif
2323
struct comp_buffer;
24+
struct comp_dev *get_wov_detector_comp(uint32_t ppl_id);
2425

2526
/* KPB internal defines */
2627

tools/topology/topology2/include/components/kpb.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ Class.Widget."kpb" {
6767
num_input_audio_formats 1
6868
num_output_audio_formats 1
6969

70-
#UUID: D8218443-5FF3-4A4C-B388-6CFE07B9562E
71-
uuid "43:84:21:d8:f3:5f:4c:4a:b3:88:6c:fe:07:b9:56:2e"
70+
#UUID: a8a0cb32-4a77-4db1-85c753d7ee07bce6 (kpb4 static module)
71+
uuid "32:cb:a0:a8:77:4a:b1:4d:85:c7:53:d7:ee:07:bc:e6"
7272
no_pm "true"
7373
cpc 720000
7474
num_input_pins 1

0 commit comments

Comments
 (0)