Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/audio/aria/aria.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,6 @@ static void aria_set_stream_params(struct comp_buffer *buffer,
const struct ipc4_audio_format *audio_fmt = &mod->priv.cfg.base_cfg.audio_fmt;

ipc4_update_buffer_format(buffer, audio_fmt);
#if SOF_USE_HIFI(3, ARIA) || SOF_USE_HIFI(4, ARIA)
audio_stream_set_align(8, 1, &buffer->stream);
#elif SOF_USE_HIFI(5, ARIA)
audio_stream_set_align(16, 1, &buffer->stream);
#endif
}

static int aria_prepare(struct processing_module *mod,
Expand All @@ -195,6 +190,7 @@ static int aria_prepare(struct processing_module *mod,

aria_set_stream_params(source, mod);
aria_set_stream_params(sink, mod);
audio_stream_set_align(SOF_FRAME_BYTE_ALIGN, SOF_FRAME_COUNT_ALIGN, &source->stream);

if (audio_stream_get_valid_fmt(&source->stream) != SOF_IPC_FRAME_S24_4LE ||
audio_stream_get_valid_fmt(&sink->stream) != SOF_IPC_FRAME_S24_4LE) {
Expand Down
2 changes: 1 addition & 1 deletion src/audio/audio_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint3
audio_stream->addr = buff_addr;
audio_stream->end_addr = (char *)audio_stream->addr + size;

audio_stream_set_align(1, 1, audio_stream);
audio_stream_set_align(SOF_FRAME_BYTE_ALIGN, SOF_FRAME_COUNT_ALIGN, audio_stream);
audio_stream_reset(audio_stream);
}
8 changes: 3 additions & 5 deletions src/audio/eq_fir/eq_fir.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,14 +366,12 @@ static int eq_fir_process(struct processing_module *mod,
return 0;
}

static void eq_fir_set_alignment(struct audio_stream *source,
struct audio_stream *sink)
static void eq_fir_set_alignment(struct audio_stream *source)
{
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

eq_fir_set_alignment() still takes a sink parameter but no longer uses it, which can trigger -Wunused-parameter (often treated as an error). Either remove the unused parameter (and adjust callers) or explicitly mark it unused.

Suggested change
{
{
(void)sink;

Copilot uses AI. Check for mistakes.
const uint32_t byte_align = 1;
const uint32_t byte_align = SOF_FRAME_BYTE_ALIGN;
const uint32_t frame_align_req = 2; /* Process multiples of 2 frames */

audio_stream_set_align(byte_align, frame_align_req, source);
audio_stream_set_align(byte_align, frame_align_req, sink);
}

static int eq_fir_prepare(struct processing_module *mod,
Expand Down Expand Up @@ -404,7 +402,7 @@ static int eq_fir_prepare(struct processing_module *mod,
return ret;
}

eq_fir_set_alignment(&sourceb->stream, &sinkb->stream);
eq_fir_set_alignment(&sourceb->stream);
channels = audio_stream_get_channels(&sinkb->stream);
frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream);

Expand Down
2 changes: 1 addition & 1 deletion src/audio/eq_iir/eq_iir.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static int eq_iir_process(struct processing_module *mod,
static void eq_iir_set_alignment(struct audio_stream *source,
struct audio_stream *sink)
{
const uint32_t byte_align = 8;
const uint32_t byte_align = SOF_FRAME_BYTE_ALIGN;
const uint32_t frame_align_req = 2;

audio_stream_set_align(byte_align, frame_align_req, source);
Expand Down
3 changes: 1 addition & 2 deletions src/audio/igo_nr/igo_nr.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,8 +832,7 @@ static int32_t igo_nr_prepare(struct processing_module *mod,
if (ret)
return ret;

source_set_alignment_constants(source, 1, IGO_FRAME_SIZE);
sink_set_alignment_constants(sink, 1, IGO_FRAME_SIZE);
source_set_alignment_constants(source, SOF_FRAME_BYTE_ALIGN, IGO_FRAME_SIZE);

igo_nr_set_igo_params(mod);

Expand Down
17 changes: 10 additions & 7 deletions src/audio/mixer/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,18 @@ static int mixer_reset(struct processing_module *mod)
/* init and calculate the aligned setting for available frames and free frames retrieve*/
static inline void mixer_set_frame_alignment(struct audio_stream *source)
{
#if XCHAL_HAVE_HIFI3 || XCHAL_HAVE_HIFI4

/* Xtensa intrinsics ask for 8-byte aligned. 5.1 format SSE audio
* requires 16-byte aligned.
* requires 16-byte aligned. Note: The SOF_FRAME_BYTE_ALIGN is the
* same value 16 with HiFi5.
*/
const uint32_t byte_align = audio_stream_get_channels(source) == 6 ? 16 : 8;
const uint32_t byte_align = audio_stream_get_channels(source) == 6 ?
MIXER_HIFI_FRAME_BYTE_ALIGN_6CH : SOF_FRAME_BYTE_ALIGN;

/*There is no limit for frame number, so set it as 1*/
const uint32_t frame_align_req = 1;
/* There is no limit for frame number, so set it as default (1). */
const uint32_t frame_align_req = SOF_FRAME_COUNT_ALIGN;

audio_stream_set_align(byte_align, frame_align_req, source);
#endif
}

static int mixer_prepare(struct processing_module *mod,
Expand All @@ -216,7 +216,10 @@ static int mixer_prepare(struct processing_module *mod,
}

Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

mixer_prepare() no longer sets alignment requirements on the sink stream, but mixer_set_frame_alignment() contains special handling for 5.1ch (16-byte) that is likely relevant to the output pointer alignment as well (not just the inputs). If the sink isn’t configured consistently, the sink write pointer can become misaligned over time depending on processed frame counts. Consider applying the same alignment setup to sink->stream (or otherwise ensuring the output alignment requirement is enforced).

Suggested change
mixer_set_frame_alignment(&sink->stream);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't understand how the sink write could become misaligned since it follows the source align with same amount of frames and samples.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added a comment why the sink align constraints are not set.

md->mix_func = mixer_get_processing_function(dev, sink);
mixer_set_frame_alignment(&sink->stream);

/* No need to set sink align constraints, set constraints for each
* source next. The sink align will follow to common source alignment.
*/

/* check each mixer source state */
struct comp_buffer *source;
Expand Down
3 changes: 3 additions & 0 deletions src/audio/mixer/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void sys_comp_module_mixer_interface_init(void);

#define MIXER_MAX_SOURCES 2

/* Xtensa HiFi optimized version needs this for 5.1ch */
#define MIXER_HIFI_FRAME_BYTE_ALIGN_6CH 16

/* mixer component private data */
struct mixer_data {
void (*mix_func)(struct comp_dev *dev, struct audio_stream *sink,
Expand Down
3 changes: 1 addition & 2 deletions src/audio/selector/selector.c
Original file line number Diff line number Diff line change
Expand Up @@ -1007,8 +1007,7 @@ static int selector_prepare(struct processing_module *mod,
sourceb = comp_dev_get_first_data_producer(dev);
sinkb = comp_dev_get_first_data_consumer(dev);

audio_stream_set_align(4, 1, &sourceb->stream);
audio_stream_set_align(4, 1, &sinkb->stream);
audio_stream_set_align(SOF_FRAME_BYTE_ALIGN, SOF_FRAME_COUNT_ALIGN, &sourceb->stream);

/* get source data format and period bytes */
cd->source_format = audio_stream_get_frm_fmt(&sourceb->stream);
Expand Down
7 changes: 3 additions & 4 deletions src/audio/src/src_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,12 @@ int src_copy_sxx(struct comp_data *cd, struct sof_source *source,
return -ENOTSUP;
}

void src_set_alignment(struct sof_source *source, struct sof_sink *sink)
void src_set_alignment(struct sof_source *source)
{
const uint32_t byte_align = 1;
const uint32_t frame_align_req = 1;
const uint32_t byte_align = SOF_FRAME_BYTE_ALIGN;
const uint32_t frame_align_req = SOF_FRAME_COUNT_ALIGN;

source_set_alignment_constants(source, byte_align, frame_align_req);
sink_set_alignment_constants(sink, byte_align, frame_align_req);
}

static int src_verify_params(struct processing_module *mod)
Expand Down
2 changes: 1 addition & 1 deletion src/audio/src/src_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ int32_t src_input_rates(void);

int32_t src_output_rates(void);

void src_set_alignment(struct sof_source *source, struct sof_sink *sink);
void src_set_alignment(struct sof_source *source);

struct comp_data {
#if CONFIG_IPC_MAJOR_4
Expand Down
2 changes: 1 addition & 1 deletion src/audio/src/src_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int src_prepare_general(struct processing_module *mod,
enum sof_ipc_frame sink_format;

/* set align requirements */
src_set_alignment(source, sink);
src_set_alignment(source);

/* get source/sink data format */
source_format = source_get_frm_fmt(source);
Expand Down
2 changes: 1 addition & 1 deletion src/audio/src/src_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int src_prepare_general(struct processing_module *mod,
int ret = 0;

/* set align requirements */
src_set_alignment(source, sink);
src_set_alignment(source);

switch (cd->ipc_config.base.audio_fmt.valid_bit_depth) {
#if CONFIG_FORMAT_S16LE
Expand Down
8 changes: 3 additions & 5 deletions src/audio/tdfb/tdfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,14 +689,12 @@ static int tdfb_process(struct processing_module *mod,
return 0;
}

static void tdfb_set_alignment(struct audio_stream *source,
struct audio_stream *sink)
static void tdfb_set_alignment(struct audio_stream *source)
{
const uint32_t byte_align = 1;
const uint32_t byte_align = SOF_FRAME_BYTE_ALIGN;
const uint32_t frame_align_req = 2; /* Process multiples of 2 frames */

Comment thread
singalsu marked this conversation as resolved.
audio_stream_set_align(byte_align, frame_align_req, source);
audio_stream_set_align(byte_align, frame_align_req, sink);
}

static int tdfb_prepare(struct processing_module *mod,
Expand Down Expand Up @@ -729,7 +727,7 @@ static int tdfb_prepare(struct processing_module *mod,
return ret;
}

tdfb_set_alignment(&sourceb->stream, &sinkb->stream);
tdfb_set_alignment(&sourceb->stream);

frame_fmt = audio_stream_get_frm_fmt(&sourceb->stream);
source_channels = audio_stream_get_channels(&sourceb->stream);
Expand Down
61 changes: 42 additions & 19 deletions src/audio/volume/volume.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -571,12 +572,27 @@ 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. If it rounds to zero
* round it up to smallest nonzero aligned frames count.
*/
frames = audio_stream_align_frames_round_nearest(source, frames);
if (!frames)
frames = audio_stream_align_frames_round_up(source, 1);
} 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;
Expand Down Expand Up @@ -623,30 +639,37 @@ static vol_zc_func vol_get_zc_function(struct comp_dev *dev,
/**
* \brief Set volume frames alignment limit.
* \param[in,out] source Structure pointer of source.
* \param[in,out] sink Structure pointer of sink.
*/
static void volume_set_alignment(struct audio_stream *source,
struct audio_stream *sink)
static void volume_set_alignment(struct audio_stream *source)
Comment thread
singalsu marked this conversation as resolved.
{
/* Both source and sink buffer in HiFi5 processing version,
* xtensa intrinsics ask for 16-byte aligned.
const int channels = audio_stream_get_channels(source);

/* The source buffer in HiFi5 processing version needs 16 bytes alignment. The
* macro SOF_FRAME_BYTE_ALIGN is set in common.h to the requirement align.
* The VOLUME_HIFI3_HIFI4_FRAME_BYTE_ALIGN_6CH also has the value 16 and the
* same align for 5.1 channels works for HiFi5 too.
*
* Both source and sink buffer in HiFi3 or HiFi4 processing version,
* xtensa intrinsics ask for 8-byte aligned. 5.1 format SSE audio
* requires 16-byte aligned.
* In HiFi4 processing version the source align requirement is 8 bytes. While
* the 5.1 format SSE audio requires 16 bytes alignment.
*/
const uint32_t byte_align =
(channels == 6) ? VOLUME_HIFI3_HIFI4_FRAME_BYTE_ALIGN_6CH : SOF_FRAME_BYTE_ALIGN;

/* On HiFi5 the number of samples to process must be multiple of four for s24/s32
* and multiple of eight for s16. For HiFi4 and HiFi3 the number of samples
* need to be multiple of two for s32 and multiple of four for s16.
* E.g. for s32 format for channels counts of 1, 2, 4, 6, ... the
* frame align need to be 4, 2, 1, 2, ...
*/
#if SOF_USE_HIFI(3, VOLUME) || SOF_USE_HIFI(4, VOLUME)
const uint32_t byte_align = audio_stream_get_channels(source) == 6 ?
VOLUME_HIFI3_HIFI4_FRAME_BYTE_ALIGN_6CH : SOF_FRAME_BYTE_ALIGN;
#if SOF_USE_HIFI(5, VOLUME)
const int n = (audio_stream_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 8 : 4;
#else
const uint32_t byte_align = SOF_FRAME_BYTE_ALIGN;
const int n = (audio_stream_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 4 : 2;
#endif

/*There is no limit for frame number, so both source and sink set it to be 1*/
const uint32_t frame_align_req = 1;
const uint32_t frame_align_req = (uint32_t)(n / gcd(n, channels));

audio_stream_set_align(byte_align, frame_align_req, source);
audio_stream_set_align(byte_align, frame_align_req, sink);
}

/**
Expand Down Expand Up @@ -682,7 +705,7 @@ static int volume_prepare(struct processing_module *mod,

ret = volume_peak_prepare(cd, mod);

volume_set_alignment(&sourceb->stream, &sinkb->stream);
volume_set_alignment(&sourceb->stream);

/* get sink period bytes */
sink_period_bytes = audio_stream_period_bytes(&sinkb->stream,
Expand Down
63 changes: 53 additions & 10 deletions src/include/sof/audio/audio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,55 @@ audio_stream_avail_frames(const struct audio_stream *source,
}
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.

nit/typo: "caused by logic int the function" -> "in the function"


/**
* Computes maximum number of frames aligned that can be copied from
* source buffer to sink buffer, verifying number of available source
* frames vs. free space available in sink.
* 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 ROUND_DOWN(frames, 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 = ROUND_DOWN(frames, align);

if (aligned_frames < frames)
aligned_frames += align;
Comment thread
singalsu marked this conversation as resolved.

return aligned_frames;
}

/**
* Rounds to nearest 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 to nearest.
* @return Aligned frame count.
*/
static inline uint32_t audio_stream_align_frames_round_nearest(const struct audio_stream *stream,
uint32_t frames)
{
uint16_t align = stream->runtime_stream_params.align_frame_cnt;

return ROUND_DOWN(frames + (align >> 1), align);
}

/**
* Computes maximum number of frames aligned with source align criteria
* that can be copied from source buffer to sink buffer, verifying number
* of available source frames vs. free space available in sink.
* @param source Buffer of source.
* @param sink Buffer of sink.
* @return Number of frames.
Expand All @@ -602,14 +648,11 @@ static inline uint32_t
audio_stream_avail_frames_aligned(const struct audio_stream *source,
const struct audio_stream *sink)
{
uint32_t src_frames = (audio_stream_get_avail_bytes(source) >>
source->runtime_stream_params.align_shift_idx) *
source->runtime_stream_params.align_frame_cnt;
uint32_t sink_frames = (audio_stream_get_free_bytes(sink) >>
sink->runtime_stream_params.align_shift_idx) *
sink->runtime_stream_params.align_frame_cnt;
uint32_t src_frames = audio_stream_get_avail_frames(source);
uint32_t sink_frames = audio_stream_get_free_frames(sink);
uint32_t n = MIN(src_frames, sink_frames);

return MIN(src_frames, sink_frames);
return audio_stream_align_frames_round_down(source, n);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/include/sof/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@
# define SOF_FRAME_BYTE_ALIGN 4
#endif

/* Default frame-count alignment is 1 */
#define SOF_FRAME_COUNT_ALIGN 1

#ifndef __GLIBC_USE
#define __GLIBC_USE(x) 0
#endif
Expand Down
Loading