OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <stdint.h> |
| 6 |
| 7 #include "base/macros.h" |
| 8 #include "media/base/audio_sample_types.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 namespace media { |
| 12 |
| 13 template <typename TestConfig> |
| 14 class SampleTypeTraitsTest : public testing::Test {}; |
| 15 |
| 16 TYPED_TEST_CASE_P(SampleTypeTraitsTest); |
| 17 |
| 18 struct UnsignedInt8ToFloat32TestConfig { |
| 19 using SourceTraits = UnsignedInt8SampleTypeTraits; |
| 20 using TargetTraits = Float32SampleTypeTraits; |
| 21 static const char* config_name() { return "UnsignedInt8ToFloat32TestConfig"; } |
| 22 static TargetTraits::ValueType PerformConversion( |
| 23 SourceTraits::ValueType source_value) { |
| 24 return SourceTraits::ConvertToFloat(source_value); |
| 25 } |
| 26 }; |
| 27 |
| 28 struct SignedInt16ToFloat32TestConfig { |
| 29 using SourceTraits = SignedInt16SampleTypeTraits; |
| 30 using TargetTraits = Float32SampleTypeTraits; |
| 31 static const char* config_name() { return "SignedInt16ToFloat32TestConfig"; } |
| 32 static TargetTraits::ValueType PerformConversion( |
| 33 SourceTraits::ValueType source_value) { |
| 34 return SourceTraits::ConvertToFloat(source_value); |
| 35 } |
| 36 }; |
| 37 |
| 38 struct SignedInt32ToFloat32TestConfig { |
| 39 using SourceTraits = SignedInt32SampleTypeTraits; |
| 40 using TargetTraits = Float32SampleTypeTraits; |
| 41 static const char* config_name() { return "SignedInt32ToFloat32TestConfig"; } |
| 42 static TargetTraits::ValueType PerformConversion( |
| 43 SourceTraits::ValueType source_value) { |
| 44 return SourceTraits::ConvertToFloat(source_value); |
| 45 } |
| 46 }; |
| 47 |
| 48 struct Float32ToUnsignedInt8TestConfig { |
| 49 using SourceTraits = Float32SampleTypeTraits; |
| 50 using TargetTraits = UnsignedInt8SampleTypeTraits; |
| 51 static const char* config_name() { return "Float32ToUnsignedInt8TestConfig"; } |
| 52 static TargetTraits::ValueType PerformConversion( |
| 53 SourceTraits::ValueType source_value) { |
| 54 return TargetTraits::ConvertFromFloat(source_value); |
| 55 } |
| 56 }; |
| 57 |
| 58 struct Float32ToSignedInt16TestConfig { |
| 59 using SourceTraits = Float32SampleTypeTraits; |
| 60 using TargetTraits = SignedInt16SampleTypeTraits; |
| 61 static const char* config_name() { return "Float32ToSignedInt16TestConfig"; } |
| 62 static TargetTraits::ValueType PerformConversion( |
| 63 SourceTraits::ValueType source_value) { |
| 64 return TargetTraits::ConvertFromFloat(source_value); |
| 65 } |
| 66 }; |
| 67 |
| 68 struct Float32ToSignedInt32TestConfig { |
| 69 using SourceTraits = Float32SampleTypeTraits; |
| 70 using TargetTraits = SignedInt32SampleTypeTraits; |
| 71 static const char* config_name() { return "Float32ToSignedInt32TestConfig"; } |
| 72 static TargetTraits::ValueType PerformConversion( |
| 73 SourceTraits::ValueType source_value) { |
| 74 return TargetTraits::ConvertFromFloat(source_value); |
| 75 } |
| 76 }; |
| 77 |
| 78 struct UnsignedInt8ToFloat64TestConfig { |
| 79 using SourceTraits = UnsignedInt8SampleTypeTraits; |
| 80 using TargetTraits = Float64SampleTypeTraits; |
| 81 static const char* config_name() { return "UnsignedInt8ToFloat64TestConfig"; } |
| 82 static TargetTraits::ValueType PerformConversion( |
| 83 SourceTraits::ValueType source_value) { |
| 84 return SourceTraits::ConvertToDouble(source_value); |
| 85 } |
| 86 }; |
| 87 |
| 88 struct SignedInt16ToFloat64TestConfig { |
| 89 using SourceTraits = SignedInt16SampleTypeTraits; |
| 90 using TargetTraits = Float64SampleTypeTraits; |
| 91 static const char* config_name() { return "SignedInt16ToFloat64TestConfig"; } |
| 92 static TargetTraits::ValueType PerformConversion( |
| 93 SourceTraits::ValueType source_value) { |
| 94 return SourceTraits::ConvertToDouble(source_value); |
| 95 } |
| 96 }; |
| 97 |
| 98 struct SignedInt32ToFloat64TestConfig { |
| 99 using SourceTraits = SignedInt32SampleTypeTraits; |
| 100 using TargetTraits = Float64SampleTypeTraits; |
| 101 static const char* config_name() { return "SignedInt32ToFloat64TestConfig"; } |
| 102 static TargetTraits::ValueType PerformConversion( |
| 103 SourceTraits::ValueType source_value) { |
| 104 return SourceTraits::ConvertToDouble(source_value); |
| 105 } |
| 106 }; |
| 107 |
| 108 struct Float64ToUnsignedInt8TestConfig { |
| 109 using SourceTraits = Float64SampleTypeTraits; |
| 110 using TargetTraits = UnsignedInt8SampleTypeTraits; |
| 111 static const char* config_name() { return "Float64ToUnsignedInt8TestConfig"; } |
| 112 static TargetTraits::ValueType PerformConversion( |
| 113 SourceTraits::ValueType source_value) { |
| 114 return TargetTraits::ConvertFromDouble(source_value); |
| 115 } |
| 116 }; |
| 117 |
| 118 struct Float64ToSignedInt16TestConfig { |
| 119 using SourceTraits = Float64SampleTypeTraits; |
| 120 using TargetTraits = SignedInt16SampleTypeTraits; |
| 121 static const char* config_name() { return "Float64ToSignedInt16TestConfig"; } |
| 122 static TargetTraits::ValueType PerformConversion( |
| 123 SourceTraits::ValueType source_value) { |
| 124 return TargetTraits::ConvertFromDouble(source_value); |
| 125 } |
| 126 }; |
| 127 |
| 128 struct Float64ToSignedInt32TestConfig { |
| 129 using SourceTraits = Float64SampleTypeTraits; |
| 130 using TargetTraits = SignedInt32SampleTypeTraits; |
| 131 static const char* config_name() { return "Float64ToSignedInt32TestConfig"; } |
| 132 static TargetTraits::ValueType PerformConversion( |
| 133 SourceTraits::ValueType source_value) { |
| 134 return TargetTraits::ConvertFromDouble(source_value); |
| 135 } |
| 136 }; |
| 137 |
| 138 TYPED_TEST_P(SampleTypeTraitsTest, ConvertExampleValues) { |
| 139 using Config = TypeParam; |
| 140 using SourceTraits = typename Config::SourceTraits; |
| 141 using TargetTraits = typename Config::TargetTraits; |
| 142 using SourceType = typename SourceTraits::ValueType; |
| 143 using TargetType = typename TargetTraits::ValueType; |
| 144 SourceType source_max = SourceTraits::kMaxValue; |
| 145 SourceType source_min = SourceTraits::kMinValue; |
| 146 SourceType source_zero_point = SourceTraits::kZeroPointValue; |
| 147 SourceType source_two = static_cast<SourceType>(2); |
| 148 TargetType target_max = TargetTraits::kMaxValue; |
| 149 TargetType target_min = TargetTraits::kMinValue; |
| 150 TargetType target_zero_point = TargetTraits::kZeroPointValue; |
| 151 TargetType target_two = static_cast<TargetType>(2); |
| 152 |
| 153 SCOPED_TRACE(Config::config_name()); |
| 154 |
| 155 { |
| 156 SCOPED_TRACE("Convert zero-point value"); |
| 157 ASSERT_EQ(target_zero_point, |
| 158 Config::PerformConversion(SourceTraits::kZeroPointValue)); |
| 159 } |
| 160 { |
| 161 SCOPED_TRACE("Convert max value"); |
| 162 ASSERT_EQ(target_max, Config::PerformConversion(source_max)); |
| 163 } |
| 164 { |
| 165 SCOPED_TRACE("Convert min value"); |
| 166 ASSERT_EQ(target_min, Config::PerformConversion(source_min)); |
| 167 } |
| 168 |
| 169 { |
| 170 SCOPED_TRACE("Convert value half way between min and zero point"); |
| 171 // Note: This somewhat unconventional way of calculating the source and |
| 172 // target value is necessary to avoid any intermediate result falling |
| 173 // outside the corresponding numeric range. |
| 174 auto source_value = source_min + ((source_zero_point / source_two) - |
| 175 (source_min / source_two)); |
| 176 auto expected_target_value = |
| 177 target_min + |
| 178 ((target_zero_point / target_two) - (target_min / target_two)); |
| 179 ASSERT_EQ(expected_target_value, Config::PerformConversion(source_value)); |
| 180 } |
| 181 |
| 182 { |
| 183 SCOPED_TRACE("Convert value half way between zero point and max"); |
| 184 |
| 185 auto source_value = |
| 186 source_zero_point + ((source_max - source_zero_point) / source_two); |
| 187 auto expected_target_value = |
| 188 target_zero_point + ((target_max - target_zero_point) / target_two); |
| 189 |
| 190 if (std::numeric_limits<SourceType>::is_integer && |
| 191 std::is_floating_point<TargetType>::value) { |
| 192 // The source value half-way between zero point and max falls in the |
| 193 // middle between two integers, so we expect it to be off by 0.5. |
| 194 TargetType kTolerance = |
| 195 static_cast<TargetType>(0.5) * (source_max - source_zero_point); |
| 196 ASSERT_NEAR(expected_target_value, |
| 197 Config::PerformConversion(source_value), kTolerance); |
| 198 } else if (std::is_floating_point<SourceType>::value && |
| 199 std::numeric_limits<TargetType>::is_integer) { |
| 200 // The quantization error of the scaling factor due to the limited |
| 201 // precision of the floating point type can cause the result to be off |
| 202 // by 1. |
| 203 auto kTolerance = static_cast<TargetType>(1); |
| 204 ASSERT_NEAR(expected_target_value, |
| 205 Config::PerformConversion(source_value), kTolerance); |
| 206 } else { |
| 207 ASSERT_EQ(expected_target_value, Config::PerformConversion(source_value)); |
| 208 } |
| 209 } |
| 210 } |
| 211 |
| 212 REGISTER_TYPED_TEST_CASE_P(SampleTypeTraitsTest, ConvertExampleValues); |
| 213 |
| 214 typedef ::testing::Types<UnsignedInt8ToFloat32TestConfig, |
| 215 SignedInt16ToFloat32TestConfig, |
| 216 SignedInt32ToFloat32TestConfig, |
| 217 Float32ToUnsignedInt8TestConfig, |
| 218 Float32ToSignedInt16TestConfig, |
| 219 Float32ToSignedInt32TestConfig, |
| 220 UnsignedInt8ToFloat64TestConfig, |
| 221 SignedInt16ToFloat64TestConfig, |
| 222 SignedInt32ToFloat64TestConfig, |
| 223 Float64ToUnsignedInt8TestConfig, |
| 224 Float64ToSignedInt16TestConfig, |
| 225 Float64ToSignedInt32TestConfig> |
| 226 TestConfigs; |
| 227 INSTANTIATE_TYPED_TEST_CASE_P(CommonTypes, SampleTypeTraitsTest, TestConfigs); |
| 228 |
| 229 } // namespace media |
OLD | NEW |