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

Side by Side Diff: webrtc/modules/audio_coding/neteq/normal.cc

Issue 2499013002: NetEq: Don't interpolate longer than the output size (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_coding/neteq/normal.h" 11 #include "webrtc/modules/audio_coding/neteq/normal.h"
12 12
13 #include <string.h> // memset, memcpy 13 #include <string.h> // memset, memcpy
14 14
15 #include <algorithm> // min 15 #include <algorithm> // min
16 16
17 #include "webrtc/base/checks.h"
17 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 18 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
18 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" 19 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
19 #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h" 20 #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
20 #include "webrtc/modules/audio_coding/neteq/background_noise.h" 21 #include "webrtc/modules/audio_coding/neteq/background_noise.h"
21 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" 22 #include "webrtc/modules/audio_coding/neteq/decoder_database.h"
22 #include "webrtc/modules/audio_coding/neteq/expand.h" 23 #include "webrtc/modules/audio_coding/neteq/expand.h"
23 24
24 namespace webrtc { 25 namespace webrtc {
25 26
26 int Normal::Process(const int16_t* input, 27 int Normal::Process(const int16_t* input,
27 size_t length, 28 size_t length,
28 Modes last_mode, 29 Modes last_mode,
29 int16_t* external_mute_factor_array, 30 int16_t* external_mute_factor_array,
30 AudioMultiVector* output) { 31 AudioMultiVector* output) {
31 if (length == 0) { 32 if (length == 0) {
32 // Nothing to process. 33 // Nothing to process.
33 output->Clear(); 34 output->Clear();
34 return static_cast<int>(length); 35 return static_cast<int>(length);
35 } 36 }
36 37
37 assert(output->Empty()); 38 RTC_DCHECK(output->Empty());
38 // Output should be empty at this point. 39 // Output should be empty at this point.
39 if (length % output->Channels() != 0) { 40 if (length % output->Channels() != 0) {
40 // The length does not match the number of channels. 41 // The length does not match the number of channels.
41 output->Clear(); 42 output->Clear();
42 return 0; 43 return 0;
43 } 44 }
44 output->PushBackInterleaved(input, length); 45 output->PushBackInterleaved(input, length);
45 46
46 const int fs_mult = fs_hz_ / 8000; 47 const int fs_mult = fs_hz_ / 8000;
47 assert(fs_mult > 0); 48 RTC_DCHECK_GT(fs_mult, 0);
48 // fs_shift = log2(fs_mult), rounded down. 49 // fs_shift = log2(fs_mult), rounded down.
49 // Note that |fs_shift| is not "exact" for 48 kHz. 50 // Note that |fs_shift| is not "exact" for 48 kHz.
50 // TODO(hlundin): Investigate this further. 51 // TODO(hlundin): Investigate this further.
51 const int fs_shift = 30 - WebRtcSpl_NormW32(fs_mult); 52 const int fs_shift = 30 - WebRtcSpl_NormW32(fs_mult);
52 53
53 // Check if last RecOut call resulted in an Expand. If so, we have to take 54 // Check if last RecOut call resulted in an Expand. If so, we have to take
54 // care of some cross-fading and unmuting. 55 // care of some cross-fading and unmuting.
55 if (last_mode == kModeExpand) { 56 if (last_mode == kModeExpand) {
56 // Generate interpolation data using Expand. 57 // Generate interpolation data using Expand.
57 // First, set Expand parameters to appropriate values. 58 // First, set Expand parameters to appropriate values.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 } 109 }
109 if (mute_factor > external_mute_factor_array[channel_ix]) { 110 if (mute_factor > external_mute_factor_array[channel_ix]) {
110 external_mute_factor_array[channel_ix] = 111 external_mute_factor_array[channel_ix] =
111 static_cast<int16_t>(std::min(mute_factor, 16384)); 112 static_cast<int16_t>(std::min(mute_factor, 16384));
112 } 113 }
113 114
114 // If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14). 115 // If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14).
115 int increment = 64 / fs_mult; 116 int increment = 64 / fs_mult;
116 for (size_t i = 0; i < length_per_channel; i++) { 117 for (size_t i = 0; i < length_per_channel; i++) {
117 // Scale with mute factor. 118 // Scale with mute factor.
118 assert(channel_ix < output->Channels()); 119 RTC_DCHECK_LT(channel_ix, output->Channels());
119 assert(i < output->Size()); 120 RTC_DCHECK_LT(i, output->Size());
120 int32_t scaled_signal = (*output)[channel_ix][i] * 121 int32_t scaled_signal = (*output)[channel_ix][i] *
121 external_mute_factor_array[channel_ix]; 122 external_mute_factor_array[channel_ix];
122 // Shift 14 with proper rounding. 123 // Shift 14 with proper rounding.
123 (*output)[channel_ix][i] = 124 (*output)[channel_ix][i] =
124 static_cast<int16_t>((scaled_signal + 8192) >> 14); 125 static_cast<int16_t>((scaled_signal + 8192) >> 14);
125 // Increase mute_factor towards 16384. 126 // Increase mute_factor towards 16384.
126 external_mute_factor_array[channel_ix] = static_cast<int16_t>(std::min( 127 external_mute_factor_array[channel_ix] = static_cast<int16_t>(std::min(
127 external_mute_factor_array[channel_ix] + increment, 16384)); 128 external_mute_factor_array[channel_ix] + increment, 16384));
128 } 129 }
129 130
130 // Interpolate the expanded data into the new vector. 131 // Interpolate the expanded data into the new vector.
131 // (NB/WB/SWB32/SWB48 8/16/32/48 samples.) 132 // (NB/WB/SWB32/SWB48 8/16/32/48 samples.)
132 assert(fs_shift < 3); // Will always be 0, 1, or, 2. 133 RTC_DCHECK_LT(fs_shift, 3); // Will always be 0, 1, or, 2.
133 increment = 4 >> fs_shift; 134 increment = 4 >> fs_shift;
134 int fraction = increment; 135 int fraction = increment;
135 for (size_t i = 0; i < static_cast<size_t>(8 * fs_mult); i++) { 136 // Don't interpolate over more samples than what is in output. When this
137 // cap strikes, the interpolation will likely sound worse, but this is an
138 // emergency operation in response to unexpected input.
139 const size_t interp_len_samples =
140 std::min(static_cast<size_t>(8 * fs_mult), output->Size());
kwiberg-webrtc 2016/11/14 14:36:33 Oooh, I just realized that it's possible to define
141 for (size_t i = 0; i < interp_len_samples; ++i) {
136 // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8 142 // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8
137 // now for legacy bit-exactness. 143 // now for legacy bit-exactness.
138 assert(channel_ix < output->Channels()); 144 RTC_DCHECK_LT(channel_ix, output->Channels());
139 assert(i < output->Size()); 145 RTC_DCHECK_LT(i, output->Size());
140 (*output)[channel_ix][i] = 146 (*output)[channel_ix][i] =
141 static_cast<int16_t>((fraction * (*output)[channel_ix][i] + 147 static_cast<int16_t>((fraction * (*output)[channel_ix][i] +
142 (32 - fraction) * expanded[channel_ix][i] + 8) >> 5); 148 (32 - fraction) * expanded[channel_ix][i] + 8) >> 5);
143 fraction += increment; 149 fraction += increment;
144 } 150 }
145 } 151 }
146 } else if (last_mode == kModeRfc3389Cng) { 152 } else if (last_mode == kModeRfc3389Cng) {
147 assert(output->Channels() == 1); // Not adapted for multi-channel yet. 153 RTC_DCHECK_EQ(output->Channels(), 1); // Not adapted for multi-channel yet.
148 static const size_t kCngLength = 48; 154 static const size_t kCngLength = 48;
149 RTC_DCHECK_LE(static_cast<size_t>(8 * fs_mult), kCngLength); 155 RTC_DCHECK_LE(static_cast<size_t>(8 * fs_mult), kCngLength);
150 int16_t cng_output[kCngLength]; 156 int16_t cng_output[kCngLength];
151 // Reset mute factor and start up fresh. 157 // Reset mute factor and start up fresh.
152 external_mute_factor_array[0] = 16384; 158 external_mute_factor_array[0] = 16384;
153 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder(); 159 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
154 160
155 if (cng_decoder) { 161 if (cng_decoder) {
156 // Generate long enough for 48kHz. 162 // Generate long enough for 48kHz.
157 if (!cng_decoder->Generate(cng_output, 0)) { 163 if (!cng_decoder->Generate(cng_output, 0)) {
158 // Error returned; set return vector to all zeros. 164 // Error returned; set return vector to all zeros.
159 memset(cng_output, 0, sizeof(cng_output)); 165 memset(cng_output, 0, sizeof(cng_output));
160 } 166 }
161 } else { 167 } else {
162 // If no CNG instance is defined, just copy from the decoded data. 168 // If no CNG instance is defined, just copy from the decoded data.
163 // (This will result in interpolating the decoded with itself.) 169 // (This will result in interpolating the decoded with itself.)
164 (*output)[0].CopyTo(fs_mult * 8, 0, cng_output); 170 (*output)[0].CopyTo(fs_mult * 8, 0, cng_output);
165 } 171 }
166 // Interpolate the CNG into the new vector. 172 // Interpolate the CNG into the new vector.
167 // (NB/WB/SWB32/SWB48 8/16/32/48 samples.) 173 // (NB/WB/SWB32/SWB48 8/16/32/48 samples.)
168 assert(fs_shift < 3); // Will always be 0, 1, or, 2. 174 RTC_DCHECK_LT(fs_shift, 3); // Will always be 0, 1, or, 2.
169 int16_t increment = 4 >> fs_shift; 175 int16_t increment = 4 >> fs_shift;
170 int16_t fraction = increment; 176 int16_t fraction = increment;
171 for (size_t i = 0; i < static_cast<size_t>(8 * fs_mult); i++) { 177 for (size_t i = 0; i < static_cast<size_t>(8 * fs_mult); i++) {
172 // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8 now 178 // TODO(hlundin): Add 16 instead of 8 for correct rounding. Keeping 8 now
173 // for legacy bit-exactness. 179 // for legacy bit-exactness.
174 (*output)[0][i] = (fraction * (*output)[0][i] + 180 (*output)[0][i] = (fraction * (*output)[0][i] +
175 (32 - fraction) * cng_output[i] + 8) >> 5; 181 (32 - fraction) * cng_output[i] + 8) >> 5;
176 fraction += increment; 182 fraction += increment;
177 } 183 }
178 } else if (external_mute_factor_array[0] < 16384) { 184 } else if (external_mute_factor_array[0] < 16384) {
179 // Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are 185 // Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are
180 // still ramping up from previous muting. 186 // still ramping up from previous muting.
181 // If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14). 187 // If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14).
182 int increment = 64 / fs_mult; 188 int increment = 64 / fs_mult;
183 size_t length_per_channel = length / output->Channels(); 189 size_t length_per_channel = length / output->Channels();
184 for (size_t i = 0; i < length_per_channel; i++) { 190 for (size_t i = 0; i < length_per_channel; i++) {
185 for (size_t channel_ix = 0; channel_ix < output->Channels(); 191 for (size_t channel_ix = 0; channel_ix < output->Channels();
186 ++channel_ix) { 192 ++channel_ix) {
187 // Scale with mute factor. 193 // Scale with mute factor.
188 assert(channel_ix < output->Channels()); 194 RTC_DCHECK_LT(channel_ix, output->Channels());
189 assert(i < output->Size()); 195 RTC_DCHECK_LT(i, output->Size());
190 int32_t scaled_signal = (*output)[channel_ix][i] * 196 int32_t scaled_signal = (*output)[channel_ix][i] *
191 external_mute_factor_array[channel_ix]; 197 external_mute_factor_array[channel_ix];
192 // Shift 14 with proper rounding. 198 // Shift 14 with proper rounding.
193 (*output)[channel_ix][i] = 199 (*output)[channel_ix][i] =
194 static_cast<int16_t>((scaled_signal + 8192) >> 14); 200 static_cast<int16_t>((scaled_signal + 8192) >> 14);
195 // Increase mute_factor towards 16384. 201 // Increase mute_factor towards 16384.
196 external_mute_factor_array[channel_ix] = static_cast<int16_t>(std::min( 202 external_mute_factor_array[channel_ix] = static_cast<int16_t>(std::min(
197 16384, external_mute_factor_array[channel_ix] + increment)); 203 16384, external_mute_factor_array[channel_ix] + increment));
198 } 204 }
199 } 205 }
200 } 206 }
201 207
202 return static_cast<int>(length); 208 return static_cast<int>(length);
203 } 209 }
204 210
205 } // namespace webrtc 211 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698