OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // To compensate for the attenuation this algorithm introduces to the target | 72 // To compensate for the attenuation this algorithm introduces to the target |
73 // signal. It was estimated empirically from a low-noise low-reverberation | 73 // signal. It was estimated empirically from a low-noise low-reverberation |
74 // recording from broadside. | 74 // recording from broadside. |
75 const float kCompensationGain = 2.f; | 75 const float kCompensationGain = 2.f; |
76 | 76 |
77 // Does conjugate(|norm_mat|) * |mat| * transpose(|norm_mat|). No extra space is | 77 // Does conjugate(|norm_mat|) * |mat| * transpose(|norm_mat|). No extra space is |
78 // used; to accomplish this, we compute both multiplications in the same loop. | 78 // used; to accomplish this, we compute both multiplications in the same loop. |
79 // The returned norm is clamped to be non-negative. | 79 // The returned norm is clamped to be non-negative. |
80 float Norm(const ComplexMatrix<float>& mat, | 80 float Norm(const ComplexMatrix<float>& mat, |
81 const ComplexMatrix<float>& norm_mat) { | 81 const ComplexMatrix<float>& norm_mat) { |
82 RTC_CHECK_EQ(1u, norm_mat.num_rows()); | 82 RTC_CHECK_EQ(1, norm_mat.num_rows()); |
83 RTC_CHECK_EQ(norm_mat.num_columns(), mat.num_rows()); | 83 RTC_CHECK_EQ(norm_mat.num_columns(), mat.num_rows()); |
84 RTC_CHECK_EQ(norm_mat.num_columns(), mat.num_columns()); | 84 RTC_CHECK_EQ(norm_mat.num_columns(), mat.num_columns()); |
85 | 85 |
86 complex<float> first_product = complex<float>(0.f, 0.f); | 86 complex<float> first_product = complex<float>(0.f, 0.f); |
87 complex<float> second_product = complex<float>(0.f, 0.f); | 87 complex<float> second_product = complex<float>(0.f, 0.f); |
88 | 88 |
89 const complex<float>* const* mat_els = mat.elements(); | 89 const complex<float>* const* mat_els = mat.elements(); |
90 const complex<float>* const* norm_mat_els = norm_mat.elements(); | 90 const complex<float>* const* norm_mat_els = norm_mat.elements(); |
91 | 91 |
92 for (size_t i = 0; i < norm_mat.num_columns(); ++i) { | 92 for (size_t i = 0; i < norm_mat.num_columns(); ++i) { |
93 for (size_t j = 0; j < norm_mat.num_columns(); ++j) { | 93 for (size_t j = 0; j < norm_mat.num_columns(); ++j) { |
94 first_product += conj(norm_mat_els[0][j]) * mat_els[j][i]; | 94 first_product += conj(norm_mat_els[0][j]) * mat_els[j][i]; |
95 } | 95 } |
96 second_product += first_product * norm_mat_els[0][i]; | 96 second_product += first_product * norm_mat_els[0][i]; |
97 first_product = 0.f; | 97 first_product = 0.f; |
98 } | 98 } |
99 return std::max(second_product.real(), 0.f); | 99 return std::max(second_product.real(), 0.f); |
100 } | 100 } |
101 | 101 |
102 // Does conjugate(|lhs|) * |rhs| for row vectors |lhs| and |rhs|. | 102 // Does conjugate(|lhs|) * |rhs| for row vectors |lhs| and |rhs|. |
103 complex<float> ConjugateDotProduct(const ComplexMatrix<float>& lhs, | 103 complex<float> ConjugateDotProduct(const ComplexMatrix<float>& lhs, |
104 const ComplexMatrix<float>& rhs) { | 104 const ComplexMatrix<float>& rhs) { |
105 RTC_CHECK_EQ(1u, lhs.num_rows()); | 105 RTC_CHECK_EQ(1, lhs.num_rows()); |
106 RTC_CHECK_EQ(1u, rhs.num_rows()); | 106 RTC_CHECK_EQ(1, rhs.num_rows()); |
107 RTC_CHECK_EQ(lhs.num_columns(), rhs.num_columns()); | 107 RTC_CHECK_EQ(lhs.num_columns(), rhs.num_columns()); |
108 | 108 |
109 const complex<float>* const* lhs_elements = lhs.elements(); | 109 const complex<float>* const* lhs_elements = lhs.elements(); |
110 const complex<float>* const* rhs_elements = rhs.elements(); | 110 const complex<float>* const* rhs_elements = rhs.elements(); |
111 | 111 |
112 complex<float> result = complex<float>(0.f, 0.f); | 112 complex<float> result = complex<float>(0.f, 0.f); |
113 for (size_t i = 0; i < lhs.num_columns(); ++i) { | 113 for (size_t i = 0; i < lhs.num_columns(); ++i) { |
114 result += conj(lhs_elements[0][i]) * rhs_elements[0][i]; | 114 result += conj(lhs_elements[0][i]) * rhs_elements[0][i]; |
115 } | 115 } |
116 | 116 |
(...skipping 14 matching lines...) Expand all Loading... |
131 float abs_value = std::abs(mat_els[i][j]); | 131 float abs_value = std::abs(mat_els[i][j]); |
132 sum_squares += abs_value * abs_value; | 132 sum_squares += abs_value * abs_value; |
133 } | 133 } |
134 } | 134 } |
135 return sum_squares; | 135 return sum_squares; |
136 } | 136 } |
137 | 137 |
138 // Does |out| = |in|.' * conj(|in|) for row vector |in|. | 138 // Does |out| = |in|.' * conj(|in|) for row vector |in|. |
139 void TransposedConjugatedProduct(const ComplexMatrix<float>& in, | 139 void TransposedConjugatedProduct(const ComplexMatrix<float>& in, |
140 ComplexMatrix<float>* out) { | 140 ComplexMatrix<float>* out) { |
141 RTC_CHECK_EQ(1u, in.num_rows()); | 141 RTC_CHECK_EQ(1, in.num_rows()); |
142 RTC_CHECK_EQ(out->num_rows(), in.num_columns()); | 142 RTC_CHECK_EQ(out->num_rows(), in.num_columns()); |
143 RTC_CHECK_EQ(out->num_columns(), in.num_columns()); | 143 RTC_CHECK_EQ(out->num_columns(), in.num_columns()); |
144 const complex<float>* in_elements = in.elements()[0]; | 144 const complex<float>* in_elements = in.elements()[0]; |
145 complex<float>* const* out_elements = out->elements(); | 145 complex<float>* const* out_elements = out->elements(); |
146 for (size_t i = 0; i < out->num_rows(); ++i) { | 146 for (size_t i = 0; i < out->num_rows(); ++i) { |
147 for (size_t j = 0; j < out->num_columns(); ++j) { | 147 for (size_t j = 0; j < out->num_columns(); ++j) { |
148 out_elements[i][j] = in_elements[i] * conj(in_elements[j]); | 148 out_elements[i][j] = in_elements[i] * conj(in_elements[j]); |
149 } | 149 } |
150 } | 150 } |
151 } | 151 } |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 | 442 |
443 bool NonlinearBeamformer::is_target_present() { return is_target_present_; } | 443 bool NonlinearBeamformer::is_target_present() { return is_target_present_; } |
444 | 444 |
445 void NonlinearBeamformer::ProcessAudioBlock(const complex_f* const* input, | 445 void NonlinearBeamformer::ProcessAudioBlock(const complex_f* const* input, |
446 size_t num_input_channels, | 446 size_t num_input_channels, |
447 size_t num_freq_bins, | 447 size_t num_freq_bins, |
448 size_t num_output_channels, | 448 size_t num_output_channels, |
449 complex_f* const* output) { | 449 complex_f* const* output) { |
450 RTC_CHECK_EQ(kNumFreqBins, num_freq_bins); | 450 RTC_CHECK_EQ(kNumFreqBins, num_freq_bins); |
451 RTC_CHECK_EQ(num_input_channels_, num_input_channels); | 451 RTC_CHECK_EQ(num_input_channels_, num_input_channels); |
452 RTC_CHECK_EQ(0u, num_output_channels); | 452 RTC_CHECK_EQ(0, num_output_channels); |
453 | 453 |
454 // Calculating the post-filter masks. Note that we need two for each | 454 // Calculating the post-filter masks. Note that we need two for each |
455 // frequency bin to account for the positive and negative interferer | 455 // frequency bin to account for the positive and negative interferer |
456 // angle. | 456 // angle. |
457 for (size_t i = low_mean_start_bin_; i <= high_mean_end_bin_; ++i) { | 457 for (size_t i = low_mean_start_bin_; i <= high_mean_end_bin_; ++i) { |
458 eig_m_.CopyFromColumn(input, i, num_input_channels_); | 458 eig_m_.CopyFromColumn(input, i, num_input_channels_); |
459 float eig_m_norm_factor = std::sqrt(SumSquares(eig_m_)); | 459 float eig_m_norm_factor = std::sqrt(SumSquares(eig_m_)); |
460 if (eig_m_norm_factor != 0.f) { | 460 if (eig_m_norm_factor != 0.f) { |
461 eig_m_.Scale(1.f / eig_m_norm_factor); | 461 eig_m_.Scale(1.f / eig_m_norm_factor); |
462 } | 462 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 new_mask_ + high_mean_end_bin_ + 1); | 588 new_mask_ + high_mean_end_bin_ + 1); |
589 if (new_mask_[quantile] > kMaskTargetThreshold) { | 589 if (new_mask_[quantile] > kMaskTargetThreshold) { |
590 is_target_present_ = true; | 590 is_target_present_ = true; |
591 interference_blocks_count_ = 0; | 591 interference_blocks_count_ = 0; |
592 } else { | 592 } else { |
593 is_target_present_ = interference_blocks_count_++ < hold_target_blocks_; | 593 is_target_present_ = interference_blocks_count_++ < hold_target_blocks_; |
594 } | 594 } |
595 } | 595 } |
596 | 596 |
597 } // namespace webrtc | 597 } // namespace webrtc |
OLD | NEW |