OLD | NEW |
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 |
OLD | NEW |