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_fax.h" 12 13#include <assert.h> 14 15#include <algorithm> 16 17#include "webrtc/modules/audio_coding/neteq/decoder_database.h" 18#include "webrtc/modules/audio_coding/neteq/sync_buffer.h" 19 20namespace webrtc { 21 22Operations DecisionLogicFax::GetDecisionSpecialized( 23 const SyncBuffer& sync_buffer, 24 const Expand& expand, 25 int decoder_frame_length, 26 const RTPHeader* packet_header, 27 Modes prev_mode, 28 bool play_dtmf, 29 bool* reset_decoder) { 30 assert(playout_mode_ == kPlayoutFax || playout_mode_ == kPlayoutOff); 31 uint32_t target_timestamp = sync_buffer.end_timestamp(); 32 uint32_t available_timestamp = 0; 33 int is_cng_packet = 0; 34 if (packet_header) { 35 available_timestamp = packet_header->timestamp; 36 is_cng_packet = 37 decoder_database_->IsComfortNoise(packet_header->payloadType); 38 } 39 if (is_cng_packet) { 40 if (static_cast<int32_t>((generated_noise_samples_ + target_timestamp) 41 - available_timestamp) >= 0) { 42 // Time to play this packet now. 43 return kRfc3389Cng; 44 } else { 45 // Wait before playing this packet. 46 return kRfc3389CngNoPacket; 47 } 48 } 49 if (!packet_header) { 50 // No packet. If in CNG mode, play as usual. Otherwise, use other method to 51 // generate data. 52 if (cng_state_ == kCngRfc3389On) { 53 // Continue playing comfort noise. 54 return kRfc3389CngNoPacket; 55 } else if (cng_state_ == kCngInternalOn) { 56 // Continue playing codec-internal comfort noise. 57 return kCodecInternalCng; 58 } else { 59 // Nothing to play. Generate some data to play out. 60 switch (playout_mode_) { 61 case kPlayoutOff: 62 return kAlternativePlc; 63 case kPlayoutFax: 64 return kAudioRepetition; 65 default: 66 assert(false); 67 return kUndefined; 68 } 69 } 70 } else if (target_timestamp == available_timestamp) { 71 return kNormal; 72 } else { 73 if (static_cast<int32_t>((generated_noise_samples_ + target_timestamp) 74 - available_timestamp) >= 0) { 75 return kNormal; 76 } else { 77 // If currently playing comfort noise, continue with that. Do not 78 // increase the timestamp counter since generated_noise_samples_ will 79 // be increased. 80 if (cng_state_ == kCngRfc3389On) { 81 return kRfc3389CngNoPacket; 82 } else if (cng_state_ == kCngInternalOn) { 83 return kCodecInternalCng; 84 } else { 85 // Otherwise, do packet-loss concealment and increase the 86 // timestamp while waiting for the time to play this packet. 87 switch (playout_mode_) { 88 case kPlayoutOff: 89 return kAlternativePlcIncreaseTimestamp; 90 case kPlayoutFax: 91 return kAudioRepetitionIncreaseTimestamp; 92 default: 93 assert(0); 94 return kUndefined; 95 } 96 } 97 } 98 } 99} 100 101 102} // namespace webrtc 103