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/interface/logging.h" 23 24 namespace webrtc { 25 26 DecisionLogic* DecisionLogic::Create(int fs_hz, 27 int 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 int 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, int 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 int 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 int samples_left = static_cast<int>( 127 sync_buffer.FutureLength() - expand.overlap_length()); 128 const int cur_size_samples = 129 samples_left + packet_buffer_.NumSamplesInBuffer(decoder_database_, 130 decoder_frame_length); 131 LOG(LS_VERBOSE) << "Buffers: " << packet_buffer_.NumPacketsInBuffer() << 132 " packets * " << decoder_frame_length << " samples/packet + " << 133 samples_left << " samples in sync buffer = " << cur_size_samples; 134 135 prev_time_scale_ = prev_time_scale_ && 136 (prev_mode == kModeAccelerateSuccess || 137 prev_mode == kModeAccelerateLowEnergy || 138 prev_mode == kModePreemptiveExpandSuccess || 139 prev_mode == kModePreemptiveExpandLowEnergy); 140 141 FilterBufferLevel(cur_size_samples, prev_mode); 142 143 return GetDecisionSpecialized(sync_buffer, expand, decoder_frame_length, 144 packet_header, prev_mode, play_dtmf, 145 reset_decoder); 146 } 147 148 void DecisionLogic::ExpandDecision(Operations operation) { 149 if (operation == kExpand) { 150 num_consecutive_expands_++; 151 } else { 152 num_consecutive_expands_ = 0; 153 } 154 } 155 156 void DecisionLogic::FilterBufferLevel(int buffer_size_samples, 157 Modes prev_mode) { 158 const int elapsed_time_ms = output_size_samples_ / (8 * fs_mult_); 159 delay_manager_->UpdateCounters(elapsed_time_ms); 160 161 // Do not update buffer history if currently playing CNG since it will bias 162 // the filtered buffer level. 163 if ((prev_mode != kModeRfc3389Cng) && (prev_mode != kModeCodecInternalCng)) { 164 buffer_level_filter_->SetTargetBufferLevel( 165 delay_manager_->base_target_level()); 166 167 int buffer_size_packets = 0; 168 if (packet_length_samples_ > 0) { 169 // Calculate size in packets. 170 buffer_size_packets = buffer_size_samples / packet_length_samples_; 171 } 172 int sample_memory_local = 0; 173 if (prev_time_scale_) { 174 sample_memory_local = sample_memory_; 175 timescale_hold_off_ = kMinTimescaleInterval; 176 } 177 buffer_level_filter_->Update(buffer_size_packets, sample_memory_local, 178 packet_length_samples_); 179 prev_time_scale_ = false; 180 } 181 182 timescale_hold_off_ = std::max(timescale_hold_off_ - 1, 0); 183 } 184 185 } // namespace webrtc 186