From af8766bd437086f916de3268007125e4574e81e6 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 16 Aug 2023 14:42:37 +0200 Subject: [PATCH 1/5] loadable module: don't define PHDR twice Loadable modules are linked, using a linked script, built by a cmake script. That linker script includes multiple existing linker script fragments. Each of those fragments defines 1 or more sections and respective PHDRs. However, some of those scripts, e.g. common_rodata_linker_script.txt and data_linker_script.txt add sections to the same rodata_phdr PHDR. This makes the linker allocate sections in that PHDR twice in the resulting output file: one copy is real and the other one is filled with zeros. Removing one of the PHDR definitions solves the problem and removes about 60KiB of empty space from the output file. Signed-off-by: Guennadi Liakhovetski --- lmdk/cmake/ldscripts/common_rodata_linker_script.txt | 5 +---- lmdk/cmake/ldscripts/common_text_linker_script.txt | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lmdk/cmake/ldscripts/common_rodata_linker_script.txt b/lmdk/cmake/ldscripts/common_rodata_linker_script.txt index 2f3e4bfad4d9..343107e7d37d 100644 --- a/lmdk/cmake/ldscripts/common_rodata_linker_script.txt +++ b/lmdk/cmake/ldscripts/common_rodata_linker_script.txt @@ -1,7 +1,4 @@ - -PHDRS { - rodata_phdr PT_LOAD; -} +/* The .rodata PHDR is already defined in data_linker_script.txt */ SECTIONS { .common.rodata : ALIGN(4096) { diff --git a/lmdk/cmake/ldscripts/common_text_linker_script.txt b/lmdk/cmake/ldscripts/common_text_linker_script.txt index 10468dc4bf3a..ecdd39d738c4 100644 --- a/lmdk/cmake/ldscripts/common_text_linker_script.txt +++ b/lmdk/cmake/ldscripts/common_text_linker_script.txt @@ -1,7 +1,4 @@ - -PHDRS { - text_phdr PT_LOAD; -} +/* The .text PHDR is already defined in text_linker_script.txt */ SECTIONS { .common.text : ALIGN(4096){ From 5f3d492a0b165f957183db3817db104c57dd4b26 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 27 Jun 2023 11:55:07 +0300 Subject: [PATCH 2/5] module: fix firmware compilation for loadable modules Set correct source & sink parameters for module prepare function Signed-off-by: Guennadi Liakhovetski --- src/audio/module_adapter/module/modules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 1f7ee82b6a42..428afdef7596 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -174,7 +174,7 @@ static int modules_prepare(struct processing_module *mod, struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; - ret = mod_in->prepare(mod, NULL, 0, NULL, 0); + ret = mod_in->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); } else { ret = iadk_wrapper_prepare(mod->priv.module_adapter); } From 22c398c77702909f20fe58687fc28802cd128931 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 8 Sep 2023 16:59:06 +0200 Subject: [PATCH 3/5] module-adapter: allow multiple processing modes to be implemented The module-adapter API has 3 processing modes: raw, stream and source-sink, and until now only one of them can be implemented by any module. However, the "modules" module, that loads loadable modules, has to implement all of them to be prepared to handle any loadable modules. This adds support for such modules. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Rander Wang --- src/audio/module_adapter/module/generic.c | 6 +- src/audio/module_adapter/module/modules.c | 55 ++++++++++++++++--- src/audio/module_adapter/module_adapter.c | 10 ++++ src/include/module/module/base.h | 8 +++ .../sof/audio/module_adapter/module/generic.h | 11 +--- 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 3ab9f991feb9..565209af6951 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -98,7 +98,7 @@ int module_init(struct processing_module *mod, const struct module_interface *in /* check interface, there must be one and only one of processing procedure */ if (!interface->init || (!!interface->process + !!interface->process_audio_stream + - !!interface->process_raw_data != 1)) { + !!interface->process_raw_data < 1)) { comp_err(dev, "module_init(): comp %d is missing mandatory interfaces", dev_comp_id(dev)); return -EIO; @@ -258,10 +258,10 @@ int module_process_legacy(struct processing_module *mod, /* set state to processing */ md->state = MODULE_PROCESSING; #endif - if (md->ops->process_audio_stream) + if (IS_PROCESSING_MODE_AUDIO_STREAM(mod)) ret = md->ops->process_audio_stream(mod, input_buffers, num_input_buffers, output_buffers, num_output_buffers); - else if (md->ops->process_raw_data) + else if (IS_PROCESSING_MODE_RAW_DATA(mod)) ret = md->ops->process_raw_data(mod, input_buffers, num_input_buffers, output_buffers, num_output_buffers); else diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 428afdef7596..61bcd7b02421 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -142,10 +142,22 @@ static int modules_init(struct processing_module *mod) struct module_interface *mod_in = (struct module_interface *)md->module_adapter; + /* The order of preference */ + if (mod_in->process) + mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK; + else if (mod_in->process_audio_stream) + mod->proc_type = MODULE_PROCESS_TYPE_STREAM; + else if (mod_in->process_raw_data) + mod->proc_type = MODULE_PROCESS_TYPE_RAW; + else + return -EINVAL; + ret = mod_in->init(mod); } else { + mod->proc_type = MODULE_PROCESS_TYPE_RAW; ret = iadk_wrapper_init(md->module_adapter); } + return ret; } @@ -195,18 +207,45 @@ static int modules_init_process(struct processing_module *mod) return 0; } +static int modules_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) +{ + if (!mod->is_native_sof) + return -EOPNOTSUPP; + + struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; + + return mod_in->process(mod, sources, num_of_sources, sinks, num_of_sinks); +} + +static int modules_process_audio_stream(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) +{ + if (!mod->is_native_sof) + return -EOPNOTSUPP; + + struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; + + return mod_in->process_audio_stream(mod, input_buffers, num_input_buffers, + output_buffers, num_output_buffers); +} + /* - * \brief modules_process. + * \brief modules_process_raw. * \param[in] mod - processing module pointer. * * \return: zero on success * error code on failure */ -static int modules_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) +static int modules_process_raw(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 comp_dev *dev = mod->dev; struct module_data *md = &mod->priv; @@ -384,7 +423,9 @@ static int modules_reset(struct processing_module *mod) static const struct module_interface interface = { .init = modules_init, .prepare = modules_prepare, - .process_raw_data = modules_process, + .process_raw_data = modules_process_raw, + .process = modules_process, + .process_audio_stream = modules_process_audio_stream, .set_processing_mode = modules_set_processing_mode, .get_processing_mode = modules_get_processing_mode, .set_configuration = modules_set_configuration, diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index e30c6cbc51cb..3a8fff55c0f5 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -93,6 +93,16 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, mod->max_sources = 1; mod->max_sinks = 1; + /* The order of preference */ + if (interface->process) + mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK; + else if (interface->process_audio_stream) + mod->proc_type = MODULE_PROCESS_TYPE_STREAM; + else if (interface->process_raw_data) + mod->proc_type = MODULE_PROCESS_TYPE_RAW; + else + goto err; + /* Init processing module */ ret = module_init(mod, interface); if (ret) { diff --git a/src/include/module/module/base.h b/src/include/module/module/base.h index 56964162467f..ea951412c653 100644 --- a/src/include/module/module/base.h +++ b/src/include/module/module/base.h @@ -60,6 +60,12 @@ struct module_data { #endif /* SOF_MODULE_PRIVATE */ }; +enum module_processing_type { + MODULE_PROCESS_TYPE_SOURCE_SINK, + MODULE_PROCESS_TYPE_STREAM, + MODULE_PROCESS_TYPE_RAW, +}; + /* * A pointer to this structure is passed to module API functions (from struct module_interface). * This structure should contain only fields that should be available to a module. @@ -153,6 +159,8 @@ struct processing_module { /* max source/sinks supported by the module */ uint32_t max_sources; uint32_t max_sinks; + + enum module_processing_type proc_type; #endif /* SOF_MODULE_PRIVATE */ }; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 1ab2485fe348..a108b81f1404 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -25,14 +25,9 @@ * helpers to determine processing type * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE */ -#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) - -#define IS_PROCESSING_MODE_RAW_DATA(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) - -#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process) +#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_STREAM) +#define IS_PROCESSING_MODE_RAW_DATA(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_RAW) +#define IS_PROCESSING_MODE_SINK_SOURCE(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_SOURCE_SINK) #define MAX_BLOB_SIZE 8192 #define MODULE_MAX_SOURCES 8 From efff75dd85c70aeb7281540a34ff107454541bf5 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Thu, 7 Dec 2023 10:55:47 +0800 Subject: [PATCH 4/5] dummy-smart-amp: use sink & source buffer Use process instead of process_audio_stream for pipeline 2.0 Signed-off-by: Rander Wang --- src/samples/audio/smart_amp_test_ipc4.c | 316 +++++++++++------------- 1 file changed, 144 insertions(+), 172 deletions(-) diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index d09a8f9a9720..5395f1a6ef08 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -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 @@ static int smart_amp_init(struct processing_module *mod) 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; - int ret; + int16_t const *src_addr = (int16_t const *)src_ptr; + int16_t *dst_addr = (int16_t *)dst_ptr; + int count = size >> 1; + int i; - 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; + 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++; } - 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) +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) { - 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; + int32_t const *src_addr = (int32_t const *)src_ptr; + int32_t *dst_addr = (int32_t *)dst_ptr; + int count = size >> 2; 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); + + 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++; } - 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) +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); - 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); - } + 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; - return 0; -} + ret = sink_get_buffer(sink, size, + (void **)&dst_ptr, + (void **)&dst_begin, + &dst_size); + if (ret) + return ret; -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; + 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(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); - - output_buffers[0].size = sink_bytes; + ret = smart_amp_process_data(mod, src_input, fb_input, sinks[0], avail); - 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, From 694aa9e3feb2352296cdebfb0ed1eec594e18d9a Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 8 Dec 2023 13:38:29 +0800 Subject: [PATCH 5/5] lmdk: add dummy loadable smart amp support It will be built will __SOF_MODULE_SERVICE_BUILD__ enabled Signed-off-by: Rander Wang --- lmdk/cmake/ldscripts/data_linker_script.txt | 2 +- lmdk/libraries/smart_amp_test/CMakeLists.txt | 25 ++++ .../smart_amp_test/smart_amp_test.toml | 79 ++++++++++ lmdk/modules/smart_amp_test/CMakeLists.txt | 13 ++ src/include/ipc4/base-config.h | 3 +- .../sof/samples/audio/smart_amp_test.h | 16 +- src/samples/audio/smart_amp_test_ipc4.c | 138 ++++++++++-------- 7 files changed, 215 insertions(+), 61 deletions(-) create mode 100644 lmdk/libraries/smart_amp_test/CMakeLists.txt create mode 100644 lmdk/libraries/smart_amp_test/smart_amp_test.toml create mode 100644 lmdk/modules/smart_amp_test/CMakeLists.txt diff --git a/lmdk/cmake/ldscripts/data_linker_script.txt b/lmdk/cmake/ldscripts/data_linker_script.txt index cbdf8001c0be..63eed21cb07a 100644 --- a/lmdk/cmake/ldscripts/data_linker_script.txt +++ b/lmdk/cmake/ldscripts/data_linker_script.txt @@ -15,7 +15,7 @@ SECTIONS { _data_end = ABSOLUTE(.); } >HPSRAM_seg : data_phdr - .rodata : { + .rodata : ALIGN(4096) { _rodata_start = ABSOLUTE(.); *(.gnu.linkonce.r.*) *(.rodata) diff --git a/lmdk/libraries/smart_amp_test/CMakeLists.txt b/lmdk/libraries/smart_amp_test/CMakeLists.txt new file mode 100644 index 000000000000..0282a83bbf90 --- /dev/null +++ b/lmdk/libraries/smart_amp_test/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.20) +set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/../../cmake/xtensa-toolchain.cmake") + +project(smart_amp_test) + +macro(is_zephyr ret) + if(CONFIG_ZEPHYR_SOF_MODULE) + set(${ret} TRUE) + else() + set(${ret} FALSE) + endif() +endmacro() + +# list of modules to be built and included into this loadable library +set(MODULES_LIST smart_amp_test) + +# toml file for rimage to generate manifets +set(TOML "${CMAKE_CURRENT_LIST_DIR}/smart_amp_test.toml") + +# TODO: Move it somewhere??? +add_definitions(-DMAJOR_IADSP_API_VERSION=5) +add_definitions(-DMIDDLE_IADSP_API_VERSION=0) +add_definitions(-DMINOR_IADSP_API_VERSION=0) + +include(../../cmake/build.cmake) diff --git a/lmdk/libraries/smart_amp_test/smart_amp_test.toml b/lmdk/libraries/smart_amp_test/smart_amp_test.toml new file mode 100644 index 000000000000..34f3463343dd --- /dev/null +++ b/lmdk/libraries/smart_amp_test/smart_amp_test.toml @@ -0,0 +1,79 @@ +version = [3, 0] + +[adsp] +name = "mtl" +image_size = "0x2C0000" # (22) bank * 128KB +alias_mask = "0xE0000000" + +[[adsp.mem_zone]] +type = "ROM" +base = "0x1FF80000" +size = "0x400" +[[adsp.mem_zone]] +type = "IMR" +base = "0xA104A000" +size = "0x2000" +[[adsp.mem_zone]] +type = "SRAM" +base = "0xa00f0000" +size = "0x100000" + +[[adsp.mem_alias]] +type = "uncached" +base = "0x40000000" +[[adsp.mem_alias]] +type = "cached" +base = "0xA0000000" + +[cse] +partition_name = "ADSP" +[[cse.entry]] +name = "ADSP.man" +offset = "0x5c" +length = "0x464" +[[cse.entry]] +name = "ADSP.met" +offset = "0x4c0" +length = "0x70" +[[cse.entry]] +name = "ADSP" +offset = "0x540" +length = "0x0" # calculated by rimage + +[css] + +[signed_pkg] +name = "ADSP" +[[signed_pkg.module]] +name = "ADSP.met" + +[adsp_file] +[[adsp_file.comp]] +base_offset = "0x2000" + +[fw_desc.header] +name = "ADSPFW" +load_offset = "0x40000" + +[module] +count = 1 + + [[module.entry]] + name = "SMATEST" + uuid = "167A961E-8AE4-11EA-89F1-000C29CE1635" + affinity_mask = "0x1" + instance_count = "1" + domain_types = "0" + load_type = "0" + init_config = "1" + module_type = "0xD" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 0, 0, 0xfeef, 0xf, 0xa, 0x45ff, + 1, 0, 0xfeef, 0xf, 0xa, 0x45ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 4096, 1000000, 128, 128, 0, 0, 0] diff --git a/lmdk/modules/smart_amp_test/CMakeLists.txt b/lmdk/modules/smart_amp_test/CMakeLists.txt new file mode 100644 index 000000000000..37fcdb87108b --- /dev/null +++ b/lmdk/modules/smart_amp_test/CMakeLists.txt @@ -0,0 +1,13 @@ +target_sources(smart_amp_test PRIVATE ${SOF_BASE}/src/samples/audio/smart_amp_test_ipc4.c) + +set_target_properties(smart_amp_test PROPERTIES + HPSRAM_ADDR "0xa06c1000" +) + +target_compile_definitions(smart_amp_test PRIVATE + __SOF_MODULE_SERVICE_BUILD__=1 + CONFIG_XTENSA=1 + CONFIG_IPC_MAJOR_4=1 +) + +target_include_directories(smart_amp_test PRIVATE "${SOF_BASE}/src/include") diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index b95ecbd3e1f9..07a35a47e9aa 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -23,8 +23,9 @@ #ifndef __SOF_IPC4_BASE_CONFIG_H__ #define __SOF_IPC4_BASE_CONFIG_H__ - +#ifndef __SOF_MODULE_SERVICE_BUILD__ #include +#endif #include struct sof_ipc_stream_params; diff --git a/src/include/sof/samples/audio/smart_amp_test.h b/src/include/sof/samples/audio/smart_amp_test.h index 3feda5005125..c5ddd8032d99 100644 --- a/src/include/sof/samples/audio/smart_amp_test.h +++ b/src/include/sof/samples/audio/smart_amp_test.h @@ -8,8 +8,10 @@ #ifndef __SOF_AUDIO_SMART_AMP_H__ #define __SOF_AUDIO_SMART_AMP_H__ +#ifndef __SOF_MODULE_SERVICE_BUILD__ #include #include +#endif #if CONFIG_IPC_MAJOR_4 #include @@ -19,10 +21,20 @@ #define SMART_AMP_MAX_STREAM_CHAN 8 +/* Max channels for all intel platforms are 8 */ +#define MAX_CHANNELS 8 + /** IPC blob types */ #define SOF_SMART_AMP_CONFIG 0 #define SOF_SMART_AMP_MODEL 1 +#ifdef __SOF_MODULE_SERVICE_BUILD__ +#define LOG_ERR(...) +#define LOG_WRN(...) +#define LOG_DBG(...) +#define LOG_INF(...) +#endif + struct smart_amp_model_data { uint32_t data_size; void *data; @@ -83,8 +95,8 @@ struct smart_amp_model_data { struct sof_smart_amp_config { uint32_t size; uint32_t feedback_channels; - int8_t source_ch_map[PLATFORM_MAX_CHANNELS]; - int8_t feedback_ch_map[PLATFORM_MAX_CHANNELS]; + int8_t source_ch_map[MAX_CHANNELS]; + int8_t feedback_ch_map[MAX_CHANNELS]; }; #if CONFIG_IPC_MAJOR_4 diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 5395f1a6ef08..f6ffd6dae115 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -3,8 +3,9 @@ // Copyright(c) 2020 Intel Corporation. All rights reserved. // // Author: Bartosz Kokoszko + +#ifndef __SOF_MODULE_SERVICE_BUILD__ #include -#include #include #include #include @@ -18,6 +19,7 @@ #include LOG_MODULE_REGISTER(smart_amp_test, CONFIG_SOF_LOG_LEVEL); +#include /* 167a961e-8ae4-11ea-89f1-000c29ce1635 */ DECLARE_SOF_RT_UUID("smart_amp-test", smart_amp_test_comp_uuid, 0x167a961e, 0x8ae4, @@ -25,6 +27,22 @@ 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); +#else +#include +#include +#include + +#include +#include +#include +#include +#include +#include