audio_sample_types_unittest.cc 8.7 KB

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