audio: invalidate and writeback buffers where needed

Calls buffer_invalidate and buffer_writeback in audio components
processing functions. It is required to achieve data synchronization
in case buffers are inter-core.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2020-02-10 10:46:25 +01:00 committed by Liam Girdwood
parent cf774d14e2
commit 0bd252253e
11 changed files with 120 additions and 60 deletions

View File

@ -789,14 +789,35 @@ static int asrc_control_loop(struct comp_dev *dev, struct comp_data *cd)
return 0;
}
static void asrc_process(struct comp_dev *dev, struct comp_buffer *source,
struct comp_buffer *sink)
{
struct comp_data *cd = comp_get_drvdata(dev);
int consumed = 0;
int produced = 0;
/* consumed bytes are not known at this point */
buffer_invalidate(source, source->stream.size);
cd->asrc_func(dev, &source->stream, &sink->stream, &consumed,
&produced);
buffer_writeback(sink, produced *
audio_stream_frame_bytes(&sink->stream));
comp_dbg(dev, "asrc_copy(), consumed = %u, produced = %u",
consumed, produced);
comp_update_buffer_consume(source, consumed *
audio_stream_frame_bytes(&source->stream));
comp_update_buffer_produce(sink, produced *
audio_stream_frame_bytes(&sink->stream));
}
/* copy and process stream data from source to sink buffers */
static int asrc_copy(struct comp_dev *dev)
{
struct comp_data *cd = comp_get_drvdata(dev);
struct comp_buffer *source;
struct comp_buffer *sink;
int consumed = 0;
int produced = 0;
int frames_src;
int frames_snk;
int ret;
@ -835,22 +856,7 @@ static int asrc_copy(struct comp_dev *dev)
}
if (cd->source_frames && cd->sink_frames)
cd->asrc_func(dev, &source->stream, &sink->stream, &consumed,
&produced);
comp_dbg(dev, "asrc_copy(), consumed = %u, produced = %u",
consumed, produced);
/* Calc new free and available if data was processed. These
* functions must not be called with 0 consumed/produced.
*/
if (consumed > 0)
comp_update_buffer_consume(source, consumed *
audio_stream_frame_bytes(&source->stream));
if (produced > 0)
comp_update_buffer_produce(sink, produced *
audio_stream_frame_bytes(&sink->stream));
asrc_process(dev, source, sink);
return 0;
}

View File

@ -728,6 +728,7 @@ static int test_keyword_copy(struct comp_dev *dev)
struct comp_buffer, sink_list);
/* copy and perform detection */
buffer_invalidate(source, source->stream.avail);
cd->detect_func(dev, &source->stream,
source->stream.avail /
audio_stream_frame_bytes(&source->stream));

View File

@ -687,6 +687,24 @@ static int eq_fir_trigger(struct comp_dev *dev, int cmd)
return comp_set_state(dev, cmd);
}
static void eq_fir_process(struct comp_dev *dev, struct comp_buffer *source,
struct comp_buffer *sink, int frames,
uint32_t source_bytes, uint32_t sink_bytes)
{
struct comp_data *cd = comp_get_drvdata(dev);
buffer_invalidate(source, source_bytes);
cd->eq_fir_func(cd->fir, &source->stream, &sink->stream, frames,
source->stream.channels);
buffer_writeback(sink, sink_bytes);
/* calc new free and available */
comp_update_buffer_consume(source, source_bytes);
comp_update_buffer_produce(sink, sink_bytes);
}
/* copy and process stream data from source to sink buffers */
static int eq_fir_copy(struct comp_dev *dev)
{
@ -732,12 +750,9 @@ static int eq_fir_copy(struct comp_dev *dev)
n = (cl.frames >> 1) << 1;
/* Run EQ function */
cd->eq_fir_func(cd->fir, &sourceb->stream, &sinkb->stream, n,
sourceb->stream.channels);
/* calc new free and available */
comp_update_buffer_consume(sourceb, n * cl.source_frame_bytes);
comp_update_buffer_produce(sinkb, n * cl.sink_frame_bytes);
eq_fir_process(dev, sourceb, sinkb, n,
n * cl.source_frame_bytes,
n * cl.sink_frame_bytes);
}
return 0;

View File

@ -778,6 +778,23 @@ static int eq_iir_trigger(struct comp_dev *dev, int cmd)
return comp_set_state(dev, cmd);
}
static void eq_iir_process(struct comp_dev *dev, struct comp_buffer *source,
struct comp_buffer *sink, int frames,
uint32_t source_bytes, uint32_t sink_bytes)
{
struct comp_data *cd = comp_get_drvdata(dev);
buffer_invalidate(source, source_bytes);
cd->eq_iir_func(dev, &source->stream, &sink->stream, frames);
buffer_writeback(sink, sink_bytes);
/* calc new free and available */
comp_update_buffer_consume(source, source_bytes);
comp_update_buffer_produce(sink, sink_bytes);
}
/* copy and process stream data from source to sink buffers */
static int eq_iir_copy(struct comp_dev *dev)
{
@ -811,11 +828,8 @@ static int eq_iir_copy(struct comp_dev *dev)
comp_get_copy_limits(sourceb, sinkb, &cl);
/* Run EQ function */
cd->eq_iir_func(dev, &sourceb->stream, &sinkb->stream, cl.frames);
/* calc new free and available */
comp_update_buffer_consume(sourceb, cl.source_bytes);
comp_update_buffer_produce(sinkb, cl.sink_bytes);
eq_iir_process(dev, sourceb, sinkb, cl.frames, cl.source_bytes,
cl.sink_bytes);
return 0;
}

View File

@ -81,8 +81,8 @@ 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 inline bool kpb_is_sample_width_supported(uint32_t sampling_width);
static void kpb_copy_samples(struct audio_stream *sink,
const struct audio_stream *source, size_t size,
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 audio_stream *sink,
size_t size, size_t sample_width);
@ -637,8 +637,7 @@ static int kpb_copy(struct comp_dev *dev)
goto out;
}
kpb_copy_samples(&sink->stream, &source->stream, copy_bytes,
sample_width);
kpb_copy_samples(sink, source, copy_bytes, sample_width);
/* Buffer source data internally in history buffer for future
* use by clients.
@ -684,8 +683,7 @@ static int kpb_copy(struct comp_dev *dev)
goto out;
}
kpb_copy_samples(&sink->stream, &source->stream, copy_bytes,
sample_width);
kpb_copy_samples(sink, source, copy_bytes, sample_width);
comp_update_buffer_produce(sink, copy_bytes);
comp_update_buffer_consume(source, copy_bytes);
@ -697,6 +695,7 @@ static int kpb_copy(struct comp_dev *dev)
* the internal history buffer.
*/
if (source->stream.avail <= kpb->buffer_size) {
buffer_invalidate(source, source->stream.avail);
ret = kpb_buffer_data(dev, source,
source->stream.avail);
if (ret) {
@ -1371,8 +1370,8 @@ static inline bool kpb_is_sample_width_supported(uint32_t sampling_width)
*
* \return none.
*/
static void kpb_copy_samples(struct audio_stream *sink,
const struct audio_stream *source, size_t size,
static void kpb_copy_samples(struct comp_buffer *sink,
struct comp_buffer *source, size_t size,
size_t sample_width)
{
void *dst;
@ -1381,14 +1380,18 @@ static void kpb_copy_samples(struct audio_stream *sink,
size_t j = 0;
size_t channel;
size_t frames = KPB_BYTES_TO_FRAMES(size, sample_width);
struct audio_stream *istream = &source->stream;
struct audio_stream *ostream = &sink->stream;
buffer_invalidate(source, size);
for (i = 0; i < frames; i++) {
for (channel = 0; channel < KPB_NUM_OF_CHANNELS; channel++) {
switch (sample_width) {
#if CONFIG_FORMAT_S16LE
case 16:
dst = audio_stream_write_frag_s16(sink, j);
src = audio_stream_read_frag_s16(source, j);
dst = audio_stream_write_frag_s16(ostream, j);
src = audio_stream_read_frag_s16(istream, j);
*((int16_t *)dst) = *((int16_t *)src);
break;
#endif /* CONFIG_FORMAT_S16LE */
@ -1396,8 +1399,8 @@ static void kpb_copy_samples(struct audio_stream *sink,
case 24:
/* FALLTHROUGH */
case 32:
dst = audio_stream_write_frag_s32(sink, j);
src = audio_stream_read_frag_s32(source, j);
dst = audio_stream_write_frag_s32(ostream, j);
src = audio_stream_read_frag_s32(istream, j);
*((int32_t *)dst) = *((int32_t *)src);
break;
#endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE*/
@ -1408,6 +1411,8 @@ static void kpb_copy_samples(struct audio_stream *sink,
j++;
}
}
buffer_writeback(sink, size);
}
/**

View File

@ -327,10 +327,14 @@ static int mixer_copy(struct comp_dev *dev)
source_bytes, sink_bytes);
/* mix streams */
md->mix_func(dev, &sink->stream, sources_stream, i, frames);
for (i = num_mix_sources - 1; i >= 0; i--)
buffer_invalidate(sources[i], source_bytes);
md->mix_func(dev, &sink->stream, sources_stream, num_mix_sources,
frames);
buffer_writeback(sink, sink_bytes);
/* update source buffer pointers */
for (i = --num_mix_sources; i >= 0; i--)
for (i = num_mix_sources - 1; i >= 0; i--)
comp_update_buffer_consume(sources[i], source_bytes);
/* update sink buffer pointer */

View File

@ -330,8 +330,10 @@ static int demux_copy(struct comp_dev *dev)
if (!sinks[i])
continue;
buffer_invalidate(source, source_bytes);
cd->demux(dev, &sinks[i]->stream, &source->stream, frames,
&cd->config.streams[i]);
buffer_writeback(sinks[i], sinks_bytes[i]);
}
/* update components */
@ -397,12 +399,14 @@ static int mux_copy(struct comp_dev *dev)
continue;
sources_bytes[i] = frames *
audio_stream_frame_bytes(sources_stream[i]);
buffer_invalidate(sources[i], sources_bytes[i]);
}
sink_bytes = frames * audio_stream_frame_bytes(&sink->stream);
/* produce output */
cd->mux(dev, &sink->stream, &sources_stream[0], frames,
&cd->config.streams[0]);
buffer_writeback(sink, sink_bytes);
/* update components */
comp_update_buffer_produce(sink, sink_bytes);

View File

@ -387,7 +387,9 @@ static int selector_copy(struct comp_dev *dev)
source_bytes, sink_bytes);
/* copy selected channels from in to out */
buffer_invalidate(source, source_bytes);
cd->sel_func(dev, &sink->stream, &source->stream, frames);
buffer_writeback(sink, sink_bytes);
/* calculate new free and available */
comp_update_buffer_produce(sink, sink_bytes);

View File

@ -738,6 +738,28 @@ static int src_get_copy_limits(struct comp_data *cd,
return 0;
}
static void src_process(struct comp_dev *dev, struct comp_buffer *source,
struct comp_buffer *sink)
{
struct comp_data *cd = comp_get_drvdata(dev);
int consumed = 0;
int produced = 0;
/* consumed bytes are not known at this point */
buffer_invalidate(source, source->stream.size);
cd->src_func(dev, &source->stream, &sink->stream, &consumed, &produced);
buffer_writeback(sink, produced *
audio_stream_frame_bytes(&sink->stream));
comp_dbg(dev, "src_copy(), consumed = %u, produced = %u",
consumed, produced);
comp_update_buffer_consume(source, consumed *
audio_stream_frame_bytes(&source->stream));
comp_update_buffer_produce(sink, produced *
audio_stream_frame_bytes(&sink->stream));
}
/* copy and process stream data from source to sink buffers */
static int src_copy(struct comp_dev *dev)
{
@ -745,8 +767,6 @@ static int src_copy(struct comp_dev *dev)
struct comp_buffer *source;
struct comp_buffer *sink;
int ret;
int consumed = 0;
int produced = 0;
comp_dbg(dev, "src_copy()");
@ -766,21 +786,7 @@ static int src_copy(struct comp_dev *dev)
return PPL_STATUS_PATH_STOP;
}
cd->src_func(dev, &source->stream, &sink->stream, &consumed, &produced);
comp_dbg(dev, "src_copy(), consumed = %u, produced = %u",
consumed, produced);
/* Calc new free and available if data was processed. These
* functions must not be called with 0 consumed/produced.
*/
if (consumed > 0)
comp_update_buffer_consume(source,
consumed * audio_stream_frame_bytes(&source->stream));
if (produced > 0)
comp_update_buffer_produce(sink,
produced * audio_stream_frame_bytes(&sink->stream));
src_process(dev, source, sink);
/* produced no data */
return 0;

View File

@ -622,6 +622,7 @@ static int tone_copy(struct comp_dev *dev)
if (sink->stream.free >= cd->period_bytes) {
/* create tone */
cd->tone_func(dev, &sink->stream, dev->frames);
buffer_writeback(sink, cd->period_bytes);
/* calc new free and available */
comp_update_buffer_produce(sink, cd->period_bytes);

View File

@ -663,7 +663,9 @@ static int volume_copy(struct comp_dev *dev)
c.source_bytes, c.sink_bytes);
/* copy and scale volume */
buffer_invalidate(source, c.source_bytes);
cd->scale_vol(dev, &sink->stream, &source->stream, c.frames);
buffer_writeback(sink, c.sink_bytes);
/* calculate new free and available */
comp_update_buffer_produce(sink, c.sink_bytes);