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 |
(...skipping 21 matching lines...) Expand all Loading... | |
32 : fs_hz_(fs_hz), | 32 : fs_hz_(fs_hz), |
33 num_channels_(num_channels), | 33 num_channels_(num_channels), |
34 fs_mult_(fs_hz_ / 8000), | 34 fs_mult_(fs_hz_ / 8000), |
35 timestamps_per_call_(static_cast<size_t>(fs_hz_ / 100)), | 35 timestamps_per_call_(static_cast<size_t>(fs_hz_ / 100)), |
36 expand_(expand), | 36 expand_(expand), |
37 sync_buffer_(sync_buffer), | 37 sync_buffer_(sync_buffer), |
38 expanded_(num_channels_) { | 38 expanded_(num_channels_) { |
39 assert(num_channels_ > 0); | 39 assert(num_channels_ > 0); |
40 } | 40 } |
41 | 41 |
42 Merge::~Merge() = default; | |
43 | |
42 size_t Merge::Process(int16_t* input, size_t input_length, | 44 size_t Merge::Process(int16_t* input, size_t input_length, |
43 int16_t* external_mute_factor_array, | 45 int16_t* external_mute_factor_array, |
44 AudioMultiVector* output) { | 46 AudioMultiVector* output) { |
45 // TODO(hlundin): Change to an enumerator and skip assert. | 47 // TODO(hlundin): Change to an enumerator and skip assert. |
46 assert(fs_hz_ == 8000 || fs_hz_ == 16000 || fs_hz_ == 32000 || | 48 assert(fs_hz_ == 8000 || fs_hz_ == 16000 || fs_hz_ == 32000 || |
47 fs_hz_ == 48000); | 49 fs_hz_ == 48000); |
48 assert(fs_hz_ <= kMaxSampleRate); // Should not be possible. | 50 assert(fs_hz_ <= kMaxSampleRate); // Should not be possible. |
49 | 51 |
50 size_t old_length; | 52 size_t old_length; |
51 size_t expand_period; | 53 size_t expand_period; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 // master (i.e., first) channel only. | 86 // master (i.e., first) channel only. |
85 // Downsample to 4kHz sample rate. | 87 // Downsample to 4kHz sample rate. |
86 Downsample(input_channel, input_length_per_channel, expanded_channel, | 88 Downsample(input_channel, input_length_per_channel, expanded_channel, |
87 expanded_length); | 89 expanded_length); |
88 | 90 |
89 // Calculate the lag of the strongest correlation period. | 91 // Calculate the lag of the strongest correlation period. |
90 best_correlation_index = CorrelateAndPeakSearch( | 92 best_correlation_index = CorrelateAndPeakSearch( |
91 old_length, input_length_per_channel, expand_period); | 93 old_length, input_length_per_channel, expand_period); |
92 } | 94 } |
93 | 95 |
94 static const int kTempDataSize = 3600; | 96 temp_data_.resize(input_length_per_channel + best_correlation_index); |
95 int16_t temp_data[kTempDataSize]; // TODO(hlundin) Remove this. | 97 int16_t* decoded_output = temp_data_.data() + best_correlation_index; |
96 int16_t* decoded_output = temp_data + best_correlation_index; | |
97 | 98 |
98 // Mute the new decoded data if needed (and unmute it linearly). | 99 // Mute the new decoded data if needed (and unmute it linearly). |
99 // This is the overlapping part of expanded_signal. | 100 // This is the overlapping part of expanded_signal. |
100 size_t interpolation_length = std::min( | 101 size_t interpolation_length = std::min( |
101 kMaxCorrelationLength * fs_mult_, | 102 kMaxCorrelationLength * fs_mult_, |
102 expanded_length - best_correlation_index); | 103 expanded_length - best_correlation_index); |
103 interpolation_length = std::min(interpolation_length, | 104 interpolation_length = std::min(interpolation_length, |
104 input_length_per_channel); | 105 input_length_per_channel); |
105 if (*external_mute_factor < 16384) { | 106 if (*external_mute_factor < 16384) { |
106 // Set a suitable muting slope (Q20). 0.004 for NB, 0.002 for WB, | 107 // Set a suitable muting slope (Q20). 0.004 for NB, 0.002 for WB, |
(...skipping 13 matching lines...) Expand all Loading... | |
120 memmove( | 121 memmove( |
121 &decoded_output[interpolation_length], | 122 &decoded_output[interpolation_length], |
122 &input_channel[interpolation_length], | 123 &input_channel[interpolation_length], |
123 sizeof(int16_t) * (input_length_per_channel - interpolation_length)); | 124 sizeof(int16_t) * (input_length_per_channel - interpolation_length)); |
124 } | 125 } |
125 | 126 |
126 // Do overlap and mix linearly. | 127 // Do overlap and mix linearly. |
127 int16_t increment = | 128 int16_t increment = |
128 static_cast<int16_t>(16384 / (interpolation_length + 1)); // In Q14. | 129 static_cast<int16_t>(16384 / (interpolation_length + 1)); // In Q14. |
129 int16_t mute_factor = 16384 - increment; | 130 int16_t mute_factor = 16384 - increment; |
130 memmove(temp_data, expanded_channel, | 131 memmove(temp_data_.data(), expanded_channel, |
131 sizeof(int16_t) * best_correlation_index); | 132 sizeof(int16_t) * best_correlation_index); |
132 DspHelper::CrossFade(&expanded_channel[best_correlation_index], | 133 DspHelper::CrossFade(&expanded_channel[best_correlation_index], |
133 input_channel, interpolation_length, | 134 input_channel, interpolation_length, |
134 &mute_factor, increment, decoded_output); | 135 &mute_factor, increment, decoded_output); |
135 | 136 |
136 output_length = best_correlation_index + input_length_per_channel; | 137 output_length = best_correlation_index + input_length_per_channel; |
137 if (channel == 0) { | 138 if (channel == 0) { |
138 assert(output->Empty()); // Output should be empty at this point. | 139 assert(output->Empty()); // Output should be empty at this point. |
139 output->AssertSize(output_length); | 140 output->AssertSize(output_length); |
140 } else { | 141 } else { |
141 assert(output->Size() == output_length); | 142 assert(output->Size() == output_length); |
142 } | 143 } |
143 memcpy(&(*output)[channel][0], temp_data, | 144 memcpy(&(*output)[channel][0], temp_data_.data(), |
144 sizeof(temp_data[0]) * output_length); | 145 sizeof(temp_data_[0]) * output_length); |
145 } | 146 } |
146 | 147 |
147 // Copy back the first part of the data to |sync_buffer_| and remove it from | 148 // Copy back the first part of the data to |sync_buffer_| and remove it from |
148 // |output|. | 149 // |output|. |
149 sync_buffer_->ReplaceAtIndex(*output, old_length, sync_buffer_->next_index()); | 150 sync_buffer_->ReplaceAtIndex(*output, old_length, sync_buffer_->next_index()); |
150 output->PopFront(old_length); | 151 output->PopFront(old_length); |
151 | 152 |
152 // Return new added length. |old_length| samples were borrowed from | 153 // Return new added length. |old_length| samples were borrowed from |
153 // |sync_buffer_|. | 154 // |sync_buffer_|. |
154 return output_length - old_length; | 155 return output_length - old_length; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 return required_length; | 202 return required_length; |
202 } | 203 } |
203 | 204 |
204 int16_t Merge::SignalScaling(const int16_t* input, size_t input_length, | 205 int16_t Merge::SignalScaling(const int16_t* input, size_t input_length, |
205 const int16_t* expanded_signal) const { | 206 const int16_t* expanded_signal) const { |
206 // Adjust muting factor if new vector is more or less of the BGN energy. | 207 // Adjust muting factor if new vector is more or less of the BGN energy. |
207 const size_t mod_input_length = | 208 const size_t mod_input_length = |
208 std::min(static_cast<size_t>(64 * fs_mult_), input_length); | 209 std::min(static_cast<size_t>(64 * fs_mult_), input_length); |
209 const int16_t expanded_max = | 210 const int16_t expanded_max = |
210 WebRtcSpl_MaxAbsValueW16(expanded_signal, mod_input_length); | 211 WebRtcSpl_MaxAbsValueW16(expanded_signal, mod_input_length); |
211 const int16_t input_max = WebRtcSpl_MaxAbsValueW16(input, mod_input_length); | 212 int32_t factor = (expanded_max * expanded_max) / |
minyue-webrtc
2016/05/02 10:44:52
first fix:
old code does give enough shifts, sinc
hlundin-webrtc
2016/05/02 11:28:15
Acknowledged.
minyue-webrtc
2016/05/02 11:41:12
ok. but I ought to modify my sentence as "old code
| |
212 | 213 (std::numeric_limits<int32_t>::max() / |
213 // Calculate energy of expanded signal. | 214 static_cast<int32_t>(mod_input_length)); |
214 // |log_fs_mult| is log2(fs_mult_), but is not exact for 48000 Hz. | 215 const int expanded_shift = factor == 0 ? 0 : 31 - WebRtcSpl_NormW32(factor); |
215 int log_fs_mult = 30 - WebRtcSpl_NormW32(fs_mult_); | |
216 int expanded_shift = 6 + log_fs_mult | |
217 - WebRtcSpl_NormW32(expanded_max * expanded_max); | |
218 expanded_shift = std::max(expanded_shift, 0); | |
219 int32_t energy_expanded = WebRtcSpl_DotProductWithScale(expanded_signal, | 216 int32_t energy_expanded = WebRtcSpl_DotProductWithScale(expanded_signal, |
220 expanded_signal, | 217 expanded_signal, |
221 mod_input_length, | 218 mod_input_length, |
222 expanded_shift); | 219 expanded_shift); |
223 | 220 |
224 // Calculate energy of input signal. | 221 // Calculate energy of input signal. |
225 int input_shift = 6 + log_fs_mult - WebRtcSpl_NormW32(input_max * input_max); | 222 const int16_t input_max = WebRtcSpl_MaxAbsValueW16(input, mod_input_length); |
226 input_shift = std::max(input_shift, 0); | 223 factor = (input_max * input_max) / (std::numeric_limits<int32_t>::max() / |
224 static_cast<int32_t>(mod_input_length)); | |
225 const int input_shift = factor == 0 ? 0 : 31 - WebRtcSpl_NormW32(factor); | |
227 int32_t energy_input = WebRtcSpl_DotProductWithScale(input, input, | 226 int32_t energy_input = WebRtcSpl_DotProductWithScale(input, input, |
228 mod_input_length, | 227 mod_input_length, |
229 input_shift); | 228 input_shift); |
230 | 229 |
231 // Align to the same Q-domain. | 230 // Align to the same Q-domain. |
232 if (input_shift > expanded_shift) { | 231 if (input_shift > expanded_shift) { |
233 energy_expanded = energy_expanded >> (input_shift - expanded_shift); | 232 energy_expanded = energy_expanded >> (input_shift - expanded_shift); |
234 } else { | 233 } else { |
235 energy_input = energy_input >> (expanded_shift - input_shift); | 234 energy_input = energy_input >> (expanded_shift - input_shift); |
236 } | 235 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
366 } | 365 } |
367 return best_correlation_index; | 366 return best_correlation_index; |
368 } | 367 } |
369 | 368 |
370 size_t Merge::RequiredFutureSamples() { | 369 size_t Merge::RequiredFutureSamples() { |
371 return fs_hz_ / 100 * num_channels_; // 10 ms. | 370 return fs_hz_ / 100 * num_channels_; // 10 ms. |
372 } | 371 } |
373 | 372 |
374 | 373 |
375 } // namespace webrtc | 374 } // namespace webrtc |
OLD | NEW |