| 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..3c67d4941463d1929e97ae7cbe6a7b40d0635682
|
| --- /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::ConvertToFloat(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::ConvertToFloat(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::ConvertToFloat(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::ConvertFromFloat(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::ConvertFromFloat(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::ConvertFromFloat(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::ConvertToDouble(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::ConvertToDouble(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::ConvertToDouble(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::ConvertFromDouble(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::ConvertFromDouble(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::ConvertFromDouble(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
|
|
|