Chromium Code Reviews| 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_ |