Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 5 #ifndef MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_ | |
| 6 #define MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_ | |
| 7 | |
| 8 #include <cstdint> | |
| 9 #include <limits> | |
| 10 | |
| 11 // Provides one class per sample type. Each class satisfies a concept we call | |
| 12 // "SampleTypeTraits", which requires that the following publics are provided: | |
| 13 // * A typedef |ValueType| specifying the C++ type for storing sample values | |
| 14 // * A static method min_value() that returns the minimum sample value | |
| 15 // * A static method max_value() that returns the maximum sample value | |
| 16 // * A static method zero_point_value() that returns the sample value | |
| 17 // representing an amplitude of zero | |
| 18 // * A static method convert_from_float32() that takes a float32 sample value | |
| 19 // and converts it to |ValueType|. | |
| 20 // * A static method convert_to_float32() that takes a value of |ValueType| | |
| 21 // to a float32 sample value. | |
| 22 | |
| 23 namespace media { | |
| 24 | |
| 25 class Linear8BitUnsignedIntSampleTypeTraits { | |
| 26 public: | |
| 27 typedef uint8_t ValueType; | |
|
miu
2016/06/07 22:16:36
Chromium's preferring the new syntax for new code:
chfremer
2016/06/08 18:46:39
Done.
| |
| 28 static uint8_t min_value() { return 0; } | |
|
miu
2016/06/07 22:16:36
All the zero-arg static methods in these classes s
chfremer
2016/06/08 18:46:39
Done.
| |
| 29 static uint8_t max_value() { return 255; } | |
| 30 static uint8_t zero_point_value() { return 128; } | |
| 31 static uint8_t convert_from_float32(float source_value) { | |
| 32 // Apply clipping to avoid having out-of-range values wrap around in the | |
| 33 // uint8_t domain. | |
| 34 if (source_value <= -1.0f) { | |
| 35 return min_value(); | |
| 36 } | |
| 37 if (source_value >= 1.0f) { | |
| 38 return max_value(); | |
| 39 } | |
| 40 // Apply scaling and shift | |
| 41 return static_cast<uint8_t>( | |
| 42 (source_value * get_scale_factor(source_value)) + zero_point_value()); | |
| 43 } | |
| 44 static float convert_to_float32(uint8_t source_value) { | |
| 45 // Apply shift | |
| 46 float shifted_value = static_cast<float>(source_value) - zero_point_value(); | |
| 47 // Apply scaling | |
| 48 return shifted_value / get_scale_factor(shifted_value); | |
| 49 } | |
| 50 | |
| 51 private: | |
| 52 // Since zero_point_value() is not the exact center between | |
| 53 // min_value() and max_value(), we apply a different scaling for positive | |
| 54 // and negative values. | |
| 55 static float get_scale_factor(float input_value) { | |
| 56 return (input_value < 0.0f) ? scale_factor_for_negative() | |
| 57 : scale_factor_for_positive(); | |
| 58 } | |
| 59 static float scale_factor_for_positive() { | |
| 60 return max_value() - zero_point_value(); | |
| 61 } | |
| 62 static float scale_factor_for_negative() { | |
| 63 return zero_point_value() - min_value(); | |
| 64 } | |
| 65 }; | |
| 66 | |
| 67 class Linear16BitSignedIntSampleTypeTraits { | |
|
miu
2016/06/07 22:16:36
Seems all these classes for the integer types are
chfremer
2016/06/08 18:46:39
Thanks for this beautiful suggestion.
I will creat
| |
| 68 public: | |
| 69 typedef int16_t ValueType; | |
| 70 static int16_t min_value() { return std::numeric_limits<int16_t>::min(); } | |
| 71 static int16_t max_value() { return std::numeric_limits<int16_t>::max(); } | |
| 72 static int16_t zero_point_value() { return 0; } | |
| 73 | |
| 74 static int16_t convert_from_float32(float source_value) { | |
| 75 // Apply clipping to avoid having out-of-range values wrap around in the | |
| 76 // int16_t domain. | |
| 77 if (source_value <= -1.0f) { | |
| 78 return min_value(); | |
| 79 } | |
| 80 if (source_value >= 1.0f) { | |
| 81 return max_value(); | |
| 82 } | |
| 83 // Apply scaling and convert type. | |
| 84 return static_cast<int16_t>(source_value * get_scale_factor(source_value)); | |
| 85 } | |
| 86 | |
| 87 static float convert_to_float32(int16_t source_value) { | |
| 88 return source_value / get_scale_factor(source_value); | |
| 89 } | |
| 90 | |
| 91 private: | |
| 92 // Since zero_point_value() is not the exact center between | |
| 93 // min_value() and max_value(), we apply a different scaling for positive | |
| 94 // and negative values. | |
| 95 static float get_scale_factor(float input_value) { | |
| 96 return (input_value < 0.0f) ? (-static_cast<float>(min_value())) | |
| 97 : static_cast<float>(max_value()); | |
| 98 } | |
| 99 }; | |
| 100 | |
| 101 class Linear32BitSignedIntSampleTypeTraits { | |
| 102 public: | |
| 103 typedef int32_t ValueType; | |
| 104 static int32_t min_value() { return std::numeric_limits<int32_t>::min(); } | |
| 105 static int32_t max_value() { return std::numeric_limits<int32_t>::max(); } | |
| 106 static int32_t zero_point_value() { return 0; } | |
| 107 | |
| 108 static int32_t convert_from_float32(float source_value) { | |
| 109 // Note: Due to the limited precision, float cannot represent the integer | |
| 110 // std::numeric_limits<int32_t>::max(), which we want to use as the scaling | |
| 111 // factor for positive values. When converting to float, this scaling factor | |
| 112 // gets quantized to a neighboring value that float can represent. | |
| 113 // Not sure if this depends on the compiler or platform, but when tested on | |
| 114 // an example workstation, the quantized value came out as | |
| 115 // std::numeric_limits<int32_t>::max() + 1. When multiplied with a | |
| 116 // |source_value| of 1.0f and converted to int32_t, this would cause an | |
| 117 // overflow leading to a large negative value instead. | |
| 118 // To ensure this does not happen, we handle the case of |source_value| == | |
| 119 // 1.0 in the handling for clipping. | |
| 120 // For the case of |source_value| being the largest possible float value | |
| 121 // smaller than 1.0, multiplying by (numeric_limits<int32_t>::max() + 1) | |
| 122 // already results in a value smaller than numeric_limits<int32_t>::max(), | |
| 123 // so this does not cause any issue. | |
| 124 // For the negative case of std::numeric_limits<int32_t>::min() it turns out | |
| 125 // that the quantized value matches the desired value exactly, so there is | |
| 126 // no issue at all. | |
| 127 | |
| 128 // Apply clipping and handling of the 1.0f case | |
| 129 if (source_value <= -1.0f) { | |
| 130 return min_value(); | |
| 131 } | |
| 132 if (source_value >= 1.0f) { | |
| 133 return max_value(); | |
| 134 } | |
| 135 // Apply scaling and convert type. | |
| 136 return static_cast<int32_t>(source_value * get_scale_factor(source_value)); | |
| 137 } | |
| 138 | |
| 139 static float convert_to_float32(int32_t source_value) { | |
| 140 // Note: For the case of |source_value| == numeric_limits<int32_t>::max() | |
| 141 // what happens is that, before the division, |source_value| gets converted | |
| 142 // to float, which causes the same quantization error that we get for the | |
| 143 // scale factor. As a result, we obtain exactly 1.0f, which is what we want. | |
| 144 return source_value / get_scale_factor(source_value); | |
| 145 } | |
| 146 | |
| 147 private: | |
| 148 // Since zero_point_value() is not the exact center between | |
| 149 // min_value() and max_value(), we apply a different scaling for positive | |
| 150 // and negative values. | |
| 151 static float get_scale_factor(float input_value) { | |
| 152 return (input_value < 0.0f) ? (-static_cast<float>(min_value())) | |
| 153 : static_cast<float>(max_value()); | |
| 154 } | |
| 155 }; | |
| 156 | |
| 157 class Float32SampleTypeTraits { | |
| 158 public: | |
| 159 typedef float ValueType; | |
| 160 static float min_value() { return -1.0f; } | |
| 161 static float max_value() { return 1.0f; } | |
| 162 static float zero_point_value() { return 0.0f; } | |
| 163 static float convert_from_float32(float source_value) { return source_value; } | |
| 164 static float convert_to_float32(float source_value) { return source_value; } | |
| 165 }; | |
| 166 | |
| 167 } // namespace media | |
| 168 | |
| 169 #endif // MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_ | |
| OLD | NEW |