Package: xmms-jackasyn
Version: 0.1-1
Severity: grave
Tags: patch
Justification: renders package unusable

on big endian machine, some input format such as ogg are not correctly
converted. the endianness check is missing from the configure.in. the
attached patch says it all.

another unrelated issue is that when skipping from a stereo file to a
mono file, the right channel remains full of the last buffer read from
the mono file and read it in loop. adding a mono_to_stereo conversion
function as found in current xmms output fixes this (see 2nd patch).

bye, paul

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: powerpc (ppc)
Kernel: Linux 2.6.9-powerpc
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)

Versions of packages xmms-jackasyn depends on:
ii  libc6                    2.3.2.ds1-20    GNU C Library: Shared libraries an
ii  libglib1.2               1.2.10-9        The GLib library of C routines
ii  libgtk1.2                1.2.10-17       The GIMP Toolkit set of widgets fo
ii  libjack0.80.0-0          0.99.0-2        JACK Audio Connection Kit (librari
ii  libjackasyn0             0.11-1          The Asynchrounous JACK Library
ii  libx11-6                 4.3.0.dfsg.1-10 X Window System protocol client li
ii  libxext6                 4.3.0.dfsg.1-10 X Window System miscellaneous exte
ii  libxi6                   4.3.0.dfsg.1-10 X Window System Input extension li
ii  xlibs                    4.3.0.dfsg.1-10 X Keyboard Extension (XKB) configu
ii  xmms                     1.2.10-2        Versatile X audio player that look

-- no debconf information
--- ../xmms-jackasyn-0.1/configure.in	2002-10-30 17:24:26.000000000 +0000
+++ xmms-jackasyn-0.1/configure.in	2005-01-24 14:05:58.000000000 +0000
@@ -12,6 +12,7 @@
 AC_PROG_CC
 AC_PROG_INSTALL
 
+AC_C_BIGENDIAN
 dnl Checks for header files.
 AC_STDC_HEADERS
 AC_CHECK_HEADERS(fcntl.h sys/time.h)
--- ../xmms-jackasyn-0.1/audio.c	2002-10-30 18:11:37.000000000 +0000
+++ xmms-jackasyn-0.1/audio.c	2005-01-24 15:37:01.254287808 +0000
@@ -38,6 +38,7 @@
 static gboolean realtime, select_works;
 
 static int (*jackxmms_convert_func)(void **data, int length);
+static int (*jackxmms_stereo_convert_func)(void **data, int length, int fmt);
 
 struct format_info {
 	union {
@@ -295,6 +296,10 @@
 	if (jackxmms_convert_func != NULL)
 		length = jackxmms_convert_func(&data, length);
 
+	if (jackxmms_stereo_convert_func != NULL)
+		length = jackxmms_stereo_convert_func(&data, length,
+						 output.format.oss);
+
 	if (effect.frequency == output.frequency)
 		output_bytes += write_all(fd, data, length);
 	else
@@ -478,7 +483,7 @@
 		close(fd);
 	}
 	g_free(device_name);
-	jackxmms_get_convert_buffer(0);
+	jackxmms_free_convert_buffer();
 	wr_index = 0;
 	rd_index = 0;
 }
@@ -614,6 +619,11 @@
 	/* FIXME: Handle mono/stereo only soundcards */
 	stereo = output.channels - 1;
 	ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
+	output.channels = stereo + 1;
+
+	jackxmms_stereo_convert_func = jackxmms_get_stereo_convert_func(output.channels,
+							      effect.channels);
+	
 	if (ioctl(fd, SNDCTL_DSP_SPEED, &output.frequency) == -1)
 		g_warning("SNDCTL_DSP_SPEED ioctl failed: %s", strerror(errno));
 
--- ../xmms-jackasyn-0.1/convert.c	2002-10-15 11:55:20.000000000 +0100
+++ xmms-jackasyn-0.1/convert.c	2005-01-23 13:13:57.000000000 +0000
@@ -18,19 +18,29 @@
 
 #include "jack.h"
 
-void* jackxmms_get_convert_buffer(size_t size)
+struct buffer {
+	void *buffer;
+	int size;
+} format_buffer, stereo_buffer;
+
+
+static void* jackxmms_get_convert_buffer(struct buffer *buffer, size_t size)
 {
-	static size_t length;
-	static void *buffer;
+	if (size > 0 && size <= buffer->size)
+		return buffer->buffer;
 
-	if (size > 0 && size <= length)
-		return buffer;
+	buffer->size = size;
+	buffer->buffer = g_realloc(buffer->buffer, size);
+	return buffer->buffer;
+}
 
-	length = size;
-	buffer = g_realloc(buffer, size);
-	return buffer;
+void jackxmms_free_convert_buffer(void)
+{
+	jackxmms_get_convert_buffer(&format_buffer, 0);
+	jackxmms_get_convert_buffer(&stereo_buffer, 0);
 }
 
+
 static int convert_swap_endian(void **data, int length)
 {
 	guint16 *ptr = *data;
@@ -131,7 +141,7 @@
 	guint8 *input = *data;
 	guint16 *output;
 	int i;
-	*data = jackxmms_get_convert_buffer(length * 2);
+	*data = jackxmms_get_convert_buffer(&format_buffer, length * 2);
 	output = *data;
 	for (i = 0; i < length; i++)
 		*output++ = *input++ << 8;
@@ -144,7 +154,7 @@
 	guint8 *input = *data;
 	guint16 *output;
 	int i;
-	*data = jackxmms_get_convert_buffer(length * 2);
+	*data = jackxmms_get_convert_buffer(&format_buffer, length * 2);
 	output = *data;
 	for (i = 0; i < length; i++)
 		*output++ = (*input++ << 8) ^ (1 << 15);
@@ -158,7 +168,7 @@
 	guint8 *input = *data;
 	guint16 *output;
 	int i;
-	*data = jackxmms_get_convert_buffer(length * 2);
+	*data = jackxmms_get_convert_buffer(&format_buffer, length * 2);
 	output = *data;
 	for (i = 0; i < length; i++)
 		*output++ = *input++;
@@ -171,7 +181,7 @@
 	guint8 *input = *data;
 	guint16 *output;
 	int i;
-	*data = jackxmms_get_convert_buffer(length * 2);
+	*data = jackxmms_get_convert_buffer(&format_buffer, length * 2);
 	output = *data;
 	for (i = 0; i < length; i++)
 		*output++ = *input++ ^ (1 << 7);
@@ -284,3 +294,149 @@
 		  "Input: %d; Output %d.", input, output);
 	return NULL;
 }
+
+static int convert_mono_to_stereo(void **data, int length, int fmt)
+{
+	int i;
+	void *outbuf = jackxmms_get_convert_buffer(&stereo_buffer, length * 2);
+
+	if (fmt == AFMT_U8 || fmt ==  AFMT_S8)
+	{
+		guint8 *output = outbuf, *input = *data;
+		for (i = 0; i < length; i++)
+		{
+			*output++ = *input;
+			*output++ = *input;
+			input++;
+		}
+	}
+	else 
+	{
+		guint16 *output = outbuf, *input = *data;
+		for (i = 0; i < length / 2; i++)
+		{
+			*output++ = *input;
+			*output++ = *input;
+			input++;
+		}
+	}
+	*data = outbuf;
+
+	return length * 2;
+}
+
+static int convert_stereo_to_mono(void **data, int length, int fmt)
+{
+	int i;
+
+	switch (fmt)
+	{
+		case AFMT_U8:
+		{
+			guint8 *output = *data, *input = *data;
+			for (i = 0; i < length / 2; i++)
+			{
+				guint16 tmp;
+				tmp = *input++;
+				tmp += *input++;
+				*output++ = tmp / 2;
+			}
+		}
+		break;
+		case AFMT_S8:
+		{
+			gint8 *output = *data, *input = *data;
+			for (i = 0; i < length / 2; i++)
+			{
+				gint16 tmp;
+				tmp = *input++;
+				tmp += *input++;
+				*output++ = tmp / 2;
+			}
+		}
+		break;
+		case AFMT_U16_LE:
+		{
+			guint16 *output = *data, *input = *data;
+			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);
+			}
+		}
+		break;
+		case AFMT_U16_BE:
+		{
+			guint16 *output = *data, *input = *data;
+			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);
+			}
+		}
+		break;
+		case AFMT_S16_LE:
+		{
+			gint16 *output = *data, *input = *data;
+			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);
+			}
+		}
+		break;
+		case AFMT_S16_BE:
+		{
+			gint16 *output = *data, *input = *data;
+			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);
+			}
+		}
+		break;
+		default:
+			g_error("unknown format");
+	}
+
+	return length / 2;
+}
+
+int (*jackxmms_get_stereo_convert_func(int output, int input))(void **, int, int)
+{
+	if (output == input)
+		return NULL;
+
+	if (input == 1 && output == 2)
+		return convert_mono_to_stereo;
+	if (input == 2 && output == 1)
+		return convert_stereo_to_mono;
+
+	g_warning("Input has %d channels, soundcard uses %d channels\n"
+		  "No conversion is available", input, output);
+	return NULL;
+}
--- ../xmms-jackasyn-0.1/jack.h	2002-10-15 11:55:23.000000000 +0100
+++ xmms-jackasyn-0.1/jack.h	2005-01-23 13:29:51.000000000 +0000
@@ -78,8 +78,9 @@
 int jackxmms_get_written_time(void);
 void jackxmms_set_audio_params(void);
 
-void* jackxmms_get_convert_buffer(size_t size);
+void jackxmms_free_convert_buffer(void);
 int (*jackxmms_get_convert_func(int output, int input))(void **, int);
+int (*jackxmms_get_stereo_convert_func(int output, int input))(void **, int, int);
 
 #define DEV_DSP "/dev/dsp"
 #define DEV_MIXER "/dev/mixer"

Reply via email to