diff --git a/lmdk/cmake/build.cmake b/lmdk/cmake/build.cmake index 15369cb41dbe..8412bf313c05 100644 --- a/lmdk/cmake/build.cmake +++ b/lmdk/cmake/build.cmake @@ -9,6 +9,11 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/config.cmake) +# Build common module functions from sof to a static library +add_library(sof STATIC) +target_include_directories(sof PRIVATE "${SOF_BASE}/src/include") +add_subdirectory("${SOF_BASE}/src/module" module_api) + foreach(MODULE ${MODULES_LIST}) add_executable(${MODULE}) add_subdirectory(${LMDK_BASE}/modules/${MODULE} ${MODULE}_module) @@ -19,6 +24,7 @@ foreach(MODULE ${MODULES_LIST}) target_include_directories(${MODULE} PRIVATE "${LMDK_BASE}/include" "${RIMAGE_INCLUDE_DIR}" + "${SOF_BASE}/src/include/module" ) # generate linker script @@ -35,6 +41,9 @@ foreach(MODULE ${MODULES_LIST}) -P ${CMAKE_CURRENT_LIST_DIR}/ldscripts.cmake ) + # Link module with sof common module functions + target_link_libraries(${MODULE} sof) + target_link_options(${MODULE} PRIVATE "-nostartfiles" "-Wl,--no-undefined" "-Wl,--unresolved-symbols=report-all" "-Wl,--error-unresolved-symbols" diff --git a/lmdk/cmake/config.cmake b/lmdk/cmake/config.cmake index 6edc79541a89..6faa6d353215 100644 --- a/lmdk/cmake/config.cmake +++ b/lmdk/cmake/config.cmake @@ -16,3 +16,22 @@ cmake_path(ABSOLUTE_PATH SOF_BASE NORMALIZE) set(RIMAGE_INCLUDE_DIR ${SOF_BASE}/tools/rimage/src/include) cmake_path(ABSOLUTE_PATH RIMAGE_INCLUDE_DIR NORMALIZE) + +# Adds sources to target like target_sources, but assumes that +# paths are relative to subdirectory. +# Works like: +# Cmake >= 3.13: +# target_sources( PRIVATE ) +# Cmake < 3.13: +# target_sources( PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/) +function(add_local_sources target) + foreach(arg ${ARGN}) + if(IS_ABSOLUTE ${arg}) + set(path ${arg}) + else() + set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) + endif() + + target_sources(${target} PRIVATE ${path}) + endforeach() +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4caeabf27c54..29d1ad54a8bb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,8 @@ add_subdirectory(ipc) add_subdirectory(audio) add_subdirectory(lib) add_subdirectory(math) +add_subdirectory(module) + if(CONFIG_SAMPLES) add_subdirectory(samples) endif() diff --git a/src/audio/module_adapter/iadk/system_agent.cpp b/src/audio/module_adapter/iadk/system_agent.cpp index f42d0e15819e..77c0e120db9f 100644 --- a/src/audio/module_adapter/iadk/system_agent.cpp +++ b/src/audio/module_adapter/iadk/system_agent.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 3a2fd29abd04..90634c2253ad 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* Intel module adapter is an extension to SOF module adapter component that allows to integrate * modules developed under IADK (Intel Audio Development Kit) Framework. IADK modules uses uniform diff --git a/src/audio/sink_api_helper.c b/src/audio/sink_api_helper.c index 9961ee61dcb8..5d25474ac6b8 100644 --- a/src/audio/sink_api_helper.c +++ b/src/audio/sink_api_helper.c @@ -1,12 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2023 Intel Corporation. All rights reserved. -// +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ #include -#include #include +/* This file contains private sink API functions intended for use only by the sof. */ + void sink_init(struct sof_sink *sink, const struct sink_ops *ops, struct sof_audio_stream_params *audio_stream_params) { @@ -14,48 +15,6 @@ void sink_init(struct sof_sink *sink, const struct sink_ops *ops, sink->audio_stream_params = audio_stream_params; } -size_t sink_get_free_size(struct sof_sink *sink) -{ - return sink->ops->get_free_size(sink); -} - -int sink_get_buffer(struct sof_sink *sink, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size) -{ - int ret; - - if (sink->requested_write_frag_size) - return -EBUSY; - - ret = sink->ops->get_buffer(sink, req_size, data_ptr, - buffer_start, buffer_size); - - if (!ret) - sink->requested_write_frag_size = req_size; - return ret; -} - -int sink_commit_buffer(struct sof_sink *sink, size_t commit_size) -{ - int ret; - - /* check if there was a buffer obtained for writing by sink_get_buffer */ - if (!sink->requested_write_frag_size) - return -ENODATA; - - /* limit size of data to be committed to previously obtained size */ - if (commit_size > sink->requested_write_frag_size) - commit_size = sink->requested_write_frag_size; - - ret = sink->ops->commit_buffer(sink, commit_size); - - if (!ret) - sink->requested_write_frag_size = 0; - - sink->num_of_bytes_processed += commit_size; - return ret; -} - size_t sink_get_num_of_processed_bytes(struct sof_sink *sink) { return sink->num_of_bytes_processed; @@ -66,128 +25,12 @@ void sink_reset_num_of_processed_bytes(struct sof_sink *sink) sink->num_of_bytes_processed = 0; } -enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink *sink) -{ - return sink->audio_stream_params->frame_fmt; -} - -enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink *sink) -{ - return sink->audio_stream_params->valid_sample_fmt; -} - -uint32_t sink_get_rate(struct sof_sink *sink) -{ - return sink->audio_stream_params->rate; -} - -uint32_t sink_get_channels(struct sof_sink *sink) -{ - return sink->audio_stream_params->channels; -} - -uint32_t sink_get_buffer_fmt(struct sof_sink *sink) -{ - return sink->audio_stream_params->buffer_fmt; -} - bool sink_get_overrun(struct sof_sink *sink) { return sink->audio_stream_params->overrun_permitted; } -int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt) -{ - sink->audio_stream_params->frame_fmt = frame_fmt; - - /* notify the implementation */ - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -int sink_set_valid_fmt(struct sof_sink *sink, - enum sof_ipc_frame valid_sample_fmt) -{ - sink->audio_stream_params->valid_sample_fmt = valid_sample_fmt; - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -int sink_set_rate(struct sof_sink *sink, unsigned int rate) -{ - sink->audio_stream_params->rate = rate; - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -int sink_set_channels(struct sof_sink *sink, unsigned int channels) -{ - sink->audio_stream_params->channels = channels; - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt) -{ - sink->audio_stream_params->buffer_fmt = buffer_fmt; - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted) -{ - sink->audio_stream_params->overrun_permitted = overrun_permitted; - if (sink->ops->on_audio_format_set) - return sink->ops->on_audio_format_set(sink); - return 0; -} - -size_t sink_get_frame_bytes(struct sof_sink *sink) -{ - return get_frame_bytes(sink_get_frm_fmt(sink), - sink_get_channels(sink)); -} - -size_t sink_get_free_frames(struct sof_sink *sink) -{ - return sink_get_free_size(sink) / - sink_get_frame_bytes(sink); -} - -int sink_set_params(struct sof_sink *sink, - struct sof_ipc_stream_params *params, bool force_update) -{ - if (sink->ops->audio_set_ipc_params) - return sink->ops->audio_set_ipc_params(sink, params, force_update); - return 0; -} - -int sink_set_alignment_constants(struct sof_sink *sink, - const uint32_t byte_align, - const uint32_t frame_align_req) -{ - if (sink->ops->set_alignment_constants) - return sink->ops->set_alignment_constants(sink, byte_align, frame_align_req); - return 0; -} - void sink_set_min_free_space(struct sof_sink *sink, size_t min_free_space) { sink->min_free_space = min_free_space; } - -size_t sink_get_min_free_space(struct sof_sink *sink) -{ - return sink->min_free_space; -} - -uint32_t sink_get_id(struct sof_sink *sink) -{ - return sink->audio_stream_params->id; -} - diff --git a/src/audio/source_api_helper.c b/src/audio/source_api_helper.c index f1aec4924f9b..c7ca28c71720 100644 --- a/src/audio/source_api_helper.c +++ b/src/audio/source_api_helper.c @@ -1,12 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause -// -// Copyright(c) 2023 Intel Corporation. All rights reserved. -// +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ #include -#include #include +/* This file contains private source API functions intended for use only by the sof. */ + void source_init(struct sof_source *source, const struct source_ops *ops, struct sof_audio_stream_params *audio_stream_params) { @@ -15,47 +16,6 @@ void source_init(struct sof_source *source, const struct source_ops *ops, source->audio_stream_params = audio_stream_params; } -size_t source_get_data_available(struct sof_source *source) -{ - return source->ops->get_data_available(source); -} - -int source_get_data(struct sof_source *source, size_t req_size, - void const **data_ptr, void const **buffer_start, size_t *buffer_size) -{ - int ret; - - if (source->requested_read_frag_size) - return -EBUSY; - - ret = source->ops->get_data(source, req_size, data_ptr, buffer_start, buffer_size); - - if (!ret) - source->requested_read_frag_size = req_size; - return ret; -} - -int source_release_data(struct sof_source *source, size_t free_size) -{ - int ret; - - /* Check if anything was obtained before for reading by source_get_data */ - if (!source->requested_read_frag_size) - return -ENODATA; - - /* limit size of data to be freed to previously obtained size */ - if (free_size > source->requested_read_frag_size) - free_size = source->requested_read_frag_size; - - ret = source->ops->release_data(source, free_size); - - if (!ret) - source->requested_read_frag_size = 0; - - source->num_of_bytes_processed += free_size; - return ret; -} - size_t source_get_num_of_processed_bytes(struct sof_source *source) { return source->num_of_bytes_processed; @@ -66,31 +26,6 @@ void source_reset_num_of_processed_bytes(struct sof_source *source) source->num_of_bytes_processed = 0; } -enum sof_ipc_frame source_get_frm_fmt(struct sof_source *source) -{ - return source->audio_stream_params->frame_fmt; -} - -enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source) -{ - return source->audio_stream_params->valid_sample_fmt; -} - -unsigned int source_get_rate(struct sof_source *source) -{ - return source->audio_stream_params->rate; -} - -unsigned int source_get_channels(struct sof_source *source) -{ - return source->audio_stream_params->channels; -} - -uint32_t source_get_buffer_fmt(struct sof_source *source) -{ - return source->audio_stream_params->buffer_fmt; -} - bool source_get_underrun(struct sof_source *source) { return source->audio_stream_params->underrun_permitted; @@ -145,18 +80,6 @@ int source_set_underrun(struct sof_source *source, bool underrun_permitted) return 0; } -size_t source_get_frame_bytes(struct sof_source *source) -{ - return get_frame_bytes(source_get_frm_fmt(source), - source_get_channels(source)); -} - -size_t source_get_data_frames_available(struct sof_source *source) -{ - return source_get_data_available(source) / - source_get_frame_bytes(source); -} - int source_set_params(struct sof_source *source, struct sof_ipc_stream_params *params, bool force_update) { @@ -178,13 +101,3 @@ void source_set_min_available(struct sof_source *source, size_t min_available) { source->min_available = min_available; } - -size_t source_get_min_available(struct sof_source *source) -{ - return source->min_available; -} - -uint32_t source_get_id(struct sof_source *source) -{ - return source->audio_stream_params->id; -} diff --git a/src/include/ipc/stream.h b/src/include/ipc/stream.h index 1c9bd7a824ac..c397f34a1d27 100644 --- a/src/include/ipc/stream.h +++ b/src/include/ipc/stream.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2018 Intel Corporation. All rights reserved. + * Copyright(c) 2018 - 2023 Intel Corporation. All rights reserved. * * Author: Liam Girdwood * Keyon Jie @@ -16,6 +16,7 @@ #ifndef __IPC_STREAM_H__ #define __IPC_STREAM_H__ +#include #include #include @@ -48,18 +49,6 @@ /* generic PCM flags for runtime settings */ #define SOF_PCM_FLAG_XRUN_STOP (1 << 0) /**< Stop on any XRUN */ -/* stream PCM frame format */ -enum sof_ipc_frame { - SOF_IPC_FRAME_S16_LE = 0, - SOF_IPC_FRAME_S24_4LE, - SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_FLOAT, - /* other formats here */ - SOF_IPC_FRAME_S24_3LE, - SOF_IPC_FRAME_S24_4LE_MSB, - SOF_IPC_FRAME_U8, -}; - /* stream buffer format */ enum sof_ipc_buffer_format { SOF_IPC_BUFFER_INTERLEAVED, diff --git a/src/include/ipc4/base-config.h b/src/include/ipc4/base-config.h index d28728c3e63f..b95ecbd3e1f9 100644 --- a/src/include/ipc4/base-config.h +++ b/src/include/ipc4/base-config.h @@ -1,6 +1,6 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2021 Intel Corporation. All rights reserved. +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2021 - 2023 Intel Corporation. All rights reserved. */ /* @@ -24,219 +24,8 @@ #ifndef __SOF_IPC4_BASE_CONFIG_H__ #define __SOF_IPC4_BASE_CONFIG_H__ -#include #include - -enum ipc4_sampling_frequency { - IPC4_FS_8000HZ = 8000, - IPC4_FS_11025HZ = 11025, - IPC4_FS_12000HZ = 12000, /**< Mp3, AAC, SRC only */ - IPC4_FS_16000HZ = 16000, - IPC4_FS_18900HZ = 18900, /**< SRC only for 44100 */ - IPC4_FS_22050HZ = 22050, - IPC4_FS_24000HZ = 24000, /**< Mp3, AAC, SRC only */ - IPC4_FS_32000HZ = 32000, - IPC4_FS_37800HZ = 37800, /**< SRC only for 44100 */ - IPC4_FS_44100HZ = 44100, - IPC4_FS_48000HZ = 48000, /**< Default */ - IPC4_FS_64000HZ = 64000, /**< AAC, SRC only */ - IPC4_FS_88200HZ = 88200, /**< AAC, SRC only */ - IPC4_FS_96000HZ = 96000, /**< AAC, SRC only */ - IPC4_FS_176400HZ = 176400, /**< SRC only */ - IPC4_FS_192000HZ = 192000, /**< SRC only */ - IPC4_FS_INVALID -}; - -enum ipc4_bit_depth { - IPC4_DEPTH_8BIT = 8, /**< 8 bits depth */ - IPC4_DEPTH_16BIT = 16, /**< 16 bits depth */ - IPC4_DEPTH_24BIT = 24, /**< 24 bits depth - Default */ - IPC4_DEPTH_32BIT = 32, /**< 32 bits depth */ - IPC4_DEPTH_64BIT = 64, /**< 64 bits depth */ - IPC4_DEPTH_INVALID -}; - -enum ipc4_channel_config { - IPC4_CHANNEL_CONFIG_MONO = 0, /**< one channel only */ - IPC4_CHANNEL_CONFIG_STEREO = 1, /**< L & R */ - IPC4_CHANNEL_CONFIG_2_POINT_1 = 2, /**< L, R & LFE; PCM only */ - IPC4_CHANNEL_CONFIG_3_POINT_0 = 3, /**< L, C & R; MP3 & AAC only */ - IPC4_CHANNEL_CONFIG_3_POINT_1 = 4, /**< L, C, R & LFE; PCM only */ - IPC4_CHANNEL_CONFIG_QUATRO = 5, /**< L, R, Ls & Rs; PCM only */ - IPC4_CHANNEL_CONFIG_4_POINT_0 = 6, /**< L, C, R & Cs; MP3 & AAC only */ - IPC4_CHANNEL_CONFIG_5_POINT_0 = 7, /**< L, C, R, Ls & Rs */ - IPC4_CHANNEL_CONFIG_5_POINT_1 = 8, /**< L, C, R, Ls, Rs & LFE */ - IPC4_CHANNEL_CONFIG_DUAL_MONO = 9, /**< one channel replicated in two */ - /**< Stereo (L,R) in 4 slots, 1st stream: [ L, R, -, - ] */ - IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_0 = 10, - /**< Stereo (L,R) in 4 slots, 2nd stream: [ -, -, L, R ] */ - IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_1 = 11, - IPC4_CHANNEL_CONFIG_7_POINT_1 = 12, /**< L, C, R, Ls, Rs & LFE., LS, RS */ - IPC4_CHANNEL_CONFIG_INVALID -}; - -enum ipc4_channel_index { - CHANNEL_LEFT = 0, - CHANNEL_CENTER = 1, - CHANNEL_RIGHT = 2, - CHANNEL_LEFT_SURROUND = 3, - CHANNEL_CENTER_SURROUND = 3, - CHANNEL_RIGHT_SURROUND = 4, - CHANNEL_LEFT_SIDE = 5, - CHANNEL_RIGHT_SIDE = 6, - CHANNEL_LFE = 7, - CHANNEL_INVALID = 0xF, -}; - -enum ipc4_interleaved_style { - IPC4_CHANNELS_INTERLEAVED = 0, - IPC4_CHANNELS_NONINTERLEAVED = 1, -}; - -enum ipc4_sample_type { - IPC4_TYPE_MSB_INTEGER = 0, /**< integer with Most Significant Byte first */ - IPC4_TYPE_LSB_INTEGER = 1, /**< integer with Least Significant Byte first */ - IPC4_TYPE_SIGNED_INTEGER = 2, - IPC4_TYPE_UNSIGNED_INTEGER = 3, - IPC4_TYPE_FLOAT = 4 -}; - -enum ipc4_stream_type { - IPC4_STREAM_PCM = 0, /**< PCM stream */ - IPC4_STREAM_MP3 = 1, /**< MP3 encoded stream */ - IPC4_STREAM_AAC = 2, /**< AAC encoded stream */ - /* TODO: revisit max stream type count. Currently - * it aligns with windows audio driver and we will - * update all when more types are supported - */ - IPC4_STREAM_COUNT = 3, - IPC4_STREAM_INVALID = 0xFF -}; - -struct ipc4_audio_format { - enum ipc4_sampling_frequency sampling_frequency; - enum ipc4_bit_depth depth; - uint32_t ch_map; - enum ipc4_channel_config ch_cfg; - uint32_t interleaving_style; - uint32_t channels_count : 8; - uint32_t valid_bit_depth : 8; - enum ipc4_sample_type s_type : 8; - uint32_t reserved : 8; -} __attribute__((packed, aligned(4))); - -struct ipc4_base_module_cfg { - uint32_t cpc; /**< the max count of Cycles Per Chunk processing */ - uint32_t ibs; /**< input Buffer Size (in bytes) */ - uint32_t obs; /**< output Buffer Size (in bytes) */ - uint32_t is_pages; /**< number of physical pages used */ - struct ipc4_audio_format audio_fmt; -} __attribute__((packed, aligned(4))); - -struct ipc4_input_pin_format { - uint32_t pin_index; /**< index of the pin */ - uint32_t ibs; /**< specifies input frame size (in bytes) */ - struct ipc4_audio_format audio_fmt; /**< format of the input data */ -} __attribute__((packed, aligned(4))); - -struct ipc4_output_pin_format { - uint32_t pin_index; /**< index of the pin */ - uint32_t obs; /**< specifies output frame size (in bytes) */ - struct ipc4_audio_format audio_fmt; /**< format of the output data */ -} __attribute__((packed, aligned(4))); - -struct ipc4_base_module_cfg_ext { - /* specifies number of items in input_pins array. Maximum size is 8 */ - uint16_t nb_input_pins; - /* specifies number of items in output_pins array. Maximum size is 8 */ - uint16_t nb_output_pins; - uint8_t reserved[12]; - /* Specifies format of input pins followed by output pins. - * Pin format arrays may be non-continuous i.e. may contain pin #0 format - * followed by pin #2 format in case pin #1 will not be in use. - * FW assigned format of the pin based on pin_index, not on a position of - * the item in the array. Applies to both input and output pins. - */ - uint8_t pin_formats[]; -} __attribute__((packed, aligned(4))); - -#define ipc4_calc_base_module_cfg_ext_size(in_pins, out_pins) \ - (sizeof(struct ipc4_base_module_cfg_ext) + \ - (in_pins) * sizeof(struct ipc4_input_pin_format) + \ - (out_pins) * sizeof(struct ipc4_output_pin_format)) - -/* Struct to combine the base_cfg and base_cfg_ext for easier parsing */ -struct ipc4_base_module_extended_cfg { - struct ipc4_base_module_cfg base_cfg; - struct ipc4_base_module_cfg_ext base_cfg_ext; -} __attribute__((packed, aligned(4))); - -/* This enum defines short 16bit parameters common for all modules. - * Value of module specific parameters have to be less than 0x3000. - */ -enum ipc4_base_module_params { - /* handled inside LargeConfigGet of module instance */ - IPC4_MOD_INST_PROPS = 0xFE, - /* handled inside ConfigSet of module instance */ - IPC4_MOD_INST_ENABLE = 0x3000 -}; - -struct ipc4_pin_props { - /* type of the connected stream. */ - enum ipc4_stream_type stream_type; - - /* audio format of the stream. The content is valid in case of ePcm stream_type. */ - struct ipc4_audio_format format; - - /* unique ID of the physical queue connected to the pin. - * If there is no queue connected, then -1 (invalid queue ID) is set - */ - uint32_t phys_queue_id; -} __attribute__((packed, aligned(4))); - -struct ipc4_pin_list_info { - uint32_t pin_count; - struct ipc4_pin_props pin_info[1]; -} __attribute__((packed, aligned(4))); - -/* structure describing module instance properties used in response - * to module LargeConfigGet with MOD_INST_PROPS parameter. - */ -struct ipc4_module_instance_props { - uint32_t id; - uint32_t dp_queue_type; - uint32_t queue_alignment; - uint32_t cp_usage_mask; - uint32_t stack_bytes; - uint32_t bss_total_bytes; - uint32_t bss_used_bytes; - uint32_t ibs_bytes; - uint32_t obs_bytes; - uint32_t cpc; - uint32_t cpc_peak; - struct ipc4_pin_list_info input_queues; - struct ipc4_pin_list_info output_queues; - uint32_t input_gateway; - uint32_t output_gateway; -} __attribute__((packed, aligned(4))); - -/* Reflects the last two entries in ModuleInstanceProps sttructure */ -struct ipc4_in_out_gateway { - uint32_t input_gateway; - uint32_t output_gateway; -} __attribute__((packed, aligned(4))); - -/* this structure may be used by modules to carry - * short 16bit parameters as part of the IxC register content. - */ -union ipc4_cfg_param_id_data { - uint32_t dw; - struct { - uint32_t data16 : 16; /* Input/Output small config data */ - uint32_t id : 14; /* input parameter ID */ - uint32_t _rsvd : 2; - } f; -} __attribute__((packed, aligned(4))); +#include struct sof_ipc_stream_params; void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *base_cfg, diff --git a/src/include/ipc4/up_down_mixer.h b/src/include/ipc4/up_down_mixer.h index a4e2246016bd..afd913b6c0d6 100644 --- a/src/include/ipc4/up_down_mixer.h +++ b/src/include/ipc4/up_down_mixer.h @@ -7,7 +7,6 @@ #ifndef __SOF_IPC4_UP_DOWN_MIXER_H__ #define __SOF_IPC4_UP_DOWN_MIXER_H__ -#include #include "base-config.h" /** diff --git a/src/include/module/audio/audio_stream.h b/src/include/module/audio/audio_stream.h new file mode 100644 index 000000000000..0941047a6395 --- /dev/null +++ b/src/include/module/audio/audio_stream.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski + * Adrian Warecki + */ + +#ifndef __MODULE_AUDIO_AUDIO_STREAM_H__ +#define __MODULE_AUDIO_AUDIO_STREAM_H__ + +#include +#include +#include "../ipc/stream.h" + +/** + * set of parameters describing audio stream + * this structure is shared between audio_stream.h and sink/source interface + * TODO: compressed formats + */ +struct sof_audio_stream_params { + uint32_t id; + enum sof_ipc_frame frame_fmt; /**< Sample data format */ + enum sof_ipc_frame valid_sample_fmt; + + uint32_t rate; /**< Number of data frames per second [Hz] */ + uint16_t channels; /**< Number of samples in each frame */ + + /** + * align_frame_cnt indicates minimum number of frames that satisfies both byte + * align and frame align requirements. E.g: Consider an algorithm that processes + * in blocks of 3 frames configured to process 16-bit stereo using xtensa HiFi3 + * SIMD. Therefore with 16-bit stereo we have a frame size of 4 bytes, and + * SIMD intrinsic requirement of 8 bytes(2 frames) for HiFi3 and an algorithim + * requirement of 3 frames. Hence the common processing block size has to align + * with frame(1), intrinsic(2) and algorithm (3) giving us an optimum processing + * block size of 6 frames. + */ + uint16_t align_frame_cnt; + + /** + * the free/available bytes of sink/source right shift align_shift_idx, the result + * multiplied by align_frame_cnt is the frame count free/available that can meet + * the align requirement. + */ + uint16_t align_shift_idx; + + bool overrun_permitted; /**< indicates whether overrun is permitted */ + bool underrun_permitted; /**< indicates whether underrun is permitted */ + + uint32_t buffer_fmt; /**< enum sof_ipc_buffer_format */ +}; + +#endif /* __MODULE_AUDIO_AUDIO_STREAM_H__ */ diff --git a/src/include/module/audio/format.h b/src/include/module/audio/format.h new file mode 100644 index 000000000000..df6e58b4a9d5 --- /dev/null +++ b/src/include/module/audio/format.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 - 2023 Intel Corporation. All rights reserved. + * + * Author: Seppo Ingalsuo + * Liam Girdwood + * Keyon Jie + * Adrian Warecki + */ + +#ifndef __MODULE_AUDIO_FORMAT_H__ +#define __MODULE_AUDIO_FORMAT_H__ + +#include +#include "../ipc/stream.h" + +static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt) +{ + switch (fmt) { + case SOF_IPC_FRAME_S16_LE: + return 2; + case SOF_IPC_FRAME_S24_3LE: + return 3; + case SOF_IPC_FRAME_U8: + return 1; + default: + return 4; + } +} + +static inline uint32_t get_sample_bitdepth(enum sof_ipc_frame fmt) +{ + switch (fmt) { + case SOF_IPC_FRAME_S16_LE: + return 16; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S24_3LE: + return 24; + case SOF_IPC_FRAME_U8: + return 8; + default: + return 32; + } +} + +static inline uint32_t get_frame_bytes(enum sof_ipc_frame fmt, uint32_t channels) +{ + return get_sample_bytes(fmt) * channels; +} + +#endif /* __MODULE_AUDIO_FORMAT_H__ */ diff --git a/src/include/module/audio/sink_api.h b/src/include/module/audio/sink_api.h new file mode 100644 index 000000000000..d5fd0118b3bf --- /dev/null +++ b/src/include/module/audio/sink_api.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __MODULE_AUDIO_SINK_API_H__ +#define __MODULE_AUDIO_SINK_API_H__ + +#include +#include +#include +#include + +#include "audio_stream.h" +#include "format.h" + +/** + * this is a definition of API to sink of audio data + * + * THE SINK is any component that can store data somehow and provide a buffer to be filled + * with data at request. The sink API does not define how the data will be processed/used + * + * The user - a module - sees this API as a destination it must send data to + * The IMPLEMENTATION - audio_stream, DP Queue - sees this as a producer that + * PROVIDES data for processing + * + * Examples of components that should expose SINK api + * - /dev/null + * all the data stored in sink buffer are just simply discarded + * - I2S sender + * Data stored in sink buffer will be sent to the external world + * - a memory ring buffer + * data stored in the buffer will be sent to another module (usually using source API, but it + * does not matter in fact). + * + * The main advantage of using sink API instead of just taking pointers to the buffers is that + * the buffer may be prepared at the moment the data producer is requesting it. i.e. + * - cache may be written back/invalidated if necessary + * - data may be moved to make linear space + * - part of the buffer may be locked to prevent reading + * etc.etc. it depends on implementation of the data sink + * + * NOTE: the module should get a complete portion of space it needs for processing, fill it + * than release. The reason is - the depending on the implementation, the calls may be + * expensive - may involve some data moving in memory, cache writebacks, etc. + * + */ + +/* forward def */ +struct sof_sink; +struct sof_audio_stream_params; +struct sof_ipc_stream_params; + +/** + * this is a definition of internals of sink API + * + * The clients of stream API should use access functions provided below! + * + */ + +struct sink_ops { + /** + * see comment of sink_get_free_size() + */ + size_t (*get_free_size)(struct sof_sink *sink); + + /** + * see comment of sink_get_buffer() + */ + int (*get_buffer)(struct sof_sink *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size); + + /** + * see comment of sink_commit_buffer() + */ + int (*commit_buffer)(struct sof_sink *sink, size_t commit_size); + + /** + * OPTIONAL: Notification to the sink implementation about changes in audio format + * + * Once any of *audio_stream_params elements changes, the implementation of + * sink may need to perform some extra operations. + * This callback will be called immediately after any change + * + * @retval 0 if success, negative if new parameters are not supported + */ + int (*on_audio_format_set)(struct sof_sink *sink); + + /** + * OPTIONAL + * see sink_set_params comments + */ + int (*audio_set_ipc_params)(struct sof_sink *sink, + struct sof_ipc_stream_params *params, bool force_update); + + /** + * OPTIONAL + * see comment for sink_set_alignment_constants + */ + int (*set_alignment_constants)(struct sof_sink *sink, + const uint32_t byte_align, + const uint32_t frame_align_req); +}; + +/** internals of sink API. NOT TO BE MODIFIED OUTSIDE OF sink_api.c */ +struct sof_sink { + const struct sink_ops *ops; /** operations interface */ + size_t requested_write_frag_size; /** keeps number of bytes requested by get_buffer() */ + size_t num_of_bytes_processed; /** processed bytes counter */ + size_t min_free_space; /** minimum buffer space required by the module using sink + * it is module's OBS as declared in module bind IPC + */ + struct sof_audio_stream_params *audio_stream_params; /** pointer to audio params */ +}; + +/** + * + * Public functions + * + */ + +/** + * Retrieves size of free space available in sink (in bytes) + * return number of free bytes in buffer available to immediate filling + */ +static inline size_t sink_get_free_size(struct sof_sink *sink) +{ + return sink->ops->get_free_size(sink); +} + +static inline enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink *sink) +{ + return sink->audio_stream_params->frame_fmt; +} + +static inline uint32_t sink_get_channels(struct sof_sink *sink) +{ + return sink->audio_stream_params->channels; +} + +/** get size of a single audio frame (in bytes) */ +size_t sink_get_frame_bytes(struct sof_sink *sink); + +/** + * Retrieves size of free space available in sink (in frames) + * return number of free frames in buffer available to immediate filling + */ +size_t sink_get_free_frames(struct sof_sink *sink); + +/** + * Get a circular buffer to operate on (to write). + * + * Retrieves a fragment of circular data to be used by the caller + * After calling get_buffer, the space for data is guaranteed to be available + * for exclusive use on the caller core through provided pointer + * if the provided pointers are cached, it is guaranteed that the caller may safely use it without + * any additional cache operations + * The caller MUST take care of data circularity based on provided pointers + * + * @param sink a handler to sink + * @param [in] req_size requested size of space + * @param [out] data_ptr a pointer to the space will be provided there + * @param [out] buffer_start pointer to circular buffer start + * @param [out] buffer_size size of circular buffer + * + * @retval -ENODATA if req_size is bigger than free space + * + */ +int sink_get_buffer(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, + size_t *buffer_size); + +/** + * Commits that the buffer previously obtained by get_buffer is filled with data + * and ready to be used + * + * @param sink a handler to sink + * @param commit_size amount of data that the caller declares as valid + * if commit_size is bigger than the amount of data obtained before by get_buffer(), only + * the amount obtained before will be committed. That means - if somebody obtained a buffer, + * filled it with data and wants to commit it in whole, it may simple call + * commit_buffer with commit_size==MAXINT + * @return proper error code (0 on success) + */ +int sink_commit_buffer(struct sof_sink *sink, size_t commit_size); + +/** set of functions for retrieve audio parameters */ +int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt); + +static inline enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink *sink) +{ + return sink->audio_stream_params->valid_sample_fmt; +} + +static inline uint32_t sink_get_rate(struct sof_sink *sink) +{ + return sink->audio_stream_params->rate; +} + +static inline uint32_t sink_get_buffer_fmt(struct sof_sink *sink) +{ + return sink->audio_stream_params->buffer_fmt; +} + +/** + * initial set of audio parameters, provided in sof_ipc_stream_params + * + * @param sink a handler to sink + * @param params the set of parameters + * @param force_update tells the implementation that the params should override actual settings + * @return 0 if success + */ +int sink_set_params(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update); + +/** + * Set frame_align_shift and frame_align of stream according to byte_align and + * frame_align_req alignment requirement. Once the channel number,frame size + * are determined, the frame_align and frame_align_shift are determined too. + * these two feature will be used in audio_stream_get_avail_frames_aligned + * to calculate the available frames. it should be called in component prepare + * or param functions only once before stream copy. if someone forgets to call + * this first, there would be unexampled error such as nothing is copied at all. + * + * @param sink a handler to sink + * @param byte_align Processing byte alignment requirement. + * @param frame_align_req Processing frames alignment requirement. + * + * @return 0 if success + */ +int sink_set_alignment_constants(struct sof_sink *sink, + const uint32_t byte_align, + const uint32_t frame_align_req); + +int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt); +int sink_set_rate(struct sof_sink *sink, unsigned int rate); +int sink_set_channels(struct sof_sink *sink, unsigned int channels); +int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt); +int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted); +int sink_set_params(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update); + +static inline size_t sink_get_min_free_space(struct sof_sink *sink) +{ + return sink->min_free_space; +} + +static inline uint32_t sink_get_id(struct sof_sink *sink) +{ + return sink->audio_stream_params->id; +} + +#endif /* __MODULE_AUDIO_SINK_API_H__ */ diff --git a/src/include/module/audio/source_api.h b/src/include/module/audio/source_api.h new file mode 100644 index 000000000000..e4b522bdb7f0 --- /dev/null +++ b/src/include/module/audio/source_api.h @@ -0,0 +1,229 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __MODULE_AUDIO_SOURCE_API_H__ +#define __MODULE_AUDIO_SOURCE_API_H__ + +#include +#include +#include +#include + +#include "audio_stream.h" +#include "format.h" + +/** + * this is a definition of API to source of audio data + * + * THE SOURCE is any component in the system that have data stored somehow and can give the + * data outside at request. The source API does not define who and how has produced the data + * + * The user - a module - sees this as a producer that PROVIDES data for processing + * The IMPLEMENTATION - audio_stream, DP Queue - sees this API as a destination it must send data to + * * + * Examples of components that should expose source API: + * - DMIC + * Data are coming from the outside world, stores in tmp buffer and can be presented + * to the rest of the system using source_api + * - a memory ring buffer + * Data are coming from other module (usually using sink_api, but it does not matter in fact) + * + * The main advantage of using source API instead of just taking pointers to the data is that + * the data may be prepared at the moment the data receiver is requesting it. i.e. + * - cache may be written back/invalidated if necessary + * - data may be moved from circular to linear space + * - part of the buffer may be locked to prevent writing + * etc.etc. it depends on implementation of the data source + * + * Data in general are provided as a circular buffer and the data receiver should be able to + * deal with it. Of course if needed an implementation of source providing linear data can be + * implemented and used as a mid-layer for modules needing it. + * + * NOTE: the module should get a complete portion of data it needs for processing, process it + * than release. The reason is - the depending on the implementation, the calls may be + * expensive - may involve some data moving in memory, cache writebacks, etc. + */ + + /* forward def */ +struct sof_source; +struct sof_audio_stream_params; +struct sof_ipc_stream_params; + +/** + * this is a definition of internals of source API + * + * The clients of stream API should use access functions provided below! + * + */ + +struct source_ops { + /** + * see comment of source_get_data_available() + */ + size_t (*get_data_available)(struct sof_source *source); + + /** + * see comment of source_get_data_available() + */ + int (*get_data)(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size); + + /** + * see comment of source_release_data() + */ + int (*release_data)(struct sof_source *source, size_t free_size); + + /** + * OPTIONAL: Notification to the source implementation about changes in audio format + * + * Once any of *audio_stream_params elements changes, the implementation of + * source may need to perform some extra operations. + * This callback will be called immediately after any change + * + * @retval 0 if success, negative if new parameteres are not supported + */ + int (*on_audio_format_set)(struct sof_source *source); + + /** + * OPTIONAL + * see source_set_params comments + */ + int (*audio_set_ipc_params)(struct sof_source *source, + struct sof_ipc_stream_params *params, bool force_update); + + /** + * OPTIONAL + * see comment for source_set_alignment_constants + */ + int (*set_alignment_constants)(struct sof_source *source, + const uint32_t byte_align, + const uint32_t frame_align_req); +}; + +/** internals of source API. NOT TO BE MODIFIED OUTSIDE OF source_api.c */ +struct sof_source { + const struct source_ops *ops; + size_t requested_read_frag_size; /* keeps size of data obtained by get_data() */ + size_t num_of_bytes_processed; /* processed bytes counter */ + size_t min_available; /* minimum data available required by the module using + * source + * it is module's IBS as declared in module bind IPC + */ + + struct sof_audio_stream_params *audio_stream_params; +}; + +/** + * + * Public functions + * + */ + +/** + * Retrieves size of available data (in bytes) + * return number of bytes that are available for immediate use + */ +static inline size_t source_get_data_available(struct sof_source *source) +{ + return source->ops->get_data_available(source); +} + +static inline enum sof_ipc_frame source_get_frm_fmt(struct sof_source *source) +{ + return source->audio_stream_params->frame_fmt; +} + +static inline unsigned int source_get_channels(struct sof_source *source) +{ + return source->audio_stream_params->channels; +} + +/** get size of a single audio frame (in bytes) */ +size_t source_get_frame_bytes(struct sof_source *source); + +/** + * Retrieves size of available data (in frames) + * return number of frames that are available for immediate use + */ +size_t source_get_data_frames_available(struct sof_source *source); + +/** + * Retrieves a fragment of circular data to be used by the caller (to read) + * After calling get_data, the data are guaranteed to be available + * for exclusive use (read only) + * if the provided pointers are cached, it is guaranteed that the caller may safely use it without + * any additional cache operations + * + * The caller MUST take care of data circularity based on provided pointers + * + * Depending on implementation - there may be a way to have several receivers of the same + * data, as long as the receiver respects that data are read-only and won'do anything + * fancy with cache handling itself + * + * some implementation data may be stored in linear buffer + * in that case: + * data_ptr = buffer_start + * buffer_end = data_ptr + req_size + * buffer_size = req_size + * + * and the data receiver may use it as usual, rollover will simple never occur + * NOTE! the caller MUST NOT assume that pointers to start/end of the circular buffer + * are constant. They may change between calls + * + * @param source a handler to source + * @param [in] req_size requested size of data. + * @param [out] data_ptr a pointer to data will be provided there + * @param [out] buffer_start pointer to circular buffer start + * @param [out] buffer_size size of circular buffer + * + * @retval -ENODATA if req_size is bigger than available data + */ +int source_get_data(struct sof_source *source, size_t req_size, void const **data_ptr, + void const **buffer_start, size_t *buffer_size); + +/** + * Releases fragment previously obtained by source_get_data() + * Once called, the data are no longer available for the caller + * + * @param source a handler to source + * @param free_size amount of data that the caller declares as "never needed again" + * if free_size == 0 the source implementation MUST keep all data in memory and make them + * available again at next get_data() call + * if free_size is bigger than the amount of data obtained before by get_data(), only + * the amount obtained before will be freed. That means - if somebody obtained some data, + * processed it and won't need it again, it may simple call put_data with free_size==MAXINT + * + * @return proper error code (0 on success) + */ +int source_release_data(struct sof_source *source, size_t free_size); + +/** set of functions for retrieve audio parameters */ +static inline enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source) +{ + return source->audio_stream_params->valid_sample_fmt; +} + +static inline unsigned int source_get_rate(struct sof_source *source) +{ + return source->audio_stream_params->rate; +} + +static inline uint32_t source_get_buffer_fmt(struct sof_source *source) +{ + return source->audio_stream_params->buffer_fmt; +} + +static inline size_t source_get_min_available(struct sof_source *source) +{ + return source->min_available; +} + +static inline uint32_t source_get_id(struct sof_source *source) +{ + return source->audio_stream_params->id; +} + +#endif /* __MODULE_AUDIO_SOURCE_API_H__ */ diff --git a/src/include/sof/audio/module_adapter/iadk/adsp_error_code.h b/src/include/module/iadk/adsp_error_code.h similarity index 78% rename from src/include/sof/audio/module_adapter/iadk/adsp_error_code.h rename to src/include/module/iadk/adsp_error_code.h index 8dbcd2698a45..e7b820e0e416 100644 --- a/src/include/sof/audio/module_adapter/iadk/adsp_error_code.h +++ b/src/include/module/iadk/adsp_error_code.h @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2022 Intel Corporation. All rights reserved. + * Copyright(c) 2022 - 2023 Intel Corporation. All rights reserved. + * + * Author: Adrian Warecki */ -#ifndef _ADSP_ERROR_CODE_H_ -#define _ADSP_ERROR_CODE_H_ +#ifndef __MODULE_IADK_ADSP_ERROR_CODE_H__ +#define __MODULE_IADK_ADSP_ERROR_CODE_H__ #include @@ -34,4 +36,4 @@ typedef uint32_t AdspErrorCode; /* Service is not supported on target platform. */ #define ADSP_SERVICE_UNAVAILABLE 143 -#endif /* _ADSP_ERROR_CODE_H_ */ +#endif /* __MODULE_IADK_ADSP_ERROR_CODE_H__ */ diff --git a/src/include/module/ipc/stream.h b/src/include/module/ipc/stream.h new file mode 100644 index 000000000000..86837d7ea302 --- /dev/null +++ b/src/include/module/ipc/stream.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 - 2023 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + * Keyon Jie + * Adrian Warecki + */ + +#ifndef __MODULE_IPC_STREAM_H__ +#define __MODULE_IPC_STREAM_H__ + +/* stream PCM frame format */ +enum sof_ipc_frame { + SOF_IPC_FRAME_S16_LE = 0, + SOF_IPC_FRAME_S24_4LE, + SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_FLOAT, + /* other formats here */ + SOF_IPC_FRAME_S24_3LE, + SOF_IPC_FRAME_S24_4LE_MSB, + SOF_IPC_FRAME_U8, +}; + +#endif /* __MODULE_IPC_STREAM_H__ */ diff --git a/src/include/module/ipc4/base-config.h b/src/include/module/ipc4/base-config.h new file mode 100644 index 000000000000..f35369783e0e --- /dev/null +++ b/src/include/module/ipc4/base-config.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2021 - 2023 Intel Corporation. All rights reserved. + */ + +/* + * This file contains structures that are exact copies of an existing ABI used + * by IOT middleware. They are Intel specific and will be used by one middleware. + * + * Some of the structures may contain programming implementations that makes them + * unsuitable for generic use and general usage. + * + * This code is mostly copied "as-is" from existing C++ interface files hence the use of + * different style in places. The intention is to keep the interface as close as possible to + * original so it's easier to track changes with IPC host code. + */ + +/** + * \file include/ipc4/base-config.h + * \brief IPC4 global definitions. + * NOTE: This ABI uses bit fields and is non portable. + */ + +#ifndef __MODULE_IPC4_BASE_CONFIG_H__ +#define __MODULE_IPC4_BASE_CONFIG_H__ + +#include + +enum ipc4_sampling_frequency { + IPC4_FS_8000HZ = 8000, + IPC4_FS_11025HZ = 11025, + IPC4_FS_12000HZ = 12000, /**< Mp3, AAC, SRC only */ + IPC4_FS_16000HZ = 16000, + IPC4_FS_18900HZ = 18900, /**< SRC only for 44100 */ + IPC4_FS_22050HZ = 22050, + IPC4_FS_24000HZ = 24000, /**< Mp3, AAC, SRC only */ + IPC4_FS_32000HZ = 32000, + IPC4_FS_37800HZ = 37800, /**< SRC only for 44100 */ + IPC4_FS_44100HZ = 44100, + IPC4_FS_48000HZ = 48000, /**< Default */ + IPC4_FS_64000HZ = 64000, /**< AAC, SRC only */ + IPC4_FS_88200HZ = 88200, /**< AAC, SRC only */ + IPC4_FS_96000HZ = 96000, /**< AAC, SRC only */ + IPC4_FS_176400HZ = 176400, /**< SRC only */ + IPC4_FS_192000HZ = 192000, /**< SRC only */ + IPC4_FS_INVALID +}; + +enum ipc4_bit_depth { + IPC4_DEPTH_8BIT = 8, /**< 8 bits depth */ + IPC4_DEPTH_16BIT = 16, /**< 16 bits depth */ + IPC4_DEPTH_24BIT = 24, /**< 24 bits depth - Default */ + IPC4_DEPTH_32BIT = 32, /**< 32 bits depth */ + IPC4_DEPTH_64BIT = 64, /**< 64 bits depth */ + IPC4_DEPTH_INVALID +}; + +enum ipc4_channel_config { + IPC4_CHANNEL_CONFIG_MONO = 0, /**< one channel only */ + IPC4_CHANNEL_CONFIG_STEREO = 1, /**< L & R */ + IPC4_CHANNEL_CONFIG_2_POINT_1 = 2, /**< L, R & LFE; PCM only */ + IPC4_CHANNEL_CONFIG_3_POINT_0 = 3, /**< L, C & R; MP3 & AAC only */ + IPC4_CHANNEL_CONFIG_3_POINT_1 = 4, /**< L, C, R & LFE; PCM only */ + IPC4_CHANNEL_CONFIG_QUATRO = 5, /**< L, R, Ls & Rs; PCM only */ + IPC4_CHANNEL_CONFIG_4_POINT_0 = 6, /**< L, C, R & Cs; MP3 & AAC only */ + IPC4_CHANNEL_CONFIG_5_POINT_0 = 7, /**< L, C, R, Ls & Rs */ + IPC4_CHANNEL_CONFIG_5_POINT_1 = 8, /**< L, C, R, Ls, Rs & LFE */ + IPC4_CHANNEL_CONFIG_DUAL_MONO = 9, /**< one channel replicated in two */ + /**< Stereo (L,R) in 4 slots, 1st stream: [ L, R, -, - ] */ + IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_0 = 10, + /**< Stereo (L,R) in 4 slots, 2nd stream: [ -, -, L, R ] */ + IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_1 = 11, + IPC4_CHANNEL_CONFIG_7_POINT_1 = 12, /**< L, C, R, Ls, Rs & LFE., LS, RS */ + IPC4_CHANNEL_CONFIG_INVALID +}; + +enum ipc4_channel_index { + CHANNEL_LEFT = 0, + CHANNEL_CENTER = 1, + CHANNEL_RIGHT = 2, + CHANNEL_LEFT_SURROUND = 3, + CHANNEL_CENTER_SURROUND = 3, + CHANNEL_RIGHT_SURROUND = 4, + CHANNEL_LEFT_SIDE = 5, + CHANNEL_RIGHT_SIDE = 6, + CHANNEL_LFE = 7, + CHANNEL_INVALID = 0xF, +}; + +enum ipc4_interleaved_style { + IPC4_CHANNELS_INTERLEAVED = 0, + IPC4_CHANNELS_NONINTERLEAVED = 1, +}; + +enum ipc4_sample_type { + IPC4_TYPE_MSB_INTEGER = 0, /**< integer with Most Significant Byte first */ + IPC4_TYPE_LSB_INTEGER = 1, /**< integer with Least Significant Byte first */ + IPC4_TYPE_SIGNED_INTEGER = 2, + IPC4_TYPE_UNSIGNED_INTEGER = 3, + IPC4_TYPE_FLOAT = 4 +}; + +enum ipc4_stream_type { + IPC4_STREAM_PCM = 0, /**< PCM stream */ + IPC4_STREAM_MP3 = 1, /**< MP3 encoded stream */ + IPC4_STREAM_AAC = 2, /**< AAC encoded stream */ + /* TODO: revisit max stream type count. Currently + * it aligns with windows audio driver and we will + * update all when more types are supported + */ + IPC4_STREAM_COUNT = 3, + IPC4_STREAM_INVALID = 0xFF +}; + +struct ipc4_audio_format { + enum ipc4_sampling_frequency sampling_frequency; + enum ipc4_bit_depth depth; + uint32_t ch_map; + enum ipc4_channel_config ch_cfg; + uint32_t interleaving_style; + uint32_t channels_count : 8; + uint32_t valid_bit_depth : 8; + enum ipc4_sample_type s_type : 8; + uint32_t reserved : 8; +} __attribute__((packed, aligned(4))); + +struct ipc4_base_module_cfg { + uint32_t cpc; /**< the max count of Cycles Per Chunk processing */ + uint32_t ibs; /**< input Buffer Size (in bytes) */ + uint32_t obs; /**< output Buffer Size (in bytes) */ + uint32_t is_pages; /**< number of physical pages used */ + struct ipc4_audio_format audio_fmt; +} __attribute__((packed, aligned(4))); + +struct ipc4_input_pin_format { + uint32_t pin_index; /**< index of the pin */ + uint32_t ibs; /**< specifies input frame size (in bytes) */ + struct ipc4_audio_format audio_fmt; /**< format of the input data */ +} __attribute__((packed, aligned(4))); + +struct ipc4_output_pin_format { + uint32_t pin_index; /**< index of the pin */ + uint32_t obs; /**< specifies output frame size (in bytes) */ + struct ipc4_audio_format audio_fmt; /**< format of the output data */ +} __attribute__((packed, aligned(4))); + +struct ipc4_base_module_cfg_ext { + /* specifies number of items in input_pins array. Maximum size is 8 */ + uint16_t nb_input_pins; + /* specifies number of items in output_pins array. Maximum size is 8 */ + uint16_t nb_output_pins; + uint8_t reserved[12]; + /* Specifies format of input pins followed by output pins. + * Pin format arrays may be non-continuous i.e. may contain pin #0 format + * followed by pin #2 format in case pin #1 will not be in use. + * FW assigned format of the pin based on pin_index, not on a position of + * the item in the array. Applies to both input and output pins. + */ + uint8_t pin_formats[]; +} __attribute__((packed, aligned(4))); + +#define ipc4_calc_base_module_cfg_ext_size(in_pins, out_pins) \ + (sizeof(struct ipc4_base_module_cfg_ext) + \ + (in_pins) * sizeof(struct ipc4_input_pin_format) + \ + (out_pins) * sizeof(struct ipc4_output_pin_format)) + +/* Struct to combine the base_cfg and base_cfg_ext for easier parsing */ +struct ipc4_base_module_extended_cfg { + struct ipc4_base_module_cfg base_cfg; + struct ipc4_base_module_cfg_ext base_cfg_ext; +} __attribute__((packed, aligned(4))); + +/* This enum defines short 16bit parameters common for all modules. + * Value of module specific parameters have to be less than 0x3000. + */ +enum ipc4_base_module_params { + /* handled inside LargeConfigGet of module instance */ + IPC4_MOD_INST_PROPS = 0xFE, + /* handled inside ConfigSet of module instance */ + IPC4_MOD_INST_ENABLE = 0x3000 +}; + +struct ipc4_pin_props { + /* type of the connected stream. */ + enum ipc4_stream_type stream_type; + + /* audio format of the stream. The content is valid in case of ePcm stream_type. */ + struct ipc4_audio_format format; + + /* unique ID of the physical queue connected to the pin. + * If there is no queue connected, then -1 (invalid queue ID) is set + */ + uint32_t phys_queue_id; +} __attribute__((packed, aligned(4))); + +struct ipc4_pin_list_info { + uint32_t pin_count; + struct ipc4_pin_props pin_info[1]; +} __attribute__((packed, aligned(4))); + +/* structure describing module instance properties used in response + * to module LargeConfigGet with MOD_INST_PROPS parameter. + */ +struct ipc4_module_instance_props { + uint32_t id; + uint32_t dp_queue_type; + uint32_t queue_alignment; + uint32_t cp_usage_mask; + uint32_t stack_bytes; + uint32_t bss_total_bytes; + uint32_t bss_used_bytes; + uint32_t ibs_bytes; + uint32_t obs_bytes; + uint32_t cpc; + uint32_t cpc_peak; + struct ipc4_pin_list_info input_queues; + struct ipc4_pin_list_info output_queues; + uint32_t input_gateway; + uint32_t output_gateway; +} __attribute__((packed, aligned(4))); + +/* Reflects the last two entries in ModuleInstanceProps sttructure */ +struct ipc4_in_out_gateway { + uint32_t input_gateway; + uint32_t output_gateway; +} __attribute__((packed, aligned(4))); + +/* this structure may be used by modules to carry + * short 16bit parameters as part of the IxC register content. + */ +union ipc4_cfg_param_id_data { + uint32_t dw; + struct { + uint32_t data16 : 16; /* Input/Output small config data */ + uint32_t id : 14; /* input parameter ID */ + uint32_t _rsvd : 2; + } f; +} __attribute__((packed, aligned(4))); + +#endif /* __MODULE_IPC4_BASE_CONFIG_H__ */ diff --git a/src/include/sof/audio/module_adapter/library/module_api_ver.h b/src/include/module/module/api_ver.h similarity index 79% rename from src/include/sof/audio/module_adapter/library/module_api_ver.h rename to src/include/module/module/api_ver.h index ba6c1bcbe383..a315400df4f2 100644 --- a/src/include/sof/audio/module_adapter/library/module_api_ver.h +++ b/src/include/module/module/api_ver.h @@ -5,8 +5,12 @@ * Author: Pawel Dobrowolski */ -#ifndef __MODULE_API_VER_H__ -#define __MODULE_API_VER_H__ +#ifndef __MODULE_MODULE_API_VER_H__ +#define __MODULE_MODULE_API_VER_H__ + +#include + +#define ADSP_BUILD_INFO_FORMAT 0 /* * Api version 5.0.0 for sof loadable modules @@ -31,4 +35,4 @@ struct sof_module_api_build_info{ union sof_module_api_version api_version_number; }; -#endif /* __MODULE_API_VER_H__ */ +#endif /* __MODULE_MODULE_API_VER_H__ */ diff --git a/src/include/module/module/base.h b/src/include/module/module/base.h new file mode 100644 index 000000000000..56964162467f --- /dev/null +++ b/src/include/module/module/base.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. + * + * Author: Marcin Rajwa + * Adrian Warecki + */ + +#ifndef __MODULE_MODULE_GENERIC__ +#define __MODULE_MODULE_GENERIC__ + +#include +#include +#include + +#include "interface.h" +#include "../ipc4/base-config.h" + +#define module_get_private_data(mod) ((mod)->priv.private) +#define module_set_private_data(mod, data) ((mod)->priv.private = data) + +/** + * \struct module_config + * \brief Module config container, used for both config types. + */ +struct module_config { + size_t size; /**< Specifies the size of whole config */ + bool avail; /**< Marks config as available to use.*/ + void *data; /**< tlv config, a pointer to memory where config is stored. */ + const void *init_data; /**< Initial IPC configuration. */ +#if CONFIG_IPC_MAJOR_4 + struct ipc4_base_module_cfg base_cfg; +#endif +}; + +/* + * A structure containing a module's private data, intended for its exclusive use. + * + * This structure should contain only fields that are used be a module. + * All other fields, used exclusively by SOF must be moved to another structure! + */ +struct module_data { + void *private; /**< self object, memory tables etc here */ + struct module_config cfg; /**< module configuration data */ + + /* + * Fields below can only be accessed by the SOF and must be moved to a new structure. + * Below #ifdef is a temporary solution used until work on separating a common interface + * for loadable modules is completed. + */ +#ifdef SOF_MODULE_API_PRIVATE + enum module_state state; + size_t new_cfg_size; /**< size of new module config data */ + void *runtime_params; + const struct module_interface *ops; /**< module specific operations */ + struct module_memory memory; /**< memory allocated by module */ + struct module_processing_data mpd; /**< shared data comp <-> module */ + void *module_adapter; /**ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP + */ + struct list_item dp_queue_ll_to_dp_list; + struct list_item dp_queue_dp_to_ll_list; + }; + }; + struct comp_buffer *source_comp_buffer; /**< single source component buffer */ + struct comp_buffer *sink_comp_buffer; /**< single sink compoonent buffer */ + + /* module-specific flags for comp_verify_params() */ + uint32_t verify_params_flags; + + /* flag to indicate module does not pause */ + bool no_pause; + + /* + * flag to indicate that the sink buffer writeback should be skipped. It will be handled + * in the module's process callback + */ + bool skip_sink_buffer_writeback; + + /* + * flag to indicate that the source buffer invalidate should be skipped. It will be handled + * in the module's process callback + */ + bool skip_src_buffer_invalidate; + + /* + * True for module with one source component buffer and one sink component buffer + * to enable reduction of module processing overhead. False if component uses + * multiple buffers. + */ + bool stream_copy_single_to_single; + + /* flag to insure that module is loadable */ + bool is_native_sof; + + /* pointer to system services for loadable modules */ + uint32_t *sys_service; + + /* total processed data after stream started */ + uint64_t total_data_consumed; + uint64_t total_data_produced; + + /* max source/sinks supported by the module */ + uint32_t max_sources; + uint32_t max_sinks; +#endif /* SOF_MODULE_PRIVATE */ +}; + +#endif /* __MODULE_MODULE_GENERIC__ */ diff --git a/src/include/module/module/interface.h b/src/include/module/module/interface.h new file mode 100644 index 000000000000..c868f227db27 --- /dev/null +++ b/src/include/module/module/interface.h @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. + * + * Author: Jaroslaw Stelter + * Adrian Warecki + */ + +#ifndef __MODULE_MODULE_INTERFACE__ +#define __MODULE_MODULE_INTERFACE__ + +#include +#include + +/** + * \enum module_cfg_fragment_position + * \brief Fragment position in config + * MODULE_CFG_FRAGMENT_FIRST: first fragment of the large configuration + * MODULE_CFG_FRAGMENT_SINGLE: only fragment of the configuration + * MODULE_CFG_FRAGMENT_LAST: last fragment of the configuration + * MODULE_CFG_FRAGMENT_MIDDLE: intermediate fragment of the large configuration + */ +enum module_cfg_fragment_position { + MODULE_CFG_FRAGMENT_MIDDLE = 0, + MODULE_CFG_FRAGMENT_FIRST, + MODULE_CFG_FRAGMENT_LAST, + MODULE_CFG_FRAGMENT_SINGLE, +}; + +/** + * \enum module_processing_mode + * MODULE_PROCESSING_NORMAL: Indicates that module is expected to apply its custom processing on + * the input signal + * MODULE_PROCESSING_BYPASS: Indicates that module is expected to skip custom processing on + * the input signal and act as a passthrough component + */ + +enum module_processing_mode { + MODULE_PROCESSING_NORMAL = 0, + MODULE_PROCESSING_BYPASS, +}; + +/** + * \struct input_stream_buffer + * \brief Input stream buffer + */ +struct input_stream_buffer { + void *data; /* data stream buffer */ + uint32_t size; /* size of data in the buffer */ + uint32_t consumed; /* number of bytes consumed by the module */ + + /* Indicates end of stream condition has occurred on the input stream */ + bool end_of_stream; +}; + +/** + * \struct output_stream_buffer + * \brief Output stream buffer + */ +struct output_stream_buffer { + void *data; /* data stream buffer */ + uint32_t size; /* size of data in the buffer */ +}; + +struct processing_module; +struct sof_source; +struct sof_sink; + +/** + * \struct module_interface + * \brief 3rd party processing module interface + */ +struct module_interface { + /** + * Module specific initialization procedure, called as part of + * module_adapter component creation in .new() + */ + int (*init)(struct processing_module *mod); + /** + * Module specific prepare procedure, called as part of module_adapter + * component preparation in .prepare() + */ + int (*prepare)(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); + + /** + * (optional) return true if the module is ready to process + * This procedure should check if the module is ready for immediate + * processing. + * + * NOTE! the call MUST NOT perform any time consuming operations + * + * this procedure will always return true for LL module + * + * For DP there's a default implementation that will do a simple check if there's + * at least IBS bytes of data on first source and at least OBS free space on first sink + * + * In case more sophisticated check is needed the method should be implemented in + * the module + */ + bool (*is_ready_to_process)(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); + + /** + * Module specific processing procedure + * This procedure is responsible to consume + * samples provided by the module_adapter and produce/output the processed + * ones back to module_adapter. + * + * there are 3 versions of the procedure, the difference is the format of + * input/output data + * + * the module MUST implement one and ONLY one of them + * + * process_audio_stream and process_raw_data are depreciated and will be removed + * once pipeline learns to use module API directly (without module adapter) + * modules that need such processing should use proper wrappers + * + * process + * - sources are handlers to source API struct source*[] + * - sinks are handlers to sink API struct sink*[] + */ + int (*process)(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); + + /** + * process_audio_stream (depreciated) + * - sources are input_stream_buffer[] + * - sources[].data is a pointer to audio_stream structure + * - sinks are output_stream_buffer[] + * - sinks[].data is a pointer to audio_stream structure + * + * It can be used by modules that support 1:1, 1:N, N:1 sources:sinks configuration. + */ + int (*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); + + /** + * process_raw_data (depreciated) + * - sources are input_stream_buffer[] + * - sources[].data is a pointer to raw audio data + * - sinks are output_stream_buffer[] + * - sinks[].data is a pointer to raw audio data + */ + int (*process_raw_data)(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers); + + /** + * Set module configuration for the given configuration ID + * + * If the complete configuration message is greater than MAX_BLOB_SIZE bytes, the + * transmission will be split into several smaller fragments. + * In this case the ADSP System will perform multiple calls to SetConfiguration() until + * completion of the configuration message sending. + * \note config_id indicates ID of the configuration message only on the first fragment + * sending, otherwise it is set to 0. + */ + int (*set_configuration)(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, + size_t response_size); + + /** + * Get module runtime configuration for the given configuration ID + * + * If the complete configuration message is greater than MAX_BLOB_SIZE bytes, the + * transmission will be split into several smaller fragments. + * In this case the ADSP System will perform multiple calls to GetConfiguration() until + * completion of the configuration message retrieval. + * \note config_id indicates ID of the configuration message only on the first fragment + * retrieval, otherwise it is set to 0. + */ + int (*get_configuration)(struct processing_module *mod, + uint32_t config_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size); + + /** + * Set processing mode for the module + */ + int (*set_processing_mode)(struct processing_module *mod, + enum module_processing_mode mode); + + /** + * Get the current processing mode for the module + */ + enum module_processing_mode (*get_processing_mode)(struct processing_module *mod); + + /** + * Module specific reset procedure, called as part of module_adapter component + * reset in .reset(). This should reset all parameters to their initial stage + * and free all memory allocated during prepare(). + */ + int (*reset)(struct processing_module *mod); + /** + * Module specific free procedure, called as part of module_adapter component + * free in .free(). This should free all memory allocated during module initialization. + */ + int (*free)(struct processing_module *mod); + /** + * Module specific bind procedure, called when modules are bound with each other + */ + int (*bind)(struct processing_module *mod, void *data); + /** + * Module specific unbind procedure, called when modules are disconnected from one another + */ + int (*unbind)(struct processing_module *mod, void *data); + + /** + * Module specific trigger procedure, called when modules are triggered + */ + int (*trigger)(struct processing_module *mod, int cmd); + + /* + * Ops relevant only for the endpoint devices such as the host copier or DAI copier. + * Other modules should not implement these. + * + * Below #ifdef is a temporary solution used until work on separating a common interface + * for loadable modules is completed. + */ +#ifdef SOF_MODULE_API_PRIVATE + const struct module_endpoint_ops *endpoint_ops; +#endif /* SOF_MODULE_PRIVATE */ +}; + +#endif /* __MODULE_MODULE_INTERFACE__ */ diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 4243c25f8350..09bfb68a038d 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2020 Intel Corporation. All rights reserved. + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. * * Author: Karol Trzcinski */ @@ -16,9 +16,7 @@ #include #include -#include #include -#include #include #include #include @@ -26,6 +24,7 @@ #include #include #include +#include #include #include @@ -34,44 +33,6 @@ * @{ */ -/** - * set of parameters describing audio stream - * this structure is shared between audio_stream.h and sink/source interface - * TODO: compressed formats - */ -struct sof_audio_stream_params { - uint32_t id; - enum sof_ipc_frame frame_fmt; /**< Sample data format */ - enum sof_ipc_frame valid_sample_fmt; - - uint32_t rate; /**< Number of data frames per second [Hz] */ - uint16_t channels; /**< Number of samples in each frame */ - - /** - * align_frame_cnt indicates minimum number of frames that satisfies both byte - * align and frame align requirements. E.g: Consider an algorithm that processes - * in blocks of 3 frames configured to process 16-bit stereo using xtensa HiFi3 - * SIMD. Therefore with 16-bit stereo we have a frame size of 4 bytes, and - * SIMD intrinsic requirement of 8 bytes(2 frames) for HiFi3 and an algorithim - * requirement of 3 frames. Hence the common processing block size has to align - * with frame(1), intrinsic(2) and algorithm (3) giving us an optimum processing - * block size of 6 frames. - */ - uint16_t align_frame_cnt; - - /** - * the free/available bytes of sink/source right shift align_shift_idx, the result - * multiplied by align_frame_cnt is the frame count free/available that can meet - * the align requirement. - */ - uint16_t align_shift_idx; - - bool overrun_permitted; /**< indicates whether overrun is permitted */ - bool underrun_permitted; /**< indicates whether underrun is permitted */ - - uint32_t buffer_fmt; /**< enum sof_ipc_buffer_format */ -}; - /** * Audio stream is a circular buffer aware of audio format of the data * in the buffer so provides API for reading and writing not only bytes, diff --git a/src/include/sof/audio/coefficients/up_down_mixer/up_down_mixer.h b/src/include/sof/audio/coefficients/up_down_mixer/up_down_mixer.h index 7344039b640d..ed6730502a79 100644 --- a/src/include/sof/audio/coefficients/up_down_mixer/up_down_mixer.h +++ b/src/include/sof/audio/coefficients/up_down_mixer/up_down_mixer.h @@ -6,7 +6,6 @@ // Author: Adrian Bonislawski #include -#include #include #if CONFIG_COMP_UP_DOWN_MIXER diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index a872e1d3048e..59214f3d2ee9 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -19,29 +19,13 @@ #include #include #include -#include #include -#include -#include -#include -#include #include -#include -#include -#include #include -#include -#include #include -#include #include #include -#include -#include -#include -#include -#include #include struct comp_dev; diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 2c51943413c3..208be66b1f8d 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -17,11 +17,7 @@ #define __SOF_AUDIO_COMPONENT_INT_H__ #include -#include -#include #include -#include -#include /** \addtogroup component_api_helpers Component Mgmt API * @{ diff --git a/src/include/sof/audio/dp_queue.h b/src/include/sof/audio/dp_queue.h index 1c699f11e273..877613d141f9 100644 --- a/src/include/sof/audio/dp_queue.h +++ b/src/include/sof/audio/dp_queue.h @@ -9,8 +9,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/include/sof/audio/format.h b/src/include/sof/audio/format.h index a33d3c60fce4..8174e53a4163 100644 --- a/src/include/sof/audio/format.h +++ b/src/include/sof/audio/format.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2016 Intel Corporation. All rights reserved. + * Copyright(c) 2016 - 2023 Intel Corporation. All rights reserved. * * Author: Seppo Ingalsuo * Liam Girdwood @@ -165,39 +165,4 @@ static inline int32_t sign_extend_s24(int32_t x) return (x << 8) >> 8; } -static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt) -{ - switch (fmt) { - case SOF_IPC_FRAME_S16_LE: - return 2; - case SOF_IPC_FRAME_S24_3LE: - return 3; - case SOF_IPC_FRAME_U8: - return 1; - default: - return 4; - } -} - -static inline uint32_t get_sample_bitdepth(enum sof_ipc_frame fmt) -{ - switch (fmt) { - case SOF_IPC_FRAME_S16_LE: - return 16; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S24_3LE: - return 24; - case SOF_IPC_FRAME_U8: - return 8; - default: - return 32; - } -} - -static inline uint32_t get_frame_bytes(enum sof_ipc_frame fmt, - uint32_t channels) -{ - return get_sample_bytes(fmt) * channels; -} - #endif /* __SOF_AUDIO_FORMAT_H__ */ diff --git a/src/include/sof/audio/module_adapter/iadk/system_error.h b/src/include/sof/audio/module_adapter/iadk/system_error.h index 57b57b4b8afe..821f136694bb 100644 --- a/src/include/sof/audio/module_adapter/iadk/system_error.h +++ b/src/include/sof/audio/module_adapter/iadk/system_error.h @@ -7,7 +7,7 @@ #ifndef _ADSP_SYSTEM_ERROR_H_ #define _ADSP_SYSTEM_ERROR_H_ -#include "adsp_error_code.h" +#include namespace intel_adsp { diff --git a/src/include/sof/audio/module_adapter/iadk/system_service.h b/src/include/sof/audio/module_adapter/iadk/system_service.h index 54b15c0ab275..453247a38505 100644 --- a/src/include/sof/audio/module_adapter/iadk/system_service.h +++ b/src/include/sof/audio/module_adapter/iadk/system_service.h @@ -9,7 +9,7 @@ #include "logger.h" #include "adsp_stddef.h" -#include "adsp_error_code.h" +#include #include "native_system_service.h" #include diff --git a/src/include/sof/audio/module_adapter/library/native_system_service.h b/src/include/sof/audio/module_adapter/library/native_system_service.h index 6007770e208f..74f6a823192b 100644 --- a/src/include/sof/audio/module_adapter/library/native_system_service.h +++ b/src/include/sof/audio/module_adapter/library/native_system_service.h @@ -5,10 +5,12 @@ /*! \file native_system_service.h */ #ifndef NATIVE_SYSTEM_SERVICE_H #define NATIVE_SYSTEM_SERVICE_H + +#include + #include "logger.h" #include "adsp_stddef.h" -#include "adsp_error_code.h" -#include +#include /*! \brief This struct defines the obfuscating type for notifications. */ typedef struct _adsp_notification_handle {} *adsp_notification_handle; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 90f91ab0cef7..10cbfa61acf9 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -1,11 +1,12 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2020 Intel Corporation. All rights reserved. +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. * * * \file generic.h * \brief Generic Module API header file * \author Marcin Rajwa + * \author Adrian Warecki * */ @@ -37,7 +38,6 @@ #define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ (!!((struct module_data *)&(mod)->priv)->ops->process) -#define module_get_private_data(mod) (mod->priv.private) #define MAX_BLOB_SIZE 8192 #define MODULE_MAX_SOURCES 8 @@ -126,20 +126,6 @@ struct module_param { int32_t data[]; /**< A pointer to memory where config is stored.*/ }; -/** - * \struct module_config - * \brief Module config container, used for both config types. - */ -struct module_config { - size_t size; /**< Specifies the size of whole config */ - bool avail; /**< Marks config as available to use.*/ - void *data; /**< tlv config, a pointer to memory where config is stored. */ - const void *init_data; /**< Initial IPC configuration. */ -#if CONFIG_IPC_MAJOR_4 - struct ipc4_base_module_cfg base_cfg; -#endif -}; - /** * \struct module_memory * \brief module memory block - used for every memory allocated by module @@ -164,103 +150,14 @@ struct module_processing_data { void *out_buff; /**< A pointer to module output buffer. */ }; -/** private, runtime module data */ -struct module_data { - enum module_state state; - size_t new_cfg_size; /**< size of new module config data */ - void *private; /**< self object, memory tables etc here */ - void *runtime_params; - struct module_config cfg; /**< module configuration data */ - const struct module_interface *ops; /**< module specific operations */ - struct module_memory memory; /**< memory allocated by module */ - struct module_processing_data mpd; /**< shared data comp <-> module */ - void *module_adapter; /**ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP - */ - struct list_item dp_queue_ll_to_dp_list; - struct list_item dp_queue_dp_to_ll_list; - }; - }; - struct comp_buffer *source_comp_buffer; /**< single source component buffer */ - struct comp_buffer *sink_comp_buffer; /**< single sink compoonent buffer */ - - /* module-specific flags for comp_verify_params() */ - uint32_t verify_params_flags; - - /* flag to indicate module does not pause */ - bool no_pause; - - /* - * flag to indicate that the sink buffer writeback should be skipped. It will be handled - * in the module's process callback - */ - bool skip_sink_buffer_writeback; - - /* - * flag to indicate that the source buffer invalidate should be skipped. It will be handled - * in the module's process callback - */ - bool skip_src_buffer_invalidate; - - /* - * True for module with one source component buffer and one sink component buffer - * to enable reduction of module processing overhead. False if component uses - * multiple buffers. - */ - bool stream_copy_single_to_single; - - /* flag to insure that module is loadable */ - bool is_native_sof; - - /* pointer to system services for loadable modules */ - uint32_t *sys_service; - - /* total processed data after stream started */ - uint64_t total_data_consumed; - uint64_t total_data_produced; +/* + * Definition used to extend structure definitions to include fields for exclusive use by SOF. + * This is a temporary solution used until work on separating a common interface for loadable + * modules is completed. + */ +#define SOF_MODULE_API_PRIVATE - /* max source/sinks supported by the module */ - uint32_t max_sources; - uint32_t max_sinks; -}; +#include /*****************************************************************************/ /* Module generic interfaces */ diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index 7cc165ad83ff..ccddcf6fda0a 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -1,13 +1,8 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2020 Intel Corporation. All rights reserved. - * - * - * \file common.h - * \brief Extract from generic.h definitions that need to be included - * in intel module adapter code. - * \author Jaroslaw Stelter +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright(c) 2020 - 2023 Intel Corporation. All rights reserved. * + * Author: Jaroslaw Stelter */ #ifndef __SOF_MODULE_INTERFACE__ @@ -17,59 +12,20 @@ #include #include -/** - * \enum module_cfg_fragment_position - * \brief Fragment position in config - * MODULE_CFG_FRAGMENT_FIRST: first fragment of the large configuration - * MODULE_CFG_FRAGMENT_SINGLE: only fragment of the configuration - * MODULE_CFG_FRAGMENT_LAST: last fragment of the configuration - * MODULE_CFG_FRAGMENT_MIDDLE: intermediate fragment of the large configuration - */ -enum module_cfg_fragment_position { - MODULE_CFG_FRAGMENT_MIDDLE = 0, - MODULE_CFG_FRAGMENT_FIRST, - MODULE_CFG_FRAGMENT_LAST, - MODULE_CFG_FRAGMENT_SINGLE, -}; - -/** - * \enum module_processing_mode - * MODULE_PROCESSING_NORMAL: Indicates that module is expected to apply its custom processing on - * the input signal - * MODULE_PROCESSING_BYPASS: Indicates that module is expected to skip custom processing on - * the input signal and act as a passthrough component +/* + * Definition used to extend structure definitions to include fields for exclusive use by SOF. + * This is a temporary solution used until work on separating a common interface for loadable + * modules is completed. */ +#define SOF_MODULE_API_PRIVATE -enum module_processing_mode { - MODULE_PROCESSING_NORMAL = 0, - MODULE_PROCESSING_BYPASS, -}; - -/** - * \struct input_stream_buffer - * \brief Input stream buffer - */ -struct input_stream_buffer { - void *data; /* data stream buffer */ - uint32_t size; /* size of data in the buffer */ - uint32_t consumed; /* number of bytes consumed by the module */ - - /* Indicates end of stream condition has occurred on the input stream */ - bool end_of_stream; -}; - -/** - * \struct output_stream_buffer - * \brief Output stream buffer - */ -struct output_stream_buffer { - void *data; /* data stream buffer */ - uint32_t size; /* size of data in the buffer */ -}; +#include struct comp_dev; struct timestamp_data; struct dai_ts_data; +struct sof_ipc_stream_posn; + /** * \struct module_endpoint_ops * \brief Ops relevant only for the endpoint devices such as the host copier or DAI copier. @@ -147,164 +103,6 @@ struct module_endpoint_ops { int (*trigger)(struct comp_dev *dev, int cmd); }; -struct processing_module; -/** - * \struct module_interface - * \brief 3rd party processing module interface - */ -struct module_interface { - /** - * Module specific initialization procedure, called as part of - * module_adapter component creation in .new() - */ - int (*init)(struct processing_module *mod); - /** - * Module specific prepare procedure, called as part of module_adapter - * component preparation in .prepare() - */ - int (*prepare)(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks); - - /** - * (optional) return true if the module is ready to process - * This procedure should check if the module is ready for immediate - * processing. - * - * NOTE! the call MUST NOT perform any time consuming operations - * - * this procedure will always return true for LL module - * - * For DP there's a default implementation that will do a simple check if there's - * at least IBS bytes of data on first source and at least OBS free space on first sink - * - * In case more sophisticated check is needed the method should be implemented in - * the module - */ - bool (*is_ready_to_process)(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks); - - /** - * Module specific processing procedure - * This procedure is responsible to consume - * samples provided by the module_adapter and produce/output the processed - * ones back to module_adapter. - * - * there are 3 versions of the procedure, the difference is the format of - * input/output data - * - * the module MUST implement one and ONLY one of them - * - * process_audio_stream and process_raw_data are depreciated and will be removed - * once pipeline learns to use module API directly (without module adapter) - * modules that need such processing should use proper wrappers - * - * process - * - sources are handlers to source API struct source*[] - * - sinks are handlers to sink API struct sink*[] - */ - int (*process)(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks); - - /** - * process_audio_stream (depreciated) - * - sources are input_stream_buffer[] - * - sources[].data is a pointer to audio_stream structure - * - sinks are output_stream_buffer[] - * - sinks[].data is a pointer to audio_stream structure - * - * It can be used by modules that support 1:1, 1:N, N:1 sources:sinks configuration. - */ - int (*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); - - /** - * process_raw_data (depreciated) - * - sources are input_stream_buffer[] - * - sources[].data is a pointer to raw audio data - * - sinks are output_stream_buffer[] - * - sinks[].data is a pointer to raw audio data - */ - int (*process_raw_data)(struct processing_module *mod, - struct input_stream_buffer *input_buffers, - int num_input_buffers, - struct output_stream_buffer *output_buffers, - int num_output_buffers); - - /** - * Set module configuration for the given configuration ID - * - * If the complete configuration message is greater than MAX_BLOB_SIZE bytes, the - * transmission will be split into several smaller fragments. - * In this case the ADSP System will perform multiple calls to SetConfiguration() until - * completion of the configuration message sending. - * \note config_id indicates ID of the configuration message only on the first fragment - * sending, otherwise it is set to 0. - */ - int (*set_configuration)(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, - size_t response_size); - - /** - * Get module runtime configuration for the given configuration ID - * - * If the complete configuration message is greater than MAX_BLOB_SIZE bytes, the - * transmission will be split into several smaller fragments. - * In this case the ADSP System will perform multiple calls to GetConfiguration() until - * completion of the configuration message retrieval. - * \note config_id indicates ID of the configuration message only on the first fragment - * retrieval, otherwise it is set to 0. - */ - int (*get_configuration)(struct processing_module *mod, - uint32_t config_id, uint32_t *data_offset_size, - uint8_t *fragment, size_t fragment_size); - - /** - * Set processing mode for the module - */ - int (*set_processing_mode)(struct processing_module *mod, - enum module_processing_mode mode); - - /** - * Get the current processing mode for the module - */ - enum module_processing_mode (*get_processing_mode)(struct processing_module *mod); - - /** - * Module specific reset procedure, called as part of module_adapter component - * reset in .reset(). This should reset all parameters to their initial stage - * and free all memory allocated during prepare(). - */ - int (*reset)(struct processing_module *mod); - /** - * Module specific free procedure, called as part of module_adapter component - * free in .free(). This should free all memory allocated during module initialization. - */ - int (*free)(struct processing_module *mod); - /** - * Module specific bind procedure, called when modules are bound with each other - */ - int (*bind)(struct processing_module *mod, void *data); - /** - * Module specific unbind procedure, called when modules are disconnected from one another - */ - int (*unbind)(struct processing_module *mod, void *data); - - /** - * Module specific trigger procedure, called when modules are triggered - */ - int (*trigger)(struct processing_module *mod, int cmd); - - const struct module_endpoint_ops *endpoint_ops; -}; - /* Convert first_block/last_block indicator to fragment position */ static inline enum module_cfg_fragment_position first_last_block_to_frag_pos(bool first_block, bool last_block) diff --git a/src/include/sof/audio/module_adapter/module/modules.h b/src/include/sof/audio/module_adapter/module/modules.h index 2c99f08a4389..07d099d4fdb9 100644 --- a/src/include/sof/audio/module_adapter/module/modules.h +++ b/src/include/sof/audio/module_adapter/module/modules.h @@ -35,7 +35,7 @@ * - Processing Module Adapter - SOF base FW side of ProcessingModuleInterface API * * Using the same philosofy loadable modules are using module adapter to interact with SOF FW. - * Module recognision is done by checking module API version defined in module_api_ver.h + * Module recognision is done by checking module API version defined in module/module/api_ver.h * with version read from elf file. */ diff --git a/src/include/sof/audio/sink_api.h b/src/include/sof/audio/sink_api.h index e9c1fa7e2d80..11ffc6e08c3d 100644 --- a/src/include/sof/audio/sink_api.h +++ b/src/include/sof/audio/sink_api.h @@ -7,96 +7,20 @@ #ifndef __SOF_SINK_API_H__ #define __SOF_SINK_API_H__ -#include -#include -#include -#include +#include /** - * this is a definition of API to sink of audio data + * Init of the API, must be called before any operation * - * THE SINK is any component that can store data somehow and provide a buffer to be filled - * with data at request. The sink API does not define how the data will be processed/used - * - * The user - a module - sees this API as a destination it must send data to - * The IMPLEMENTATION - audio_stream, DP Queue - sees this as a producer that - * PROVIDES data for processing - * - * Examples of components that should expose SINK api - * - /dev/null - * all the data stored in sink buffer are just simply discarded - * - I2S sender - * Data stored in sink buffer will be sent to the external world - * - a memory ring buffer - * data stored in the buffer will be sent to another module (usually using source API, but it - * does not matter in fact). - * - * The main advantage of using sink API instead of just taking pointers to the buffers is that - * the buffer may be prepared at the moment the data producer is requesting it. i.e. - * - cache may be written back/invalidated if necessary - * - data may be moved to make linear space - * - part of the buffer may be locked to prevent reading - * etc.etc. it depends on implementation of the data sink - * - * NOTE: the module should get a complete portion of space it needs for processing, fill it - * than release. The reason is - the depending on the implementation, the calls may be - * expensive - may involve some data moving in memory, cache writebacks, etc. - * - */ - -/** definition of obfsfucated handler of sink API */ -struct sof_sink; - -/* forward def */ -struct sof_ipc_stream_params; - -/** - * Retrieves size of free space available in sink (in bytes) - * return number of free bytes in buffer available to immediate filling - */ -size_t sink_get_free_size(struct sof_sink *sink); - -/** - * Retrieves size of free space available in sink (in frames) - * return number of free bytes in buffer available to immediate filling - */ -size_t sink_get_free_frames(struct sof_sink *sink); - -/** - * Get a circular buffer to operate on (to write). - * - * Retrieves a fragment of circular data to be used by the caller - * After calling get_buffer, the space for data is guaranteed to be available - * for exclusive use on the caller core through provided pointer - * if the provided pointers are cached, it is guaranteed that the caller may safely use it without - * any additional cache operations - * The caller MUST take care of data circularity based on provided pointers - * - * @param sink a handler to sink - * @param [in] req_size requested size of space - * @param [out] data_ptr a pointer to the space will be provided there - * @param [out] buffer_start pointer to circular buffer start - * @param [out] buffer_size size of circular buffer - * - * @retval -ENODATA if req_size is bigger than free space - * - */ -int sink_get_buffer(struct sof_sink *sink, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size); - -/** - * Commits that the buffer previously obtained by get_buffer is filled with data - * and ready to be used - * - * @param sink a handler to sink - * @param commit_size amount of data that the caller declares as valid - * if commit_size is bigger than the amount of data obtained before by get_buffer(), only - * the amount obtained before will be committed. That means - if somebody obtained a buffer, - * filled it with data and wants to commit it in whole, it may simple call - * commit_buffer with commit_size==MAXINT - * @return proper error code (0 on success) + * @param sink pointer to the structure + * @param ops pointer to API operations + * @param audio_stream_params pointer to structure with audio parameters + * note that the audio_stream_params must be accessible by the caller core + * the implementation must ensure coherent access to the parameteres + * in case of i.e. cross core shared queue, it must be located in non-cached memory */ -int sink_commit_buffer(struct sof_sink *sink, size_t commit_size); +void sink_init(struct sof_sink *sink, const struct sink_ops *ops, + struct sof_audio_stream_params *audio_stream_params); /** * Get total number of bytes processed by the sink (meaning - committed by sink_commit_buffer()) @@ -111,56 +35,10 @@ size_t sink_get_num_of_processed_bytes(struct sof_sink *sink); */ void sink_reset_num_of_processed_bytes(struct sof_sink *sink); -/** get size of a single audio frame (in bytes) */ -size_t sink_get_frame_bytes(struct sof_sink *sink); - /** set of functions for retrieve audio parameters */ -enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink *sink); -enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink *sink); -uint32_t sink_get_rate(struct sof_sink *sink); -uint32_t sink_get_channels(struct sof_sink *sink); -uint32_t sink_get_buffer_fmt(struct sof_sink *sink); bool sink_get_overrun(struct sof_sink *sink); /** set of functions for setting audio parameters */ -int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt); -int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt); -int sink_set_rate(struct sof_sink *sink, unsigned int rate); -int sink_set_channels(struct sof_sink *sink, unsigned int channels); -int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted); -int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt); void sink_set_min_free_space(struct sof_sink *sink, size_t min_free_space); -size_t sink_get_min_free_space(struct sof_sink *sink); -uint32_t sink_get_id(struct sof_sink *sink); - -/** - * initial set of audio parameters, provided in sof_ipc_stream_params - * - * @param sink a handler to sink - * @param params the set of parameters - * @param force_update tells the implementation that the params should override actual settings - * @return 0 if success - */ -int sink_set_params(struct sof_sink *sink, - struct sof_ipc_stream_params *params, bool force_update); - -/** - * Set frame_align_shift and frame_align of stream according to byte_align and - * frame_align_req alignment requirement. Once the channel number,frame size - * are determined, the frame_align and frame_align_shift are determined too. - * these two feature will be used in audio_stream_get_avail_frames_aligned - * to calculate the available frames. it should be called in component prepare - * or param functions only once before stream copy. if someone forgets to call - * this first, there would be unexampled error such as nothing is copied at all. - * - * @param sink a handler to sink - * @param byte_align Processing byte alignment requirement. - * @param frame_align_req Processing frames alignment requirement. - * - * @return 0 if success - */ -int sink_set_alignment_constants(struct sof_sink *sink, - const uint32_t byte_align, - const uint32_t frame_align_req); #endif /* __SOF_SINK_API_H__ */ diff --git a/src/include/sof/audio/sink_api_implementation.h b/src/include/sof/audio/sink_api_implementation.h deleted file mode 100644 index 23cec8dbb30e..000000000000 --- a/src/include/sof/audio/sink_api_implementation.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2023 Intel Corporation. All rights reserved. - * - */ - -#ifndef __SOF_SINK_API_IMPLEMENTATION_H__ -#define __SOF_SINK_API_IMPLEMENTATION_H__ - -#include -#include -#include - -/* forward def */ -struct sof_audio_stream_params; - -/** - * this is a definition of internals of sink API - * - * this file should be included by the implementations of sink API - * - * The clients of stream API should use functions provided in sink_api.h ONLY - * - */ - -struct sink_ops { - /** - * see comment of sink_get_free_size() - */ - size_t (*get_free_size)(struct sof_sink *sink); - - /** - * see comment of sink_get_buffer() - */ - int (*get_buffer)(struct sof_sink *sink, size_t req_size, - void **data_ptr, void **buffer_start, size_t *buffer_size); - - /** - * see comment of sink_commit_buffer() - */ - int (*commit_buffer)(struct sof_sink *sink, size_t commit_size); - - /** - * OPTIONAL: Notification to the sink implementation about changes in audio format - * - * Once any of *audio_stream_params elements changes, the implementation of - * sink may need to perform some extra operations. - * This callback will be called immediately after any change - * - * @retval 0 if success, negative if new parameters are not supported - */ - int (*on_audio_format_set)(struct sof_sink *sink); - - /** - * OPTIONAL - * see sink_set_params comments - */ - int (*audio_set_ipc_params)(struct sof_sink *sink, - struct sof_ipc_stream_params *params, bool force_update); - - /** - * OPTIONAL - * see comment for sink_set_alignment_constants - */ - int (*set_alignment_constants)(struct sof_sink *sink, - const uint32_t byte_align, - const uint32_t frame_align_req); -}; - -/** internals of sink API. NOT TO BE MODIFIED OUTSIDE OF sink_api_helper.h */ -struct sof_sink { - const struct sink_ops *ops; /** operations interface */ - size_t requested_write_frag_size; /** keeps number of bytes requested by get_buffer() */ - size_t num_of_bytes_processed; /** processed bytes counter */ - size_t min_free_space; /** minimum buffer space required by the module using sink - * it is module's OBS as declared in module bind IPC - */ - struct sof_audio_stream_params *audio_stream_params; /** pointer to audio params */ -}; - -/** - * Init of the API, must be called before any operation - * - * @param sink pointer to the structure - * @param ops pointer to API operations - * @param audio_stream_params pointer to structure with audio parameters - * note that the audio_stream_params must be accessible by the caller core - * the implementation must ensure coherent access to the parameteres - * in case of i.e. cross core shared queue, it must be located in non-cached memory - */ -void sink_init(struct sof_sink *sink, const struct sink_ops *ops, - struct sof_audio_stream_params *audio_stream_params); - -#endif /* __SOF_SINK_API_IMPLEMENTATION_H__ */ diff --git a/src/include/sof/audio/source_api.h b/src/include/sof/audio/source_api.h index de224f4bc51a..2f84e1948ebe 100644 --- a/src/include/sof/audio/source_api.h +++ b/src/include/sof/audio/source_api.h @@ -7,110 +7,20 @@ #ifndef __SOF_SOURCE_API_H__ #define __SOF_SOURCE_API_H__ -#include -#include -#include -#include +#include /** - * this is a definition of API to source of audio data - * - * THE SOURCE is any component in the system that have data stored somehow and can give the - * data outside at request. The source API does not define who and how has produced the data - * - * The user - a module - sees this as a producer that PROVIDES data for processing - * The IMPLEMENTATION - audio_stream, DP Queue - sees this API as a destination it must send data to - * * - * Examples of components that should expose source API: - * - DMIC - * Data are coming from the outside world, stores in tmp buffer and can be presented - * to the rest of the system using source_api - * - a memory ring buffer - * Data are coming from other module (usually using sink_api, but it does not matter in fact) - * - * The main advantage of using source API instead of just taking pointers to the data is that - * the data may be prepared at the moment the data receiver is requesting it. i.e. - * - cache may be written back/invalidated if necessary - * - data may be moved from circular to linear space - * - part of the buffer may be locked to prevent writing - * etc.etc. it depends on implementation of the data source - * - * Data in general are provided as a circular buffer and the data receiver should be able to - * deal with it. Of course if needed an implementation of source providing linear data can be - * implemented and used as a mid-layer for modules needing it. - * - * NOTE: the module should get a complete portion of data it needs for processing, process it - * than release. The reason is - the depending on the implementation, the calls may be - * expensive - may involve some data moving in memory, cache writebacks, etc. - */ - -/** definition of obfsfucated handler of source API */ -struct sof_source; - -/* forward def */ -struct sof_ipc_stream_params; - -/** - * Retrieves size of available data (in bytes) - * return number of bytes that are available for immediate use - */ -size_t source_get_data_available(struct sof_source *source); - -/** - * Retrieves size of available data (in frames) - * return number of bytes that are available for immediate use - */ -size_t source_get_data_frames_available(struct sof_source *source); - -/** - * Retrieves a fragment of circular data to be used by the caller (to read) - * After calling get_data, the data are guaranteed to be available - * for exclusive use (read only) - * if the provided pointers are cached, it is guaranteed that the caller may safely use it without - * any additional cache operations - * - * The caller MUST take care of data circularity based on provided pointers - * - * Depending on implementation - there may be a way to have several receivers of the same - * data, as long as the receiver respects that data are read-only and won'do anything - * fancy with cache handling itself - * - * some implementation data may be stored in linear buffer - * in that case: - * data_ptr = buffer_start - * buffer_end = data_ptr + req_size - * buffer_size = req_size - * - * and the data receiver may use it as usual, rollover will simple never occur - * NOTE! the caller MUST NOT assume that pointers to start/end of the circular buffer - * are constant. They may change between calls - * - * @param source a handler to source - * @param [in] req_size requested size of data. - * @param [out] data_ptr a pointer to data will be provided there - * @param [out] buffer_start pointer to circular buffer start - * @param [out] buffer_size size of circular buffer - * - * @retval -ENODATA if req_size is bigger than available data + * Init of the API, must be called before any operation + * + * @param source pointer to the structure + * @param ops pointer to API operations + * @param audio_stream_params pointer to structure with audio parameters + * note that the audio_stream_params must be accessible by the caller core + * the implementation must ensure coherent access to the parameteres + * in case of i.e. cross core shared queue, it must be located in non-cached memory */ -int source_get_data(struct sof_source *source, size_t req_size, - void const **data_ptr, void const **buffer_start, size_t *buffer_size); - -/** - * Releases fragment previously obtained by source_get_data() - * Once called, the data are no longer available for the caller - * - * @param source a handler to source - * @param free_size amount of data that the caller declares as "never needed again" - * if free_size == 0 the source implementation MUST keep all data in memory and make them - * available again at next get_data() call - * if free_size is bigger than the amount of data obtained before by get_data(), only - * the amount obtained before will be freed. That means - if somebody obtained some data, - * processed it and won't need it again, it may simple call put_data with free_size==MAXINT - * - * @return proper error code (0 on success) - */ -int source_release_data(struct sof_source *source, size_t free_size); +void source_init(struct sof_source *source, const struct source_ops *ops, + struct sof_audio_stream_params *audio_stream_params); /** * Get total number of bytes processed by the source (meaning - freed by source_release_data()) @@ -122,15 +32,7 @@ size_t source_get_num_of_processed_bytes(struct sof_source *source); */ void source_reset_num_of_processed_bytes(struct sof_source *source); -/** get size of a single audio frame (in bytes) */ -size_t source_get_frame_bytes(struct sof_source *source); - /** set of functions for retrieve audio parameters */ -enum sof_ipc_frame source_get_frm_fmt(struct sof_source *source); -enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source); -unsigned int source_get_rate(struct sof_source *source); -unsigned int source_get_channels(struct sof_source *source); -uint32_t source_get_buffer_fmt(struct sof_source *source); bool source_get_underrun(struct sof_source *source); uint32_t source_get_id(struct sof_source *source); @@ -143,7 +45,6 @@ int source_set_channels(struct sof_source *source, unsigned int channels); int source_set_underrun(struct sof_source *source, bool underrun_permitted); int source_set_buffer_fmt(struct sof_source *source, uint32_t buffer_fmt); void source_set_min_available(struct sof_source *source, size_t min_available); -size_t source_get_min_available(struct sof_source *source); /** * initial set of audio parameters, provided in sof_ipc_stream_params diff --git a/src/include/sof/audio/source_api_implementation.h b/src/include/sof/audio/source_api_implementation.h deleted file mode 100644 index 606141c92dfb..000000000000 --- a/src/include/sof/audio/source_api_implementation.h +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2023 Intel Corporation. All rights reserved. - * - */ - -#ifndef __SOF_SOURCE_API_IMPLEMENTATION_H__ -#define __SOF_SOURCE_API_IMPLEMENTATION_H__ - -#include -#include -#include - -/* forward def */ -struct sof_audio_stream_params; - -/** - * this is a definition of internals of source API - * - * this file should be included by the implementations of source API - * - * The clients of stream API should use functions provided in source_api.h ONLY - * - */ - -struct source_ops { - /** - * see comment of source_get_data_available() - */ - size_t (*get_data_available)(struct sof_source *source); - - /** - * see comment of source_get_data_available() - */ - int (*get_data)(struct sof_source *source, size_t req_size, - void const **data_ptr, void const **buffer_start, size_t *buffer_size); - - /** - * see comment of source_release_data() - */ - int (*release_data)(struct sof_source *source, size_t free_size); - - /** - * OPTIONAL: Notification to the source implementation about changes in audio format - * - * Once any of *audio_stream_params elements changes, the implementation of - * source may need to perform some extra operations. - * This callback will be called immediately after any change - * - * @retval 0 if success, negative if new parameteres are not supported - */ - int (*on_audio_format_set)(struct sof_source *source); - - /** - * OPTIONAL - * see source_set_params comments - */ - int (*audio_set_ipc_params)(struct sof_source *source, - struct sof_ipc_stream_params *params, bool force_update); - - /** - * OPTIONAL - * see comment for source_set_alignment_constants - */ - int (*set_alignment_constants)(struct sof_source *source, - const uint32_t byte_align, - const uint32_t frame_align_req); -}; - -/** internals of source API. NOT TO BE MODIFIED OUTSIDE OF source_api_helper.h */ -struct sof_source { - const struct source_ops *ops; - size_t requested_read_frag_size; /** keeps size of data obtained by get_data() */ - size_t num_of_bytes_processed; /** processed bytes counter */ - size_t min_available; /** minimum data available required by the module using - * source - * it is module's IBS as declared in module bind IPC - */ - - struct sof_audio_stream_params *audio_stream_params; -}; - -/** - * Init of the API, must be called before any operation - * - * @param source pointer to the structure - * @param ops pointer to API operations - * @param audio_stream_params pointer to structure with audio parameters - * note that the audio_stream_params must be accessible by the caller core - * the implementation must ensure coherent access to the parameteres - * in case of i.e. cross core shared queue, it must be located in non-cached memory - */ -void source_init(struct sof_source *source, const struct source_ops *ops, - struct sof_audio_stream_params *audio_stream_params); - -#endif /* __SOF_SOURCE_API_IMPLEMENTATION_H__ */ diff --git a/src/include/sof/audio/up_down_mixer/up_down_mixer.h b/src/include/sof/audio/up_down_mixer/up_down_mixer.h index f2d9c2fb893f..3542b6d1acf5 100644 --- a/src/include/sof/audio/up_down_mixer/up_down_mixer.h +++ b/src/include/sof/audio/up_down_mixer/up_down_mixer.h @@ -10,14 +10,11 @@ #include #include -#include #include -#include #include #include #include #include -#include #include #include diff --git a/src/include/sof/common.h b/src/include/sof/common.h index 6a875f5a90f7..5c10ba049716 100644 --- a/src/include/sof/common.h +++ b/src/include/sof/common.h @@ -27,7 +27,6 @@ #if !defined(__ASSEMBLER__) && defined(__XTENSA__) #include -#include #define VERIFY_ALIGN #endif diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt new file mode 100644 index 000000000000..1cdd0d2137a9 --- /dev/null +++ b/src/module/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(audio) diff --git a/src/module/audio/CMakeLists.txt b/src/module/audio/CMakeLists.txt new file mode 100644 index 000000000000..2d805aa68929 --- /dev/null +++ b/src/module/audio/CMakeLists.txt @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause + +is_zephyr(it_is) +if(it_is) ### Zephyr ### + zephyr_library_sources( + source_api.c + sink_api.c + ) +else() ### Not Zephyr ### + add_local_sources(sof + source_api.c + sink_api.c + ) +endif() # Zephyr diff --git a/src/module/audio/sink_api.c b/src/module/audio/sink_api.c new file mode 100644 index 000000000000..cb40405974dc --- /dev/null +++ b/src/module/audio/sink_api.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + +#include +#include + +/* This file contains public sink API functions that were too large to mark is as inline. */ + +int sink_get_buffer(struct sof_sink *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + int ret; + + if (sink->requested_write_frag_size) + return -EBUSY; + + ret = sink->ops->get_buffer(sink, req_size, data_ptr, + buffer_start, buffer_size); + + if (!ret) + sink->requested_write_frag_size = req_size; + return ret; +} + +int sink_commit_buffer(struct sof_sink *sink, size_t commit_size) +{ + int ret; + + /* check if there was a buffer obtained for writing by sink_get_buffer */ + if (!sink->requested_write_frag_size) + return -ENODATA; + + /* limit size of data to be committed to previously obtained size */ + if (commit_size > sink->requested_write_frag_size) + commit_size = sink->requested_write_frag_size; + + ret = sink->ops->commit_buffer(sink, commit_size); + + if (!ret) + sink->requested_write_frag_size = 0; + + sink->num_of_bytes_processed += commit_size; + return ret; +} + +int sink_set_frm_fmt(struct sof_sink *sink, enum sof_ipc_frame frame_fmt) +{ + sink->audio_stream_params->frame_fmt = frame_fmt; + + /* notify the implementation */ + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +size_t sink_get_frame_bytes(struct sof_sink *sink) +{ + return get_frame_bytes(sink_get_frm_fmt(sink), sink_get_channels(sink)); +} + +size_t sink_get_free_frames(struct sof_sink *sink) +{ + return sink_get_free_size(sink) / sink_get_frame_bytes(sink); +} + +int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt) +{ + sink->audio_stream_params->valid_sample_fmt = valid_sample_fmt; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_rate(struct sof_sink *sink, unsigned int rate) +{ + sink->audio_stream_params->rate = rate; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_channels(struct sof_sink *sink, unsigned int channels) +{ + sink->audio_stream_params->channels = channels; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_buffer_fmt(struct sof_sink *sink, uint32_t buffer_fmt) +{ + sink->audio_stream_params->buffer_fmt = buffer_fmt; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_overrun(struct sof_sink *sink, bool overrun_permitted) +{ + sink->audio_stream_params->overrun_permitted = overrun_permitted; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_params(struct sof_sink *sink, struct sof_ipc_stream_params *params, bool force_update) +{ + if (sink->ops->audio_set_ipc_params) + return sink->ops->audio_set_ipc_params(sink, params, force_update); + return 0; +} + +int sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_align, + const uint32_t frame_align_req) +{ + if (sink->ops->set_alignment_constants) + return sink->ops->set_alignment_constants(sink, byte_align, frame_align_req); + return 0; +} diff --git a/src/module/audio/source_api.c b/src/module/audio/source_api.c new file mode 100644 index 000000000000..2f589524621f --- /dev/null +++ b/src/module/audio/source_api.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + */ + + +#include +#include + +/* This file contains public source API functions that were too large to mark is as inline. */ + +int source_get_data(struct sof_source *source, size_t req_size, + void const **data_ptr, void const **buffer_start, size_t *buffer_size) +{ + int ret; + + if (source->requested_read_frag_size) + return -EBUSY; + + ret = source->ops->get_data(source, req_size, data_ptr, buffer_start, buffer_size); + + if (!ret) + source->requested_read_frag_size = req_size; + return ret; +} + +int source_release_data(struct sof_source *source, size_t free_size) +{ + int ret; + + /* Check if anything was obtained before for reading by source_get_data */ + if (!source->requested_read_frag_size) + return -ENODATA; + + /* limit size of data to be freed to previously obtained size */ + if (free_size > source->requested_read_frag_size) + free_size = source->requested_read_frag_size; + + ret = source->ops->release_data(source, free_size); + + if (!ret) + source->requested_read_frag_size = 0; + + source->num_of_bytes_processed += free_size; + return ret; +} + +size_t source_get_frame_bytes(struct sof_source *source) +{ + return get_frame_bytes(source_get_frm_fmt(source), + source_get_channels(source)); +} + +size_t source_get_data_frames_available(struct sof_source *source) +{ + return source_get_data_available(source) / + source_get_frame_bytes(source); +} diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index acc92539a5e6..4db02de6f571 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -8,6 +8,8 @@ cmocka_test(buffer_copy ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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 @@ -30,6 +32,8 @@ cmocka_test(buffer_new ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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 @@ -51,6 +55,8 @@ cmocka_test(buffer_wrap ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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 @@ -72,6 +78,8 @@ cmocka_test(buffer_write ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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 diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index 5eb4d19c3151..866e262f0f0a 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -19,4 +19,6 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ) diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 547cb7be9642..3059f45956ab 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -31,6 +31,8 @@ add_library(audio_for_eq_fir 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 diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index 01aebc99223e..a16016f70044 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -24,6 +24,8 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-stream.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-xrun.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ) target_link_libraries(mixer PRIVATE -lm) diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index c6f67ae89127..73451ba72458 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -18,6 +18,8 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index 13adc77e000c..52f268a908c5 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -13,6 +13,8 @@ if(CONFIG_FORMAT_FLOAT) ${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}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index c8219517c19f..2f27d7cfcd74 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -29,6 +29,8 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -51,6 +53,8 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -73,6 +77,8 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index 46be5bdac073..36c13759be6d 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index f6530bc2b3b0..901bd3c2e4f2 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -28,6 +28,8 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.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 diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index d21819848cd0..921698d04809 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -12,6 +12,8 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c + ${PROJECT_SOURCE_DIR}/src/module/audio/source_api.c + ${PROJECT_SOURCE_DIR}/src/module/audio/sink_api.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index b4d729bada78..563dc6b14622 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -397,6 +397,9 @@ zephyr_library_sources( lib.c ) +# SOF module interface functions +add_subdirectory(../src/module module_unused_install/) + if(CONFIG_ZEPHYR_DP_SCHEDULER) zephyr_library_sources(${SOF_AUDIO_PATH}/dp_queue.c) endif()