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