From b347bd6f209aff10fefefabd2132455e9e010ab8 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Wed, 6 Sep 2023 15:37:00 +0300 Subject: [PATCH] [TEST]Audio: Multiband-DRC: For test update switch control from FW side Testing 1 2 3 ... This just toggles the switch control state to user space. Leave alsamixer running and watch the control blink :) Signed-off-by: Seppo Ingalsuo --- src/audio/multiband_drc/multiband_drc.c | 78 +++++++++++++++++++ src/include/ipc4/header.h | 17 ++++ .../sof/audio/multiband_drc/multiband_drc.h | 15 ++++ 3 files changed, 110 insertions(+) diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index 49e8929da5cc..b618f6164d75 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -34,6 +34,12 @@ #include #include +#if CONFIG_IPC_MAJOR_4 +#include +#endif + +#define TEST_NOTIFICATIONS 1 + LOG_MODULE_REGISTER(multiband_drc, CONFIG_SOF_LOG_LEVEL); /* 0d9f2256-8e4f-47b3-8448-239a334f1191 */ @@ -223,6 +229,43 @@ static int multiband_drc_setup(struct processing_module *mod, int16_t channels, * End of Multiband DRC setup code. Next the standard component methods. */ +#if CONFIG_IPC_MAJOR_4 +static struct ipc_msg *multiband_drc_notification_init(struct comp_ipc_config *ipc_config) +{ + struct ipc_msg msg_proto; + union ipc4_notification_header *primary = + (union ipc4_notification_header *)&msg_proto.header; + struct ipc_msg *msg; + struct multiband_drc_notification_payload *payload; + + memset_s(&msg_proto, sizeof(msg_proto), 0, sizeof(msg_proto)); + + primary->r.notif_type = SOF_IPC4_MODULE_NOTIFICATION; + primary->r.type = SOF_IPC4_GLB_NOTIFICATION; + primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST; + primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG; + + msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension, + sizeof(struct multiband_drc_notification_payload)); + if (!msg) + return NULL; + + payload = (struct multiband_drc_notification_payload *)msg->tx_data; + payload->module_data.instance_id = IPC4_INST_ID(ipc_config->id); + payload->module_data.module_id = IPC4_MOD_ID(ipc_config->id); + payload->module_data.event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL | + SOF_IPC4_SWITCH_CONTROL_PARAM_ID; + payload->module_data.event_data_size = sizeof(struct sof_ipc4_control_msg_payload) + + sizeof(struct sof_ipc4_ctrl_value_chan); + + payload->control_msg.id = 0; + payload->control_msg.num_elems = 1; + payload->control_value.channel = 0; + + return msg; +} +#endif + static int multiband_drc_init(struct processing_module *mod) { struct module_data *md = &mod->priv; @@ -277,6 +320,13 @@ static int multiband_drc_init(struct processing_module *mod) } multiband_drc_reset_state(&cd->state); +#if CONFIG_IPC_MAJOR_4 + cd->msg = multiband_drc_notification_init(&dev->ipc_config); + if (!cd->msg) { + comp_err(dev, "failed to initialize notification."); + goto cd_fail; + } +#endif return 0; cd_fail: @@ -291,6 +341,8 @@ static int multiband_drc_free(struct processing_module *mod) comp_info(mod->dev, "multiband_drc_free()"); + ipc_msg_free(cd->msg); + comp_data_blob_handler_free(cd->model_handler); rfree(cd); @@ -419,6 +471,18 @@ static void multiband_drc_set_alignment(struct audio_stream __sparse_cache *sour audio_stream_init_alignment_constants(1, 1, sink); } +static void multiband_drc_send_module_notify(struct multiband_drc_comp_data *cd, uint32_t val) +{ +#if CONFIG_IPC_MAJOR_4 + struct ipc_msg *msg = cd->msg; + struct multiband_drc_notification_payload *ipc_payload; + + ipc_payload = (struct multiband_drc_notification_payload *)msg->tx_data; + ipc_payload->control_value.value = val; + ipc_msg_send(msg, NULL, false); +#endif +} + static int multiband_drc_process(struct processing_module *mod, struct input_stream_buffer *input_buffers, int num_input_buffers, struct output_stream_buffer *output_buffers, @@ -433,6 +497,20 @@ static int multiband_drc_process(struct processing_module *mod, comp_dbg(dev, "multiband_drc_process()"); +#if TEST_NOTIFICATIONS + cd->ctrl_update_count++; + if (cd->ctrl_update_count == 1000) { + multiband_drc_send_module_notify(cd, 1); + comp_info(dev, "notify 1"); + } + + if (cd->ctrl_update_count >= 2000) { + multiband_drc_send_module_notify(cd, 0); + cd->ctrl_update_count = 0; + comp_info(dev, "notify 0"); + } +#endif + /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); diff --git a/src/include/ipc4/header.h b/src/include/ipc4/header.h index 5aaa361283bc..5abef50342b0 100644 --- a/src/include/ipc4/header.h +++ b/src/include/ipc4/header.h @@ -173,6 +173,7 @@ struct ipc4_message_reply { #define SOF_IPC4_SWITCH_CONTROL_PARAM_ID 200 #define SOF_IPC4_ENUM_CONTROL_PARAM_ID 201 +#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL ((uint32_t)(0xA15A << 16)) /** * struct sof_ipc4_ctrl_value_chan: generic channel mapped value data @@ -198,4 +199,20 @@ struct sof_ipc4_control_msg_payload { struct sof_ipc4_ctrl_value_chan chanv[]; } __attribute((packed, aligned(4))); +/** + * struct sof_ipc4_notify_module_data - payload for module notification + * @instance_id: instance ID of the originator module of the notification + * @module_id: module ID of the originator of the notification + * @event_id: module specific event id + * @event_data_size: Size of the @event_data (if any) in bytes + * @event_data: Optional notification data, module and notification dependent + */ +struct sof_ipc4_notify_module_data { + uint16_t instance_id; + uint16_t module_id; + uint32_t event_id; + uint32_t event_data_size; + uint8_t event_data[]; +} __attribute((packed, aligned(4))); + #endif diff --git a/src/include/sof/audio/multiband_drc/multiband_drc.h b/src/include/sof/audio/multiband_drc/multiband_drc.h index a5058bd158dc..75f37a4ef2c4 100644 --- a/src/include/sof/audio/multiband_drc/multiband_drc.h +++ b/src/include/sof/audio/multiband_drc/multiband_drc.h @@ -13,10 +13,15 @@ #include #include #include +#include #include #include #include +#if CONFIG_IPC_MAJOR_4 +#include +#endif + /** * Stores the state of the sub-components in Multiband DRC */ @@ -37,13 +42,23 @@ struct multiband_drc_comp_data { struct multiband_drc_state state; /**< compressor state */ struct comp_data_blob_handler *model_handler; struct sof_multiband_drc_config *config; /**< pointer to setup blob */ + struct ipc_msg *msg; /**< host notification */ bool config_ready; /**< set when fully received */ enum sof_ipc_frame source_format; /**< source frame format */ bool process_enabled; /**< true if component is enabled */ multiband_drc_func multiband_drc_func; /**< processing function */ crossover_split crossover_split; /**< crossover n-way split func */ + uint32_t ctrl_update_count; }; +#if CONFIG_IPC_MAJOR_4 +struct multiband_drc_notification_payload { + struct sof_ipc4_notify_module_data module_data; + struct sof_ipc4_control_msg_payload control_msg; + struct sof_ipc4_ctrl_value_chan control_value; +}; +#endif + struct multiband_drc_proc_fnmap { enum sof_ipc_frame frame_fmt; multiband_drc_func multiband_drc_proc_func;