<commit_before>/*
 *  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.
 */

/*
 * Contains the API functions for the AEC.
 */
#include "echo_cancellation.h"

#include <math.h>
#ifdef WEBRTC_AEC_DEBUG_DUMP
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>

#include "aec_core.h"
#include "resampler.h"
#include "ring_buffer.h"

#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 int bufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples)
static const int sampMsNb = 8; // samples per ms in nb
// Target suppression levels for nlp modes
// log{0.001, 0.00001, 0.00000001}
static const float targetSupp[3] = {-6.9f, -11.5f, -18.4f};
static const float minOverDrive[3] = {1.0f, 2.0f, 5.0f};
static const int initCheck = 42;

typedef struct {
    int delayCtr;
    int sampFreq;
    int splitSampFreq;
    int scSampFreq;
    float sampFactor; // scSampRate / sampFreq
    short nlpMode;
    short autoOnOff;
    short activity;
    short skewMode;
    short bufSizeStart;
    //short bufResetCtr;  // counts number of noncausal frames
    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;

#ifdef WEBRTC_AEC_DEBUG_DUMP
    FILE *bufFile;
    FILE *delayFile;
    FILE *skewFile;
#endif

    // Structures
    void *farendBuf;
    void *resampler;

    int skewFrCtr;
    int resample; // if the skew is small enough we don't resample
    int highSkewCtr;
    float skew;

    int lastError;

    aec_t *aec;
} aecpc_t;

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

// Stuffs the farend buffer if the estimated delay is too large
static int DelayComp(aecpc_t *aecInst);

WebRtc_Word32 WebRtcAec_Create(void **aecInst)
{
    aecpc_t *aecpc;
    if (aecInst == NULL) {
        return -1;
    }

    aecpc = malloc(sizeof(aecpc_t));
    *aecInst = aecpc;
    if (aecpc == NULL) {
        return -1;
    }

    if (WebRtcAec_CreateAec(&aecpc->aec) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    if (WebRtcApm_CreateBuffer(&aecpc->farendBuf, bufSizeSamp) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    if (WebRtcAec_CreateResampler(&aecpc->resampler) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    aecpc->initFlag = 0;
    aecpc->lastError = 0;

#ifdef WEBRTC_AEC_DEBUG_DUMP
    aecpc->aec->farFile = fopen("aec_far.pcm","wb");
    aecpc->aec->nearFile = fopen("aec_near.pcm","wb");
    aecpc->aec->outFile = fopen("aec_out.pcm","wb");
    aecpc->aec->outLinearFile = fopen("aec_out_linear.pcm","wb");
    aecpc->bufFile = fopen("aec_buf.dat", "wb");
    aecpc->skewFile = fopen("aec_skew.dat", "wb");
    aecpc->delayFile = fopen("aec_delay.dat", "wb");
#endif

    return 0;
}

WebRtc_Word32 WebRtcAec_Free(void *aecInst)
{
    aecpc_t *aecpc = aecInst;

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

#ifdef WEBRTC_AEC_DEBUG_DUMP
    fclose(aecpc->aec->farFile);
    fclose(aecpc->aec->nearFile);<commit_msg>Handle debug files from multiple AEC instances.<commit_after>/*
 *  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.
 */

/*
 * Contains the API functions for the AEC.
 */
#include "echo_cancellation.h"

#include <math.h>
#ifdef WEBRTC_AEC_DEBUG_DUMP
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>

#include "aec_core.h"
#include "resampler.h"
#include "ring_buffer.h"

#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 int bufSizeSamp = BUF_SIZE_FRAMES * FRAME_LEN; // buffer size (samples)
static const int sampMsNb = 8; // samples per ms in nb
// Target suppression levels for nlp modes
// log{0.001, 0.00001, 0.00000001}
static const float targetSupp[3] = {-6.9f, -11.5f, -18.4f};
static const float minOverDrive[3] = {1.0f, 2.0f, 5.0f};
static const int initCheck = 42;

#ifdef WEBRTC_AEC_DEBUG_DUMP
static int instance_count = 0;
#endif

typedef struct {
    int delayCtr;
    int sampFreq;
    int splitSampFreq;
    int scSampFreq;
    float sampFactor; // scSampRate / sampFreq
    short nlpMode;
    short autoOnOff;
    short activity;
    short skewMode;
    short bufSizeStart;
    //short bufResetCtr;  // counts number of noncausal frames
    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;

#ifdef WEBRTC_AEC_DEBUG_DUMP
    FILE *bufFile;
    FILE *delayFile;
    FILE *skewFile;
#endif

    // Structures
    void *farendBuf;
    void *resampler;

    int skewFrCtr;
    int resample; // if the skew is small enough we don't resample
    int highSkewCtr;
    float skew;

    int lastError;

    aec_t *aec;
} aecpc_t;

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

// Stuffs the farend buffer if the estimated delay is too large
static int DelayComp(aecpc_t *aecInst);

WebRtc_Word32 WebRtcAec_Create(void **aecInst)
{
    aecpc_t *aecpc;
    if (aecInst == NULL) {
        return -1;
    }

    aecpc = malloc(sizeof(aecpc_t));
    *aecInst = aecpc;
    if (aecpc == NULL) {
        return -1;
    }

    if (WebRtcAec_CreateAec(&aecpc->aec) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    if (WebRtcApm_CreateBuffer(&aecpc->farendBuf, bufSizeSamp) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    if (WebRtcAec_CreateResampler(&aecpc->resampler) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    aecpc->initFlag = 0;
    aecpc->lastError = 0;

#ifdef WEBRTC_AEC_DEBUG_DUMP
    {
      char filename[64];
      sprintf(filename, "aec_far%d.pcm", instance_count);
      aecpc->aec->farFile = fopen(filename, "wb");
      sprintf(filename, "aec_near%d.pcm", instance_count);
      aecpc->aec->nearFile = fopen(filename, "wb");
      sprintf(filename, "aec_out%d.pcm", instance_count);
      aecpc->aec->outFile = fopen(filename, "wb");
      sprintf(filename, "aec_out_linear%d.pcm", instance_count);
      aecpc->aec->outLinearFile = fopen(filename, "wb");
      sprintf(filename, "aec_buf%d.dat", instance_count);
      aecpc->bufFile = fopen(filename, "wb");
      sprintf(filename, "aec_skew%d.dat", instance_count);
      aecpc->skewFile = fopen(filename, "wb");
      sprintf(filename, "aec_delay%d.dat", instance_count);
      aecpc->delayFile = fopen(filename, "wb");
      instance_count++;
    }
#endif

    return 0;
}

WebRtc_Word32 WebRtcAec_Free(void *aecInst)
{
    aecpc_t *aecpc = aecInst;

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

#ifdef WEBRTC_AEC_DEBUG_DUMP
    fclose(aecpc->aec->farFile);
    fclose(aecpc->aec->nearFile);
{'fraction_non_alphanumeric': 0.1084841628959276, 'fraction_numerical': 0.01572398190045249, 'mean_word_length': 3.068568798895536, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7480040', 'n_tokens_mistral': 3350, 'n_tokens_neox': 3187, 'n_words': 888}