Index: media/base/audio_sample_types_unittest.cc |
diff --git a/media/base/audio_sample_types_unittest.cc b/media/base/audio_sample_types_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8c11c1e56eebca56d26fca8b3e5227750a988837 |
--- /dev/null |
+++ b/media/base/audio_sample_types_unittest.cc |
@@ -0,0 +1,229 @@ |
+// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stdint.h> |
+ |
+#include "base/macros.h" |
+#include "media/base/audio_sample_types.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace media { |
+ |
+template <typename TestConfig> |
+class SampleTypeTraitsTest : public testing::Test {}; |
+ |
+TYPED_TEST_CASE_P(SampleTypeTraitsTest); |
+ |
+struct UnsignedInt8ToFloat32TestConfig { |
+ using SourceTraits = UnsignedInt8SampleTypeTraits; |
+ using TargetTraits = Float32SampleTypeTraits; |
+ static const char* config_name() { return "UnsignedInt8ToFloat32TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToFloat(source_value); |
+ } |
+}; |
+ |
+struct SignedInt16ToFloat32TestConfig { |
+ using SourceTraits = SignedInt16SampleTypeTraits; |
+ using TargetTraits = Float32SampleTypeTraits; |
+ static const char* config_name() { return "SignedInt16ToFloat32TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToFloat(source_value); |
+ } |
+}; |
+ |
+struct SignedInt32ToFloat32TestConfig { |
+ using SourceTraits = SignedInt32SampleTypeTraits; |
+ using TargetTraits = Float32SampleTypeTraits; |
+ static const char* config_name() { return "SignedInt32ToFloat32TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToFloat(source_value); |
+ } |
+}; |
+ |
+struct Float32ToUnsignedInt8TestConfig { |
+ using SourceTraits = Float32SampleTypeTraits; |
+ using TargetTraits = UnsignedInt8SampleTypeTraits; |
+ static const char* config_name() { return "Float32ToUnsignedInt8TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromFloat(source_value); |
+ } |
+}; |
+ |
+struct Float32ToSignedInt16TestConfig { |
+ using SourceTraits = Float32SampleTypeTraits; |
+ using TargetTraits = SignedInt16SampleTypeTraits; |
+ static const char* config_name() { return "Float32ToSignedInt16TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromFloat(source_value); |
+ } |
+}; |
+ |
+struct Float32ToSignedInt32TestConfig { |
+ using SourceTraits = Float32SampleTypeTraits; |
+ using TargetTraits = SignedInt32SampleTypeTraits; |
+ static const char* config_name() { return "Float32ToSignedInt32TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromFloat(source_value); |
+ } |
+}; |
+ |
+struct UnsignedInt8ToFloat64TestConfig { |
+ using SourceTraits = UnsignedInt8SampleTypeTraits; |
+ using TargetTraits = Float64SampleTypeTraits; |
+ static const char* config_name() { return "UnsignedInt8ToFloat64TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToDouble(source_value); |
+ } |
+}; |
+ |
+struct SignedInt16ToFloat64TestConfig { |
+ using SourceTraits = SignedInt16SampleTypeTraits; |
+ using TargetTraits = Float64SampleTypeTraits; |
+ static const char* config_name() { return "SignedInt16ToFloat64TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToDouble(source_value); |
+ } |
+}; |
+ |
+struct SignedInt32ToFloat64TestConfig { |
+ using SourceTraits = SignedInt32SampleTypeTraits; |
+ using TargetTraits = Float64SampleTypeTraits; |
+ static const char* config_name() { return "SignedInt32ToFloat64TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return SourceTraits::ToDouble(source_value); |
+ } |
+}; |
+ |
+struct Float64ToUnsignedInt8TestConfig { |
+ using SourceTraits = Float64SampleTypeTraits; |
+ using TargetTraits = UnsignedInt8SampleTypeTraits; |
+ static const char* config_name() { return "Float64ToUnsignedInt8TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromDouble(source_value); |
+ } |
+}; |
+ |
+struct Float64ToSignedInt16TestConfig { |
+ using SourceTraits = Float64SampleTypeTraits; |
+ using TargetTraits = SignedInt16SampleTypeTraits; |
+ static const char* config_name() { return "Float64ToSignedInt16TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromDouble(source_value); |
+ } |
+}; |
+ |
+struct Float64ToSignedInt32TestConfig { |
+ using SourceTraits = Float64SampleTypeTraits; |
+ using TargetTraits = SignedInt32SampleTypeTraits; |
+ static const char* config_name() { return "Float64ToSignedInt32TestConfig"; } |
+ static TargetTraits::ValueType PerformConversion( |
+ SourceTraits::ValueType source_value) { |
+ return TargetTraits::FromDouble(source_value); |
+ } |
+}; |
+ |
+TYPED_TEST_P(SampleTypeTraitsTest, ConvertExampleValues) { |
+ using Config = TypeParam; |
+ using SourceTraits = typename Config::SourceTraits; |
+ using TargetTraits = typename Config::TargetTraits; |
+ using SourceType = typename SourceTraits::ValueType; |
+ using TargetType = typename TargetTraits::ValueType; |
+ SourceType source_max = SourceTraits::kMaxValue; |
+ SourceType source_min = SourceTraits::kMinValue; |
+ SourceType source_zero_point = SourceTraits::kZeroPointValue; |
+ SourceType source_two = static_cast<SourceType>(2); |
+ TargetType target_max = TargetTraits::kMaxValue; |
+ TargetType target_min = TargetTraits::kMinValue; |
+ TargetType target_zero_point = TargetTraits::kZeroPointValue; |
+ TargetType target_two = static_cast<TargetType>(2); |
+ |
+ SCOPED_TRACE(Config::config_name()); |
+ |
+ { |
+ SCOPED_TRACE("Convert zero-point value"); |
+ ASSERT_EQ(target_zero_point, |
+ Config::PerformConversion(SourceTraits::kZeroPointValue)); |
+ } |
+ { |
+ SCOPED_TRACE("Convert max value"); |
+ ASSERT_EQ(target_max, Config::PerformConversion(source_max)); |
+ } |
+ { |
+ SCOPED_TRACE("Convert min value"); |
+ ASSERT_EQ(target_min, Config::PerformConversion(source_min)); |
+ } |
+ |
+ { |
+ SCOPED_TRACE("Convert value half way between min and zero point"); |
+ // Note: This somewhat unconventional way of calculating the source and |
+ // target value is necessary to avoid any intermediate result falling |
+ // outside the corresponding numeric range. |
+ auto source_value = source_min + ((source_zero_point / source_two) - |
+ (source_min / source_two)); |
+ auto expected_target_value = |
+ target_min + |
+ ((target_zero_point / target_two) - (target_min / target_two)); |
+ ASSERT_EQ(expected_target_value, Config::PerformConversion(source_value)); |
+ } |
+ |
+ { |
+ SCOPED_TRACE("Convert value half way between zero point and max"); |
+ |
+ auto source_value = |
+ source_zero_point + ((source_max - source_zero_point) / source_two); |
+ auto expected_target_value = |
+ target_zero_point + ((target_max - target_zero_point) / target_two); |
+ |
+ if (std::numeric_limits<SourceType>::is_integer && |
+ std::is_floating_point<TargetType>::value) { |
+ // The source value half-way between zero point and max falls in the |
+ // middle between two integers, so we expect it to be off by 0.5. |
+ TargetType kTolerance = |
+ static_cast<TargetType>(0.5) * (source_max - source_zero_point); |
+ ASSERT_NEAR(expected_target_value, |
+ Config::PerformConversion(source_value), kTolerance); |
+ } else if (std::is_floating_point<SourceType>::value && |
+ std::numeric_limits<TargetType>::is_integer) { |
+ // The quantization error of the scaling factor due to the limited |
+ // precision of the floating point type can cause the result to be off |
+ // by 1. |
+ auto kTolerance = static_cast<TargetType>(1); |
+ ASSERT_NEAR(expected_target_value, |
+ Config::PerformConversion(source_value), kTolerance); |
+ } else { |
+ ASSERT_EQ(expected_target_value, Config::PerformConversion(source_value)); |
+ } |
+ } |
+} |
+ |
+REGISTER_TYPED_TEST_CASE_P(SampleTypeTraitsTest, ConvertExampleValues); |
+ |
+typedef ::testing::Types<UnsignedInt8ToFloat32TestConfig, |
+ SignedInt16ToFloat32TestConfig, |
+ SignedInt32ToFloat32TestConfig, |
+ Float32ToUnsignedInt8TestConfig, |
+ Float32ToSignedInt16TestConfig, |
+ Float32ToSignedInt32TestConfig, |
+ UnsignedInt8ToFloat64TestConfig, |
+ SignedInt16ToFloat64TestConfig, |
+ SignedInt32ToFloat64TestConfig, |
+ Float64ToUnsignedInt8TestConfig, |
+ Float64ToSignedInt16TestConfig, |
+ Float64ToSignedInt32TestConfig> |
+ TestConfigs; |
+INSTANTIATE_TYPED_TEST_CASE_P(CommonTypes, SampleTypeTraitsTest, TestConfigs); |
+ |
+} // namespace media |