| 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..965820ca3b142c1819e9185c599805319e23eff8
|
| --- /dev/null
|
| +++ b/webrtc/modules/audio_processing/test/bitexactness_tools.cc
|
| @@ -0,0 +1,145 @@
|
| +/*
|
| + * 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");
|
| + case 16000:
|
| + return ResourcePath("far16_stereo", "pcm");
|
| + case 32000:
|
| + return ResourcePath("far32_stereo", "pcm");
|
| + case 48000:
|
| + return ResourcePath("far48_stereo", "pcm");
|
| + default:
|
| + RTC_DCHECK(false);
|
| + }
|
| + return "";
|
| +}
|
| +
|
| +std::string GetApmCaptureTestVectorFileName(int sample_rate_hz) {
|
| + switch (sample_rate_hz) {
|
| + case 8000:
|
| + return ResourcePath("near8_stereo", "pcm");
|
| + case 16000:
|
| + return ResourcePath("near16_stereo", "pcm");
|
| + case 32000:
|
| + return ResourcePath("near32_stereo", "pcm");
|
| + case 48000:
|
| + return ResourcePath("near48_stereo", "pcm");
|
| + 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
|
|
|