From 263f85e9f57f5a613cc10c889755ee0be7a7a94b Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Wed, 15 Apr 2026 14:10:22 +0300 Subject: [PATCH 1/2] Audio: Audio Stream: Add function to calculate aligned number of frames This patch adds to audio_stream.h inline functions: - audio_stream_align_frames_round_down() - audio_stream_align_frames_round_up() They are useful when an algorithm needs to process a number of frames that is smaller then data size than offered by module API. E.g. when volume component ramps the volume, the block with same gain is smaller than a normal processing period. Signed-off-by: Seppo Ingalsuo --- src/include/sof/audio/audio_stream.h | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 9703ec9cadea..e6ed374f404f 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -612,6 +612,38 @@ audio_stream_avail_frames_aligned(const struct audio_stream *source, return MIN(src_frames, sink_frames); } +/** + * Rounds down a frame count to meet the alignment constraint of the stream. + * @param stream Audio stream with alignment requirements set. + * @param frames Frame count to round down. + * @return Largest aligned frame count less than or equal to frames. + */ +static inline uint32_t audio_stream_align_frames_round_down(const struct audio_stream *stream, + uint32_t frames) +{ + uint16_t align = stream->runtime_stream_params.align_frame_cnt; + + return (frames / align) * align; +} + +/** + * Rounds up a frame count to meet the alignment constraint of the stream. + * @param stream Audio stream with alignment requirements set. + * @param frames Frame count to round up. + * @return Smallest aligned frame count greater than or equal to frames. + */ +static inline uint32_t audio_stream_align_frames_round_up(const struct audio_stream *stream, + uint32_t frames) +{ + uint16_t align = stream->runtime_stream_params.align_frame_cnt; + uint32_t aligned_frames = (frames / align) * align; + + if (aligned_frames < frames) + aligned_frames += align; + + return aligned_frames; +} + /** * Updates the buffer state after writing to the buffer. * @param buffer Buffer to update. From f4a3c0cf70b553c23f33a7a61829fcd0dcac2587 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Wed, 15 Apr 2026 14:31:42 +0300 Subject: [PATCH 2/2] Audio: Volume: Fix the ramping and ZC mode align This patch fixes an issue where processing smaller parts of the period can break the data align constraints. The frames count value from zc_get() function or from cd->vol_ramp_frames is rounded up to next align compatible frames count. The failure with align constraints appeared as glitches in audio with some 44.1 kHz family sample rates. Signed-off-by: Seppo Ingalsuo --- src/audio/volume/volume.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index aed356a3ec83..4a4ab881ce8e 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -556,6 +556,7 @@ static int volume_process(struct processing_module *mod, struct output_stream_buffer *output_buffers, int num_output_buffers) { struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = input_buffers[0].data; uint32_t avail_frames = input_buffers[0].size; uint32_t frames; int64_t prev_sum = 0; @@ -571,12 +572,23 @@ static int volume_process(struct processing_module *mod, frames = avail_frames; } else if (cd->ramp_type == SOF_VOLUME_LINEAR_ZC) { /* with ZC ramping look for next ZC offset */ - frames = cd->zc_get(input_buffers[0].data, cd->vol_ramp_frames, &prev_sum); + frames = cd->zc_get(source, cd->vol_ramp_frames, &prev_sum); + /* Align frames count to audio stream constraints */ + frames = audio_stream_align_frames_round_up(source, frames); } else { - /* without ZC process max ramp chunk */ - frames = cd->vol_ramp_frames; + /* During volume ramp align the number of frames used in this + * gain step. Align up since with low rates this would typically + * become zero. + */ + frames = audio_stream_align_frames_round_up(source, cd->vol_ramp_frames); } + /* Cancel the gain step for ZC or smaller ramp step if it exceeds + * the available frames. + */ + if (frames > avail_frames) + frames = avail_frames; + if (!cd->ramp_finished) { volume_ramp(mod); cd->vol_ramp_elapsed_frames += frames;