From eed6747e8c61190a41f0636620db3cf7678a8c79 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 10 Sep 2025 16:45:18 +0200 Subject: [PATCH 1/8] cmocka: eq_iir: Add missing source files to CMakeLists.txt Include two required source files for sink/source api. Signed-off-by: Adrian Warecki --- test/cmocka/src/audio/eq_iir/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index a328590b7106..aa704a1af92b 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -35,6 +35,8 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c From d3e8b9e16c84696ee068dce8e4f2f1228c5c00f3 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Fri, 28 Mar 2025 14:42:43 +0100 Subject: [PATCH 2/8] ipc4: handler: Simplify error handling in ipc4_pipeline_prepare Move the check of the ret variable value after the switch to simplify the code. Signed-off-by: Adrian Warecki --- src/ipc/ipc4/handler.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index c50a1d996c5d..c1cffb497625 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -300,8 +300,6 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) tr_dbg(&ipc_tr, "pipeline %d: set params", ppl_icd->id); ret = ipc4_pcm_params(host); - if (ret < 0) - return IPC4_INVALID_REQUEST; break; default: ipc_cmd_err(&ipc_tr, @@ -315,9 +313,6 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) case COMP_STATE_INIT: tr_dbg(&ipc_tr, "pipeline %d: reset from init", ppl_icd->id); ret = ipc4_pipeline_complete(ipc, ppl_icd->id, cmd); - if (ret < 0) - ret = IPC4_INVALID_REQUEST; - break; case COMP_STATE_READY: case COMP_STATE_ACTIVE: @@ -337,9 +332,6 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) case COMP_STATE_INIT: tr_dbg(&ipc_tr, "pipeline %d: pause from init", ppl_icd->id); ret = ipc4_pipeline_complete(ipc, ppl_icd->id, cmd); - if (ret < 0) - ret = IPC4_INVALID_REQUEST; - break; default: /* No action needed */ @@ -360,6 +352,8 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) return IPC4_INVALID_REQUEST; } + if (ret < 0) + return IPC4_INVALID_REQUEST; return ret; } From 814e7bbd3b0266b52c54219bbc3065365af2bdba Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Fri, 28 Mar 2025 16:22:58 +0100 Subject: [PATCH 3/8] ipc4: handler: pipeline: Add support for eos state Add support for setting the pipeline in the EOS state. Setting this state sets the except_eos flag in the pipeline, indicating that the end of data to be processed is expected. Signed-off-by: Adrian Warecki --- src/include/sof/audio/pipeline.h | 1 + src/ipc/ipc4/handler.c | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index affe6569d547..5221d330e0f1 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -68,6 +68,7 @@ struct pipeline { int32_t xrun_bytes; /* last xrun length */ uint32_t status; /* pipeline status */ struct tr_ctx tctx; /* trace settings */ + bool expect_eos; /* pipeline is expecting end of stream */ /* scheduling */ struct task *pipe_task; /* pipeline processing task */ diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index c1cffb497625..b2ddb3c3f742 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -287,6 +287,12 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) switch (cmd) { case SOF_IPC4_PIPELINE_STATE_RUNNING: + if (ppl_icd->pipeline->expect_eos) { + ipc_cmd_err(&ipc_tr, "pipeline %d: Can't transition from EOS to RUNNING", + ppl_icd->id); + return IPC4_INVALID_REQUEST; + } + /* init params when pipeline is complete or reset */ switch (status) { case COMP_STATE_ACTIVE: @@ -339,11 +345,15 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) } break; - /* special case- TODO */ case SOF_IPC4_PIPELINE_STATE_EOS: - if (status != COMP_STATE_ACTIVE) + if (status != COMP_STATE_ACTIVE) { + ipc_cmd_err(&ipc_tr, "pipeline %d: Invalid state for EOS: %d", + ppl_icd->id, status); return IPC4_INVALID_REQUEST; - COMPILER_FALLTHROUGH; + } + ppl_icd->pipeline->expect_eos = true; + return 0; /* Must return here. Any other transition clears expect_eos. */ + /* special case - TODO */ case SOF_IPC4_PIPELINE_STATE_SAVED: case SOF_IPC4_PIPELINE_STATE_ERROR_STOP: default: @@ -354,6 +364,9 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) if (ret < 0) return IPC4_INVALID_REQUEST; + + ppl_icd->pipeline->expect_eos = false; + return ret; } @@ -417,6 +430,9 @@ int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *dela } break; + case SOF_IPC4_PIPELINE_STATE_EOS: + /* EOS handled in ipc4_pipeline_prepare */ + return 0; default: ipc_cmd_err(&ipc_tr, "pipeline %d: unsupported trigger cmd: %d", ppl_icd->id, cmd); From c6a26137d81a60a5f2df46794d057d9e7d915128 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Fri, 4 Apr 2025 14:38:21 +0200 Subject: [PATCH 4/8] audio: stream: Introduce audio stream state Add enum describing the state of a audio stream. Change the hw_params_configured field to state. A stream is initially in the STREAM_STATE_INITIAL state. After configuring the parameters, it transitions to the STREAM_STATE_READY state. Signed-off-by: Adrian Warecki --- src/include/module/audio/audio_stream.h | 16 +++++++++++++++- src/include/sof/audio/audio_buffer.h | 6 +++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/include/module/audio/audio_stream.h b/src/include/module/audio/audio_stream.h index f66fc414e865..e24e0c123d75 100644 --- a/src/include/module/audio/audio_stream.h +++ b/src/include/module/audio/audio_stream.h @@ -13,6 +13,20 @@ #include #include "../ipc/stream.h" + +/** + * @enum sof_audio_buffer_state + * @brief Define states of an audio stream buffer connecting two components. + * + * This enum represents the lifecycle of an audio stream, including its + * initialization, readiness, and end-of-stream handling. It is used to + * track and manage the state transitions of the stream during audio processing. + */ +enum sof_audio_buffer_state { + AUDIOBUF_STATE_INITIAL, /* Initial state, hw params not configured. */ + AUDIOBUF_STATE_READY, /* Stream ready, hw params configured */ +}; + /** * set of parameters describing audio stream * this structure is shared between audio_stream.h and sink/source interface @@ -53,7 +67,7 @@ struct sof_audio_stream_params { uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ - bool hw_params_configured; /**< indicates whether hw params were set */ + enum sof_audio_buffer_state state; /**< audio stream state */ }; #endif /* __MODULE_AUDIO_AUDIO_STREAM_H__ */ diff --git a/src/include/sof/audio/audio_buffer.h b/src/include/sof/audio/audio_buffer.h index a4b52248ce59..46f2a06054ab 100644 --- a/src/include/sof/audio/audio_buffer.h +++ b/src/include/sof/audio/audio_buffer.h @@ -214,17 +214,17 @@ static inline bool audio_buffer_is_shared(struct sof_audio_buffer *buffer) static inline bool audio_buffer_hw_params_configured(struct sof_audio_buffer *buffer) { - return buffer->audio_stream_params->hw_params_configured; + return buffer->audio_stream_params->state != AUDIOBUF_STATE_INITIAL; } static inline void audio_buffer_set_hw_params_configured(struct sof_audio_buffer *buffer) { - buffer->audio_stream_params->hw_params_configured = true; + buffer->audio_stream_params->state = AUDIOBUF_STATE_READY; } static inline void audio_buffer_reset_params(struct sof_audio_buffer *buffer) { - buffer->audio_stream_params->hw_params_configured = false; + buffer->audio_stream_params->state = AUDIOBUF_STATE_INITIAL; } static inline uint16_t audio_buffer_get_chmap(struct sof_audio_buffer *buffer, size_t index) From dd17e226a498d7ed8e361685becb4eed13a74ea8 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Mon, 7 Apr 2025 15:57:20 +0200 Subject: [PATCH 5/8] audio: stream: Add end of stream state Add new STREAM_STATE_END_OF_STREAM state indicating the end of a stream. Additional state STREAM_STATE_END_OF_STREAM_FLUSH indicates that end of stream has been detected, but silence is transmitted for the needs of DP modules. Signed-off-by: Adrian Warecki --- src/include/module/audio/audio_stream.h | 4 ++++ src/include/module/audio/source_api.h | 5 +++++ src/include/sof/audio/audio_buffer.h | 17 +++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/include/module/audio/audio_stream.h b/src/include/module/audio/audio_stream.h index e24e0c123d75..e032ef322f85 100644 --- a/src/include/module/audio/audio_stream.h +++ b/src/include/module/audio/audio_stream.h @@ -25,6 +25,10 @@ enum sof_audio_buffer_state { AUDIOBUF_STATE_INITIAL, /* Initial state, hw params not configured. */ AUDIOBUF_STATE_READY, /* Stream ready, hw params configured */ + AUDIOBUF_STATE_END_OF_STREAM, /* Detected End Of Stream */ + AUDIOBUF_STATE_END_OF_STREAM_FLUSH, /* Detected End Of Stream, generating silence + * to flush buffers in dp modules. + */ }; /** diff --git a/src/include/module/audio/source_api.h b/src/include/module/audio/source_api.h index 336535e1be26..556dead4a583 100644 --- a/src/include/module/audio/source_api.h +++ b/src/include/module/audio/source_api.h @@ -323,4 +323,9 @@ static inline struct processing_module *source_get_bound_module(struct sof_sourc return source->bound_module; } +static inline enum sof_audio_buffer_state source_get_state(const struct sof_source *source) +{ + return source->audio_stream_params->state; +} + #endif /* __MODULE_AUDIO_SOURCE_API_H__ */ diff --git a/src/include/sof/audio/audio_buffer.h b/src/include/sof/audio/audio_buffer.h index 46f2a06054ab..5156971d515f 100644 --- a/src/include/sof/audio/audio_buffer.h +++ b/src/include/sof/audio/audio_buffer.h @@ -227,6 +227,23 @@ static inline void audio_buffer_reset_params(struct sof_audio_buffer *buffer) buffer->audio_stream_params->state = AUDIOBUF_STATE_INITIAL; } +static inline enum sof_audio_buffer_state audio_buffer_get_state( + const struct sof_audio_buffer *buffer) +{ + return buffer->audio_stream_params->state; +} + +static inline void audio_buffer_set_state(struct sof_audio_buffer *buffer, + enum sof_audio_buffer_state state) +{ + buffer->audio_stream_params->state = state; +} + +static inline void audio_buffer_set_eos(struct sof_audio_buffer *buffer) +{ + buffer->audio_stream_params->state = AUDIOBUF_STATE_END_OF_STREAM; +} + static inline uint16_t audio_buffer_get_chmap(struct sof_audio_buffer *buffer, size_t index) { return buffer->audio_stream_params->chmap[index]; From 9ef087a5c5d62e2577008d695094e35b6d4500d7 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 16 Apr 2025 13:10:04 +0200 Subject: [PATCH 6/8] host: Add eos detection Add end of stream support to the host. When the pipeline is in the eos state and host runs out of available data, set the sink to the eos state. Signed-off-by: Adrian Warecki --- src/audio/host-zephyr.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index b7f203eea3a0..5aec7ff1a4d4 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -393,6 +393,32 @@ static int host_get_status(struct comp_dev *dev, struct host_data *hd, struct dm /* Minimum time between 2 consecutive "no bytes to copy" messages in milliseconds */ #define SOF_MIN_NO_BYTES_INTERVAL_MS 20 +static inline bool host_handle_eos(struct host_data *hd, struct comp_dev *dev, + uint32_t avail_samples) +{ + struct sof_audio_buffer *buffer = &hd->local_buffer->audio_buffer; + enum sof_audio_buffer_state state = audio_buffer_get_state(buffer); + + if (!dev->pipeline->expect_eos) + return false; + + if (!avail_samples) { + /* EOS is detected, so we need to set the sink + * state to AUDIOBUF_STATE_END_OF_STREAM. + */ + if (state != AUDIOBUF_STATE_END_OF_STREAM) { + audio_buffer_set_eos(buffer); + comp_info(dev, "host_handle_eos() - EOS detected"); + } + return true; + } + + if (state == AUDIOBUF_STATE_END_OF_STREAM) + comp_warn(dev, "Data available after reporting end of stream!"); + + return false; +} + /** * Calculates bytes to be copied in normal mode. * @param dev Host component device. @@ -440,6 +466,9 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { avail_samples = (dma_stat.pending_length - hd->partial_size) / dma_sample_bytes; free_samples = audio_stream_get_free_samples(&buffer->stream); + + if (host_handle_eos(hd, dev, avail_samples)) + return 0; } else { avail_samples = audio_stream_get_avail_samples(&buffer->stream); free_samples = (dma_stat.free - hd->partial_size) / dma_sample_bytes; From 91b6dd8cc26fe5d7a2ae1ed4684e7c7896078522 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 23 Apr 2025 17:33:41 +0200 Subject: [PATCH 7/8] component: Add eos support in components copy function Add eos support in the function that calls the module's data processing function. If the end of the stream in the source buffer is detected, pass it to the output buffer. For DP modules, generate silence on the input after end of the stream to allow them to process the remaining data. Signed-off-by: Adrian Warecki --- src/audio/component.c | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/audio/component.c b/src/audio/component.c index 8b5cc022e98f..0964b0b62ebb 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -5,6 +5,7 @@ // Author: Liam Girdwood #include +#include #include #include #include @@ -496,6 +497,62 @@ void audio_stream_copy_to_linear(const struct audio_stream *source, int ioffset, } } +static bool comp_check_eos(struct comp_dev *dev) +{ + enum sof_audio_buffer_state sink_state = AUDIOBUF_STATE_INITIAL; + struct comp_buffer *buffer; + + if (!dev->pipeline->expect_eos) + return false; + + comp_dev_for_each_producer(dev, buffer) { + struct sof_source *source = audio_buffer_get_source(&buffer->audio_buffer); + enum sof_audio_buffer_state state = source_get_state(source); + + if (source_get_pipeline_id(source) != dev->pipeline->pipeline_id) + continue; + + if (state == AUDIOBUF_STATE_END_OF_STREAM_FLUSH) { + /* Earlier in the pipeline, there is a DP module that has reached + * the EOS state. However, silence is generated to flush its internal + * buffers, so pass this state to the output buffers. + */ + comp_dbg(dev, "comp_check_eos() - EOS flush detected"); + sink_state = AUDIOBUF_STATE_END_OF_STREAM_FLUSH; + break; + } else if (state == AUDIOBUF_STATE_END_OF_STREAM) { + /* EOS is detected, so we need to set the sink state to AUDIOBUF_STATE_EOS. */ + size_t min_avail = source_get_min_available(source); + + if (source_get_data_available(source) < min_avail) { + comp_dbg(dev, "comp_check_eos() - EOS detected"); + if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) { + /* For DP modules, fill missing input data with silence to + * allow it to process the remaining data. + */ + struct sof_sink *previous_mod_data_sink = + audio_buffer_get_sink(&buffer->audio_buffer); + sink_fill_with_silence(previous_mod_data_sink, min_avail); + sink_state = AUDIOBUF_STATE_END_OF_STREAM_FLUSH; + } else { + sink_state = AUDIOBUF_STATE_END_OF_STREAM; + break; + } + } + } + } + + if (sink_state != AUDIOBUF_STATE_INITIAL) { + comp_dev_for_each_consumer(dev, buffer) + audio_buffer_set_state(&buffer->audio_buffer, sink_state); + + /* For AUDIOBUF_STATE_END_OF_STREAM_FLUSH process data normally. */ + return sink_state != AUDIOBUF_STATE_END_OF_STREAM_FLUSH; + } + + return false; +} + /** See comp_ops::copy */ int comp_copy(struct comp_dev *dev) { @@ -530,6 +587,9 @@ int comp_copy(struct comp_dev *dev) const uint32_t begin_stamp = (uint32_t)telemetry_timestamp(); #endif + if (comp_check_eos(dev)) + return 0; + ret = dev->drv->ops.copy(dev); #ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS From 358cfaf5258dc32203972eb758b79cbb90755434 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 2 Apr 2025 15:58:22 +0200 Subject: [PATCH 8/8] mixin: Add eos notification Add sending notification when end of stream is detected. Signed-off-by: Adrian Warecki --- src/audio/mixin_mixout/mixin_mixout.c | 49 +++++++++++++++++++-------- src/audio/pipeline/pipeline-graph.c | 3 ++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 5043d02920f0..6eaba83aca3b 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -79,6 +79,8 @@ struct mixin_data { #if CONFIG_XRUN_NOTIFICATIONS_ENABLE uint32_t last_reported_underrun; uint32_t underrun_notification_period; + uint32_t eos_delay_periods; + bool eos_delay_configured; #endif }; @@ -248,23 +250,40 @@ static void silence(struct cir_buf_ptr *stream, uint32_t start_offset, #if CONFIG_XRUN_NOTIFICATIONS_ENABLE static void mixin_check_notify_underrun(struct comp_dev *dev, struct mixin_data *mixin_data, + enum sof_audio_buffer_state state, size_t source_avail, size_t sinks_free) { + const bool eos_detected = state == AUDIOBUF_STATE_END_OF_STREAM_FLUSH || + state == AUDIOBUF_STATE_END_OF_STREAM; + struct ipc_msg *notify; mixin_data->last_reported_underrun++; - if (!source_avail && mixin_data->last_reported_underrun >= - mixin_data->underrun_notification_period) { - mixin_data->last_reported_underrun = 0; + if (!source_avail || eos_detected) { + if (eos_detected) { + if (mixin_data->eos_delay_configured) { + mixin_data->eos_delay_periods--; + } else { + pipeline_get_dai_comp_latency(dev->pipeline->pipeline_id, + &mixin_data->eos_delay_periods); + mixin_data->eos_delay_configured = true; + } + } + + if ((!eos_detected && mixin_data->last_reported_underrun >= + mixin_data->underrun_notification_period) || + (eos_detected && mixin_data->eos_delay_periods == 0)) { + mixin_data->last_reported_underrun = 0; - notify = ipc_notification_pool_get(IPC4_RESOURCE_EVENT_SIZE); - if (!notify) - return; + notify = ipc_notification_pool_get(IPC4_RESOURCE_EVENT_SIZE); + if (!notify) + return; - mixer_underrun_notif_msg_init(notify, dev->ipc_config.id, false, - source_avail, sinks_free); - ipc_msg_send(notify, notify->tx_data, false); + mixer_underrun_notif_msg_init(notify, dev->ipc_config.id, eos_detected, + source_avail, sinks_free); + ipc_msg_send(notify, notify->tx_data, false); + } } } #endif @@ -294,9 +313,10 @@ static int mixin_process(struct processing_module *mod, uint32_t source_avail_frames, sinks_free_frames; struct processing_module *active_mixouts[MIXIN_MAX_SINKS]; uint16_t sinks_ids[MIXIN_MAX_SINKS]; + struct pending_frames *pending_frames; uint32_t bytes_to_consume = 0; uint32_t frames_to_copy; - struct pending_frames *pending_frames; + size_t frame_bytes; int i, ret; struct cir_buf_ptr source_ptr; @@ -389,10 +409,10 @@ static int mixin_process(struct processing_module *mod, return 0; #if CONFIG_XRUN_NOTIFICATIONS_ENABLE - size_t frame_bytes = source_get_frame_bytes(sources[0]); - size_t min_frames = MIN(dev->frames, sinks_free_frames); + frame_bytes = source_get_frame_bytes(sources[0]); + const size_t min_frames = MIN(dev->frames, sinks_free_frames); - mixin_check_notify_underrun(dev, mixin_data, + mixin_check_notify_underrun(dev, mixin_data, source_get_state(sources[0]), source_avail_frames * frame_bytes, min_frames * frame_bytes); #endif @@ -461,7 +481,7 @@ static int mixin_process(struct processing_module *mod, * silence instead of that source data */ if (source_avail_frames == 0) { - uint32_t frame_bytes = sink_get_frame_bytes(mixout_mod->sinks[0]); + frame_bytes = sink_get_frame_bytes(mixout_mod->sinks[0]); /* generate silence */ silence(&mixout_data->acquired_buf, start_frame * frame_bytes, @@ -698,6 +718,7 @@ static int mixin_prepare(struct processing_module *mod, int ret; comp_info(dev, "mixin_prepare()"); + md->eos_delay_configured = false; ret = mixin_params(mod); if (ret < 0) diff --git a/src/audio/pipeline/pipeline-graph.c b/src/audio/pipeline/pipeline-graph.c index 4dc4466865f3..678b8095289f 100644 --- a/src/audio/pipeline/pipeline-graph.c +++ b/src/audio/pipeline/pipeline-graph.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -551,4 +552,6 @@ struct comp_dev *pipeline_get_dai_comp_latency(uint32_t pipeline_id, uint32_t *l return NULL; } +EXPORT_SYMBOL(pipeline_get_dai_comp_latency); + #endif