Skip to content

Conversation

@ShriramShastry
Copy link
Contributor

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.

Copy link
Collaborator

@lyakh lyakh left a 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++);
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from 1fee8c6 to 7ab7496 Compare February 23, 2024 07:46
@ShriramShastry ShriramShastry marked this pull request as ready for review February 23, 2024 09:09
@ShriramShastry ShriramShastry requested a review from a team as a code owner February 23, 2024 09:09
Copy link
Member

@lgirdwood lgirdwood left a 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.
Copy link
Member

Choose a reason for hiding this comment

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

C style.

Comment on lines 853 to 878
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;
}
Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Collaborator

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.

Copy link
Contributor

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.

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch 6 times, most recently from 33fcded to 6ec3be3 Compare February 26, 2024 07:30
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;
Copy link
Collaborator

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)
Copy link
Collaborator

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) {
Copy link
Collaborator

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;
Copy link
Collaborator

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;
Copy link
Collaborator

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;
Copy link
Collaborator

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;
Copy link
Collaborator

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)
Copy link
Collaborator

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

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from 6ec3be3 to cfd021f Compare February 26, 2024 11:33
@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from cfd021f to e71095c Compare February 26, 2024 12:28
Copy link
Contributor Author

@ShriramShastry ShriramShastry left a 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.

@lgirdwood
Copy link
Member

@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
Copy link
Collaborator

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
Copy link
Collaborator

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.

Copy link
Collaborator

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 &&
Copy link
Collaborator

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;
Copy link
Collaborator

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) {
Copy link
Collaborator

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)
Copy link
Collaborator

@singalsu singalsu Feb 26, 2024

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.

Copy link
Collaborator

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.

@lyakh
Copy link
Collaborator

lyakh commented Feb 27, 2024

@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?"

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from e71095c to 7d2d12d Compare February 28, 2024 15:27
@cujomalainey
Copy link
Contributor

cujomalainey commented Feb 28, 2024

Sorry but google is going to NACK this until we at least get a release and stabilize this component first

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from b612915 to 7c91c4e Compare February 29, 2024 06:59
@lgirdwood lgirdwood added this to the v2.10 milestone Feb 29, 2024
@lgirdwood
Copy link
Member

Sorry but google is going to NACK this until we at least get a release and stabilize this component first

Okay, we'll wait till the release and stable component are available.

Pushing it out to v2.10 to allow stabilization, baseline MCPS measurements and alignment.

Copy link
Collaborator

@singalsu singalsu left a 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;
Copy link
Collaborator

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);
Copy link
Collaborator

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.

Copy link
Contributor Author

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) {
Copy link
Collaborator

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,
Copy link
Collaborator

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.

Copy link
Contributor Author

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,
Copy link
Collaborator

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);
Copy link
Collaborator

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?

Copy link
Contributor Author

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;
Copy link
Collaborator

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.

@cujomalainey
Copy link
Contributor

Sorry but google is going to NACK this until we at least get a release and stabilize this component first

Okay, we'll wait till the release and stable component are available.

Thanks :) just remember, premature optimization is the root of all evil

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from 7c91c4e to 05745bd Compare March 1, 2024 17:29
Copy link
Contributor Author

@ShriramShastry ShriramShastry left a 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)
Copy link
Contributor Author

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)
Copy link
Contributor Author

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,
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch 2 times, most recently from fdf5826 to a3376f3 Compare March 3, 2024 14:26
@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch 2 times, most recently from 09cd6df to 2822725 Compare March 3, 2024 14:45
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>
@ShriramShastry ShriramShastry force-pushed the shastry_aec_optimization_perf_dev branch from 2822725 to 476dd43 Compare March 3, 2024 15:19
Copy link
Contributor Author

@ShriramShastry ShriramShastry left a 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);
Copy link
Contributor Author

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);
Copy link
Contributor Author

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,
Copy link
Contributor Author

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.

@ShriramShastry ShriramShastry requested a review from singalsu March 3, 2024 16:01
@lgirdwood lgirdwood modified the milestones: v2.10, v2.11 Apr 16, 2024
@ShriramShastry
Copy link
Contributor Author

ShriramShastry commented May 9, 2024

Sorry but google is going to NACK this until we at least get a release and stabilize this component first

Okay, we'll wait till the release and stable component are available.

Thanks :) just remember, premature optimization is the root of all evil

@cujomalainey , Do you have any progress ?
Thank you

@cujomalainey
Copy link
Contributor

Sorry but google is going to NACK this until we at least get a release and stabilize this component first

Okay, we'll wait till the release and stable component are available.

Thanks :) just remember, premature optimization is the root of all evil

@cujomalainey , Do you have any progress ? Thank you

#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);
Copy link
Collaborator

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);
Copy link
Collaborator

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;
Copy link
Collaborator

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) {
Copy link
Collaborator

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);
Copy link
Collaborator

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));
Copy link
Collaborator

Choose a reason for hiding this comment

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

malloc()?

Copy link
Collaborator

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.

@kv2019i
Copy link
Collaborator

kv2019i commented Sep 6, 2024

Release reminder - one week to v2.11-rc1.

@kv2019i kv2019i modified the milestones: v2.11, v2.12 Sep 13, 2024
@kv2019i kv2019i removed this from the v2.12 milestone Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants