]> code.delx.au - pulseaudio/blob - src/pulsecore/svolume_c.c
Fixup #include directives according to Coding Style
[pulseaudio] / src / pulsecore / svolume_c.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27
28 #include <pulsecore/macro.h>
29 #include <pulsecore/g711.h>
30 #include <pulsecore/core-util.h>
31 #include <pulsecore/endianmacros.h>
32
33 #include "sample-util.h"
34
35 static void pa_volume_u8_c(uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
36 unsigned channel;
37
38 for (channel = 0; length; length--) {
39 int32_t t, hi, lo;
40
41 hi = volumes[channel] >> 16;
42 lo = volumes[channel] & 0xFFFF;
43
44 t = (int32_t) *samples - 0x80;
45 t = ((t * lo) >> 16) + (t * hi);
46 t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
47 *samples++ = (uint8_t) (t + 0x80);
48
49 if (PA_UNLIKELY(++channel >= channels))
50 channel = 0;
51 }
52 }
53
54 static void pa_volume_alaw_c(uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
55 unsigned channel;
56
57 for (channel = 0; length; length--) {
58 int32_t t, hi, lo;
59
60 hi = volumes[channel] >> 16;
61 lo = volumes[channel] & 0xFFFF;
62
63 t = (int32_t) st_alaw2linear16(*samples);
64 t = ((t * lo) >> 16) + (t * hi);
65 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
66 *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
67
68 if (PA_UNLIKELY(++channel >= channels))
69 channel = 0;
70 }
71 }
72
73 static void pa_volume_ulaw_c(uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
74 unsigned channel;
75
76 for (channel = 0; length; length--) {
77 int32_t t, hi, lo;
78
79 hi = volumes[channel] >> 16;
80 lo = volumes[channel] & 0xFFFF;
81
82 t = (int32_t) st_ulaw2linear16(*samples);
83 t = ((t * lo) >> 16) + (t * hi);
84 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
85 *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
86
87 if (PA_UNLIKELY(++channel >= channels))
88 channel = 0;
89 }
90 }
91
92 static void pa_volume_s16ne_c(int16_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
93 unsigned channel;
94
95 length /= sizeof(int16_t);
96
97 for (channel = 0; length; length--) {
98 int32_t t, hi, lo;
99
100 /* Multiplying the 32bit volume factor with the 16bit
101 * sample might result in an 48bit value. We want to
102 * do without 64 bit integers and hence do the
103 * multiplication independantly for the HI and LO part
104 * of the volume. */
105
106 hi = volumes[channel] >> 16;
107 lo = volumes[channel] & 0xFFFF;
108
109 t = (int32_t)(*samples);
110 t = ((t * lo) >> 16) + (t * hi);
111 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
112 *samples++ = (int16_t) t;
113
114 if (PA_UNLIKELY(++channel >= channels))
115 channel = 0;
116 }
117 }
118
119 static void pa_volume_s16re_c(int16_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
120 unsigned channel;
121
122 length /= sizeof(int16_t);
123
124 for (channel = 0; length; length--) {
125 int32_t t, hi, lo;
126
127 hi = volumes[channel] >> 16;
128 lo = volumes[channel] & 0xFFFF;
129
130 t = (int32_t) PA_INT16_SWAP(*samples);
131 t = ((t * lo) >> 16) + (t * hi);
132 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
133 *samples++ = PA_INT16_SWAP((int16_t) t);
134
135 if (PA_UNLIKELY(++channel >= channels))
136 channel = 0;
137 }
138 }
139
140 static void pa_volume_float32ne_c(float *samples, float *volumes, unsigned channels, unsigned length) {
141 unsigned channel;
142
143 length /= sizeof(float);
144
145 for (channel = 0; length; length--) {
146 *samples++ *= volumes[channel];
147
148 if (PA_UNLIKELY(++channel >= channels))
149 channel = 0;
150 }
151 }
152
153 static void pa_volume_float32re_c(float *samples, float *volumes, unsigned channels, unsigned length) {
154 unsigned channel;
155
156 length /= sizeof(float);
157
158 for (channel = 0; length; length--) {
159 float t;
160
161 t = PA_FLOAT32_SWAP(*samples);
162 t *= volumes[channel];
163 *samples++ = PA_FLOAT32_SWAP(t);
164
165 if (PA_UNLIKELY(++channel >= channels))
166 channel = 0;
167 }
168 }
169
170 static void pa_volume_s32ne_c(int32_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
171 unsigned channel;
172
173 length /= sizeof(int32_t);
174
175 for (channel = 0; length; length--) {
176 int64_t t;
177
178 t = (int64_t)(*samples);
179 t = (t * volumes[channel]) >> 16;
180 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
181 *samples++ = (int32_t) t;
182
183 if (PA_UNLIKELY(++channel >= channels))
184 channel = 0;
185 }
186 }
187
188 static void pa_volume_s32re_c(int32_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
189 unsigned channel;
190
191 length /= sizeof(int32_t);
192
193 for (channel = 0; length; length--) {
194 int64_t t;
195
196 t = (int64_t) PA_INT32_SWAP(*samples);
197 t = (t * volumes[channel]) >> 16;
198 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
199 *samples++ = PA_INT32_SWAP((int32_t) t);
200
201 if (PA_UNLIKELY(++channel >= channels))
202 channel = 0;
203 }
204 }
205
206 static void pa_volume_s24ne_c(uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
207 unsigned channel;
208 uint8_t *e;
209
210 e = samples + length;
211
212 for (channel = 0; samples < e; samples += 3) {
213 int64_t t;
214
215 t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
216 t = (t * volumes[channel]) >> 16;
217 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
218 PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
219
220 if (PA_UNLIKELY(++channel >= channels))
221 channel = 0;
222 }
223 }
224
225 static void pa_volume_s24re_c(uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
226 unsigned channel;
227 uint8_t *e;
228
229 e = samples + length;
230
231 for (channel = 0; samples < e; samples += 3) {
232 int64_t t;
233
234 t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
235 t = (t * volumes[channel]) >> 16;
236 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
237 PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
238
239 if (PA_UNLIKELY(++channel >= channels))
240 channel = 0;
241 }
242 }
243
244 static void pa_volume_s24_32ne_c(uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
245 unsigned channel;
246
247 length /= sizeof(uint32_t);
248
249 for (channel = 0; length; length--) {
250 int64_t t;
251
252 t = (int64_t) ((int32_t) (*samples << 8));
253 t = (t * volumes[channel]) >> 16;
254 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
255 *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
256
257 if (PA_UNLIKELY(++channel >= channels))
258 channel = 0;
259 }
260 }
261
262 static void pa_volume_s24_32re_c(uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
263 unsigned channel;
264
265 length /= sizeof(uint32_t);
266
267 for (channel = 0; length; length--) {
268 int64_t t;
269
270 t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
271 t = (t * volumes[channel]) >> 16;
272 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
273 *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
274
275 if (PA_UNLIKELY(++channel >= channels))
276 channel = 0;
277 }
278 }
279
280 static pa_do_volume_func_t do_volume_table[] = {
281 [PA_SAMPLE_U8] = (pa_do_volume_func_t) pa_volume_u8_c,
282 [PA_SAMPLE_ALAW] = (pa_do_volume_func_t) pa_volume_alaw_c,
283 [PA_SAMPLE_ULAW] = (pa_do_volume_func_t) pa_volume_ulaw_c,
284 [PA_SAMPLE_S16NE] = (pa_do_volume_func_t) pa_volume_s16ne_c,
285 [PA_SAMPLE_S16RE] = (pa_do_volume_func_t) pa_volume_s16re_c,
286 [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
287 [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
288 [PA_SAMPLE_S32NE] = (pa_do_volume_func_t) pa_volume_s32ne_c,
289 [PA_SAMPLE_S32RE] = (pa_do_volume_func_t) pa_volume_s32re_c,
290 [PA_SAMPLE_S24NE] = (pa_do_volume_func_t) pa_volume_s24ne_c,
291 [PA_SAMPLE_S24RE] = (pa_do_volume_func_t) pa_volume_s24re_c,
292 [PA_SAMPLE_S24_32NE] = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
293 [PA_SAMPLE_S24_32RE] = (pa_do_volume_func_t) pa_volume_s24_32re_c
294 };
295
296 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f) {
297 pa_assert(f >= 0);
298 pa_assert(f < PA_SAMPLE_MAX);
299
300 return do_volume_table[f];
301 }
302
303 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func) {
304 pa_assert(f >= 0);
305 pa_assert(f < PA_SAMPLE_MAX);
306
307 do_volume_table[f] = func;
308 }