diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 2494c7ba578e..3a052553ee6c 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -10,7 +10,6 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) add_local_sources(sof host-legacy.c component.c - buffer.c source_api_helper.c sink_api_helper.c sink_source_utils.c @@ -18,6 +17,8 @@ if(NOT CONFIG_COMP_MODULE_SHARED_LIBRARY_BUILD) channel_map.c ) + add_subdirectory(buffers) + if(CONFIG_COMP_BLOB) add_local_sources(sof data_blob.c) endif() @@ -128,7 +129,8 @@ endif() add_local_sources(sof component.c data_blob.c - buffer.c + buffers/comp_buffer.c + buffers/audio_buffer.c source_api_helper.c sink_api_helper.c sink_source_utils.c diff --git a/src/audio/audio_stream.c b/src/audio/audio_stream.c index 855a67ae3b04..ede9f7922a8a 100644 --- a/src/audio/audio_stream.c +++ b/src/audio/audio_stream.c @@ -9,67 +9,6 @@ #include #include -static size_t audio_stream_get_free_size(struct sof_sink *sink) -{ - struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); - - return audio_stream_get_free_bytes(audio_stream); -} - -static int audio_stream_get_buffer(struct sof_sink *sink, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size) -{ - struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); - - if (req_size > audio_stream_get_free_size(sink)) - return -ENODATA; - - /* get circular buffer parameters */ - *data_ptr = audio_stream->w_ptr; - *buffer_start = audio_stream->addr; - *buffer_size = audio_stream->size; - return 0; -} - -static int audio_stream_commit_buffer(struct sof_sink *sink, size_t commit_size) -{ - struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); - struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); - - if (commit_size) { - buffer_stream_writeback(buffer, commit_size); - audio_stream_produce(audio_stream, commit_size); - } - - return 0; -} - -static size_t audio_stream_get_data_available(struct sof_source *source) -{ - struct audio_stream *audio_stream = container_of(source, struct audio_stream, _source_api); - - return audio_stream_get_avail_bytes(audio_stream); -} - -static int audio_stream_get_data(struct sof_source *source, size_t req_size, - void const **data_ptr, void const **buffer_start, - size_t *buffer_size) -{ - struct audio_stream *audio_stream = container_of(source, struct audio_stream, _source_api); - struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); - - if (req_size > audio_stream_get_data_available(source)) - return -ENODATA; - - buffer_stream_invalidate(buffer, req_size); - - /* get circular buffer parameters */ - *data_ptr = audio_stream->r_ptr; - *buffer_start = audio_stream->addr; - *buffer_size = audio_stream->size; - return 0; -} - static uint32_t audio_stream_frame_align_get(const uint32_t byte_align, const uint32_t frame_align_req, uint32_t frame_size) @@ -105,93 +44,6 @@ void audio_stream_set_align(const uint32_t byte_align, audio_stream_recalc_align(stream); } EXPORT_SYMBOL(audio_stream_set_align); - -static int audio_stream_release_data(struct sof_source *source, size_t free_size) -{ - struct audio_stream *audio_stream = container_of(source, struct audio_stream, _source_api); - - if (free_size) - audio_stream_consume(audio_stream, free_size); - - return 0; -} - -static int audio_stream_set_ipc_params_source(struct sof_source *source, - struct sof_ipc_stream_params *params, - bool force_update) -{ - struct audio_stream *audio_stream = container_of(source, struct audio_stream, _source_api); - struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); - - return buffer_set_params(buffer, params, force_update); -} - -static int audio_stream_set_ipc_params_sink(struct sof_sink *sink, - struct sof_ipc_stream_params *params, - bool force_update) -{ - struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); - struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream); - - return buffer_set_params(buffer, params, force_update); -} - -static int audio_stream_source_set_alignment_constants(struct sof_source *source, - const uint32_t byte_align, - const uint32_t frame_align_req) -{ - struct audio_stream *audio_stream = container_of(source, struct audio_stream, _source_api); - - audio_stream_set_align(byte_align, frame_align_req, audio_stream); - - return 0; -} - -static int audio_stream_sink_set_alignment_constants(struct sof_sink *sink, - const uint32_t byte_align, - const uint32_t frame_align_req) -{ - struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); - - audio_stream_set_align(byte_align, frame_align_req, audio_stream); - - return 0; -} - -static int source_format_set(struct sof_source *source) -{ - struct audio_stream *s = container_of(source, struct audio_stream, _source_api); - - audio_stream_recalc_align(s); - return 0; -} - -static int sink_format_set(struct sof_sink *sink) -{ - struct audio_stream *s = container_of(sink, struct audio_stream, _sink_api); - - audio_stream_recalc_align(s); - return 0; -} - -static const struct source_ops audio_stream_source_ops = { - .get_data_available = audio_stream_get_data_available, - .get_data = audio_stream_get_data, - .release_data = audio_stream_release_data, - .audio_set_ipc_params = audio_stream_set_ipc_params_source, - .on_audio_format_set = source_format_set, - .set_alignment_constants = audio_stream_source_set_alignment_constants -}; - -static const struct sink_ops audio_stream_sink_ops = { - .get_free_size = audio_stream_get_free_size, - .get_buffer = audio_stream_get_buffer, - .commit_buffer = audio_stream_commit_buffer, - .audio_set_ipc_params = audio_stream_set_ipc_params_sink, - .on_audio_format_set = sink_format_set, - .set_alignment_constants = audio_stream_sink_set_alignment_constants -}; - void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint32_t size) { audio_stream->size = size; @@ -199,38 +51,5 @@ void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint3 audio_stream->end_addr = (char *)audio_stream->addr + size; audio_stream_set_align(1, 1, audio_stream); - source_init(audio_stream_get_source(audio_stream), &audio_stream_source_ops, - &audio_stream->runtime_stream_params); - sink_init(audio_stream_get_sink(audio_stream), &audio_stream_sink_ops, - &audio_stream->runtime_stream_params); audio_stream_reset(audio_stream); } - -/* get a handler to source API */ -#if CONFIG_PIPELINE_2_0 -struct sof_source *audio_stream_get_source(struct audio_stream *audio_stream) -{ - return audio_stream->secondary_buffer_source ? - audio_buffer_get_source(audio_stream->secondary_buffer_source) : - &audio_stream->_source_api; -} - -struct sof_sink *audio_stream_get_sink(struct audio_stream *audio_stream) -{ - return audio_stream->secondary_buffer_sink ? - audio_buffer_get_sink(audio_stream->secondary_buffer_sink) : - &audio_stream->_sink_api; -} - -#else /* CONFIG_PIPELINE_2_0 */ - -struct sof_source *audio_stream_get_source(struct audio_stream *audio_stream) -{ - return &audio_stream->_source_api; -} - -struct sof_sink *audio_stream_get_sink(struct audio_stream *audio_stream) -{ - return &audio_stream->_sink_api; -} -#endif /* CONFIG_PIPELINE_2_0 */ diff --git a/src/audio/buffers/CMakeLists.txt b/src/audio/buffers/CMakeLists.txt new file mode 100644 index 000000000000..944a84dedb7e --- /dev/null +++ b/src/audio/buffers/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof audio_buffer.c) +add_local_sources(sof comp_buffer.c) + +if(CONFIG_PIPELINE_2_0) + add_local_sources(sof ring_buffer.c) +endif() diff --git a/src/audio/buffers/audio_buffer.c b/src/audio/buffers/audio_buffer.c new file mode 100644 index 000000000000..9cbd587196b9 --- /dev/null +++ b/src/audio/buffers/audio_buffer.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2024 Intel Corporation. All rights reserved. +// +// Author: Marcin Szkudlinski + +#include +#include +#include +#include +#include +#include +#include +#include + +#if CONFIG_PIPELINE_2_0 + +int audio_buffer_attach_secondary_buffer(struct sof_audio_buffer *buffer, bool at_input, + struct sof_audio_buffer *secondary_buffer) +{ + if (buffer->secondary_buffer_sink || buffer->secondary_buffer_source) + return -EINVAL; + + /* secondary buffer must share audio params with the primary buffer */ + secondary_buffer->audio_stream_params = buffer->audio_stream_params; + /* for performance reasons pointers to params are also kept in sink/src structures */ + secondary_buffer->_sink_api.audio_stream_params = buffer->audio_stream_params; + secondary_buffer->_source_api.audio_stream_params = buffer->audio_stream_params; + + if (at_input) + buffer->secondary_buffer_sink = secondary_buffer; + else + buffer->secondary_buffer_source = secondary_buffer; + + return 0; +} + +int audio_buffer_sync_secondary_buffer(struct sof_audio_buffer *buffer, size_t limit) +{ + int err; + + struct sof_source *data_src; + struct sof_sink *data_dst; + + if (buffer->secondary_buffer_sink) { + /* + * audio_buffer sink API is shadowed, that means there's a secondary_buffer + * at data input + * get data from secondary_buffer (use source API) + * copy to primary buffer (use sink API) + * note! can't use audio_buffer_get_sink because it will provide a shadowed + * sink handler (to a secondary buffer). + */ + data_src = audio_buffer_get_source(buffer->secondary_buffer_sink); + data_dst = &buffer->_sink_api; /* primary buffer's sink API */ + } else if (buffer->secondary_buffer_source) { + /* + * comp_buffer source API is shadowed, that means there's a secondary_buffer + * at data output + * get data from comp_buffer (use source API) + * copy to secondary_buffer (use sink API) + */ + data_src = &buffer->_source_api; + data_dst = audio_buffer_get_sink(buffer->secondary_buffer_source); + + } else { + return -EINVAL; + } + + /* + * keep data_available and free_size in local variables to avoid check_time/use_time + * race in MIN macro + */ + size_t data_available = source_get_data_available(data_src); + size_t free_size = sink_get_free_size(data_dst); + size_t to_copy = MIN(MIN(data_available, free_size), limit); + + err = source_to_sink_copy(data_src, data_dst, true, to_copy); + return err; +} + +#endif /* CONFIG_PIPELINE_2_0 */ + +void audio_buffer_free(struct sof_audio_buffer *buffer) +{ + if (!buffer) + return; + + CORE_CHECK_STRUCT(buffer); +#if CONFIG_PIPELINE_2_0 + audio_buffer_free(buffer->secondary_buffer_sink); + audio_buffer_free(buffer->secondary_buffer_source); +#endif /* CONFIG_PIPELINE_2_0 */ + if (buffer->ops->free) + buffer->ops->free(buffer); + rfree(buffer); +} diff --git a/src/audio/buffer.c b/src/audio/buffers/comp_buffer.c similarity index 71% rename from src/audio/buffer.c rename to src/audio/buffers/comp_buffer.c index 1e2d4b5c1eb5..66ab613ed9f8 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffers/comp_buffer.c @@ -30,6 +30,176 @@ LOG_MODULE_REGISTER(buffer, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(buffer); DECLARE_TR_CTX(buffer_tr, SOF_UUID(buffer_uuid), LOG_LEVEL_INFO); +static size_t comp_buffer_get_data_available(struct sof_source *source) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + return audio_stream_get_avail_bytes(&buffer->stream); +} + +static int comp_buffer_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, + size_t *buffer_size) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + if (req_size > audio_stream_get_avail_bytes(&buffer->stream)) + return -ENODATA; + + buffer_stream_invalidate(buffer, req_size); + + /* get circular buffer parameters */ + *data_ptr = buffer->stream.r_ptr; + *buffer_start = buffer->stream.addr; + *buffer_size = buffer->stream.size; + return 0; +} + +static int comp_buffer_release_data(struct sof_source *source, size_t free_size) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + if (free_size) + audio_stream_consume(&buffer->stream, free_size); + + return 0; +} + +static int comp_buffer_set_ipc_params_source(struct sof_source *source, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + return buffer_set_params(buffer, params, force_update); +} + +static int comp_buffer_source_format_set(struct sof_source *source) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + audio_stream_recalc_align(&buffer->stream); + return 0; +} + +static int comp_buffer_source_set_alignment_constants(struct sof_source *source, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + struct comp_buffer *buffer = comp_buffer_get_from_source(source); + + audio_stream_set_align(byte_align, frame_align_req, &buffer->stream); + return 0; +} + +static size_t comp_buffer_get_free_size(struct sof_sink *sink) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + return audio_stream_get_free_bytes(&buffer->stream); +} + +static int comp_buffer_get_buffer(struct sof_sink *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + if (req_size > audio_stream_get_free_bytes(&buffer->stream)) + return -ENODATA; + + /* get circular buffer parameters */ + *data_ptr = buffer->stream.w_ptr; + *buffer_start = buffer->stream.addr; + *buffer_size = buffer->stream.size; + return 0; +} + +static int comp_buffer_commit_buffer(struct sof_sink *sink, size_t commit_size) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + if (commit_size) { + buffer_stream_writeback(buffer, commit_size); + audio_stream_produce(&buffer->stream, commit_size); + } + + return 0; +} + +static int comp_buffer_set_ipc_params_sink(struct sof_sink *sink, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + return buffer_set_params(buffer, params, force_update); +} + +static int comp_buffer_sink_format_set(struct sof_sink *sink) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + audio_stream_recalc_align(&buffer->stream); + return 0; +} + +static int comp_buffer_sink_set_alignment_constants(struct sof_sink *sink, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + struct comp_buffer *buffer = comp_buffer_get_from_sink(sink); + + audio_stream_set_align(byte_align, frame_align_req, &buffer->stream); + return 0; +} + +/* free component in the pipeline */ +static void comp_buffer_free(struct sof_audio_buffer *audio_buffer) +{ + if (!audio_buffer) + return; + + CORE_CHECK_STRUCT(audio_buffer); + + struct comp_buffer *buffer = container_of(audio_buffer, struct comp_buffer, audio_buffer); + + struct buffer_cb_free cb_data = { + .buffer = buffer, + }; + + buf_dbg(buffer, "buffer_free()"); + + notifier_event(buffer, NOTIFIER_ID_BUFFER_FREE, + NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); + + /* In case some listeners didn't unregister from buffer's callbacks */ + notifier_unregister_all(NULL, buffer); + + rfree(buffer->stream.addr); +} + +static const struct source_ops comp_buffer_source_ops = { + .get_data_available = comp_buffer_get_data_available, + .get_data = comp_buffer_get_data, + .release_data = comp_buffer_release_data, + .audio_set_ipc_params = comp_buffer_set_ipc_params_source, + .on_audio_format_set = comp_buffer_source_format_set, + .set_alignment_constants = comp_buffer_source_set_alignment_constants +}; + +static const struct sink_ops comp_buffer_sink_ops = { + .get_free_size = comp_buffer_get_free_size, + .get_buffer = comp_buffer_get_buffer, + .commit_buffer = comp_buffer_commit_buffer, + .audio_set_ipc_params = comp_buffer_set_ipc_params_sink, + .on_audio_format_set = comp_buffer_sink_format_set, + .set_alignment_constants = comp_buffer_sink_set_alignment_constants +}; + +static const struct audio_buffer_ops audio_buffer_ops = { + .free = comp_buffer_free, +}; + static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, uint32_t caps, uint32_t flags, bool is_shared) { @@ -47,11 +217,13 @@ static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, u return NULL; } - CORE_CHECK_STRUCT_INIT(buffer, is_shared); - buffer->is_shared = is_shared; buffer->caps = caps; + audio_buffer_init(&buffer->audio_buffer, BUFFER_TYPE_LEGACY_BUFFER, is_shared, + &comp_buffer_source_ops, &comp_buffer_sink_ops, &audio_buffer_ops, + &buffer->stream.runtime_stream_params); + /* From here no more uncached access to the buffer object, except its list headers */ audio_stream_set_addr(&buffer->stream, stream_addr); buffer_init_stream(buffer, size); @@ -95,66 +267,6 @@ struct comp_buffer *buffer_alloc(size_t size, uint32_t caps, uint32_t flags, uin return buffer; } -#if CONFIG_PIPELINE_2_0 -int buffer_attach_secondary_buffer(struct comp_buffer *buffer, bool at_input, - struct sof_audio_buffer *secondary_buffer) -{ - if (buffer->stream.secondary_buffer_sink || buffer->stream.secondary_buffer_source) { - buf_err(buffer, "Only one secondary buffer may be attached to a buffer"); - return -EINVAL; - } - if (at_input) - buffer->stream.secondary_buffer_sink = secondary_buffer; - else - buffer->stream.secondary_buffer_source = secondary_buffer; - - buf_info(buffer, "ring_buffer attached to buffer as a secondary, at_input: %u", at_input); - return 0; -} - -int buffer_sync_secondary_buffer(struct comp_buffer *buffer, size_t limit) -{ - int err; - - struct sof_source *data_src; - struct sof_sink *data_dst; - - if (buffer->stream.secondary_buffer_sink) { - /* - * comp_buffer sink API is shadowed, that means there's a secondary_buffer - * at data input - * get data from secondary_buffer (use source API) - * copy to comp_buffer (use sink API) - */ - data_src = audio_buffer_get_source(buffer->stream.secondary_buffer_sink); - data_dst = &buffer->stream._sink_api; - } else if (buffer->stream.secondary_buffer_source) { - /* - * comp_buffer source API is shadowed, that means there's a secondary_buffer - * at data output - * get data from comp_buffer (use source API) - * copy to secondary_buffer (use sink API) - */ - data_src = &buffer->stream._source_api; - data_dst = audio_buffer_get_sink(buffer->stream.secondary_buffer_source); - - } else { - return -EINVAL; - } - - /* - * keep data_available and free_size in local variables to avoid check_time/use_time - * race in MIN macro - */ - size_t data_available = source_get_data_available(data_src); - size_t free_size = sink_get_free_size(data_dst); - size_t to_copy = MIN(MIN(data_available, free_size), limit); - - err = source_to_sink_copy(data_src, data_dst, true, to_copy); - return err; -} -#endif /* CONFIG_PIPELINE_2_0 */ - struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_size, uint32_t caps, uint32_t flags, uint32_t align, bool is_shared) { @@ -201,7 +313,7 @@ struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_siz void buffer_zero(struct comp_buffer *buffer) { buf_dbg(buffer, "stream_zero()"); - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); bzero(audio_stream_get_addr(&buffer->stream), audio_stream_get_size(&buffer->stream)); if (buffer->caps & SOF_MEM_CAPS_DMA) @@ -214,7 +326,7 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen { void *new_ptr = NULL; - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); /* validate request */ if (size == 0) { @@ -256,7 +368,7 @@ int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, siz void *new_ptr = NULL; size_t new_size; - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); /* validate request */ if (minimum_size == 0 || preferred_size < minimum_size) { @@ -311,7 +423,7 @@ int buffer_set_params(struct comp_buffer *buffer, int ret; int i; - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); if (!params) { buf_err(buffer, "buffer_set_params(): !params"); @@ -341,7 +453,7 @@ bool buffer_params_match(struct comp_buffer *buffer, struct sof_ipc_stream_params *params, uint32_t flag) { assert(params); - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); if ((flag & BUFF_PARAMS_FRAME_FMT) && audio_stream_get_frm_fmt(&buffer->stream) != params->frame_fmt) @@ -358,33 +470,6 @@ bool buffer_params_match(struct comp_buffer *buffer, return true; } -/* free component in the pipeline */ -void buffer_free(struct comp_buffer *buffer) -{ - struct buffer_cb_free cb_data = { - .buffer = buffer, - }; - - CORE_CHECK_STRUCT(buffer); - - if (!buffer) - return; - - buf_dbg(buffer, "buffer_free()"); - - notifier_event(buffer, NOTIFIER_ID_BUFFER_FREE, - NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data)); - - /* In case some listeners didn't unregister from buffer's callbacks */ - notifier_unregister_all(NULL, buffer); -#if CONFIG_PIPELINE_2_0 - audio_buffer_free(buffer->stream.secondary_buffer_sink); - audio_buffer_free(buffer->stream.secondary_buffer_source); -#endif /* CONFIG_PIPELINE_2_0 */ - rfree(buffer->stream.addr); - rfree(buffer); -} - void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) { struct buffer_cb_transact cb_data = { @@ -431,7 +516,7 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) .transaction_begin_address = audio_stream_get_rptr(&buffer->stream), }; - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); /* return if no bytes */ if (!bytes) { @@ -471,7 +556,7 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) void buffer_attach(struct comp_buffer *buffer, struct list_item *head, int dir) { struct list_item *list = buffer_comp_list(buffer, dir); - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); list_item_prepend(list, head); } @@ -482,6 +567,6 @@ void buffer_attach(struct comp_buffer *buffer, struct list_item *head, int dir) void buffer_detach(struct comp_buffer *buffer, struct list_item *head, int dir) { struct list_item *buf_list = buffer_comp_list(buffer, dir); - CORE_CHECK_STRUCT(buffer); + CORE_CHECK_STRUCT(&buffer->audio_buffer); list_item_del(buf_list); } diff --git a/src/audio/buffers/ring_buffer.c b/src/audio/buffers/ring_buffer.c index 9ce7eeee87c2..3168478f1226 100644 --- a/src/audio/buffers/ring_buffer.c +++ b/src/audio/buffers/ring_buffer.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(ring_buffer, CONFIG_SOF_LOG_LEVEL); SOF_DEFINE_REG_UUID(ring_buffer); -DECLARE_TR_CTX(dp_queue_tr, SOF_UUID(ring_buffer_uuid), LOG_LEVEL_INFO); +DECLARE_TR_CTX(ring_buffer_tr, SOF_UUID(ring_buffer_uuid), LOG_LEVEL_INFO); static inline struct ring_buffer *ring_buffer_from_sink(struct sof_sink *sink) { @@ -227,10 +227,13 @@ static int ring_buffer_set_ipc_params(struct ring_buffer *ring_buffer, if (ring_buffer->_hw_params_configured && !force_update) return 0; - ring_buffer->audio_stream_params->frame_fmt = params->frame_fmt; - ring_buffer->audio_stream_params->rate = params->rate; - ring_buffer->audio_stream_params->channels = params->channels; - ring_buffer->audio_stream_params->buffer_fmt = params->buffer_fmt; + struct sof_audio_stream_params *audio_stream_params = + audio_buffer_get_stream_params(&ring_buffer->audio_buffer); + + audio_stream_params->frame_fmt = params->frame_fmt; + audio_stream_params->rate = params->rate; + audio_stream_params->channels = params->channels; + audio_stream_params->buffer_fmt = params->buffer_fmt; ring_buffer->_hw_params_configured = true; @@ -271,9 +274,12 @@ static const struct sink_ops ring_buffer_sink_ops = { .audio_set_ipc_params = ring_buffer_set_ipc_params_sink, }; +static const struct audio_buffer_ops audio_buffer_ops = { + .free = ring_buffer_free, +}; + struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_space, uint32_t flags, - uint32_t id, - struct sof_audio_stream_params *audio_stream_params) + uint32_t id) { struct ring_buffer *ring_buffer; @@ -288,19 +294,22 @@ struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_spa return NULL; ring_buffer->_flags = flags; - ring_buffer->audio_stream_params = audio_stream_params; - CORE_CHECK_STRUCT_INIT(&ring_buffer->audio_buffer, flags & RING_BUFFER_MODE_SHARED); - - /* initiate structures */ - source_init(audio_buffer_get_source(&ring_buffer->audio_buffer), &ring_buffer_source_ops, - ring_buffer->audio_stream_params); - sink_init(audio_buffer_get_sink(&ring_buffer->audio_buffer), &ring_buffer_sink_ops, - ring_buffer->audio_stream_params); + /* init base structure. The audio_stream_params is NULL because ring_buffer + * is currently used as a secondary buffer for DP only + * + * pointer in audio_buffer will be overwritten when attaching ring_buffer as a + * secondary buffer + */ + audio_buffer_init(&ring_buffer->audio_buffer, BUFFER_TYPE_RING_BUFFER, + flags & RING_BUFFER_MODE_SHARED, &ring_buffer_source_ops, + &ring_buffer_sink_ops, &audio_buffer_ops, NULL); /* set obs/ibs in sink/source interfaces */ - sink_set_min_free_space(&ring_buffer->audio_buffer._sink_api, min_free_space); - source_set_min_available(&ring_buffer->audio_buffer._source_api, min_available); + sink_set_min_free_space(audio_buffer_get_sink(&ring_buffer->audio_buffer), + min_free_space); + source_set_min_available(audio_buffer_get_source(&ring_buffer->audio_buffer), + min_available); uint32_t max_ibs_obs = MAX(min_available, min_free_space); @@ -315,15 +324,10 @@ struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_spa if (!ring_buffer->_data_buffer) goto err; - ring_buffer->audio_stream_params->id = id; tr_info(&ring_buffer_tr, "Ring buffer created, id: %u shared: %u min_available: %u min_free_space %u, size %u", id, ring_buffer_is_shared(ring_buffer), min_available, min_free_space, ring_buffer->data_buffer_size); - /* set common buffer api */ - ring_buffer->audio_buffer.free = ring_buffer_free; - ring_buffer->audio_buffer.buffer_type = BUFFER_TYPE_RING_BUFFER; - /* return a pointer to allocated structure */ return ring_buffer; err: diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 24f30ff31677..4ae3707d5d17 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -285,7 +285,6 @@ static int mixin_process(struct processing_module *mod, * and frames free in each connected mixout sink buffer. */ for (i = 0; i < num_of_sinks; i++) { - struct audio_stream *stream; struct comp_buffer *unused_in_between_buf; struct comp_dev *mixout; struct sof_sink *mixout_sink; @@ -299,9 +298,8 @@ static int mixin_process(struct processing_module *mod, * TODO: find out a solution to reach mixout without knowledge of mixin * sof_sink implementation. */ - stream = container_of(sinks[i], struct audio_stream, _sink_api); /* unused buffer between mixin and mixout */ - unused_in_between_buf = container_of(stream, struct comp_buffer, stream); + unused_in_between_buf = comp_buffer_get_from_sink(sinks[i]); mixout = unused_in_between_buf->sink; /* Skip non-active mixout like it is not connected so it does not @@ -477,7 +475,6 @@ static int mixout_process(struct processing_module *mod, * produced now. */ for (i = 0; i < num_of_sources; i++) { - const struct audio_stream *source_stream; struct comp_buffer *unused_in_between_buf; struct comp_dev *mixin; @@ -487,9 +484,7 @@ static int mixout_process(struct processing_module *mod, * TODO: find out a solution to reach mixin without knowledge of mixout * sof_source implementation. */ - source_stream = container_of(sources[i], struct audio_stream, _source_api); - unused_in_between_buf = container_of(source_stream, struct comp_buffer, - stream); + unused_in_between_buf = comp_buffer_get_from_source(sources[i]); mixin = unused_in_between_buf->source; pending_frames = get_mixin_pending_frames(md, mixin); @@ -502,13 +497,10 @@ static int mixout_process(struct processing_module *mod, if (frames_to_produce > 0 && frames_to_produce < INT32_MAX) { for (i = 0; i < num_of_sources; i++) { - const struct audio_stream *source_stream; struct comp_buffer *unused_in_between_buf; struct comp_dev *mixin; - source_stream = container_of(sources[i], struct audio_stream, _source_api); - unused_in_between_buf = container_of(source_stream, - struct comp_buffer, stream); + unused_in_between_buf = comp_buffer_get_from_source(sources[i]); mixin = unused_in_between_buf->source; pending_frames = get_mixin_pending_frames(md, mixin); @@ -567,7 +559,6 @@ static int mixout_reset(struct processing_module *mod) int i; for (i = 0; i < mod->num_of_sources; i++) { - const struct audio_stream *source_stream; const struct comp_buffer *source_buf; bool stop; @@ -577,11 +568,7 @@ static int mixout_reset(struct processing_module *mod) * TODO: find out a solution to reach mixin without knowledge of mixout * sof_source implementation. */ - source_stream = container_of(mod->sources[i], - struct audio_stream, _source_api); - source_buf = container_of(source_stream, struct comp_buffer, - stream); - + source_buf = comp_buffer_get_from_source(mod->sources[i]); stop = (dev->pipeline == source_buf->source->pipeline && source_buf->source->state > COMP_STATE_PAUSED); diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 149bc04400b2..d8ae391469db 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -920,7 +920,7 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev) */ struct comp_buffer *buffer = container_of(blist, struct comp_buffer, sink_list); - err = buffer_sync_secondary_buffer(buffer, UINT_MAX); + err = audio_buffer_sync_secondary_buffer(&buffer->audio_buffer, UINT_MAX); if (err) { comp_err(dev, "LL to DP copy error status: %d", err); @@ -947,10 +947,10 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev) struct comp_buffer *buffer = container_of(blist, struct comp_buffer, source_list); struct sof_source *following_mod_data_source = - audio_stream_get_source(&buffer->stream); + audio_buffer_get_source(&buffer->audio_buffer); - err = buffer_sync_secondary_buffer - (buffer, + err = audio_buffer_sync_secondary_buffer + (&buffer->audio_buffer, source_get_min_available(following_mod_data_source)); if (err) { diff --git a/src/audio/module_adapter/module_adapter_ipc3.c b/src/audio/module_adapter/module_adapter_ipc3.c index 2055f8c4f33d..28ecd9adc0bd 100644 --- a/src/audio/module_adapter/module_adapter_ipc3.c +++ b/src/audio/module_adapter/module_adapter_ipc3.c @@ -329,7 +329,7 @@ int module_adapter_sink_src_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink_buffer = container_of(blist, struct comp_buffer, source_list); - mod->sinks[i] = audio_stream_get_sink(&sink_buffer->stream); + mod->sinks[i] = audio_buffer_get_sink(&sink_buffer->audio_buffer); i++; } mod->num_of_sinks = i; @@ -339,7 +339,7 @@ int module_adapter_sink_src_prepare(struct comp_dev *dev) struct comp_buffer *source_buffer = container_of(blist, struct comp_buffer, sink_list); - mod->sources[i] = audio_stream_get_source(&source_buffer->stream); + mod->sources[i] = audio_buffer_get_source(&source_buffer->audio_buffer); i++; } mod->num_of_sources = i; diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c index 3c23411d7fd1..060cef446f73 100644 --- a/src/audio/module_adapter/module_adapter_ipc4.c +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -195,7 +195,7 @@ static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink_buffer = container_of(blist, struct comp_buffer, source_list); - mod->sinks[i] = audio_stream_get_sink(&sink_buffer->stream); + mod->sinks[i] = audio_buffer_get_sink(&sink_buffer->audio_buffer); i++; } mod->num_of_sinks = i; @@ -205,7 +205,7 @@ static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) struct comp_buffer *source_buffer = container_of(blist, struct comp_buffer, sink_list); - mod->sources[i] = audio_stream_get_source(&source_buffer->stream); + mod->sources[i] = audio_buffer_get_source(&source_buffer->audio_buffer); i++; } mod->num_of_sources = i; diff --git a/src/audio/source_api_helper.c b/src/audio/source_api_helper.c index c7ca28c71720..03d7b216936e 100644 --- a/src/audio/source_api_helper.c +++ b/src/audio/source_api_helper.c @@ -3,6 +3,7 @@ * Copyright(c) 2023 Intel Corporation. All rights reserved. */ +#include #include #include diff --git a/src/include/sof/audio/audio_buffer.h b/src/include/sof/audio/audio_buffer.h index 356153924f84..00067f3c15a7 100644 --- a/src/include/sof/audio/audio_buffer.h +++ b/src/include/sof/audio/audio_buffer.h @@ -9,10 +9,23 @@ #include #include #include +#include +#include #define BUFFER_TYPE_LEGACY_BUFFER 1 -#define BUFFER_TYPE_LEGACY_RING_HYBRID 2 -#define BUFFER_TYPE_RING_BUFFER 3 +#define BUFFER_TYPE_RING_BUFFER 2 + +/* forward def */ +struct sof_audio_buffer; + +struct audio_buffer_ops { + /** + * @brief this method must free all structures allocated by buffer implementation + * it must not free the buffer memory itself + * OPTIONAL + */ + void (*free)(struct sof_audio_buffer *buffer); +}; /* base class for all buffers, all buffers must inherit from it */ struct sof_audio_buffer { @@ -21,21 +34,114 @@ struct sof_audio_buffer { /* type of the buffer BUFFER_TYPE_* */ uint32_t buffer_type; - /* runtime stream params */ - struct sof_audio_stream_params audio_stream_params; +#if CONFIG_PIPELINE_2_0 + /** + * sink API of an additional buffer + * of any type at data input + * + * to be removed when hybrid buffers are no longer needed + */ + struct sof_audio_buffer *secondary_buffer_sink; + + /** + * source API of an additional buffer + * at data output + */ + struct sof_audio_buffer *secondary_buffer_source; + +#endif /* CONFIG_PIPELINE_2_0 */ + + /* effective runtime stream params + * before pipelin2.0 is ready, stream params may be kept in audio_stream structure + * also for hybrid buffering audio params need to be shared between primary and secondary + * buffers + * + * So currently only a pointer to effective stream params is here. + * Note that the same pointer MUST be set in source and sink api (kept there for + * performance reasons) + */ + struct sof_audio_stream_params *audio_stream_params; + /* private: */ struct sof_source _source_api; /**< src api handler */ struct sof_sink _sink_api; /**< sink api handler */ /* virtual methods */ - /** - * @brief this method must free all structures allocated by buffer implementation - * it must not free the buffer memory itself - */ - void (*free)(struct sof_audio_buffer *buffer); + const struct audio_buffer_ops *ops; }; +#if CONFIG_PIPELINE_2_0 +/* + * attach a secondary buffer (any type) before buffer (when at_input == true) or behind a buffer + * + * before buffer (at_input == true): + * 2.0 mod ==> (sink_API) secondary buffer ==> + * ==> comp_buffer (audio_stream or source API) ==> 1.0 mod + * + * after buffer (at_input == false): + * 1.0 mod ==> (audio_stream or sink API) ==> comp_buffer ==> + * ==> secondary buffer(source API) == 2.0 mod + * + * If a secondary buffer is attached, it replaces source or sink interface of audio_stream + * allowing the module connected to it using all properties of secondary buffer (like + * lockless cross-core connection in case of ring_buffer etc.) keeping legacy interface + * to other modules + * + * buffer_sync_secondary_buffer must be called every 1 ms to move data to/from + * secondary buffer to comp_buffer + * + * @param buffer pointer to a buffer + * @param at_input true indicates that a secondary buffer is located at data input, replacing + * sink API of audio_stream + * false indicates that a secondary buffer is located at data output, replacing + * source API of audio_stream + * @param secondary_buffer pointer to a buffer to be attached + * + * to be removed when hybrid buffers are no longer needed + */ +int audio_buffer_attach_secondary_buffer(struct sof_audio_buffer *buffer, bool at_input, + struct sof_audio_buffer *secondary_buffer); + +/* + * move data from/to secondary buffer, must be called periodically as described above + * + * @param buffer pointer to a buffer + * @param limit data copy limit. Indicates maximum amount of data that will be moved from/to + * secondary buffer in an operation + * + * to be removed when hybrid buffers are no longer needed + */ +int audio_buffer_sync_secondary_buffer(struct sof_audio_buffer *buffer, size_t limit); + +/** + * @brief return a handler to sink API of audio_buffer. + * the handler may be used by helper functions defined in sink_api.h + */ +static inline +struct sof_sink *audio_buffer_get_sink(struct sof_audio_buffer *buffer) +{ + CORE_CHECK_STRUCT(buffer); + return buffer->secondary_buffer_sink ? + audio_buffer_get_sink(buffer->secondary_buffer_sink) : + &buffer->_sink_api; +} + +/** + * @brief return a handler to source API of audio_buffer + * the handler may be used by helper functions defined in source_api.h + */ +static inline +struct sof_source *audio_buffer_get_source(struct sof_audio_buffer *buffer) +{ + CORE_CHECK_STRUCT(buffer); + return buffer->secondary_buffer_source ? + audio_buffer_get_source(buffer->secondary_buffer_source) : + &buffer->_source_api; +} + +#else /* CONFIG_PIPELINE_2_0 */ + /** * @brief return a handler to sink API of audio_buffer. * the handler may be used by helper functions defined in sink_api.h @@ -58,6 +164,17 @@ struct sof_source *audio_buffer_get_source(struct sof_audio_buffer *buffer) return &buffer->_source_api; } +#endif /* CONFIG_PIPELINE_2_0 */ + +/** + * @brief return a handler to stream params structure + */ +static inline +struct sof_audio_stream_params *audio_buffer_get_stream_params(struct sof_audio_buffer *buffer) +{ + return buffer->audio_stream_params; +} + /** * @brief return a pointer to struct sof_audio_buffer from sink pointer * NOTE! ensure that sink is really provided by sof_audio_buffer @@ -79,18 +196,35 @@ static inline struct sof_audio_buffer *sof_audo_buffer_from_source(struct sof_so } /** - * @brief free buffer and all allocated resources + * @brief initialize audio buffer structures + * + * @param buffer pointer to the audio_buffer + * @param buffer_type a type of the buffer, BUFFER_TYPE_* + * @param is_shared indicates if the buffer will be shared between cores + * @param source_ops pointer to virtual methods table for source API + * @param sink_ops pointer to virtual methods table for sink API + * @param audio_buffer_ops pointer to required buffer virtual methods implementation + * @param audio_stream_params pointer to audio stream (currently kept in buffer implementation) */ static inline -void audio_buffer_free(struct sof_audio_buffer *buffer) +void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared, + const struct source_ops *source_ops, const struct sink_ops *sink_ops, + const struct audio_buffer_ops *audio_buffer_ops, + struct sof_audio_stream_params *audio_stream_params) { - if (!buffer) - return; - - CORE_CHECK_STRUCT(buffer); - if (buffer->free) - buffer->free(buffer); - rfree(buffer); + CORE_CHECK_STRUCT_INIT(&buffer, is_shared); + buffer->buffer_type = buffer_type; + buffer->ops = audio_buffer_ops; + buffer->audio_stream_params = audio_stream_params; + source_init(audio_buffer_get_source(buffer), source_ops, + audio_buffer_get_stream_params(buffer)); + sink_init(audio_buffer_get_sink(buffer), sink_ops, + audio_buffer_get_stream_params(buffer)); } +/** + * @brief free buffer and all allocated resources + */ +void audio_buffer_free(struct sof_audio_buffer *buffer); + #endif /* __SOF_AUDIO_BUFFER__ */ diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 0f73e6f3c84a..f930c7af3d8a 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -47,12 +47,8 @@ * audio_stream_consume()/audio_stream_produce() (just a single call following * series of reads/writes). * - * Audio stream implements pipeline2.0 sink and source API */ struct audio_stream { - struct sof_source _source_api; /**< source API, don't modify, use helper functions only */ - struct sof_sink _sink_api; /**< sink API, don't modify, use helper functions only */ - /* runtime data */ uint32_t size; /**< Runtime buffer size in bytes (period multiple) */ uint32_t avail; /**< Available bytes for reading */ @@ -63,19 +59,7 @@ struct audio_stream { void *end_addr; /**< Buffer end address */ uint8_t byte_align_req; uint8_t frame_align_req; -#if CONFIG_PIPELINE_2_0 - /** - * sink API of an additional buffer - * of any type at data input - */ - struct sof_audio_buffer *secondary_buffer_sink; - /** - * source API of an additional buffer - * at data output - */ - struct sof_audio_buffer *secondary_buffer_source; -#endif /* CONFIG_PIPELINE_2_0 */ /* runtime stream params */ struct sof_audio_stream_params runtime_stream_params; @@ -1028,15 +1012,6 @@ static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth, *valid_fmt = SOF_IPC_FRAME_FLOAT; } } - -/** get a handler to source API - */ -struct sof_source * -audio_stream_get_source(struct audio_stream *audio_stream); - -struct sof_sink * -audio_stream_get_sink(struct audio_stream *audio_stream); - /** @}*/ #endif /* __SOF_AUDIO_AUDIO_STREAM_H__ */ diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index c259b07d5fed..48d297b83919 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -120,19 +120,12 @@ extern struct tr_ctx buffer_tr; /* * audio component buffer - connects 2 audio components together in pipeline. * - * The buffer is a hot structure that must be shared on certain cache - * incoherent architectures. + * this is a legacy component connector for pipeline 1.0 * - * Access flow (on cache incoherent architectures only) - * 1) buffer acquired by using uncache cache coherent pointer. - * 2) buffer is invalidated after lock acquired. - * 3) buffer is safe to use cached pointer for access. - * 4) release buffer cached pointer - * 5) write back cached data and release lock using uncache pointer. */ struct comp_buffer { /* data buffer */ - CORE_CHECK_STRUCT_FIELD; + struct sof_audio_buffer audio_buffer; struct audio_stream stream; @@ -190,49 +183,33 @@ struct comp_buffer *buffer_alloc(size_t size, uint32_t caps, uint32_t flags, uin struct comp_buffer *buffer_alloc_range(size_t preferred_size, size_t minimum_size, uint32_t caps, uint32_t flags, uint32_t align, bool is_shared); struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared); -#if CONFIG_PIPELINE_2_0 -/* - * attach a secondary buffer (any type) before buffer (when at_input == true) or behind a buffer - * - * before buffer (at_input == true): - * 2.0 mod ==> (sink_API) secondary buffer ==> - * ==> comp_buffer (audio_stream or source API) ==> 1.0 mod - * - * after buffer (at_input == false): - * 1.0 mod ==> (audio_stream or sink API) ==> comp_buffer ==> - * ==> secondary buffer(source API) == 2.0 mod - * - * If a secondary buffer is attached, it replaces source or sink interface of audio_stream - * allowing the module connected to it using all properties of secondary buffer (like - * lockless cross-core connection in case of ring_buffer etc.) keeping legacy interface - * to other modules - * - * buffer_sync_secondary_buffer must be called every 1 ms to move data to/from - * secondary buffer to comp_buffer - * - * @param buffer pointer to a buffer - * @param at_input true indicates that a secondary buffer is located at data input, replacing - * sink API of audio_stream - * false indicates that a secondary buffer is located at data output, replacing - * source API of audio_stream - * @param secondary_buffer pointer to a buffer to be attached - */ -int buffer_attach_secondary_buffer(struct comp_buffer *buffer, bool at_input, - struct sof_audio_buffer *secondary_buffer); -/* - * move data from/to secondary buffer, must be called periodically as described above - * - * @param buffer pointer to a buffer - * @param limit data copy limit. Indicates maximum amount of data that will be moved from/to - * secondary buffer in an operation - */ -int buffer_sync_secondary_buffer(struct comp_buffer *buffer, size_t limit); -#endif /* CONFIG_PIPELINE_2_0 */ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment); int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, size_t minimum_size, uint32_t alignment); -void buffer_free(struct comp_buffer *buffer); + +/* legacy wrappers, to be removed. Don't use them if possible */ +static inline struct comp_buffer *comp_buffer_get_from_source(struct sof_source *source) +{ + struct sof_audio_buffer *audio_buffer = sof_audo_buffer_from_source(source); + + return container_of(audio_buffer, struct comp_buffer, audio_buffer); +} + +static inline struct comp_buffer *comp_buffer_get_from_sink(struct sof_sink *sink) +{ + struct sof_audio_buffer *audio_buffer = sof_audo_buffer_from_sink(sink); + + return container_of(audio_buffer, struct comp_buffer, audio_buffer); +} + +static inline void buffer_free(struct comp_buffer *buffer) +{ + audio_buffer_free(&buffer->audio_buffer); +} + +/* end of legacy wrappers */ + void buffer_zero(struct comp_buffer *buffer); /* called by a component after producing data into this buffer */ diff --git a/src/include/sof/audio/ring_buffer.h b/src/include/sof/audio/ring_buffer.h index d900eb6294ec..e9727917c442 100644 --- a/src/include/sof/audio/ring_buffer.h +++ b/src/include/sof/audio/ring_buffer.h @@ -106,18 +106,9 @@ struct sof_audio_stream_params; /* the ring_buffer structure */ struct ring_buffer { - struct sof_audio_buffer audio_buffer; - /* public: read only */ + struct sof_audio_buffer audio_buffer; - /* note! - * as ring_buffer is currently used as a shadow for comp_buffer only for DP components, - * the audio_stream_params vector must be shared between comp_buffer and ring_buffer - * the audio_stream_params pointer should point to the proper comp_buffer structure - * - * to be changed to the structure itself when pipeline2.0 is introduced - */ - struct sof_audio_stream_params *audio_stream_params; size_t data_buffer_size; uint32_t _flags; /* RING_BUFFER_MODE_* */ @@ -140,11 +131,8 @@ struct ring_buffer { * * @param id a stream ID, accessible later by sink_get_id/source_get_id * - * @param audio_stream_params pointer to audio params vector, shared between ring_buffer and - * comp_buffer for dp modules - * */ struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_space, uint32_t flags, - uint32_t id, struct sof_audio_stream_params *audio_stream_params); + uint32_t id); #endif /* __SOF_RING_BUFFER_H__ */ diff --git a/src/include/sof/coherent.h b/src/include/sof/coherent.h index 8e13b661440c..d98739b92c6f 100644 --- a/src/include/sof/coherent.h +++ b/src/include/sof/coherent.h @@ -385,29 +385,17 @@ static inline void __coherent_shared(struct coherent *c, const size_t size) __must_check static inline struct coherent __sparse_cache *coherent_acquire_thread( struct coherent *c, const size_t size) { - if (c->shared) { - struct coherent __sparse_cache *cc = uncache_to_cache(c); - + if (c->shared) k_mutex_lock(&c->mutex, K_FOREVER); - /* invalidate local copy */ - dcache_invalidate_region(cc, size); - } - return (__sparse_force struct coherent __sparse_cache *)c; } static inline void coherent_release_thread(struct coherent __sparse_cache *c, const size_t size) { - if (c->shared) { - struct coherent *uc = cache_to_uncache(c); - - /* wtb and inv local data to coherent object */ - dcache_writeback_invalidate_region(c, size); - - k_mutex_unlock(&uc->mutex); - } + if (c->shared) + k_mutex_unlock(&c->mutex); } static inline void *__coherent_init_thread(size_t offset, const size_t size) diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index d427643ef3ea..c7798861a518 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -556,33 +556,34 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) * sink_module needs to set its IBS (input buffer size) * as min_available in buffer's source ifc */ - sink_set_min_free_space(audio_stream_get_sink(&buffer->stream), obs); - source_set_min_available(audio_stream_get_source(&buffer->stream), ibs); + sink_set_min_free_space(audio_buffer_get_sink(&buffer->audio_buffer), obs); + source_set_min_available(audio_buffer_get_source(&buffer->audio_buffer), ibs); #if CONFIG_ZEPHYR_DP_SCHEDULER struct ring_buffer *ring_buffer = NULL; if (sink->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP || source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { - ring_buffer = - ring_buffer_create(source_get_min_available(&buffer->stream._source_api), - sink_get_min_free_space(&buffer->stream._sink_api), - buffer->is_shared ? - RING_BUFFER_MODE_SHARED : RING_BUFFER_MODE_LOCAL, - buf_get_id(buffer), - &buffer->stream.runtime_stream_params); + struct sof_source *source = audio_buffer_get_source(&buffer->audio_buffer); + struct sof_sink *sink = audio_buffer_get_sink(&buffer->audio_buffer); + + ring_buffer = ring_buffer_create(source_get_min_available(source), + sink_get_min_free_space(sink), + buffer->is_shared ? + RING_BUFFER_MODE_SHARED : RING_BUFFER_MODE_LOCAL, + buf_get_id(buffer)); if (!ring_buffer) goto free; } if (sink->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) /* data destination module needs to use ring_buffer */ - buffer_attach_secondary_buffer(buffer, false /* at_input = false */, - &ring_buffer->audio_buffer); + audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, false, /* at_input */ + &ring_buffer->audio_buffer); else if (source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) /* data source module needs to use ring_buffer */ - buffer_attach_secondary_buffer(buffer, true /* at_input = true */, - &ring_buffer->audio_buffer); + audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, true, /* at_input */ + &ring_buffer->audio_buffer); #endif /* CONFIG_ZEPHYR_DP_SCHEDULER */ /* * Connect and bind the buffer to both source and sink components with LL processing been diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index 4db02de6f571..f97c77f3679b 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -3,7 +3,8 @@ cmocka_test(buffer_copy buffer_copy.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c @@ -27,7 +28,8 @@ cmocka_test(buffer_new buffer_new.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c @@ -50,7 +52,8 @@ cmocka_test(buffer_wrap buffer_wrap.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c @@ -73,7 +76,8 @@ cmocka_test(buffer_write buffer_write.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index 866e262f0f0a..61abb66332c2 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -9,7 +9,8 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 3059f45956ab..305a6846966c 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -24,7 +24,8 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 8f00dbedc750..0460c34dfc6e 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -25,7 +25,8 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index 8b8147ed769e..723cb091ff61 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -13,7 +13,8 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 6f54cd5b4ca3..67b10f77270d 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -14,7 +14,8 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/mux/mux_generic.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index 52f268a908c5..4ef68bc32b96 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -6,7 +6,8 @@ if(CONFIG_FORMAT_FLOAT) ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/pcm_converter/pcm_converter.c ${PROJECT_SOURCE_DIR}/src/audio/pcm_converter/pcm_converter_generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index 2f27d7cfcd74..6ba4fecd4c97 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -24,7 +24,8 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c @@ -48,7 +49,8 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c @@ -72,7 +74,8 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index 36c13759be6d..d5c9ed31ad4e 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -15,7 +15,8 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/selector/selector.c ${PROJECT_SOURCE_DIR}/src/audio/selector/selector_generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 901bd3c2e4f2..d89927578222 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -23,7 +23,8 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index 921698d04809..c3d9e47e6ea5 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -7,7 +7,8 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/math/fft/fft_16_hifi3.c ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32.c ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32_hifi3.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/comp_buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/buffers/audio_buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index c74596a060af..d3423c743103 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -415,7 +415,8 @@ zephyr_library_sources( # SOF mandatory audio processing ${SOF_AUDIO_PATH}/channel_map.c - ${SOF_AUDIO_PATH}/buffer.c + ${SOF_AUDIO_PATH}/buffers/comp_buffer.c + ${SOF_AUDIO_PATH}/buffers/audio_buffer.c ${SOF_AUDIO_PATH}/source_api_helper.c ${SOF_AUDIO_PATH}/sink_api_helper.c ${SOF_AUDIO_PATH}/sink_source_utils.c