Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: webrtc/modules/audio_processing/vad/vad_audio_proc.cc

Issue 1212543002: Pull the Voice Activity Detector out from the AGC (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/agc/agc_audio_proc.h" 11 #include "webrtc/modules/audio_processing/vad/vad_audio_proc.h"
12 12
13 #include <math.h> 13 #include <math.h>
14 #include <stdio.h> 14 #include <stdio.h>
15 15
16 #include "webrtc/common_audio/fft4g.h" 16 #include "webrtc/common_audio/fft4g.h"
17 #include "webrtc/modules/audio_processing/agc/agc_audio_proc_internal.h" 17 #include "webrtc/modules/audio_processing/vad/vad_audio_proc_internal.h"
18 #include "webrtc/modules/audio_processing/agc/pitch_internal.h" 18 #include "webrtc/modules/audio_processing/vad/pitch_internal.h"
19 #include "webrtc/modules/audio_processing/agc/pole_zero_filter.h" 19 #include "webrtc/modules/audio_processing/vad/pole_zero_filter.h"
20 extern "C" { 20 extern "C" {
21 #include "webrtc/modules/audio_coding/codecs/isac/main/source/codec.h" 21 #include "webrtc/modules/audio_coding/codecs/isac/main/source/codec.h"
22 #include "webrtc/modules/audio_coding/codecs/isac/main/source/lpc_analysis.h" 22 #include "webrtc/modules/audio_coding/codecs/isac/main/source/lpc_analysis.h"
23 #include "webrtc/modules/audio_coding/codecs/isac/main/source/pitch_estimator.h" 23 #include "webrtc/modules/audio_coding/codecs/isac/main/source/pitch_estimator.h"
24 #include "webrtc/modules/audio_coding/codecs/isac/main/source/structs.h" 24 #include "webrtc/modules/audio_coding/codecs/isac/main/source/structs.h"
25 } 25 }
26 #include "webrtc/modules/interface/module_common_types.h" 26 #include "webrtc/modules/interface/module_common_types.h"
27 27
28 namespace webrtc { 28 namespace webrtc {
29 29
30 // The following structures are declared anonymous in iSAC's structs.h. To 30 // The following structures are declared anonymous in iSAC's structs.h. To
31 // forward declare them, we use this derived class trick. 31 // forward declare them, we use this derived class trick.
32 struct AgcAudioProc::PitchAnalysisStruct : public ::PitchAnalysisStruct {}; 32 struct VadAudioProc::PitchAnalysisStruct : public ::PitchAnalysisStruct {};
33 struct AgcAudioProc::PreFiltBankstr : public ::PreFiltBankstr {}; 33 struct VadAudioProc::PreFiltBankstr : public ::PreFiltBankstr {};
34 34
35 static const float kFrequencyResolution = kSampleRateHz / 35 static const float kFrequencyResolution =
36 static_cast<float>(AgcAudioProc::kDftSize); 36 kSampleRateHz / static_cast<float>(VadAudioProc::kDftSize);
37 static const int kSilenceRms = 5; 37 static const int kSilenceRms = 5;
38 38
39 // TODO(turajs): Make a Create or Init for AgcAudioProc. 39 // TODO(turajs): Make a Create or Init for VadAudioProc.
40 AgcAudioProc::AgcAudioProc() 40 VadAudioProc::VadAudioProc()
41 : audio_buffer_(), 41 : audio_buffer_(),
42 num_buffer_samples_(kNumPastSignalSamples), 42 num_buffer_samples_(kNumPastSignalSamples),
43 log_old_gain_(-2), 43 log_old_gain_(-2),
44 old_lag_(50), // Arbitrary but valid as pitch-lag (in samples). 44 old_lag_(50), // Arbitrary but valid as pitch-lag (in samples).
45 pitch_analysis_handle_(new PitchAnalysisStruct), 45 pitch_analysis_handle_(new PitchAnalysisStruct),
46 pre_filter_handle_(new PreFiltBankstr), 46 pre_filter_handle_(new PreFiltBankstr),
47 high_pass_filter_(PoleZeroFilter::Create( 47 high_pass_filter_(PoleZeroFilter::Create(kCoeffNumerator,
48 kCoeffNumerator, kFilterOrder, kCoeffDenominator, kFilterOrder)) { 48 kFilterOrder,
49 kCoeffDenominator,
50 kFilterOrder)) {
49 static_assert(kNumPastSignalSamples + kNumSubframeSamples == 51 static_assert(kNumPastSignalSamples + kNumSubframeSamples ==
50 sizeof(kLpcAnalWin) / sizeof(kLpcAnalWin[0]), 52 sizeof(kLpcAnalWin) / sizeof(kLpcAnalWin[0]),
51 "lpc analysis window incorrect size"); 53 "lpc analysis window incorrect size");
52 static_assert(kLpcOrder + 1 == sizeof(kCorrWeight) / sizeof(kCorrWeight[0]), 54 static_assert(kLpcOrder + 1 == sizeof(kCorrWeight) / sizeof(kCorrWeight[0]),
53 "correlation weight incorrect size"); 55 "correlation weight incorrect size");
54 56
55 // TODO(turajs): Are we doing too much in the constructor? 57 // TODO(turajs): Are we doing too much in the constructor?
56 float data[kDftSize]; 58 float data[kDftSize];
57 // Make FFT to initialize. 59 // Make FFT to initialize.
58 ip_[0] = 0; 60 ip_[0] = 0;
59 WebRtc_rdft(kDftSize, 1, data, ip_, w_fft_); 61 WebRtc_rdft(kDftSize, 1, data, ip_, w_fft_);
60 // TODO(turajs): Need to initialize high-pass filter. 62 // TODO(turajs): Need to initialize high-pass filter.
61 63
62 // Initialize iSAC components. 64 // Initialize iSAC components.
63 WebRtcIsac_InitPreFilterbank(pre_filter_handle_.get()); 65 WebRtcIsac_InitPreFilterbank(pre_filter_handle_.get());
64 WebRtcIsac_InitPitchAnalysis(pitch_analysis_handle_.get()); 66 WebRtcIsac_InitPitchAnalysis(pitch_analysis_handle_.get());
65 } 67 }
66 68
67 AgcAudioProc::~AgcAudioProc() {} 69 VadAudioProc::~VadAudioProc() {
70 }
68 71
69 void AgcAudioProc::ResetBuffer() { 72 void VadAudioProc::ResetBuffer() {
70 memcpy(audio_buffer_, &audio_buffer_[kNumSamplesToProcess], 73 memcpy(audio_buffer_, &audio_buffer_[kNumSamplesToProcess],
71 sizeof(audio_buffer_[0]) * kNumPastSignalSamples); 74 sizeof(audio_buffer_[0]) * kNumPastSignalSamples);
72 num_buffer_samples_ = kNumPastSignalSamples; 75 num_buffer_samples_ = kNumPastSignalSamples;
73 } 76 }
74 77
75 int AgcAudioProc::ExtractFeatures(const int16_t* frame, 78 int VadAudioProc::ExtractFeatures(const int16_t* frame,
76 int length, 79 int length,
77 AudioFeatures* features) { 80 AudioFeatures* features) {
78 features->num_frames = 0; 81 features->num_frames = 0;
79 if (length != kNumSubframeSamples) { 82 if (length != kNumSubframeSamples) {
80 return -1; 83 return -1;
81 } 84 }
82 85
83 // High-pass filter to remove the DC component and very low frequency content. 86 // High-pass filter to remove the DC component and very low frequency content.
84 // We have experienced that this high-pass filtering improves voice/non-voiced 87 // We have experienced that this high-pass filtering improves voice/non-voiced
85 // classification. 88 // classification.
86 if (high_pass_filter_->Filter(frame, kNumSubframeSamples, 89 if (high_pass_filter_->Filter(frame, kNumSubframeSamples,
87 &audio_buffer_[num_buffer_samples_]) != 0) { 90 &audio_buffer_[num_buffer_samples_]) != 0) {
88 return -1; 91 return -1;
89 } 92 }
90 93
91 num_buffer_samples_ += kNumSubframeSamples; 94 num_buffer_samples_ += kNumSubframeSamples;
92 if (num_buffer_samples_ < kBufferLength) { 95 if (num_buffer_samples_ < kBufferLength) {
93 return 0; 96 return 0;
94 } 97 }
95 assert(num_buffer_samples_ == kBufferLength); 98 assert(num_buffer_samples_ == kBufferLength);
96 features->num_frames = kNum10msSubframes; 99 features->num_frames = kNum10msSubframes;
97 features->silence = false; 100 features->silence = false;
98 101
99 Rms(features->rms, kMaxNumFrames); 102 Rms(features->rms, kMaxNumFrames);
100 for (int i = 0; i < kNum10msSubframes; ++i) { 103 for (int i = 0; i < kNum10msSubframes; ++i) {
101 if (features->rms[i] < kSilenceRms) { 104 if (features->rms[i] < kSilenceRms) {
102 // PitchAnalysis can cause NaNs in the pitch gain if it's fed silence. 105 // PitchAnalysis can cause NaNs in the pitch gain if it's fed silence.
103 // Bail out here instead. 106 // Bail out here instead.
104 features->silence = true; 107 features->silence = true;
105 ResetBuffer(); 108 ResetBuffer();
106 return 0; 109 return 0;
107 } 110 }
108 } 111 }
109 112
110 PitchAnalysis(features->log_pitch_gain, features->pitch_lag_hz, 113 PitchAnalysis(features->log_pitch_gain, features->pitch_lag_hz,
111 kMaxNumFrames); 114 kMaxNumFrames);
112 FindFirstSpectralPeaks(features->spectral_peak, kMaxNumFrames); 115 FindFirstSpectralPeaks(features->spectral_peak, kMaxNumFrames);
113 ResetBuffer(); 116 ResetBuffer();
114 return 0; 117 return 0;
115 } 118 }
116 119
117 // Computes |kLpcOrder + 1| correlation coefficients. 120 // Computes |kLpcOrder + 1| correlation coefficients.
118 void AgcAudioProc::SubframeCorrelation(double* corr, int length_corr, 121 void VadAudioProc::SubframeCorrelation(double* corr,
122 int length_corr,
119 int subframe_index) { 123 int subframe_index) {
120 assert(length_corr >= kLpcOrder + 1); 124 assert(length_corr >= kLpcOrder + 1);
121 double windowed_audio[kNumSubframeSamples + kNumPastSignalSamples]; 125 double windowed_audio[kNumSubframeSamples + kNumPastSignalSamples];
122 int buffer_index = subframe_index * kNumSubframeSamples; 126 int buffer_index = subframe_index * kNumSubframeSamples;
123 127
124 for (int n = 0; n < kNumSubframeSamples + kNumPastSignalSamples; n++) 128 for (int n = 0; n < kNumSubframeSamples + kNumPastSignalSamples; n++)
125 windowed_audio[n] = audio_buffer_[buffer_index++] * kLpcAnalWin[n]; 129 windowed_audio[n] = audio_buffer_[buffer_index++] * kLpcAnalWin[n];
126 130
127 WebRtcIsac_AutoCorr(corr, windowed_audio, kNumSubframeSamples + 131 WebRtcIsac_AutoCorr(corr, windowed_audio,
128 kNumPastSignalSamples, kLpcOrder); 132 kNumSubframeSamples + kNumPastSignalSamples, kLpcOrder);
129 } 133 }
130 134
131 // Compute |kNum10msSubframes| sets of LPC coefficients, one per 10 ms input. 135 // Compute |kNum10msSubframes| sets of LPC coefficients, one per 10 ms input.
132 // The analysis window is 15 ms long and it is centered on the first half of 136 // The analysis window is 15 ms long and it is centered on the first half of
133 // each 10ms sub-frame. This is equivalent to computing LPC coefficients for the 137 // each 10ms sub-frame. This is equivalent to computing LPC coefficients for the
134 // first half of each 10 ms subframe. 138 // first half of each 10 ms subframe.
135 void AgcAudioProc::GetLpcPolynomials(double* lpc, int length_lpc) { 139 void VadAudioProc::GetLpcPolynomials(double* lpc, int length_lpc) {
136 assert(length_lpc >= kNum10msSubframes * (kLpcOrder + 1)); 140 assert(length_lpc >= kNum10msSubframes * (kLpcOrder + 1));
137 double corr[kLpcOrder + 1]; 141 double corr[kLpcOrder + 1];
138 double reflec_coeff[kLpcOrder]; 142 double reflec_coeff[kLpcOrder];
139 for (int i = 0, offset_lpc = 0; i < kNum10msSubframes; 143 for (int i = 0, offset_lpc = 0; i < kNum10msSubframes;
140 i++, offset_lpc += kLpcOrder + 1) { 144 i++, offset_lpc += kLpcOrder + 1) {
141 SubframeCorrelation(corr, kLpcOrder + 1, i); 145 SubframeCorrelation(corr, kLpcOrder + 1, i);
142 corr[0] *= 1.0001; 146 corr[0] *= 1.0001;
143 // This makes Lev-Durb a bit more stable. 147 // This makes Lev-Durb a bit more stable.
144 for (int k = 0; k < kLpcOrder + 1; k++) { 148 for (int k = 0; k < kLpcOrder + 1; k++) {
145 corr[k] *= kCorrWeight[k]; 149 corr[k] *= kCorrWeight[k];
146 } 150 }
147 WebRtcIsac_LevDurb(&lpc[offset_lpc], reflec_coeff, corr, kLpcOrder); 151 WebRtcIsac_LevDurb(&lpc[offset_lpc], reflec_coeff, corr, kLpcOrder);
148 } 152 }
149 } 153 }
150 154
151 // Fit a second order curve to these 3 points and find the location of the 155 // Fit a second order curve to these 3 points and find the location of the
152 // extremum. The points are inverted before curve fitting. 156 // extremum. The points are inverted before curve fitting.
153 static float QuadraticInterpolation(float prev_val, float curr_val, 157 static float QuadraticInterpolation(float prev_val,
158 float curr_val,
154 float next_val) { 159 float next_val) {
155 // Doing the interpolation in |1 / A(z)|^2. 160 // Doing the interpolation in |1 / A(z)|^2.
156 float fractional_index = 0; 161 float fractional_index = 0;
157 next_val = 1.0f / next_val; 162 next_val = 1.0f / next_val;
158 prev_val = 1.0f / prev_val; 163 prev_val = 1.0f / prev_val;
159 curr_val = 1.0f / curr_val; 164 curr_val = 1.0f / curr_val;
160 165
161 fractional_index = -(next_val - prev_val) * 0.5f / (next_val + prev_val - 166 fractional_index =
162 2.f * curr_val); 167 -(next_val - prev_val) * 0.5f / (next_val + prev_val - 2.f * curr_val);
163 assert(fabs(fractional_index) < 1); 168 assert(fabs(fractional_index) < 1);
164 return fractional_index; 169 return fractional_index;
165 } 170 }
166 171
167 // 1 / A(z), where A(z) is defined by |lpc| is a model of the spectral envelope 172 // 1 / A(z), where A(z) is defined by |lpc| is a model of the spectral envelope
168 // of the input signal. The local maximum of the spectral envelope corresponds 173 // of the input signal. The local maximum of the spectral envelope corresponds
169 // with the local minimum of A(z). It saves complexity, as we save one 174 // with the local minimum of A(z). It saves complexity, as we save one
170 // inversion. Furthermore, we find the first local maximum of magnitude squared, 175 // inversion. Furthermore, we find the first local maximum of magnitude squared,
171 // to save on one square root. 176 // to save on one square root.
172 void AgcAudioProc::FindFirstSpectralPeaks(double* f_peak, int length_f_peak) { 177 void VadAudioProc::FindFirstSpectralPeaks(double* f_peak, int length_f_peak) {
173 assert(length_f_peak >= kNum10msSubframes); 178 assert(length_f_peak >= kNum10msSubframes);
174 double lpc[kNum10msSubframes * (kLpcOrder + 1)]; 179 double lpc[kNum10msSubframes * (kLpcOrder + 1)];
175 // For all sub-frames. 180 // For all sub-frames.
176 GetLpcPolynomials(lpc, kNum10msSubframes * (kLpcOrder + 1)); 181 GetLpcPolynomials(lpc, kNum10msSubframes * (kLpcOrder + 1));
177 182
178 const int kNumDftCoefficients = kDftSize / 2 + 1; 183 const int kNumDftCoefficients = kDftSize / 2 + 1;
179 float data[kDftSize]; 184 float data[kDftSize];
180 185
181 for (int i = 0; i < kNum10msSubframes; i++) { 186 for (int i = 0; i < kNum10msSubframes; i++) {
182 // Convert to float with zero pad. 187 // Convert to float with zero pad.
183 memset(data, 0, sizeof(data)); 188 memset(data, 0, sizeof(data));
184 for (int n = 0; n < kLpcOrder + 1; n++) { 189 for (int n = 0; n < kLpcOrder + 1; n++) {
185 data[n] = static_cast<float>(lpc[i * (kLpcOrder + 1) + n]); 190 data[n] = static_cast<float>(lpc[i * (kLpcOrder + 1) + n]);
186 } 191 }
187 // Transform to frequency domain. 192 // Transform to frequency domain.
188 WebRtc_rdft(kDftSize, 1, data, ip_, w_fft_); 193 WebRtc_rdft(kDftSize, 1, data, ip_, w_fft_);
189 194
190 int index_peak = 0; 195 int index_peak = 0;
191 float prev_magn_sqr = data[0] * data[0]; 196 float prev_magn_sqr = data[0] * data[0];
192 float curr_magn_sqr = data[2] * data[2] + data[3] * data[3]; 197 float curr_magn_sqr = data[2] * data[2] + data[3] * data[3];
193 float next_magn_sqr; 198 float next_magn_sqr;
194 bool found_peak = false; 199 bool found_peak = false;
195 for (int n = 2; n < kNumDftCoefficients - 1; n++) { 200 for (int n = 2; n < kNumDftCoefficients - 1; n++) {
196 next_magn_sqr = data[2 * n] * data[2 * n] + 201 next_magn_sqr =
197 data[2 * n + 1] * data[2 * n + 1]; 202 data[2 * n] * data[2 * n] + data[2 * n + 1] * data[2 * n + 1];
198 if (curr_magn_sqr < prev_magn_sqr && curr_magn_sqr < next_magn_sqr) { 203 if (curr_magn_sqr < prev_magn_sqr && curr_magn_sqr < next_magn_sqr) {
199 found_peak = true; 204 found_peak = true;
200 index_peak = n - 1; 205 index_peak = n - 1;
201 break; 206 break;
202 } 207 }
203 prev_magn_sqr = curr_magn_sqr; 208 prev_magn_sqr = curr_magn_sqr;
204 curr_magn_sqr = next_magn_sqr; 209 curr_magn_sqr = next_magn_sqr;
205 } 210 }
206 float fractional_index = 0; 211 float fractional_index = 0;
207 if (!found_peak) { 212 if (!found_peak) {
208 // Checking if |kNumDftCoefficients - 1| is the local minimum. 213 // Checking if |kNumDftCoefficients - 1| is the local minimum.
209 next_magn_sqr = data[1] * data[1]; 214 next_magn_sqr = data[1] * data[1];
210 if (curr_magn_sqr < prev_magn_sqr && curr_magn_sqr < next_magn_sqr) { 215 if (curr_magn_sqr < prev_magn_sqr && curr_magn_sqr < next_magn_sqr) {
211 index_peak = kNumDftCoefficients - 1; 216 index_peak = kNumDftCoefficients - 1;
212 } 217 }
213 } else { 218 } else {
214 // A peak is found, do a simple quadratic interpolation to get a more 219 // A peak is found, do a simple quadratic interpolation to get a more
215 // accurate estimate of the peak location. 220 // accurate estimate of the peak location.
216 fractional_index = QuadraticInterpolation(prev_magn_sqr, curr_magn_sqr, 221 fractional_index =
217 next_magn_sqr); 222 QuadraticInterpolation(prev_magn_sqr, curr_magn_sqr, next_magn_sqr);
218 } 223 }
219 f_peak[i] = (index_peak + fractional_index) * kFrequencyResolution; 224 f_peak[i] = (index_peak + fractional_index) * kFrequencyResolution;
220 } 225 }
221 } 226 }
222 227
223 // Using iSAC functions to estimate pitch gains & lags. 228 // Using iSAC functions to estimate pitch gains & lags.
224 void AgcAudioProc::PitchAnalysis(double* log_pitch_gains, double* pitch_lags_hz, 229 void VadAudioProc::PitchAnalysis(double* log_pitch_gains,
230 double* pitch_lags_hz,
225 int length) { 231 int length) {
226 // TODO(turajs): This can be "imported" from iSAC & and the next two 232 // TODO(turajs): This can be "imported" from iSAC & and the next two
227 // constants. 233 // constants.
228 assert(length >= kNum10msSubframes); 234 assert(length >= kNum10msSubframes);
229 const int kNumPitchSubframes = 4; 235 const int kNumPitchSubframes = 4;
230 double gains[kNumPitchSubframes]; 236 double gains[kNumPitchSubframes];
231 double lags[kNumPitchSubframes]; 237 double lags[kNumPitchSubframes];
232 238
233 const int kNumSubbandFrameSamples = 240; 239 const int kNumSubbandFrameSamples = 240;
234 const int kNumLookaheadSamples = 24; 240 const int kNumLookaheadSamples = 24;
235 241
236 float lower[kNumSubbandFrameSamples]; 242 float lower[kNumSubbandFrameSamples];
237 float upper[kNumSubbandFrameSamples]; 243 float upper[kNumSubbandFrameSamples];
238 double lower_lookahead[kNumSubbandFrameSamples]; 244 double lower_lookahead[kNumSubbandFrameSamples];
239 double upper_lookahead[kNumSubbandFrameSamples]; 245 double upper_lookahead[kNumSubbandFrameSamples];
240 double lower_lookahead_pre_filter[kNumSubbandFrameSamples + 246 double lower_lookahead_pre_filter[kNumSubbandFrameSamples +
241 kNumLookaheadSamples]; 247 kNumLookaheadSamples];
242 248
243 // Split signal to lower and upper bands 249 // Split signal to lower and upper bands
244 WebRtcIsac_SplitAndFilterFloat(&audio_buffer_[kNumPastSignalSamples], 250 WebRtcIsac_SplitAndFilterFloat(&audio_buffer_[kNumPastSignalSamples], lower,
245 lower, upper, lower_lookahead, upper_lookahead, 251 upper, lower_lookahead, upper_lookahead,
246 pre_filter_handle_.get()); 252 pre_filter_handle_.get());
247 WebRtcIsac_PitchAnalysis(lower_lookahead, lower_lookahead_pre_filter, 253 WebRtcIsac_PitchAnalysis(lower_lookahead, lower_lookahead_pre_filter,
248 pitch_analysis_handle_.get(), lags, gains); 254 pitch_analysis_handle_.get(), lags, gains);
249 255
250 // Lags are computed on lower-band signal with sampling rate half of the 256 // Lags are computed on lower-band signal with sampling rate half of the
251 // input signal. 257 // input signal.
252 GetSubframesPitchParameters(kSampleRateHz / 2, gains, lags, 258 GetSubframesPitchParameters(
253 kNumPitchSubframes, kNum10msSubframes, 259 kSampleRateHz / 2, gains, lags, kNumPitchSubframes, kNum10msSubframes,
254 &log_old_gain_, &old_lag_, 260 &log_old_gain_, &old_lag_, log_pitch_gains, pitch_lags_hz);
255 log_pitch_gains, pitch_lags_hz);
256 } 261 }
257 262
258 void AgcAudioProc::Rms(double* rms, int length_rms) { 263 void VadAudioProc::Rms(double* rms, int length_rms) {
259 assert(length_rms >= kNum10msSubframes); 264 assert(length_rms >= kNum10msSubframes);
260 int offset = kNumPastSignalSamples; 265 int offset = kNumPastSignalSamples;
261 for (int i = 0; i < kNum10msSubframes; i++) { 266 for (int i = 0; i < kNum10msSubframes; i++) {
262 rms[i] = 0; 267 rms[i] = 0;
263 for (int n = 0; n < kNumSubframeSamples; n++, offset++) 268 for (int n = 0; n < kNumSubframeSamples; n++, offset++)
264 rms[i] += audio_buffer_[offset] * audio_buffer_[offset]; 269 rms[i] += audio_buffer_[offset] * audio_buffer_[offset];
265 rms[i] = sqrt(rms[i] / kNumSubframeSamples); 270 rms[i] = sqrt(rms[i] / kNumSubframeSamples);
266 } 271 }
267 } 272 }
268 273
269 } // namespace webrtc 274 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698