Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 // Performs echo control (suppression) with fft routines in fixed-point
     12 
     13 #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_SOURCE_AECM_CORE_H_
     14 #define WEBRTC_MODULES_AUDIO_PROCESSING_AECM_MAIN_SOURCE_AECM_CORE_H_
     15 
     16 #define AECM_DYNAMIC_Q // turn on/off dynamic Q-domain
     17 //#define AECM_WITH_ABS_APPROX
     18 //#define AECM_SHORT                // for 32 sample partition length (otherwise 64)
     19 
     20 // TODO(bjornv): These defines will be removed in final version.
     21 //#define STORE_CHANNEL_DATA
     22 //#define VAD_DATA
     23 
     24 #include "typedefs.h"
     25 #include "signal_processing_library.h"
     26 // TODO(bjornv): Will be removed in final version.
     27 //#include <stdio.h>
     28 
     29 // Algorithm parameters
     30 
     31 #define FRAME_LEN       80              // Total frame length, 10 ms
     32 #ifdef AECM_SHORT
     33 
     34 #define PART_LEN        32              // Length of partition
     35 #define PART_LEN_SHIFT  6               // Length of (PART_LEN * 2) in base 2
     36 
     37 #else
     38 
     39 #define PART_LEN        64              // Length of partition
     40 #define PART_LEN_SHIFT  7               // Length of (PART_LEN * 2) in base 2
     41 
     42 #endif
     43 
     44 #define PART_LEN1       (PART_LEN + 1)  // Unique fft coefficients
     45 #define PART_LEN2       (PART_LEN << 1) // Length of partition * 2
     46 #define PART_LEN4       (PART_LEN << 2) // Length of partition * 4
     47 #define FAR_BUF_LEN     PART_LEN4       // Length of buffers
     48 #define MAX_DELAY 100
     49 
     50 // Counter parameters
     51 #ifdef AECM_SHORT
     52 
     53 #define CONV_LEN        1024            // Convergence length used at startup
     54 #else
     55 
     56 #define CONV_LEN        512             // Convergence length used at startup
     57 #endif
     58 
     59 #define CONV_LEN2       (CONV_LEN << 1) // Convergence length * 2 used at startup
     60 // Energy parameters
     61 #define MAX_BUF_LEN     64              // History length of energy signals
     62 
     63 #define FAR_ENERGY_MIN  1025            // Lowest Far energy level: At least 2 in energy
     64 #define FAR_ENERGY_DIFF 929             // Allowed difference between max and min
     65 
     66 #define ENERGY_DEV_OFFSET       0       // The energy error offset in Q8
     67 #define ENERGY_DEV_TOL  400             // The energy estimation tolerance in Q8
     68 #define FAR_ENERGY_VAD_REGION   230     // Far VAD tolerance region
     69 // Stepsize parameters
     70 #define MU_MIN          10              // Min stepsize 2^-MU_MIN (far end energy dependent)
     71 #define MU_MAX          1               // Max stepsize 2^-MU_MAX (far end energy dependent)
     72 #define MU_DIFF         9               // MU_MIN - MU_MAX
     73 // Channel parameters
     74 #define MIN_MSE_COUNT   20              // Min number of consecutive blocks with enough far end
     75                                         // energy to compare channel estimates
     76 #define MIN_MSE_DIFF    29              // The ratio between adapted and stored channel to
     77                                         // accept a new storage (0.8 in Q-MSE_RESOLUTION)
     78 #define MSE_RESOLUTION  5               // MSE parameter resolution
     79 #define RESOLUTION_CHANNEL16    12      // W16 Channel in Q-RESOLUTION_CHANNEL16
     80 #define RESOLUTION_CHANNEL32    28      // W32 Channel in Q-RESOLUTION_CHANNEL
     81 #define CHANNEL_VAD     16              // Minimum energy in frequency band to update channel
     82 // Suppression gain parameters: SUPGAIN_ parameters in Q-(RESOLUTION_SUPGAIN)
     83 #define RESOLUTION_SUPGAIN      8       // Channel in Q-(RESOLUTION_SUPGAIN)
     84 #define SUPGAIN_DEFAULT (1 << RESOLUTION_SUPGAIN)   // Default suppression gain
     85 #define SUPGAIN_ERROR_PARAM_A   3072    // Estimation error parameter (Maximum gain) (8 in Q8)
     86 #define SUPGAIN_ERROR_PARAM_B   1536    // Estimation error parameter (Gain before going down)
     87 #define SUPGAIN_ERROR_PARAM_D   SUPGAIN_DEFAULT // Estimation error parameter
     88                                                 // (Should be the same as Default) (1 in Q8)
     89 #define SUPGAIN_EPC_DT  200             // = SUPGAIN_ERROR_PARAM_C * ENERGY_DEV_TOL
     90 // Defines for "check delay estimation"
     91 #define CORR_WIDTH      31              // Number of samples to correlate over.
     92 #define CORR_MAX        16              // Maximum correlation offset
     93 #define CORR_MAX_BUF    63
     94 #define CORR_DEV        4
     95 #define CORR_MAX_LEVEL  20
     96 #define CORR_MAX_LOW    4
     97 #define CORR_BUF_LEN    (CORR_MAX << 1) + 1
     98 // Note that CORR_WIDTH + 2*CORR_MAX <= MAX_BUF_LEN
     99 
    100 #define ONE_Q14         (1 << 14)
    101 
    102 // NLP defines
    103 #define NLP_COMP_LOW    3277            // 0.2 in Q14
    104 #define NLP_COMP_HIGH   ONE_Q14         // 1 in Q14
    105 
    106 typedef struct
    107 {
    108     int farBufWritePos;
    109     int farBufReadPos;
    110     int knownDelay;
    111     int lastKnownDelay;
    112     int firstVAD; // Parameter to control poorly initialized channels
    113 
    114     void *farFrameBuf;
    115     void *nearNoisyFrameBuf;
    116     void *nearCleanFrameBuf;
    117     void *outFrameBuf;
    118 
    119     WebRtc_Word16 xBuf[PART_LEN2]; // farend
    120     WebRtc_Word16 dBufClean[PART_LEN2]; // nearend
    121     WebRtc_Word16 dBufNoisy[PART_LEN2]; // nearend
    122     WebRtc_Word16 outBuf[PART_LEN];
    123 
    124     WebRtc_Word16 farBuf[FAR_BUF_LEN];
    125 
    126     WebRtc_Word16 mult;
    127     WebRtc_UWord32 seed;
    128 
    129     // Delay estimation variables
    130     WebRtc_UWord16 medianYlogspec[PART_LEN1];
    131     WebRtc_UWord16 medianXlogspec[PART_LEN1];
    132     WebRtc_UWord16 medianBCount[MAX_DELAY];
    133     WebRtc_UWord16 xfaHistory[PART_LEN1][MAX_DELAY];
    134     WebRtc_Word16 delHistoryPos;
    135     WebRtc_UWord32 bxHistory[MAX_DELAY];
    136     WebRtc_UWord16 currentDelay;
    137     WebRtc_UWord16 previousDelay;
    138     WebRtc_Word16 delayAdjust;
    139 
    140     WebRtc_Word16 nlpFlag;
    141     WebRtc_Word16 fixedDelay;
    142 
    143     WebRtc_UWord32 totCount;
    144 
    145     WebRtc_Word16 xfaQDomainBuf[MAX_DELAY];
    146     WebRtc_Word16 dfaCleanQDomain;
    147     WebRtc_Word16 dfaCleanQDomainOld;
    148     WebRtc_Word16 dfaNoisyQDomain;
    149     WebRtc_Word16 dfaNoisyQDomainOld;
    150 
    151     WebRtc_Word16 nearLogEnergy[MAX_BUF_LEN];
    152     WebRtc_Word16 farLogEnergy[MAX_BUF_LEN];
    153     WebRtc_Word16 echoAdaptLogEnergy[MAX_BUF_LEN];
    154     WebRtc_Word16 echoStoredLogEnergy[MAX_BUF_LEN];
    155 
    156     WebRtc_Word16 channelAdapt16[PART_LEN1];
    157     WebRtc_Word32 channelAdapt32[PART_LEN1];
    158     WebRtc_Word16 channelStored[PART_LEN1];
    159     WebRtc_Word32 echoFilt[PART_LEN1];
    160     WebRtc_Word16 nearFilt[PART_LEN1];
    161     WebRtc_Word32 noiseEst[PART_LEN1];
    162     WebRtc_Word16 noiseEstQDomain[PART_LEN1];
    163     WebRtc_Word16 noiseEstCtr;
    164     WebRtc_Word16 cngMode;
    165 
    166     WebRtc_Word32 mseAdaptOld;
    167     WebRtc_Word32 mseStoredOld;
    168     WebRtc_Word32 mseThreshold;
    169 
    170     WebRtc_Word16 farEnergyMin;
    171     WebRtc_Word16 farEnergyMax;
    172     WebRtc_Word16 farEnergyMaxMin;
    173     WebRtc_Word16 farEnergyVAD;
    174     WebRtc_Word16 farEnergyMSE;
    175     WebRtc_Word16 currentVADValue;
    176     WebRtc_Word16 vadUpdateCount;
    177 
    178     WebRtc_Word16 delayHistogram[MAX_DELAY];
    179     WebRtc_Word16 delayVadCount;
    180     WebRtc_Word16 maxDelayHistIdx;
    181     WebRtc_Word16 lastMinPos;
    182 
    183     WebRtc_Word16 startupState;
    184     WebRtc_Word16 mseChannelCount;
    185     WebRtc_Word16 delayCount;
    186     WebRtc_Word16 newDelayCorrData;
    187     WebRtc_Word16 lastDelayUpdateCount;
    188     WebRtc_Word16 delayCorrelation[CORR_BUF_LEN];
    189     WebRtc_Word16 supGain;
    190     WebRtc_Word16 supGainOld;
    191     WebRtc_Word16 delayOffsetFlag;
    192 
    193     WebRtc_Word16 supGainErrParamA;
    194     WebRtc_Word16 supGainErrParamD;
    195     WebRtc_Word16 supGainErrParamDiffAB;
    196     WebRtc_Word16 supGainErrParamDiffBD;
    197 
    198     // TODO(bjornv): Will be removed after final version has been committed.
    199 #ifdef VAD_DATA
    200     FILE *vad_file;
    201     FILE *delay_file;
    202     FILE *far_file;
    203     FILE *far_cur_file;
    204     FILE *far_min_file;
    205     FILE *far_max_file;
    206     FILE *far_vad_file;
    207 #endif
    208 
    209     // TODO(bjornv): Will be removed after final version has been committed.
    210 #ifdef STORE_CHANNEL_DATA
    211     FILE *channel_file;
    212     FILE *channel_file_init;
    213 #endif
    214 
    215 #ifdef AEC_DEBUG
    216     FILE *farFile;
    217     FILE *nearFile;
    218     FILE *outFile;
    219 #endif
    220 } AecmCore_t;
    221 
    222 ///////////////////////////////////////////////////////////////////////////////////////////////
    223 // WebRtcAecm_CreateCore(...)
    224 //
    225 // Allocates the memory needed by the AECM. The memory needs to be
    226 // initialized separately using the WebRtcAecm_InitCore() function.
    227 //
    228 // Input:
    229 //      - aecm          : Instance that should be created
    230 //
    231 // Output:
    232 //      - aecm          : Created instance
    233 //
    234 // Return value         :  0 - Ok
    235 //                        -1 - Error
    236 //
    237 int WebRtcAecm_CreateCore(AecmCore_t **aecm);
    238 
    239 ///////////////////////////////////////////////////////////////////////////////////////////////
    240 // WebRtcAecm_InitCore(...)
    241 //
    242 // This function initializes the AECM instant created with WebRtcAecm_CreateCore(...)
    243 // Input:
    244 //      - aecm          : Pointer to the AECM instance
    245 //      - samplingFreq  : Sampling Frequency
    246 //
    247 // Output:
    248 //      - aecm          : Initialized instance
    249 //
    250 // Return value         :  0 - Ok
    251 //                        -1 - Error
    252 //
    253 int WebRtcAecm_InitCore(AecmCore_t * const aecm, int samplingFreq);
    254 
    255 ///////////////////////////////////////////////////////////////////////////////////////////////
    256 // WebRtcAecm_FreeCore(...)
    257 //
    258 // This function releases the memory allocated by WebRtcAecm_CreateCore()
    259 // Input:
    260 //      - aecm          : Pointer to the AECM instance
    261 //
    262 // Return value         :  0 - Ok
    263 //                        -1 - Error
    264 //           11001-11016: Error
    265 //
    266 int WebRtcAecm_FreeCore(AecmCore_t *aecm);
    267 
    268 int WebRtcAecm_Control(AecmCore_t *aecm, int delay, int nlpFlag, int delayOffsetFlag);
    269 
    270 ///////////////////////////////////////////////////////////////////////////////////////////////
    271 // WebRtcAecm_ProcessFrame(...)
    272 //
    273 // This function processes frames and sends blocks to WebRtcAecm_ProcessBlock(...)
    274 //
    275 // Inputs:
    276 //      - aecm          : Pointer to the AECM instance
    277 //      - farend        : In buffer containing one frame of echo signal
    278 //      - nearendNoisy  : In buffer containing one frame of nearend+echo signal without NS
    279 //      - nearendClean  : In buffer containing one frame of nearend+echo signal with NS
    280 //
    281 // Output:
    282 //      - out           : Out buffer, one frame of nearend signal          :
    283 //
    284 //
    285 void WebRtcAecm_ProcessFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend,
    286                              const WebRtc_Word16 * const nearendNoisy,
    287                              const WebRtc_Word16 * const nearendClean,
    288                              WebRtc_Word16 * const out);
    289 
    290 ///////////////////////////////////////////////////////////////////////////////////////////////
    291 // WebRtcAecm_ProcessBlock(...)
    292 //
    293 // This function is called for every block within one frame
    294 // This function is called by WebRtcAecm_ProcessFrame(...)
    295 //
    296 // Inputs:
    297 //      - aecm          : Pointer to the AECM instance
    298 //      - farend        : In buffer containing one block of echo signal
    299 //      - nearendNoisy  : In buffer containing one frame of nearend+echo signal without NS
    300 //      - nearendClean  : In buffer containing one frame of nearend+echo signal with NS
    301 //
    302 // Output:
    303 //      - out           : Out buffer, one block of nearend signal          :
    304 //
    305 //
    306 void WebRtcAecm_ProcessBlock(AecmCore_t * const aecm, const WebRtc_Word16 * const farend,
    307                                 const WebRtc_Word16 * const nearendNoisy,
    308                                 const WebRtc_Word16 * const noisyClean,
    309                                 WebRtc_Word16 * const out);
    310 
    311 ///////////////////////////////////////////////////////////////////////////////////////////////
    312 // WebRtcAecm_BufferFarFrame()
    313 //
    314 // Inserts a frame of data into farend buffer.
    315 //
    316 // Inputs:
    317 //      - aecm          : Pointer to the AECM instance
    318 //      - farend        : In buffer containing one frame of farend signal
    319 //      - farLen        : Length of frame
    320 //
    321 void WebRtcAecm_BufferFarFrame(AecmCore_t * const aecm, const WebRtc_Word16 * const farend,
    322                                const int farLen);
    323 
    324 ///////////////////////////////////////////////////////////////////////////////////////////////
    325 // WebRtcAecm_FetchFarFrame()
    326 //
    327 // Read the farend buffer to account for known delay
    328 //
    329 // Inputs:
    330 //      - aecm          : Pointer to the AECM instance
    331 //      - farend        : In buffer containing one frame of farend signal
    332 //      - farLen        : Length of frame
    333 //      - knownDelay    : known delay
    334 //
    335 void WebRtcAecm_FetchFarFrame(AecmCore_t * const aecm, WebRtc_Word16 * const farend,
    336                               const int farLen, const int knownDelay);
    337 
    338 #endif
    339