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