From 0bcc48081f34dfcb32cc53eaa6195723f0d156b7 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Thu, 16 May 2019 11:46:56 +0200 Subject: [PATCH 01/12] kpb: add new, more clear states This patch adds new state KPB_STATE_DRAINING. In this state kpb drains data from internal history buffer to host sink bypassig any other component. In the same time internal buffering is turned off. Signed-off-by: Marcin Rajwa --- src/audio/kpb.c | 17 ++++++++--------- src/include/sof/audio/kpb.h | 3 ++- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index a5b786ee6896..a839c86a2012 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -465,14 +465,11 @@ static int kpb_copy(struct comp_dev *dev) sink = (kpb->state == KPB_STATE_BUFFERING) ? kpb->rt_sink : kpb->cli_sink; - /* Pause selector copy during draining and/or draining on demand. - * We keep selector in this "paused" state as long as draining - * is going and later during direct copy to client's/host sink, - * in so called "draining on demand" state. In order to rearm - * detection algorithm kpb_reset is needed. - */ - if (kpb->state != KPB_STATE_BUFFERING) + /* Stop copying downstream if in draining mode */ + if (kpb->state == KPB_STATE_DRAINING) { + comp_update_buffer_consume(source, source->avail); return PPL_STATUS_PATH_STOP; + } /* Process source data */ /* Check if there are valid pointers */ @@ -693,6 +690,7 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) size_t history_depth = cli->history_depth * kpb->config.no_channels * (kpb->config.sampling_freq / 1000) * (kpb->config.sampling_width / 8); + struct hb *buff = kpb->history_buffer; struct hb *first_buff = buff; size_t buffered = 0; @@ -776,6 +774,7 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) /* Pause selector copy. */ kpb->rt_sink->sink->state = COMP_STATE_PAUSED; + kpb->state = KPB_STATE_DRAINING; /* Set host-sink copy mode to blocking */ comp_set_attribute(kpb->cli_sink->sink, @@ -839,9 +838,9 @@ static uint64_t kpb_draining_task(void *arg) } /* Draining is done. Now switch KPB to copy real time stream - * to client's sink + * to client's sink. This state is called "draining on demand" */ - *draining_data->state = KPB_STATE_DRAINING_ON_DEMAND; + *draining_data->state = KPB_STATE_HOST_COPY; /* Reset host-sink copy mode back to unblocking */ comp_set_attribute(sink->sink, COMP_ATTR_COPY_BLOCKING, 0); diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index 9939429cb502..6ecba42bd5ce 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -35,7 +35,8 @@ enum kpb_state { KPB_STATE_BUFFERING = 0, - KPB_STATE_DRAINING_ON_DEMAND, + KPB_STATE_DRAINING, + KPB_STATE_HOST_COPY, }; enum kpb_event { From 6b4aedae98821908b10be3b044d4a4248c862a1b Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Thu, 16 May 2019 11:54:39 +0200 Subject: [PATCH 02/12] detector: add history depth as config option Detector was using keyphrase_length to: 1. delay detection 2. to calculate the amount of data that shall be drained from history buffer. This was confusing people, therefore we use two separate variables name with better naming. 1. history_depth -> to define default draining request. (in bytes) 2. preamble_time -> to define delay after which detection should be active. Signed-off-by: Marcin Rajwa --- src/audio/detect_test.c | 19 +++++++++++++------ src/include/user/detect_test.h | 10 ++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index d0713d6421d2..9de4c754f737 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -40,6 +40,7 @@ struct comp_data { uint32_t detect_preamble; /**< current keyphrase preamble length */ uint32_t keyphrase_samples; /**< keyphrase length in samples */ uint32_t buf_copy_pos; /**< current copy position for incoming data */ + uint32_t history_depth; /** defines draining size in bytes. */ struct notify_data event; struct kpb_event_data event_data; @@ -73,9 +74,9 @@ static void notify_kpb(struct comp_dev *dev) cd->client_data.history_end = 0; /**< keyphrase end, 0 is now */ cd->client_data.history_begin = cd->detect_preamble; /* time in milliseconds */ - cd->client_data.history_depth = cd->detect_preamble / - (dev->params.rate / 1000); - + cd->client_data.history_depth = (cd->history_depth != 0) ? + cd->history_depth : + cd->config.history_depth; cd->event_data.event_id = KPB_EVENT_BEGIN_DRAINING; cd->event_data.client_data = &cd->client_data; @@ -118,6 +119,12 @@ static void default_detect_test(struct comp_dev *dev, if (cd->detect_preamble >= cd->keyphrase_samples) { if (cd->activation >= cd->config.activation_threshold) { + /* The algorithm shall use cd->history_depth + * to specify its draining size request. + * Zero value means default config value + * will be used. + */ + cd->history_depth = 0; detect_test_notify(dev); cd->detected = 1; } @@ -280,14 +287,14 @@ static int test_keyword_params(struct comp_dev *dev) dev->frame_bytes = comp_frame_bytes(dev); /* calculate the length of the preamble */ - if (cd->config.keyphrase_length) { - if (cd->config.keyphrase_length > KPB_MAX_BUFF_TIME) { + if (cd->config.preamble_time) { + if (cd->config.preamble_time > KPB_MAX_BUFF_TIME) { trace_keyword_error("test_keyword_params() " "error: kp length too long"); return -EINVAL; } - cd->keyphrase_samples = cd->config.keyphrase_length * + cd->keyphrase_samples = cd->config.preamble_time * (dev->params.rate / 1000); } else { cd->keyphrase_samples = KEYPHRASE_DEFAULT_PREAMBLE_LENGTH; diff --git a/src/include/user/detect_test.h b/src/include/user/detect_test.h index d56efd084281..02cc85a84863 100644 --- a/src/include/user/detect_test.h +++ b/src/include/user/detect_test.h @@ -18,9 +18,8 @@ struct sof_detect_test_config { /** synthetic system load settings */ uint32_t load_mips; uint32_t load_memory_size; - - /** length of the keyphrase in milliseconds */ - uint32_t keyphrase_length; + /** time in ms after which detection is activated */ + uint32_t preamble_time; /** activation right shift, determines the speed of activation */ uint16_t activation_shift; @@ -28,8 +27,11 @@ struct sof_detect_test_config { /** activation threshold */ int16_t activation_threshold; + /** default draining size in bytes */ + uint32_t history_depth; + /** reserved for future use */ - uint32_t reserved[3]; + uint32_t reserved[2]; } __attribute__((packed)); /** used for binary blob size sanity checks */ From 5c6c90c84fff8060562f4ee4c69afd86dd5f86eb Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Thu, 16 May 2019 11:58:13 +0200 Subject: [PATCH 03/12] topology: provide default config for new detector params This patch provides default parameters for newly added detect_preamble and history_depth. Both by default are set to max buffering time of KPB. Signed-off-by: Marcin Rajwa --- tools/topology/m4/detect_test_coef.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/topology/m4/detect_test_coef.m4 b/tools/topology/m4/detect_test_coef.m4 index 6358be7ad8ec..bf02e54d3577 100644 --- a/tools/topology/m4/detect_test_coef.m4 +++ b/tools/topology/m4/detect_test_coef.m4 @@ -5,7 +5,7 @@ CONTROLBYTES_PRIV(DETECTOR_priv, ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' ` 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,' -` 0x03,0x00,0xff,0x3f,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x34,0x08,0x00,0x00,' +` 0x03,0x00,0xff,0x3f,0x34,0x08,0x00,0x00,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"' ) From b69b47afb32cd8df07ff48553837028dbc391274 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Thu, 16 May 2019 13:16:53 +0200 Subject: [PATCH 04/12] detector: remove unused notification data Remove history_begin and history_end members from kpb as they are not used anywhere. Signed-off-by: Marcin Rajwa --- src/audio/detect_test.c | 2 -- src/include/sof/audio/kpb.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index 9de4c754f737..c8e2c2fdd8f5 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -71,8 +71,6 @@ static void notify_kpb(struct comp_dev *dev) cd->client_data.r_ptr = NULL; cd->client_data.sink = NULL; cd->client_data.id = 0; /**< TODO: acquire proper id from kpb */ - cd->client_data.history_end = 0; /**< keyphrase end, 0 is now */ - cd->client_data.history_begin = cd->detect_preamble; /* time in milliseconds */ cd->client_data.history_depth = (cd->history_depth != 0) ? cd->history_depth : diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index 6ecba42bd5ce..26b596465381 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -62,8 +62,6 @@ enum kpb_client_state { struct kpb_client { uint8_t id; /**< id associated with output sink */ uint32_t history_depth; /**< normalized value of buffered bytes */ - uint32_t history_begin; /**< place where key phrase begins */ - uint32_t history_end; /**< place where key phrase ends */ enum kpb_client_state state; /**< current state of a client */ void *r_ptr; /**< current read position */ struct comp_buffer *sink; /**< client's sink */ From 1517583f5946e6e1a32e291a89b9e4084984f8fb Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Fri, 17 May 2019 01:37:15 +0200 Subject: [PATCH 05/12] kpb: add additional log message into draining task This patch adds two new trace messages into draining task - the amount of drained data and time needed to drain them in milliseconds. Signed-off-by: Marcin Rajwa --- src/audio/kpb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index a839c86a2012..f49a9060b991 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -22,6 +22,7 @@ #include #include #include +#include /* KPB private data, runtime data */ struct comp_data { @@ -803,9 +804,14 @@ static uint64_t kpb_draining_task(void *arg) size_t size_to_read; size_t size_to_copy; bool move_buffer = false; + uint32_t drained = 0; + uint64_t time_start; + uint64_t time_end; trace_kpb("kpb_draining_task(), start."); + time_start = platform_timer_get(platform_timer); + while (history_depth > 0) { size_to_read = (uint32_t)buff->end_addr - (uint32_t)buff->r_ptr; @@ -827,6 +833,7 @@ static uint64_t kpb_draining_task(void *arg) size_to_copy)); buff->r_ptr += (uint32_t)size_to_copy; history_depth -= size_to_copy; + drained += size_to_copy; if (move_buffer) { buff->r_ptr = buff->start_addr; @@ -837,6 +844,8 @@ static uint64_t kpb_draining_task(void *arg) comp_update_buffer_produce(sink, size_to_copy); } + time_end = platform_timer_get(platform_timer); + /* Draining is done. Now switch KPB to copy real time stream * to client's sink. This state is called "draining on demand" */ @@ -845,7 +854,10 @@ static uint64_t kpb_draining_task(void *arg) /* Reset host-sink copy mode back to unblocking */ comp_set_attribute(sink->sink, COMP_ATTR_COPY_BLOCKING, 0); - trace_kpb("kpb_draining_task(), done."); + trace_kpb("kpb_draining_task(), done. %u drained in %d ms.", + drained, + (time_end - time_start) + / clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1)); return 0; } From ab40a0477d7625420e5150fb53e2d5a39f6006be Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Fri, 17 May 2019 01:38:37 +0200 Subject: [PATCH 06/12] detector: remove unnecessary preamble time verification Remove unnecessary check of preamble time. Previously it was allowing preamble time smaller than kpb buffering time. There is no reason for such a constrain. Signed-off-by: Marcin Rajwa --- src/audio/detect_test.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index c8e2c2fdd8f5..5521e3cce208 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -286,12 +286,6 @@ static int test_keyword_params(struct comp_dev *dev) /* calculate the length of the preamble */ if (cd->config.preamble_time) { - if (cd->config.preamble_time > KPB_MAX_BUFF_TIME) { - trace_keyword_error("test_keyword_params() " - "error: kp length too long"); - return -EINVAL; - } - cd->keyphrase_samples = cd->config.preamble_time * (dev->params.rate / 1000); } else { From 1fec5683641c21321a8eccb6df9a38f624d85af7 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Fri, 17 May 2019 01:45:24 +0200 Subject: [PATCH 07/12] detector: set default preamble time to 0 With this patch default preamble is set to zero meaning KWD is activated from start, no delay. Signed-off-by: Marcin Rajwa --- src/audio/detect_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index 5521e3cce208..d9a7f4edf631 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -29,8 +29,8 @@ #define ACTIVATION_DEFAULT_THRESHOLD_S16 \ ((int16_t)((INT16_MAX) * (ACTIVATION_DEFAULT_THRESHOLD))) -/* number of samples to be treated as a full keyphrase */ -#define KEYPHRASE_DEFAULT_PREAMBLE_LENGTH (30 * 1024) +/* default number of samples before detection is activated */ +#define KEYPHRASE_DEFAULT_PREAMBLE_LENGTH 0 struct comp_data { struct sof_detect_test_config config; From a6526512bac6b077e6e3a964764a8ccc79e0bf4a Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Fri, 17 May 2019 12:10:50 +0200 Subject: [PATCH 08/12] kpb: replace draining and copy *memcpy* use with safer method memcpy function doesn't care about "wrap-ups" and sample sizes which are crucial in copy of audio signals. Signed-off-by: Marcin Rajwa --- src/audio/kpb.c | 84 +++++++++++++++++++++++++++++++++---- src/include/sof/audio/kpb.h | 4 ++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index f49a9060b991..f4d924ccf2e6 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -54,9 +54,13 @@ static size_t kpb_allocate_history_buffer(struct comp_data *kpb); static void kpb_clear_history_buffer(struct hb *buff); static void kpb_free_history_buffer(struct hb *buff); static bool kpb_has_enough_history_data(struct comp_data *kpb, - struct hb *buff, size_t his_req); + struct hb *buff, size_t his_req); static inline bool kpb_is_sample_width_supported(uint32_t sampling_width); - +static void kpb_copy_samples(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, + size_t sample_width); +static void kpb_drain_samples(void *source, struct comp_buffer *sink, + size_t size, size_t sample_width); /** * \brief Create a key phrase buffer component. @@ -498,7 +502,8 @@ static int kpb_copy(struct comp_dev *dev) /* Sink and source are both ready and have space */ copy_bytes = MIN(sink->free, source->avail); - assert(!memcpy_s(sink->w_ptr, copy_bytes, source->r_ptr, copy_bytes)); + kpb_copy_samples(sink, source, copy_bytes, + kpb->config.sampling_width); /* Buffer source data internally in history buffer for future * use by clients. @@ -687,10 +692,11 @@ static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli) */ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) { - bool is_sink_ready = (kpb->cli_sink->sink->state == COMP_STATE_ACTIVE); + bool is_sink_ready = (kpb->host_sink->sink->state == COMP_STATE_ACTIVE); + size_t sample_width = kpb->config.sampling_width; size_t history_depth = cli->history_depth * kpb->config.no_channels * (kpb->config.sampling_freq / 1000) * - (kpb->config.sampling_width / 8); + (sample_width / 8); struct hb *buff = kpb->history_buffer; struct hb *first_buff = buff; @@ -772,6 +778,7 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) kpb->draining_task_data.history_buffer = buff; kpb->draining_task_data.history_depth = history_depth; kpb->draining_task_data.state = &kpb->state; + kpb->draining_task_data.sample_width = sample_width; /* Pause selector copy. */ kpb->rt_sink->sink->state = COMP_STATE_PAUSED; @@ -801,6 +808,7 @@ static uint64_t kpb_draining_task(void *arg) struct comp_buffer *sink = draining_data->sink; struct hb *buff = draining_data->history_buffer; size_t history_depth = draining_data->history_depth; + size_t sample_width = draining_data->sample_width; size_t size_to_read; size_t size_to_copy; bool move_buffer = false; @@ -829,8 +837,9 @@ static uint64_t kpb_draining_task(void *arg) } } - assert(!memcpy_s(sink->w_ptr, size_to_copy, buff->r_ptr, - size_to_copy)); + kpb_drain_samples(buff->r_ptr, sink, size_to_copy, + sample_width); + buff->r_ptr += (uint32_t)size_to_copy; history_depth -= size_to_copy; drained += size_to_copy; @@ -862,6 +871,36 @@ static uint64_t kpb_draining_task(void *arg) return 0; } +/** + * \brief Drain data samples safe, according to configuration. + * + * \param[in] dev - kpb component device pointer + * \param[in] sink - pointer to sink buffer. + * \param[in] source - pointer to source buffer. + * \param[in] size - requested copy size in bytes. + * + * \return none. + */ +static void kpb_drain_samples(void *source, struct comp_buffer *sink, + size_t size, size_t sample_width) +{ + int16_t *dest; + int16_t *src = (int16_t *)source; + uint32_t i; + uint32_t j = 0; + uint32_t channel; + uint32_t frames = KPB_BYTES_TO_FRAMES(size, sample_width); + + for (i = 0; i < frames; i++) { + for (channel = 0; channel < KPB_NR_OF_CHANNELS; channel++) { + dest = buffer_write_frag_s16(sink, j); + *dest = *src; + src++; + j++; + } + } +} + /** * \brief Initialize history buffer by zeroing its memory. * \param[in] buff - pointer to current history buffer. @@ -952,6 +991,37 @@ static inline bool kpb_is_sample_width_supported(uint32_t sampling_width) return ret; } +/** + * \brief Copy data samples safe, according to configuration. + * + * \param[in] dev - kpb component device pointer + * \param[in] sink - pointer to sink buffer. + * \param[in] source - pointer to source buffer. + * \param[in] size - requested copy size in bytes. + * + * \return none. + */ +static void kpb_copy_samples(struct comp_buffer *sink, + struct comp_buffer *source, size_t size, + size_t sample_width) +{ + int16_t *src; + int16_t *dest; + uint32_t i; + uint32_t j = 0; + uint32_t channel; + uint32_t frames = KPB_BYTES_TO_FRAMES(size, sample_width); + + for (i = 0; i < frames; i++) { + for (channel = 0; channel < KPB_NR_OF_CHANNELS; channel++) { + src = buffer_read_frag_s16(source, j); + dest = buffer_write_frag_s16(sink, j); + *dest = *src; + j++; + } + } +} + struct comp_driver comp_kpb = { .type = SOF_COMP_KPB, .ops = { diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index 26b596465381..685064f5b766 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -32,6 +32,9 @@ #define KPB_NO_OF_HISTORY_BUFFERS 2 /**< no of internal buffers */ #define KPB_ALLOCATION_STEP 0x100 #define KPB_NO_OF_MEM_POOLS 3 +#define KPB_BYTES_TO_FRAMES(bytes, sample_width) \ + (bytes / ((KPB_SAMPLE_CONTAINER_SIZE(sample_width) / 8) * \ + KPB_NR_OF_CHANNELS)) enum kpb_state { KPB_STATE_BUFFERING = 0, @@ -94,6 +97,7 @@ struct dd { size_t history_depth; uint8_t is_draining_active; enum kpb_state *state; + size_t sample_width; }; /** \brief kpb component configuration data. */ From b190d1a5b1770611ad0f323a61f8b0262bb431f4 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Tue, 21 May 2019 14:44:17 +0200 Subject: [PATCH 09/12] kpb: rename sinks to be more understandable Kpb rt_sink is confusing and was replaced with sel_sink which stands for selector sink - the component to which KPB copies during BUFFERING state. Likewise the cli_sink was replaced to host_sink clearly stating that we copy out of DSP. Signed-off-by: Marcin Rajwa --- src/audio/kpb.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index f4d924ccf2e6..cd847a61c149 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -34,8 +34,8 @@ struct comp_data { uint32_t source_period_bytes; /**< source number of period bytes */ uint32_t sink_period_bytes; /**< sink number of period bytes */ struct sof_kpb_config config; /**< component configuration data */ - struct comp_buffer *rt_sink; /**< real time sink (channel selector ) */ - struct comp_buffer *cli_sink; /**< draining sink (client) */ + struct comp_buffer *sel_sink; /**< real time sink (channel selector ) */ + struct comp_buffer *host_sink; /**< draining sink (client) */ struct hb *history_buffer; bool is_internal_buffer_full; size_t buffered_data; @@ -384,10 +384,10 @@ static int kpb_prepare(struct comp_dev *dev) } if (sink->sink->comp.type == SOF_COMP_SELECTOR) { /* We found proper real time sink */ - cd->rt_sink = sink; + cd->sel_sink = sink; } else if (sink->sink->comp.type == SOF_COMP_HOST) { /* We found proper host sink */ - cd->cli_sink = sink; + cd->host_sink = sink; } } @@ -467,8 +467,8 @@ static int kpb_copy(struct comp_dev *dev) /* Get source and sink buffers */ source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - sink = (kpb->state == KPB_STATE_BUFFERING) ? kpb->rt_sink - : kpb->cli_sink; + sink = (kpb->state == KPB_STATE_BUFFERING) ? kpb->sel_sink + : kpb->host_sink; /* Stop copying downstream if in draining mode */ if (kpb->state == KPB_STATE_DRAINING) { @@ -697,7 +697,6 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) size_t history_depth = cli->history_depth * kpb->config.no_channels * (kpb->config.sampling_freq / 1000) * (sample_width / 8); - struct hb *buff = kpb->history_buffer; struct hb *first_buff = buff; size_t buffered = 0; @@ -774,18 +773,18 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) trace_kpb("kpb_init_draining(), schedule draining task"); /* Add one-time draining task into the scheduler. */ - kpb->draining_task_data.sink = kpb->cli_sink; + kpb->draining_task_data.sink = kpb->host_sink; kpb->draining_task_data.history_buffer = buff; kpb->draining_task_data.history_depth = history_depth; kpb->draining_task_data.state = &kpb->state; kpb->draining_task_data.sample_width = sample_width; /* Pause selector copy. */ - kpb->rt_sink->sink->state = COMP_STATE_PAUSED; + kpb->sel_sink->sink->state = COMP_STATE_PAUSED; kpb->state = KPB_STATE_DRAINING; /* Set host-sink copy mode to blocking */ - comp_set_attribute(kpb->cli_sink->sink, + comp_set_attribute(kpb->host_sink->sink, COMP_ATTR_COPY_BLOCKING, 1); /* Schedule draining task */ From 649bfc987571313fc45f361e34104dba6eb6140f Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Wed, 5 Jun 2019 22:50:45 +0200 Subject: [PATCH 10/12] kpb: remove redundant pause of selector in kpb_init_draining() After detection of keyword we shall stop further copy to selector pipeline. We do this in regular copy() function so there is no need to do it also in init_draining() function. Signed-off-by: Marcin Rajwa --- src/audio/kpb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index cd847a61c149..d96b033d5c55 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -779,8 +779,7 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) kpb->draining_task_data.state = &kpb->state; kpb->draining_task_data.sample_width = sample_width; - /* Pause selector copy. */ - kpb->sel_sink->sink->state = COMP_STATE_PAUSED; + /* Change KPB internal state to DRAINING */ kpb->state = KPB_STATE_DRAINING; /* Set host-sink copy mode to blocking */ From bc4887f204e3934c5c099ef6d74b6f35006695c3 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Mon, 10 Jun 2019 13:09:20 +0200 Subject: [PATCH 11/12] platform: include clk.h in platform.h for imx8 target. The CLK_CPU macro is undefined for imx8 platform therefore shall be added. Signed-off-by: Marcin Rajwa --- src/platform/imx8/include/platform/platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/imx8/include/platform/platform.h b/src/platform/imx8/include/platform/platform.h index c8778687b62c..96c8357d0771 100644 --- a/src/platform/imx8/include/platform/platform.h +++ b/src/platform/imx8/include/platform/platform.h @@ -10,6 +10,7 @@ #include #include +#include struct sof; From 508e2452c1de2c1318282638b6ce8eea11a49bdb Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Tue, 11 Jun 2019 10:26:13 +0200 Subject: [PATCH 12/12] cmocka: update KPB tests for new dependencies KPB source code started to use timer related features therefore cmocka tests need to include these dependencies. Signed-off-by: Marcin Rajwa --- test/cmocka/src/audio/kpb/kpb_mock.c | 16 ++++++++++++++++ test/cmocka/src/audio/kpb/kpb_mock.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/test/cmocka/src/audio/kpb/kpb_mock.c b/test/cmocka/src/audio/kpb/kpb_mock.c index a803bab161ad..7b0eae9cddc9 100644 --- a/test/cmocka/src/audio/kpb/kpb_mock.c +++ b/test/cmocka/src/audio/kpb/kpb_mock.c @@ -14,6 +14,7 @@ #include #include #include +#include TRACE_IMPL() @@ -73,3 +74,18 @@ void __panic(uint32_t p, char *filename, uint32_t linenum) (void)filename; (void)linenum; } + +uint64_t platform_timer_get(struct timer *timer) +{ + (void)timer; + + return 0; +} + +uint64_t clock_ms_to_ticks(int clock, uint64_t ms) +{ + (void)clock; + (void)ms; + + return 0; +} diff --git a/test/cmocka/src/audio/kpb/kpb_mock.h b/test/cmocka/src/audio/kpb/kpb_mock.h index b9fbdc738a28..5f3e67d79dfd 100644 --- a/test/cmocka/src/audio/kpb/kpb_mock.h +++ b/test/cmocka/src/audio/kpb/kpb_mock.h @@ -6,3 +6,5 @@ */ int comp_set_state(struct comp_dev *dev, int cmd); + +struct timer *platform_timer;