Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(939)

Unified Diff: media/base/audio_sample_types.h

Issue 2024993004: AudioBus: Add a ToInterleavedFloat() method to AudioBus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switched to templated method approach Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/audio_bus_unittest.cc ('k') | media/cast/sender/audio_encoder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/audio_sample_types.h
diff --git a/media/base/audio_sample_types.h b/media/base/audio_sample_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..324e9b38f508045e2b7f022fe12cf72addb6f7b2
--- /dev/null
+++ b/media/base/audio_sample_types.h
@@ -0,0 +1,169 @@
+// 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.
+
+#ifndef MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_
+#define MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_
+
+#include <cstdint>
+#include <limits>
+
+// Provides one class per sample type. Each class satisfies a concept we call
+// "SampleTypeTraits", which requires that the following publics are provided:
+// * A typedef |ValueType| specifying the C++ type for storing sample values
+// * A static method min_value() that returns the minimum sample value
+// * A static method max_value() that returns the maximum sample value
+// * A static method zero_point_value() that returns the sample value
+// representing an amplitude of zero
+// * A static method convert_from_float32() that takes a float32 sample value
+// and converts it to |ValueType|.
+// * A static method convert_to_float32() that takes a value of |ValueType|
+// to a float32 sample value.
+
+namespace media {
+
+class Linear8BitUnsignedIntSampleTypeTraits {
+ public:
+ 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.
+ 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.
+ static uint8_t max_value() { return 255; }
+ static uint8_t zero_point_value() { return 128; }
+ static uint8_t convert_from_float32(float source_value) {
+ // Apply clipping to avoid having out-of-range values wrap around in the
+ // uint8_t domain.
+ if (source_value <= -1.0f) {
+ return min_value();
+ }
+ if (source_value >= 1.0f) {
+ return max_value();
+ }
+ // Apply scaling and shift
+ return static_cast<uint8_t>(
+ (source_value * get_scale_factor(source_value)) + zero_point_value());
+ }
+ static float convert_to_float32(uint8_t source_value) {
+ // Apply shift
+ float shifted_value = static_cast<float>(source_value) - zero_point_value();
+ // Apply scaling
+ return shifted_value / get_scale_factor(shifted_value);
+ }
+
+ private:
+ // Since zero_point_value() is not the exact center between
+ // min_value() and max_value(), we apply a different scaling for positive
+ // and negative values.
+ static float get_scale_factor(float input_value) {
+ return (input_value < 0.0f) ? scale_factor_for_negative()
+ : scale_factor_for_positive();
+ }
+ static float scale_factor_for_positive() {
+ return max_value() - zero_point_value();
+ }
+ static float scale_factor_for_negative() {
+ return zero_point_value() - min_value();
+ }
+};
+
+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
+ public:
+ typedef int16_t ValueType;
+ static int16_t min_value() { return std::numeric_limits<int16_t>::min(); }
+ static int16_t max_value() { return std::numeric_limits<int16_t>::max(); }
+ static int16_t zero_point_value() { return 0; }
+
+ static int16_t convert_from_float32(float source_value) {
+ // Apply clipping to avoid having out-of-range values wrap around in the
+ // int16_t domain.
+ if (source_value <= -1.0f) {
+ return min_value();
+ }
+ if (source_value >= 1.0f) {
+ return max_value();
+ }
+ // Apply scaling and convert type.
+ return static_cast<int16_t>(source_value * get_scale_factor(source_value));
+ }
+
+ static float convert_to_float32(int16_t source_value) {
+ return source_value / get_scale_factor(source_value);
+ }
+
+ private:
+ // Since zero_point_value() is not the exact center between
+ // min_value() and max_value(), we apply a different scaling for positive
+ // and negative values.
+ static float get_scale_factor(float input_value) {
+ return (input_value < 0.0f) ? (-static_cast<float>(min_value()))
+ : static_cast<float>(max_value());
+ }
+};
+
+class Linear32BitSignedIntSampleTypeTraits {
+ public:
+ typedef int32_t ValueType;
+ static int32_t min_value() { return std::numeric_limits<int32_t>::min(); }
+ static int32_t max_value() { return std::numeric_limits<int32_t>::max(); }
+ static int32_t zero_point_value() { return 0; }
+
+ static int32_t convert_from_float32(float source_value) {
+ // Note: Due to the limited precision, float cannot represent the integer
+ // std::numeric_limits<int32_t>::max(), which we want to use as the scaling
+ // factor for positive values. When converting to float, this scaling factor
+ // gets quantized to a neighboring value that float can represent.
+ // Not sure if this depends on the compiler or platform, but when tested on
+ // an example workstation, the quantized value came out as
+ // std::numeric_limits<int32_t>::max() + 1. When multiplied with a
+ // |source_value| of 1.0f and converted to int32_t, this would cause an
+ // overflow leading to a large negative value instead.
+ // To ensure this does not happen, we handle the case of |source_value| ==
+ // 1.0 in the handling for clipping.
+ // For the case of |source_value| being the largest possible float value
+ // smaller than 1.0, multiplying by (numeric_limits<int32_t>::max() + 1)
+ // already results in a value smaller than numeric_limits<int32_t>::max(),
+ // so this does not cause any issue.
+ // For the negative case of std::numeric_limits<int32_t>::min() it turns out
+ // that the quantized value matches the desired value exactly, so there is
+ // no issue at all.
+
+ // Apply clipping and handling of the 1.0f case
+ if (source_value <= -1.0f) {
+ return min_value();
+ }
+ if (source_value >= 1.0f) {
+ return max_value();
+ }
+ // Apply scaling and convert type.
+ return static_cast<int32_t>(source_value * get_scale_factor(source_value));
+ }
+
+ static float convert_to_float32(int32_t source_value) {
+ // Note: For the case of |source_value| == numeric_limits<int32_t>::max()
+ // what happens is that, before the division, |source_value| gets converted
+ // to float, which causes the same quantization error that we get for the
+ // scale factor. As a result, we obtain exactly 1.0f, which is what we want.
+ return source_value / get_scale_factor(source_value);
+ }
+
+ private:
+ // Since zero_point_value() is not the exact center between
+ // min_value() and max_value(), we apply a different scaling for positive
+ // and negative values.
+ static float get_scale_factor(float input_value) {
+ return (input_value < 0.0f) ? (-static_cast<float>(min_value()))
+ : static_cast<float>(max_value());
+ }
+};
+
+class Float32SampleTypeTraits {
+ public:
+ typedef float ValueType;
+ static float min_value() { return -1.0f; }
+ static float max_value() { return 1.0f; }
+ static float zero_point_value() { return 0.0f; }
+ static float convert_from_float32(float source_value) { return source_value; }
+ static float convert_to_float32(float source_value) { return source_value; }
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_AUDIO_SAMPLE_TYPES_H_
« no previous file with comments | « media/base/audio_bus_unittest.cc ('k') | media/cast/sender/audio_encoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698