Skip to content

Commit

Permalink
google_rtc_audio_processing: IPC4 workarounds
Browse files Browse the repository at this point in the history
Component stream state management on IPC4 seems to have bugs.  AEC
starts running with the channel count set incorrectly on the upstream
reference buffer, which is a problem not only for AEC but also for (I
think) the copier on the other side which stalls out if this isn't
fixed directly on the source.

Also the alignment constant setter function (which is not purely a
field setter, it turns out) doesn't get called on the connected
buffers, leading to extremely hard to debug overruns at runtime.

None of these objects are or should be under the control of the AEC
component, but it seems like it's responsible for fixing this anyway.
I see similar code sprinkled around other components in the tree
too...

Signed-off-by: Andy Ross <[email protected]>
  • Loading branch information
andyross committed Dec 16, 2023
1 parent 720c38a commit bab124d
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/audio/google/google_rtc_audio_processing.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,31 @@ static int google_rtc_audio_processing_prepare(struct processing_module *mod,
comp_warn(dev, "Too many mic channels: %d, truncating to %d",
mic_chan, CHAN_MAX);

#ifdef CONFIG_IPC_MAJOR_4
/* Bug workaround: IPC4 doesn't correctly initialize metadata
* on (at least) our reference source. Use our
* kconfig-derived value instead, but yell about it. Note
* that we MUST correct this at the source level and not just
* re-interpret it ourselves, otherwise other elements of the
* pipeline get confused.
*/
if (ref_chan != CHAN_MAX) {
comp_err(dev, "Incorrect ref channels %d, setting %d",
ref_chan, CHAN_MAX);
ref_chan = CHAN_MAX;
source_set_channels(sources[cd->aec_reference_source], ref_chan);
}

/* IPC4 also fails to call this function (which isn't merely a
* field set, it recomputes other values that are otherwise
* left as garbage) on our input stream at setup time, leading
* to confusing failures with buffering behavior.
*/
source_set_alignment_constants(sources[0], source_get_frame_bytes(sources[0]), 1);
source_set_alignment_constants(sources[1], source_get_frame_bytes(sources[1]), 1);
sink_set_alignment_constants(sinks[0], sink_get_frame_bytes(sinks[0]), 1);
#endif

if (out_chan != mic_chan) {
comp_err(dev, "Input/output mic channel mismatch");
ret = -EINVAL;
Expand Down

0 comments on commit bab124d

Please sign in to comment.