OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
DaleCurtis
2016/04/01 19:31:20
2016
| |
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_CONVERSION_H_ | |
6 #define MEDIA_BASE_AUDIO_SAMPLE_CONVERSION_H_ | |
7 | |
8 #include <limits> | |
9 | |
10 namespace media { | |
11 | |
12 namespace internal { | |
13 | |
14 template <typename T> | |
15 struct IntegerSampleTraits { | |
16 typedef T promoted_type; | |
17 static const T bias = 0; | |
18 static promoted_type min() { return std::numeric_limits<T>::min(); } | |
19 static promoted_type max() { return std::numeric_limits<T>::max(); } | |
20 }; | |
21 | |
22 template <> | |
23 struct IntegerSampleTraits<uint8_t> { | |
24 typedef int16_t promoted_type; | |
25 static const uint8_t bias = 128; | |
26 static promoted_type min() { return std::numeric_limits<int8_t>::min(); } | |
27 static promoted_type max() { return std::numeric_limits<int8_t>::max(); } | |
28 }; | |
29 | |
30 } // namespace internal | |
31 | |
32 template <typename Format> | |
33 void DeinterleaveOneChannel(const Format* source, | |
34 int start_frame, | |
35 int frames, | |
36 float* channel_data, | |
37 int channel_count, | |
38 int ch) { | |
39 using Traits = internal::IntegerSampleTraits<Format>; | |
40 using Promoted = typename Traits::promoted_type; | |
41 | |
42 const float min = 1.0f / Traits::min(); | |
43 const float max = 1.0f / Traits::max(); | |
44 | |
45 for (int i = start_frame, offset = ch; i < start_frame + frames; | |
46 ++i, offset += channel_count) { | |
47 const Promoted v = static_cast<Promoted>(source[offset]) - Traits::bias; | |
48 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 :
| |
49 } | |
50 } | |
51 | |
52 template <> | |
53 inline void DeinterleaveOneChannel<float>(const float* source, | |
54 int start_frame, | |
55 int frames, | |
56 float* channel_data, | |
57 int channel_count, | |
58 int ch) { | |
59 for (int i = start_frame, offset = ch; i < start_frame + frames; | |
60 ++i, offset += channel_count) { | |
61 channel_data[i] = source[offset]; | |
62 } | |
63 } | |
64 | |
65 template <typename Format> | |
66 void InterleaveOneChannel(const float* channel_data, | |
67 int start_frame, | |
68 int frames, | |
69 Format* dest, | |
70 int channel_count, | |
71 int ch) { | |
72 using Traits = internal::IntegerSampleTraits<Format>; | |
73 using Promoted = typename Traits::promoted_type; | |
74 | |
75 const Promoted min = Traits::min(); | |
76 const Promoted max = Traits::max(); | |
77 | |
78 for (int i = start_frame, offset = ch; i < start_frame + frames; | |
79 ++i, offset += channel_count) { | |
80 const float v = channel_data[i]; | |
81 | |
82 Promoted sample; | |
83 if (v < 0) | |
84 sample = v <= -1 ? min : static_cast<Promoted>(-v * min); | |
85 else | |
86 sample = v >= 1 ? max : static_cast<Promoted>(v * max); | |
87 | |
88 dest[offset] = static_cast<Format>(sample + Traits::bias); | |
89 } | |
90 } | |
91 | |
92 template <> | |
93 inline void InterleaveOneChannel<float>(const float* channel_data, | |
94 int start_frame, | |
95 int frames, | |
96 float* dest, | |
97 int channel_count, | |
98 int ch) { | |
99 for (int i = start_frame, offset = ch; i < start_frame + frames; | |
100 ++i, offset += channel_count) { | |
101 dest[offset] = channel_data[i]; | |
102 } | |
103 } | |
104 | |
105 } // namespace media | |
106 | |
107 #endif // MEDIA_BASE_AUDIO_SAMPLE_CONVERSION_H_ | |
OLD | NEW |