Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipeline2 0 - audio_buffer / sink / source api extensions and simplifications #9594

Merged
merged 5 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
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
126 changes: 126 additions & 0 deletions src/audio/buffers/audio_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stddef.h>
#include <errno.h>
#include <rtos/alloc.h>
#include <ipc/stream.h>
#include <sof/audio/audio_buffer.h>
#include <sof/audio/sink_api.h>
#include <sof/audio/source_api.h>
Expand Down Expand Up @@ -95,3 +96,128 @@ void audio_buffer_free(struct sof_audio_buffer *buffer)
buffer->ops->free(buffer);
rfree(buffer);
}

static
kv2019i marked this conversation as resolved.
Show resolved Hide resolved
int audio_buffer_source_set_ipc_params_default(struct sof_audio_buffer *buffer,
struct sof_ipc_stream_params *params,
bool force_update)
{
CORE_CHECK_STRUCT(buffer);

if (audio_buffer_hw_params_configured(buffer) && !force_update)
return 0;

struct sof_audio_stream_params *audio_stream_params =
audio_buffer_get_stream_params(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;

audio_buffer_set_hw_params_configured(buffer);

if (buffer->ops->on_audio_format_set)
return buffer->ops->on_audio_format_set(buffer);
return 0;
}

static
int audio_buffer_sink_set_ipc_params(struct sof_sink *sink, struct sof_ipc_stream_params *params,
bool force_update)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);

if (buffer->ops->audio_set_ipc_params)
return buffer->ops->audio_set_ipc_params(buffer, params, force_update);
return audio_buffer_source_set_ipc_params_default(buffer, params, force_update);
}

static
int audio_buffer_sink_on_audio_format_set(struct sof_sink *sink)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);

if (buffer->ops->on_audio_format_set)
return buffer->ops->on_audio_format_set(buffer);
return 0;
}

static
int audio_buffer_sink_set_alignment_constants(struct sof_sink *sink,
const uint32_t byte_align,
const uint32_t frame_align_req)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);

if (buffer->ops->set_alignment_constants)
return buffer->ops->set_alignment_constants(buffer, byte_align, frame_align_req);
return 0;
}

static
int audio_buffer_source_set_ipc_params(struct sof_source *source,
struct sof_ipc_stream_params *params, bool force_update)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);

if (buffer->ops->audio_set_ipc_params)
return buffer->ops->audio_set_ipc_params(buffer, params, force_update);
return audio_buffer_source_set_ipc_params_default(buffer, params, force_update);
}

static
int audio_buffer_source_on_audio_format_set(struct sof_source *source)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);

if (buffer->ops->on_audio_format_set)
return buffer->ops->on_audio_format_set(buffer);
return 0;
}

static
int audio_buffer_source_set_alignment_constants(struct sof_source *source,
const uint32_t byte_align,
const uint32_t frame_align_req)
{
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);

if (buffer->ops->set_alignment_constants)
return buffer->ops->set_alignment_constants(buffer, byte_align, frame_align_req);
return 0;
}

void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared,
struct source_ops *source_ops, struct sink_ops *sink_ops,
const struct audio_buffer_ops *audio_buffer_ops,
struct sof_audio_stream_params *audio_stream_params)
{
CORE_CHECK_STRUCT_INIT(&buffer, is_shared);
buffer->buffer_type = buffer_type;
buffer->ops = audio_buffer_ops;
buffer->audio_stream_params = audio_stream_params;
buffer->is_shared = is_shared;

/* set default implementations of sink/source methods, if there's no
* specific implementation provided
*/
if (!sink_ops->audio_set_ipc_params)
sink_ops->audio_set_ipc_params = audio_buffer_sink_set_ipc_params;
if (!sink_ops->on_audio_format_set && buffer->ops->on_audio_format_set)
sink_ops->on_audio_format_set = audio_buffer_sink_on_audio_format_set;
if (!sink_ops->set_alignment_constants && buffer->ops->set_alignment_constants)
sink_ops->set_alignment_constants = audio_buffer_sink_set_alignment_constants;

if (!source_ops->audio_set_ipc_params)
source_ops->audio_set_ipc_params = audio_buffer_source_set_ipc_params;
if (!source_ops->on_audio_format_set && buffer->ops->on_audio_format_set)
source_ops->on_audio_format_set = audio_buffer_source_on_audio_format_set;
if (!source_ops->set_alignment_constants && buffer->ops->set_alignment_constants)
source_ops->set_alignment_constants = audio_buffer_source_set_alignment_constants;

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));
}
71 changes: 26 additions & 45 deletions src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,33 +64,6 @@ static int comp_buffer_release_data(struct sof_source *source, size_t 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);
Expand Down Expand Up @@ -125,33 +98,43 @@ static int comp_buffer_commit_buffer(struct sof_sink *sink, size_t 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)
static int comp_buffer_set_ipc_params(struct sof_audio_buffer *audio_buffer,
struct sof_ipc_stream_params *params,
bool force_update)
{
struct comp_buffer *buffer = comp_buffer_get_from_sink(sink);
struct comp_buffer *buffer = container_of(audio_buffer, struct comp_buffer, audio_buffer);

return buffer_set_params(buffer, params, force_update);
}

static int comp_buffer_sink_format_set(struct sof_sink *sink)
static int comp_buffer_format_set(struct sof_audio_buffer *audio_buffer)
{
struct comp_buffer *buffer = comp_buffer_get_from_sink(sink);
struct comp_buffer *buffer = container_of(audio_buffer, struct comp_buffer, audio_buffer);

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)
static int comp_buffer_set_alignment_constants(struct sof_audio_buffer *audio_buffer,
const uint32_t byte_align,
const uint32_t frame_align_req)
{
struct comp_buffer *buffer = comp_buffer_get_from_sink(sink);
struct comp_buffer *buffer = container_of(audio_buffer, struct comp_buffer, audio_buffer);

audio_stream_set_align(byte_align, frame_align_req, &buffer->stream);
return 0;
}

static void comp_buffer_reset(struct sof_audio_buffer *audio_buffer)
{
struct comp_buffer *buffer = container_of(audio_buffer, struct comp_buffer, audio_buffer);

/* reset rw pointers and avail/free bytes counters */
audio_stream_reset(&buffer->stream);
lgirdwood marked this conversation as resolved.
Show resolved Hide resolved
/* clear buffer contents */
buffer_zero(buffer);
}

/* free component in the pipeline */
static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)
{
Expand All @@ -177,26 +160,24 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)
rfree(buffer->stream.addr);
}

static const struct source_ops comp_buffer_source_ops = {
static 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 = {
static 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,
.reset = comp_buffer_reset,
.audio_set_ipc_params = comp_buffer_set_ipc_params,
.on_audio_format_set = comp_buffer_format_set,
.set_alignment_constants = comp_buffer_set_alignment_constants
};

static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, uint32_t caps,
Expand Down
93 changes: 35 additions & 58 deletions src/audio/buffers/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,18 @@ 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)
marcinszkudlinski marked this conversation as resolved.
Show resolved Hide resolved
{
struct sof_audio_buffer *audio_buffer = sof_audo_buffer_from_sink(sink);
struct sof_audio_buffer *audio_buffer = sof_audio_buffer_from_sink(sink);

return container_of(audio_buffer, struct ring_buffer, audio_buffer);
}

static inline struct ring_buffer *ring_buffer_from_source(struct sof_source *source)
{
struct sof_audio_buffer *audio_buffer = sof_audo_buffer_from_source(source);
struct sof_audio_buffer *audio_buffer = sof_audio_buffer_from_source(source);

return container_of(audio_buffer, struct ring_buffer, audio_buffer);
}

/**
* @brief remove the queue from the list, free memory
*/
static void ring_buffer_free(struct sof_audio_buffer *buffer)
{
struct ring_buffer *ring_buffer = (struct ring_buffer *)buffer;

rfree((__sparse_force void *)ring_buffer->_data_buffer);
}

/**
* @brief return true if the ring buffer is shared between 2 cores
*/
Expand Down Expand Up @@ -93,6 +83,36 @@ static inline void ring_buffer_writeback_shared(struct ring_buffer *ring_buffer,
dcache_writeback_region(ptr, size);
}


/**
* @brief remove the queue from the list, free memory
*/
static void ring_buffer_free(struct sof_audio_buffer *audio_buffer)
{
if (!audio_buffer)
return;

struct ring_buffer *ring_buffer =
container_of(audio_buffer, struct ring_buffer, audio_buffer);

rfree((__sparse_force void *)ring_buffer->_data_buffer);
}

static void ring_buffer_reset(struct sof_audio_buffer *audio_buffer)
{
struct ring_buffer *ring_buffer =
container_of(audio_buffer, struct ring_buffer, audio_buffer);

ring_buffer->_write_offset = 0;
ring_buffer->_read_offset = 0;

ring_buffer_invalidate_shared(ring_buffer, ring_buffer->_data_buffer,
ring_buffer->data_buffer_size);
bzero((__sparse_force void *)ring_buffer->_data_buffer, ring_buffer->data_buffer_size);
ring_buffer_writeback_shared(ring_buffer, ring_buffer->_data_buffer,
ring_buffer->data_buffer_size);
}

static inline
uint8_t __sparse_cache *ring_buffer_get_pointer(struct ring_buffer *ring_buffer, size_t offset)
{
Expand Down Expand Up @@ -219,64 +239,21 @@ static int ring_buffer_release_data(struct sof_source *source, size_t free_size)
return 0;
}

static int ring_buffer_set_ipc_params(struct ring_buffer *ring_buffer,
struct sof_ipc_stream_params *params,
bool force_update)
{
CORE_CHECK_STRUCT(&ring_buffer->audio_buffer);

if (audio_buffer_hw_params_configured(&ring_buffer->audio_buffer) && !force_update)
return 0;

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;

audio_buffer_set_hw_params_configured(&ring_buffer->audio_buffer);

return 0;
}

static int ring_buffer_set_ipc_params_source(struct sof_source *source,
struct sof_ipc_stream_params *params,
bool force_update)
{
struct ring_buffer *ring_buffer = ring_buffer_from_source(source);

CORE_CHECK_STRUCT(&ring_buffer->audio_buffer);
return ring_buffer_set_ipc_params(ring_buffer, params, force_update);
}

static int ring_buffer_set_ipc_params_sink(struct sof_sink *sink,
struct sof_ipc_stream_params *params,
bool force_update)
{
struct ring_buffer *ring_buffer = ring_buffer_from_sink(sink);

CORE_CHECK_STRUCT(&ring_buffer->audio_buffer);
return ring_buffer_set_ipc_params(ring_buffer, params, force_update);
}

static const struct source_ops ring_buffer_source_ops = {
static struct source_ops ring_buffer_source_ops = {
.get_data_available = ring_buffer_get_data_available,
.get_data = ring_buffer_get_data,
.release_data = ring_buffer_release_data,
.audio_set_ipc_params = ring_buffer_set_ipc_params_source,
};

static const struct sink_ops ring_buffer_sink_ops = {
static struct sink_ops ring_buffer_sink_ops = {
.get_free_size = ring_buffer_get_free_size,
.get_buffer = ring_buffer_get_buffer,
.commit_buffer = ring_buffer_commit_buffer,
.audio_set_ipc_params = ring_buffer_set_ipc_params_sink,
};

static const struct audio_buffer_ops audio_buffer_ops = {
.free = ring_buffer_free,
.reset = ring_buffer_reset
};

struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_space, bool is_shared,
Expand Down
Loading
Loading