Mercurial > audlegacy-plugins
changeset 2696:87c4bc8e8ec6
Remove legacy audio format conversion from OSS plugin. Core aka libSAD
should be doing this now, I guess.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 06 Jun 2008 15:30:41 +0300 |
parents | c2861c84f850 |
children | 7d6d9eebb826 ca2e5680b74e |
files | src/OSS/Makefile src/OSS/OSS.h src/OSS/audio.c src/OSS/convert.c |
diffstat | 4 files changed, 9 insertions(+), 639 deletions(-) [+] |
line wrap: on
line diff
--- a/src/OSS/Makefile Fri Jun 06 15:02:21 2008 +0300 +++ b/src/OSS/Makefile Fri Jun 06 15:30:41 2008 +0300 @@ -3,8 +3,7 @@ SRCS = OSS.c \ mixer.c \ configure.c \ - audio.c \ - convert.c + audio.c include ../../buildsys.mk include ../../extra.mk
--- a/src/OSS/OSS.h Fri Jun 06 15:02:21 2008 +0300 +++ b/src/OSS/OSS.h Fri Jun 06 15:30:41 2008 +0300 @@ -65,12 +65,6 @@ int oss_get_output_time(void); int oss_get_written_time(void); void oss_set_audio_params(void); - -void oss_free_convert_buffer(void); -int (*oss_get_convert_func(int output, int input)) (void **, int); -int (*oss_get_stereo_convert_func(int output, int input)) (void **, int, - int); - void oss_tell(AFormat * fmt, gint * rate, gint * nch); #endif
--- a/src/OSS/audio.c Fri Jun 06 15:02:21 2008 +0300 +++ b/src/OSS/audio.c Fri Jun 06 15:30:41 2008 +0300 @@ -48,9 +48,6 @@ static GThread *buffer_thread; static gboolean select_works; -static int (*oss_convert_func) (void **data, int length); -static int (*oss_stereo_convert_func) (void **data, int length, int fmt); - struct format_info { union { AFormat xmms; @@ -69,13 +66,6 @@ struct format_info input; /* - * The format we get from the effect plugin. - * This will be different from input if the effect plugin does - * some kind of format conversion. - */ -struct format_info effect; - -/* * The format of the data we actually send to the soundcard. * This might be different from effect if we need to resample or do * some other format conversion. @@ -95,9 +85,6 @@ } -static gint oss_downsample(gpointer ob, guint length, guint speed, - guint espeed); - static int oss_calc_bitrate(int oss_fmt, int rate, int channels) { @@ -158,18 +145,14 @@ static void oss_setup_format(AFormat fmt, int rate, int nch) { - effect.format.xmms = fmt; - effect.frequency = rate; - effect.channels = nch; - effect.bps = oss_calc_bitrate(oss_get_format(fmt), rate, nch); - + output.bps = oss_calc_bitrate(oss_get_format(fmt), rate, nch); output.format.oss = oss_get_format(fmt); output.frequency = rate; output.channels = nch; fragsize = 0; - while ((1L << fragsize) < effect.bps / 25) + while ((1L << fragsize) < output.bps / 25) fragsize++; fragsize--; @@ -187,7 +170,7 @@ { if (!going) return 0; - return (written * 1000) / effect.bps; + return (written * 1000) / output.bps; } gint @@ -241,12 +224,12 @@ return (buffer_size - (wr_index - rd_index)) - device_buffer_size - 1; } -static inline ssize_t -write_all(int fd, const void *buf, size_t count) +static void +oss_write_audio(gpointer data, size_t length) { size_t done = 0; do { - ssize_t n = write(fd, (gchar *) buf + done, count - done); + ssize_t n = write(fd, (gchar *) data + done, length - done); if (n == -1) { if (errno == EINTR) continue; @@ -254,161 +237,9 @@ break; } done += n; - } while (count > done); - - return done; -} - -static void -oss_write_audio(gpointer data, int length) -{ - if (oss_convert_func != NULL) - length = oss_convert_func(&data, length); - - if (oss_stereo_convert_func != NULL) - length = oss_stereo_convert_func(&data, length, output.format.oss); - - if (effect.frequency == output.frequency) - output_bytes += write_all(fd, data, length); - else - output_bytes += oss_downsample(data, length, - effect.frequency, output.frequency); -} - -static void -swap_endian(guint16 * data, int length) -{ - int i; - for (i = 0; i < length; i += 2, data++) - *data = GUINT16_SWAP_LE_BE(*data); -} - -#define NOT_NATIVE_ENDIAN ((IS_BIG_ENDIAN && \ - (output.format.oss == AFMT_S16_LE || \ - output.format.oss == AFMT_U16_LE)) || \ - (!IS_BIG_ENDIAN && \ - (output.format.oss == AFMT_S16_BE || \ - output.format.oss == AFMT_U16_BE))) - + } while (length > done); -#define RESAMPLE_STEREO(sample_type) \ -do { \ - const gint shift = sizeof (sample_type); \ - gint i, in_samples, out_samples, x, delta; \ - sample_type *inptr = (sample_type *)ob, *outptr; \ - guint nlen = (((length >> shift) * espeed) / speed); \ - if (nlen == 0) \ - break; \ - nlen <<= shift; \ - if (NOT_NATIVE_ENDIAN) \ - swap_endian(ob, length); \ - if(nlen > nbuffer_size) \ - { \ - nbuffer = g_realloc(nbuffer, nlen); \ - nbuffer_size = nlen; \ - } \ - outptr = (sample_type *)nbuffer; \ - in_samples = length >> shift; \ - out_samples = nlen >> shift; \ - delta = (in_samples << 12) / out_samples; \ - for (x = 0, i = 0; i < out_samples; i++) \ - { \ - gint x1, frac; \ - x1 = (x >> 12) << 12; \ - frac = x - x1; \ - *outptr++ = \ - (sample_type) \ - ((inptr[(x1 >> 12) << 1] * \ - ((1<<12) - frac) + \ - inptr[((x1 >> 12) + 1) << 1] * \ - frac) >> 12); \ - *outptr++ = \ - (sample_type) \ - ((inptr[((x1 >> 12) << 1) + 1] * \ - ((1<<12) - frac) + \ - inptr[(((x1 >> 12) + 1) << 1) + 1] * \ - frac) >> 12); \ - x += delta; \ - } \ - if (NOT_NATIVE_ENDIAN) \ - swap_endian(nbuffer, nlen); \ - w = write_all(fd, nbuffer, nlen); \ -} while (0) - - -#define RESAMPLE_MONO(sample_type) \ -do { \ - const gint shift = sizeof (sample_type) - 1; \ - gint i, x, delta, in_samples, out_samples; \ - sample_type *inptr = (sample_type *)ob, *outptr; \ - guint nlen = (((length >> shift) * espeed) / speed); \ - if (nlen == 0) \ - break; \ - nlen <<= shift; \ - if (NOT_NATIVE_ENDIAN) \ - swap_endian(ob, length); \ - if(nlen > nbuffer_size) \ - { \ - nbuffer = g_realloc(nbuffer, nlen); \ - nbuffer_size = nlen; \ - } \ - outptr = (sample_type *)nbuffer; \ - in_samples = length >> shift; \ - out_samples = nlen >> shift; \ - delta = ((length >> shift) << 12) / out_samples; \ - for (x = 0, i = 0; i < out_samples; i++) \ - { \ - gint x1, frac; \ - x1 = (x >> 12) << 12; \ - frac = x - x1; \ - *outptr++ = \ - (sample_type) \ - ((inptr[x1 >> 12] * ((1<<12) - frac) + \ - inptr[(x1 >> 12) + 1] * frac) >> 12); \ - x += delta; \ - } \ - if (NOT_NATIVE_ENDIAN) \ - swap_endian(nbuffer, nlen); \ - w = write_all(fd, nbuffer, nlen); \ -} while (0) - - -static gint -oss_downsample(gpointer ob, guint length, guint speed, guint espeed) -{ - guint w = 0; - static gpointer nbuffer = NULL; - static guint nbuffer_size = 0; - - switch (output.format.oss) { - case AFMT_S16_BE: - case AFMT_S16_LE: - if (output.channels == 2) - RESAMPLE_STEREO(gint16); - else - RESAMPLE_MONO(gint16); - break; - case AFMT_U16_BE: - case AFMT_U16_LE: - if (output.channels == 2) - RESAMPLE_STEREO(guint16); - else - RESAMPLE_MONO(guint16); - break; - case AFMT_S8: - if (output.channels == 2) - RESAMPLE_STEREO(gint8); - else - RESAMPLE_MONO(gint8); - break; - case AFMT_U8: - if (output.channels == 2) - RESAMPLE_STEREO(guint8); - else - RESAMPLE_MONO(guint8); - break; - } - return w; + output_bytes += done; } void @@ -438,7 +269,6 @@ g_thread_join(buffer_thread); g_free(device_name); - oss_free_convert_buffer(); wr_index = 0; rd_index = 0; @@ -554,19 +384,12 @@ ioctl(fd, SNDCTL_DSP_STEREO, &stereo); output.channels = stereo + 1; - oss_stereo_convert_func = oss_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)); if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blk_size) == -1) blk_size = 1L << fragsize; - oss_convert_func = - oss_get_convert_func(output.format.oss, - oss_get_format(effect.format.xmms)); - /* * Stupid hack to find out if the driver support selects, some * drivers won't work properly without a select and some won't
--- a/src/OSS/convert.c Fri Jun 06 15:02:21 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2001 Haavard Kvaalen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "OSS.h" - -struct buffer { - void *buffer; - int size; -} format_buffer, stereo_buffer; - - -static void * -oss_get_convert_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; -} - -void -oss_free_convert_buffer(void) -{ - oss_get_convert_buffer(&format_buffer, 0); - oss_get_convert_buffer(&stereo_buffer, 0); -} - - -static int -convert_swap_endian(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(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(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(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(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(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(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(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(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(void **data, int length) -{ - guint8 *input = *data; - guint16 *output; - int i; - *data = oss_get_convert_buffer(&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(void **data, int length) -{ - guint8 *input = *data; - guint16 *output; - int i; - *data = oss_get_convert_buffer(&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(void **data, int length) -{ - guint8 *input = *data; - guint16 *output; - int i; - *data = oss_get_convert_buffer(&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(void **data, int length) -{ - guint8 *input = *data; - guint16 *output; - int i; - *data = oss_get_convert_buffer(&format_buffer, length * 2); - output = *data; - for (i = 0; i < length; i++) - *output++ = *input++ ^ (1 << 7); - - return i * 2; -} - -int (*oss_get_convert_func(int output, int input)) (void **, int) { - if (output == input) - return NULL; - - if ((output == AFMT_U16_BE && input == AFMT_U16_LE) || - (output == AFMT_U16_LE && input == AFMT_U16_BE) || - (output == AFMT_S16_BE && input == AFMT_S16_LE) || - (output == AFMT_S16_LE && input == AFMT_S16_BE)) - return convert_swap_endian; - - if ((output == AFMT_U16_BE && input == AFMT_S16_BE) || - (output == AFMT_U16_LE && input == AFMT_S16_LE) || - (output == AFMT_S16_BE && input == AFMT_U16_BE) || - (output == AFMT_S16_LE && input == AFMT_U16_LE)) - return convert_swap_sign16; - - if ((IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_S16_LE) || - (output == AFMT_S16_BE && input == AFMT_U16_LE))) || - (!IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_S16_BE) || - (output == AFMT_S16_LE && input == AFMT_U16_BE)))) - return convert_swap_sign_and_endian_to_native; - - if ((!IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_S16_LE) || - (output == AFMT_S16_BE && input == AFMT_U16_LE))) || - (IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_S16_BE) || - (output == AFMT_S16_LE && input == AFMT_U16_BE)))) - return convert_swap_sign_and_endian_to_alien; - - if ((IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_U16_BE) || - (output == AFMT_S8 && input == AFMT_S16_BE))) || - (!IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_U16_LE) || - (output == AFMT_S8 && input == AFMT_S16_LE)))) - return convert_to_8_native_endian; - - if ((IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_S16_BE) || - (output == AFMT_S8 && input == AFMT_U16_BE))) || - (!IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_S16_LE) || - (output == AFMT_S8 && input == AFMT_U16_LE)))) - return convert_to_8_native_endian_swap_sign; - - if ((!IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_U16_BE) || - (output == AFMT_S8 && input == AFMT_S16_BE))) || - (IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_U16_LE) || - (output == AFMT_S8 && input == AFMT_S16_LE)))) - return convert_to_8_alien_endian; - - if ((!IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_S16_BE) || - (output == AFMT_S8 && input == AFMT_U16_BE))) || - (IS_BIG_ENDIAN && - ((output == AFMT_U8 && input == AFMT_S16_LE) || - (output == AFMT_S8 && input == AFMT_U16_LE)))) - return convert_to_8_alien_endian_swap_sign; - - if ((output == AFMT_U8 && input == AFMT_S8) || - (output == AFMT_S8 && input == AFMT_U8)) - return convert_swap_sign8; - - if ((IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_U8) || - (output == AFMT_S16_BE && input == AFMT_S8))) || - (!IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_U8) || - (output == AFMT_S16_LE && input == AFMT_S8)))) - return convert_to_16_native_endian; - - if ((IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_S8) || - (output == AFMT_S16_BE && input == AFMT_U8))) || - (!IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_S8) || - (output == AFMT_S16_LE && input == AFMT_U8)))) - return convert_to_16_native_endian_swap_sign; - - if ((!IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_U8) || - (output == AFMT_S16_BE && input == AFMT_S8))) || - (IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_U8) || - (output == AFMT_S16_LE && input == AFMT_S8)))) - return convert_to_16_alien_endian; - - if ((!IS_BIG_ENDIAN && - ((output == AFMT_U16_BE && input == AFMT_S8) || - (output == AFMT_S16_BE && input == AFMT_U8))) || - (IS_BIG_ENDIAN && - ((output == AFMT_U16_LE && input == AFMT_S8) || - (output == AFMT_S16_LE && input == AFMT_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(void **data, int length, int fmt) -{ - int i; - void *outbuf = oss_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 (*oss_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; -}