|
18 | 18 | #include <sof/audio/component_ext.h> |
19 | 19 | #include <sof/audio/pipeline.h> |
20 | 20 | #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> |
21 | 24 | #include <sof/audio/ipc-config.h> |
22 | 25 | #include <sof/common.h> |
23 | 26 | #include <rtos/panic.h> |
24 | 27 | #include <sof/ipc/msg.h> |
| 28 | +#include <sof/ipc/topology.h> |
25 | 29 | #include <rtos/timer.h> |
26 | 30 | #include <rtos/alloc.h> |
27 | 31 | #include <rtos/clk.h> |
@@ -369,6 +373,9 @@ static int kpb_bind(struct comp_dev *dev, struct bind_info *bind_data) |
369 | 373 | sink_buf_id = buf_get_id(sink); |
370 | 374 |
|
371 | 375 | 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"); |
372 | 379 | if (sink_buf_id == 0) |
373 | 380 | kpb->sel_sink = sink; |
374 | 381 | else |
@@ -887,6 +894,38 @@ static int kpb_prepare(struct comp_dev *dev) |
887 | 894 | return -ENOMEM; |
888 | 895 | } |
889 | 896 |
|
| 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 | + |
890 | 929 | #ifndef CONFIG_IPC_MAJOR_4 |
891 | 930 | /* Search for KPB related sinks. |
892 | 931 | * NOTE! We assume here that channel selector component device |
@@ -936,10 +975,36 @@ static int kpb_prepare(struct comp_dev *dev) |
936 | 975 | } |
937 | 976 | #endif /* CONFIG_IPC_MAJOR_4 */ |
938 | 977 |
|
| 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 | + |
939 | 989 | if (!kpb->sel_sink) { |
940 | 990 | comp_err(dev, "could not find sink: sel_sink %p", |
941 | 991 | kpb->sel_sink); |
942 | 992 | 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 | + } |
943 | 1008 | } |
944 | 1009 |
|
945 | 1010 | kpb->sync_draining_mode = true; |
@@ -1234,19 +1299,16 @@ static int kpb_copy(struct comp_dev *dev) |
1234 | 1299 | sink = kpb->sel_sink; |
1235 | 1300 | ret = PPL_STATUS_PATH_STOP; |
1236 | 1301 |
|
| 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 | + |
1237 | 1305 | if (!sink) { |
1238 | 1306 | comp_err(dev, "no sink."); |
1239 | 1307 | ret = -EINVAL; |
1240 | 1308 | break; |
1241 | 1309 | } |
1242 | 1310 |
|
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 */ |
1250 | 1312 |
|
1251 | 1313 | /* Validate sink */ |
1252 | 1314 | if (!audio_stream_get_wptr(&sink->stream)) { |
@@ -1313,6 +1375,16 @@ static int kpb_copy(struct comp_dev *dev) |
1313 | 1375 | else |
1314 | 1376 | comp_update_buffer_produce(sink, produced_bytes); |
1315 | 1377 |
|
| 1378 | + uint32_t ppl_id = dev->pipeline ? dev->pipeline->pipeline_id : (dev_comp_id(dev) >> 16); |
| 1379 | + struct comp_dev *wov_comp = get_wov_detector_comp(ppl_id); |
| 1380 | + if (wov_comp) { |
| 1381 | + comp_err(dev, "kpb_copy: produced=%u bytes, triggering wov=0x%x", |
| 1382 | + copy_bytes, dev_comp_id(wov_comp)); |
| 1383 | + comp_copy(wov_comp); |
| 1384 | + } else { |
| 1385 | + comp_err(dev, "kpb_copy: get_wov_detector_comp(%u) returned NULL!", ppl_id); |
| 1386 | + } |
| 1387 | + |
1316 | 1388 | comp_update_buffer_consume(source, copy_bytes); |
1317 | 1389 |
|
1318 | 1390 | break; |
|
0 commit comments