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"