-
Notifications
You must be signed in to change notification settings - Fork 349
Audio: aec: optimize acoustic echo cancellation processing #8877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Audio: aec: optimize acoustic echo cancellation processing #8877
Conversation
lyakh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks wrong to me
| float **ref_ptr = cd->aec_reference_buffer_ptrs; | ||
|
|
||
| while (ref != ref_end) | ||
| *ref_ptr++ = convert_int16_to_float(ref++); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks very different from what it was, and it looks wrong to me. convert_int16_to_float() is now called for a pointer, and the LHS *ref_ptr = ... now does a pointer assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was a good catch.
The LHS code snippet calls convert_int16_to_float(ref[channel]) for each channel and stores the result in cd->aec_reference_buffer_ptrs[channel][i]. This suggests that convert_int16_to_float() is a function that accepts an int16_t and returns a float value.
In the RHS code snippet,convert_int16_to_float(ref++)is called in a loop, with the result assigned to *ref_ptr++. This implies that convert_int16_to_float() is a function that accepts a pointer to int16_t and returns a pointer to float. This is a considerable deviation from the LHS code snippet and may cause problems if convert_int16_to_float() is not intended to handle pointers.
Furthermore, in the RHS code snippet, *ref_ptr++ = convert_int16_to_float(ref++); does a pointer assignment, which implies it changes the position of ref_ptr rather than the value it points to. This could be troublesome if ref_ptr is meant to point to a specific memory address.
I'II fix it.
Thank you.
1fee8c6 to
7ab7496
Compare
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@singalsu @cujomalainey pls review.
| */ | ||
| // Optimization:Reduce cycle waste by streamlining the inner loop, | ||
| // converting from array indexing to pointer arithmetic, | ||
| // and putting data copy verification outside the loop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C style.
| while (ref != ref_end) { | ||
| if (ref && (void *)ref >= (void *)ref_buf_start && | ||
| (void *)ref < (void *)ref_buf_end) { | ||
| *ref_buf++ = *ref++; | ||
| } else { | ||
| // ref does not point to valid int16_t data | ||
| return -2; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wont it be better to work out start and end for both buffers and then memcpy ? This should also have a comment on what we are doing. i.e. why we copy from A to B.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope memcpy_s is ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it should be - I think @singalsu and @andrula-song have used it elsewhere in modules and IIUC it can take advantage of HiFi memcpy for better MCPS.
| int16_t *const dest) | ||
| { | ||
| if (!state || !src || !dest || !state->aec_reference) | ||
| return -1; // Return an error code if any of the pointers are null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets have proper errno codes for all negative error numbers. Most of these are passed up the stack and could result in confusion if we are passing wrong codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will include the proper error code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - please have a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and some lines below still -1 in use. @thesofproject/google 's comments would be useful for error codes from mockup. If the real library uses similar, returning them would be better if the error code macros are possible to share in this public open-source version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The internal library does not have error code. 0 means success any negative value mean error.
33fcded to
6ec3be3
Compare
| const int16_t *ref_end = ref + cd->num_frames * cd->num_aec_reference_channels; | ||
|
|
||
| if ((void *)ref_end >= (void *)ref_buf_end) | ||
| ref_end = (void *)ref_buf_start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ref_buf_end? Also, please don't type-cast to non-const types const pointers. I'd do
if ((const int8_t *)ref_end > ref_buf_end)
ref_end = (const int16_t *)ref_buf_end;
| for (s_chan = 0; s_chan < cd->num_aec_reference_channels; ++s_chan) { | ||
| /* Check that ref is within the valid range of the ref_buf buffer */ | ||
| if (ref && (void *)ref >= (void *)ref_buf_start && | ||
| (void *)ref < (void *)ref_buf_end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to check ref for NULL at all. You anyway check, that it's in a range
| int16_t *ref_buf = cd->aec_reference_buffer; | ||
|
|
||
| /* Check that ref is within the valid range of the ref_buf buffer */ | ||
| if (ref && (void *)ref >= (void *)ref_buf_start && (void *)ref < (void *)ref_buf_end) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, and please use proper types for comparison type-casts
|
|
||
| if (memcpy_s(ref_buf, num_bytes, ref, num_bytes) != 0) { | ||
| /* Handle error */ | ||
| return -2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is a -2?
| const int16_t *src_end = src + cd->num_frames * cd->config.output_fmt.channels_count; | ||
|
|
||
| if ((void *)src_end >= (void *)src_buf_end) | ||
| src_end = (void *)src_buf_start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
types and end
| while (src != src_end) { | ||
| /* Check if src has exceeded the buffer end */ | ||
| if ((void *)src >= (void *)src_buf_end) | ||
| src = (void *)src_buf_start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please, fix types everywhere
| int16_t *dst_end = dst + cd->num_frames * cd->config.output_fmt.channels_count; | ||
|
|
||
| if ((void *)dst_end >= (void *)dst_buf_end) | ||
| dst_end = (void *)dst_buf_start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
end
| cd->process_buffer_ptrs[channel][i]); | ||
| float **proc_ptr = cd->process_buffer_ptrs; | ||
|
|
||
| while (dst != dst_end && *proc_ptr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for loops would fit better here since you need to step your pointers
6ec3be3 to
cfd021f
Compare
cfd021f to
e71095c
Compare
ShriramShastry
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing the code,; I have made the changes based on the review comments.
|
@thesofproject/google pls review. Thanks ! |
| int16_t *const dest) | ||
| { | ||
| if (!state || !src || !dest || !state->aec_reference) | ||
| return -1; // Return an error code if any of the pointers are null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and some lines below still -1 in use. @thesofproject/google 's comments would be useful for error codes from mockup. If the real library uses similar, returning them would be better if the error code macros are possible to share in this public open-source version.
| #define ERR_INVALID_REF -1 | ||
| #define ERR_MEMCPY_FAIL -2 | ||
| #define ERR_INVALID_SRC -3 | ||
| #define ERR_INVALID_DST -4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use typically -EINVAL or -ENOMEM depending on the case and text description of issue, so not sure if this detail level is needed. They might also cause confusion with errno.h values 1- 4 when reported back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ShriramShastry NAK, this file as well as most of the SOF use POSIX error codes, please don't invent any new ones and mix them with existing ones.
| for (i = 0; i < cd->num_frames; ++i) { | ||
| for (s_chan = 0; s_chan < cd->num_aec_reference_channels; ++s_chan) { | ||
| /* Check that ref is within the valid range of the ref_buf buffer */ | ||
| if ((int16_t const *)ref >= ref_buf_start && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what condition could the else happen? Can this check be done before the loop with known num_frames and num reference channels and o ther information?
| /* If it does, wrap the reference buffer end pointer back to the start | ||
| * of the buffer | ||
| */ | ||
| ref_end = (const int16_t *)ref_buf_start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would something like ref_data_end be a better name? I was first confusing this with ref_buf_end.
| ref += cd->num_aec_reference_channels; | ||
| if ((void *)ref >= (void *)ref_buf_end) | ||
| ref = (void *)ref_buf_start; | ||
| if (memcpy_s(ref_buf, num_bytes, ref, num_bytes) != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not use mempcy_s() in hot code parts. There's num_bytes in both source and dest size so memcpy_s() never will return error. This seems to apply for all memcpy_s() usages in this patch.
| const int16_t *src_end = src + cd->num_frames * cd->config.output_fmt.channels_count; | ||
|
|
||
| /* Check if the calculated end of the source buffer exceeds the actual end of the buffer */ | ||
| if (src_end >= (const int16_t *)src_buf_end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's quite many of these pointer check and wrap code lines. An inline function or macro (ternary?) would make cleaner looking code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
E.g. cir_buf_wrap() from audio_stream.h.
|
@ShriramShastry could you please explain in simple terms what exactly you're trying to optimise in this PR - which algorithms you find non-optimal, how you replace them, and - very importantly - how you test the result? Can you provide a single simple example like "I take this kind of a loop and replace it with this and this brings X% performance gain?" |
e71095c to
7d2d12d
Compare
|
Sorry but google is going to NACK this until we at least get a release and stabilize this component first |
b612915 to
7c91c4e
Compare
Pushing it out to v2.10 to allow stabilization, baseline MCPS measurements and alignment. |
singalsu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check these please.
| int16_t *dst; | ||
| int8_t *dst_buf_start; | ||
| int8_t *dst_buf_end; | ||
| size_t dst_buf_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add to commit message how much is MCPS performance is before and after (assuming stub library) in some platform you tested , or at least some cycles reduce % with some simulator core config. The optimization seems to cover both IPC3 and IPC4 parts. For IPC3 the relevant platform is e.g. TGL (or ADL - but in this context same), and for IPC4 MTL.
| cd->aec_reference_buffer[buffer_offset++] = ref[channel]; | ||
| #endif /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ | ||
| int16_t *ref_buf = cd->aec_reference_buffer; | ||
| size_t sizeofrefbuffer = sizeof(cd->aec_reference_buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used only one, could use this directly later (if correct code, looks suspicious). This would be size of of the content of the pointer, a single float or int16.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you are correct about the problem with size_t sizeofrefbuffer = sizeof(cd->aec_reference_buffer); because in C, the sizeof operator returns the size of the variable's type rather than the buffer it points to. If sizeofrefbuffer is expected to represent the buffer's size, it may cause incorrect behavior. sizeof cannot be used to calculate the size of cd->aec_reference_buffer if it is a dynamically allocated array because it must be tracked separately when created. sizeof can be used to determine the size of a statically allocated array, but only in the scope where the array is defined, not on a pointer to the array. As a result, I feel the goal is to determine the size of the buffer cd->aec_reference_buffer. I'II fix bug.
Thank you
| ref += cd->num_aec_reference_channels; | ||
| if ((void *)ref >= (void *)ref_buf_end) | ||
| ref = (void *)ref_buf_start; | ||
| if (num_bytes > sizeofrefbuffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this now comparing num_bytes to sizeof(int16_t)?
| const int16_t *src_end = src + cd->num_frames * cd->config.output_fmt.channels_count; | ||
|
|
||
| /* Check if the calculated end of the source buffer exceeds the actual end of the buffer */ | ||
| src_end = (int16_t *)cir_buf_wrap((void *)src_end, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont' think cir_buf_wrap needs type casts for input arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the following warning.
[14/33] Building C object modules/sof/CMakeFiles/modules_sof...f_aec/sof/src/audio/google/google_rtc_audio_processing.c.obj
/home/shastry/work/sof/sof_aec/sof/src/audio/google/google_rtc_audio_processing.c:952:25: warning: passing 'const int16_t * ' (aka 'const short *') to parameter of type 'void *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers ]
src_end = cir_buf_wrap(src_end, src_buf_start, src_buf_end);
And so on for all of the cir_buf_wrap() calls in the code.
To address these warnings, we could change the cir_buf_wrap function to accept const void * parameters instead. The cir_buf_wrap_const() change allows to pass const pointers to the function without discarding the const qualifier.
| /* If the source pointer has reached or exceeded the end of the source | ||
| * buffer, wrap it back to the start | ||
| */ | ||
| src = (int16_t *)cir_buf_wrap((void *)src, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, no type casts for arguments needed?
| /* If we haven't filled the buffer yet, copy the data */ | ||
| if (cd->raw_mic_buffer_frame_index < cd->num_frames) { | ||
| size_t num_bytes = sizeof(int16_t) * cd->num_capture_channels; | ||
| size_t buffer_size = sizeof(cd->raw_mic_buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct, this would be size of a single sample?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original code calculates the total size of the memory block pointed to by cd->raw_mic_buffer using cd->num_frames * cd->num_capture_channels * sizeof(cd->raw_mic_buffer[0]). To calculate the memory block's total size in bytes, multiply the total number of frames by the number of samples per frame and the size of a single sample.
Modified code: The line size_t buffer_size = sizeof(cd->raw_mic_buffer); calculates the size of the pointer cd->raw_mic_buffer, not the entire memory block it points to. The sizeof operator returns the _pointer's size_ rather than the _memory block_ to which it points.
Yes, your right -this a Bug, I'II fix it.
| size_t buffer_size = sizeof(cd->raw_mic_buffer); | ||
| size_t frame_index = cd->raw_mic_buffer_frame_index; | ||
| size_t buffer_used = frame_index * sizeof(int16_t); | ||
| size_t buffer_remaining = buffer_size - buffer_used; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can combine these equations and eliminate variables those are not used later in this inner loop.
Thanks :) just remember, premature optimization is the root of all evil |
7c91c4e to
05745bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for reviewing the code. I 've included the modification, please have a look.
| float **proc_ptr = cd->process_buffer_ptrs; | ||
|
|
||
| /* Check for null pointers and buffer overflows */ | ||
| if (!dst || !proc_ptr || dst >= dst_end || *proc_ptr >= *proc_ptr + cd->num_frames) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cir_buf_wrap function wraps circular buffers if a pointer goes beyond the buffer's end. It determines dst_end by determining the number of frames and channels. If dst >= dst_end, it means all data has been processed. However, the condition *proc_ptr >= *proc_ptr + cd->num_frames is always false, I would like your opinion and may need to be altered for safety.
| size_t num_bytes = (ref_data_end - ref) * sizeof(*ref); | ||
|
|
||
| ref += cd->num_aec_reference_channels; | ||
| if ((void *)ref >= (void *)ref_buf_end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changed code does not explicitly include the logic for incrementing the ref pointer by cd->num_aec_reference_channels and verifying if ref has reached or surpassed ref_buf_end.
However, the changed code retains similar reasoning in a new way. The changed code's line ref = ref_data_end; essentially shifts the ref pointer to the end of the most recently processed data. In the original code, cd->num_aec_reference_channels was used to increment ref.
The original code's check if ((void *)ref >= (void *)ref_buf_end) is used to return the ref pointer to the buffer's beginning if it has reached or beyond the end. In the changed code, the cir_buf_wrap function calculates src_end.
| /* 32float: de-interlace ref buffer, convert it to float, skip channels if > Max | ||
| * 16int: linearize buffer, skip channels if > Max | ||
| */ | ||
| /* Reduce cycle waste by streamlining the inner loop, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I keep the comment here and add in commit message. Hope it is ok.
| assert(!ret); | ||
| src_buf_end = src_buf_start + src_buf_size; | ||
|
|
||
| /* The second optimization eliminates the inner loop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I'II add in the commit message, and keep the comment.
fdf5826 to
a3376f3
Compare
09cd6df to
2822725
Compare
This check-in proposal enhances the audio Echo Cancellation AEC) implementation. The enhancements seek to enhance loop designs and memory copy operations, reducing cycle consumption. When pointer arithmetic is substituted for array indexing, it expedites performance and enhances data processing. To maximize efficiency, data copy verification is done outside of the loop, and performance is increased by using pointer arithmetic instead of inner loops. Error management is included when the size of the destination buffer is exceeded by the source data. Before converting or copying data, the pointers "ref," "src," and "dst" are verified to be inside the valid range of "ref_buf," "src_buf," and "dst_buf." These changes improve the code's robustness and efficiency by adding the necessary error checks. Signed-off-by: shastry <malladi.sastry@intel.com>
2822725 to
476dd43
Compare
ShriramShastry
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for reviewing the code; I've included your suggestions, and please take a look.
Thank you.
| cd->aec_reference_buffer[buffer_offset++] = ref[channel]; | ||
| #endif /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ | ||
| int16_t *ref_buf = cd->aec_reference_buffer; | ||
| size_t sizeofrefbuffer = sizeof(cd->aec_reference_buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you are correct about the problem with size_t sizeofrefbuffer = sizeof(cd->aec_reference_buffer); because in C, the sizeof operator returns the size of the variable's type rather than the buffer it points to. If sizeofrefbuffer is expected to represent the buffer's size, it may cause incorrect behavior. sizeof cannot be used to calculate the size of cd->aec_reference_buffer if it is a dynamically allocated array because it must be tracked separately when created. sizeof can be used to determine the size of a statically allocated array, but only in the scope where the array is defined, not on a pointer to the array. As a result, I feel the goal is to determine the size of the buffer cd->aec_reference_buffer. I'II fix bug.
Thank you
| /* If we haven't filled the buffer yet, copy the data */ | ||
| if (cd->raw_mic_buffer_frame_index < cd->num_frames) { | ||
| size_t num_bytes = sizeof(int16_t) * cd->num_capture_channels; | ||
| size_t buffer_size = sizeof(cd->raw_mic_buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original code calculates the total size of the memory block pointed to by cd->raw_mic_buffer using cd->num_frames * cd->num_capture_channels * sizeof(cd->raw_mic_buffer[0]). To calculate the memory block's total size in bytes, multiply the total number of frames by the number of samples per frame and the size of a single sample.
Modified code: The line size_t buffer_size = sizeof(cd->raw_mic_buffer); calculates the size of the pointer cd->raw_mic_buffer, not the entire memory block it points to. The sizeof operator returns the _pointer's size_ rather than the _memory block_ to which it points.
Yes, your right -this a Bug, I'II fix it.
| const int16_t *src_end = src + cd->num_frames * cd->config.output_fmt.channels_count; | ||
|
|
||
| /* Check if the calculated end of the source buffer exceeds the actual end of the buffer */ | ||
| src_end = (int16_t *)cir_buf_wrap((void *)src_end, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the following warning.
[14/33] Building C object modules/sof/CMakeFiles/modules_sof...f_aec/sof/src/audio/google/google_rtc_audio_processing.c.obj
/home/shastry/work/sof/sof_aec/sof/src/audio/google/google_rtc_audio_processing.c:952:25: warning: passing 'const int16_t * ' (aka 'const short *') to parameter of type 'void *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers ]
src_end = cir_buf_wrap(src_end, src_buf_start, src_buf_end);
And so on for all of the cir_buf_wrap() calls in the code.
To address these warnings, we could change the cir_buf_wrap function to accept const void * parameters instead. The cir_buf_wrap_const() change allows to pass const pointers to the function without discarding the const qualifier.
@cujomalainey , Do you have any progress ? |
#8919 is still blocked |
| /* Function prototype for google_rtc_safe_memcpy */ | ||
| int google_rtc_safe_memcpy(struct google_rtc_audio_processing_comp_data *cd, int16_t *dst, | ||
| int16_t *src, size_t num_bytes, size_t buffer_size, | ||
| size_t frame_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this prototype makes no sense here. Either please make the function static or declare it in a header - if it needs to be called from other files.
|
|
||
| /* Copy the source data to the destination buffer */ | ||
| buffer_start += offset; | ||
| memcpy(buffer_start, src, num_bytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about just memcpy(dst + offset,...)
| /* Free the old buffer if it exists */ | ||
| if (cd->aec_reference_buffer) { | ||
| free(cd->aec_reference_buffer); | ||
| cd->aec_reference_buffer = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant, it's overwritten 4 lines later
| size_t number_of_elements = cd->num_frames * cd->num_aec_reference_channels; | ||
|
|
||
| /* Free the old buffer if it exists */ | ||
| if (cd->aec_reference_buffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant, freeing NULL should be ok
|
|
||
| /* Free the old buffer if it exists */ | ||
| if (cd->aec_reference_buffer) { | ||
| free(cd->aec_reference_buffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this function? Are you calling Zephyr libc free()? Is this what is needed here?
| } | ||
|
|
||
| /* Allocate the new buffer */ | ||
| cd->aec_reference_buffer = malloc(number_of_elements * sizeof(int16_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
malloc()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memory allocation inside processing? I'll stop here.
|
Release reminder - one week to v2.11-rc1. |
This check-in introduces performance optimization modifications to the audio Echo Cancellation (AEC) implementation. The enhancements primarily focus on refining loop structures and memory copy operations to ensure more efficient use of cycles.