Index: media/base/audio_sample_conversion.h |
diff --git a/media/base/audio_sample_conversion.h b/media/base/audio_sample_conversion.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ba2289ea8eea6367e0e35450d0ce7cec89fe2ec2 |
--- /dev/null |
+++ b/media/base/audio_sample_conversion.h |
@@ -0,0 +1,107 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
DaleCurtis
2016/04/01 19:31:20
2016
|
+// 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_CONVERSION_H_ |
+#define MEDIA_BASE_AUDIO_SAMPLE_CONVERSION_H_ |
+ |
+#include <limits> |
+ |
+namespace media { |
+ |
+namespace internal { |
+ |
+template <typename T> |
+struct IntegerSampleTraits { |
+ typedef T promoted_type; |
+ static const T bias = 0; |
+ static promoted_type min() { return std::numeric_limits<T>::min(); } |
+ static promoted_type max() { return std::numeric_limits<T>::max(); } |
+}; |
+ |
+template <> |
+struct IntegerSampleTraits<uint8_t> { |
+ typedef int16_t promoted_type; |
+ static const uint8_t bias = 128; |
+ static promoted_type min() { return std::numeric_limits<int8_t>::min(); } |
+ static promoted_type max() { return std::numeric_limits<int8_t>::max(); } |
+}; |
+ |
+} // namespace internal |
+ |
+template <typename Format> |
+void DeinterleaveOneChannel(const Format* source, |
+ int start_frame, |
+ int frames, |
+ float* channel_data, |
+ int channel_count, |
+ int ch) { |
+ using Traits = internal::IntegerSampleTraits<Format>; |
+ using Promoted = typename Traits::promoted_type; |
+ |
+ const float min = 1.0f / Traits::min(); |
+ const float max = 1.0f / Traits::max(); |
+ |
+ for (int i = start_frame, offset = ch; i < start_frame + frames; |
+ ++i, offset += channel_count) { |
+ const Promoted v = static_cast<Promoted>(source[offset]) - Traits::bias; |
+ channel_data[i] = v * (v < 0 ? -min : max); |
DaleCurtis
2016/04/01 19:31:20
Out of curiosity if you make this "v * (v ? max :
|
+ } |
+} |
+ |
+template <> |
+inline void DeinterleaveOneChannel<float>(const float* source, |
+ int start_frame, |
+ int frames, |
+ float* channel_data, |
+ int channel_count, |
+ int ch) { |
+ for (int i = start_frame, offset = ch; i < start_frame + frames; |
+ ++i, offset += channel_count) { |
+ channel_data[i] = source[offset]; |
+ } |
+} |
+ |
+template <typename Format> |
+void InterleaveOneChannel(const float* channel_data, |
+ int start_frame, |
+ int frames, |
+ Format* dest, |
+ int channel_count, |
+ int ch) { |
+ using Traits = internal::IntegerSampleTraits<Format>; |
+ using Promoted = typename Traits::promoted_type; |
+ |
+ const Promoted min = Traits::min(); |
+ const Promoted max = Traits::max(); |
+ |
+ for (int i = start_frame, offset = ch; i < start_frame + frames; |
+ ++i, offset += channel_count) { |
+ const float v = channel_data[i]; |
+ |
+ Promoted sample; |
+ if (v < 0) |
+ sample = v <= -1 ? min : static_cast<Promoted>(-v * min); |
+ else |
+ sample = v >= 1 ? max : static_cast<Promoted>(v * max); |
+ |
+ dest[offset] = static_cast<Format>(sample + Traits::bias); |
+ } |
+} |
+ |
+template <> |
+inline void InterleaveOneChannel<float>(const float* channel_data, |
+ int start_frame, |
+ int frames, |
+ float* dest, |
+ int channel_count, |
+ int ch) { |
+ for (int i = start_frame, offset = ch; i < start_frame + frames; |
+ ++i, offset += channel_count) { |
+ dest[offset] = channel_data[i]; |
+ } |
+} |
+ |
+} // namespace media |
+ |
+#endif // MEDIA_BASE_AUDIO_SAMPLE_CONVERSION_H_ |