| // 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 "cobalt/media/base/audio_sample_types.h" |
| #include "base/basictypes.h" |
| #include "starboard/types.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace cobalt { |
| 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 |
| } // namespace cobalt |