/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stdlib.h>
//#include <string.h>

#include "echo_control_mobile.h"
#include "aecm_core.h"
#include "ring_buffer.h"
#ifdef AEC_DEBUG
#include <stdio.h>
#endif
#ifdef MAC_IPHONE_PRINT
#include <time.h>
#include <stdio.h>
#elif defined ARM_WINM_LOG
#include "windows.h"
extern HANDLE logFile;
#endif

#define BUF_SIZE_FRAMES 50 // buffer size (frames)
// Maximum length of resampled signal. Must be an integer multiple of frames
// (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN
// The factor of 2 handles wb, and the + 1 is as a safety margin
#define MAX_RESAMP_LEN (5 * FRAME_LEN)

static const size_t kBufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples)
static const int kSampMsNb = 8; // samples per ms in nb
// Target suppression levels for nlp modes
// log{0.001, 0.00001, 0.00000001}
static const int kInitCheck = 42;

typedef struct
{
    int sampFreq;
    int scSampFreq;
    short bufSizeStart;
    int knownDelay;

    // Stores the last frame added to the farend buffer
    short farendOld[2][FRAME_LEN];
    short initFlag; // indicates if AEC has been initialized

    // Variables used for averaging far end buffer size
    short counter;
    short sum;
    short firstVal;
    short checkBufSizeCtr;

    // Variables used for delay shifts
    short msInSndCardBuf;
    short filtDelay;
    int timeForDelayChange;
    int ECstartup;
    int checkBuffSize;
    int delayChange;
    short lastDelayDiff;

    WebRtc_Word16 echoMode;

#ifdef AEC_DEBUG
    FILE *bufFile;
    FILE *delayFile;
    FILE *preCompFile;
    FILE *postCompFile;
#endif // AEC_DEBUG
    // Structures
    void *farendBuf;

    int lastError;

    AecmCore_t *aecmCore;
} aecmob_t;

// Estimates delay to set the position of the farend buffer read pointer
// (controlled by knownDelay)
static int WebRtcAecm_EstBufDelay(aecmob_t *aecmInst, short msInSndCardBuf);

// Stuffs the farend buffer if the estimated delay is too large
static int WebRtcAecm_DelayComp(aecmob_t *aecmInst);

WebRtc_Word32 WebRtcAecm_Create(void **aecmInst)
{
    aecmob_t *aecm;
    if (aecmInst == NULL)
    {
        return -1;
    }

    aecm = malloc(sizeof(aecmob_t));
    *aecmInst = aecm;
    if (aecm == NULL)
    {
        return -1;
    }

    if (WebRtcAecm_CreateCore(&aecm->aecmCore) == -1)
    {
        WebRtcAecm_Free(aecm);
        aecm = NULL;
        return -1;
    }

    if (WebRtc_CreateBuffer(&aecm->farendBuf, kBufSizeSamp,
                            sizeof(int16_t)) == -1)
    {
        WebRtcAecm_Free(aecm);
        aecm = NULL;
        return -1;
    }

    aecm->initFlag = 0;
    aecm->lastError = 0;

#ifdef AEC_DEBUG
    aecm->aecmCore->farFile = fopen("aecFar.pcm","wb");
    aecm->aecmCore->nearFile = fopen("aecNear.pcm","wb");
    aecm->aecmCore->outFile = fopen("aecOut.pcm","wb");
    //aecm->aecmCore->outLpFile = fopen("aecOutLp.pcm","wb");

    aecm->bufFile = fopen("aecBuf.dat", "wb");
    aecm->delayFile = fopen("aecDelay.dat", "wb");
    aecm->preCompFile = fopen("preComp.pcm", "wb");
    aecm->postCompFile = fopen("postComp.pcm", "wb");
#endif // AEC_DEBUG
    return 0;
}

WebRtc_Word32 WebRtcAecm_Free(void *aecmInst)
{
    aecmob_t *aecm = aecmInst;

    if (aecm == NULL)
    {
        return -1;
    }

#ifdef AEC_DEBUG
    fclose(aecm->aecmCore->farFile);
    fclose(aecm->aecmCore->nearFile);
    fclose(aecm->aecmCore->outFile);
    //fclose(aecm->aecmCore->outLpFile);

    fclose(aecm->bufFile);
    fclose(aecm->delayFile);
    fclose(aecm->preCompFile);
    fclose(aecm->postCompFile);
#endif // AEC_DEBUG
    WebRtcAecm_FreeCore(aecm->aecmCore);
    WebRtc_FreeBuffer(aecm->farendBuf);
    free(aecm);

    return 0;
}

WebRtc_Word32 WebRtcAecm_Init(void *aecmInst, WebRtc_Word32 sampFreq)
{
    aecmob_t *aecm = aecmInst;
    AecmConfig aecConfig;

    if (aecm == NULL)
    {
        return -1;
    }

    if (sampFreq != 8000 && sampFreq != 16000)
    {
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }
    aecm->sampFreq = sampFreq;

    // Initialize AECM core
    if (WebRtcAecm_InitCore(aecm->aecmCore, aecm->sampFreq) == -1)
    {
        aecm->lastError = AECM_UNSPECIFIED_ERROR;
        return -1;
    }

    // Initialize farend buffer
    if (WebRtc_InitBuffer(aecm->farendBuf) == -1)
    {
        aecm->lastError = AECM_UNSPECIFIED_ERROR;
        return -1;
    }

    aecm->initFlag = kInitCheck; // indicates that initialization has been done

    aecm->delayChange = 1;

    aecm->sum = 0;
    aecm->counter = 0;
    aecm->checkBuffSize = 1;
    aecm->firstVal = 0;

    aecm->ECstartup = 1;
    aecm->bufSizeStart = 0;
    aecm->checkBufSizeCtr = 0;
    aecm->filtDelay = 0;
    aecm->timeForDelayChange = 0;
    aecm->knownDelay = 0;
    aecm->lastDelayDiff = 0;

    memset(&aecm->farendOld[0][0], 0, 160);

    // Default settings.
    aecConfig.cngMode = AecmTrue;
    aecConfig.echoMode = 3;

    if (WebRtcAecm_set_config(aecm, aecConfig) == -1)
    {
        aecm->lastError = AECM_UNSPECIFIED_ERROR;
        return -1;
    }

    return 0;
}

WebRtc_Word32 WebRtcAecm_BufferFarend(void *aecmInst, const WebRtc_Word16 *farend,
                                      WebRtc_Word16 nrOfSamples)
{
    aecmob_t *aecm = aecmInst;
    WebRtc_Word32 retVal = 0;

    if (aecm == NULL)
    {
        return -1;
    }

    if (farend == NULL)
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }

    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    if (nrOfSamples != 80 && nrOfSamples != 160)
    {
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }

    // TODO: Is this really a good idea?
    if (!aecm->ECstartup)
    {
        WebRtcAecm_DelayComp(aecm);
    }

    WebRtc_WriteBuffer(aecm->farendBuf, farend, (size_t) nrOfSamples);

    return retVal;
}

WebRtc_Word32 WebRtcAecm_Process(void *aecmInst, const WebRtc_Word16 *nearendNoisy,
                                 const WebRtc_Word16 *nearendClean, WebRtc_Word16 *out,
                                 WebRtc_Word16 nrOfSamples, WebRtc_Word16 msInSndCardBuf)
{
    aecmob_t *aecm = aecmInst;
    WebRtc_Word32 retVal = 0;
    short i;
    short nmbrOfFilledBuffers;
    short nBlocks10ms;
    short nFrames;
#ifdef AEC_DEBUG
    short msInAECBuf;
#endif

#ifdef ARM_WINM_LOG
    __int64 freq, start, end, diff;
    unsigned int milliseconds;
    DWORD temp;
#elif defined MAC_IPHONE_PRINT
    //       double endtime = 0, starttime = 0;
    struct timeval starttime;
    struct timeval endtime;
    static long int timeused = 0;
    static int timecount = 0;
#endif

    if (aecm == NULL)
    {
        return -1;
    }

    if (nearendNoisy == NULL)
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }

    if (out == NULL)
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }

    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    if (nrOfSamples != 80 && nrOfSamples != 160)
    {
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }

    if (msInSndCardBuf < 0)
    {
        msInSndCardBuf = 0;
        aecm->lastError = AECM_BAD_PARAMETER_WARNING;
        retVal = -1;
    } else if (msInSndCardBuf > 500)
    {
        msInSndCardBuf = 500;
        aecm->lastError = AECM_BAD_PARAMETER_WARNING;
        retVal = -1;
    }
    msInSndCardBuf += 10;
    aecm->msInSndCardBuf = msInSndCardBuf;

    nFrames = nrOfSamples / FRAME_LEN;
    nBlocks10ms = nFrames / aecm->aecmCore->mult;

    if (aecm->ECstartup)
    {
        if (nearendClean == NULL)
        {
            memcpy(out, nearendNoisy, sizeof(short) * nrOfSamples);
        } else
        {
            memcpy(out, nearendClean, sizeof(short) * nrOfSamples);
        }

        nmbrOfFilledBuffers =
            (short) WebRtc_available_read(aecm->farendBuf) / FRAME_LEN;
        // The AECM is in the start up mode
        // AECM is disabled until the soundcard buffer and farend buffers are OK

        // Mechanism to ensure that the soundcard buffer is reasonably stable.
        if (aecm->checkBuffSize)
        {
            aecm->checkBufSizeCtr++;
            // Before we fill up the far end buffer we require the amount of data on the
            // sound card to be stable (+/-8 ms) compared to the first value. This
            // comparison is made during the following 4 consecutive frames. If it seems
            // to be stable then we start to fill up the far end buffer.

            if (aecm->counter == 0)
            {
                aecm->firstVal = aecm->msInSndCardBuf;
                aecm->sum = 0;
            }

            if (abs(aecm->firstVal - aecm->msInSndCardBuf)
                    < WEBRTC_SPL_MAX(0.2 * aecm->msInSndCardBuf, kSampMsNb))
            {
                aecm->sum += aecm->msInSndCardBuf;
                aecm->counter++;
            } else
            {
                aecm->counter = 0;
            }

            if (aecm->counter * nBlocks10ms >= 6)
            {
                // The farend buffer size is determined in blocks of 80 samples
                // Use 75% of the average value of the soundcard buffer
                aecm->bufSizeStart
                        = WEBRTC_SPL_MIN((3 * aecm->sum
                                        * aecm->aecmCore->mult) / (aecm->counter * 40), BUF_SIZE_FRAMES);
                // buffersize has now been determined
                aecm->checkBuffSize = 0;
            }

            if (aecm->checkBufSizeCtr * nBlocks10ms > 50)
            {
                // for really bad sound cards, don't disable echocanceller for more than 0.5 sec
                aecm->bufSizeStart = WEBRTC_SPL_MIN((3 * aecm->msInSndCardBuf
                                * aecm->aecmCore->mult) / 40, BUF_SIZE_FRAMES);
                aecm->checkBuffSize = 0;
            }
        }

        // if checkBuffSize changed in the if-statement above
        if (!aecm->checkBuffSize)
        {
            // soundcard buffer is now reasonably stable
            // When the far end buffer is filled with approximately the same amount of
            // data as the amount on the sound card we end the start up phase and start
            // to cancel echoes.

            if (nmbrOfFilledBuffers == aecm->bufSizeStart)
            {
                aecm->ECstartup = 0; // Enable the AECM
            } else if (nmbrOfFilledBuffers > aecm->bufSizeStart)
            {
                WebRtc_MoveReadPtr(aecm->farendBuf,
                                   (int) WebRtc_available_read(aecm->farendBuf)
                                   - (int) aecm->bufSizeStart * FRAME_LEN);
                aecm->ECstartup = 0;
            }
        }

    } else
    {
        // AECM is enabled

        // Note only 1 block supported for nb and 2 blocks for wb
        for (i = 0; i < nFrames; i++)
        {
            int16_t farend[FRAME_LEN];
            const int16_t* farend_ptr = NULL;

            nmbrOfFilledBuffers =
                (short) WebRtc_available_read(aecm->farendBuf) / FRAME_LEN;

            // Check that there is data in the far end buffer
            if (nmbrOfFilledBuffers > 0)
            {
                // Get the next 80 samples from the farend buffer
                WebRtc_ReadBuffer(aecm->farendBuf, (void**) &farend_ptr, farend,
                                  FRAME_LEN);

                // Always store the last frame for use when we run out of data
                memcpy(&(aecm->farendOld[i][0]), farend_ptr,
                       FRAME_LEN * sizeof(short));
            } else
            {
                // We have no data so we use the last played frame
                memcpy(farend, &(aecm->farendOld[i][0]), FRAME_LEN * sizeof(short));
                farend_ptr = farend;
            }

            // Call buffer delay estimator when all data is extracted,
            // i,e. i = 0 for NB and i = 1 for WB
            if ((i == 0 && aecm->sampFreq == 8000) || (i == 1 && aecm->sampFreq == 16000))
            {
                WebRtcAecm_EstBufDelay(aecm, aecm->msInSndCardBuf);
            }

#ifdef ARM_WINM_LOG
            // measure tick start
            QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
            QueryPerformanceCounter((LARGE_INTEGER*)&start);
#elif defined MAC_IPHONE_PRINT
            //            starttime = clock()/(double)CLOCKS_PER_SEC;
            gettimeofday(&starttime, NULL);
#endif
            // Call the AECM
            /*WebRtcAecm_ProcessFrame(aecm->aecmCore, farend, &nearend[FRAME_LEN * i],
             &out[FRAME_LEN * i], aecm->knownDelay);*/
            if (nearendClean == NULL)
            {
                if (WebRtcAecm_ProcessFrame(aecm->aecmCore,
                                            farend_ptr,
                                            &nearendNoisy[FRAME_LEN * i],
                                            NULL,
                                            &out[FRAME_LEN * i]) == -1)
                {
                    return -1;
                }
            } else
            {
                if (WebRtcAecm_ProcessFrame(aecm->aecmCore,
                                            farend_ptr,
                                            &nearendNoisy[FRAME_LEN * i],
                                            &nearendClean[FRAME_LEN * i],
                                            &out[FRAME_LEN * i]) == -1)
                {
                    return -1;
                }
            }

#ifdef ARM_WINM_LOG

            // measure tick end
            QueryPerformanceCounter((LARGE_INTEGER*)&end);

            if(end > start)
            {
                diff = ((end - start) * 1000) / (freq/1000);
                milliseconds = (unsigned int)(diff & 0xffffffff);
                WriteFile (logFile, &milliseconds, sizeof(unsigned int), &temp, NULL);
            }
#elif defined MAC_IPHONE_PRINT
            //            endtime = clock()/(double)CLOCKS_PER_SEC;
            //            printf("%f\n", endtime - starttime);

            gettimeofday(&endtime, NULL);

            if( endtime.tv_usec > starttime.tv_usec)
            {
                timeused += endtime.tv_usec - starttime.tv_usec;
            } else
            {
                timeused += endtime.tv_usec + 1000000 - starttime.tv_usec;
            }

            if(++timecount == 1000)
            {
                timecount = 0;
                printf("AEC: %ld\n", timeused);
                timeused = 0;
            }
#endif

        }
    }

#ifdef AEC_DEBUG
    msInAECBuf = (short) WebRtc_available_read(aecm->farendBuf) /
        (kSampMsNb * aecm->aecmCore->mult);
    fwrite(&msInAECBuf, 2, 1, aecm->bufFile);
    fwrite(&(aecm->knownDelay), sizeof(aecm->knownDelay), 1, aecm->delayFile);
#endif

    return retVal;
}

WebRtc_Word32 WebRtcAecm_set_config(void *aecmInst, AecmConfig config)
{
    aecmob_t *aecm = aecmInst;

    if (aecm == NULL)
    {
        return -1;
    }

    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    if (config.cngMode != AecmFalse && config.cngMode != AecmTrue)
    {
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }
    aecm->aecmCore->cngMode = config.cngMode;

    if (config.echoMode < 0 || config.echoMode > 4)
    {
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }
    aecm->echoMode = config.echoMode;

    if (aecm->echoMode == 0)
    {
        aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 3;
        aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 3;
        aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 3;
        aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 3;
        aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 3)
                - (SUPGAIN_ERROR_PARAM_B >> 3);
        aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 3)
                - (SUPGAIN_ERROR_PARAM_D >> 3);
    } else if (aecm->echoMode == 1)
    {
        aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 2;
        aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 2;
        aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 2;
        aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 2;
        aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 2)
                - (SUPGAIN_ERROR_PARAM_B >> 2);
        aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 2)
                - (SUPGAIN_ERROR_PARAM_D >> 2);
    } else if (aecm->echoMode == 2)
    {
        aecm->aecmCore->supGain = SUPGAIN_DEFAULT >> 1;
        aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT >> 1;
        aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A >> 1;
        aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D >> 1;
        aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A >> 1)
                - (SUPGAIN_ERROR_PARAM_B >> 1);
        aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B >> 1)
                - (SUPGAIN_ERROR_PARAM_D >> 1);
    } else if (aecm->echoMode == 3)
    {
        aecm->aecmCore->supGain = SUPGAIN_DEFAULT;
        aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT;
        aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A;
        aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D;
        aecm->aecmCore->supGainErrParamDiffAB = SUPGAIN_ERROR_PARAM_A - SUPGAIN_ERROR_PARAM_B;
        aecm->aecmCore->supGainErrParamDiffBD = SUPGAIN_ERROR_PARAM_B - SUPGAIN_ERROR_PARAM_D;
    } else if (aecm->echoMode == 4)
    {
        aecm->aecmCore->supGain = SUPGAIN_DEFAULT << 1;
        aecm->aecmCore->supGainOld = SUPGAIN_DEFAULT << 1;
        aecm->aecmCore->supGainErrParamA = SUPGAIN_ERROR_PARAM_A << 1;
        aecm->aecmCore->supGainErrParamD = SUPGAIN_ERROR_PARAM_D << 1;
        aecm->aecmCore->supGainErrParamDiffAB = (SUPGAIN_ERROR_PARAM_A << 1)
                - (SUPGAIN_ERROR_PARAM_B << 1);
        aecm->aecmCore->supGainErrParamDiffBD = (SUPGAIN_ERROR_PARAM_B << 1)
                - (SUPGAIN_ERROR_PARAM_D << 1);
    }

    return 0;
}

WebRtc_Word32 WebRtcAecm_get_config(void *aecmInst, AecmConfig *config)
{
    aecmob_t *aecm = aecmInst;

    if (aecm == NULL)
    {
        return -1;
    }

    if (config == NULL)
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }

    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    config->cngMode = aecm->aecmCore->cngMode;
    config->echoMode = aecm->echoMode;

    return 0;
}

WebRtc_Word32 WebRtcAecm_InitEchoPath(void* aecmInst,
                                      const void* echo_path,
                                      size_t size_bytes)
{
    aecmob_t *aecm = aecmInst;
    const WebRtc_Word16* echo_path_ptr = echo_path;

    if ((aecm == NULL) || (echo_path == NULL))
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }
    if (size_bytes != WebRtcAecm_echo_path_size_bytes())
    {
        // Input channel size does not match the size of AECM
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }
    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    WebRtcAecm_InitEchoPathCore(aecm->aecmCore, echo_path_ptr);

    return 0;
}

WebRtc_Word32 WebRtcAecm_GetEchoPath(void* aecmInst,
                                     void* echo_path,
                                     size_t size_bytes)
{
    aecmob_t *aecm = aecmInst;
    WebRtc_Word16* echo_path_ptr = echo_path;

    if ((aecm == NULL) || (echo_path == NULL))
    {
        aecm->lastError = AECM_NULL_POINTER_ERROR;
        return -1;
    }
    if (size_bytes != WebRtcAecm_echo_path_size_bytes())
    {
        // Input channel size does not match the size of AECM
        aecm->lastError = AECM_BAD_PARAMETER_ERROR;
        return -1;
    }
    if (aecm->initFlag != kInitCheck)
    {
        aecm->lastError = AECM_UNINITIALIZED_ERROR;
        return -1;
    }

    memcpy(echo_path_ptr, aecm->aecmCore->channelStored, size_bytes);
    return 0;
}

size_t WebRtcAecm_echo_path_size_bytes()
{
    return (PART_LEN1 * sizeof(WebRtc_Word16));
}

WebRtc_Word32 WebRtcAecm_get_version(WebRtc_Word8 *versionStr, WebRtc_Word16 len)
{
    const char version[] = "AECM 1.2.0";
    const short versionLen = (short)strlen(version) + 1; // +1 for null-termination

    if (versionStr == NULL)
    {
        return -1;
    }

    if (versionLen > len)
    {
        return -1;
    }

    strncpy(versionStr, version, versionLen);
    return 0;
}

WebRtc_Word32 WebRtcAecm_get_error_code(void *aecmInst)
{
    aecmob_t *aecm = aecmInst;

    if (aecm == NULL)
    {
        return -1;
    }

    return aecm->lastError;
}

static int WebRtcAecm_EstBufDelay(aecmob_t *aecm, short msInSndCardBuf)
{
    short delayNew, nSampSndCard;
    short nSampFar = (short) WebRtc_available_read(aecm->farendBuf);
    short diff;

    nSampSndCard = msInSndCardBuf * kSampMsNb * aecm->aecmCore->mult;

    delayNew = nSampSndCard - nSampFar;

    if (delayNew < FRAME_LEN)
    {
        WebRtc_MoveReadPtr(aecm->farendBuf, FRAME_LEN);
        delayNew += FRAME_LEN;
    }

    aecm->filtDelay = WEBRTC_SPL_MAX(0, (8 * aecm->filtDelay + 2 * delayNew) / 10);

    diff = aecm->filtDelay - aecm->knownDelay;
    if (diff > 224)
    {
        if (aecm->lastDelayDiff < 96)
        {
            aecm->timeForDelayChange = 0;
        } else
        {
            aecm->timeForDelayChange++;
        }
    } else if (diff < 96 && aecm->knownDelay > 0)
    {
        if (aecm->lastDelayDiff > 224)
        {
            aecm->timeForDelayChange = 0;
        } else
        {
            aecm->timeForDelayChange++;
        }
    } else
    {
        aecm->timeForDelayChange = 0;
    }
    aecm->lastDelayDiff = diff;

    if (aecm->timeForDelayChange > 25)
    {
        aecm->knownDelay = WEBRTC_SPL_MAX((int)aecm->filtDelay - 160, 0);
    }
    return 0;
}

static int WebRtcAecm_DelayComp(aecmob_t *aecm)
{
    int nSampFar = (int) WebRtc_available_read(aecm->farendBuf);
    int nSampSndCard, delayNew, nSampAdd;
    const int maxStuffSamp = 10 * FRAME_LEN;

    nSampSndCard = aecm->msInSndCardBuf * kSampMsNb * aecm->aecmCore->mult;
    delayNew = nSampSndCard - nSampFar;

    if (delayNew > FAR_BUF_LEN - FRAME_LEN * aecm->aecmCore->mult)
    {
        // The difference of the buffer sizes is larger than the maximum
        // allowed known delay. Compensate by stuffing the buffer.
        nSampAdd = (int)(WEBRTC_SPL_MAX(((nSampSndCard >> 1) - nSampFar),
                FRAME_LEN));
        nSampAdd = WEBRTC_SPL_MIN(nSampAdd, maxStuffSamp);

        WebRtc_MoveReadPtr(aecm->farendBuf, -nSampAdd);
        aecm->delayChange = 1; // the delay needs to be updated
    }

    return 0;
}
