summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/modules/audio_processing/agc/analog_agc.h
blob: 16ea29c496156d551c5c93c7ccac56ef9340ef4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 *  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.
 */

#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_

#include "webrtc/modules/audio_processing/agc/digital_agc.h"
#include "webrtc/modules/audio_processing/agc/include/gain_control.h"
#include "webrtc/typedefs.h"

//#define AGC_DEBUG
//#define MIC_LEVEL_FEEDBACK
#ifdef AGC_DEBUG
#include <stdio.h>
#endif

/* Analog Automatic Gain Control variables:
 * Constant declarations (inner limits inside which no changes are done)
 * In the beginning the range is narrower to widen as soon as the measure
 * 'Rxx160_LP' is inside it. Currently the starting limits are -22.2+/-1dBm0
 * and the final limits -22.2+/-2.5dBm0. These levels makes the speech signal
 * go towards -25.4dBm0 (-31.4dBov). Tuned with wbfile-31.4dBov.pcm
 * The limits are created by running the AGC with a file having the desired
 * signal level and thereafter plotting Rxx160_LP in the dBm0-domain defined
 * by out=10*log10(in/260537279.7); Set the target level to the average level
 * of our measure Rxx160_LP. Remember that the levels are in blocks of 16 in
 * Q(-7). (Example matlab code: round(db2pow(-21.2)*16/2^7) )
 */
#define RXX_BUFFER_LEN  10

static const int16_t kMsecSpeechInner = 520;
static const int16_t kMsecSpeechOuter = 340;

static const int16_t kNormalVadThreshold = 400;

static const int16_t kAlphaShortTerm = 6; // 1 >> 6 = 0.0156
static const int16_t kAlphaLongTerm = 10; // 1 >> 10 = 0.000977

typedef struct
{
    // Configurable parameters/variables
    uint32_t            fs;                 // Sampling frequency
    int16_t             compressionGaindB;  // Fixed gain level in dB
    int16_t             targetLevelDbfs;    // Target level in -dBfs of envelope (default -3)
    int16_t             agcMode;            // Hard coded mode (adaptAna/adaptDig/fixedDig)
    uint8_t             limiterEnable;      // Enabling limiter (on/off (default off))
    WebRtcAgc_config_t  defaultConfig;
    WebRtcAgc_config_t  usedConfig;

    // General variables
    int16_t             initFlag;
    int16_t             lastError;

    // Target level parameters
    // Based on the above: analogTargetLevel = round((32767*10^(-22/20))^2*16/2^7)
    int32_t             analogTargetLevel;  // = RXX_BUFFER_LEN * 846805;       -22 dBfs
    int32_t             startUpperLimit;    // = RXX_BUFFER_LEN * 1066064;      -21 dBfs
    int32_t             startLowerLimit;    // = RXX_BUFFER_LEN * 672641;       -23 dBfs
    int32_t             upperPrimaryLimit;  // = RXX_BUFFER_LEN * 1342095;      -20 dBfs
    int32_t             lowerPrimaryLimit;  // = RXX_BUFFER_LEN * 534298;       -24 dBfs
    int32_t             upperSecondaryLimit;// = RXX_BUFFER_LEN * 2677832;      -17 dBfs
    int32_t             lowerSecondaryLimit;// = RXX_BUFFER_LEN * 267783;       -27 dBfs
    uint16_t            targetIdx;          // Table index for corresponding target level
#ifdef MIC_LEVEL_FEEDBACK
    uint16_t            targetIdxOffset;    // Table index offset for level compensation
#endif
    int16_t             analogTarget;       // Digital reference level in ENV scale

    // Analog AGC specific variables
    int32_t             filterState[8];     // For downsampling wb to nb
    int32_t             upperLimit;         // Upper limit for mic energy
    int32_t             lowerLimit;         // Lower limit for mic energy
    int32_t             Rxx160w32;          // Average energy for one frame
    int32_t             Rxx16_LPw32;        // Low pass filtered subframe energies
    int32_t             Rxx160_LPw32;       // Low pass filtered frame energies
    int32_t             Rxx16_LPw32Max;     // Keeps track of largest energy subframe
    int32_t             Rxx16_vectorw32[RXX_BUFFER_LEN];// Array with subframe energies
    int32_t             Rxx16w32_array[2][5];// Energy values of microphone signal
    int32_t             env[2][10];         // Envelope values of subframes

    int16_t             Rxx16pos;           // Current position in the Rxx16_vectorw32
    int16_t             envSum;             // Filtered scaled envelope in subframes
    int16_t             vadThreshold;       // Threshold for VAD decision
    int16_t             inActive;           // Inactive time in milliseconds
    int16_t             msTooLow;           // Milliseconds of speech at a too low level
    int16_t             msTooHigh;          // Milliseconds of speech at a too high level
    int16_t             changeToSlowMode;   // Change to slow mode after some time at target
    int16_t             firstCall;          // First call to the process-function
    int16_t             msZero;             // Milliseconds of zero input
    int16_t             msecSpeechOuterChange;// Min ms of speech between volume changes
    int16_t             msecSpeechInnerChange;// Min ms of speech between volume changes
    int16_t             activeSpeech;       // Milliseconds of active speech
    int16_t             muteGuardMs;        // Counter to prevent mute action
    int16_t             inQueue;            // 10 ms batch indicator

    // Microphone level variables
    int32_t             micRef;             // Remember ref. mic level for virtual mic
    uint16_t            gainTableIdx;       // Current position in virtual gain table
    int32_t             micGainIdx;         // Gain index of mic level to increase slowly
    int32_t             micVol;             // Remember volume between frames
    int32_t             maxLevel;           // Max possible vol level, incl dig gain
    int32_t             maxAnalog;          // Maximum possible analog volume level
    int32_t             maxInit;            // Initial value of "max"
    int32_t             minLevel;           // Minimum possible volume level
    int32_t             minOutput;          // Minimum output volume level
    int32_t             zeroCtrlMax;        // Remember max gain => don't amp low input

    int16_t             scale;              // Scale factor for internal volume levels
#ifdef MIC_LEVEL_FEEDBACK
    int16_t             numBlocksMicLvlSat;
    uint8_t             micLvlSat;
#endif
    // Structs for VAD and digital_agc
    AgcVad_t            vadMic;
    DigitalAgc_t        digitalAgc;

#ifdef AGC_DEBUG
    FILE*               fpt;
    FILE*               agcLog;
    int32_t             fcount;
#endif

    int16_t             lowLevelSignal;
} Agc_t;

#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AGC_MAIN_SOURCE_ANALOG_AGC_H_