Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 50 additions & 16 deletions src/audio/kpb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,13 +1143,23 @@ static void kpb_micselect_copy16(struct comp_buffer *sink,
ae_int16 *out_ptr;

for (ch = 0; ch < micsel_channels; ch++) {
const ae_int16 *input_data = (const ae_int16 *)(in_ptr) + offsets[ch];
const ae_int16 *input_frame = in_ptr;
size_t copied = 0;

out_ptr = audio_stream_get_wptr(ostream);
out_ptr += ch;
for (i = 0; i < samples_per_chan; i++) {
AE_L16_XP(d16, input_data, in_offset);
AE_S16_0_XC(d16, out_ptr, out_offset);
while (copied < samples_per_chan) {
size_t frames = audio_stream_frames_without_wrap(istream, input_frame);
const ae_int16 *input_data = input_frame + offsets[ch];

frames = MIN(frames, samples_per_chan - copied);
for (i = 0; i < frames; i++) {
AE_L16_XP(d16, input_data, in_offset);
AE_S16_0_XC(d16, out_ptr, out_offset);
}
input_frame = audio_stream_wrap(istream,
(void *)(input_frame + frames * in_channels));
copied += frames;
}
}
}
Expand Down Expand Up @@ -1178,13 +1188,23 @@ static void kpb_micselect_copy32(struct comp_buffer *sink,
ae_int32 *out_ptr;

for (ch = 0; ch < micsel_channels; ch++) {
const ae_int32 *input_data = (const ae_int32 *)(in_ptr) + offsets[ch];
const ae_int32 *input_frame = in_ptr;
size_t copied = 0;

out_ptr = audio_stream_get_wptr(ostream);
out_ptr += ch;
for (i = 0; i < samples_per_chan; i++) {
AE_L32_XP(d32, input_data, in_offset);
AE_S32_L_XC(d32, out_ptr, out_offset);
while (copied < samples_per_chan) {
size_t frames = audio_stream_frames_without_wrap(istream, input_frame);
const ae_int32 *input_data = input_frame + offsets[ch];

frames = MIN(frames, samples_per_chan - copied);
for (i = 0; i < frames; i++) {
AE_L32_XP(d32, input_data, in_offset);
AE_S32_L_XC(d32, out_ptr, out_offset);
}
input_frame = audio_stream_wrap(istream,
(void *)(input_frame + frames * in_channels));
copied += frames;
}
}
}
Expand All @@ -1211,12 +1231,16 @@ static void kpb_micselect_copy16(struct comp_buffer *sink,
out_data = audio_stream_get_wptr(ostream);

for (size_t i = 0; i < samples_per_chan * in_channels; i += in_channels) {
const int16_t *in_sample = audio_stream_get_frag(istream, in_data,
i + offsets[ch],
sizeof(*in_sample));

if (&out_data[out_samples + ch]
>= (int16_t *)audio_stream_get_end_addr(ostream)) {
out_data = (int16_t *)audio_stream_get_addr(ostream);
out_samples = 0;
}
out_data[out_samples + ch] = in_data[i + offsets[ch]];
out_data[out_samples + ch] = *in_sample;
out_samples += micsel_channels;
}
}
Expand All @@ -1242,12 +1266,16 @@ static void kpb_micselect_copy32(struct comp_buffer *sink,
out_data = audio_stream_get_wptr(ostream);

for (size_t i = 0; i < samples_per_chan * in_channels; i += in_channels) {
const int32_t *in_sample = audio_stream_get_frag(istream, in_data,
i + offsets[ch],
sizeof(*in_sample));

if (&out_data[out_samples + ch]
>= (int32_t *)audio_stream_get_end_addr(ostream)) {
out_data = (int32_t *)audio_stream_get_addr(ostream);
out_samples = 0;
}
out_data[out_samples + ch] = in_data[i + offsets[ch]];
out_data[out_samples + ch] = *in_sample;
out_samples += micsel_channels;
}
}
Expand Down Expand Up @@ -1326,7 +1354,6 @@ static int kpb_copy(struct comp_dev *dev)
case KPB_STATE_RUN:
/* In normal RUN state we simply copy to our sink. */
sink = kpb->sel_sink;
ret = PPL_STATUS_PATH_STOP;

if (!sink) {
comp_err(dev, "no sink.");
Expand All @@ -1339,6 +1366,7 @@ static int kpb_copy(struct comp_dev *dev)
copy_bytes = audio_stream_get_avail_bytes(&source->stream);
comp_update_buffer_consume(source, copy_bytes);
comp_dbg(dev, "KD not active, dropping %zu bytes...", copy_bytes);
ret = PPL_STATUS_PATH_STOP;
break;
}

Expand All @@ -1354,7 +1382,8 @@ static int kpb_copy(struct comp_dev *dev)
comp_err(dev, "nothing to copy sink->free %u source->avail %u",
audio_stream_get_free_bytes(&sink->stream),
audio_stream_get_avail_bytes(&source->stream));
ret = PPL_STATUS_PATH_STOP;
if (!audio_stream_get_avail_bytes(&sink->stream))
ret = PPL_STATUS_PATH_STOP;
break;
}

Expand All @@ -1375,7 +1404,8 @@ static int kpb_copy(struct comp_dev *dev)
comp_err(dev, "nothing to copy sink->free %u source->avail %u",
free,
avail);
ret = PPL_STATUS_PATH_STOP;
if (!audio_stream_get_avail_bytes(&sink->stream))
ret = PPL_STATUS_PATH_STOP;
break;
}
kpb_micselect_copy(dev, sink, source, produced_bytes, channels);
Expand All @@ -1390,7 +1420,6 @@ static int kpb_copy(struct comp_dev *dev)
comp_err(dev, "internal buffering failed.");
break;
}
ret = PPL_STATUS_PATH_STOP;

/* Update buffered size. NOTE! We only record buffered
* data up to the size of history buffer.
Expand Down Expand Up @@ -1708,7 +1737,6 @@ static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli)
static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli)
{
struct comp_data *kpb = comp_get_drvdata(dev);
bool is_sink_ready = (comp_buffer_get_sink_state(kpb->host_sink) == COMP_STATE_ACTIVE);
size_t sample_width = kpb->config.sampling_width;
size_t drain_req = (size_t)cli->drain_req * kpb->config.channels *
(kpb->config.sampling_freq / 1000) *
Expand All @@ -1727,12 +1755,18 @@ static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli)
comp_info(dev, "requested draining of %d [ms] from history buffer",
cli->drain_req);

/* The drain pin stays unbound when a client only signals detections. */
if (!kpb->host_sink) {
comp_dbg(dev, "no draining sink, ignoring request");
return;
}

if (kpb->state != KPB_STATE_RUN) {
comp_err(dev, "wrong KPB state");
} else if (cli->id > KPB_MAX_NO_OF_CLIENTS) {
comp_err(dev, "wrong client id");
/* TODO: check also if client is registered */
} else if (!is_sink_ready) {
} else if (comp_buffer_get_sink_state(kpb->host_sink) != COMP_STATE_ACTIVE) {
comp_err(dev, "sink not ready for draining");
} else if (kpb->hd.buffered < drain_req ||
cli->drain_req > KPB_MAX_DRAINING_REQ) {
Expand Down
Loading