From 0f37123985c3b914fbfc46fe2592431c53e5f03b Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Thu, 15 May 2025 19:30:12 +0300 Subject: [PATCH 1/2] Module: Audio: Add s16/32 source_get_data and sink_get_buffer This patch adds helper functions source_get_data_s16(), source_get_data_s32(), sink_get_buffer_s16(), and sink_get_buffer_s32(). The buffer_samples as number of samples simplifies the processing function with no division or shift needed to convert buffer size in bytes to samples. Also the int16_t and int32_t typed arguments for data pointer and buffer start avoid type casts in a typical simple processing function. Signed-off-by: Seppo Ingalsuo --- src/include/module/audio/sink_api.h | 38 +++++++++++++++++++++++++++ src/include/module/audio/source_api.h | 36 +++++++++++++++++++++++++ src/module/audio/sink_api.c | 32 ++++++++++++++++++++++ src/module/audio/source_api.c | 32 ++++++++++++++++++++++ 4 files changed, 138 insertions(+) diff --git a/src/include/module/audio/sink_api.h b/src/include/module/audio/sink_api.h index 98129b229f17..839111abc536 100644 --- a/src/include/module/audio/sink_api.h +++ b/src/include/module/audio/sink_api.h @@ -170,6 +170,44 @@ size_t sink_get_free_frames(struct sof_sink *sink); int sink_get_buffer(struct sof_sink *sink, size_t req_size, void **data_ptr, void **buffer_start, size_t *buffer_size); +/** + * Get a circular buffer to operate on (to write). + * + * Same as sink_get_buffer() except that the size of circular buffer is returned as + * 16 bit samples count. The returned samples count simplifies pointer arithmetic in a + * samples process function. The data pointers are int16_t type. + * + * @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_samples number of s16 samples total in circular buffer + * + * @retval -ENODATA if req_size is bigger than free space + * + */ +int sink_get_buffer_s16(struct sof_sink *sink, size_t req_size, int16_t **data_ptr, + int16_t **buffer_start, int *buffer_samples); + +/** + * Get a circular buffer to operate on (to write). + * + * Same as sink_get_buffer() except that the size of circular buffer is returned as + * 32 bit samples count. The returned samples count simplifies pointer arithmetic in a + * samples process function. The data pointers are int32_t type. + * + * @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_samples number of s32 samples total in circular buffer + * + * @retval -ENODATA if req_size is bigger than free space + * + */ +int sink_get_buffer_s32(struct sof_sink *sink, size_t req_size, int32_t **data_ptr, + int32_t **buffer_start, int *buffer_samples); + /** * Commits that the buffer previously obtained by get_buffer is filled with data * and ready to be used diff --git a/src/include/module/audio/source_api.h b/src/include/module/audio/source_api.h index 0925fb251bd2..cb82cab457f3 100644 --- a/src/include/module/audio/source_api.h +++ b/src/include/module/audio/source_api.h @@ -184,6 +184,42 @@ size_t source_get_data_frames_available(struct sof_source *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); +/** + * Retrieves a fragment of circular data (to read) + * + * Same as source_get_data() except that the size of circular buffer is returned as + * 16 bit samples count. The returned samples count simplifies pointer arithmetic in a + * samples process function. The data pointers are int16_t type. + * + * @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_samples number of 16 bit samples total in circular buffer + * + * @retval -ENODATA if req_size is bigger than available data + */ +int source_get_data_s16(struct sof_source *source, size_t req_size, int16_t const **data_ptr, + int16_t const **buffer_start, int *buffer_samples); + +/** + * Retrieves a fragment of circular data (to read) + * + * Same as source_get_data() except that the size of circular buffer is returned as + * 32 bit samples count. The returned samples count simplifies pointer arithmetic in a + * samples process function. The data pointers are int32_t type. + * + * @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_samples number of 32 bit samples total in circular buffer + * + * @retval -ENODATA if req_size is bigger than available data + */ +int source_get_data_s32(struct sof_source *source, size_t req_size, int32_t const **data_ptr, + int32_t const **buffer_start, int *buffer_samples); + /** * Releases fragment previously obtained by source_get_data() * Once called, the data are no longer available for the caller diff --git a/src/module/audio/sink_api.c b/src/module/audio/sink_api.c index 5ec904d61b2f..c0a94031f105 100644 --- a/src/module/audio/sink_api.c +++ b/src/module/audio/sink_api.c @@ -36,6 +36,38 @@ int sink_get_buffer(struct sof_sink *sink, size_t req_size, } EXPORT_SYMBOL(sink_get_buffer); +int sink_get_buffer_s16(struct sof_sink *sink, size_t req_size, + int16_t **data_ptr, int16_t **buffer_start, int *buffer_samples) +{ + size_t buffer_size; + int ret; + + ret = sink_get_buffer(sink, req_size, (void **)data_ptr, (void **)buffer_start, + &buffer_size); + if (ret) + return ret; + + *buffer_samples = buffer_size >> 1; + return 0; +} +EXPORT_SYMBOL(sink_get_buffer_s16); + +int sink_get_buffer_s32(struct sof_sink *sink, size_t req_size, + int32_t **data_ptr, int32_t **buffer_start, int *buffer_samples) +{ + size_t buffer_size; + int ret; + + ret = sink_get_buffer(sink, req_size, (void **)data_ptr, (void **)buffer_start, + &buffer_size); + if (ret) + return ret; + + *buffer_samples = buffer_size >> 2; + return 0; +} +EXPORT_SYMBOL(sink_get_buffer_s32); + int sink_commit_buffer(struct sof_sink *sink, size_t commit_size) { int ret; diff --git a/src/module/audio/source_api.c b/src/module/audio/source_api.c index b74a6716b344..6ee2c54ed8d3 100644 --- a/src/module/audio/source_api.c +++ b/src/module/audio/source_api.c @@ -35,6 +35,38 @@ int source_get_data(struct sof_source *source, size_t req_size, } EXPORT_SYMBOL(source_get_data); +int source_get_data_s16(struct sof_source *source, size_t req_size, int16_t const **data_ptr, + int16_t const **buffer_start, int *buffer_samples) +{ + size_t buffer_size; + int ret; + + ret = source_get_data(source, req_size, (void const **)data_ptr, + (void const **)buffer_start, &buffer_size); + if (ret) + return ret; + + *buffer_samples = buffer_size >> 1; + return 0; +} +EXPORT_SYMBOL(source_get_data_s16); + +int source_get_data_s32(struct sof_source *source, size_t req_size, int32_t const **data_ptr, + int32_t const **buffer_start, int *buffer_samples) +{ + size_t buffer_size; + int ret; + + ret = source_get_data(source, req_size, (void const **)data_ptr, + (void const **)buffer_start, &buffer_size); + if (ret) + return ret; + + *buffer_samples = buffer_size >> 2; + return 0; +} +EXPORT_SYMBOL(source_get_data_s32); + int source_release_data(struct sof_source *source, size_t free_size) { int ret; From 48f9f0b3e419eeb2cdcacb9a31caf08a232a2e31 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Thu, 15 May 2025 19:51:08 +0300 Subject: [PATCH 2/2] Audio: Template: Use s16/32 versions of source and sink API This patch modifies the template component to use in process functions the source_get_data_s16/32() and sink_get_buffer_s16/32() functions. Signed-off-by: Seppo Ingalsuo --- src/audio/template_comp/template-generic.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/audio/template_comp/template-generic.c b/src/audio/template_comp/template-generic.c index 39617e667b90..d233227786d5 100644 --- a/src/audio/template_comp/template-generic.c +++ b/src/audio/template_comp/template-generic.c @@ -30,9 +30,8 @@ static int template_comp_s16(const struct processing_module *mod, uint32_t frames) { struct template_comp_comp_data *cd = module_get_private_data(mod); - int16_t *x, *x_start, *x_end; + int16_t const *x, *x_start, *x_end; int16_t *y, *y_start, *y_end; - size_t size; int x_size, y_size; int source_samples_without_wrap; int samples_without_wrap; @@ -47,19 +46,15 @@ static int template_comp_s16(const struct processing_module *mod, * control the samples process loop. If the number of bytes requested is not * possible, an error is returned. */ - ret = source_get_data(source, bytes, (void const **)&x, (void const **)&x_start, &size); + ret = source_get_data_s16(source, bytes, &x, &x_start, &x_size); if (ret) return ret; - x_size = size >> 1; /* Bytes to number of s16 samples */ - /* Similarly get pointer to sink data in circular buffer, buffer start and size. */ - ret = sink_get_buffer(sink, bytes, (void **)&y, (void **)&y_start, &size); + ret = sink_get_buffer_s16(sink, bytes, &y, &y_start, &y_size); if (ret) return ret; - y_size = size >> 1; /* Bytes to number of s16 samples */ - /* Set helper pointers to buffer end for wrap check. Then loop until all * samples are processed. */ @@ -122,9 +117,8 @@ static int template_comp_s32(const struct processing_module *mod, uint32_t frames) { struct template_comp_comp_data *cd = module_get_private_data(mod); - int32_t *x, *x_start, *x_end; + int32_t const *x, *x_start, *x_end; int32_t *y, *y_start, *y_end; - size_t size; int x_size, y_size; int source_samples_without_wrap; int samples_without_wrap; @@ -139,19 +133,15 @@ static int template_comp_s32(const struct processing_module *mod, * control the samples process loop. If the number of bytes requested is not * possible, an error is returned. */ - ret = source_get_data(source, bytes, (void const **)&x, (void const **)&x_start, &size); + ret = source_get_data_s32(source, bytes, &x, &x_start, &x_size); if (ret) return ret; - x_size = size >> 2; /* Bytes to number of s32 samples */ - /* Similarly get pointer to sink data in circular buffer, buffer start and size. */ - ret = sink_get_buffer(sink, bytes, (void **)&y, (void **)&y_start, &size); + ret = sink_get_buffer_s32(sink, bytes, &y, &y_start, &y_size); if (ret) return ret; - y_size = size >> 2; /* Bytes to number of s32 samples */ - /* Set helper pointers to buffer end for wrap check. Then loop until all * samples are processed. */