AEC Algorithm User Guide
1. OVERVIEW¶
1.1. Module Description¶
AEC (short for Acoustic Echo Cancellation) is a function used to suppress far-end echo.
Echo is common in conference systems, building intercom, security monitoring and other scenarios. When the far-end sound is played from the speaker, the microphone re-collects the sound played by the speaker and transmits it back to the far-end after a very small delay, which will cause an echo to be heard at the far-end.
1.2. Keyword¶
-
Far-end signal (Sin)
The signal source of the device speaker, or the signal from the remote.
-
Near-end signal (Rin)
The signal recorded by the microphone of the device, which may include acoustic echo and near-end talker signals.
-
Acoustic echo (AE)
The sound played from the speaker of the device is transmitted back to the microphone through a direct or indirect path, and the echo is generated. The far-end talker will hear his echo after a certain delay after speaking. This echo is claimed as an acoustic echo (AE).
-
Single talk
Only the speaker on the device side plays the far-end signal (Sin = AE + NS when NS =0)
-
Double talk
While the speaker on the device side is playing, the near-end talker also speaks into the microphone (Sin = AE + NS when NS≠0)

1.3. Note¶
In order to facilitate debugging and confirm the effect of the algorithm, the user application needs to implement replacement algorithm parameter and grab audio data.
2. API REFERENCE¶
2.1. API List¶
| API name | Features |
|---|---|
| IaaAec_GetBufferSize | Get the memory size required for Aec algorithm running |
| IaaAec_Init | Initialize the memory required for the Aec algorithm |
| IaaAec_Config | Configure Aec algorithm |
| IaaAec_Reset | Reinitialize the memory of Aec algorithm |
| IaaAec_Free | Release Aec algorithm resources |
| IaaAec_Run | Aec algorithm processing |
| IaaAec_GetLibVersion | Get the version information of the Aec algorithm |
| IaaAec_SetRecursiveRatio | Set Aec recursive ratio for adjusting converge speed. |
| IaaAec_ADF_Run | Run Linear Aec algorithm. |
| IaaAec_NLP_Run | Run Non-Linear Aec algorithm. |
| IaaAec_GetAPIVersion | Get API version. |
| IaaAec_SetHandleId | Set Aec algorithm id. |
2.2. IaaAec_GetBufferSize¶
-
Features
Get the memory size required for Aec algorithm running.
-
Syntax
unsigned int IaaAec_GetBufferSize(void);
-
Return value
Return value is the memory size required for Aec algorithm running.
-
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
The interface only returns the required memory size, and the application and release of memory need to be processed by the application.
2.3. IaaAec_Init¶
-
Features
Initialize the memory required for the Aec algorithm.
-
Syntax
AEC_HANDLE IaaAec_Init (char* working_buffer_address, AudioAecInit * aec_init);
-
Parameters
Parameter Name Description Input/Output working_buffer_address Memory address used by Aec algorithm Input aec_init Aec algorithm initialization structure pointer Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so / libAEC_LINUX.a
-
-
Note
- Aec algorithm only supports 8K/16K sampling rate.
2.4. IaaAec_Config¶
-
Features
Configure Aec algorithm.
-
Syntax
ALGO_AEC_RET IaaAec_Config(AEC_HANDLE handle, AudioAecConfig *aec_config);
-
Parameters
Parameter Name Description Input/Output handle Aec algorithm handle Input aec_config Aec algorithm configuration parameter structure pointer Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so / libAEC_LINUX.a
-
2.5. IaaAec_Reset¶
-
Features
Reinitialize the memory of Aec algorithm.
-
Syntax
AEC_HANDLE IaaAec_Reset(char* working_buffer_address, AudioAecInit * aec_init);
-
Parameters
Parameter Name Description Input/Output working_buffer_address Memory address used by Aec algorithm Input aec_init Aec algorithm initialization structure pointer Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
-
Reinitialize the Aec algorithm for the same algorithm handle (same memory address) (that is, reset the sampling rate and the number of near-end and far-end channels)
-
After re-initializing the Aec algorithm, it needs to be reconfigured
-
2.6. IaaAec_Free¶
-
Features
Release Aec algorithm resources
-
Syntax
ALGO_AEC_RET IaaAec_Free(AEC_HANDLE handle);
-
Parameters
Parameter Name Description Input/Output handle Aec algorithm handle Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
Must call IaaAec_Free first, and then release the memory used by the Aec algorithm.
2.7. IaaAec_Run¶
-
Features
Aec algorithm processing
-
Syntax
ALGO_AEC_RET IaaAec_Run(AEC_HANDLE handle, short* pss_audio_near_end, short* pss_audio_far_end);
-
Parameters
Parameter Name Description Input/Output handle Algorithm handle Input pss_audio_near_end Near-end data pointer Input/Output pss_audio_far_end Far-end data pointer Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
-
The amount of near-end and far-end data must correspond to the point_number (the number of sampling points required for one IaaAec_Run) when calling IaaAec_Init.
-
The result after AEC is output by pss_audio_near_end.
-
If the input data is stereo, please arrange the left and right channel by turns.
-
-
Example
#include <stdio.h> #include <string.h> #include <sys/time.h> #include <stdlib.h> #include "AudioAecProcess.h" /* 0:Fixed input file 1:User input file */ #define IN_PARAMETER 1 float AVERAGE_RUN(int a) { static unsigned int num = 0; static float avg = 0; if(0 == num) avg = 0; num++; avg = avg + ((float)a - avg) / ((float)num); return avg; } unsigned int _OsCounterGetMs(void) { struct timeval t1; gettimeofday(&t1, NULL); unsigned int T = ((1000000 * t1.tv_sec) + t1.tv_usec) / 1000; return T; } int main(int argc, char *argv[]) { short in_output[1024]; short input_far[1024]; char src_file1[128] = {0}; char src_file2[128] = {0}; char dst_file[128] = {0}; unsigned int workingBufferSize; char *workingBuffer = NULL; int counter = 0; ALGO_AEC_RET ret; int tempSize; unsigned int T0, T1; float avg; FILE *fpInFar, *fpOut, *fpInNear; AudioAecInit aec_init; AudioAecConfig aec_config; AEC_HANDLE handle; /*********************User change section start*******************/ unsigned int supMode_band[6] = {20,40,60,80,100,120}; unsigned int supMode[7] = {4,4,4,4,4,4,4}; aec_init.point_number = 128; aec_init.nearend_channel = 1; aec_init.farend_channel = 1; aec_init.sample_rate = IAA_AEC_SAMPLE_RATE_16000; aec_config.delay_sample = 0; aec_config.comfort_noise_enable = IAA_AEC_FALSE; /*********************User change section end*******************/ memcpy(&(aec_config.suppression_mode_freq[0]), supMode_band, sizeof(supMode_band)); memcpy(&(aec_config.suppression_mode_intensity[0]), supMode, sizeof(supMode)); //(1)IaaAec_GetBufferSize workingBufferSize = IaaAec_GetBufferSize(); workingBuffer = (char*)malloc(workingBufferSize); if(NULL == workingBuffer) { printf("workingBuffer malloc failed !\n"); return -1; } printf("workingBuffer malloc success !\n"); //(2)IaaAec_Init handle = IaaAec_Init(workingBuffer, &aec_init); if (NULL == handle) { printf("AEC init failed !\r\n"); return -1; } printf("AEC init success !\r\n"); //(3)IaaAec_Config ret = IaaAec_Config(handle, &aec_config); if(ret) { printf("IaaAec_Config failed !\n"); return -1; } printf("IaaAec_Config succeed !\n"); #if IN_PARAMETER if(argc < 4) { printf("Please enter the correct parameters!\n"); return -1; } sscanf(argv[1], "%s", src_file1); sscanf(argv[2], "%s", src_file2); sscanf(argv[3], "%s", dst_file); #else sprintf(src_file1, "%s", "./farend.wav"); sprintf(src_file2, "%s", "./nearend.wav"); if(argc < 2) { printf("Please enter the correct parameters!\n"); return -1; } sscanf(argv[1], "%s", dst_file); #endif fpInFar = fopen(src_file1, "rb"); if(NULL == fpInFar) { printf("src_file1 open failed !\n"); return -1; } printf("src_file1 open succeed !\n"); fpInNear = fopen(src_file2, "rb"); if(NULL == fpInNear) { printf("src_file2 open failed !\n"); return -1; } printf("src_file2 open succeed !\n"); fpOut = fopen(dst_file, "wb"); if(NULL == fpOut) { printf("dst_file open failed !\n"); return -1; } printf("dst_file open succeed !\n"); #if 1 fread(in_output, sizeof(char), 44, fpInNear); // Remove the 44 bytes header fwrite(in_output, sizeof(char), 44, fpOut); // New file add header fread(input_far, sizeof(char), 44, fpInFar); // Remove the 44 bytes header #endif tempSize = aec_init.point_number * aec_init.nearend_channel; while(fread(in_output, sizeof(short), tempSize, fpInNear)) { tempSize = aec_init.point_number * aec_init.farend_channel; fread(input_far, sizeof(short), tempSize, fpInFar); counter++; T0 = (long)_OsCounterGetMs(); //(4)IaaAec_Run ret = IaaAec_Run(handle, in_output, input_far); T1 = (long)_OsCounterGetMs(); avg = AVERAGE_RUN(T1 - T0); if(0 == counter % 100) { printf("counter = %d\n", counter); printf("current time = %f\n", (float)counter * aec_init.point_number / aec_init.sample_rate); printf("process time = %lu(ms)\t", (long)(T1 - T0)); printf("AVG is %.2f ms\n", avg); } if(ret < 0) { printf("IaaAec_Run failed !\n"); break; } tempSize = aec_init.point_number * aec_init.nearend_channel; fwrite(in_output, sizeof(short), tempSize, fpOut); } //(5)IaaAec_Free IaaAec_Free(handle); fclose(fpInFar); fclose(fpInNear); fclose(fpOut); free(workingBuffer); printf("AEC end !\n"); return 0; }
2.8. IaaAec_GetLibVersion¶
-
Features
Get the version information of the Aec algorithm.
-
Syntax
ALGO_AEC_RET IaaAec_GetLibVersion(unsigned short *ver_year, unsigned short *ver_date, unsigned short *ver_time);
-
Parameters
Parameter Name Description Input/Output ver_year Year when Aec Algorithm Library was built output ver_date Date when Aec Algorithm Library was built output ver_time Date when Aec Algorithm Library was built output -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
2.9. IaaAec_SetRecursiveRatio¶
-
Features
Set Aec recursive ratio for adjusting converge speed.
-
Syntax
ALGO_AEC_RET IaaAec_SetRecursiveRatio(AEC_HANDLE handle, unsigned int recursive_ratio);
-
Parameters
Parameter Name Description Input/Output handle Aec algorithm handle Input recursive_ratio Recursive parameter input. Larger the value, Faster the converge speed. For the scenario of switching from double talk to single talk, decrease AEC over suppress near end signal. BUT echo suppress would be more aggressive. The discontinuity of background noise become worse.
Range: 1~10.Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
2.10. IaaAec_ADF_Run¶
-
Features
Aec linear algorithm processing
-
Syntax
ALGO_AEC_RET IaaAec_ADF_Run(AEC_HANDLE handle, short* pss_audio_near_end, short* pss_audio_far_end);
-
Parameters
Parameter Name Description Input/Output handle Algorithm handle Input pss_audio_near_end Near-end data pointer Input/Output pss_audio_far_end Far-end data pointer Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
-
The amount of near-end and far-end data must correspond to the point_number (the number of sampling points required for one IaaAec_ADF_Run) when calling IaaAec_Init.
-
The result after linear AEC is output by pss_audio_near_end.
-
If the input data is stereo, please arrange the left and right channel by turns.
-
2.11. IaaAec_NLP_Run¶
-
Features
Aec non-linear algorithm processing
-
Syntax
ALGO_AEC_RET IaaAec_NLP_Run(AEC_HANDLE handle, short* pss_audio_near_end);
-
Parameters
Parameter Name Description Input/Output handle Algorithm handle Input pss_audio_near_end Near-end data pointer Input/Output -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
-
Note
-
The amount of near-end data must correspond to the point_number (the number of sampling points required for one IaaAec_NLP_Run) when calling IaaAec_Init.
-
The result after non-linear AEC is output by pss_audio_near_end.
-
If the input data is stereo, please arrange the left and right channel by turns.
-
2.12. IaaAec_GetAPIVersion¶
-
Features
Get API version.
-
Syntax
ALGO_AEC_RET IaaAec_GetAPIVersion(unsigned short* major, unsigned short* minor);
-
Parameters
Parameter Name Description Input/Output major Return version output minor Return version Output -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
2.13. IaaAec_SetHandleId¶
-
Features
Set Aec algorithm id.
-
Syntax
ALGO_AEC_RET IaaAec_SetHandleId(AEC_HANDLE handle, int id);
-
Parameters
Parameter Name Description Input/Output handle Algorithm handle Input id Aec algorithm handle id
Range: [0,100]Input -
Return value
Return value Result 0 Successful Non-zero Failed, refer to error code -
Dependency
-
Header: AudioAecProcess.h
-
Library: libAEC_LINUX.so/ libAEC_LINUX.a
-
3. AEC DATA TYPE¶
3.1. AEC data type list¶
The AEC module related data types are defined as follows:
| DATA TYPE | Description |
|---|---|
| AudioAecInit | The initialization parameter structure of the Aec algorithm |
| AudioAecConfig | the configuration parameter structure of the Aec algorithm |
| IAA_AEC_SAMPLE_RATE | AEC algorithm supported sampling rate type |
| IAA_AEC_BOOL | The Boolean type used internally in the Aec algorithm |
| AEC_HANDLE | The handle type of the Aec algorithm |
3.2. AudioAecInit¶
-
Description
Define the initialization parameter structure of the Aec algorithm.
-
Definition
typedef struct { unsigned int point_number; unsigned int nearend_channel; unsigned int farend_channel; IAA_AEC_SAMPLE_RATE sample_rate; }AudioAecInit; -
Member
Member name Description point_number The number of sampling points processed by the Aec algorithm once. The default value is 128. User can use following command to check
strings libAEC_LINUX.so \| grep PNnearend_channel The near-end channel number ( the microphone channel number). User can set mono or stereo.
Range: [1, 2]farend_channel The far-end channel number (the speaker channel number). User can set mono or stereo.
Range: [1, 2]sample_rate Sampling rate processed by Aec algorithm -
Note
-
If the input data is stereo, User need to intersect the left and right channels. For example, L/R/L/R/L/R...
-
IaaAec_Run reads the length of the near-end data pointer as
$point_number \times nearend_channel \times 2 $ bytes
Reads the length of the far-end data pointer as
$point_number \times farend_channel \times 2 $ bytes
-
If it is set to stereo channels, AEC will average the two channels into one channel and copy the processed result to the two channels. If you need to separate the two channels, please initialize two handles and execute IaaApc_Run separately.
-
-
Related data types and interfaces
3.3. AudioAecConfig¶
-
Description
Define the configuration parameter structure of the Aec algorithm
-
Definition
typedef struct { IAA_AEC_BOOL comfort_noise_enable; short delay_sample; unsigned int suppression_mode_freq[6]; unsigned int suppression_mode_intensity[7]; }AudioAecConfig; -
Member
Member name Description comfort_noise_enable Add comfort noise after AEC to avoid the muting part of the paragraph after echo cancellation, which makes users feel disconnected.
If noise reduction is turned on after AEC, it is recommended to turn on comfort noise to help NR converge noise.delay_sample Echo delay samples between left and right channels When Stereo cost down is turned on, you can set the sample delay number according to the relative position of the microphone, reducing the amount of calculation required for the dual-channel.
Default value : 0
Unit : the number of samples
Value ranges: -9-9suppression_mode_freq The frequency band division of AEC processing divides the highest frequency that can be resolved by different sampling rates into 128 equal parts. Setting six values, which can cut out seven segments to set different AEC intensities.
Value ranges: 1-127suppression_mode_intensity Set seven intensities respectively in the seven paragraphs cut by the suppression_mode_freq.
Value ranges: 0-25 -
Note
-
comfort_noise_enable
After enabling the parameter, the AEC algorithm will add some comfort noise when there is no sound. This function can be enabled when you require a stable noise floor or when AEC is too clean that causes the NR convergence time is too long.
-
delay_sample
Due to the placement of the microphone and the speaker, the distance between the microphones, etc., the time points when the left and right channels receive the echo are not consistent, and the echo delay between the two channels is different.
This value indicates how many sampling points the left channel receives the echo earlier than the right channel. You can adjust this value to align the left and right channel data. When setting, please use the left channel as a reference. For example, the echo of the left channel is 4 samples faster than the right, s16DelaySample is set to 4, otherwise it is set to -4.
-
suppression_mode_freq
This array divides the highest frequency of the current sampling rate into 7 frequency bands for processing. The following is the conversion formula of array elements and frequency range:
residual\ Echo\ Frequency\ Range/(sampleRate/2) \times pointNumber(128)
The array requires that each element must be greater than the previous element.
-
suppression_mode_intensity
This array represents the echo cancellation intensity of each frequency band, and each element corresponds to the 7 frequency bands divided by u32AecSupfreq. The greater the intensity, the more details are eliminated and the more unnatural the sound.
-
-
Related data types and interfaces
3.4. IAA_AEC_SAMPLE_RATE¶
-
Description
AEC algorithm supported sampling rate type.
-
Definition
typedef enum { IAA_AEC_SAMPLE_RATE_8000 = 8000 , IAA_AEC_SAMPLE_RATE_16000 = 16000 , IAA_AEC_SAMPLE_RATE_32000 = 32000 , IAA_AEC_SAMPLE_RATE_48000 = 48000 , }IAA_AEC_SAMPLE_RATE; -
Member
Member name Description IAA_AEC_SAMPLE_RATE_8000 8K sampling rate IAA_AEC_SAMPLE_RATE_16000 16K sampling rate IAA_AEC_SAMPLE_RATE_32000 32K sampling rate IAA_AEC_SAMPLE_RATE_48000 48K sampling rate -
Related data types and interfaces
3.5. IAA_AEC_BOOL¶
-
Description
Define the Boolean type used internally in the Aec algorithm.
-
Definition
typedef enum { IAA_AEC_TRUE = 1, IAA_AEC_FALSE = 0, }IAA_AEC_BOOL; -
Member
Member name Description IAA_AEC_TRUE True IAA_AEC_FALSE False -
Related data types and interfaces
3.6. AEC_HANDLE¶
-
Description
Define the handle type of the Aec algorithm.
-
Definition
typedef void* AEC_HANDLE;
-
Related data types and interfaces
4. ERROR CODE¶
AEC API error codes are shown as follow:
| Error code | Macro definition | Description |
|---|---|---|
| 0x00000000 | ALGO_AEC_RET_SUCCESS | AEC runs successfully |
| 0x10000401 | ALGO_AEC_RET_INIT_ERROR | AEC has not been initialized |
| 0x10000402 | ALGO_AEC_RET_INVALID_HANDLE | Invalid HANDLE |
| 0x10000403 | ALGO_AEC_RET_INVALID_SAMPLE_RATE | Sampling rate is not supported |
| 0x10000404 | ALGO_AEC_RET_INVALID_POINT_NUMBER | Points per frame are not supported |
| 0x10000405 | ALGO_AEC_RET_INVALID_CHANNEL | Channel number is not supported |
| 0x10000406 | ALGO_AEC_RET_INVALID_ENABLE | Calling is not supported |
| 0x10000407 | ALGO_AEC_RET_INVALID_SUP_BAND | Invalid AEC suppression band parameter setting |
| 0x10000408 | ALGO_AEC_RET_INVALID_SUP_MODE | Invalid AEC suppression strength parameter setting |
| 0x10000409 | ALGO_AEC_RET_INVALID_COMFORT_NOISE | Invalid AEC comfort noise parameter setting |
| 0x10000410 | ALGO_AEC_RET_INVALID_DELAY_SAMPLE | Invalid AEC delay sample number setting |
| 0x10000411 | ALGO_AEC_RET_INVALID_RECURSIVE_RATIO | Invalid AEC recursive parameter setting |
| 0x10000412 | ALGO_AEC_RET_API_CONFLICT | Other APIs are running |
| 0x10000413 | ALGO_AEC_RET_INVALID_CALLING | Incorrect API calling sequence |