Chromium Code Reviews| Index: webrtc/modules/audio_processing/test/bitexactness_tools.cc |
| diff --git a/webrtc/modules/audio_processing/test/bitexactness_tools.cc b/webrtc/modules/audio_processing/test/bitexactness_tools.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..637f7de0fa1dfa149eb541aa6239e1f09f51530b |
| --- /dev/null |
| +++ b/webrtc/modules/audio_processing/test/bitexactness_tools.cc |
| @@ -0,0 +1,153 @@ |
| +/* |
| + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| + * |
| + * Use of this source code is governed by a BSD-style license |
| + * that can be found in the LICENSE file in the root of the source |
| + * tree. An additional intellectual property rights grant can be found |
| + * in the file PATENTS. All contributing project authors may |
| + * be found in the AUTHORS file in the root of the source tree. |
| + */ |
| + |
| +#include "webrtc/modules/audio_processing/test/bitexactness_tools.h" |
| + |
| +#include <math.h> |
| +#include <algorithm> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "webrtc/base/array_view.h" |
| +#include "webrtc/test/testsupport/fileutils.h" |
| + |
| +namespace webrtc { |
| +namespace test { |
| + |
| +std::string GetApmRenderTestVectorFileName(int sample_rate_hz) { |
| + switch (sample_rate_hz) { |
| + case 8000: |
| + return ResourcePath("far8_stereo", "pcm"); |
| + break; |
|
hlundin-webrtc
2016/03/17 14:14:40
You don't need break after return.
peah-webrtc
2016/03/17 22:26:02
Done.
|
| + case 16000: |
| + return ResourcePath("far16_stereo", "pcm"); |
| + break; |
| + case 32000: |
| + return ResourcePath("far32_stereo", "pcm"); |
| + break; |
| + case 48000: |
| + return ResourcePath("far48_stereo", "pcm"); |
| + break; |
| + default: |
| + RTC_DCHECK(false); |
| + } |
| + return ""; |
| +} |
| + |
| +std::string GetApmCaptureTestVectorFileName(int sample_rate_hz) { |
| + switch (sample_rate_hz) { |
| + case 8000: |
| + return ResourcePath("near8_stereo", "pcm"); |
| + break; |
|
hlundin-webrtc
2016/03/17 14:14:40
Skip the breaks! :)
peah-webrtc
2016/03/17 22:26:02
Done.
|
| + case 16000: |
| + return ResourcePath("near16_stereo", "pcm"); |
| + break; |
| + case 32000: |
| + return ResourcePath("near32_stereo", "pcm"); |
| + break; |
| + case 48000: |
| + return ResourcePath("near48_stereo", "pcm"); |
| + break; |
| + default: |
| + RTC_DCHECK(false); |
| + } |
| + return ""; |
| +} |
| + |
| +void ReadFloatSamplesFromStereoFile(size_t samples_per_channel, |
| + size_t num_channels, |
| + InputAudioFile* stereo_pcm_file, |
| + rtc::ArrayView<float> data) { |
| + RTC_DCHECK_EQ(data.size(), samples_per_channel * num_channels); |
| + std::vector<int16_t> read_samples(samples_per_channel * 2); |
| + stereo_pcm_file->Read(samples_per_channel * 2, read_samples.data()); |
| + |
| + // Convert samples to float and discard any channels not needed. |
| + for (size_t sample = 0; sample < samples_per_channel; ++sample) { |
| + for (size_t channel = 0; channel < num_channels; ++channel) { |
| + data[sample * num_channels + channel] = |
| + read_samples[sample * 2 + channel] / 32768.0f; |
| + } |
| + } |
| +} |
| + |
| +::testing::AssertionResult BitExactFrame(size_t samples_per_channel, |
| + size_t num_channels, |
| + rtc::ArrayView<const float> reference, |
| + rtc::ArrayView<const float> output, |
| + float tolerance) { |
| + // Form vectors to compare the reference to. Only the first values of the |
| + // outputs are compared in order not having to specify all preceeding frames |
| + // as testvectors. |
| + const size_t reference_frame_length = |
| + rtc::CheckedDivExact(reference.size(), num_channels); |
| + |
| + std::vector<float> output_to_verify; |
| + for (size_t channel_no = 0; channel_no < num_channels; ++channel_no) { |
| + output_to_verify.insert(output_to_verify.end(), |
| + output.begin() + channel_no * samples_per_channel, |
| + output.begin() + channel_no * samples_per_channel + |
| + reference_frame_length); |
| + } |
| + |
| + return BitExactVector(reference, output_to_verify, tolerance); |
| +} |
| + |
| +::testing::AssertionResult BitExactVector(rtc::ArrayView<const float> reference, |
| + rtc::ArrayView<const float> output, |
| + float tolerance) { |
| + // The vectors are deemed to be bitexact only if |
| + // a) output have a size at least as long as the reference. |
| + // b) the samples in the reference are bitexact with the corresponding samples |
| + // in the output. |
| + |
| + bool equal = true; |
| + if (output.size() < reference.size()) { |
| + equal = false; |
| + } else { |
| + // Compare the first samples in the vectors. |
| + for (size_t k = 0; k < reference.size(); ++k) { |
| + if (fabs(output[k] - reference[k]) > tolerance) { |
| + equal = false; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (equal) { |
| + return ::testing::AssertionSuccess(); |
| + } |
| + |
| + // Lambda function that produces a formatted string with the data in the |
| + // vector. |
| + auto print_vector_in_c_format = [](rtc::ArrayView<const float> v, |
| + size_t num_values_to_print) { |
| + std::string s = "{ "; |
| + for (size_t k = 0; k < std::min(num_values_to_print, v.size()); ++k) { |
| + s += std::to_string(v[k]) + "f"; |
| + s += (k < (num_values_to_print - 1)) ? ", " : ""; |
| + } |
| + return s + " }"; |
| + }; |
| + |
| + // If the vectors are deemed not to be similar, return a report of the |
| + // difference. |
| + return ::testing::AssertionFailure() |
| + << std::endl |
| + << " Actual values : " |
| + << print_vector_in_c_format(output, |
| + std::min(output.size(), reference.size())) |
| + << std::endl |
| + << " Expected values: " |
| + << print_vector_in_c_format(reference, reference.size()) << std::endl; |
| +} |
| + |
| +} // namespace test |
| +} // namespace webrtc |