Skip to content

module: volume: Rework module to use sink/source api#10959

Open
softwarecki wants to merge 8 commits into
thesofproject:mainfrom
softwarecki:p20-volume
Open

module: volume: Rework module to use sink/source api#10959
softwarecki wants to merge 8 commits into
thesofproject:mainfrom
softwarecki:p20-volume

Conversation

@softwarecki

@softwarecki softwarecki commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Rework the volume to only use the sink/source api to prepare sof for the full transition to pipeline 2.0.

Add a new header file panic.h that defines an assert() macro for runtime
assertions. This macro is used by inline static functions in module api
header files.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Add two inline utility functions for calculating the number of samples to
the end of a circular buffer:
cir_buf_samples_to_wrap_s16() for 16-bit samples and
cir_buf_samples_to_wrap_s32() for 32-bit samples.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Introduce two new structures cir_buf_source and cir_buf_sink.
The cir_buf_source structure provides a read-only view of source data in a
circular buffer, with const pointers. The cir_buf_sink structure provides a
writable view of sink data in a circular buffer. Both structures include
pointers for buffer start, end, and current position.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Introduce functions to calculate aligned frames for sink and source api.
Add sink_get_free_frames_aligned() to compute free aligned frames in a
sink. Add source_get_aligned_frames_available() to compute aligned
available frames in a source. Add source_sink_avail_frames_aligned to
determine the maximum number of aligned frames that can be processed
between a source and a sink.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Move circular buffer helper functions cir_buf_samples_without_wrap_s32()
and cir_buf_wrap() to a public module api header. Introduce a new
cir_buf_samples_without_wrap_s16() variant that returns the number of
samples without buffer wrap for s16 data.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
…dling

Introduce cir_buf_bytes_without_wrap_rewind() to calculate the number of
bytes to rewind in a circular buffer from the current pointer to the
buffer start. This function ensures proper handling of backward reads.

Add cir_buf_rewind_wrap() to verify and adjust pointers when rewinding
past the start of a circular buffer. This function wraps the pointer to
the buffer's end if necessary, ensuring correct behavior.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Add source_align_frames_round_up() and source_align_frames_round_nearest()
helpers based on existing audio_stream_* alignment utilities, adapting them
to operate on source api.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Rework the volume module to only use the sink/source api to prepare sof for
the full transition to pipeline 2.0.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the volume processing module to use the sink/source API (buffer acquire/commit via sof_source / sof_sink) rather than the legacy input/output stream buffer API, as a step toward the pipeline 2.0 transition.

Changes:

  • Update volume processing entrypoints to acquire source/sink buffers once per period and commit via sink/source APIs.
  • Rework volume DSP backends (generic + HiFi3/4/5, with and without peakvol) to operate on circular-buffer “views” instead of stream buffer structs.
  • Add/adjust sink/source alignment helpers and circular buffer utilities to support the new processing flow.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/cmocka/src/audio/volume/volume_process.c Adjust unit test harness to call volume processing via circular-buffer views and initialize channel count.
src/include/sof/audio/sink_source_utils.h Add helper to compute aligned available frames across source+sink.
src/include/sof/audio/audio_stream.h Remove some circular-buffer helper inlines from SOF audio_stream header.
src/include/module/audio/source_api.h Add aligned-frames helpers and frame-rounding helpers for sources.
src/include/module/audio/sink_api.h Add aligned free-frames helper for sinks.
src/include/module/audio/audio_stream.h Add circular buffer view structs and wrap/rewind/sample helper inlines for module-facing code.
src/audio/volume/volume.h Change processing function typedefs to accept circular-buffer views and pass channel count explicitly for ZC.
src/audio/volume/volume.c Rework prepare/process to use sink/source APIs and new alignment helpers; update ZC logic to use views.
src/audio/volume/volume_hifi5.c Update HiFi5 backend to process via circular-buffer views.
src/audio/volume/volume_hifi5_with_peakvol.c Update HiFi5+peakvol backend to process via circular-buffer views.
src/audio/volume/volume_hifi4.c Update HiFi4 backend to process via circular-buffer views.
src/audio/volume/volume_hifi4_with_peakvol.c Update HiFi4+peakvol backend to process via circular-buffer views.
src/audio/volume/volume_hifi3.c Update HiFi3 backend to process via circular-buffer views.
src/audio/volume/volume_hifi3_with_peakvol.c Update HiFi3+peakvol backend to process via circular-buffer views.
src/audio/volume/volume_generic.c Update generic backend to process via circular-buffer views.
src/audio/volume/volume_generic_with_peakvol.c Update generic+peakvol backend to process via circular-buffer views.
lmdk/include/rtos/panic.h Add LMKD-specific panic/assert header to satisfy new module-header dependency on <rtos/panic.h>.

Comment on lines +51 to +55
static inline size_t source_sink_avail_frames_aligned(struct sof_source *source,
struct sof_sink *sink)
{
return MIN(source_get_aligned_frames_available(source), sink_get_free_frames_aligned(sink));
}
Comment on lines +348 to +352
return frames;

aligned_frames = ROUND_DOWN(frames, align);
if (aligned_frames < frames)
aligned_frames += align;
Comment on lines +360 to +365

if (!align)
return frames;

return ROUND_DOWN(frames + (align >> 1), align);
}
Comment thread src/audio/volume/volume.c
Comment on lines +755 to 758
if (sink_get_free_size(sinks[0]) < sink_period_bytes) {
comp_err(dev, "sink buffer size %d is insufficient < %d",
audio_stream_get_size(&sinkb->stream), sink_period_bytes);
sink_get_free_size(sinks[0]), sink_period_bytes);
ret = -ENOMEM;
Comment thread lmdk/include/rtos/panic.h
Comment on lines +15 to +17
/* runtime assertion */
#define assert(x) do {if (!(x)) while (1);} while (0)

*/
struct cir_buf_sink {
void *buf_start; /**< Start address of the circular buffer. */
void *buf_end; /**< End address of the circular buffer. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the above two be const too? They shouldn't be used for writing, only the ptr below?

/**
* @brief Calculates numbers of s16 samples to buffer wrap when reading stream
* backwards from current sample pointed by ptr towards begin.
* @param ptr Read or write pointer og circular buffer.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"of"

{
int to_end = (const int16_t *)buf_end - (const int16_t *)ptr;

assert((intptr_t)buf_end >= (intptr_t)ptr);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert() only works in debug builds, is that enough or should this be checked always?

*/
static inline int cir_buf_bytes_without_wrap_rewind(const void *ptr, const void *buf_start)
{
assert((intptr_t)ptr >= (intptr_t)buf_start);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void * cannot be compared directly?


assert((intptr_t)ptr >= (intptr_t)buf_start);

return (void *)ptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ouch. no. we should never ("almost never") drop const

uint16_t align = source->audio_stream_params->align_frame_cnt;
uint32_t aligned_frames;

if (!align)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align <= 1


aligned_frames = ROUND_DOWN(frames, align);
if (aligned_frames < frames)
aligned_frames += align;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about ROUND_UP()?

ae_f16x4 *out = (ae_f16x4 *)audio_stream_wrap(sink, (char *)audio_stream_get_wptr(sink)
+ bsink->size);
const int channels_count = audio_stream_get_channels(sink);
ae_f16x4 *in = (void *)source->ptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const? maybe also check the rest of in pointers - this one just occurred to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants