bitexactness_tools.cc (5217B)
1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/audio_processing/test/bitexactness_tools.h" 12 13 #include <algorithm> 14 #include <cmath> 15 #include <cstddef> 16 #include <cstdint> 17 #include <ostream> // no-presubmit-check TODO(webrtc:8982) 18 #include <string> 19 #include <vector> 20 21 #include "api/array_view.h" 22 #include "modules/audio_coding/neteq/tools/input_audio_file.h" 23 #include "rtc_base/checks.h" 24 #include "test/gtest.h" 25 #include "test/testsupport/file_utils.h" 26 27 namespace webrtc { 28 namespace test { 29 30 std::string GetApmRenderTestVectorFileName(int sample_rate_hz) { 31 switch (sample_rate_hz) { 32 case 8000: 33 return ResourcePath("far8_stereo", "pcm"); 34 case 16000: 35 return ResourcePath("far16_stereo", "pcm"); 36 case 32000: 37 return ResourcePath("far32_stereo", "pcm"); 38 case 48000: 39 return ResourcePath("far48_stereo", "pcm"); 40 default: 41 RTC_DCHECK_NOTREACHED(); 42 } 43 return ""; 44 } 45 46 std::string GetApmCaptureTestVectorFileName(int sample_rate_hz) { 47 switch (sample_rate_hz) { 48 case 8000: 49 return ResourcePath("near8_stereo", "pcm"); 50 case 16000: 51 return ResourcePath("near16_stereo", "pcm"); 52 case 32000: 53 return ResourcePath("near32_stereo", "pcm"); 54 case 48000: 55 return ResourcePath("near48_stereo", "pcm"); 56 default: 57 RTC_DCHECK_NOTREACHED(); 58 } 59 return ""; 60 } 61 62 void ReadFloatSamplesFromStereoFile(size_t samples_per_channel, 63 size_t num_channels, 64 InputAudioFile* stereo_pcm_file, 65 ArrayView<float> data) { 66 RTC_DCHECK_LE(num_channels, 2); 67 RTC_DCHECK_EQ(data.size(), samples_per_channel * num_channels); 68 std::vector<int16_t> read_samples(samples_per_channel * 2); 69 stereo_pcm_file->Read(samples_per_channel * 2, read_samples.data()); 70 71 // Convert samples to float and discard any channels not needed. 72 for (size_t sample = 0; sample < samples_per_channel; ++sample) { 73 for (size_t channel = 0; channel < num_channels; ++channel) { 74 data[sample * num_channels + channel] = 75 read_samples[sample * 2 + channel] / 32768.0f; 76 } 77 } 78 } 79 80 ::testing::AssertionResult VerifyDeinterleavedArray( 81 size_t samples_per_channel, 82 size_t num_channels, 83 ArrayView<const float> reference, 84 ArrayView<const float> output, 85 float element_error_bound) { 86 // Form vectors to compare the reference to. Only the first values of the 87 // outputs are compared in order not having to specify all preceeding frames 88 // as testvectors. 89 const size_t reference_frame_length = 90 CheckedDivExact(reference.size(), num_channels); 91 92 std::vector<float> output_to_verify; 93 for (size_t channel_no = 0; channel_no < num_channels; ++channel_no) { 94 output_to_verify.insert(output_to_verify.end(), 95 output.begin() + channel_no * samples_per_channel, 96 output.begin() + channel_no * samples_per_channel + 97 reference_frame_length); 98 } 99 100 return VerifyArray(reference, output_to_verify, element_error_bound); 101 } 102 103 ::testing::AssertionResult VerifyArray(ArrayView<const float> reference, 104 ArrayView<const float> output, 105 float element_error_bound) { 106 // The vectors are deemed to be bitexact only if 107 // a) output have a size at least as long as the reference. 108 // b) the samples in the reference are bitexact with the corresponding samples 109 // in the output. 110 111 bool equal = true; 112 if (output.size() < reference.size()) { 113 equal = false; 114 } else { 115 // Compare the first samples in the vectors. 116 for (size_t k = 0; k < reference.size(); ++k) { 117 if (fabs(output[k] - reference[k]) > element_error_bound) { 118 equal = false; 119 break; 120 } 121 } 122 } 123 124 if (equal) { 125 return ::testing::AssertionSuccess(); 126 } 127 128 // Lambda function that produces a formatted string with the data in the 129 // vector. 130 auto print_vector_in_c_format = [](ArrayView<const float> v, 131 size_t num_values_to_print) { 132 std::string s = "{ "; 133 for (size_t k = 0; k < std::min(num_values_to_print, v.size()); ++k) { 134 s += std::to_string(v[k]) + "f"; 135 s += (k < (num_values_to_print - 1)) ? ", " : ""; 136 } 137 return s + " }"; 138 }; 139 140 // If the vectors are deemed not to be similar, return a report of the 141 // difference. 142 return ::testing::AssertionFailure() 143 << std::endl 144 << " Actual values : " 145 << print_vector_in_c_format(output, 146 std::min(output.size(), reference.size())) 147 << std::endl 148 << " Expected values: " 149 << print_vector_in_c_format(reference, reference.size()) << std::endl; 150 } 151 152 } // namespace test 153 } // namespace webrtc