OSDN Git Service

Add additional audio format conversion for packed 24 bit
[android-x86/system-media.git] / audio_utils / primitives.c
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <audio_utils/primitives.h>
18
19 void ditherAndClamp(int32_t* out, const int32_t *sums, size_t c)
20 {
21     size_t i;
22     for (i=0 ; i<c ; i++) {
23         int32_t l = *sums++;
24         int32_t r = *sums++;
25         int32_t nl = l >> 12;
26         int32_t nr = r >> 12;
27         l = clamp16(nl);
28         r = clamp16(nr);
29         *out++ = (r<<16) | (l & 0xFFFF);
30     }
31 }
32
33 void memcpy_to_i16_from_u8(int16_t *dst, const uint8_t *src, size_t count)
34 {
35     dst += count;
36     src += count;
37     while (count--) {
38         *--dst = (int16_t)(*--src - 0x80) << 8;
39     }
40 }
41
42 void memcpy_to_u8_from_i16(uint8_t *dst, const int16_t *src, size_t count)
43 {
44     while (count--) {
45         *dst++ = (*src++ >> 8) + 0x80;
46     }
47 }
48
49 void memcpy_to_i16_from_i32(int16_t *dst, const int32_t *src, size_t count)
50 {
51     while (count--) {
52         *dst++ = *src++ >> 16;
53     }
54 }
55
56 void memcpy_to_i16_from_float(int16_t *dst, const float *src, size_t count)
57 {
58     while (count--) {
59         *dst++ = clamp16FromFloat(*src++);
60     }
61 }
62
63 void memcpy_to_float_from_q19_12(float *dst, const int32_t *src, size_t c)
64 {
65     size_t i;
66     for (i = 0; i < c; ++i) {
67         *dst++ = float_from_q19_12(*src++);
68     }
69 }
70
71 void memcpy_to_float_from_i16(float *dst, const int16_t *src, size_t count)
72 {
73     while (count--) {
74         *dst++ = float_from_i16(*src++);
75     }
76 }
77
78 void memcpy_to_float_from_p24(float *dst, const uint8_t *src, size_t count)
79 {
80     while (count--) {
81         *dst++ = float_from_p24(src);
82         src += 3;
83     }
84 }
85
86 void memcpy_to_i16_from_p24(int16_t *dst, const uint8_t *src, size_t count)
87 {
88     while (count--) {
89 #ifdef HAVE_BIG_ENDIAN
90         *dst++ = src[1] | (src[0] << 8);
91 #else
92         *dst++ = src[1] | (src[2] << 8);
93 #endif
94         src += 3;
95     }
96 }
97
98 void memcpy_to_p24_from_i16(uint8_t *dst, const int16_t *src, size_t count)
99 {
100     while (count--) {
101 #ifdef HAVE_BIG_ENDIAN
102         *dst++ = *src >> 8;
103         *dst++ = *src++;
104         *dst++ = 0;
105 #else
106         *dst++ = 0;
107         *dst++ = *src;
108         *dst++ = *src++ >> 8;
109 #endif
110     }
111 }
112
113 void memcpy_to_p24_from_float(uint8_t *dst, const float *src, size_t count)
114 {
115     while (count--) {
116         int32_t ival = clamp24_from_float(*src++);
117
118 #ifdef HAVE_BIG_ENDIAN
119         *dst++ = ival >> 16;
120         *dst++ = ival >> 8;
121         *dst++ = ival;
122 #else
123         *dst++ = ival;
124         *dst++ = ival >> 8;
125         *dst++ = ival >> 16;
126 #endif
127     }
128 }
129
130 void downmix_to_mono_i16_from_stereo_i16(int16_t *dst, const int16_t *src, size_t count)
131 {
132     while (count--) {
133         *dst++ = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
134         src += 2;
135     }
136 }
137
138 void upmix_to_stereo_i16_from_mono_i16(int16_t *dst, const int16_t *src, size_t count)
139 {
140     while (count--) {
141         int32_t temp = *src++;
142         dst[0] = temp;
143         dst[1] = temp;
144         dst += 2;
145     }
146 }
147
148 size_t nonZeroMono32(const int32_t *samples, size_t count)
149 {
150     size_t nonZero = 0;
151     while (count-- > 0) {
152         if (*samples++ != 0) {
153             nonZero++;
154         }
155     }
156     return nonZero;
157 }
158
159 size_t nonZeroMono16(const int16_t *samples, size_t count)
160 {
161     size_t nonZero = 0;
162     while (count-- > 0) {
163         if (*samples++ != 0) {
164             nonZero++;
165         }
166     }
167     return nonZero;
168 }
169
170 size_t nonZeroStereo32(const int32_t *frames, size_t count)
171 {
172     size_t nonZero = 0;
173     while (count-- > 0) {
174         if (frames[0] != 0 || frames[1] != 0) {
175             nonZero++;
176         }
177         frames += 2;
178     }
179     return nonZero;
180 }
181
182 size_t nonZeroStereo16(const int16_t *frames, size_t count)
183 {
184     size_t nonZero = 0;
185     while (count-- > 0) {
186         if (frames[0] != 0 || frames[1] != 0) {
187             nonZero++;
188         }
189         frames += 2;
190     }
191     return nonZero;
192 }