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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 cb->num_channels(), | 78 cb->num_channels(), |
79 cb_int.channels()); | 79 cb_int.channels()); |
80 for (size_t i = 0; i < cb->num_channels(); ++i) { | 80 for (size_t i = 0; i < cb->num_channels(); ++i) { |
81 S16ToFloat(cb_int.channels()[i], | 81 S16ToFloat(cb_int.channels()[i], |
82 cb->num_frames(), | 82 cb->num_frames(), |
83 cb->channels()[i]); | 83 cb->channels()[i]); |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) { | 87 void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) { |
88 ConvertToFloat(frame.data_, cb); | 88 ConvertToFloat(frame.data(), cb); |
89 } | 89 } |
90 | 90 |
91 // Number of channels including the keyboard channel. | 91 // Number of channels including the keyboard channel. |
92 size_t TotalChannelsFromLayout(AudioProcessing::ChannelLayout layout) { | 92 size_t TotalChannelsFromLayout(AudioProcessing::ChannelLayout layout) { |
93 switch (layout) { | 93 switch (layout) { |
94 case AudioProcessing::kMono: | 94 case AudioProcessing::kMono: |
95 return 1; | 95 return 1; |
96 case AudioProcessing::kMonoAndKeyboard: | 96 case AudioProcessing::kMonoAndKeyboard: |
97 case AudioProcessing::kStereo: | 97 case AudioProcessing::kStereo: |
98 return 2; | 98 return 2; |
(...skipping 19 matching lines...) Expand all Loading... |
118 for (size_t i = 0; i < samples_per_channel; ++i) | 118 for (size_t i = 0; i < samples_per_channel; ++i) |
119 mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1; | 119 mono[i] = (stereo[i * 2] + stereo[i * 2 + 1]) >> 1; |
120 } | 120 } |
121 | 121 |
122 void CopyLeftToRightChannel(int16_t* stereo, size_t samples_per_channel) { | 122 void CopyLeftToRightChannel(int16_t* stereo, size_t samples_per_channel) { |
123 for (size_t i = 0; i < samples_per_channel; i++) { | 123 for (size_t i = 0; i < samples_per_channel; i++) { |
124 stereo[i * 2 + 1] = stereo[i * 2]; | 124 stereo[i * 2 + 1] = stereo[i * 2]; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 void VerifyChannelsAreEqual(int16_t* stereo, size_t samples_per_channel) { | 128 void VerifyChannelsAreEqual(const int16_t* stereo, size_t samples_per_channel) { |
129 for (size_t i = 0; i < samples_per_channel; i++) { | 129 for (size_t i = 0; i < samples_per_channel; i++) { |
130 EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]); | 130 EXPECT_EQ(stereo[i * 2 + 1], stereo[i * 2]); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 void SetFrameTo(AudioFrame* frame, int16_t value) { | 134 void SetFrameTo(AudioFrame* frame, int16_t value) { |
| 135 int16_t* frame_data = frame->mutable_data(); |
135 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_; | 136 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_; |
136 ++i) { | 137 ++i) { |
137 frame->data_[i] = value; | 138 frame_data[i] = value; |
138 } | 139 } |
139 } | 140 } |
140 | 141 |
141 void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) { | 142 void SetFrameTo(AudioFrame* frame, int16_t left, int16_t right) { |
142 ASSERT_EQ(2u, frame->num_channels_); | 143 ASSERT_EQ(2u, frame->num_channels_); |
| 144 int16_t* frame_data = frame->mutable_data(); |
143 for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) { | 145 for (size_t i = 0; i < frame->samples_per_channel_ * 2; i += 2) { |
144 frame->data_[i] = left; | 146 frame_data[i] = left; |
145 frame->data_[i + 1] = right; | 147 frame_data[i + 1] = right; |
146 } | 148 } |
147 } | 149 } |
148 | 150 |
149 void ScaleFrame(AudioFrame* frame, float scale) { | 151 void ScaleFrame(AudioFrame* frame, float scale) { |
| 152 int16_t* frame_data = frame->mutable_data(); |
150 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_; | 153 for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_; |
151 ++i) { | 154 ++i) { |
152 frame->data_[i] = FloatS16ToS16(frame->data_[i] * scale); | 155 frame_data[i] = FloatS16ToS16(frame_data[i] * scale); |
153 } | 156 } |
154 } | 157 } |
155 | 158 |
156 bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) { | 159 bool FrameDataAreEqual(const AudioFrame& frame1, const AudioFrame& frame2) { |
157 if (frame1.samples_per_channel_ != frame2.samples_per_channel_) { | 160 if (frame1.samples_per_channel_ != frame2.samples_per_channel_) { |
158 return false; | 161 return false; |
159 } | 162 } |
160 if (frame1.num_channels_ != frame2.num_channels_) { | 163 if (frame1.num_channels_ != frame2.num_channels_) { |
161 return false; | 164 return false; |
162 } | 165 } |
163 if (memcmp(frame1.data_, frame2.data_, | 166 if (memcmp(frame1.data(), frame2.data(), |
164 frame1.samples_per_channel_ * frame1.num_channels_ * | 167 frame1.samples_per_channel_ * frame1.num_channels_ * |
165 sizeof(int16_t))) { | 168 sizeof(int16_t))) { |
166 return false; | 169 return false; |
167 } | 170 } |
168 return true; | 171 return true; |
169 } | 172 } |
170 | 173 |
171 void EnableAllAPComponents(AudioProcessing* ap) { | 174 void EnableAllAPComponents(AudioProcessing* ap) { |
172 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE) | 175 #if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE) |
173 EXPECT_NOERR(ap->echo_control_mobile()->Enable(true)); | 176 EXPECT_NOERR(ap->echo_control_mobile()->Enable(true)); |
(...skipping 22 matching lines...) Expand all Loading... |
196 } | 199 } |
197 | 200 |
198 // These functions are only used by ApmTest.Process. | 201 // These functions are only used by ApmTest.Process. |
199 template <class T> | 202 template <class T> |
200 T AbsValue(T a) { | 203 T AbsValue(T a) { |
201 return a > 0 ? a: -a; | 204 return a > 0 ? a: -a; |
202 } | 205 } |
203 | 206 |
204 int16_t MaxAudioFrame(const AudioFrame& frame) { | 207 int16_t MaxAudioFrame(const AudioFrame& frame) { |
205 const size_t length = frame.samples_per_channel_ * frame.num_channels_; | 208 const size_t length = frame.samples_per_channel_ * frame.num_channels_; |
206 int16_t max_data = AbsValue(frame.data_[0]); | 209 const int16_t* frame_data = frame.data(); |
| 210 int16_t max_data = AbsValue(frame_data[0]); |
207 for (size_t i = 1; i < length; i++) { | 211 for (size_t i = 1; i < length; i++) { |
208 max_data = std::max(max_data, AbsValue(frame.data_[i])); | 212 max_data = std::max(max_data, AbsValue(frame_data[i])); |
209 } | 213 } |
210 | 214 |
211 return max_data; | 215 return max_data; |
212 } | 216 } |
213 | 217 |
214 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE) | 218 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE) |
215 void TestStats(const AudioProcessing::Statistic& test, | 219 void TestStats(const AudioProcessing::Statistic& test, |
216 const audioproc::Test::Statistic& reference) { | 220 const audioproc::Test::Statistic& reference) { |
217 EXPECT_EQ(reference.instant(), test.instant); | 221 EXPECT_EQ(reference.instant(), test.instant); |
218 EXPECT_EQ(reference.average(), test.average); | 222 EXPECT_EQ(reference.average(), test.average); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 } | 530 } |
527 | 531 |
528 void ApmTest::EnableAllComponents() { | 532 void ApmTest::EnableAllComponents() { |
529 EnableAllAPComponents(apm_.get()); | 533 EnableAllAPComponents(apm_.get()); |
530 } | 534 } |
531 | 535 |
532 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame, | 536 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame, |
533 ChannelBuffer<float>* cb) { | 537 ChannelBuffer<float>* cb) { |
534 // The files always contain stereo audio. | 538 // The files always contain stereo audio. |
535 size_t frame_size = frame->samples_per_channel_ * 2; | 539 size_t frame_size = frame->samples_per_channel_ * 2; |
536 size_t read_count = fread(frame->data_, | 540 size_t read_count = fread(frame->mutable_data(), |
537 sizeof(int16_t), | 541 sizeof(int16_t), |
538 frame_size, | 542 frame_size, |
539 file); | 543 file); |
540 if (read_count != frame_size) { | 544 if (read_count != frame_size) { |
541 // Check that the file really ended. | 545 // Check that the file really ended. |
542 EXPECT_NE(0, feof(file)); | 546 EXPECT_NE(0, feof(file)); |
543 return false; // This is expected. | 547 return false; // This is expected. |
544 } | 548 } |
545 | 549 |
546 if (frame->num_channels_ == 1) { | 550 if (frame->num_channels_ == 1) { |
547 MixStereoToMono(frame->data_, frame->data_, | 551 MixStereoToMono(frame->data(), frame->mutable_data(), |
548 frame->samples_per_channel_); | 552 frame->samples_per_channel_); |
549 } | 553 } |
550 | 554 |
551 if (cb) { | 555 if (cb) { |
552 ConvertToFloat(*frame, cb); | 556 ConvertToFloat(*frame, cb); |
553 } | 557 } |
554 return true; | 558 return true; |
555 } | 559 } |
556 | 560 |
557 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame) { | 561 bool ApmTest::ReadFrame(FILE* file, AudioFrame* frame) { |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 kProcessSampleRates[i], | 1601 kProcessSampleRates[i], |
1598 kProcessSampleRates[i], | 1602 kProcessSampleRates[i], |
1599 2, | 1603 2, |
1600 2, | 1604 2, |
1601 2, | 1605 2, |
1602 false); | 1606 false); |
1603 int analog_level = 127; | 1607 int analog_level = 127; |
1604 ASSERT_EQ(0, feof(far_file_)); | 1608 ASSERT_EQ(0, feof(far_file_)); |
1605 ASSERT_EQ(0, feof(near_file_)); | 1609 ASSERT_EQ(0, feof(near_file_)); |
1606 while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) { | 1610 while (ReadFrame(far_file_, revframe_) && ReadFrame(near_file_, frame_)) { |
1607 CopyLeftToRightChannel(revframe_->data_, revframe_->samples_per_channel_); | 1611 CopyLeftToRightChannel(revframe_->mutable_data(), |
| 1612 revframe_->samples_per_channel_); |
1608 | 1613 |
1609 ASSERT_EQ(kNoErr, apm_->ProcessReverseStream(revframe_)); | 1614 ASSERT_EQ(kNoErr, apm_->ProcessReverseStream(revframe_)); |
1610 | 1615 |
1611 CopyLeftToRightChannel(frame_->data_, frame_->samples_per_channel_); | 1616 CopyLeftToRightChannel(frame_->mutable_data(), |
| 1617 frame_->samples_per_channel_); |
1612 frame_->vad_activity_ = AudioFrame::kVadUnknown; | 1618 frame_->vad_activity_ = AudioFrame::kVadUnknown; |
1613 | 1619 |
1614 ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0)); | 1620 ASSERT_EQ(kNoErr, apm_->set_stream_delay_ms(0)); |
1615 apm_->echo_cancellation()->set_stream_drift_samples(0); | 1621 apm_->echo_cancellation()->set_stream_drift_samples(0); |
1616 ASSERT_EQ(kNoErr, | 1622 ASSERT_EQ(kNoErr, |
1617 apm_->gain_control()->set_stream_analog_level(analog_level)); | 1623 apm_->gain_control()->set_stream_analog_level(analog_level)); |
1618 ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_)); | 1624 ASSERT_EQ(kNoErr, apm_->ProcessStream(frame_)); |
1619 analog_level = apm_->gain_control()->stream_analog_level(); | 1625 analog_level = apm_->gain_control()->stream_analog_level(); |
1620 | 1626 |
1621 VerifyChannelsAreEqual(frame_->data_, frame_->samples_per_channel_); | 1627 VerifyChannelsAreEqual(frame_->data(), frame_->samples_per_channel_); |
1622 } | 1628 } |
1623 rewind(far_file_); | 1629 rewind(far_file_); |
1624 rewind(near_file_); | 1630 rewind(near_file_); |
1625 } | 1631 } |
1626 } | 1632 } |
1627 | 1633 |
1628 TEST_F(ApmTest, SplittingFilter) { | 1634 TEST_F(ApmTest, SplittingFilter) { |
1629 // Verify the filter is not active through undistorted audio when: | 1635 // Verify the filter is not active through undistorted audio when: |
1630 // 1. No components are enabled... | 1636 // 1. No components are enabled... |
1631 SetFrameTo(frame_, 1000); | 1637 SetFrameTo(frame_, 1000); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 | 1749 |
1744 if (msg.channel_size() > 0) { | 1750 if (msg.channel_size() > 0) { |
1745 ASSERT_EQ(revframe_->num_channels_, | 1751 ASSERT_EQ(revframe_->num_channels_, |
1746 static_cast<size_t>(msg.channel_size())); | 1752 static_cast<size_t>(msg.channel_size())); |
1747 for (int i = 0; i < msg.channel_size(); ++i) { | 1753 for (int i = 0; i < msg.channel_size(); ++i) { |
1748 memcpy(revfloat_cb_->channels()[i], | 1754 memcpy(revfloat_cb_->channels()[i], |
1749 msg.channel(i).data(), | 1755 msg.channel(i).data(), |
1750 msg.channel(i).size()); | 1756 msg.channel(i).size()); |
1751 } | 1757 } |
1752 } else { | 1758 } else { |
1753 memcpy(revframe_->data_, msg.data().data(), msg.data().size()); | 1759 memcpy(revframe_->mutable_data(), msg.data().data(), msg.data().size()); |
1754 if (format == kFloatFormat) { | 1760 if (format == kFloatFormat) { |
1755 // We're using an int16 input file; convert to float. | 1761 // We're using an int16 input file; convert to float. |
1756 ConvertToFloat(*revframe_, revfloat_cb_.get()); | 1762 ConvertToFloat(*revframe_, revfloat_cb_.get()); |
1757 } | 1763 } |
1758 } | 1764 } |
1759 AnalyzeReverseStreamChooser(format); | 1765 AnalyzeReverseStreamChooser(format); |
1760 | 1766 |
1761 } else if (event_msg.type() == audioproc::Event::STREAM) { | 1767 } else if (event_msg.type() == audioproc::Event::STREAM) { |
1762 const audioproc::Stream msg = event_msg.stream(); | 1768 const audioproc::Stream msg = event_msg.stream(); |
1763 // ProcessStream could have changed this for the output frame. | 1769 // ProcessStream could have changed this for the output frame. |
(...skipping 10 matching lines...) Expand all Loading... |
1774 | 1780 |
1775 if (msg.input_channel_size() > 0) { | 1781 if (msg.input_channel_size() > 0) { |
1776 ASSERT_EQ(frame_->num_channels_, | 1782 ASSERT_EQ(frame_->num_channels_, |
1777 static_cast<size_t>(msg.input_channel_size())); | 1783 static_cast<size_t>(msg.input_channel_size())); |
1778 for (int i = 0; i < msg.input_channel_size(); ++i) { | 1784 for (int i = 0; i < msg.input_channel_size(); ++i) { |
1779 memcpy(float_cb_->channels()[i], | 1785 memcpy(float_cb_->channels()[i], |
1780 msg.input_channel(i).data(), | 1786 msg.input_channel(i).data(), |
1781 msg.input_channel(i).size()); | 1787 msg.input_channel(i).size()); |
1782 } | 1788 } |
1783 } else { | 1789 } else { |
1784 memcpy(frame_->data_, msg.input_data().data(), msg.input_data().size()); | 1790 memcpy(frame_->mutable_data(), msg.input_data().data(), |
| 1791 msg.input_data().size()); |
1785 if (format == kFloatFormat) { | 1792 if (format == kFloatFormat) { |
1786 // We're using an int16 input file; convert to float. | 1793 // We're using an int16 input file; convert to float. |
1787 ConvertToFloat(*frame_, float_cb_.get()); | 1794 ConvertToFloat(*frame_, float_cb_.get()); |
1788 } | 1795 } |
1789 } | 1796 } |
1790 ProcessStreamChooser(format); | 1797 ProcessStreamChooser(format); |
1791 } | 1798 } |
1792 } | 1799 } |
1793 EXPECT_NOERR(apm_->StopDebugRecording()); | 1800 EXPECT_NOERR(apm_->StopDebugRecording()); |
1794 fclose(in_file); | 1801 fclose(in_file); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 LayoutFromChannels(num_render_channels))); | 1990 LayoutFromChannels(num_render_channels))); |
1984 | 1991 |
1985 EXPECT_NOERR(apm_->set_stream_delay_ms(0)); | 1992 EXPECT_NOERR(apm_->set_stream_delay_ms(0)); |
1986 EXPECT_NOERR(fapm->set_stream_delay_ms(0)); | 1993 EXPECT_NOERR(fapm->set_stream_delay_ms(0)); |
1987 apm_->echo_cancellation()->set_stream_drift_samples(0); | 1994 apm_->echo_cancellation()->set_stream_drift_samples(0); |
1988 fapm->echo_cancellation()->set_stream_drift_samples(0); | 1995 fapm->echo_cancellation()->set_stream_drift_samples(0); |
1989 EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(analog_level)); | 1996 EXPECT_NOERR(apm_->gain_control()->set_stream_analog_level(analog_level)); |
1990 EXPECT_NOERR(fapm->gain_control()->set_stream_analog_level(analog_level)); | 1997 EXPECT_NOERR(fapm->gain_control()->set_stream_analog_level(analog_level)); |
1991 | 1998 |
1992 EXPECT_NOERR(apm_->ProcessStream(frame_)); | 1999 EXPECT_NOERR(apm_->ProcessStream(frame_)); |
1993 Deinterleave(frame_->data_, samples_per_channel, num_output_channels, | 2000 Deinterleave(frame_->data(), samples_per_channel, num_output_channels, |
1994 output_int16.channels()); | 2001 output_int16.channels()); |
1995 | 2002 |
1996 EXPECT_NOERR(fapm->ProcessStream( | 2003 EXPECT_NOERR(fapm->ProcessStream( |
1997 float_cb_->channels(), | 2004 float_cb_->channels(), |
1998 samples_per_channel, | 2005 samples_per_channel, |
1999 test->sample_rate(), | 2006 test->sample_rate(), |
2000 LayoutFromChannels(num_input_channels), | 2007 LayoutFromChannels(num_input_channels), |
2001 test->sample_rate(), | 2008 test->sample_rate(), |
2002 LayoutFromChannels(num_output_channels), | 2009 LayoutFromChannels(num_output_channels), |
2003 float_cb_->channels())); | 2010 float_cb_->channels())); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2147 if (apm_->voice_detection()->stream_has_voice()) { | 2154 if (apm_->voice_detection()->stream_has_voice()) { |
2148 has_voice_count++; | 2155 has_voice_count++; |
2149 EXPECT_EQ(AudioFrame::kVadActive, frame_->vad_activity_); | 2156 EXPECT_EQ(AudioFrame::kVadActive, frame_->vad_activity_); |
2150 } else { | 2157 } else { |
2151 EXPECT_EQ(AudioFrame::kVadPassive, frame_->vad_activity_); | 2158 EXPECT_EQ(AudioFrame::kVadPassive, frame_->vad_activity_); |
2152 } | 2159 } |
2153 | 2160 |
2154 ns_speech_prob_average += apm_->noise_suppression()->speech_probability(); | 2161 ns_speech_prob_average += apm_->noise_suppression()->speech_probability(); |
2155 | 2162 |
2156 size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_; | 2163 size_t frame_size = frame_->samples_per_channel_ * frame_->num_channels_; |
2157 size_t write_count = fwrite(frame_->data_, | 2164 size_t write_count = fwrite(frame_->data(), |
2158 sizeof(int16_t), | 2165 sizeof(int16_t), |
2159 frame_size, | 2166 frame_size, |
2160 out_file_); | 2167 out_file_); |
2161 ASSERT_EQ(frame_size, write_count); | 2168 ASSERT_EQ(frame_size, write_count); |
2162 | 2169 |
2163 // Reset in case of downmixing. | 2170 // Reset in case of downmixing. |
2164 frame_->num_channels_ = static_cast<size_t>(test->num_input_channels()); | 2171 frame_->num_channels_ = static_cast<size_t>(test->num_input_channels()); |
2165 frame_count++; | 2172 frame_count++; |
2166 | 2173 |
2167 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE) | 2174 #if defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE) |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2877 // TODO(peah): Remove the testing for | 2884 // TODO(peah): Remove the testing for |
2878 // apm->capture_nonlocked_.level_controller_enabled once the value in config_ | 2885 // apm->capture_nonlocked_.level_controller_enabled once the value in config_ |
2879 // is instead used to activate the level controller. | 2886 // is instead used to activate the level controller. |
2880 EXPECT_FALSE(apm->capture_nonlocked_.level_controller_enabled); | 2887 EXPECT_FALSE(apm->capture_nonlocked_.level_controller_enabled); |
2881 EXPECT_NEAR(kTargetLcPeakLeveldBFS, | 2888 EXPECT_NEAR(kTargetLcPeakLeveldBFS, |
2882 apm->config_.level_controller.initial_peak_level_dbfs, | 2889 apm->config_.level_controller.initial_peak_level_dbfs, |
2883 std::numeric_limits<float>::epsilon()); | 2890 std::numeric_limits<float>::epsilon()); |
2884 } | 2891 } |
2885 | 2892 |
2886 } // namespace webrtc | 2893 } // namespace webrtc |
OLD | NEW |