Home | History | Annotate | Download | only in neteq
      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 
     21 namespace webrtc {
     22 
     23 // Forward declarations.
     24 class BackgroundNoise;
     25 class RandomVector;
     26 class 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.
     32 class 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 
    175 struct 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