mirror of https://github.com/thesofproject/sof.git
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:
parent
cf774d14e2
commit
0bd252253e
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue