dummy-smart-amp: use sink & source buffer

Use process instead of process_audio_stream for pipeline 2.0

Signed-off-by: Rander Wang <rander.wang@intel.com>
This commit is contained in:
Rander Wang 2023-12-07 10:55:47 +08:00 committed by Liam Girdwood
parent 7f1193c11d
commit 73317455bf
1 changed files with 154 additions and 182 deletions

View File

@ -25,10 +25,15 @@ DECLARE_SOF_RT_UUID("smart_amp-test", smart_amp_test_comp_uuid, 0x167a961e, 0x8a
DECLARE_TR_CTX(smart_amp_test_comp_tr, SOF_UUID(smart_amp_test_comp_uuid),
LOG_LEVEL_INFO);
typedef int(*smart_amp_proc)(struct processing_module *mod,
struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink, uint32_t frames,
int8_t *chan_map);
typedef void (*smart_amp_proc)(int8_t const *src_ptr,
int8_t const *src_begin,
int8_t const *src_end,
int8_t *dst_ptr,
int8_t const *dst_begin,
int8_t const *dst_end,
uint32_t size);
struct smart_amp_data {
struct sof_smart_amp_ipc4_config ipc4_cfg;
struct sof_smart_amp_config config;
@ -86,27 +91,6 @@ sad_fail:
return ret;
}
static void smart_amp_set_params(struct processing_module *mod)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_dev *dev = mod->dev;
struct smart_amp_data *sad = module_get_private_data(mod);
struct comp_buffer *sink;
ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params);
/* update sink format */
if (!list_is_empty(&dev->bsink_list)) {
struct ipc4_output_pin_format *sink_fmt = &sad->ipc4_cfg.output_pin;
struct ipc4_audio_format out_fmt = sink_fmt->audio_fmt;
sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
ipc4_update_buffer_format(sink, &out_fmt);
params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream);
}
}
static int smart_amp_set_config(struct processing_module *mod, uint32_t config_id,
enum module_cfg_fragment_position pos, uint32_t data_offset_size,
const uint8_t *fragment, size_t fragment_size, uint8_t *response,
@ -171,160 +155,156 @@ static int smart_amp_free(struct processing_module *mod)
return 0;
}
static int smart_amp_params(struct processing_module *mod)
static void process_s16(int8_t const *src_ptr,
int8_t const *src_begin,
int8_t const *src_end,
int8_t *dst_ptr,
int8_t const *dst_begin,
int8_t const *dst_end,
uint32_t size)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_dev *dev = mod->dev;
int16_t const *src_addr = (int16_t const *)src_ptr;
int16_t *dst_addr = (int16_t *)dst_ptr;
int count = size >> 1;
int i;
for (i = 0; i < count; i++) {
if (src_addr >= (int16_t const *)src_end)
src_addr = (int16_t const *)src_begin;
if (dst_addr >= (int16_t *)dst_end)
dst_addr = (int16_t *)dst_begin;
*dst_addr = *src_addr;
src_addr++;
dst_addr++;
}
}
static void process_s32(int8_t const *src_ptr,
int8_t const *src_begin,
int8_t const *src_end,
int8_t *dst_ptr,
int8_t const *dst_begin,
int8_t const *dst_end,
uint32_t size)
{
int32_t const *src_addr = (int32_t const *)src_ptr;
int32_t *dst_addr = (int32_t *)dst_ptr;
int count = size >> 2;
int i;
for (i = 0; i < count; i++) {
if (src_addr >= (int32_t const *)src_end)
src_addr = (int32_t const *)src_begin;
if (dst_addr >= (int32_t *)dst_end)
dst_addr = (int32_t *)dst_begin;
*dst_addr = *src_addr;
src_addr++;
dst_addr++;
}
}
static int smart_amp_process_data(struct processing_module *mod,
struct sof_source *source,
struct sof_source *feedback,
struct sof_sink *sink,
size_t size)
{
struct smart_amp_data *sad = module_get_private_data(mod);
int8_t const *src_ptr;
int8_t const *src_begin;
int8_t const *src_end;
int8_t *dst_ptr;
int8_t const *dst_begin;
int8_t const *dst_end;
size_t src_size;
size_t dst_size;
int ret;
comp_dbg(dev, "smart_amp_params()");
smart_amp_set_params(mod);
ret = comp_verify_params(dev, BUFF_PARAMS_CHANNELS, params);
if (ret < 0) {
comp_err(dev, "smart_amp_params(): pcm params verification failed.");
return -EINVAL;
ret = sink_get_buffer(sink, size,
(void **)&dst_ptr,
(void **)&dst_begin,
&dst_size);
if (ret)
return ret;
if (!feedback || !source_get_data_available(feedback))
goto source;
ret = source_get_data(feedback, size,
(void const **)&src_ptr,
(void const **)&src_begin,
&src_size);
if (ret) {
if (ret == -EBUSY)
return 0;
else
return ret;
}
src_end = src_begin + src_size;
dst_end = dst_begin + dst_size;
sad->process(src_ptr, src_begin, src_end, dst_ptr, dst_begin, dst_end, size);
source_release_data(feedback, size);
source:
ret = source_get_data(source, size,
(void const **)&src_ptr,
(void const **)&src_begin,
&src_size);
if (ret)
return ret;
src_end = src_begin + src_size;
dst_end = dst_begin + dst_size;
sad->process(src_ptr, src_begin, src_end, dst_ptr, dst_begin, dst_end, size);
source_release_data(source, size);
sink_commit_buffer(sink, size);
return 0;
}
static int smart_amp_process_s16(struct processing_module *mod,
struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink,
uint32_t frames, int8_t *chan_map)
{
struct smart_amp_data *sad = module_get_private_data(mod);
struct audio_stream *source = bsource->data;
struct audio_stream *sink = bsink->data;
int16_t *src;
int16_t *dest;
uint32_t in_frag = 0;
uint32_t out_frag = 0;
int i;
int j;
bsource->consumed += frames * audio_stream_get_channels(source) * sizeof(int16_t);
for (i = 0; i < frames; i++) {
for (j = 0 ; j < sad->out_channels; j++) {
if (chan_map[j] != -1) {
src = audio_stream_read_frag_s16(source,
in_frag +
chan_map[j]);
dest = audio_stream_write_frag_s16(sink,
out_frag);
*dest = *src;
}
out_frag++;
}
in_frag += audio_stream_get_channels(source);
}
return 0;
}
static int smart_amp_process_s32(struct processing_module *mod,
struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink,
uint32_t frames, int8_t *chan_map)
{
struct smart_amp_data *sad = module_get_private_data(mod);
struct audio_stream *source = bsource->data;
struct audio_stream *sink = bsink->data;
int32_t *src;
int32_t *dest;
uint32_t in_frag = 0;
uint32_t out_frag = 0;
int i;
int j;
bsource->consumed += frames * audio_stream_get_channels(source) * sizeof(int32_t);
for (i = 0; i < frames; i++) {
for (j = 0 ; j < sad->out_channels; j++) {
if (chan_map[j] != -1) {
src = audio_stream_read_frag_s32(source,
in_frag +
chan_map[j]);
dest = audio_stream_write_frag_s32(sink,
out_frag);
*dest = *src;
}
out_frag++;
}
in_frag += audio_stream_get_channels(source);
}
return 0;
}
static smart_amp_proc get_smart_amp_process(struct comp_dev *dev,
struct comp_buffer *buf)
{
switch (audio_stream_get_frm_fmt(&buf->stream)) {
case SOF_IPC_FRAME_S16_LE:
return smart_amp_process_s16;
case SOF_IPC_FRAME_S24_4LE:
case SOF_IPC_FRAME_S32_LE:
return smart_amp_process_s32;
default:
comp_err(dev, "smart_amp_process() error: not supported frame format");
return NULL;
}
}
static int smart_amp_process(struct processing_module *mod,
struct input_stream_buffer *input_buffers, int num_input_buffers,
struct output_stream_buffer *output_buffers, int num_output_buffers)
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks)
{
struct smart_amp_data *sad = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct comp_buffer *fb_buf_c;
struct comp_buffer *buf;
struct input_stream_buffer *fb_input = NULL;
struct sof_source *fb_input = NULL;
/* if there is only one input stream, it should be the source input */
struct input_stream_buffer *src_input = &input_buffers[0];
uint32_t avail_passthrough_frames;
uint32_t avail_frames = 0;
uint32_t sink_bytes;
struct sof_source *src_input = sources[0];
uint32_t avail_passthrough;
uint32_t avail = 0;
uint32_t i;
int ret;
if (num_input_buffers == SMART_AMP_NUM_IN_PINS)
for (i = 0; i < num_input_buffers; i++) {
buf = container_of(input_buffers[i].data, struct comp_buffer, stream);
if (IPC4_SINK_QUEUE_ID(buf_get_id(buf)) ==
SOF_SMART_AMP_FEEDBACK_QUEUE_ID) {
fb_input = &input_buffers[i];
fb_buf_c = buf;
if (num_of_sources == SMART_AMP_NUM_IN_PINS) {
for (i = 0; i < num_of_sources; i++) {
if (IPC4_SINK_QUEUE_ID(source_get_id(sources[i])) ==
SOF_SMART_AMP_FEEDBACK_QUEUE_ID) {
fb_input = sources[i];
} else {
src_input = &input_buffers[i];
src_input = sources[i];
}
}
avail_passthrough_frames = src_input->size;
if (fb_input) {
if (fb_buf_c->source && comp_get_state(dev, fb_buf_c->source) == dev->state) {
/* feedback */
avail_frames = MIN(avail_passthrough_frames,
fb_input->size);
sad->process(mod, fb_input, &output_buffers[0],
avail_frames, sad->config.feedback_ch_map);
}
}
if (!avail_frames)
avail_frames = avail_passthrough_frames;
avail_passthrough = source_get_data_available(src_input);
/* bytes calculation */
sink_bytes = avail_frames *
audio_stream_frame_bytes(output_buffers[0].data);
if (fb_input && source_get_data_available(fb_input)) {
/* feedback */
avail = MIN(avail_passthrough, source_get_data_available(fb_input));
avail = MIN(avail, sink_get_free_size(sinks[0]));
} else {
avail = MIN(avail_passthrough, sink_get_free_size(sinks[0]));
}
/* process data */
sad->process(mod, src_input, &output_buffers[0],
avail_frames, sad->config.source_ch_map);
ret = smart_amp_process_data(mod, src_input, fb_input, sinks[0], avail);
output_buffers[0].size = sink_bytes;
return 0;
return ret;
}
static int smart_amp_reset(struct processing_module *mod)
@ -336,6 +316,19 @@ static int smart_amp_reset(struct processing_module *mod)
return 0;
}
static smart_amp_proc get_smart_amp_process(struct sof_sink *sink)
{
switch (sink_get_frm_fmt(sink)) {
case SOF_IPC_FRAME_S16_LE:
return process_s16;
case SOF_IPC_FRAME_S24_4LE:
case SOF_IPC_FRAME_S32_LE:
return process_s32;
default:
return NULL;
}
}
static int smart_amp_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks)
@ -346,42 +339,21 @@ static int smart_amp_prepare(struct processing_module *mod,
struct comp_buffer *sink_buffer;
struct list_item *blist;
int ret;
int i;
ret = smart_amp_params(mod);
if (ret < 0)
return ret;
comp_dbg(dev, "smart_amp_prepare()");
/* searching for stream and feedback source buffers */
list_for_item(blist, &dev->bsource_list) {
source_buffer = container_of(blist, struct comp_buffer,
sink_list);
audio_stream_init_alignment_constants(1, 1, &source_buffer->stream);
if (IPC4_SINK_QUEUE_ID(buf_get_id(source_buffer)) ==
SOF_SMART_AMP_FEEDBACK_QUEUE_ID) {
audio_stream_set_channels(&source_buffer->stream,
sad->config.feedback_channels);
audio_stream_set_rate(&source_buffer->stream,
mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency);
}
}
sink_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
sad->out_channels = audio_stream_get_channels(&sink_buffer->stream);
audio_stream_init_alignment_constants(1, 1, &sink_buffer->stream);
sad->process = get_smart_amp_process(dev, sink_buffer);
sad->process = get_smart_amp_process(sinks[0]);
if (!sad->process) {
comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed");
ret = -EINVAL;
return -EINVAL;
}
return ret;
return 0;
}
static const struct module_interface smart_amp_test_interface = {
.init = smart_amp_init,
.prepare = smart_amp_prepare,
.process_audio_stream = smart_amp_process,
.process = smart_amp_process,
.set_configuration = smart_amp_set_config,
.get_configuration = smart_amp_get_config,
.reset = smart_amp_reset,