OLD | NEW |
| (Empty) |
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 "webrtc/modules/audio_processing/agc/circular_buffer.h" | |
12 | |
13 #include <assert.h> | |
14 #include <stdlib.h> | |
15 | |
16 namespace webrtc { | |
17 | |
18 AgcCircularBuffer::AgcCircularBuffer(int buffer_size) | |
19 : buffer_(new double[buffer_size]), | |
20 is_full_(false), | |
21 index_(0), | |
22 buffer_size_(buffer_size), | |
23 sum_(0) {} | |
24 | |
25 AgcCircularBuffer::~AgcCircularBuffer() {} | |
26 | |
27 void AgcCircularBuffer::Reset() { | |
28 is_full_ = false; | |
29 index_ = 0; | |
30 sum_ = 0; | |
31 } | |
32 | |
33 AgcCircularBuffer* AgcCircularBuffer::Create(int buffer_size) { | |
34 if (buffer_size <= 0) | |
35 return NULL; | |
36 return new AgcCircularBuffer(buffer_size); | |
37 } | |
38 | |
39 double AgcCircularBuffer::Oldest() const { | |
40 if (!is_full_) | |
41 return buffer_[0]; | |
42 else | |
43 return buffer_[index_]; | |
44 } | |
45 | |
46 double AgcCircularBuffer::Mean() { | |
47 double m; | |
48 if (is_full_) { | |
49 m = sum_ / buffer_size_; | |
50 } else { | |
51 if (index_ > 0) | |
52 m = sum_ / index_; | |
53 else | |
54 m = 0; | |
55 } | |
56 return m; | |
57 } | |
58 | |
59 void AgcCircularBuffer::Insert(double value) { | |
60 if (is_full_) { | |
61 sum_ -= buffer_[index_]; | |
62 } | |
63 sum_ += value; | |
64 buffer_[index_] = value; | |
65 index_++; | |
66 if (index_ >= buffer_size_) { | |
67 is_full_ = true; | |
68 index_ = 0; | |
69 } | |
70 } | |
71 int AgcCircularBuffer::BufferLevel() { | |
72 if (is_full_) | |
73 return buffer_size_; | |
74 return index_; | |
75 } | |
76 | |
77 int AgcCircularBuffer::Get(int index, double* value) const { | |
78 int err = ConvertToLinearIndex(&index); | |
79 if (err < 0) | |
80 return -1; | |
81 *value = buffer_[index]; | |
82 return 0; | |
83 } | |
84 | |
85 int AgcCircularBuffer::Set(int index, double value) { | |
86 int err = ConvertToLinearIndex(&index); | |
87 if (err < 0) | |
88 return -1; | |
89 | |
90 sum_ -= buffer_[index]; | |
91 buffer_[index] = value; | |
92 sum_ += value; | |
93 return 0; | |
94 } | |
95 | |
96 int AgcCircularBuffer::ConvertToLinearIndex(int* index) const { | |
97 if (*index < 0 || *index >= buffer_size_) | |
98 return -1; | |
99 | |
100 if (!is_full_ && *index >= index_) | |
101 return -1; | |
102 | |
103 *index = index_ - 1 - *index; | |
104 if (*index < 0) | |
105 *index += buffer_size_; | |
106 return 0; | |
107 } | |
108 | |
109 int AgcCircularBuffer::RemoveTransient(int width_threshold, | |
110 double val_threshold) { | |
111 if (!is_full_ && index_ < width_threshold + 2) | |
112 return 0; | |
113 | |
114 int index_1 = 0; | |
115 int index_2 = width_threshold + 1; | |
116 double v = 0; | |
117 if (Get(index_1, &v) < 0) | |
118 return -1; | |
119 if (v < val_threshold) { | |
120 Set(index_1, 0); | |
121 int index; | |
122 for (index = index_2; index > index_1; index--) { | |
123 if (Get(index, &v) < 0) | |
124 return -1; | |
125 if (v < val_threshold) | |
126 break; | |
127 } | |
128 for (; index > index_1; index--) { | |
129 if (Set(index, 0.0) < 0) | |
130 return -1; | |
131 } | |
132 } | |
133 return 0; | |
134 } | |
135 | |
136 } // namespace webrtc | |
OLD | NEW |