changeset 2431:3ec22a11c83e trunk

[svn] - moved titlestring.* and xconvert.* from libaudacious to audacious
author mf0102
date Sat, 27 Jan 2007 12:10:21 -0800
parents 4e2fc64d95ef
children 4a1d1c324685
files ChangeLog src/audacious/Makefile src/audacious/titlestring.c src/audacious/titlestring.h src/audacious/xconvert.c src/audacious/xconvert.h src/libaudacious/Makefile src/libaudacious/titlestring.c src/libaudacious/titlestring.h src/libaudacious/xconvert.c src/libaudacious/xconvert.h
diffstat 11 files changed, 1407 insertions(+), 1481 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jan 27 11:40:05 2007 -0800
+++ b/ChangeLog	Sat Jan 27 12:10:21 2007 -0800
@@ -1,3 +1,14 @@
+2007-01-27 19:40:05 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
+  revision [3870]
+  - make vfs_buffered_file_new_from_uri declaration const
+  - cope properly with subsong URIs
+  
+  trunk/src/audacious/input.c             |   14 ++++++++++++--
+  trunk/src/audacious/vfs_buffered_file.c |    2 +-
+  trunk/src/audacious/vfs_buffered_file.h |    2 +-
+  3 files changed, 14 insertions(+), 4 deletions(-)
+
+
 2007-01-27 19:28:14 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
   revision [3868]
   - fix an offset error in the vfs_buffered_file wraparound implementation sections
--- a/src/audacious/Makefile	Sat Jan 27 11:40:05 2007 -0800
+++ b/src/audacious/Makefile	Sat Jan 27 12:10:21 2007 -0800
@@ -42,8 +42,10 @@
 	ui_preferences.h \
 	util.h \
 	strings.h \
+	titlestring.h \
 	vfs.h \
-	vfs_buffer.h
+	vfs_buffer.h \
+	xconvert.h
 
 SOURCES = \
 	build_stamp.c \
@@ -74,6 +76,7 @@
 	pluginenum.c \
 	signals.c \
 	strings.c \
+	titlestring.c \
 	ui_about.c \
 	ui_credits.c \
 	ui_equalizer.c \
@@ -92,7 +95,8 @@
 	vfs_buffered_file.c \
 	vfs.c \
 	vfs_common.c \
-	visualization.c
+	visualization.c \
+	xconvert.c
 
 OBJECTS = ${SOURCES:.c=.o}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/titlestring.c	Sat Jan 27 12:10:21 2007 -0800
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2001,  Espen Skoglund <esk@ira.uka.de>
+ * Copyright (C) 2001,  Haavard Kvaalen <havardk@xmms.org>
+ *
+ * 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#define GETTEXT_PACKAGE PACKAGE_NAME
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "titlestring.h"
+
+#define CHECK(input, field) \
+	(((gchar *) &input->field - (gchar *) input) < input->__size)
+
+#define VS(input, field) (CHECK(input, field) ? input->field : NULL)
+#define VI(input, field) (CHECK(input, field) ? input->field : 0)
+
+/**
+ * bmp_title_input_new:
+ *
+ * #BmpTitleInput tuple factory.
+ *
+ * Return value: A #BmpTitleInput object.
+ **/
+BmpTitleInput *
+bmp_title_input_new()
+{
+    BmpTitleInput *input;
+    input = g_new0(BmpTitleInput, 1);
+    input->__size = XMMS_TITLEINPUT_SIZE;
+    input->__version = XMMS_TITLEINPUT_VERSION;
+    return input;
+}
+
+/**
+ * bmp_title_input_free:
+ * @input: A #BmpTitleInput tuple to destroy.
+ *
+ * Destroys a #BmpTitleInput tuple.
+ **/
+void
+bmp_title_input_free(BmpTitleInput * input)
+{
+    if (input == NULL)
+        return;
+
+    if (input->performer != NULL)
+        g_free(input->performer);
+
+    if (input->album_name != NULL)
+        g_free(input->album_name);
+
+    if (input->track_name != NULL)
+        g_free(input->track_name);
+
+    if (input->date != NULL)
+        g_free(input->date);
+
+    if (input->genre != NULL)
+        g_free(input->genre);
+
+    if (input->comment != NULL)
+        g_free(input->comment);
+
+    if (input->file_name != NULL)
+        g_free(input->file_name);
+
+    if (input->file_path != NULL)
+        g_free(input->file_path);
+
+    g_free(input);
+}
+
+/**
+ * xmms_get_titlestring:
+ * @fmt: A format string.
+ * @input: A tuple to use for data.
+ *
+ * Generates a formatted string from a tuple.
+ *
+ * Return value: A formatted tuple string.
+ **/
+gchar *
+xmms_get_titlestring(const gchar * fmt, TitleInput * input)
+{
+    GString *outstr;
+    const gchar *string;
+    gchar c, convert[16];
+    gint numdigits, numpr, val, i;
+    gint f_left, f_space, f_zero, someflag, width, precision;
+    gboolean did_output = FALSE;
+    gchar digits[] = "0123456789";
+
+#define PUTCH(ch) g_string_append_c(outstr, ch)
+
+#define LEFTPAD(num)                            \
+    G_STMT_START {                              \
+        gint cnt = (num);                       \
+        if ( ! f_left && cnt > 0 )              \
+            while ( cnt-- > 0 )                 \
+                PUTCH(f_zero ? '0' : ' ');      \
+    } G_STMT_END;
+
+#define RIGHTPAD(num)                           \
+    G_STMT_START {                              \
+        gint cnt = (num);                       \
+        if ( f_left && cnt > 0 )                \
+            while ( cnt-- > 0 )                 \
+                PUTCH( ' ' );                   \
+    } G_STMT_END;
+
+    if (fmt == NULL || input == NULL)
+        return NULL;
+    outstr = g_string_new("");
+
+    for (;;) {
+        /* Copy characters until we encounter '%'. */
+        while ((c = *fmt++) != '%') {
+            if (c == '\0')
+                goto Done;
+            g_string_append_c(outstr, c);
+        }
+
+        f_left = f_space = f_zero = 0;
+        someflag = 1;
+
+
+        /* Parse flags. */
+        while (someflag) {
+            switch (*fmt) {
+            case '-':
+                f_left = 1;
+                fmt++;
+                break;
+            case ' ':
+                f_space = 1;
+                fmt++;
+                break;
+            case '0':
+                f_zero = 1;
+                fmt++;
+                break;
+            default:
+                someflag = 0;
+                break;
+            }
+        }
+
+
+        /* Parse field width. */
+        if ((c = *fmt) >= '0' && c <= '9') {
+            width = 0;
+            while ((c = *fmt++) >= '0' && c <= '9') {
+                width *= 10;
+                width += c - '0';
+            }
+            fmt--;
+        }
+        else
+            width = -1;
+
+
+        /* Parse precision. */
+        if (*fmt == '.') {
+            if ((c = *++fmt) >= '0' && c <= '9') {
+                precision = 0;
+                while ((c = *fmt++) >= '0' && c <= '9') {
+                    precision *= 10;
+                    precision += c - '0';
+                }
+                fmt--;
+            }
+            else
+                precision = -1;
+        }
+        else
+            precision = -1;
+
+
+        /* Parse format conversion. */
+        switch (c = *fmt++) {
+        case '}':              /* close optional, just ignore */
+            continue;
+
+        case '{':{             /* optional entry: %{n:...%} */
+                char n = *fmt++;
+                if (!((n == 'a' && VS(input, album_name)) ||
+                      (n == 'c' && VS(input, comment)) ||
+                      (n == 'd' && VS(input, date)) ||
+                      (n == 'e' && VS(input, file_ext)) ||
+                      (n == 'f' && VS(input, file_name)) ||
+                      (n == 'F' && VS(input, file_path)) ||
+                      (n == 'g' && VS(input, genre)) ||
+                      (n == 'n' && VI(input, track_number)) ||
+                      (n == 'p' && VS(input, performer)) ||
+                      (n == 't' && VS(input, track_name)) ||
+                      (n == 'y' && VI(input, year)))) {
+                    int nl = 0;
+                    char c;
+                    while ((c = *fmt++))    /* until end of string      */
+                        if (c == '}')   /* if end of opt            */
+                            if (!nl)
+                                break;  /* if outmost indent level  */
+                            else
+                                --nl;   /* else reduce indent       */
+                        else if (c == '{')
+                            ++nl;   /* increase indent          */
+                }
+                else
+                    ++fmt;
+                break;
+            }
+
+        case 'a':
+            string = VS(input, album_name);
+            goto Print_string;
+        case 'c':
+            string = VS(input, comment);
+            goto Print_string;
+        case 'd':
+            string = VS(input, date);
+            goto Print_string;
+        case 'e':
+            string = VS(input, file_ext);
+            goto Print_string;
+        case 'f':
+            string = VS(input, file_name);
+            goto Print_string;
+        case 'F':
+            string = VS(input, file_path);
+            goto Print_string;
+        case 'g':
+            string = VS(input, genre);
+            goto Print_string;
+        case 'n':
+            val = VI(input, track_number);
+            goto Print_number;
+        case 'p':
+            string = VS(input, performer);
+            goto Print_string;
+        case 't':
+            string = VS(input, track_name);
+	    goto Print_string;
+        case 'y':
+            val = VI(input, year);
+	    goto Print_number;
+
+          Print_string:
+            if (string == NULL)
+                break;
+            did_output = TRUE;
+
+            numpr = 0;
+            if (width > 0) {
+                /* Calculate printed size. */
+                numpr = strlen(string);
+                if (precision >= 0 && precision < numpr)
+                    numpr = precision;
+
+                LEFTPAD(width - numpr);
+            }
+
+            /* Insert string. */
+            if (precision >= 0) {
+                glong offset_max = precision, offset;
+                gchar *uptr = NULL;
+                const gchar *tmpstring = string;
+                while (precision > 0) {
+                    offset = offset_max - precision;
+                    uptr = g_utf8_offset_to_pointer(tmpstring, offset);
+                    if (*uptr == '\0')
+                        break;
+                    g_string_append_unichar(outstr, g_utf8_get_char(uptr));
+                    precision--;
+                }
+            }
+            else {
+                while ((c = *string++) != '\0')
+                    PUTCH(c);
+            }
+
+            RIGHTPAD(width - numpr);
+            break;
+
+          Print_number:
+            if (val == 0)
+                break;
+            if (c != 'N')
+                did_output = TRUE;
+
+            /* Create reversed number string. */
+            numdigits = 0;
+            do {
+                convert[numdigits++] = digits[val % 10];
+                val /= 10;
+            }
+            while (val > 0);
+
+            numpr = numdigits > precision ? numdigits : precision;
+
+            /* Insert left padding. */
+            if (!f_left && width > numpr) {
+                if (f_zero)
+                    numpr = width;
+                else
+                    for (i = width - numpr; i-- > 0;)
+                        PUTCH(' ');
+            }
+
+            /* Insert zero padding. */
+            for (i = numpr - numdigits; i-- > 0;)
+                PUTCH('0');
+
+            /* Insert number. */
+            while (numdigits > 0)
+                PUTCH(convert[--numdigits]);
+
+            RIGHTPAD(width - numpr);
+            break;
+
+        case '%':
+            PUTCH('%');
+            break;
+
+        default:
+            PUTCH('%');
+            PUTCH(c);
+            break;
+        }
+    }
+
+  Done:
+    if (did_output)
+        return g_string_free(outstr, FALSE);
+    else
+        return NULL;
+}
+
+struct _TagDescription {
+    gchar tag;
+    gchar *description;
+};
+
+typedef struct _TagDescription TagDescription;
+
+static TagDescription tag_descriptions[] = {
+    {'p', N_("Performer/Artist")},
+    {'a', N_("Album")},
+    {'g', N_("Genre")},
+    {'f', N_("File name")},
+    {'F', N_("File path")},
+    {'e', N_("File extension")},
+    {'t', N_("Track name")},
+    {'n', N_("Track number")},
+    {'d', N_("Date")},
+    {'y', N_("Year")},
+    {'c', N_("Comment")}
+};
+
+gint tag_descriptions_length =
+    sizeof(tag_descriptions) / sizeof(TagDescription);
+
+/**
+ * xmms_titlestring_descriptions:
+ * @tags: A list of formatters to provide.
+ * @columns: A number of columns to arrange them in.
+ *
+ * Generates a box explaining how to use the formatters.
+ *
+ * Return value: A GtkWidget containing the table.
+ **/
+GtkWidget *
+xmms_titlestring_descriptions(gchar * tags, gint columns)
+{
+    GtkWidget *table, *label;
+    gchar tag_str[5];
+    gint num = strlen(tags);
+    gint r = 0, c, i;
+
+    g_return_val_if_fail(tags != NULL, NULL);
+    g_return_val_if_fail(columns <= num, NULL);
+
+    table = gtk_table_new((num + columns - 1) / columns, columns * 2, FALSE);
+    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
+    gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+    for (c = 0; c < columns; c++) {
+        for (r = 0; r < (num + columns - 1 - c) / columns; r++) {
+            g_snprintf(tag_str, sizeof(tag_str), "%%%c:", *tags);
+            label = gtk_label_new(tag_str);
+            gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+            gtk_table_attach(GTK_TABLE(table), label, 2 * c, 2 * c + 1, r,
+                             r + 1, GTK_FILL, GTK_FILL, 0, 0);
+            gtk_widget_show(label);
+
+            for (i = 0; i < tag_descriptions_length; i++) {
+                if (*tags == tag_descriptions[i].tag) {
+                    label = gtk_label_new(_(tag_descriptions[i].description));
+                    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+                    gtk_table_attach(GTK_TABLE(table), label, 2 * c + 1,
+                                     2 * c + 2, r, r + 1,
+                                     GTK_EXPAND | GTK_FILL,
+                                     GTK_EXPAND | GTK_FILL, 0, 0);
+                    gtk_widget_show(label);
+                    break;
+                }
+            }
+
+            if (i == tag_descriptions_length)
+                g_warning("Invalid tag: %c", *tags);
+
+            tags++;
+        }
+
+    }
+
+    label = gtk_label_new(_("%{n:...%}: Display \"...\" only if element "
+                            "%n is present"));
+    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+    gtk_table_attach(GTK_TABLE(table), label, 0, r + 1,
+                     r + 1, r + 2, GTK_FILL, GTK_FILL, 0, 0);
+    gtk_widget_show(label);
+
+    return table;
+}
--- a/src/audacious/titlestring.h	Sat Jan 27 11:40:05 2007 -0800
+++ b/src/audacious/titlestring.h	Sat Jan 27 12:10:21 2007 -0800
@@ -25,13 +25,30 @@
 #include <unistd.h>
 #include <time.h>
 
-/*
- * Struct which is passed to xmms_get_titlestring().  An input struct
- * is allocated and initialized with XMMS_NEW_TITLEINPUT().  Before
+/**
+ * TitleInput:
+ * @__size: Private field which describes the version of the TitleInput.
+ * @__version: Private field which describes the version of the TitleInput.
+ * @performer: The performer of the media that the tuple is describing.
+ * @album_name: The name of the album that contains the media.
+ * @track_name: The title of the media.
+ * @track_number: The track number of the media.
+ * @year: The year the media was published.
+ * @date: The date the media was published.
+ * @genre: The genre of the media.
+ * @comment: Any comments attached to the media.
+ * @file_name: The filename which refers to the media.
+ * @file_ext: The file's extension.
+ * @file_path: The path that the media is in.
+ * @length: The length of the media.
+ * @formatter: The format string that should be used.
+ * @mtime: The last modified time of the file.
+ *
+ * Tuple which is passed to xmms_get_titlestring().  An input tuple
+ * is allocated and initialized with bmp_title_input_new().  Before
  * passing the struct to xmms_get_titlestring() it should be filled
  * with appropriate field values.
- */
-
+ **/
 typedef struct {
     gint __size;                /* Set by bmp_title_input_new() */
     gint __version;             /* Ditto */
@@ -47,11 +64,16 @@
     gchar *file_name;           /* %f */
     const gchar *file_ext;      /* %e *//* is not always strdup'ed, see xmms_input_get_song_info and plugins! */
     gchar *file_path;           /* %F */
-    gint length;                /* not displayable */
-    gchar *formatter;           /* not displayable */
-    time_t mtime;               /* time of modified */
+    gint length;		/* not displayable */
+    gchar *formatter;		/* not displayable */
+    time_t mtime;
 } TitleInput;
 
+/**
+ * BmpTitleInput:
+ *
+ * An alternate name for the #TitleInput object.
+ **/
 typedef TitleInput BmpTitleInput;
 
 
@@ -62,14 +84,27 @@
  * the struct layout.
  */
 
+/**
+ * XMMS_TITLEINPUT_SIZE:
+ *
+ * The size of the TitleInput object compiled into the library.
+ **/
 #define XMMS_TITLEINPUT_SIZE	sizeof(TitleInput)
+
+/**
+ * XMMS_TITLEINPUT_VERSION:
+ *
+ * The version of the TitleInput object compiled into the library.
+ **/
 #define XMMS_TITLEINPUT_VERSION	(1)
 
-#define XMMS_NEW_TITLEINPUT(input) G_STMT_START { \
-    input = g_new0(TitleInput, 1);                \
-    input->__size = XMMS_TITLEINPUT_SIZE;         \
-    input->__version = XMMS_TITLEINPUT_VERSION;   \
-} G_STMT_END
+/**
+ * XMMS_NEW_TITLEINPUT:
+ * @input: A TitleInput to initialize.
+ *
+ * Initializes a TitleInput object. Included for XMMS compatibility.
+ **/
+#define XMMS_NEW_TITLEINPUT(input) input = bmp_title_input_new();
 
 
 G_BEGIN_DECLS
@@ -78,7 +113,7 @@
 void bmp_title_input_free(BmpTitleInput * input);
 
 gchar *xmms_get_titlestring(const gchar * fmt, TitleInput * input);
-GtkWidget *xmms_titlestring_descriptions(gchar * tags, gint rows);
+GtkWidget *xmms_titlestring_descriptions(gchar * tags, gint columns);
 
 G_END_DECLS
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/xconvert.c	Sat Jan 27 12:10:21 2007 -0800
@@ -0,0 +1,849 @@
+/*  Audacious
+ *  Copyright (C) 2005-2007  Audacious team
+ *
+ *  XMMS - Cross-platform multimedia player
+ *  Copyright (C) 1998-2003  Peter Alm, Mikael Alm, Olle Hallnas,
+ *                           Thomas Nilsson and 4Front Technologies
+ *  Copyright (C) 1999-2003  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; under version 2 of the License.
+ *
+ *  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 "config.h"
+#include <stdlib.h>
+#include <audacious/plugin.h>
+#include "xconvert.h"
+
+#define IS_BIG_ENDIAN  (G_BYTE_ORDER==G_BIG_ENDIAN)
+
+/**
+ * buffer:
+ *
+ * Contains data for conversion.
+ *
+ * @buffer: A pointer to the memory being used in the conversion process.
+ * @size: The size of the memory being referenced.
+ **/
+struct buffer {
+    void *buffer;
+    int size;
+};
+
+/**
+ * xmms_convert_buffers:
+ *
+ * Stores data for conversion.
+ *
+ * @format_buffer: A buffer for converting formats.
+ * @stereo_buffer: A buffer for downmixing or upmixing.
+ * @freq_buffer: A buffer used for resampling.
+ **/
+struct xmms_convert_buffers {
+    struct buffer format_buffer, stereo_buffer, freq_buffer;
+};
+
+/**
+ * xmms_convert_buffers_new:
+ *
+ * Factory for an #xmms_convert_buffers struct.
+ *
+ * Return value: An #xmms_convert_buffers struct.
+ **/
+struct xmms_convert_buffers *
+xmms_convert_buffers_new(void)
+{
+    return g_malloc0(sizeof(struct xmms_convert_buffers));
+}
+
+/**
+ * convert_get_buffer:
+ * @buffer: A buffer to resize.
+ * @size: The new size for that buffer.
+ *
+ * Resizes a conversion buffer.
+ **/
+static void *
+convert_get_buffer(struct buffer *buffer, size_t size)
+{
+    if (size > 0 && size <= (size_t)buffer->size)
+        return buffer->buffer;
+
+    buffer->size = size;
+    buffer->buffer = g_realloc(buffer->buffer, size);
+    return buffer->buffer;
+}
+
+/**
+ * xmms_convert_buffers_free:
+ * @buf: An xmms_convert_buffers structure to free.
+ *
+ * Frees the actual buffers contained inside the buffer struct.
+ **/
+void
+xmms_convert_buffers_free(struct xmms_convert_buffers *buf)
+{
+    convert_get_buffer(&buf->format_buffer, 0);
+    convert_get_buffer(&buf->stereo_buffer, 0);
+    convert_get_buffer(&buf->freq_buffer, 0);
+}
+
+/**
+ * xmms_convert_buffers_destroy:
+ * @buf: An xmms_convert_buffers structure to destroy.
+ *
+ * Destroys an xmms_convert_buffers structure.
+ **/
+void
+xmms_convert_buffers_destroy(struct xmms_convert_buffers *buf)
+{
+    if (!buf)
+        return;
+    xmms_convert_buffers_free(buf);
+    g_free(buf);
+}
+
+static int
+convert_swap_endian(struct xmms_convert_buffers *buf, void **data, int length)
+{
+    guint16 *ptr = *data;
+    int i;
+    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(struct
+                                       xmms_convert_buffers
+                                       *buf, void **data, int length)
+{
+    guint16 *ptr = *data;
+    int i;
+    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(struct
+                                      xmms_convert_buffers *buf,
+                                      void **data, int length)
+{
+    guint16 *ptr = *data;
+    int i;
+    for (i = 0; i < length; i += 2, ptr++)
+        *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15);
+
+    return i;
+}
+
+static int
+convert_swap_sign16(struct xmms_convert_buffers *buf, void **data, int length)
+{
+    gint16 *ptr = *data;
+    int i;
+    for (i = 0; i < length; i += 2, ptr++)
+        *ptr ^= 1 << 15;
+
+    return i;
+}
+
+static int
+convert_swap_sign8(struct xmms_convert_buffers *buf, void **data, int length)
+{
+    gint8 *ptr = *data;
+    int i;
+    for (i = 0; i < length; i++)
+        *ptr++ ^= 1 << 7;
+
+    return i;
+}
+
+static int
+convert_to_8_native_endian(struct xmms_convert_buffers *buf,
+                           void **data, int length)
+{
+    gint8 *output = *data;
+    gint16 *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++)
+        *output++ = *input++ >> 8;
+
+    return i;
+}
+
+static int
+convert_to_8_native_endian_swap_sign(struct xmms_convert_buffers
+                                     *buf, void **data, int length)
+{
+    gint8 *output = *data;
+    gint16 *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++)
+        *output++ = (*input++ >> 8) ^ (1 << 7);
+
+    return i;
+}
+
+
+static int
+convert_to_8_alien_endian(struct xmms_convert_buffers *buf,
+                          void **data, int length)
+{
+    gint8 *output = *data;
+    gint16 *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++)
+        *output++ = *input++ & 0xff;
+
+    return i;
+}
+
+static int
+convert_to_8_alien_endian_swap_sign(struct xmms_convert_buffers
+                                    *buf, void **data, int length)
+{
+    gint8 *output = *data;
+    gint16 *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++)
+        *output++ = (*input++ & 0xff) ^ (1 << 7);
+
+    return i;
+}
+
+static int
+convert_to_16_native_endian(struct xmms_convert_buffers *buf,
+                            void **data, int length)
+{
+    guint8 *input = *data;
+    guint16 *output;
+    int i;
+    *data = convert_get_buffer(&buf->format_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(struct
+                                      xmms_convert_buffers *buf,
+                                      void **data, int length)
+{
+    guint8 *input = *data;
+    guint16 *output;
+    int i;
+    *data = convert_get_buffer(&buf->format_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(struct xmms_convert_buffers *buf,
+                           void **data, int length)
+{
+    guint8 *input = *data;
+    guint16 *output;
+    int i;
+    *data = convert_get_buffer(&buf->format_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(struct xmms_convert_buffers
+                                     *buf, void **data, int length)
+{
+    guint8 *input = *data;
+    guint16 *output;
+    int i;
+    *data = convert_get_buffer(&buf->format_buffer, length * 2);
+    output = *data;
+    for (i = 0; i < length; i++)
+        *output++ = *input++ ^ (1 << 7);
+
+    return i * 2;
+}
+
+static AFormat
+unnativize(AFormat fmt)
+{
+    if (fmt == FMT_S16_NE) {
+        if (IS_BIG_ENDIAN)
+            return FMT_S16_BE;
+        else
+            return FMT_S16_LE;
+    }
+    if (fmt == FMT_U16_NE) {
+        if (IS_BIG_ENDIAN)
+            return FMT_U16_BE;
+        else
+            return FMT_U16_LE;
+    }
+    return fmt;
+}
+
+/**
+ * xmms_convert_get_func:
+ * @output: A format to output data as.
+ * @input: The format of the inbound data.
+ *
+ * Looks up the proper conversion method to use.
+ *
+ * Return value: A function pointer to the desired conversion function.
+ **/
+convert_func_t
+xmms_convert_get_func(AFormat output, AFormat input)
+{
+    output = unnativize(output);
+    input = unnativize(input);
+
+    if (output == input)
+        return NULL;
+
+    if ((output == FMT_U16_BE && input == FMT_U16_LE) ||
+        (output == FMT_U16_LE && input == FMT_U16_BE) ||
+        (output == FMT_S16_BE && input == FMT_S16_LE) ||
+        (output == FMT_S16_LE && input == FMT_S16_BE))
+        return convert_swap_endian;
+
+    if ((output == FMT_U16_BE && input == FMT_S16_BE) ||
+        (output == FMT_U16_LE && input == FMT_S16_LE) ||
+        (output == FMT_S16_BE && input == FMT_U16_BE) ||
+        (output == FMT_S16_LE && input == FMT_U16_LE))
+        return convert_swap_sign16;
+
+    if ((IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_S16_LE) ||
+          (output == FMT_S16_BE && input == FMT_U16_LE))) ||
+        (!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_S16_BE) ||
+          (output == FMT_S16_LE && input == FMT_U16_BE))))
+        return convert_swap_sign_and_endian_to_native;
+
+    if ((!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_S16_LE) ||
+          (output == FMT_S16_BE && input == FMT_U16_LE))) ||
+        (IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_S16_BE) ||
+          (output == FMT_S16_LE && input == FMT_U16_BE))))
+        return convert_swap_sign_and_endian_to_alien;
+
+    if ((IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_U16_BE) ||
+          (output == FMT_S8 && input == FMT_S16_BE))) ||
+        (!IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_U16_LE) ||
+          (output == FMT_S8 && input == FMT_S16_LE))))
+        return convert_to_8_native_endian;
+
+    if ((IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_S16_BE) ||
+          (output == FMT_S8 && input == FMT_U16_BE))) ||
+        (!IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_S16_LE) ||
+          (output == FMT_S8 && input == FMT_U16_LE))))
+        return convert_to_8_native_endian_swap_sign;
+
+    if ((!IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_U16_BE) ||
+          (output == FMT_S8 && input == FMT_S16_BE))) ||
+        (IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_U16_LE) ||
+          (output == FMT_S8 && input == FMT_S16_LE))))
+        return convert_to_8_alien_endian;
+
+    if ((!IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_S16_BE) ||
+          (output == FMT_S8 && input == FMT_U16_BE))) ||
+        (IS_BIG_ENDIAN &&
+         ((output == FMT_U8 && input == FMT_S16_LE) ||
+          (output == FMT_S8 && input == FMT_U16_LE))))
+        return convert_to_8_alien_endian_swap_sign;
+
+    if ((output == FMT_U8 && input == FMT_S8) ||
+        (output == FMT_S8 && input == FMT_U8))
+        return convert_swap_sign8;
+
+    if ((IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_U8) ||
+          (output == FMT_S16_BE && input == FMT_S8))) ||
+        (!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_U8) ||
+          (output == FMT_S16_LE && input == FMT_S8))))
+        return convert_to_16_native_endian;
+
+    if ((IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_S8) ||
+          (output == FMT_S16_BE && input == FMT_U8))) ||
+        (!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_S8) ||
+          (output == FMT_S16_LE && input == FMT_U8))))
+        return convert_to_16_native_endian_swap_sign;
+
+    if ((!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_U8) ||
+          (output == FMT_S16_BE && input == FMT_S8))) ||
+        (IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_U8) ||
+          (output == FMT_S16_LE && input == FMT_S8))))
+        return convert_to_16_alien_endian;
+
+    if ((!IS_BIG_ENDIAN &&
+         ((output == FMT_U16_BE && input == FMT_S8) ||
+          (output == FMT_S16_BE && input == FMT_U8))) ||
+        (IS_BIG_ENDIAN &&
+         ((output == FMT_U16_LE && input == FMT_S8) ||
+          (output == FMT_S16_LE && input == FMT_U8))))
+        return convert_to_16_alien_endian_swap_sign;
+
+    g_warning("Translation needed, but not available.\n"
+              "Input: %d; Output %d.", input, output);
+    return NULL;
+}
+
+static int
+convert_mono_to_stereo(struct xmms_convert_buffers *buf,
+                       void **data, int length, int b16)
+{
+    int i;
+    void *outbuf = convert_get_buffer(&buf->stereo_buffer, length * 2);
+
+    if (b16) {
+        guint16 *output = outbuf, *input = *data;
+        for (i = 0; i < length / 2; i++) {
+            *output++ = *input;
+            *output++ = *input;
+            input++;
+        }
+    }
+    else {
+        guint8 *output = outbuf, *input = *data;
+        for (i = 0; i < length; i++) {
+            *output++ = *input;
+            *output++ = *input;
+            input++;
+        }
+    }
+    *data = outbuf;
+
+    return length * 2;
+}
+
+static int
+convert_mono_to_stereo_8(struct xmms_convert_buffers *buf,
+                         void **data, int length)
+{
+    return convert_mono_to_stereo(buf, data, length, FALSE);
+}
+
+static int
+convert_mono_to_stereo_16(struct xmms_convert_buffers *buf,
+                          void **data, int length)
+{
+    return convert_mono_to_stereo(buf, data, length, TRUE);
+}
+
+static int
+convert_stereo_to_mono_u8(struct xmms_convert_buffers *buf,
+                          void **data, int length)
+{
+    guint8 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++) {
+        guint16 tmp;
+        tmp = *input++;
+        tmp += *input++;
+        *output++ = tmp / 2;
+    }
+    return length / 2;
+}
+static int
+convert_stereo_to_mono_s8(struct xmms_convert_buffers *buf,
+                          void **data, int length)
+{
+    gint8 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 2; i++) {
+        gint16 tmp;
+        tmp = *input++;
+        tmp += *input++;
+        *output++ = tmp / 2;
+    }
+    return length / 2;
+}
+static int
+convert_stereo_to_mono_u16le(struct xmms_convert_buffers *buf,
+                             void **data, int length)
+{
+    guint16 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 4; i++) {
+        guint32 tmp;
+        guint16 stmp;
+        tmp = GUINT16_FROM_LE(*input);
+        input++;
+        tmp += GUINT16_FROM_LE(*input);
+        input++;
+        stmp = tmp / 2;
+        *output++ = GUINT16_TO_LE(stmp);
+    }
+    return length / 2;
+}
+
+static int
+convert_stereo_to_mono_u16be(struct xmms_convert_buffers *buf,
+                             void **data, int length)
+{
+    guint16 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 4; i++) {
+        guint32 tmp;
+        guint16 stmp;
+        tmp = GUINT16_FROM_BE(*input);
+        input++;
+        tmp += GUINT16_FROM_BE(*input);
+        input++;
+        stmp = tmp / 2;
+        *output++ = GUINT16_TO_BE(stmp);
+    }
+    return length / 2;
+}
+
+static int
+convert_stereo_to_mono_s16le(struct xmms_convert_buffers *buf,
+                             void **data, int length)
+{
+    gint16 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 4; i++) {
+        gint32 tmp;
+        gint16 stmp;
+        tmp = GINT16_FROM_LE(*input);
+        input++;
+        tmp += GINT16_FROM_LE(*input);
+        input++;
+        stmp = tmp / 2;
+        *output++ = GINT16_TO_LE(stmp);
+    }
+    return length / 2;
+}
+
+static int
+convert_stereo_to_mono_s16be(struct xmms_convert_buffers *buf,
+                             void **data, int length)
+{
+    gint16 *output = *data, *input = *data;
+    int i;
+    for (i = 0; i < length / 4; i++) {
+        gint32 tmp;
+        gint16 stmp;
+        tmp = GINT16_FROM_BE(*input);
+        input++;
+        tmp += GINT16_FROM_BE(*input);
+        input++;
+        stmp = tmp / 2;
+        *output++ = GINT16_TO_BE(stmp);
+    }
+    return length / 2;
+}
+
+/**
+ * xmms_convert_get_channel_func:
+ * @fmt: The format of the data.
+ * @output: The number of channels to output as.
+ * @input: The number of channels inbound.
+ *
+ * Looks up the proper conversion method to use.
+ *
+ * Return value: A function pointer to the desired conversion function.
+ **/
+convert_channel_func_t
+xmms_convert_get_channel_func(AFormat fmt, int output, int input)
+{
+    fmt = unnativize(fmt);
+
+    if (output == input)
+        return NULL;
+
+    if (input == 1 && output == 2)
+        switch (fmt) {
+        case FMT_U8:
+        case FMT_S8:
+            return convert_mono_to_stereo_8;
+        case FMT_U16_LE:
+        case FMT_U16_BE:
+        case FMT_S16_LE:
+        case FMT_S16_BE:
+            return convert_mono_to_stereo_16;
+        default:
+            g_warning("Unknown format: %d" "No conversion available.", fmt);
+            return NULL;
+        }
+    if (input == 2 && output == 1)
+        switch (fmt) {
+        case FMT_U8:
+            return convert_stereo_to_mono_u8;
+        case FMT_S8:
+            return convert_stereo_to_mono_s8;
+        case FMT_U16_LE:
+            return convert_stereo_to_mono_u16le;
+        case FMT_U16_BE:
+            return convert_stereo_to_mono_u16be;
+        case FMT_S16_LE:
+            return convert_stereo_to_mono_s16le;
+        case FMT_S16_BE:
+            return convert_stereo_to_mono_s16be;
+        default:
+            g_warning("Unknown format: %d.  "
+                      "No conversion available.", fmt);
+            return NULL;
+
+        }
+
+    g_warning("Input has %d channels, soundcard uses %d channels\n"
+              "No conversion is available", input, output);
+    return NULL;
+}
+
+
+#define RESAMPLE_STEREO(sample_type, bswap)			\
+	const int shift = sizeof (sample_type);			\
+        int i, in_samples, out_samples, x, delta;		\
+	sample_type *inptr = *data, *outptr;			\
+	guint nlen = (((length >> shift) * ofreq) / ifreq);	\
+	void *nbuf;						\
+	if (nlen == 0)						\
+		return 0;						\
+	nlen <<= shift;						\
+	if (bswap)						\
+		convert_swap_endian(NULL, data, length);	\
+	nbuf = convert_get_buffer(&buf->freq_buffer, nlen);	\
+	outptr = nbuf;						\
+	in_samples = length >> shift;				\
+        out_samples = nlen >> shift;				\
+	delta = (in_samples << 12) / out_samples;		\
+	for (x = 0, i = 0; i < out_samples; i++)		\
+	{							\
+		int x1, frac;					\
+		x1 = (x >> 12) << 12;				\
+		frac = x - x1;					\
+		*outptr++ =					\
+			((inptr[(x1 >> 12) << 1] *		\
+			  ((1<<12) - frac) +			\
+			  inptr[((x1 >> 12) + 1) << 1] *	\
+			  frac) >> 12);				\
+		*outptr++ =					\
+			((inptr[((x1 >> 12) << 1) + 1] *	\
+			  ((1<<12) - frac) +			\
+			  inptr[(((x1 >> 12) + 1) << 1) + 1] *	\
+			  frac) >> 12);				\
+		x += delta;					\
+	}							\
+	if (bswap)						\
+		convert_swap_endian(NULL, &nbuf, nlen);		\
+	*data = nbuf;						\
+	return nlen;						\
+
+
+#define RESAMPLE_MONO(sample_type, bswap)			\
+	const int shift = sizeof (sample_type) - 1;		\
+        int i, x, delta, in_samples, out_samples;		\
+	sample_type *inptr = *data, *outptr;			\
+	guint nlen = (((length >> shift) * ofreq) / ifreq);	\
+	void *nbuf;						\
+	if (nlen == 0)						\
+		return 0;					\
+	nlen <<= shift;						\
+	if (bswap)						\
+		convert_swap_endian(NULL, data, length);	\
+	nbuf = convert_get_buffer(&buf->freq_buffer, nlen);	\
+	outptr = nbuf;						\
+	in_samples = length >> shift;				\
+        out_samples = nlen >> shift;				\
+	delta = ((length >> shift) << 12) / out_samples;	\
+	for (x = 0, i = 0; i < out_samples; i++)		\
+	{							\
+		int x1, frac;					\
+		x1 = (x >> 12) << 12;				\
+		frac = x - x1;					\
+		*outptr++ =					\
+			((inptr[x1 >> 12] * ((1<<12) - frac) +	\
+			  inptr[(x1 >> 12) + 1] * frac) >> 12);	\
+		x += delta;					\
+	}							\
+	if (bswap)						\
+		convert_swap_endian(NULL, &nbuf, nlen);		\
+	*data = nbuf;						\
+	return nlen;						\
+
+static int
+convert_resample_stereo_s16ne(struct xmms_convert_buffers *buf,
+                              void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(gint16, FALSE);
+}
+
+static int
+convert_resample_stereo_s16ae(struct xmms_convert_buffers *buf,
+                              void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(gint16, TRUE);
+}
+
+static int
+convert_resample_stereo_u16ne(struct xmms_convert_buffers *buf,
+                              void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(guint16, FALSE);
+}
+
+static int
+convert_resample_stereo_u16ae(struct xmms_convert_buffers *buf,
+                              void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(guint16, TRUE);
+}
+
+static int
+convert_resample_mono_s16ne(struct xmms_convert_buffers *buf,
+                            void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(gint16, FALSE);
+}
+
+static int
+convert_resample_mono_s16ae(struct xmms_convert_buffers *buf,
+                            void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(gint16, TRUE);
+}
+
+static int
+convert_resample_mono_u16ne(struct xmms_convert_buffers *buf,
+                            void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(guint16, FALSE);
+}
+
+static int
+convert_resample_mono_u16ae(struct xmms_convert_buffers *buf,
+                            void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(guint16, TRUE);
+}
+
+static int
+convert_resample_stereo_u8(struct xmms_convert_buffers *buf,
+                           void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(guint8, FALSE);
+}
+
+static int
+convert_resample_mono_u8(struct xmms_convert_buffers *buf,
+                         void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(guint8, FALSE);
+}
+
+static int
+convert_resample_stereo_s8(struct xmms_convert_buffers *buf,
+                           void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_STEREO(gint8, FALSE);
+}
+
+static int
+convert_resample_mono_s8(struct xmms_convert_buffers *buf,
+                         void **data, int length, int ifreq, int ofreq)
+{
+    RESAMPLE_MONO(gint8, FALSE);
+}
+
+
+/**
+ * xmms_convert_get_frequency_func:
+ * @fmt: The format of the data.
+ * @channels: The number of channels inbound.
+ *
+ * Looks up the proper conversion method to use.
+ *
+ * Return value: A function pointer to the desired conversion function.
+ **/
+convert_freq_func_t
+xmms_convert_get_frequency_func(AFormat fmt, int channels)
+{
+    fmt = unnativize(fmt);
+    g_message("fmt %d, channels: %d", fmt, channels);
+
+    if (channels < 1 || channels > 2) {
+        g_warning("Unsupported number of channels: %d.  "
+                  "Resample function not available", channels);
+        return NULL;
+    }
+    if ((IS_BIG_ENDIAN && fmt == FMT_U16_BE) ||
+        (!IS_BIG_ENDIAN && fmt == FMT_U16_LE)) {
+        if (channels == 1)
+            return convert_resample_mono_u16ne;
+        else
+            return convert_resample_stereo_u16ne;
+    }
+    if ((IS_BIG_ENDIAN && fmt == FMT_S16_BE) ||
+        (!IS_BIG_ENDIAN && fmt == FMT_S16_LE)) {
+        if (channels == 1)
+            return convert_resample_mono_s16ne;
+        else
+            return convert_resample_stereo_s16ne;
+    }
+    if ((!IS_BIG_ENDIAN && fmt == FMT_U16_BE) ||
+        (IS_BIG_ENDIAN && fmt == FMT_U16_LE)) {
+        if (channels == 1)
+            return convert_resample_mono_u16ae;
+        else
+            return convert_resample_stereo_u16ae;
+    }
+    if ((!IS_BIG_ENDIAN && fmt == FMT_S16_BE) ||
+        (IS_BIG_ENDIAN && fmt == FMT_S16_LE)) {
+        if (channels == 1)
+            return convert_resample_mono_s16ae;
+        else
+            return convert_resample_stereo_s16ae;
+    }
+    if (fmt == FMT_U8) {
+        if (channels == 1)
+            return convert_resample_mono_u8;
+        else
+            return convert_resample_stereo_u8;
+    }
+    if (fmt == FMT_S8) {
+        if (channels == 1)
+            return convert_resample_mono_s8;
+        else
+            return convert_resample_stereo_s8;
+    }
+    g_warning("Resample function not available" "Format %d.", fmt);
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/xconvert.h	Sat Jan 27 12:10:21 2007 -0800
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (C) 2003  Haavard Kvaalen <havardk@xmms.org>
+ *
+ *  Licensed under GNU LGPL version 2.
+ */
+
+#include <audacious/plugin.h>
+
+struct xmms_convert_buffers;
+
+struct xmms_convert_buffers *xmms_convert_buffers_new(void);
+/*
+ * Free the data assosiated with the buffers, without destroying the
+ * context.  The context can be reused.
+ */
+void xmms_convert_buffers_free(struct xmms_convert_buffers *buf);
+void xmms_convert_buffers_destroy(struct xmms_convert_buffers *buf);
+
+
+typedef int (*convert_func_t) (struct xmms_convert_buffers * buf,
+                               void **data, int length);
+typedef int (*convert_channel_func_t) (struct xmms_convert_buffers * buf,
+                                       void **data, int length);
+typedef int (*convert_freq_func_t) (struct xmms_convert_buffers * buf,
+                                    void **data, int length, int ifreq,
+                                    int ofreq);
+
+
+convert_func_t xmms_convert_get_func(AFormat output, AFormat input);
+convert_channel_func_t xmms_convert_get_channel_func(AFormat fmt,
+                                                     int output,
+                                                     int input);
+convert_freq_func_t xmms_convert_get_frequency_func(AFormat fmt,
+                                                    int channels);
--- a/src/libaudacious/Makefile	Sat Jan 27 11:40:05 2007 -0800
+++ b/src/libaudacious/Makefile	Sat Jan 27 12:10:21 2007 -0800
@@ -7,16 +7,16 @@
 OBJECTIVE_SONAME_SUFFIX = 4
 
 LIBADD = \
-	$(GTK_LIBS)      \
-	$(GCONF_LIBS)	\
+	$(GTK_LIBS) \
+	$(GCONF_LIBS) \
 	$(LIBMCS_LIBS)
 
 CFLAGS += $(PICFLAGS) \
-	$(GTK_CFLAGS)        \
-	$(GCONF_CFLAGS)      \
-	$(LIBMCS_CFLAGS)	\
-	-D_AUDACIOUS_CORE    \
-	-I.. -I../..	      \
+	$(GTK_CFLAGS) \
+	$(GCONF_CFLAGS) \
+	$(LIBMCS_CFLAGS) \
+	-D_AUDACIOUS_CORE \
+	-I.. -I../.. \
 	-I../intl
 
 CONF_SRC = configdb_$(CONFIGDB_BACKEND).c
@@ -24,18 +24,14 @@
 SOURCES = \
 	$(CONF_SRC) \
 	rcfile.c \
-	beepctrl.c \
-	titlestring.c \
-	xconvert.c
+	beepctrl.c
 
 OBJECTS = ${SOURCES:.c=.o}
 
 HEADERS = \
 	rcfile.h \
 	configdb.h \
-	beepctrl.h \
-	titlestring.h \
-	xconvert.h
+	beepctrl.h
 
 include ../../mk/objective.mk
 
--- a/src/libaudacious/titlestring.c	Sat Jan 27 11:40:05 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2001,  Espen Skoglund <esk@ira.uka.de>
- * Copyright (C) 2001,  Haavard Kvaalen <havardk@xmms.org>
- *
- * 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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#define GETTEXT_PACKAGE PACKAGE_NAME
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "titlestring.h"
-
-#define CHECK(input, field) \
-	(((gchar *) &input->field - (gchar *) input) < input->__size)
-
-#define VS(input, field) (CHECK(input, field) ? input->field : NULL)
-#define VI(input, field) (CHECK(input, field) ? input->field : 0)
-
-/**
- * bmp_title_input_new:
- *
- * #BmpTitleInput tuple factory.
- *
- * Return value: A #BmpTitleInput object.
- **/
-BmpTitleInput *
-bmp_title_input_new()
-{
-    BmpTitleInput *input;
-    input = g_new0(BmpTitleInput, 1);
-    input->__size = XMMS_TITLEINPUT_SIZE;
-    input->__version = XMMS_TITLEINPUT_VERSION;
-    return input;
-}
-
-/**
- * bmp_title_input_free:
- * @input: A #BmpTitleInput tuple to destroy.
- *
- * Destroys a #BmpTitleInput tuple.
- **/
-void
-bmp_title_input_free(BmpTitleInput * input)
-{
-    if (input == NULL)
-        return;
-
-    if (input->performer != NULL)
-        g_free(input->performer);
-
-    if (input->album_name != NULL)
-        g_free(input->album_name);
-
-    if (input->track_name != NULL)
-        g_free(input->track_name);
-
-    if (input->date != NULL)
-        g_free(input->date);
-
-    if (input->genre != NULL)
-        g_free(input->genre);
-
-    if (input->comment != NULL)
-        g_free(input->comment);
-
-    if (input->file_name != NULL)
-        g_free(input->file_name);
-
-    if (input->file_path != NULL)
-        g_free(input->file_path);
-
-    g_free(input);
-}
-
-/**
- * xmms_get_titlestring:
- * @fmt: A format string.
- * @input: A tuple to use for data.
- *
- * Generates a formatted string from a tuple.
- *
- * Return value: A formatted tuple string.
- **/
-gchar *
-xmms_get_titlestring(const gchar * fmt, TitleInput * input)
-{
-    GString *outstr;
-    const gchar *string;
-    gchar c, convert[16];
-    gint numdigits, numpr, val, i;
-    gint f_left, f_space, f_zero, someflag, width, precision;
-    gboolean did_output = FALSE;
-    gchar digits[] = "0123456789";
-
-#define PUTCH(ch) g_string_append_c(outstr, ch)
-
-#define LEFTPAD(num)                            \
-    G_STMT_START {                              \
-        gint cnt = (num);                       \
-        if ( ! f_left && cnt > 0 )              \
-            while ( cnt-- > 0 )                 \
-                PUTCH(f_zero ? '0' : ' ');      \
-    } G_STMT_END;
-
-#define RIGHTPAD(num)                           \
-    G_STMT_START {                              \
-        gint cnt = (num);                       \
-        if ( f_left && cnt > 0 )                \
-            while ( cnt-- > 0 )                 \
-                PUTCH( ' ' );                   \
-    } G_STMT_END;
-
-    if (fmt == NULL || input == NULL)
-        return NULL;
-    outstr = g_string_new("");
-
-    for (;;) {
-        /* Copy characters until we encounter '%'. */
-        while ((c = *fmt++) != '%') {
-            if (c == '\0')
-                goto Done;
-            g_string_append_c(outstr, c);
-        }
-
-        f_left = f_space = f_zero = 0;
-        someflag = 1;
-
-
-        /* Parse flags. */
-        while (someflag) {
-            switch (*fmt) {
-            case '-':
-                f_left = 1;
-                fmt++;
-                break;
-            case ' ':
-                f_space = 1;
-                fmt++;
-                break;
-            case '0':
-                f_zero = 1;
-                fmt++;
-                break;
-            default:
-                someflag = 0;
-                break;
-            }
-        }
-
-
-        /* Parse field width. */
-        if ((c = *fmt) >= '0' && c <= '9') {
-            width = 0;
-            while ((c = *fmt++) >= '0' && c <= '9') {
-                width *= 10;
-                width += c - '0';
-            }
-            fmt--;
-        }
-        else
-            width = -1;
-
-
-        /* Parse precision. */
-        if (*fmt == '.') {
-            if ((c = *++fmt) >= '0' && c <= '9') {
-                precision = 0;
-                while ((c = *fmt++) >= '0' && c <= '9') {
-                    precision *= 10;
-                    precision += c - '0';
-                }
-                fmt--;
-            }
-            else
-                precision = -1;
-        }
-        else
-            precision = -1;
-
-
-        /* Parse format conversion. */
-        switch (c = *fmt++) {
-        case '}':              /* close optional, just ignore */
-            continue;
-
-        case '{':{             /* optional entry: %{n:...%} */
-                char n = *fmt++;
-                if (!((n == 'a' && VS(input, album_name)) ||
-                      (n == 'c' && VS(input, comment)) ||
-                      (n == 'd' && VS(input, date)) ||
-                      (n == 'e' && VS(input, file_ext)) ||
-                      (n == 'f' && VS(input, file_name)) ||
-                      (n == 'F' && VS(input, file_path)) ||
-                      (n == 'g' && VS(input, genre)) ||
-                      (n == 'n' && VI(input, track_number)) ||
-                      (n == 'p' && VS(input, performer)) ||
-                      (n == 't' && VS(input, track_name)) ||
-                      (n == 'y' && VI(input, year)))) {
-                    int nl = 0;
-                    char c;
-                    while ((c = *fmt++))    /* until end of string      */
-                        if (c == '}')   /* if end of opt            */
-                            if (!nl)
-                                break;  /* if outmost indent level  */
-                            else
-                                --nl;   /* else reduce indent       */
-                        else if (c == '{')
-                            ++nl;   /* increase indent          */
-                }
-                else
-                    ++fmt;
-                break;
-            }
-
-        case 'a':
-            string = VS(input, album_name);
-            goto Print_string;
-        case 'c':
-            string = VS(input, comment);
-            goto Print_string;
-        case 'd':
-            string = VS(input, date);
-            goto Print_string;
-        case 'e':
-            string = VS(input, file_ext);
-            goto Print_string;
-        case 'f':
-            string = VS(input, file_name);
-            goto Print_string;
-        case 'F':
-            string = VS(input, file_path);
-            goto Print_string;
-        case 'g':
-            string = VS(input, genre);
-            goto Print_string;
-        case 'n':
-            val = VI(input, track_number);
-            goto Print_number;
-        case 'p':
-            string = VS(input, performer);
-            goto Print_string;
-        case 't':
-            string = VS(input, track_name);
-	    goto Print_string;
-        case 'y':
-            val = VI(input, year);
-	    goto Print_number;
-
-          Print_string:
-            if (string == NULL)
-                break;
-            did_output = TRUE;
-
-            numpr = 0;
-            if (width > 0) {
-                /* Calculate printed size. */
-                numpr = strlen(string);
-                if (precision >= 0 && precision < numpr)
-                    numpr = precision;
-
-                LEFTPAD(width - numpr);
-            }
-
-            /* Insert string. */
-            if (precision >= 0) {
-                glong offset_max = precision, offset;
-                gchar *uptr = NULL;
-                const gchar *tmpstring = string;
-                while (precision > 0) {
-                    offset = offset_max - precision;
-                    uptr = g_utf8_offset_to_pointer(tmpstring, offset);
-                    if (*uptr == '\0')
-                        break;
-                    g_string_append_unichar(outstr, g_utf8_get_char(uptr));
-                    precision--;
-                }
-            }
-            else {
-                while ((c = *string++) != '\0')
-                    PUTCH(c);
-            }
-
-            RIGHTPAD(width - numpr);
-            break;
-
-          Print_number:
-            if (val == 0)
-                break;
-            if (c != 'N')
-                did_output = TRUE;
-
-            /* Create reversed number string. */
-            numdigits = 0;
-            do {
-                convert[numdigits++] = digits[val % 10];
-                val /= 10;
-            }
-            while (val > 0);
-
-            numpr = numdigits > precision ? numdigits : precision;
-
-            /* Insert left padding. */
-            if (!f_left && width > numpr) {
-                if (f_zero)
-                    numpr = width;
-                else
-                    for (i = width - numpr; i-- > 0;)
-                        PUTCH(' ');
-            }
-
-            /* Insert zero padding. */
-            for (i = numpr - numdigits; i-- > 0;)
-                PUTCH('0');
-
-            /* Insert number. */
-            while (numdigits > 0)
-                PUTCH(convert[--numdigits]);
-
-            RIGHTPAD(width - numpr);
-            break;
-
-        case '%':
-            PUTCH('%');
-            break;
-
-        default:
-            PUTCH('%');
-            PUTCH(c);
-            break;
-        }
-    }
-
-  Done:
-    if (did_output)
-        return g_string_free(outstr, FALSE);
-    else
-        return NULL;
-}
-
-struct _TagDescription {
-    gchar tag;
-    gchar *description;
-};
-
-typedef struct _TagDescription TagDescription;
-
-static TagDescription tag_descriptions[] = {
-    {'p', N_("Performer/Artist")},
-    {'a', N_("Album")},
-    {'g', N_("Genre")},
-    {'f', N_("File name")},
-    {'F', N_("File path")},
-    {'e', N_("File extension")},
-    {'t', N_("Track name")},
-    {'n', N_("Track number")},
-    {'d', N_("Date")},
-    {'y', N_("Year")},
-    {'c', N_("Comment")}
-};
-
-gint tag_descriptions_length =
-    sizeof(tag_descriptions) / sizeof(TagDescription);
-
-/**
- * xmms_titlestring_descriptions:
- * @tags: A list of formatters to provide.
- * @columns: A number of columns to arrange them in.
- *
- * Generates a box explaining how to use the formatters.
- *
- * Return value: A GtkWidget containing the table.
- **/
-GtkWidget *
-xmms_titlestring_descriptions(gchar * tags, gint columns)
-{
-    GtkWidget *table, *label;
-    gchar tag_str[5];
-    gint num = strlen(tags);
-    gint r = 0, c, i;
-
-    g_return_val_if_fail(tags != NULL, NULL);
-    g_return_val_if_fail(columns <= num, NULL);
-
-    table = gtk_table_new((num + columns - 1) / columns, columns * 2, FALSE);
-    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
-    gtk_table_set_col_spacings(GTK_TABLE(table), 5);
-
-    for (c = 0; c < columns; c++) {
-        for (r = 0; r < (num + columns - 1 - c) / columns; r++) {
-            g_snprintf(tag_str, sizeof(tag_str), "%%%c:", *tags);
-            label = gtk_label_new(tag_str);
-            gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-            gtk_table_attach(GTK_TABLE(table), label, 2 * c, 2 * c + 1, r,
-                             r + 1, GTK_FILL, GTK_FILL, 0, 0);
-            gtk_widget_show(label);
-
-            for (i = 0; i < tag_descriptions_length; i++) {
-                if (*tags == tag_descriptions[i].tag) {
-                    label = gtk_label_new(_(tag_descriptions[i].description));
-                    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-                    gtk_table_attach(GTK_TABLE(table), label, 2 * c + 1,
-                                     2 * c + 2, r, r + 1,
-                                     GTK_EXPAND | GTK_FILL,
-                                     GTK_EXPAND | GTK_FILL, 0, 0);
-                    gtk_widget_show(label);
-                    break;
-                }
-            }
-
-            if (i == tag_descriptions_length)
-                g_warning("Invalid tag: %c", *tags);
-
-            tags++;
-        }
-
-    }
-
-    label = gtk_label_new(_("%{n:...%}: Display \"...\" only if element "
-                            "%n is present"));
-    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-    gtk_table_attach(GTK_TABLE(table), label, 0, r + 1,
-                     r + 1, r + 2, GTK_FILL, GTK_FILL, 0, 0);
-    gtk_widget_show(label);
-
-    return table;
-}
--- a/src/libaudacious/titlestring.h	Sat Jan 27 11:40:05 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2001,  Espen Skoglund <esk@ira.uka.de>
- *                
- * 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.
- *                
- */
-#ifndef XMMS_TITLESTRING_H
-#define XMMS_TITLESTRING_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <unistd.h>
-#include <time.h>
-
-/**
- * TitleInput:
- * @__size: Private field which describes the version of the TitleInput.
- * @__version: Private field which describes the version of the TitleInput.
- * @performer: The performer of the media that the tuple is describing.
- * @album_name: The name of the album that contains the media.
- * @track_name: The title of the media.
- * @track_number: The track number of the media.
- * @year: The year the media was published.
- * @date: The date the media was published.
- * @genre: The genre of the media.
- * @comment: Any comments attached to the media.
- * @file_name: The filename which refers to the media.
- * @file_ext: The file's extension.
- * @file_path: The path that the media is in.
- * @length: The length of the media.
- * @formatter: The format string that should be used.
- * @mtime: The last modified time of the file.
- *
- * Tuple which is passed to xmms_get_titlestring().  An input tuple
- * is allocated and initialized with bmp_title_input_new().  Before
- * passing the struct to xmms_get_titlestring() it should be filled
- * with appropriate field values.
- **/
-typedef struct {
-    gint __size;                /* Set by bmp_title_input_new() */
-    gint __version;             /* Ditto */
-
-    gchar *performer;           /* %p */
-    gchar *album_name;          /* %a */
-    gchar *track_name;          /* %t */
-    gint track_number;          /* %n */
-    gint year;                  /* %y */
-    gchar *date;                /* %d */
-    gchar *genre;               /* %g */
-    gchar *comment;             /* %c */
-    gchar *file_name;           /* %f */
-    const gchar *file_ext;      /* %e *//* is not always strdup'ed, see xmms_input_get_song_info and plugins! */
-    gchar *file_path;           /* %F */
-    gint length;		/* not displayable */
-    gchar *formatter;		/* not displayable */
-    time_t mtime;
-} TitleInput;
-
-/**
- * BmpTitleInput:
- *
- * An alternate name for the #TitleInput object.
- **/
-typedef TitleInput BmpTitleInput;
-
-
-/*
- * Using a __size field helps the library functions detect plugins
- * that use a possibly extended version of the struct.  The __version
- * field helps the library detect possible future incompatibilities in
- * the struct layout.
- */
-
-/**
- * XMMS_TITLEINPUT_SIZE:
- *
- * The size of the TitleInput object compiled into the library.
- **/
-#define XMMS_TITLEINPUT_SIZE	sizeof(TitleInput)
-
-/**
- * XMMS_TITLEINPUT_VERSION:
- *
- * The version of the TitleInput object compiled into the library.
- **/
-#define XMMS_TITLEINPUT_VERSION	(1)
-
-/**
- * XMMS_NEW_TITLEINPUT:
- * @input: A TitleInput to initialize.
- *
- * Initializes a TitleInput object. Included for XMMS compatibility.
- **/
-#define XMMS_NEW_TITLEINPUT(input) input = bmp_title_input_new();
-
-
-G_BEGIN_DECLS
-
-TitleInput *bmp_title_input_new(void);
-void bmp_title_input_free(BmpTitleInput * input);
-
-gchar *xmms_get_titlestring(const gchar * fmt, TitleInput * input);
-GtkWidget *xmms_titlestring_descriptions(gchar * tags, gint columns);
-
-G_END_DECLS
-
-#endif                          /* !XMMS_TITLESTRING_H */
--- a/src/libaudacious/xconvert.c	Sat Jan 27 11:40:05 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,849 +0,0 @@
-/*  Audacious
- *  Copyright (C) 2005-2007  Audacious team
- *
- *  XMMS - Cross-platform multimedia player
- *  Copyright (C) 1998-2003  Peter Alm, Mikael Alm, Olle Hallnas,
- *                           Thomas Nilsson and 4Front Technologies
- *  Copyright (C) 1999-2003  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; under version 2 of the License.
- *
- *  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 "config.h"
-#include <stdlib.h>
-#include <audacious/plugin.h>
-#include "xconvert.h"
-
-#define IS_BIG_ENDIAN  (G_BYTE_ORDER==G_BIG_ENDIAN)
-
-/**
- * buffer:
- *
- * Contains data for conversion.
- *
- * @buffer: A pointer to the memory being used in the conversion process.
- * @size: The size of the memory being referenced.
- **/
-struct buffer {
-    void *buffer;
-    int size;
-};
-
-/**
- * xmms_convert_buffers:
- *
- * Stores data for conversion.
- *
- * @format_buffer: A buffer for converting formats.
- * @stereo_buffer: A buffer for downmixing or upmixing.
- * @freq_buffer: A buffer used for resampling.
- **/
-struct xmms_convert_buffers {
-    struct buffer format_buffer, stereo_buffer, freq_buffer;
-};
-
-/**
- * xmms_convert_buffers_new:
- *
- * Factory for an #xmms_convert_buffers struct.
- *
- * Return value: An #xmms_convert_buffers struct.
- **/
-struct xmms_convert_buffers *
-xmms_convert_buffers_new(void)
-{
-    return g_malloc0(sizeof(struct xmms_convert_buffers));
-}
-
-/**
- * convert_get_buffer:
- * @buffer: A buffer to resize.
- * @size: The new size for that buffer.
- *
- * Resizes a conversion buffer.
- **/
-static void *
-convert_get_buffer(struct buffer *buffer, size_t size)
-{
-    if (size > 0 && size <= (size_t)buffer->size)
-        return buffer->buffer;
-
-    buffer->size = size;
-    buffer->buffer = g_realloc(buffer->buffer, size);
-    return buffer->buffer;
-}
-
-/**
- * xmms_convert_buffers_free:
- * @buf: An xmms_convert_buffers structure to free.
- *
- * Frees the actual buffers contained inside the buffer struct.
- **/
-void
-xmms_convert_buffers_free(struct xmms_convert_buffers *buf)
-{
-    convert_get_buffer(&buf->format_buffer, 0);
-    convert_get_buffer(&buf->stereo_buffer, 0);
-    convert_get_buffer(&buf->freq_buffer, 0);
-}
-
-/**
- * xmms_convert_buffers_destroy:
- * @buf: An xmms_convert_buffers structure to destroy.
- *
- * Destroys an xmms_convert_buffers structure.
- **/
-void
-xmms_convert_buffers_destroy(struct xmms_convert_buffers *buf)
-{
-    if (!buf)
-        return;
-    xmms_convert_buffers_free(buf);
-    g_free(buf);
-}
-
-static int
-convert_swap_endian(struct xmms_convert_buffers *buf, void **data, int length)
-{
-    guint16 *ptr = *data;
-    int i;
-    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(struct
-                                       xmms_convert_buffers
-                                       *buf, void **data, int length)
-{
-    guint16 *ptr = *data;
-    int i;
-    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(struct
-                                      xmms_convert_buffers *buf,
-                                      void **data, int length)
-{
-    guint16 *ptr = *data;
-    int i;
-    for (i = 0; i < length; i += 2, ptr++)
-        *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15);
-
-    return i;
-}
-
-static int
-convert_swap_sign16(struct xmms_convert_buffers *buf, void **data, int length)
-{
-    gint16 *ptr = *data;
-    int i;
-    for (i = 0; i < length; i += 2, ptr++)
-        *ptr ^= 1 << 15;
-
-    return i;
-}
-
-static int
-convert_swap_sign8(struct xmms_convert_buffers *buf, void **data, int length)
-{
-    gint8 *ptr = *data;
-    int i;
-    for (i = 0; i < length; i++)
-        *ptr++ ^= 1 << 7;
-
-    return i;
-}
-
-static int
-convert_to_8_native_endian(struct xmms_convert_buffers *buf,
-                           void **data, int length)
-{
-    gint8 *output = *data;
-    gint16 *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++)
-        *output++ = *input++ >> 8;
-
-    return i;
-}
-
-static int
-convert_to_8_native_endian_swap_sign(struct xmms_convert_buffers
-                                     *buf, void **data, int length)
-{
-    gint8 *output = *data;
-    gint16 *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++)
-        *output++ = (*input++ >> 8) ^ (1 << 7);
-
-    return i;
-}
-
-
-static int
-convert_to_8_alien_endian(struct xmms_convert_buffers *buf,
-                          void **data, int length)
-{
-    gint8 *output = *data;
-    gint16 *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++)
-        *output++ = *input++ & 0xff;
-
-    return i;
-}
-
-static int
-convert_to_8_alien_endian_swap_sign(struct xmms_convert_buffers
-                                    *buf, void **data, int length)
-{
-    gint8 *output = *data;
-    gint16 *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++)
-        *output++ = (*input++ & 0xff) ^ (1 << 7);
-
-    return i;
-}
-
-static int
-convert_to_16_native_endian(struct xmms_convert_buffers *buf,
-                            void **data, int length)
-{
-    guint8 *input = *data;
-    guint16 *output;
-    int i;
-    *data = convert_get_buffer(&buf->format_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(struct
-                                      xmms_convert_buffers *buf,
-                                      void **data, int length)
-{
-    guint8 *input = *data;
-    guint16 *output;
-    int i;
-    *data = convert_get_buffer(&buf->format_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(struct xmms_convert_buffers *buf,
-                           void **data, int length)
-{
-    guint8 *input = *data;
-    guint16 *output;
-    int i;
-    *data = convert_get_buffer(&buf->format_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(struct xmms_convert_buffers
-                                     *buf, void **data, int length)
-{
-    guint8 *input = *data;
-    guint16 *output;
-    int i;
-    *data = convert_get_buffer(&buf->format_buffer, length * 2);
-    output = *data;
-    for (i = 0; i < length; i++)
-        *output++ = *input++ ^ (1 << 7);
-
-    return i * 2;
-}
-
-static AFormat
-unnativize(AFormat fmt)
-{
-    if (fmt == FMT_S16_NE) {
-        if (IS_BIG_ENDIAN)
-            return FMT_S16_BE;
-        else
-            return FMT_S16_LE;
-    }
-    if (fmt == FMT_U16_NE) {
-        if (IS_BIG_ENDIAN)
-            return FMT_U16_BE;
-        else
-            return FMT_U16_LE;
-    }
-    return fmt;
-}
-
-/**
- * xmms_convert_get_func:
- * @output: A format to output data as.
- * @input: The format of the inbound data.
- *
- * Looks up the proper conversion method to use.
- *
- * Return value: A function pointer to the desired conversion function.
- **/
-convert_func_t
-xmms_convert_get_func(AFormat output, AFormat input)
-{
-    output = unnativize(output);
-    input = unnativize(input);
-
-    if (output == input)
-        return NULL;
-
-    if ((output == FMT_U16_BE && input == FMT_U16_LE) ||
-        (output == FMT_U16_LE && input == FMT_U16_BE) ||
-        (output == FMT_S16_BE && input == FMT_S16_LE) ||
-        (output == FMT_S16_LE && input == FMT_S16_BE))
-        return convert_swap_endian;
-
-    if ((output == FMT_U16_BE && input == FMT_S16_BE) ||
-        (output == FMT_U16_LE && input == FMT_S16_LE) ||
-        (output == FMT_S16_BE && input == FMT_U16_BE) ||
-        (output == FMT_S16_LE && input == FMT_U16_LE))
-        return convert_swap_sign16;
-
-    if ((IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_S16_LE) ||
-          (output == FMT_S16_BE && input == FMT_U16_LE))) ||
-        (!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_S16_BE) ||
-          (output == FMT_S16_LE && input == FMT_U16_BE))))
-        return convert_swap_sign_and_endian_to_native;
-
-    if ((!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_S16_LE) ||
-          (output == FMT_S16_BE && input == FMT_U16_LE))) ||
-        (IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_S16_BE) ||
-          (output == FMT_S16_LE && input == FMT_U16_BE))))
-        return convert_swap_sign_and_endian_to_alien;
-
-    if ((IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_U16_BE) ||
-          (output == FMT_S8 && input == FMT_S16_BE))) ||
-        (!IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_U16_LE) ||
-          (output == FMT_S8 && input == FMT_S16_LE))))
-        return convert_to_8_native_endian;
-
-    if ((IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_S16_BE) ||
-          (output == FMT_S8 && input == FMT_U16_BE))) ||
-        (!IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_S16_LE) ||
-          (output == FMT_S8 && input == FMT_U16_LE))))
-        return convert_to_8_native_endian_swap_sign;
-
-    if ((!IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_U16_BE) ||
-          (output == FMT_S8 && input == FMT_S16_BE))) ||
-        (IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_U16_LE) ||
-          (output == FMT_S8 && input == FMT_S16_LE))))
-        return convert_to_8_alien_endian;
-
-    if ((!IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_S16_BE) ||
-          (output == FMT_S8 && input == FMT_U16_BE))) ||
-        (IS_BIG_ENDIAN &&
-         ((output == FMT_U8 && input == FMT_S16_LE) ||
-          (output == FMT_S8 && input == FMT_U16_LE))))
-        return convert_to_8_alien_endian_swap_sign;
-
-    if ((output == FMT_U8 && input == FMT_S8) ||
-        (output == FMT_S8 && input == FMT_U8))
-        return convert_swap_sign8;
-
-    if ((IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_U8) ||
-          (output == FMT_S16_BE && input == FMT_S8))) ||
-        (!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_U8) ||
-          (output == FMT_S16_LE && input == FMT_S8))))
-        return convert_to_16_native_endian;
-
-    if ((IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_S8) ||
-          (output == FMT_S16_BE && input == FMT_U8))) ||
-        (!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_S8) ||
-          (output == FMT_S16_LE && input == FMT_U8))))
-        return convert_to_16_native_endian_swap_sign;
-
-    if ((!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_U8) ||
-          (output == FMT_S16_BE && input == FMT_S8))) ||
-        (IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_U8) ||
-          (output == FMT_S16_LE && input == FMT_S8))))
-        return convert_to_16_alien_endian;
-
-    if ((!IS_BIG_ENDIAN &&
-         ((output == FMT_U16_BE && input == FMT_S8) ||
-          (output == FMT_S16_BE && input == FMT_U8))) ||
-        (IS_BIG_ENDIAN &&
-         ((output == FMT_U16_LE && input == FMT_S8) ||
-          (output == FMT_S16_LE && input == FMT_U8))))
-        return convert_to_16_alien_endian_swap_sign;
-
-    g_warning("Translation needed, but not available.\n"
-              "Input: %d; Output %d.", input, output);
-    return NULL;
-}
-
-static int
-convert_mono_to_stereo(struct xmms_convert_buffers *buf,
-                       void **data, int length, int b16)
-{
-    int i;
-    void *outbuf = convert_get_buffer(&buf->stereo_buffer, length * 2);
-
-    if (b16) {
-        guint16 *output = outbuf, *input = *data;
-        for (i = 0; i < length / 2; i++) {
-            *output++ = *input;
-            *output++ = *input;
-            input++;
-        }
-    }
-    else {
-        guint8 *output = outbuf, *input = *data;
-        for (i = 0; i < length; i++) {
-            *output++ = *input;
-            *output++ = *input;
-            input++;
-        }
-    }
-    *data = outbuf;
-
-    return length * 2;
-}
-
-static int
-convert_mono_to_stereo_8(struct xmms_convert_buffers *buf,
-                         void **data, int length)
-{
-    return convert_mono_to_stereo(buf, data, length, FALSE);
-}
-
-static int
-convert_mono_to_stereo_16(struct xmms_convert_buffers *buf,
-                          void **data, int length)
-{
-    return convert_mono_to_stereo(buf, data, length, TRUE);
-}
-
-static int
-convert_stereo_to_mono_u8(struct xmms_convert_buffers *buf,
-                          void **data, int length)
-{
-    guint8 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++) {
-        guint16 tmp;
-        tmp = *input++;
-        tmp += *input++;
-        *output++ = tmp / 2;
-    }
-    return length / 2;
-}
-static int
-convert_stereo_to_mono_s8(struct xmms_convert_buffers *buf,
-                          void **data, int length)
-{
-    gint8 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 2; i++) {
-        gint16 tmp;
-        tmp = *input++;
-        tmp += *input++;
-        *output++ = tmp / 2;
-    }
-    return length / 2;
-}
-static int
-convert_stereo_to_mono_u16le(struct xmms_convert_buffers *buf,
-                             void **data, int length)
-{
-    guint16 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 4; i++) {
-        guint32 tmp;
-        guint16 stmp;
-        tmp = GUINT16_FROM_LE(*input);
-        input++;
-        tmp += GUINT16_FROM_LE(*input);
-        input++;
-        stmp = tmp / 2;
-        *output++ = GUINT16_TO_LE(stmp);
-    }
-    return length / 2;
-}
-
-static int
-convert_stereo_to_mono_u16be(struct xmms_convert_buffers *buf,
-                             void **data, int length)
-{
-    guint16 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 4; i++) {
-        guint32 tmp;
-        guint16 stmp;
-        tmp = GUINT16_FROM_BE(*input);
-        input++;
-        tmp += GUINT16_FROM_BE(*input);
-        input++;
-        stmp = tmp / 2;
-        *output++ = GUINT16_TO_BE(stmp);
-    }
-    return length / 2;
-}
-
-static int
-convert_stereo_to_mono_s16le(struct xmms_convert_buffers *buf,
-                             void **data, int length)
-{
-    gint16 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 4; i++) {
-        gint32 tmp;
-        gint16 stmp;
-        tmp = GINT16_FROM_LE(*input);
-        input++;
-        tmp += GINT16_FROM_LE(*input);
-        input++;
-        stmp = tmp / 2;
-        *output++ = GINT16_TO_LE(stmp);
-    }
-    return length / 2;
-}
-
-static int
-convert_stereo_to_mono_s16be(struct xmms_convert_buffers *buf,
-                             void **data, int length)
-{
-    gint16 *output = *data, *input = *data;
-    int i;
-    for (i = 0; i < length / 4; i++) {
-        gint32 tmp;
-        gint16 stmp;
-        tmp = GINT16_FROM_BE(*input);
-        input++;
-        tmp += GINT16_FROM_BE(*input);
-        input++;
-        stmp = tmp / 2;
-        *output++ = GINT16_TO_BE(stmp);
-    }
-    return length / 2;
-}
-
-/**
- * xmms_convert_get_channel_func:
- * @fmt: The format of the data.
- * @output: The number of channels to output as.
- * @input: The number of channels inbound.
- *
- * Looks up the proper conversion method to use.
- *
- * Return value: A function pointer to the desired conversion function.
- **/
-convert_channel_func_t
-xmms_convert_get_channel_func(AFormat fmt, int output, int input)
-{
-    fmt = unnativize(fmt);
-
-    if (output == input)
-        return NULL;
-
-    if (input == 1 && output == 2)
-        switch (fmt) {
-        case FMT_U8:
-        case FMT_S8:
-            return convert_mono_to_stereo_8;
-        case FMT_U16_LE:
-        case FMT_U16_BE:
-        case FMT_S16_LE:
-        case FMT_S16_BE:
-            return convert_mono_to_stereo_16;
-        default:
-            g_warning("Unknown format: %d" "No conversion available.", fmt);
-            return NULL;
-        }
-    if (input == 2 && output == 1)
-        switch (fmt) {
-        case FMT_U8:
-            return convert_stereo_to_mono_u8;
-        case FMT_S8:
-            return convert_stereo_to_mono_s8;
-        case FMT_U16_LE:
-            return convert_stereo_to_mono_u16le;
-        case FMT_U16_BE:
-            return convert_stereo_to_mono_u16be;
-        case FMT_S16_LE:
-            return convert_stereo_to_mono_s16le;
-        case FMT_S16_BE:
-            return convert_stereo_to_mono_s16be;
-        default:
-            g_warning("Unknown format: %d.  "
-                      "No conversion available.", fmt);
-            return NULL;
-
-        }
-
-    g_warning("Input has %d channels, soundcard uses %d channels\n"
-              "No conversion is available", input, output);
-    return NULL;
-}
-
-
-#define RESAMPLE_STEREO(sample_type, bswap)			\
-	const int shift = sizeof (sample_type);			\
-        int i, in_samples, out_samples, x, delta;		\
-	sample_type *inptr = *data, *outptr;			\
-	guint nlen = (((length >> shift) * ofreq) / ifreq);	\
-	void *nbuf;						\
-	if (nlen == 0)						\
-		return 0;						\
-	nlen <<= shift;						\
-	if (bswap)						\
-		convert_swap_endian(NULL, data, length);	\
-	nbuf = convert_get_buffer(&buf->freq_buffer, nlen);	\
-	outptr = nbuf;						\
-	in_samples = length >> shift;				\
-        out_samples = nlen >> shift;				\
-	delta = (in_samples << 12) / out_samples;		\
-	for (x = 0, i = 0; i < out_samples; i++)		\
-	{							\
-		int x1, frac;					\
-		x1 = (x >> 12) << 12;				\
-		frac = x - x1;					\
-		*outptr++ =					\
-			((inptr[(x1 >> 12) << 1] *		\
-			  ((1<<12) - frac) +			\
-			  inptr[((x1 >> 12) + 1) << 1] *	\
-			  frac) >> 12);				\
-		*outptr++ =					\
-			((inptr[((x1 >> 12) << 1) + 1] *	\
-			  ((1<<12) - frac) +			\
-			  inptr[(((x1 >> 12) + 1) << 1) + 1] *	\
-			  frac) >> 12);				\
-		x += delta;					\
-	}							\
-	if (bswap)						\
-		convert_swap_endian(NULL, &nbuf, nlen);		\
-	*data = nbuf;						\
-	return nlen;						\
-
-
-#define RESAMPLE_MONO(sample_type, bswap)			\
-	const int shift = sizeof (sample_type) - 1;		\
-        int i, x, delta, in_samples, out_samples;		\
-	sample_type *inptr = *data, *outptr;			\
-	guint nlen = (((length >> shift) * ofreq) / ifreq);	\
-	void *nbuf;						\
-	if (nlen == 0)						\
-		return 0;					\
-	nlen <<= shift;						\
-	if (bswap)						\
-		convert_swap_endian(NULL, data, length);	\
-	nbuf = convert_get_buffer(&buf->freq_buffer, nlen);	\
-	outptr = nbuf;						\
-	in_samples = length >> shift;				\
-        out_samples = nlen >> shift;				\
-	delta = ((length >> shift) << 12) / out_samples;	\
-	for (x = 0, i = 0; i < out_samples; i++)		\
-	{							\
-		int x1, frac;					\
-		x1 = (x >> 12) << 12;				\
-		frac = x - x1;					\
-		*outptr++ =					\
-			((inptr[x1 >> 12] * ((1<<12) - frac) +	\
-			  inptr[(x1 >> 12) + 1] * frac) >> 12);	\
-		x += delta;					\
-	}							\
-	if (bswap)						\
-		convert_swap_endian(NULL, &nbuf, nlen);		\
-	*data = nbuf;						\
-	return nlen;						\
-
-static int
-convert_resample_stereo_s16ne(struct xmms_convert_buffers *buf,
-                              void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(gint16, FALSE);
-}
-
-static int
-convert_resample_stereo_s16ae(struct xmms_convert_buffers *buf,
-                              void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(gint16, TRUE);
-}
-
-static int
-convert_resample_stereo_u16ne(struct xmms_convert_buffers *buf,
-                              void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(guint16, FALSE);
-}
-
-static int
-convert_resample_stereo_u16ae(struct xmms_convert_buffers *buf,
-                              void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(guint16, TRUE);
-}
-
-static int
-convert_resample_mono_s16ne(struct xmms_convert_buffers *buf,
-                            void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(gint16, FALSE);
-}
-
-static int
-convert_resample_mono_s16ae(struct xmms_convert_buffers *buf,
-                            void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(gint16, TRUE);
-}
-
-static int
-convert_resample_mono_u16ne(struct xmms_convert_buffers *buf,
-                            void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(guint16, FALSE);
-}
-
-static int
-convert_resample_mono_u16ae(struct xmms_convert_buffers *buf,
-                            void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(guint16, TRUE);
-}
-
-static int
-convert_resample_stereo_u8(struct xmms_convert_buffers *buf,
-                           void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(guint8, FALSE);
-}
-
-static int
-convert_resample_mono_u8(struct xmms_convert_buffers *buf,
-                         void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(guint8, FALSE);
-}
-
-static int
-convert_resample_stereo_s8(struct xmms_convert_buffers *buf,
-                           void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_STEREO(gint8, FALSE);
-}
-
-static int
-convert_resample_mono_s8(struct xmms_convert_buffers *buf,
-                         void **data, int length, int ifreq, int ofreq)
-{
-    RESAMPLE_MONO(gint8, FALSE);
-}
-
-
-/**
- * xmms_convert_get_frequency_func:
- * @fmt: The format of the data.
- * @channels: The number of channels inbound.
- *
- * Looks up the proper conversion method to use.
- *
- * Return value: A function pointer to the desired conversion function.
- **/
-convert_freq_func_t
-xmms_convert_get_frequency_func(AFormat fmt, int channels)
-{
-    fmt = unnativize(fmt);
-    g_message("fmt %d, channels: %d", fmt, channels);
-
-    if (channels < 1 || channels > 2) {
-        g_warning("Unsupported number of channels: %d.  "
-                  "Resample function not available", channels);
-        return NULL;
-    }
-    if ((IS_BIG_ENDIAN && fmt == FMT_U16_BE) ||
-        (!IS_BIG_ENDIAN && fmt == FMT_U16_LE)) {
-        if (channels == 1)
-            return convert_resample_mono_u16ne;
-        else
-            return convert_resample_stereo_u16ne;
-    }
-    if ((IS_BIG_ENDIAN && fmt == FMT_S16_BE) ||
-        (!IS_BIG_ENDIAN && fmt == FMT_S16_LE)) {
-        if (channels == 1)
-            return convert_resample_mono_s16ne;
-        else
-            return convert_resample_stereo_s16ne;
-    }
-    if ((!IS_BIG_ENDIAN && fmt == FMT_U16_BE) ||
-        (IS_BIG_ENDIAN && fmt == FMT_U16_LE)) {
-        if (channels == 1)
-            return convert_resample_mono_u16ae;
-        else
-            return convert_resample_stereo_u16ae;
-    }
-    if ((!IS_BIG_ENDIAN && fmt == FMT_S16_BE) ||
-        (IS_BIG_ENDIAN && fmt == FMT_S16_LE)) {
-        if (channels == 1)
-            return convert_resample_mono_s16ae;
-        else
-            return convert_resample_stereo_s16ae;
-    }
-    if (fmt == FMT_U8) {
-        if (channels == 1)
-            return convert_resample_mono_u8;
-        else
-            return convert_resample_stereo_u8;
-    }
-    if (fmt == FMT_S8) {
-        if (channels == 1)
-            return convert_resample_mono_s8;
-        else
-            return convert_resample_stereo_s8;
-    }
-    g_warning("Resample function not available" "Format %d.", fmt);
-    return NULL;
-}
--- a/src/libaudacious/xconvert.h	Sat Jan 27 11:40:05 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- *  Copyright (C) 2003  Haavard Kvaalen <havardk@xmms.org>
- *
- *  Licensed under GNU LGPL version 2.
- */
-
-#include <audacious/plugin.h>
-
-struct xmms_convert_buffers;
-
-struct xmms_convert_buffers *xmms_convert_buffers_new(void);
-/*
- * Free the data assosiated with the buffers, without destroying the
- * context.  The context can be reused.
- */
-void xmms_convert_buffers_free(struct xmms_convert_buffers *buf);
-void xmms_convert_buffers_destroy(struct xmms_convert_buffers *buf);
-
-
-typedef int (*convert_func_t) (struct xmms_convert_buffers * buf,
-                               void **data, int length);
-typedef int (*convert_channel_func_t) (struct xmms_convert_buffers * buf,
-                                       void **data, int length);
-typedef int (*convert_freq_func_t) (struct xmms_convert_buffers * buf,
-                                    void **data, int length, int ifreq,
-                                    int ofreq);
-
-
-convert_func_t xmms_convert_get_func(AFormat output, AFormat input);
-convert_channel_func_t xmms_convert_get_channel_func(AFormat fmt,
-                                                     int output,
-                                                     int input);
-convert_freq_func_t xmms_convert_get_frequency_func(AFormat fmt,
-                                                    int channels);