Home | History | Annotate | Download | only in neteq
      1 /*
      2  *  Copyright (c) 2013 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_DECISION_LOGIC_H_
     12 #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
     13 
     14 #include "webrtc/base/constructormagic.h"
     15 #include "webrtc/modules/audio_coding/neteq/defines.h"
     16 #include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
     17 #include "webrtc/typedefs.h"
     18 
     19 namespace webrtc {
     20 
     21 // Forward declarations.
     22 class BufferLevelFilter;
     23 class DecoderDatabase;
     24 class DelayManager;
     25 class Expand;
     26 class PacketBuffer;
     27 class SyncBuffer;
     28 struct RTPHeader;
     29 
     30 // This is the base class for the decision tree implementations. Derived classes
     31 // must implement the method GetDecisionSpecialized().
     32 class DecisionLogic {
     33  public:
     34   // Static factory function which creates different types of objects depending
     35   // on the |playout_mode|.
     36   static DecisionLogic* Create(int fs_hz,
     37                                int output_size_samples,
     38                                NetEqPlayoutMode playout_mode,
     39                                DecoderDatabase* decoder_database,
     40                                const PacketBuffer& packet_buffer,
     41                                DelayManager* delay_manager,
     42                                BufferLevelFilter* buffer_level_filter);
     43 
     44   // Constructor.
     45   DecisionLogic(int fs_hz,
     46                 int output_size_samples,
     47                 NetEqPlayoutMode playout_mode,
     48                 DecoderDatabase* decoder_database,
     49                 const PacketBuffer& packet_buffer,
     50                 DelayManager* delay_manager,
     51                 BufferLevelFilter* buffer_level_filter);
     52 
     53   // Destructor.
     54   virtual ~DecisionLogic() {}
     55 
     56   // Resets object to a clean state.
     57   void Reset();
     58 
     59   // Resets parts of the state. Typically done when switching codecs.
     60   void SoftReset();
     61 
     62   // Sets the sample rate and the output block size.
     63   void SetSampleRate(int fs_hz, int output_size_samples);
     64 
     65   // Returns the operation that should be done next. |sync_buffer| and |expand|
     66   // are provided for reference. |decoder_frame_length| is the number of samples
     67   // obtained from the last decoded frame. If there is a packet available, the
     68   // packet header should be supplied in |packet_header|; otherwise it should
     69   // be NULL. The mode resulting form the last call to NetEqImpl::GetAudio is
     70   // supplied in |prev_mode|. If there is a DTMF event to play, |play_dtmf|
     71   // should be set to true. The output variable |reset_decoder| will be set to
     72   // true if a reset is required; otherwise it is left unchanged (i.e., it can
     73   // remain true if it was true before the call).
     74   // This method end with calling GetDecisionSpecialized to get the actual
     75   // return value.
     76   Operations GetDecision(const SyncBuffer& sync_buffer,
     77                          const Expand& expand,
     78                          int decoder_frame_length,
     79                          const RTPHeader* packet_header,
     80                          Modes prev_mode,
     81                          bool play_dtmf,
     82                          bool* reset_decoder);
     83 
     84   // These methods test the |cng_state_| for different conditions.
     85   bool CngRfc3389On() const { return cng_state_ == kCngRfc3389On; }
     86   bool CngOff() const { return cng_state_ == kCngOff; }
     87 
     88   // Resets the |cng_state_| to kCngOff.
     89   void SetCngOff() { cng_state_ = kCngOff; }
     90 
     91   // Reports back to DecisionLogic whether the decision to do expand remains or
     92   // not. Note that this is necessary, since an expand decision can be changed
     93   // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
     94   // sync buffer.
     95   virtual void ExpandDecision(Operations operation);
     96 
     97   // Adds |value| to |sample_memory_|.
     98   void AddSampleMemory(int32_t value) {
     99     sample_memory_ += value;
    100   }
    101 
    102   // Accessors and mutators.
    103   void set_sample_memory(int32_t value) { sample_memory_ = value; }
    104   int generated_noise_samples() const { return generated_noise_samples_; }
    105   void set_generated_noise_samples(int value) {
    106     generated_noise_samples_ = value;
    107   }
    108   int packet_length_samples() const { return packet_length_samples_; }
    109   void set_packet_length_samples(int value) {
    110     packet_length_samples_ = value;
    111   }
    112   void set_prev_time_scale(bool value) { prev_time_scale_ = value; }
    113   NetEqPlayoutMode playout_mode() const { return playout_mode_; }
    114 
    115  protected:
    116   // The value 6 sets maximum time-stretch rate to about 100 ms/s.
    117   static const int kMinTimescaleInterval = 6;
    118 
    119   enum CngState {
    120     kCngOff,
    121     kCngRfc3389On,
    122     kCngInternalOn
    123   };
    124 
    125   // Returns the operation that should be done next. |sync_buffer| and |expand|
    126   // are provided for reference. |decoder_frame_length| is the number of samples
    127   // obtained from the last decoded frame. If there is a packet available, the
    128   // packet header should be supplied in |packet_header|; otherwise it should
    129   // be NULL. The mode resulting form the last call to NetEqImpl::GetAudio is
    130   // supplied in |prev_mode|. If there is a DTMF event to play, |play_dtmf|
    131   // should be set to true. The output variable |reset_decoder| will be set to
    132   // true if a reset is required; otherwise it is left unchanged (i.e., it can
    133   // remain true if it was true before the call).
    134   // Should be implemented by derived classes.
    135   virtual Operations GetDecisionSpecialized(const SyncBuffer& sync_buffer,
    136                                             const Expand& expand,
    137                                             int decoder_frame_length,
    138                                             const RTPHeader* packet_header,
    139                                             Modes prev_mode,
    140                                             bool play_dtmf,
    141                                             bool* reset_decoder) = 0;
    142 
    143   // Updates the |buffer_level_filter_| with the current buffer level
    144   // |buffer_size_packets|.
    145   void FilterBufferLevel(int buffer_size_packets, Modes prev_mode);
    146 
    147   DecoderDatabase* decoder_database_;
    148   const PacketBuffer& packet_buffer_;
    149   DelayManager* delay_manager_;
    150   BufferLevelFilter* buffer_level_filter_;
    151   int fs_mult_;
    152   int output_size_samples_;
    153   CngState cng_state_;  // Remember if comfort noise is interrupted by other
    154                         // event (e.g., DTMF).
    155   int generated_noise_samples_;
    156   int packet_length_samples_;
    157   int sample_memory_;
    158   bool prev_time_scale_;
    159   int timescale_hold_off_;
    160   int num_consecutive_expands_;
    161   const NetEqPlayoutMode playout_mode_;
    162 
    163  private:
    164   DISALLOW_COPY_AND_ASSIGN(DecisionLogic);
    165 };
    166 
    167 }  // namespace webrtc
    168 #endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECISION_LOGIC_H_
    169