Skip to content

Commit 669c5d6

Browse files
committed
Audio: Up_down_mixer: Process with circular wrap
The previous processing function processed entire source and sink circular size. It avoids wrap check but is more inefficient when buffer is larger than period. The return code from sink_commit_buffer() and source_release_data() is ignored to avoid a fail in stream start where first frames count can be zero. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent bfad6f7 commit 669c5d6

1 file changed

Lines changed: 31 additions & 14 deletions

File tree

src/audio/up_down_mixer/up_down_mixer.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -435,40 +435,57 @@ up_down_mixer_process(struct processing_module *mod,
435435
struct comp_dev *dev = mod->dev;
436436

437437
size_t output_frames, input_frames, ret, input_cirbuf_size, output_cirbuf_size;
438-
const uint8_t *input0_pos, *input0_start;
439-
uint8_t *output_pos, *output_start;
438+
const uint8_t *input_pos, *input_start, *input_end;
439+
uint8_t *output_pos, *output_start, *output_end;
440+
int output_frames_without_wrap;
441+
int frames_without_wrap, frames, frames_remain;
442+
uint32_t input_bytes;
440443

441444
comp_dbg(dev, "up_down_mixer_process()");
442445

443446
output_frames = sink_get_free_frames(output_buffers[0]);
444447
input_frames = source_get_data_frames_available(input_buffers[0]);
448+
frames = MIN(input_frames, output_frames);
445449

446450
const size_t output_frame_bytes = sink_get_frame_bytes(output_buffers[0]);
447451

448-
ret = sink_get_buffer(output_buffers[0], output_frames * output_frame_bytes,
452+
ret = sink_get_buffer(output_buffers[0], frames * output_frame_bytes,
449453
(void **)&output_pos, (void **)&output_start, &output_cirbuf_size);
450454
if (ret)
451455
return -ENODATA;
452456

453-
const size_t input0_frame_bytes = source_get_frame_bytes(input_buffers[0]);
457+
const size_t input_frame_bytes = source_get_frame_bytes(input_buffers[0]);
454458

455-
ret = source_get_data(input_buffers[0], input_frames * input0_frame_bytes,
456-
(const void **)&input0_pos, (const void **)&input0_start,
459+
ret = source_get_data(input_buffers[0], frames * input_frame_bytes,
460+
(const void **)&input_pos, (const void **)&input_start,
457461
&input_cirbuf_size);
458462
if (ret) {
459463
sink_commit_buffer(output_buffers[0], 0);
460464
return -ENODATA;
461465
}
462466

463-
cd->mix_routine(cd, (const void *)input0_start, input_cirbuf_size, (void *)output_start);
464-
465-
ret = sink_commit_buffer(output_buffers[0], output_frames * output_frame_bytes);
466-
if (ret)
467-
return ret;
467+
input_end = input_start + input_cirbuf_size;
468+
output_end = output_start + output_cirbuf_size;
469+
frames_remain = frames;
470+
while (frames_remain) {
471+
frames_without_wrap = (input_end - input_pos) / input_frame_bytes;
472+
frames_without_wrap = MIN(frames_without_wrap, frames);
473+
output_frames_without_wrap = (output_end - output_pos) / output_frame_bytes;
474+
frames_without_wrap = MIN(frames_without_wrap, output_frames_without_wrap);
475+
input_bytes = input_frame_bytes * frames_without_wrap;
476+
cd->mix_routine(cd, (const void *)input_pos, input_bytes, (void *)output_pos);
477+
478+
input_pos += input_bytes;
479+
output_pos += frames_without_wrap * output_frame_bytes;
480+
input_pos = (input_pos >= input_end) ? input_pos - input_cirbuf_size : input_pos;
481+
output_pos = (output_pos >= output_end) ?
482+
output_pos - output_cirbuf_size : output_pos;
483+
frames_remain -= frames_without_wrap;
484+
}
468485

469-
ret = source_release_data(input_buffers[0], input_frames * input0_frame_bytes);
470-
if (ret)
471-
return ret;
486+
/* Ignore possible -ENODATA, can happen in start with zero frames to process */
487+
sink_commit_buffer(output_buffers[0], frames * output_frame_bytes);
488+
source_release_data(input_buffers[0], frames * input_frame_bytes);
472489
return 0;
473490
}
474491

0 commit comments

Comments
 (0)