comparison src/CoreAudio/convert.c @ 12:3da1b8942b8b trunk

[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author nenolod
date Mon, 18 Sep 2006 03:14:20 -0700
parents src/Output/CoreAudio/convert.c@13389e613d67
children f1b6f1b2cdb3
comparison
equal deleted inserted replaced
11:cff1d04026ae 12:3da1b8942b8b
1 /*
2 * Copyright (C) 2001 Haavard Kvaalen
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "coreaudio.h"
20
21 void* osx_get_convert_buffer(size_t size)
22 {
23 static size_t length;
24 static void *buffer;
25
26 if (size > 0 && size <= length)
27 return buffer;
28
29 length = size;
30 buffer = g_realloc(buffer, size);
31 return buffer;
32 }
33
34 static int convert_swap_endian(void **data, int length)
35 {
36 guint16 *ptr = *data;
37 int i;
38 for (i = 0; i < length; i += 2, ptr++)
39 *ptr = GUINT16_SWAP_LE_BE(*ptr);
40
41 return i;
42 }
43
44 static int convert_swap_sign_and_endian_to_native(void **data, int length)
45 {
46 guint16 *ptr = *data;
47 int i;
48 for (i = 0; i < length; i += 2, ptr++)
49 *ptr = GUINT16_SWAP_LE_BE(*ptr) ^ 1 << 15;
50
51 return i;
52 }
53
54 static int convert_swap_sign_and_endian_to_alien(void **data, int length)
55 {
56 guint16 *ptr = *data;
57 int i;
58 for (i = 0; i < length; i += 2, ptr++)
59 *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15);
60
61 return i;
62 }
63
64 static int convert_swap_sign16(void **data, int length)
65 {
66 gint16 *ptr = *data;
67 int i;
68 for (i = 0; i < length; i += 2, ptr++)
69 *ptr ^= 1 << 15;
70
71 return i;
72 }
73
74 static int convert_swap_sign8(void **data, int length)
75 {
76 gint8 *ptr = *data;
77 int i;
78 for (i = 0; i < length; i++)
79 *ptr++ ^= 1 << 7;
80
81 return i;
82 }
83
84 static int convert_to_8_native_endian(void **data, int length)
85 {
86 gint8 *output = *data;
87 gint16 *input = *data;
88 int i;
89 for (i = 0; i < length / 2; i++)
90 *output++ = *input++ >> 8;
91
92 return i;
93 }
94
95 static int convert_to_8_native_endian_swap_sign(void **data, int length)
96 {
97 gint8 *output = *data;
98 gint16 *input = *data;
99 int i;
100 for (i = 0; i < length / 2; i++)
101 *output++ = (*input++ >> 8) ^ (1 << 7);
102
103 return i;
104 }
105
106
107 static int convert_to_8_alien_endian(void **data, int length)
108 {
109 gint8 *output = *data;
110 gint16 *input = *data;
111 int i;
112 for (i = 0; i < length / 2; i++)
113 *output++ = *input++ & 0xff;
114
115 return i;
116 }
117
118 static int convert_to_8_alien_endian_swap_sign(void **data, int length)
119 {
120 gint8 *output = *data;
121 gint16 *input = *data;
122 int i;
123 for (i = 0; i < length / 2; i++)
124 *output++ = (*input++ & 0xff) ^ (1 << 7);
125
126 return i;
127 }
128
129 static int convert_to_16_native_endian(void **data, int length)
130 {
131 guint8 *input = *data;
132 guint16 *output;
133 int i;
134 *data = osx_get_convert_buffer(length * 2);
135 output = *data;
136 for (i = 0; i < length; i++)
137 *output++ = *input++ << 8;
138
139 return i * 2;
140 }
141
142 static int convert_to_16_native_endian_swap_sign(void **data, int length)
143 {
144 guint8 *input = *data;
145 guint16 *output;
146 int i;
147 *data = osx_get_convert_buffer(length * 2);
148 output = *data;
149 for (i = 0; i < length; i++)
150 *output++ = (*input++ << 8) ^ (1 << 15);
151
152 return i * 2;
153 }
154
155
156 static int convert_to_16_alien_endian(void **data, int length)
157 {
158 guint8 *input = *data;
159 guint16 *output;
160 int i;
161 *data = osx_get_convert_buffer(length * 2);
162 output = *data;
163 for (i = 0; i < length; i++)
164 *output++ = *input++;
165
166 return i * 2;
167 }
168
169 static int convert_to_16_alien_endian_swap_sign(void **data, int length)
170 {
171 guint8 *input = *data;
172 guint16 *output;
173 int i;
174 *data = osx_get_convert_buffer(length * 2);
175 output = *data;
176 for (i = 0; i < length; i++)
177 *output++ = *input++ ^ (1 << 7);
178
179 return i * 2;
180 }
181
182 int (*osx_get_convert_func(int output, int input))(void **, int)
183 {
184 if (output == input)
185 return NULL;
186
187 if ((output == FMT_U16_BE && input == FMT_U16_LE) ||
188 (output == FMT_U16_LE && input == FMT_U16_BE) ||
189 (output == FMT_S16_BE && input == FMT_S16_LE) ||
190 (output == FMT_S16_LE && input == FMT_S16_BE))
191 return convert_swap_endian;
192
193 if ((output == FMT_U16_BE && input == FMT_S16_BE) ||
194 (output == FMT_U16_LE && input == FMT_S16_LE) ||
195 (output == FMT_S16_BE && input == FMT_U16_BE) ||
196 (output == FMT_S16_LE && input == FMT_U16_LE))
197 return convert_swap_sign16;
198
199 if ((IS_BIG_ENDIAN &&
200 ((output == FMT_U16_BE && input == FMT_S16_LE) ||
201 (output == FMT_S16_BE && input == FMT_U16_LE))) ||
202 (!IS_BIG_ENDIAN &&
203 ((output == FMT_U16_LE && input == FMT_S16_BE) ||
204 (output == FMT_S16_LE && input == FMT_U16_BE))))
205 return convert_swap_sign_and_endian_to_native;
206
207 if ((!IS_BIG_ENDIAN &&
208 ((output == FMT_U16_BE && input == FMT_S16_LE) ||
209 (output == FMT_S16_BE && input == FMT_U16_LE))) ||
210 (IS_BIG_ENDIAN &&
211 ((output == FMT_U16_LE && input == FMT_S16_BE) ||
212 (output == FMT_S16_LE && input == FMT_U16_BE))))
213 return convert_swap_sign_and_endian_to_alien;
214
215 if ((IS_BIG_ENDIAN &&
216 ((output == FMT_U8 && input == FMT_U16_BE) ||
217 (output == FMT_S8 && input == FMT_S16_BE))) ||
218 (!IS_BIG_ENDIAN &&
219 ((output == FMT_U8 && input == FMT_U16_LE) ||
220 (output == FMT_S8 && input == FMT_S16_LE))))
221 return convert_to_8_native_endian;
222
223 if ((IS_BIG_ENDIAN &&
224 ((output == FMT_U8 && input == FMT_S16_BE) ||
225 (output == FMT_S8 && input == FMT_U16_BE))) ||
226 (!IS_BIG_ENDIAN &&
227 ((output == FMT_U8 && input == FMT_S16_LE) ||
228 (output == FMT_S8 && input == FMT_U16_LE))))
229 return convert_to_8_native_endian_swap_sign;
230
231 if ((!IS_BIG_ENDIAN &&
232 ((output == FMT_U8 && input == FMT_U16_BE) ||
233 (output == FMT_S8 && input == FMT_S16_BE))) ||
234 (IS_BIG_ENDIAN &&
235 ((output == FMT_U8 && input == FMT_U16_LE) ||
236 (output == FMT_S8 && input == FMT_S16_LE))))
237 return convert_to_8_alien_endian;
238
239 if ((!IS_BIG_ENDIAN &&
240 ((output == FMT_U8 && input == FMT_S16_BE) ||
241 (output == FMT_S8 && input == FMT_U16_BE))) ||
242 (IS_BIG_ENDIAN &&
243 ((output == FMT_U8 && input == FMT_S16_LE) ||
244 (output == FMT_S8 && input == FMT_U16_LE))))
245 return convert_to_8_alien_endian_swap_sign;
246
247 if ((output == FMT_U8 && input == FMT_S8) ||
248 (output == FMT_S8 && input == FMT_U8))
249 return convert_swap_sign8;
250
251 if ((IS_BIG_ENDIAN &&
252 ((output == FMT_U16_BE && input == FMT_U8) ||
253 (output == FMT_S16_BE && input == FMT_S8))) ||
254 (!IS_BIG_ENDIAN &&
255 ((output == FMT_U16_LE && input == FMT_U8) ||
256 (output == FMT_S16_LE && input == FMT_S8))))
257 return convert_to_16_native_endian;
258
259 if ((IS_BIG_ENDIAN &&
260 ((output == FMT_U16_BE && input == FMT_S8) ||
261 (output == FMT_S16_BE && input == FMT_U8))) ||
262 (!IS_BIG_ENDIAN &&
263 ((output == FMT_U16_LE && input == FMT_S8) ||
264 (output == FMT_S16_LE && input == FMT_U8))))
265 return convert_to_16_native_endian_swap_sign;
266
267 if ((!IS_BIG_ENDIAN &&
268 ((output == FMT_U16_BE && input == FMT_U8) ||
269 (output == FMT_S16_BE && input == FMT_S8))) ||
270 (IS_BIG_ENDIAN &&
271 ((output == FMT_U16_LE && input == FMT_U8) ||
272 (output == FMT_S16_LE && input == FMT_S8))))
273 return convert_to_16_alien_endian;
274
275 if ((!IS_BIG_ENDIAN &&
276 ((output == FMT_U16_BE && input == FMT_S8) ||
277 (output == FMT_S16_BE && input == FMT_U8))) ||
278 (IS_BIG_ENDIAN &&
279 ((output == FMT_U16_LE && input == FMT_S8) ||
280 (output == FMT_S16_LE && input == FMT_U8))))
281 return convert_to_16_alien_endian_swap_sign;
282
283 g_warning("Translation needed, but not available.\n"
284 "Input: %d; Output %d.", input, output);
285 return NULL;
286 }