]> code.delx.au - pulseaudio/blob - src/pulsecore/svolume_c.c
whitespace fixes
[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
32 #include "sample-util.h"
33 #include "endianmacros.h"
34
35 static void
36 pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
37 {
38 unsigned channel;
39
40 for (channel = 0; length; length--) {
41 int32_t t, hi, lo;
42
43 hi = volumes[channel] >> 16;
44 lo = volumes[channel] & 0xFFFF;
45
46 t = (int32_t) *samples - 0x80;
47 t = ((t * lo) >> 16) + (t * hi);
48 t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
49 *samples++ = (uint8_t) (t + 0x80);
50
51 if (PA_UNLIKELY(++channel >= channels))
52 channel = 0;
53 }
54 }
55
56 static void
57 pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
58 {
59 unsigned channel;
60
61 for (channel = 0; length; length--) {
62 int32_t t, hi, lo;
63
64 hi = volumes[channel] >> 16;
65 lo = volumes[channel] & 0xFFFF;
66
67 t = (int32_t) st_alaw2linear16(*samples);
68 t = ((t * lo) >> 16) + (t * hi);
69 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
70 *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
71
72 if (PA_UNLIKELY(++channel >= channels))
73 channel = 0;
74 }
75 }
76
77 static void
78 pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
79 {
80 unsigned channel;
81
82 for (channel = 0; length; length--) {
83 int32_t t, hi, lo;
84
85 hi = volumes[channel] >> 16;
86 lo = volumes[channel] & 0xFFFF;
87
88 t = (int32_t) st_ulaw2linear16(*samples);
89 t = ((t * lo) >> 16) + (t * hi);
90 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
91 *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
92
93 if (PA_UNLIKELY(++channel >= channels))
94 channel = 0;
95 }
96 }
97
98 static void
99 pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
100 {
101 unsigned channel;
102
103 length /= sizeof (int16_t);
104
105 for (channel = 0; length; length--) {
106 int32_t t, hi, lo;
107
108 /* Multiplying the 32bit volume factor with the 16bit
109 * sample might result in an 48bit value. We want to
110 * do without 64 bit integers and hence do the
111 * multiplication independantly for the HI and LO part
112 * of the volume. */
113
114 hi = volumes[channel] >> 16;
115 lo = volumes[channel] & 0xFFFF;
116
117 t = (int32_t)(*samples);
118 t = ((t * lo) >> 16) + (t * hi);
119 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
120 *samples++ = (int16_t) t;
121
122 if (PA_UNLIKELY(++channel >= channels))
123 channel = 0;
124 }
125 }
126
127 static void
128 pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
129 {
130 unsigned channel;
131
132 length /= sizeof (int16_t);
133
134 for (channel = 0; length; length--) {
135 int32_t t, hi, lo;
136
137 hi = volumes[channel] >> 16;
138 lo = volumes[channel] & 0xFFFF;
139
140 t = (int32_t) PA_INT16_SWAP(*samples);
141 t = ((t * lo) >> 16) + (t * hi);
142 t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
143 *samples++ = PA_INT16_SWAP((int16_t) t);
144
145 if (PA_UNLIKELY(++channel >= channels))
146 channel = 0;
147 }
148 }
149
150 static void
151 pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
152 {
153 unsigned channel;
154
155 length /= sizeof (float);
156
157 for (channel = 0; length; length--) {
158 *samples++ *= volumes[channel];
159
160 if (PA_UNLIKELY(++channel >= channels))
161 channel = 0;
162 }
163 }
164
165 static void
166 pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
167 {
168 unsigned channel;
169
170 length /= sizeof (float);
171
172 for (channel = 0; length; length--) {
173 float t;
174
175 t = PA_FLOAT32_SWAP(*samples);
176 t *= volumes[channel];
177 *samples++ = PA_FLOAT32_SWAP(t);
178
179 if (PA_UNLIKELY(++channel >= channels))
180 channel = 0;
181 }
182 }
183
184 static void
185 pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
186 {
187 unsigned channel;
188
189 length /= sizeof (int32_t);
190
191 for (channel = 0; length; length--) {
192 int64_t t;
193
194 t = (int64_t)(*samples);
195 t = (t * volumes[channel]) >> 16;
196 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
197 *samples++ = (int32_t) t;
198
199 if (PA_UNLIKELY(++channel >= channels))
200 channel = 0;
201 }
202 }
203
204 static void
205 pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
206 {
207 unsigned channel;
208
209 length /= sizeof (int32_t);
210
211 for (channel = 0; length; length--) {
212 int64_t t;
213
214 t = (int64_t) PA_INT32_SWAP(*samples);
215 t = (t * volumes[channel]) >> 16;
216 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
217 *samples++ = PA_INT32_SWAP((int32_t) t);
218
219 if (PA_UNLIKELY(++channel >= channels))
220 channel = 0;
221 }
222 }
223
224 static void
225 pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
226 {
227 unsigned channel;
228 uint8_t *e;
229
230 e = samples + length;
231
232 for (channel = 0; samples < e; samples += 3) {
233 int64_t t;
234
235 t = (int64_t)((int32_t) (PA_READ24NE(samples) << 8));
236 t = (t * volumes[channel]) >> 16;
237 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
238 PA_WRITE24NE(samples, ((uint32_t) (int32_t) t) >> 8);
239
240 if (PA_UNLIKELY(++channel >= channels))
241 channel = 0;
242 }
243 }
244
245 static void
246 pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
247 {
248 unsigned channel;
249 uint8_t *e;
250
251 e = samples + length;
252
253 for (channel = 0; samples < e; samples += 3) {
254 int64_t t;
255
256 t = (int64_t)((int32_t) (PA_READ24RE(samples) << 8));
257 t = (t * volumes[channel]) >> 16;
258 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
259 PA_WRITE24RE(samples, ((uint32_t) (int32_t) t) >> 8);
260
261 if (PA_UNLIKELY(++channel >= channels))
262 channel = 0;
263 }
264 }
265
266 static void
267 pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
268 {
269 unsigned channel;
270
271 length /= sizeof (uint32_t);
272
273 for (channel = 0; length; length--) {
274 int64_t t;
275
276 t = (int64_t) ((int32_t) (*samples << 8));
277 t = (t * volumes[channel]) >> 16;
278 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
279 *samples++ = ((uint32_t) ((int32_t) t)) >> 8;
280
281 if (PA_UNLIKELY(++channel >= channels))
282 channel = 0;
283 }
284 }
285
286 static void
287 pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
288 {
289 unsigned channel;
290
291 length /= sizeof (uint32_t);
292
293 for (channel = 0; length; length--) {
294 int64_t t;
295
296 t = (int64_t) ((int32_t) (PA_UINT32_SWAP(*samples) << 8));
297 t = (t * volumes[channel]) >> 16;
298 t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
299 *samples++ = PA_UINT32_SWAP(((uint32_t) ((int32_t) t)) >> 8);
300
301 if (PA_UNLIKELY(++channel >= channels))
302 channel = 0;
303 }
304 }
305
306 static pa_do_volume_func_t do_volume_table[] =
307 {
308 [PA_SAMPLE_U8] = (pa_do_volume_func_t) pa_volume_u8_c,
309 [PA_SAMPLE_ALAW] = (pa_do_volume_func_t) pa_volume_alaw_c,
310 [PA_SAMPLE_ULAW] = (pa_do_volume_func_t) pa_volume_ulaw_c,
311 [PA_SAMPLE_S16NE] = (pa_do_volume_func_t) pa_volume_s16ne_c,
312 [PA_SAMPLE_S16RE] = (pa_do_volume_func_t) pa_volume_s16re_c,
313 [PA_SAMPLE_FLOAT32NE] = (pa_do_volume_func_t) pa_volume_float32ne_c,
314 [PA_SAMPLE_FLOAT32RE] = (pa_do_volume_func_t) pa_volume_float32re_c,
315 [PA_SAMPLE_S32NE] = (pa_do_volume_func_t) pa_volume_s32ne_c,
316 [PA_SAMPLE_S32RE] = (pa_do_volume_func_t) pa_volume_s32re_c,
317 [PA_SAMPLE_S24NE] = (pa_do_volume_func_t) pa_volume_s24ne_c,
318 [PA_SAMPLE_S24RE] = (pa_do_volume_func_t) pa_volume_s24re_c,
319 [PA_SAMPLE_S24_32NE] = (pa_do_volume_func_t) pa_volume_s24_32ne_c,
320 [PA_SAMPLE_S24_32RE] = (pa_do_volume_func_t) pa_volume_s24_32re_c
321 };
322
323 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f) {
324 pa_assert(f >= 0);
325 pa_assert(f < PA_SAMPLE_MAX);
326
327 return do_volume_table[f];
328 }
329
330 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func) {
331 pa_assert(f >= 0);
332 pa_assert(f < PA_SAMPLE_MAX);
333
334 do_volume_table[f] = func;
335 }