blob: c8bb0f7eec50d241859fce171f9025977f318ecf [file] [log] [blame]
// 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