comparison Plugins/Output/CoreAudio/convert.c @ 1637:5261e37b4d55 trunk

[svn] - fully working CoreAudio plugin, based on the OSS plugin and an incomplete xmms coreaudio plugin (fink)
author nenolod
date Thu, 07 Sep 2006 11:32:59 -0700
parents
children 365a2b043447
comparison
equal deleted inserted replaced
1636:09905c29250d 1637:5261e37b4d55
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 printf("1\n");
188
189 if ((output == FMT_U16_BE && input == FMT_U16_LE) ||
190 (output == FMT_U16_LE && input == FMT_U16_BE) ||
191 (output == FMT_S16_BE && input == FMT_S16_LE) ||
192 (output == FMT_S16_LE && input == FMT_S16_BE))
193 return convert_swap_endian;
194
195 printf("2\n");
196
197 if ((output == FMT_U16_BE && input == FMT_S16_BE) ||
198 (output == FMT_U16_LE && input == FMT_S16_LE) ||
199 (output == FMT_S16_BE && input == FMT_U16_BE) ||
200 (output == FMT_S16_LE && input == FMT_U16_LE))
201 return convert_swap_sign16;
202
203 printf("3\n");
204
205
206 if ((IS_BIG_ENDIAN &&
207 ((output == FMT_U16_BE && input == FMT_S16_LE) ||
208 (output == FMT_S16_BE && input == FMT_U16_LE))) ||
209 (!IS_BIG_ENDIAN &&
210 ((output == FMT_U16_LE && input == FMT_S16_BE) ||
211 (output == FMT_S16_LE && input == FMT_U16_BE))))
212 return convert_swap_sign_and_endian_to_native;
213
214 printf("4\n");
215
216 if ((!IS_BIG_ENDIAN &&
217 ((output == FMT_U16_BE && input == FMT_S16_LE) ||
218 (output == FMT_S16_BE && input == FMT_U16_LE))) ||
219 (IS_BIG_ENDIAN &&
220 ((output == FMT_U16_LE && input == FMT_S16_BE) ||
221 (output == FMT_S16_LE && input == FMT_U16_BE))))
222 return convert_swap_sign_and_endian_to_alien;
223
224 printf("5\n");
225
226 if ((IS_BIG_ENDIAN &&
227 ((output == FMT_U8 && input == FMT_U16_BE) ||
228 (output == FMT_S8 && input == FMT_S16_BE))) ||
229 (!IS_BIG_ENDIAN &&
230 ((output == FMT_U8 && input == FMT_U16_LE) ||
231 (output == FMT_S8 && input == FMT_S16_LE))))
232 return convert_to_8_native_endian;
233
234 printf("6\n");
235
236 if ((IS_BIG_ENDIAN &&
237 ((output == FMT_U8 && input == FMT_S16_BE) ||
238 (output == FMT_S8 && input == FMT_U16_BE))) ||
239 (!IS_BIG_ENDIAN &&
240 ((output == FMT_U8 && input == FMT_S16_LE) ||
241 (output == FMT_S8 && input == FMT_U16_LE))))
242 return convert_to_8_native_endian_swap_sign;
243
244 printf("7\n");
245
246 if ((!IS_BIG_ENDIAN &&
247 ((output == FMT_U8 && input == FMT_U16_BE) ||
248 (output == FMT_S8 && input == FMT_S16_BE))) ||
249 (IS_BIG_ENDIAN &&
250 ((output == FMT_U8 && input == FMT_U16_LE) ||
251 (output == FMT_S8 && input == FMT_S16_LE))))
252 return convert_to_8_alien_endian;
253
254 printf("8\n");
255
256 if ((!IS_BIG_ENDIAN &&
257 ((output == FMT_U8 && input == FMT_S16_BE) ||
258 (output == FMT_S8 && input == FMT_U16_BE))) ||
259 (IS_BIG_ENDIAN &&
260 ((output == FMT_U8 && input == FMT_S16_LE) ||
261 (output == FMT_S8 && input == FMT_U16_LE))))
262 return convert_to_8_alien_endian_swap_sign;
263
264 printf("9\n");
265
266 if ((output == FMT_U8 && input == FMT_S8) ||
267 (output == FMT_S8 && input == FMT_U8))
268 return convert_swap_sign8;
269
270 printf("10\n");
271
272 if ((IS_BIG_ENDIAN &&
273 ((output == FMT_U16_BE && input == FMT_U8) ||
274 (output == FMT_S16_BE && input == FMT_S8))) ||
275 (!IS_BIG_ENDIAN &&
276 ((output == FMT_U16_LE && input == FMT_U8) ||
277 (output == FMT_S16_LE && input == FMT_S8))))
278 return convert_to_16_native_endian;
279
280 printf("11\n");
281
282 if ((IS_BIG_ENDIAN &&
283 ((output == FMT_U16_BE && input == FMT_S8) ||
284 (output == FMT_S16_BE && input == FMT_U8))) ||
285 (!IS_BIG_ENDIAN &&
286 ((output == FMT_U16_LE && input == FMT_S8) ||
287 (output == FMT_S16_LE && input == FMT_U8))))
288 return convert_to_16_native_endian_swap_sign;
289
290 printf("12\n");
291
292 if ((!IS_BIG_ENDIAN &&
293 ((output == FMT_U16_BE && input == FMT_U8) ||
294 (output == FMT_S16_BE && input == FMT_S8))) ||
295 (IS_BIG_ENDIAN &&
296 ((output == FMT_U16_LE && input == FMT_U8) ||
297 (output == FMT_S16_LE && input == FMT_S8))))
298 return convert_to_16_alien_endian;
299
300 printf("14\n");
301
302 if ((!IS_BIG_ENDIAN &&
303 ((output == FMT_U16_BE && input == FMT_S8) ||
304 (output == FMT_S16_BE && input == FMT_U8))) ||
305 (IS_BIG_ENDIAN &&
306 ((output == FMT_U16_LE && input == FMT_S8) ||
307 (output == FMT_S16_LE && input == FMT_U8))))
308 return convert_to_16_alien_endian_swap_sign;
309
310 g_warning("Translation needed, but not available.\n"
311 "Input: %d; Output %d.", input, output);
312 return NULL;
313 }