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

buffer: Create audio stream buffer #2283

Merged
merged 21 commits into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
444c7e9
fir: Mark source buffer as const in processing functions
ktrzcinx Jan 16, 2020
550b6c7
ASRC: Define processing function typedef
ktrzcinx Jan 16, 2020
61deda6
ASRC: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
79810ec
mux: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
8fa2339
DAI: Simplify dai_dma_cb by adding temporary sink_bytes variables
ktrzcinx Jan 17, 2020
a2e7fa9
DAI: Use local variable holding frame format in dai playback and capt…
ktrzcinx Jan 17, 2020
41ecf6d
detect_test: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
2558945
kpb: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
a9a1a23
mixer: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
dddc773
selector: Define processing function typedef
ktrzcinx Jan 17, 2020
3fa8eb6
selector: Mark input device pointer as const in processing functions
ktrzcinx Jan 17, 2020
7f06d47
src: Mark input buffer input buffers with const in src_get_copy_limits
ktrzcinx Jan 17, 2020
c13584d
src: Mark input device pointer as const in processing functions
ktrzcinx Jan 17, 2020
bf023fd
volume: Define processing function typedef
ktrzcinx Jan 17, 2020
d8a0547
volume: Mark input device pointer as const in processing functions
ktrzcinx Jan 17, 2020
08d0477
dma: Define processing function typedef
ktrzcinx Jan 17, 2020
865b5a1
dma: Mark source buffer as const in processing functions
ktrzcinx Jan 17, 2020
287de6b
buffer: Remove unused alloc_size
ktrzcinx Jan 13, 2020
b989e70
buffer: Introduce local variable to short function call arg list
ktrzcinx Jan 17, 2020
0b45888
buffer: Create audio stream buffer
ktrzcinx Jan 13, 2020
140a063
audio_stream: Create wrapping function
ktrzcinx Jan 15, 2020
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
63 changes: 36 additions & 27 deletions src/audio/asrc/asrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
trace_error_comp(TRACE_CLASS_SRC, comp_ptr, \
__e, ##__VA_ARGS__)

ktrzcinx marked this conversation as resolved.
Show resolved Hide resolved
typedef void (*asrc_proc_func)(struct comp_dev *dev,
const struct audio_stream *source,
struct audio_stream *sink,
int *consumed,
int *produced);

/* asrc component private data */
struct comp_data {
struct asrc_farrow *asrc_obj; /* ASRC core data */
Expand All @@ -65,11 +71,7 @@ struct comp_data {
uint8_t *buf; /* Samples buffer for input and output */
uint8_t *ibuf[PLATFORM_MAX_CHANNELS]; /* Input channels pointers */
uint8_t *obuf[PLATFORM_MAX_CHANNELS]; /* Output channels pointers */
void (*asrc_func)(struct comp_dev *dev,
struct comp_buffer *source,
struct comp_buffer *sink,
int *consumed,
int *produced);
asrc_proc_func asrc_func; /* ASRC processing function */
};
ktrzcinx marked this conversation as resolved.
Show resolved Hide resolved

/* In-line functions */
Expand All @@ -88,7 +90,8 @@ static inline void src_inc_wrap_s16(int16_t **ptr, int16_t *end, size_t size)

/* A fast copy function for same in and out rate */
static void src_copy_s32(struct comp_dev *dev,
struct comp_buffer *source, struct comp_buffer *sink,
const struct audio_stream *source,
struct audio_stream *sink,
int *n_read, int *n_written)
{
struct comp_data *cd = comp_get_drvdata(dev);
Expand Down Expand Up @@ -145,7 +148,8 @@ static void src_copy_s32(struct comp_dev *dev,
}

static void src_copy_s16(struct comp_dev *dev,
struct comp_buffer *source, struct comp_buffer *sink,
const struct audio_stream *source,
struct audio_stream *sink,
int *n_read, int *n_written)
{
struct comp_data *cd = comp_get_drvdata(dev);
Expand Down Expand Up @@ -385,17 +389,19 @@ static int asrc_prepare(struct comp_dev *dev)
struct comp_buffer, source_list);

/* get source data format and period bytes */
cd->source_format = sourceb->frame_fmt;
source_period_bytes = buffer_period_bytes(sourceb, cd->source_frames);
cd->source_format = sourceb->stream.frame_fmt;
source_period_bytes = audio_stream_period_bytes(&sourceb->stream,
cd->source_frames);

/* get sink data format and period bytes */
cd->sink_format = sinkb->frame_fmt;
sink_period_bytes = buffer_period_bytes(sinkb, cd->sink_frames);

if (sinkb->size < config->periods_sink * sink_period_bytes) {
trace_asrc_error_with_ids(dev, "asrc_prepare(), sink size=%d"
" is insufficient, when periods=%d"
", period_bytes=%d", sinkb->size,
cd->sink_format = sinkb->stream.frame_fmt;
sink_period_bytes = audio_stream_period_bytes(&sinkb->stream,
cd->sink_frames);

if (sinkb->stream.size < config->periods_sink * sink_period_bytes) {
trace_asrc_error_with_ids(dev,
"asrc_prepare(), sink size=%d is insufficient, when periods=%d, period_bytes=%d",
sinkb->stream.size,
config->periods_sink,
sink_period_bytes);
ret = -ENOMEM;
Expand All @@ -415,7 +421,7 @@ static int asrc_prepare(struct comp_dev *dev)
}

/* ASRC supports S16_LE, S24_4LE and S32_LE formats */
switch (sourceb->frame_fmt) {
switch (sourceb->stream.frame_fmt) {
case SOF_IPC_FRAME_S16_LE:
cd->asrc_func = src_copy_s16;
break;
Expand All @@ -435,7 +441,7 @@ static int asrc_prepare(struct comp_dev *dev)
/*
* Allocate input and output data buffer
*/
frame_bytes = buffer_frame_bytes(sourceb);
frame_bytes = audio_stream_frame_bytes(&sourceb->stream);
cd->buf_size = (cd->source_frames_max + cd->sink_frames_max) *
frame_bytes;

Expand All @@ -449,8 +455,8 @@ static int asrc_prepare(struct comp_dev *dev)
goto err;
}

sample_bytes = frame_bytes / sourceb->channels;
for (i = 0; i < sourceb->channels; i++) {
sample_bytes = frame_bytes / sourceb->stream.channels;
for (i = 0; i < sourceb->stream.channels; i++) {
cd->ibuf[i] = cd->buf + i * sample_bytes;
cd->obuf[i] = cd->ibuf[i] + cd->source_frames_max * frame_bytes;
}
Expand All @@ -459,7 +465,7 @@ static int asrc_prepare(struct comp_dev *dev)
* Get required size and allocate memory for ASRC
*/
sample_bits = sample_bytes * 8;
ret = asrc_get_required_size(&cd->asrc_size, sourceb->channels,
ret = asrc_get_required_size(&cd->asrc_size, sourceb->stream.channels,
sample_bits);
if (ret) {
trace_asrc_error_with_ids(dev, "asrc_prepare(), get_required_size_bytes failed");
Expand All @@ -479,7 +485,7 @@ static int asrc_prepare(struct comp_dev *dev)
/*
* Initialize ASRC
*/
ret = asrc_initialise(cd->asrc_obj, sourceb->channels,
ret = asrc_initialise(cd->asrc_obj, sourceb->stream.channels,
cd->source_rate, cd->sink_rate,
ASRC_IOF_INTERLEAVED, ASRC_IOF_INTERLEAVED,
ASRC_BM_LINEAR, cd->frames, sample_bits,
Expand Down Expand Up @@ -529,8 +535,10 @@ static int asrc_copy(struct comp_dev *dev)
sink = list_first_item(&dev->bsink_list, struct comp_buffer,
source_list);

frames_src = source->avail / buffer_frame_bytes(source);
frames_snk = sink->free / buffer_frame_bytes(sink);
frames_src = source->stream.avail /
audio_stream_frame_bytes(&source->stream);
frames_snk = sink->stream.free /
audio_stream_frame_bytes(&sink->stream);

cd->source_frames = MIN(frames_src, cd->source_frames_max);
cd->sink_frames = ceil_divide(cd->source_frames * cd->sink_rate,
Expand All @@ -549,7 +557,8 @@ static int asrc_copy(struct comp_dev *dev)
}

if (cd->source_frames && cd->sink_frames)
cd->asrc_func(dev, source, sink, &consumed, &produced);
cd->asrc_func(dev, &source->stream, &sink->stream, &consumed,
&produced);

tracev_asrc_with_ids(dev, "asrc_copy(), consumed = %u, produced = %u",
consumed, produced);
Expand All @@ -559,11 +568,11 @@ static int asrc_copy(struct comp_dev *dev)
*/
if (consumed > 0)
comp_update_buffer_consume(source, consumed *
buffer_frame_bytes(source));
audio_stream_frame_bytes(&source->stream));

if (produced > 0)
comp_update_buffer_produce(sink, produced *
buffer_frame_bytes(sink));
audio_stream_frame_bytes(&sink->stream));

return 0;
}
Expand Down
86 changes: 28 additions & 58 deletions src/audio/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t align)
return NULL;
}

buffer->addr = rballoc_align(0, caps, size, align);
if (!buffer->addr) {
buffer->stream.addr = rballoc_align(0, caps, size, align);
if (!buffer->stream.addr) {
rfree(buffer);
trace_buffer_error("buffer_alloc() error: "
"could not alloc size = %u "
Expand Down Expand Up @@ -86,21 +86,21 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size)
return -EINVAL;
}

if (size == buffer->size)
if (size == buffer->stream.size)
return 0;

new_ptr = rbrealloc(buffer->addr, 0, buffer->caps, size);
new_ptr = rbrealloc(buffer->stream.addr, 0, buffer->caps, size);

/* we couldn't allocate bigger chunk */
if (!new_ptr && size > buffer->size) {
if (!new_ptr && size > buffer->stream.size) {
trace_buffer_error_with_ids(buffer, "resize error: can't alloc %u bytes type %u",
buffer->size, buffer->caps);
buffer->stream.size, buffer->caps);
return -ENOMEM;
}

/* use bigger chunk, else just use the old chunk but set smaller */
if (new_ptr)
buffer->addr = new_ptr;
buffer->stream.addr = new_ptr;

buffer_init(buffer, size, buffer->caps);

Expand All @@ -124,7 +124,7 @@ void buffer_free(struct comp_buffer *buffer)

list_item_del(&buffer->source_list);
list_item_del(&buffer->sink_list);
rfree(buffer->addr);
rfree(buffer->stream.addr);
rfree(buffer);
}

Expand All @@ -134,8 +134,9 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)
struct buffer_cb_transact cb_data = {
.buffer = buffer,
.transaction_amount = bytes,
.transaction_begin_address = buffer->w_ptr,
.transaction_begin_address = buffer->stream.w_ptr,
};
char *addr;

/* return if no bytes */
if (!bytes) {
Expand All @@ -150,42 +151,24 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)

irq_local_disable(flags);

buffer->w_ptr = (char *)buffer->w_ptr + bytes;

/* check for pointer wrap */
if (buffer->w_ptr >= buffer->end_addr)
buffer->w_ptr = (char *)buffer->addr +
((char *)buffer->w_ptr - (char *)buffer->end_addr);

/* "overwrite" old data in circular wrap case */
if (bytes > buffer->free)
buffer->r_ptr = buffer->w_ptr;

/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = (char *)buffer->w_ptr - (char *)buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = buffer->size; /* full */
else
buffer->avail = buffer->size -
((char *)buffer->r_ptr - (char *)buffer->w_ptr);

/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
audio_stream_produce(&buffer->stream, bytes);

notifier_event(buffer, NOTIFIER_ID_BUFFER_PRODUCE,
NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data));

irq_local_enable(flags);

addr = buffer->stream.addr;

tracev_buffer_with_ids(buffer,
"comp_update_buffer_produce(), ((buffer->avail << 16) | buffer->free) = %08x, ((buffer->id << 16) | buffer->size) = %08x",
(buffer->avail << 16) | buffer->free,
(buffer->id << 16) | buffer->size);
(buffer->stream.avail << 16) |
buffer->stream.free,
(buffer->id << 16) | buffer->stream.size);
tracev_buffer_with_ids(buffer,
"comp_update_buffer_produce(), ((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x",
((char *)buffer->r_ptr - (char *)buffer->addr) << 16 |
((char *)buffer->w_ptr - (char *)buffer->addr));
((char *)buffer->stream.r_ptr - addr) << 16 |
((char *)buffer->stream.w_ptr - addr));
}

void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes)
Expand All @@ -194,8 +177,9 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes)
struct buffer_cb_transact cb_data = {
.buffer = buffer,
.transaction_amount = bytes,
.transaction_begin_address = buffer->r_ptr,
.transaction_begin_address = buffer->stream.r_ptr,
};
char *addr;

/* return if no bytes */
if (!bytes) {
Expand All @@ -210,34 +194,20 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes)

irq_local_disable(flags);

buffer->r_ptr = (char *)buffer->r_ptr + bytes;

/* check for pointer wrap */
if (buffer->r_ptr >= buffer->end_addr)
buffer->r_ptr = (char *)buffer->addr +
((char *)buffer->r_ptr - (char *)buffer->end_addr);

/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = (char *)buffer->w_ptr - (char *)buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = 0; /* empty */
else
buffer->avail = buffer->size -
((char *)buffer->r_ptr - (char *)buffer->w_ptr);

/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
audio_stream_consume(&buffer->stream, bytes);

notifier_event(buffer, NOTIFIER_ID_BUFFER_CONSUME,
NOTIFIER_TARGET_CORE_LOCAL, &cb_data, sizeof(cb_data));

irq_local_enable(flags);

addr = buffer->stream.addr;

tracev_buffer_with_ids(buffer,
"comp_update_buffer_consume(), (buffer->avail << 16) | buffer->free = %08x, (buffer->id << 16) | buffer->size = %08x, (buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr)) = %08x",
(buffer->avail << 16) | buffer->free,
(buffer->id << 16) | buffer->size,
((char *)buffer->r_ptr - (char *)buffer->addr) << 16 |
((char *)buffer->w_ptr - (char *)buffer->addr));
(buffer->stream.avail << 16) |
buffer->stream.free,
(buffer->id << 16) | buffer->stream.size,
((char *)buffer->stream.r_ptr - addr) << 16 |
((char *)buffer->stream.w_ptr - addr));
}
7 changes: 4 additions & 3 deletions src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,10 @@ int comp_get_copy_limits(struct comp_dev *dev, struct comp_copy_limits *cl)
cl->sink = list_first_item(&dev->bsink_list, struct comp_buffer,
source_list);

cl->frames = buffer_avail_frames(cl->source, cl->sink);
cl->source_frame_bytes = buffer_frame_bytes(cl->source);
cl->sink_frame_bytes = buffer_frame_bytes(cl->sink);
cl->frames = audio_stream_avail_frames(&cl->source->stream,
&cl->sink->stream);
cl->source_frame_bytes = audio_stream_frame_bytes(&cl->source->stream);
cl->sink_frame_bytes = audio_stream_frame_bytes(&cl->sink->stream);
cl->source_bytes = cl->frames * cl->source_frame_bytes;
cl->sink_bytes = cl->frames * cl->sink_frame_bytes;

Expand Down
Loading