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_EXPAND_H_
12#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_EXPAND_H_
13
14#include <assert.h>
15
16#include "webrtc/base/constructormagic.h"
17#include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
18#include "webrtc/system_wrappers/interface/scoped_ptr.h"
19#include "webrtc/typedefs.h"
20
21namespace webrtc {
22
23// Forward declarations.
24class BackgroundNoise;
25class RandomVector;
26class SyncBuffer;
27
28// This class handles extrapolation of audio data from the sync_buffer to
29// produce packet-loss concealment.
30// TODO(hlundin): Refactor this class to divide the long methods into shorter
31// ones.
32class Expand {
33 public:
34  Expand(BackgroundNoise* background_noise,
35         SyncBuffer* sync_buffer,
36         RandomVector* random_vector,
37         int fs,
38         size_t num_channels)
39      : random_vector_(random_vector),
40        sync_buffer_(sync_buffer),
41        first_expand_(true),
42        fs_hz_(fs),
43        num_channels_(num_channels),
44        consecutive_expands_(0),
45        background_noise_(background_noise),
46        overlap_length_(5 * fs / 8000),
47        lag_index_direction_(0),
48        current_lag_index_(0),
49        stop_muting_(false),
50        channel_parameters_(new ChannelParameters[num_channels_]) {
51    assert(fs == 8000 || fs == 16000 || fs == 32000 || fs == 48000);
52    assert(fs <= kMaxSampleRate);  // Should not be possible.
53    assert(num_channels_ > 0);
54    memset(expand_lags_, 0, sizeof(expand_lags_));
55    Reset();
56  }
57
58  virtual ~Expand() {}
59
60  // Resets the object.
61  virtual void Reset();
62
63  // The main method to produce concealment data. The data is appended to the
64  // end of |output|.
65  virtual int Process(AudioMultiVector* output);
66
67  // Prepare the object to do extra expansion during normal operation following
68  // a period of expands.
69  virtual void SetParametersForNormalAfterExpand();
70
71  // Prepare the object to do extra expansion during merge operation following
72  // a period of expands.
73  virtual void SetParametersForMergeAfterExpand();
74
75  // Sets the mute factor for |channel| to |value|.
76  void SetMuteFactor(int16_t value, size_t channel) {
77    assert(channel < num_channels_);
78    channel_parameters_[channel].mute_factor = value;
79  }
80
81  // Returns the mute factor for |channel|.
82  int16_t MuteFactor(size_t channel) {
83    assert(channel < num_channels_);
84    return channel_parameters_[channel].mute_factor;
85  }
86
87  // Accessors and mutators.
88  virtual size_t overlap_length() const { return overlap_length_; }
89  int16_t max_lag() const { return max_lag_; }
90
91 protected:
92  static const int kMaxConsecutiveExpands = 200;
93  void GenerateRandomVector(int seed_increment,
94                            size_t length,
95                            int16_t* random_vector);
96
97  void GenerateBackgroundNoise(int16_t* random_vector,
98                               size_t channel,
99                               int16_t mute_slope,
100                               bool too_many_expands,
101                               size_t num_noise_samples,
102                               int16_t* buffer);
103
104  // Initializes member variables at the beginning of an expand period.
105  void InitializeForAnExpandPeriod();
106
107  bool TooManyExpands();
108
109  // Analyzes the signal history in |sync_buffer_|, and set up all parameters
110  // necessary to produce concealment data.
111  void AnalyzeSignal(int16_t* random_vector);
112
113  RandomVector* random_vector_;
114  SyncBuffer* sync_buffer_;
115  bool first_expand_;
116  const int fs_hz_;
117  const size_t num_channels_;
118  int consecutive_expands_;
119
120 private:
121  static const int kUnvoicedLpcOrder = 6;
122  static const int kNumCorrelationCandidates = 3;
123  static const int kDistortionLength = 20;
124  static const int kLpcAnalysisLength = 160;
125  static const int kMaxSampleRate = 48000;
126  static const int kNumLags = 3;
127
128  struct ChannelParameters {
129    // Constructor.
130    ChannelParameters()
131        : mute_factor(16384),
132          ar_gain(0),
133          ar_gain_scale(0),
134          voice_mix_factor(0),
135          current_voice_mix_factor(0),
136          onset(false),
137          mute_slope(0) {
138      memset(ar_filter, 0, sizeof(ar_filter));
139      memset(ar_filter_state, 0, sizeof(ar_filter_state));
140    }
141    int16_t mute_factor;
142    int16_t ar_filter[kUnvoicedLpcOrder + 1];
143    int16_t ar_filter_state[kUnvoicedLpcOrder];
144    int16_t ar_gain;
145    int16_t ar_gain_scale;
146    int16_t voice_mix_factor; /* Q14 */
147    int16_t current_voice_mix_factor; /* Q14 */
148    AudioVector expand_vector0;
149    AudioVector expand_vector1;
150    bool onset;
151    int16_t mute_slope; /* Q20 */
152  };
153
154  // Calculate the auto-correlation of |input|, with length |input_length|
155  // samples. The correlation is calculated from a downsampled version of
156  // |input|, and is written to |output|. The scale factor is written to
157  // |output_scale|. Returns the length of the correlation vector.
158  int16_t Correlation(const int16_t* input, size_t input_length,
159                      int16_t* output, int16_t* output_scale) const;
160
161  void UpdateLagIndex();
162
163  BackgroundNoise* background_noise_;
164  const size_t overlap_length_;
165  int16_t max_lag_;
166  size_t expand_lags_[kNumLags];
167  int lag_index_direction_;
168  int current_lag_index_;
169  bool stop_muting_;
170  scoped_ptr<ChannelParameters[]> channel_parameters_;
171
172  DISALLOW_COPY_AND_ASSIGN(Expand);
173};
174
175struct ExpandFactory {
176  ExpandFactory() {}
177  virtual ~ExpandFactory() {}
178
179  virtual Expand* Create(BackgroundNoise* background_noise,
180                         SyncBuffer* sync_buffer,
181                         RandomVector* random_vector,
182                         int fs,
183                         size_t num_channels) const;
184};
185
186}  // namespace webrtc
187#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_EXPAND_H_
188