sync_buffer.cc (4046B)
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 #include "modules/audio_coding/neteq/sync_buffer.h" 12 13 #include <algorithm> // Access to min. 14 #include <cstddef> 15 #include <cstdint> 16 17 #include "api/audio/audio_view.h" 18 #include "modules/audio_coding/neteq/audio_multi_vector.h" 19 #include "rtc_base/buffer.h" 20 #include "rtc_base/checks.h" 21 22 namespace webrtc { 23 24 size_t SyncBuffer::FutureLength() const { 25 return Size() - next_index_; 26 } 27 28 void SyncBuffer::PushBack(const AudioMultiVector& append_this) { 29 size_t samples_added = append_this.Size(); 30 AudioMultiVector::PushBack(append_this); 31 AudioMultiVector::PopFront(samples_added); 32 if (samples_added <= next_index_) { 33 next_index_ -= samples_added; 34 } else { 35 // This means that we are pushing out future data that was never used. 36 // RTC_DCHECK_NOTREACHED(); 37 // TODO(hlundin): This assert must be disabled to support 60 ms frames. 38 // This should not happen even for 60 ms frames, but it does. Investigate 39 // why. 40 next_index_ = 0; 41 } 42 dtmf_index_ -= std::min(dtmf_index_, samples_added); 43 } 44 45 void SyncBuffer::PushBackInterleaved(const BufferT<int16_t>& append_this) { 46 const size_t size_before_adding = Size(); 47 AudioMultiVector::PushBackInterleaved(append_this); 48 const size_t samples_added_per_channel = Size() - size_before_adding; 49 RTC_DCHECK_EQ(samples_added_per_channel * Channels(), append_this.size()); 50 AudioMultiVector::PopFront(samples_added_per_channel); 51 next_index_ -= std::min(next_index_, samples_added_per_channel); 52 dtmf_index_ -= std::min(dtmf_index_, samples_added_per_channel); 53 } 54 55 void SyncBuffer::PushFrontZeros(size_t length) { 56 InsertZerosAtIndex(length, 0); 57 } 58 59 void SyncBuffer::InsertZerosAtIndex(size_t length, size_t position) { 60 position = std::min(position, Size()); 61 length = std::min(length, Size() - position); 62 AudioMultiVector::PopBack(length); 63 for (size_t channel = 0; channel < Channels(); ++channel) { 64 channels_[channel]->InsertZerosAt(length, position); 65 } 66 if (next_index_ >= position) { 67 // We are moving the `next_index_` sample. 68 set_next_index(next_index_ + length); // Overflow handled by subfunction. 69 } 70 if (dtmf_index_ > 0 && dtmf_index_ >= position) { 71 // We are moving the `dtmf_index_` sample. 72 set_dtmf_index(dtmf_index_ + length); // Overflow handled by subfunction. 73 } 74 } 75 76 void SyncBuffer::ReplaceAtIndex(const AudioMultiVector& insert_this, 77 size_t length, 78 size_t position) { 79 position = std::min(position, Size()); // Cap `position` in the valid range. 80 length = std::min(length, Size() - position); 81 OverwriteAt(insert_this, length, position); 82 } 83 84 void SyncBuffer::ReplaceAtIndex(const AudioMultiVector& insert_this, 85 size_t position) { 86 ReplaceAtIndex(insert_this, insert_this.Size(), position); 87 } 88 89 bool SyncBuffer::GetNextAudioInterleaved(InterleavedView<int16_t> audio) { 90 RTC_DCHECK_EQ(audio.num_channels(), Channels()); 91 bool read = ReadInterleavedFromIndex(next_index_, audio); 92 if (read) { 93 next_index_ += audio.samples_per_channel(); 94 } 95 return read; 96 } 97 98 void SyncBuffer::IncreaseEndTimestamp(uint32_t increment) { 99 end_timestamp_ += increment; 100 } 101 102 void SyncBuffer::Flush() { 103 Zeros(Size()); 104 next_index_ = Size(); 105 end_timestamp_ = 0; 106 dtmf_index_ = 0; 107 } 108 109 void SyncBuffer::set_next_index(size_t value) { 110 // Cannot set `next_index_` larger than the size of the buffer. 111 next_index_ = std::min(value, Size()); 112 } 113 114 void SyncBuffer::set_dtmf_index(size_t value) { 115 // Cannot set `dtmf_index_` larger than the size of the buffer. 116 dtmf_index_ = std::min(value, Size()); 117 } 118 119 } // namespace webrtc