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 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" 12 13 #include <algorithm> 14 15 #include "webrtc/modules/audio_coding/neteq/buffer_level_filter.h" 16 #include "webrtc/modules/audio_coding/neteq/decision_logic_fax.h" 17 #include "webrtc/modules/audio_coding/neteq/decision_logic_normal.h" 18 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" 19 #include "webrtc/modules/audio_coding/neteq/expand.h" 20 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" 21 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" 22 #include "webrtc/system_wrappers/include/logging.h" 23 24 namespace webrtc { 25 26 DecisionLogic* DecisionLogic::Create(int fs_hz, 27 size_t output_size_samples, 28 NetEqPlayoutMode playout_mode, 29 DecoderDatabase* decoder_database, 30 const PacketBuffer& packet_buffer, 31 DelayManager* delay_manager, 32 BufferLevelFilter* buffer_level_filter) { 33 switch (playout_mode) { 34 case kPlayoutOn: 35 case kPlayoutStreaming: 36 return new DecisionLogicNormal(fs_hz, 37 output_size_samples, 38 playout_mode, 39 decoder_database, 40 packet_buffer, 41 delay_manager, 42 buffer_level_filter); 43 case kPlayoutFax: 44 case kPlayoutOff: 45 return new DecisionLogicFax(fs_hz, 46 output_size_samples, 47 playout_mode, 48 decoder_database, 49 packet_buffer, 50 delay_manager, 51 buffer_level_filter); 52 } 53 // This line cannot be reached, but must be here to avoid compiler errors. 54 assert(false); 55 return NULL; 56 } 57 58 DecisionLogic::DecisionLogic(int fs_hz, 59 size_t output_size_samples, 60 NetEqPlayoutMode playout_mode, 61 DecoderDatabase* decoder_database, 62 const PacketBuffer& packet_buffer, 63 DelayManager* delay_manager, 64 BufferLevelFilter* buffer_level_filter) 65 : decoder_database_(decoder_database), 66 packet_buffer_(packet_buffer), 67 delay_manager_(delay_manager), 68 buffer_level_filter_(buffer_level_filter), 69 cng_state_(kCngOff), 70 generated_noise_samples_(0), 71 packet_length_samples_(0), 72 sample_memory_(0), 73 prev_time_scale_(false), 74 timescale_hold_off_(kMinTimescaleInterval), 75 num_consecutive_expands_(0), 76 playout_mode_(playout_mode) { 77 delay_manager_->set_streaming_mode(playout_mode_ == kPlayoutStreaming); 78 SetSampleRate(fs_hz, output_size_samples); 79 } 80 81 void DecisionLogic::Reset() { 82 cng_state_ = kCngOff; 83 generated_noise_samples_ = 0; 84 packet_length_samples_ = 0; 85 sample_memory_ = 0; 86 prev_time_scale_ = false; 87 timescale_hold_off_ = 0; 88 num_consecutive_expands_ = 0; 89 } 90 91 void DecisionLogic::SoftReset() { 92 packet_length_samples_ = 0; 93 sample_memory_ = 0; 94 prev_time_scale_ = false; 95 timescale_hold_off_ = kMinTimescaleInterval; 96 } 97 98 void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { 99 // TODO(hlundin): Change to an enumerator and skip assert. 100 assert(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 || fs_hz == 48000); 101 fs_mult_ = fs_hz / 8000; 102 output_size_samples_ = output_size_samples; 103 } 104 105 Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer, 106 const Expand& expand, 107 size_t decoder_frame_length, 108 const RTPHeader* packet_header, 109 Modes prev_mode, 110 bool play_dtmf, bool* reset_decoder) { 111 if (prev_mode == kModeRfc3389Cng || 112 prev_mode == kModeCodecInternalCng || 113 prev_mode == kModeExpand) { 114 // If last mode was CNG (or Expand, since this could be covering up for 115 // a lost CNG packet), increase the |generated_noise_samples_| counter. 116 generated_noise_samples_ += output_size_samples_; 117 // Remember that CNG is on. This is needed if comfort noise is interrupted 118 // by DTMF. 119 if (prev_mode == kModeRfc3389Cng) { 120 cng_state_ = kCngRfc3389On; 121 } else if (prev_mode == kModeCodecInternalCng) { 122 cng_state_ = kCngInternalOn; 123 } 124 } 125 126 const size_t samples_left = 127 sync_buffer.FutureLength() - expand.overlap_length(); 128 const size_t cur_size_samples = 129 samples_left + packet_buffer_.NumSamplesInBuffer(decoder_database_, 130 decoder_frame_length); 131 132 prev_time_scale_ = prev_time_scale_ && 133 (prev_mode == kModeAccelerateSuccess || 134 prev_mode == kModeAccelerateLowEnergy || 135 prev_mode == kModePreemptiveExpandSuccess || 136 prev_mode == kModePreemptiveExpandLowEnergy); 137 138 FilterBufferLevel(cur_size_samples, prev_mode); 139 140 return GetDecisionSpecialized(sync_buffer, expand, decoder_frame_length, 141 packet_header, prev_mode, play_dtmf, 142 reset_decoder); 143 } 144 145 void DecisionLogic::ExpandDecision(Operations operation) { 146 if (operation == kExpand) { 147 num_consecutive_expands_++; 148 } else { 149 num_consecutive_expands_ = 0; 150 } 151 } 152 153 void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples, 154 Modes prev_mode) { 155 const int elapsed_time_ms = 156 static_cast<int>(output_size_samples_ / (8 * fs_mult_)); 157 delay_manager_->UpdateCounters(elapsed_time_ms); 158 159 // Do not update buffer history if currently playing CNG since it will bias 160 // the filtered buffer level. 161 if ((prev_mode != kModeRfc3389Cng) && (prev_mode != kModeCodecInternalCng)) { 162 buffer_level_filter_->SetTargetBufferLevel( 163 delay_manager_->base_target_level()); 164 165 size_t buffer_size_packets = 0; 166 if (packet_length_samples_ > 0) { 167 // Calculate size in packets. 168 buffer_size_packets = buffer_size_samples / packet_length_samples_; 169 } 170 int sample_memory_local = 0; 171 if (prev_time_scale_) { 172 sample_memory_local = sample_memory_; 173 timescale_hold_off_ = kMinTimescaleInterval; 174 } 175 buffer_level_filter_->Update(buffer_size_packets, sample_memory_local, 176 packet_length_samples_); 177 prev_time_scale_ = false; 178 } 179 180 timescale_hold_off_ = std::max(timescale_hold_off_ - 1, 0); 181 } 182 183 } // namespace webrtc 184