Mercurial > audlegacy-plugins
diff src/Output/sun/convert.c @ 0:13389e613d67 trunk
[svn] - initial import of audacious-plugins tree (lots to do)
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 01:11:49 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Output/sun/convert.c Mon Sep 18 01:11:49 2006 -0700 @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2001 Haavard Kvaalen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sun.h" + +void * sun_get_convert_buffer(size_t size) +{ + static size_t length; + static void *buffer; + + if (size > 0 && size <= length) + return buffer; + + length = size; + buffer = g_realloc(buffer, size); + return buffer; +} + +static int convert_swap_endian(void **data, int length) +{ + int i; + guint16 *ptr = *data; + + for (i = 0; i < length; i += 2, ptr++) + *ptr = GUINT16_SWAP_LE_BE(*ptr); + + return i; +} + +static int convert_swap_sign_and_endian_to_native(void **data, int length) +{ + int i; + guint16 *ptr = *data; + + for (i = 0; i < length; i += 2, ptr++) + *ptr = GUINT16_SWAP_LE_BE(*ptr) ^ 1 << 15; + + return (i); +} + +static int convert_swap_sign_and_endian_to_alien(void **data, int length) +{ + int i; + guint16 *ptr = *data; + + for (i = 0; i < length; i += 2, ptr++) + *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15); + + return i; +} + +static int convert_swap_sign16(void **data, int length) +{ + int i; + gint16 *ptr = *data; + + for (i = 0; i < length; i += 2, ptr++) + *ptr ^= 1 << 15; + + return i; +} + +static int convert_swap_sign8(void **data, int length) +{ + int i; + gint8 *ptr = *data; + + for (i = 0; i < length; i++) + *ptr++ ^= 1 << 7; + + return i; +} + +static int convert_to_8_native_endian(void **data, int length) +{ + int i; + gint16 *input = *data; + gint8 *output = *data; + + for (i = 0; i < length / 2; i++) + *output++ = *input++ >> 8; + + return i; +} + +static int convert_to_8_native_endian_swap_sign(void **data, int length) +{ + int i; + gint16 *input = *data; + gint8 *output = *data; + + for (i = 0; i < length / 2; i++) + *output++ = (*input++ >> 8) ^ (1 << 7); + + return i; +} + + +static int convert_to_8_alien_endian(void **data, int length) +{ + int i; + gint16 *input = *data; + gint8 *output = *data; + + for (i = 0; i < length / 2; i++) + *output++ = *input++ & 0xff; + + return i; +} + +static int convert_to_8_alien_endian_swap_sign(void **data, int length) +{ + int i; + gint16 *input = *data; + gint8 *output = *data; + + for (i = 0; i < length / 2; i++) + *output++ = (*input++ & 0xff) ^ (1 << 7); + + return i; +} + +static int convert_to_16_native_endian(void **data, int length) +{ + int i; + guint16 *output; + guint8 *input = *data; + + *data = sun_get_convert_buffer(length * 2); + output = *data; + + for (i = 0; i < length; i++) + *output++ = *input++ << 8; + + return (i * 2); +} + +static int convert_to_16_native_endian_swap_sign(void **data, int length) +{ + int i; + guint16 *output; + guint8 *input = *data; + + *data = sun_get_convert_buffer(length * 2); + output = *data; + for (i = 0; i < length; i++) + *output++ = (*input++ << 8) ^ (1 << 15); + + return (i * 2); +} + + +static int convert_to_16_alien_endian(void **data, int length) +{ + int i; + guint16 *output; + guint8 *input = *data; + + *data = sun_get_convert_buffer(length * 2); + output = *data; + for (i = 0; i < length; i++) + *output++ = *input++; + + return (i * 2); +} + +static int convert_to_16_alien_endian_swap_sign(void **data, int length) +{ + int i; + guint16 *output; + guint8 *input = *data; + + *data = sun_get_convert_buffer(length * 2); + output = *data; + for (i = 0; i < length; i++) + *output++ = *input++ ^ (1 << 7); + + return (i * 2); +} + +int (*sun_get_convert_func(int output, int input))(void **, int) +{ + if (output == input) + return NULL; + + if ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_ULINEAR_LE) || + (output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_ULINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_SLINEAR_BE)) + return convert_swap_endian; + + if ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_SLINEAR_BE) || + (output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_ULINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_ULINEAR_LE)) + return convert_swap_sign16; + + if ((IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_ULINEAR_LE))) || + (!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_SLINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_ULINEAR_BE)))) + return convert_swap_sign_and_endian_to_native; + + if ((!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_ULINEAR_LE))) || + (IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_SLINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_ULINEAR_BE)))) + return convert_swap_sign_and_endian_to_alien; + + if ((IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_ULINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_SLINEAR_BE))) || + (!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_ULINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_SLINEAR_LE)))) + return convert_to_8_native_endian; + + if ((IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_SLINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_ULINEAR_BE))) || + (!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_ULINEAR_LE)))) + return convert_to_8_native_endian_swap_sign; + + if ((!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_ULINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_SLINEAR_BE))) || + (IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_ULINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_SLINEAR_LE)))) + return convert_to_8_alien_endian; + + if ((!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_SLINEAR_BE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_ULINEAR_BE))) || + (IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_SLINEAR_LE) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_ULINEAR_LE)))) + return convert_to_8_alien_endian_swap_sign; + + if ((output == AUDIO_ENCODING_PCM8 && + input == AUDIO_ENCODING_SLINEAR) || + (output == AUDIO_ENCODING_SLINEAR && + input == AUDIO_ENCODING_PCM8)) + return convert_swap_sign8; + + if ((IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_PCM8) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_SLINEAR))) || + (!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_PCM8) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_SLINEAR)))) + return convert_to_16_native_endian; + + if ((IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_SLINEAR) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_PCM8))) || + (!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_SLINEAR) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_PCM8)))) + return convert_to_16_native_endian_swap_sign; + + if ((!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_PCM8) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_SLINEAR))) || + (IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_PCM8) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_SLINEAR)))) + return convert_to_16_alien_endian; + + if ((!IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_BE && + input == AUDIO_ENCODING_SLINEAR) || + (output == AUDIO_ENCODING_SLINEAR_BE && + input == AUDIO_ENCODING_PCM8))) || + (IS_BIG_ENDIAN && + ((output == AUDIO_ENCODING_ULINEAR_LE && + input == AUDIO_ENCODING_SLINEAR) || + (output == AUDIO_ENCODING_SLINEAR_LE && + input == AUDIO_ENCODING_PCM8)))) + return convert_to_16_alien_endian_swap_sign; + + return NULL; +}