]> code.delx.au - pulseaudio/blob - src/pulsecore/sconv-s16le.c
use PA_FLOAT32_SWAP where useful
[pulseaudio] / src / pulsecore / sconv-s16le.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 /* Despite the name of this file we implement S32 handling here, too. */
27
28 #include <inttypes.h>
29 #include <stdio.h>
30
31 #include <liboil/liboilfuncs.h>
32
33 #include <pulsecore/sconv.h>
34 #include <pulsecore/macro.h>
35 #include <pulsecore/log.h>
36
37 #include "endianmacros.h"
38
39 #include "sconv-s16le.h"
40
41 #ifndef INT16_FROM
42 #define INT16_FROM PA_INT16_FROM_LE
43 #endif
44
45 #ifndef INT16_TO
46 #define INT16_TO PA_INT16_TO_LE
47 #endif
48
49 #ifndef INT32_FROM
50 #define INT32_FROM PA_INT32_FROM_LE
51 #endif
52
53 #ifndef INT32_TO
54 #define INT32_TO PA_INT32_TO_LE
55 #endif
56
57 #ifndef SWAP_WORDS
58 #ifdef WORDS_BIGENDIAN
59 #define SWAP_WORDS 1
60 #else
61 #define SWAP_WORDS 0
62 #endif
63 #endif
64
65 void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
66 pa_assert(a);
67 pa_assert(b);
68
69 #if SWAP_WORDS == 1
70
71 for (; n > 0; n--) {
72 int16_t s = *(a++);
73 *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
74 }
75
76 #else
77 {
78 static const double add = 0, factor = 1.0/0x7FFF;
79 oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor);
80 }
81 #endif
82 }
83
84 void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
85 pa_assert(a);
86 pa_assert(b);
87
88 #if SWAP_WORDS == 1
89
90 for (; n > 0; n--) {
91 int32_t s = *(a++);
92 *(b++) = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
93 }
94
95 #else
96 {
97 static const double add = 0, factor = 1.0/0x7FFFFFFF;
98 oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor);
99 }
100 #endif
101 }
102
103 void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
104 pa_assert(a);
105 pa_assert(b);
106
107 #if SWAP_WORDS == 1
108
109 for (; n > 0; n--) {
110 int16_t s;
111 float v = *(a++);
112
113 v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
114 s = (int16_t) (v * 0x7FFF);
115 *(b++) = INT16_TO(s);
116 }
117
118 #else
119 {
120 static const double add = 0, factor = 0x7FFF;
121 oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor);
122 }
123 #endif
124 }
125
126 void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
127 pa_assert(a);
128 pa_assert(b);
129
130 #if SWAP_WORDS == 1
131
132 for (; n > 0; n--) {
133 int32_t s;
134 float v = *(a++);
135
136 v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
137 s = (int32_t) ((double) v * (double) 0x7FFFFFFF);
138 *(b++) = INT32_TO(s);
139 }
140
141 #else
142 {
143 static const double add = 0, factor = 0x7FFFFFFF;
144 oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor);
145 }
146 #endif
147 }
148
149 void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
150 pa_assert(a);
151 pa_assert(b);
152
153 for (; n > 0; n--) {
154 int16_t s = *(a++);
155 float k = ((float) INT16_FROM(s))/0x7FFF;
156 k = PA_FLOAT32_SWAP(k);
157 *(b++) = k;
158 }
159 }
160
161 void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
162 pa_assert(a);
163 pa_assert(b);
164
165 for (; n > 0; n--) {
166 int32_t s = *(a++);
167 float k = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
168 k = PA_FLOAT32_SWAP(k);
169 *(b++) = k;
170 }
171 }
172
173 void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
174 pa_assert(a);
175 pa_assert(b);
176
177 for (; n > 0; n--) {
178 int16_t s;
179 float v = *(a++);
180 v = PA_FLOAT32_SWAP(v);
181 v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
182 s = (int16_t) (v * 0x7FFF);
183 *(b++) = INT16_TO(s);
184 }
185 }
186
187 void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
188 pa_assert(a);
189 pa_assert(b);
190
191 for (; n > 0; n--) {
192 int32_t s;
193 float v = *(a++);
194 v = PA_FLOAT32_SWAP(v);
195 v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
196 s = (int32_t) ((double) v * 0x7FFFFFFF);
197 *(b++) = INT32_TO(s);
198 }
199 }
200
201 void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) {
202 pa_assert(a);
203 pa_assert(b);
204
205 for (; n > 0; n--) {
206 *b = (int16_t) (INT32_FROM(*a) >> 16);
207 a++;
208 b++;
209 }
210 }
211
212 void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {
213 pa_assert(a);
214 pa_assert(b);
215
216 for (; n > 0; n--) {
217 int16_t s = (int16_t) (INT32_FROM(*a) >> 16);
218 *b = PA_INT16_SWAP(s);
219 a++;
220 b++;
221 }
222 }
223
224 void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) {
225 pa_assert(a);
226 pa_assert(b);
227
228 for (; n > 0; n--) {
229 *b = INT32_TO(((int32_t) *a) << 16);
230 a++;
231 b++;
232 }
233 }
234
235 void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {
236 pa_assert(a);
237 pa_assert(b);
238
239 for (; n > 0; n--) {
240 int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;
241 *b = INT32_TO(s);
242 a++;
243 b++;
244 }
245 }