1 /*
2  *  Copyright (c) 2012 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 #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
12 #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
13 
14 #include <string.h>  // size_t
15 
16 #include "webrtc/base/constructormagic.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
19 #include "webrtc/modules/audio_coding/neteq/include/neteq.h"
20 #include "webrtc/typedefs.h"
21 
22 namespace webrtc {
23 
24 // Forward declarations.
25 class PostDecodeVad;
26 
27 // This class handles estimation of background noise parameters.
28 class BackgroundNoise {
29  public:
30   // TODO(hlundin): For 48 kHz support, increase kMaxLpcOrder to 10.
31   // Will work anyway, but probably sound a little worse.
32   static const size_t kMaxLpcOrder = 8;  // 32000 / 8000 + 4.
33 
34   explicit BackgroundNoise(size_t num_channels);
35   virtual ~BackgroundNoise();
36 
37   void Reset();
38 
39   // Updates the parameter estimates based on the signal currently in the
40   // |sync_buffer|, and on the latest decision in |vad| if it is running.
41   void Update(const AudioMultiVector& sync_buffer,
42               const PostDecodeVad& vad);
43 
44   // Returns |energy_| for |channel|.
45   int32_t Energy(size_t channel) const;
46 
47   // Sets the value of |mute_factor_| for |channel| to |value|.
48   void SetMuteFactor(size_t channel, int16_t value);
49 
50   // Returns |mute_factor_| for |channel|.
51   int16_t MuteFactor(size_t channel) const;
52 
53   // Returns a pointer to |filter_| for |channel|.
54   const int16_t* Filter(size_t channel) const;
55 
56   // Returns a pointer to |filter_state_| for |channel|.
57   const int16_t* FilterState(size_t channel) const;
58 
59   // Copies |length| elements from |input| to the filter state. Will not copy
60   // more than |kMaxLpcOrder| elements.
61   void SetFilterState(size_t channel, const int16_t* input, size_t length);
62 
63   // Returns |scale_| for |channel|.
64   int16_t Scale(size_t channel) const;
65 
66   // Returns |scale_shift_| for |channel|.
67   int16_t ScaleShift(size_t channel) const;
68 
69   // Accessors.
initialized()70   bool initialized() const { return initialized_; }
mode()71   NetEq::BackgroundNoiseMode mode() const { return mode_; }
72 
73   // Sets the mode of the background noise playout for cases when there is long
74   // duration of packet loss.
set_mode(NetEq::BackgroundNoiseMode mode)75   void set_mode(NetEq::BackgroundNoiseMode mode) { mode_ = mode; }
76 
77  private:
78   static const int kThresholdIncrement = 229;  // 0.0035 in Q16.
79   static const size_t kVecLen = 256;
80   static const int kLogVecLen = 8;  // log2(kVecLen).
81   static const size_t kResidualLength = 64;
82   static const int16_t kLogResidualLength = 6;  // log2(kResidualLength)
83 
84   struct ChannelParameters {
85     // Constructor.
ChannelParametersChannelParameters86     ChannelParameters() {
87       Reset();
88     }
89 
ResetChannelParameters90     void Reset() {
91       energy = 2500;
92       max_energy = 0;
93       energy_update_threshold = 500000;
94       low_energy_update_threshold = 0;
95       memset(filter_state, 0, sizeof(filter_state));
96       memset(filter, 0, sizeof(filter));
97       filter[0] = 4096;
98       mute_factor = 0,
99       scale = 20000;
100       scale_shift = 24;
101     }
102 
103     int32_t energy;
104     int32_t max_energy;
105     int32_t energy_update_threshold;
106     int32_t low_energy_update_threshold;
107     int16_t filter_state[kMaxLpcOrder];
108     int16_t filter[kMaxLpcOrder + 1];
109     int16_t mute_factor;
110     int16_t scale;
111     int16_t scale_shift;
112   };
113 
114   int32_t CalculateAutoCorrelation(const int16_t* signal,
115                                    size_t length,
116                                    int32_t* auto_correlation) const;
117 
118   // Increments the energy threshold by a factor 1 + |kThresholdIncrement|.
119   void IncrementEnergyThreshold(size_t channel, int32_t sample_energy);
120 
121   // Updates the filter parameters.
122   void SaveParameters(size_t channel,
123                       const int16_t* lpc_coefficients,
124                       const int16_t* filter_state,
125                       int32_t sample_energy,
126                       int32_t residual_energy);
127 
128   size_t num_channels_;
129   rtc::scoped_ptr<ChannelParameters[]> channel_parameters_;
130   bool initialized_;
131   NetEq::BackgroundNoiseMode mode_;
132 
133   RTC_DISALLOW_COPY_AND_ASSIGN(BackgroundNoise);
134 };
135 
136 }  // namespace webrtc
137 #endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
138