# HG changeset patch # User nenolod # Date 1157652400 25200 # Node ID 09905c29250d808e99483c9797481e92b7e4fbcc # Parent a3a6f657f895a8dabf9e9d27bb93afde1599cf41 [svn] - remove CoreAudio plugin, and try again :P diff -r a3a6f657f895 -r 09905c29250d ChangeLog --- a/ChangeLog Thu Sep 07 09:11:46 2006 -0700 +++ b/ChangeLog Thu Sep 07 11:06:40 2006 -0700 @@ -1,3 +1,14 @@ +2006-09-07 16:11:46 +0000 William Pitcock + revision [2201] + - fork the OSS plugin for CoreAudio work + + + Changes: Modified: + +0 -17 trunk/Plugins/Output/CoreAudio/Makefile.in + +30 -39 trunk/Plugins/Output/CoreAudio/OSS.h + +0 -1695 trunk/Plugins/Output/CoreAudio/soundcard.h + + 2006-09-07 05:10:19 +0000 William Pitcock revision [2199] - kludge for libintl borkenness diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/OSS.c --- a/Plugins/Output/CoreAudio/OSS.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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" - -#include -#include -#include - -OutputPlugin oss_op = { - NULL, - NULL, - NULL, /* Description */ - oss_init, - oss_cleanup, - oss_about, - oss_configure, - oss_get_volume, - oss_set_volume, - oss_open, - oss_write, - oss_close, - oss_flush, - oss_pause, - oss_free, - oss_playing, - oss_get_output_time, - oss_get_written_time, - oss_tell -}; - -OutputPlugin * -get_oplugin_info(void) -{ - oss_op.description = g_strdup_printf(_("OSS Output Plugin")); - return &oss_op; -} - - -void oss_cleanup(void) -{ - g_free(oss_op.description); - oss_op.description = NULL; - - if (oss_cfg.alt_audio_device) { - free(oss_cfg.alt_audio_device); - oss_cfg.alt_audio_device = NULL; - } - - if (oss_cfg.alt_mixer_device) { - free(oss_cfg.alt_mixer_device); - oss_cfg.alt_mixer_device = NULL; - } -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/OSS.h --- a/Plugins/Output/CoreAudio/OSS.h Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2006 William Pitcock - * - * 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 COREAUDIO_H -#define COREAUDIO_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include - -#include "audacious/plugin.h" - -#define IS_BIG_ENDIAN (G_BYTE_ORDER == G_BIG_ENDIAN) - -extern OutputPlugin op; - -struct CoreAudioState { - -}; - -void ca_init(void); -void ca_cleanup(void); -void ca_about(void); -void ca_configure(void); - -void ca_get_volume(int *l, int *r); -void ca_set_volume(int l, int r); - -int ca_playing(void); -int ca_free(void); -void ca_write(void *ptr, int length); -void ca_close(void); -void ca_flush(int time); -void ca_pause(short p); -int ca_open(AFormat fmt, int rate, int nch); -int ca_get_output_time(void); -int ca_get_written_time(void); -void ca_set_audio_params(void); - -void ca_free_convert_buffer(void); -int (*ca_get_convert_func(int output, int input)) (void **, int); -int (*ca_get_stereo_convert_func(int output, int input)) (void **, int, - int); - -void ca_tell(AFormat * fmt, gint * rate, gint * nch); - -#endif diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/about.c --- a/Plugins/Output/CoreAudio/about.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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" - -#include -#include -#include - -#include - - -void -oss_about(void) -{ - static GtkWidget *dialog; - - if (dialog != NULL) - return; - - dialog = xmms_show_message(_("About OSS Driver"), - _("Audacious OSS Driver\n\n " - "This program is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n" - "\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n" - "\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n" - "USA."), _("Ok"), FALSE, NULL, NULL); - g_signal_connect(G_OBJECT(dialog), "destroy", - G_CALLBACK(gtk_widget_destroyed), &dialog); -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/audio.c --- a/Plugins/Output/CoreAudio/audio.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,723 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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 -#include -#include - -#include -#include -#include -#include -#include - -#include "OSS.h" - - -#define NFRAGS 32 - -static gint fd = 0; -static char *buffer; -static gboolean going, prebuffer, paused, unpause, do_pause, remove_prebuffer; -static gint device_buffer_used, buffer_size, prebuffer_size, blk_size; -static gint rd_index = 0, wr_index = 0; -static gint output_time_offset = 0; -static guint64 written = 0, output_bytes = 0; -static gint flush; -static gint fragsize, device_buffer_size; -static gchar *device_name; -static GThread *buffer_thread; -static gboolean realtime, 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; - int oss; - } format; - int frequency; - int channels; - int bps; -}; - - -/* - * The format of the data from the input plugin - * This will never change during a song. - */ -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. - */ -struct format_info output; - - -static void -oss_calc_device_buffer_used(void) -{ - audio_buf_info buf_info; - if (paused) - device_buffer_used = 0; - else if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &buf_info)) - device_buffer_used = - (buf_info.fragstotal * buf_info.fragsize) - buf_info.bytes; -} - - -static gint oss_downsample(gpointer ob, guint length, guint speed, - guint espeed); - -static int -oss_calc_bitrate(int oss_fmt, int rate, int channels) -{ - int bitrate = rate * channels; - - if (oss_fmt == AFMT_U16_BE || oss_fmt == AFMT_U16_LE || - oss_fmt == AFMT_S16_BE || oss_fmt == AFMT_S16_LE) - bitrate *= 2; - - return bitrate; -} - -static int -oss_get_format(AFormat fmt) -{ - int format = 0; - - switch (fmt) { - case FMT_U8: - format = AFMT_U8; - break; - case FMT_S8: - format = AFMT_S8; - break; - case FMT_U16_LE: - format = AFMT_U16_LE; - break; - case FMT_U16_BE: - format = AFMT_U16_BE; - break; - case FMT_U16_NE: -#if (G_BYTE_ORDER == G_BIG_ENDIAN) - format = AFMT_U16_BE; -#else - format = AFMT_U16_LE; -#endif - break; - case FMT_S16_LE: - format = AFMT_S16_LE; - break; - case FMT_S16_BE: - format = AFMT_S16_BE; - break; - case FMT_S16_NE: -#if (G_BYTE_ORDER == G_BIG_ENDIAN) - format = AFMT_S16_BE; -#else - format = AFMT_S16_LE; -#endif - break; - } - - return format; -} - -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.format.oss = oss_get_format(fmt); - output.frequency = rate; - output.channels = nch; - - - fragsize = 0; - while ((1L << fragsize) < effect.bps / 25) - fragsize++; - fragsize--; - - device_buffer_size = ((1L << fragsize) * (NFRAGS + 1)); - - oss_set_audio_params(); - - output.bps = oss_calc_bitrate(output.format.oss, output.frequency, - output.channels); -} - - -gint -oss_get_written_time(void) -{ - if (!going) - return 0; - return (written * 1000) / effect.bps; -} - -gint -oss_get_output_time(void) -{ - guint64 bytes; - - if (!fd || !going) - return 0; - - if (realtime) - oss_calc_device_buffer_used(); - bytes = output_bytes < device_buffer_used ? - 0 : output_bytes - device_buffer_used; - - return output_time_offset + ((bytes * 1000) / output.bps); -} - -static int -oss_used(void) -{ - if (realtime) - return 0; - else { - if (wr_index >= rd_index) - return wr_index - rd_index; - return buffer_size - (rd_index - wr_index); - } -} - -gint -oss_playing(void) -{ - if (!going) - return 0; - if (realtime) - oss_calc_device_buffer_used(); - if (!oss_used() && (device_buffer_used - (3 * blk_size)) <= 0) - return FALSE; - - return TRUE; -} - -gint -oss_free(void) -{ - if (!realtime) { - if (remove_prebuffer && prebuffer) { - prebuffer = FALSE; - remove_prebuffer = FALSE; - } - if (prebuffer) - remove_prebuffer = TRUE; - - if (rd_index > wr_index) - return (rd_index - wr_index) - device_buffer_size - 1; - return (buffer_size - (wr_index - rd_index)) - device_buffer_size - 1; - } - else if (paused) - return 0; - else - return 1000000; -} - -static inline ssize_t -write_all(int fd, const void *buf, size_t count) -{ - size_t done = 0; - do { - ssize_t n = write(fd, (gchar *) buf + done, count - done); - if (n == -1) { - if (errno == EINTR) - continue; - else - break; - } - done += n; - } while (count > done); - - return done; -} - -static void -oss_write_audio(gpointer data, int length) -{ - - audio_buf_info abuf_info; - AFormat new_format; - int new_frequency, new_channels; - EffectPlugin *ep; - - new_format = input.format.xmms; - new_frequency = input.frequency; - new_channels = input.channels; - - - ep = get_current_effect_plugin(); - if (effects_enabled() && ep && ep->query_format) { - ep->query_format(&new_format, &new_frequency, &new_channels); - } - - if (new_format != effect.format.xmms || - new_frequency != effect.frequency || - new_channels != effect.channels) { - output_time_offset += (output_bytes * 1000) / output.bps; - output_bytes = 0; - close(fd); - fd = open(device_name, O_WRONLY); - oss_setup_format(new_format, new_frequency, new_channels); - } - if (effects_enabled() && ep && ep->mod_samples) - length = ep->mod_samples(&data, length, - input.format.xmms, - input.frequency, input.channels); - if (realtime && !ioctl(fd, SNDCTL_DSP_GETOSPACE, &abuf_info)) { - while (abuf_info.bytes < length) { - xmms_usleep(10000); - if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &abuf_info)) - break; - } - } - - 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))) - - -#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; -} - -void -oss_write(gpointer ptr, int length) -{ - int cnt, off = 0; - - if (!realtime) { - remove_prebuffer = FALSE; - - written += length; - while (length > 0) { - cnt = MIN(length, buffer_size - wr_index); - memcpy(buffer + wr_index, (char *) ptr + off, cnt); - wr_index = (wr_index + cnt) % buffer_size; - length -= cnt; - off += cnt; - } - } - else { - if (paused) - return; - oss_write_audio(ptr, length); - written += length; - } -} - -void -oss_close(void) -{ - if (!going) - return; - going = 0; - if (!realtime) - g_thread_join(buffer_thread); - else { - ioctl(fd, SNDCTL_DSP_RESET, 0); - close(fd); - } - g_free(device_name); - oss_free_convert_buffer(); - wr_index = 0; - rd_index = 0; -} - -void -oss_flush(gint time) -{ - if (!realtime) { - flush = time; - while (flush != -1) - xmms_usleep(10000); - } - else { - ioctl(fd, SNDCTL_DSP_RESET, 0); - close(fd); - fd = open(device_name, O_WRONLY); - oss_set_audio_params(); - output_time_offset = time; - written = ((guint64) time * input.bps) / 1000; - output_bytes = 0; - } -} - -void -oss_pause(short p) -{ - if (!realtime) { - if (p == TRUE) - do_pause = TRUE; - else - unpause = TRUE; - } - else - paused = p; - -} - -gpointer -oss_loop(gpointer arg) -{ - gint length, cnt; - fd_set set; - struct timeval tv; - - while (going) { - if (oss_used() > prebuffer_size) - prebuffer = FALSE; - if (oss_used() > 0 && !paused && !prebuffer) { - tv.tv_sec = 0; - tv.tv_usec = 10000; - FD_ZERO(&set); - FD_SET(fd, &set); - if (!select_works || (select(fd + 1, NULL, &set, NULL, &tv) > 0)) { - length = MIN(blk_size, oss_used()); - while (length > 0) { - cnt = MIN(length, buffer_size - rd_index); - oss_write_audio(buffer + rd_index, cnt); - rd_index = (rd_index + cnt) % buffer_size; - length -= cnt; - } - if (!oss_used()) - ioctl(fd, SNDCTL_DSP_POST, 0); - } - } - else - xmms_usleep(10000); - oss_calc_device_buffer_used(); - if (do_pause && !paused) { - do_pause = FALSE; - paused = TRUE; - /* - * We lose some data here that is sent to the - * soundcard, but not yet played. I don't - * think this is worth fixing. - */ - ioctl(fd, SNDCTL_DSP_RESET, 0); - } - else if (unpause && paused) { - unpause = FALSE; - close(fd); - fd = open(device_name, O_WRONLY); - oss_set_audio_params(); - paused = FALSE; - } - - if (flush != -1) { - /* - * This close and open is a work around of a - * bug that exists in some drivers which cause - * the driver to get fucked up by a reset - */ - - ioctl(fd, SNDCTL_DSP_RESET, 0); - close(fd); - fd = open(device_name, O_WRONLY); - oss_set_audio_params(); - output_time_offset = flush; - written = ((guint64) flush * input.bps) / 1000; - rd_index = wr_index = output_bytes = 0; - flush = -1; - prebuffer = TRUE; - } - - } - - ioctl(fd, SNDCTL_DSP_RESET, 0); - close(fd); - g_free(buffer); - return NULL; -} - -void -oss_set_audio_params(void) -{ - int frag, stereo, ret; - struct timeval tv; - fd_set set; - - ioctl(fd, SNDCTL_DSP_RESET, 0); - frag = (NFRAGS << 16) | fragsize; - ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag); - /* - * Set the stream format. This ioctl() might fail, but should - * return a format that works if it does. - */ - ioctl(fd, SNDCTL_DSP_SETFMT, &output.format.oss); - if (ioctl(fd, SNDCTL_DSP_SETFMT, &output.format.oss) == -1) - g_warning("SNDCTL_DSP_SETFMT ioctl failed: %s", strerror(errno)); - - stereo = output.channels - 1; - 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 - * work with a select :/ - */ - - tv.tv_sec = 0; - tv.tv_usec = 50000; - FD_ZERO(&set); - FD_SET(fd, &set); - ret = select(fd + 1, NULL, &set, NULL, &tv); - if (ret > 0) - select_works = TRUE; - else - select_works = FALSE; -} - -gint -oss_open(AFormat fmt, gint rate, gint nch) -{ - - if (oss_cfg.use_alt_audio_device && oss_cfg.alt_audio_device) - device_name = g_strdup(oss_cfg.alt_audio_device); - else { - if (oss_cfg.audio_device > 0) - device_name = - g_strdup_printf("%s%d", DEV_DSP, oss_cfg.audio_device); - else - device_name = g_strdup(DEV_DSP); - } - - fd = open(device_name, O_WRONLY); - - if (fd == -1) { - g_warning("oss_open(): Failed to open audio device (%s): %s", - device_name, strerror(errno)); - g_free(device_name); - return 0; - } - - input.format.xmms = fmt; - input.frequency = rate; - input.channels = nch; - input.bps = oss_calc_bitrate(oss_get_format(fmt), rate, nch); - - oss_setup_format(fmt, rate, nch); - - realtime = xmms_check_realtime_priority(); - - if (!realtime) { - buffer_size = (oss_cfg.buffer_size * input.bps) / 1000; - if (buffer_size < 8192) - buffer_size = 8192; - prebuffer_size = (buffer_size * oss_cfg.prebuffer) / 100; - if (buffer_size - prebuffer_size < 4096) - prebuffer_size = buffer_size - 4096; - - buffer_size += device_buffer_size; - buffer = g_malloc0(buffer_size); - } - flush = -1; - prebuffer = TRUE; - wr_index = rd_index = output_time_offset = written = output_bytes = 0; - paused = FALSE; - do_pause = FALSE; - unpause = FALSE; - remove_prebuffer = FALSE; - - going = 1; - if (!realtime) - buffer_thread = g_thread_create(oss_loop, NULL, TRUE, NULL); - return 1; -} - -void oss_tell(AFormat * fmt, gint * rate, gint * nch) -{ - (*fmt) = input.format.xmms; - (*rate) = input.frequency; - (*nch) = input.channels; -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/configure.c --- a/Plugins/Output/CoreAudio/configure.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,375 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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" - -#include -#include -#include -#include -#include - -#include - - -static GtkWidget *configure_win = NULL; -static GtkWidget *mixer_usemaster_check, *buffer_size_spin, *buffer_pre_spin; -static GtkWidget *adevice_use_alt_check, *audio_alt_device_entry; -static GtkWidget *mdevice_use_alt_check, *mixer_alt_device_entry; -static gint audio_device, mixer_device; - -static void -configure_win_ok_cb(GtkWidget * w, gpointer data) -{ - ConfigDb *db; - - oss_cfg.audio_device = audio_device; - oss_cfg.mixer_device = mixer_device; - oss_cfg.buffer_size = - gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_size_spin)); - oss_cfg.prebuffer = - gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(buffer_pre_spin)); - oss_cfg.use_master = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON - (mixer_usemaster_check)); - oss_cfg.use_alt_audio_device = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON - (adevice_use_alt_check)); - oss_cfg.use_alt_mixer_device = - gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON - (mdevice_use_alt_check)); - g_free(oss_cfg.alt_audio_device); - oss_cfg.alt_audio_device = - gtk_editable_get_chars(GTK_EDITABLE(audio_alt_device_entry), 0, -1); - g_strstrip(oss_cfg.alt_audio_device); - g_free(oss_cfg.alt_mixer_device); - oss_cfg.alt_mixer_device = - gtk_editable_get_chars(GTK_EDITABLE(mixer_alt_device_entry), 0, -1); - g_strstrip(oss_cfg.alt_mixer_device); - - if (oss_cfg.use_alt_audio_device) - /* do a minimum of sanity checking */ - if (oss_cfg.alt_audio_device[0] != '/') - oss_cfg.use_alt_audio_device = FALSE; - if (oss_cfg.use_alt_mixer_device) - if (oss_cfg.alt_mixer_device[0] != '/') - oss_cfg.use_alt_mixer_device = FALSE; - - db = bmp_cfg_db_open(); - - bmp_cfg_db_set_int(db, "OSS", "audio_device", oss_cfg.audio_device); - bmp_cfg_db_set_int(db, "OSS", "mixer_device", oss_cfg.mixer_device); - bmp_cfg_db_set_int(db, "OSS", "buffer_size", oss_cfg.buffer_size); - bmp_cfg_db_set_int(db, "OSS", "prebuffer", oss_cfg.prebuffer); - bmp_cfg_db_set_bool(db, "OSS", "use_master", oss_cfg.use_master); - bmp_cfg_db_set_bool(db, "OSS", "use_alt_audio_device", - oss_cfg.use_alt_audio_device); - bmp_cfg_db_set_string(db, "OSS", "alt_audio_device", - oss_cfg.alt_audio_device); - bmp_cfg_db_set_bool(db, "OSS", "use_alt_mixer_device", - oss_cfg.use_alt_mixer_device); - bmp_cfg_db_set_string(db, "OSS", "alt_mixer_device", - oss_cfg.alt_mixer_device); - bmp_cfg_db_close(db); -} - -static void -configure_win_audio_dev_cb(GtkWidget * widget, gint device) -{ - audio_device = device; -} - -static void -configure_win_mixer_dev_cb(GtkWidget * widget, gint device) -{ - mixer_device = device; -} - -static void -audio_device_toggled(GtkToggleButton * widget, gpointer data) -{ - gboolean use_alt_audio_device = gtk_toggle_button_get_active(widget); - gtk_widget_set_sensitive(GTK_WIDGET(data), !use_alt_audio_device); - gtk_widget_set_sensitive(audio_alt_device_entry, use_alt_audio_device); -} - -static void -mixer_device_toggled(GtkToggleButton * widget, gpointer data) -{ - gboolean use_alt_device = gtk_toggle_button_get_active(widget); - gtk_widget_set_sensitive(GTK_WIDGET(data), !use_alt_device); - gtk_widget_set_sensitive(mixer_alt_device_entry, use_alt_device); -} - -static void -scan_devices(gchar * type, GtkWidget * option_menu, GtkSignalFunc sigfunc) -{ - GtkWidget *menu, *item; - FILE *file; - gchar buffer[256], *temp, *tmp2; - gboolean found = FALSE; - gint index = 0; - - menu = gtk_menu_new(); - - if ((file = fopen("/dev/sndstat", "r"))) { - while (fgets(buffer, 255, file)) { - if (found && buffer[0] == '\n') - break; - if (buffer[strlen(buffer) - 1] == '\n') - buffer[strlen(buffer) - 1] = '\0'; - if (found) { - if (index == 0) { - tmp2 = strchr(buffer, ':'); - if (tmp2) { - tmp2++; - while (*tmp2 == ' ') - tmp2++; - } - else - tmp2 = buffer; - temp = g_strdup_printf(_("Default (%s)"), tmp2); - item = gtk_menu_item_new_with_label(temp); - g_free(temp); - } - else - item = gtk_menu_item_new_with_label(buffer); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(sigfunc), (gpointer)(long)(index++)); - gtk_widget_show(item); - gtk_menu_append(GTK_MENU(menu), item); - } - if (!strcasecmp(buffer, type)) - found = 1; - - } - fclose(file); - } - else { - item = gtk_menu_item_new_with_label(_("Default")); - g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(sigfunc), - (gpointer) 0); - gtk_widget_show(item); - gtk_menu_append(GTK_MENU(menu), item); - } - gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu); -} - -void -oss_configure(void) -{ - GtkWidget *vbox, *notebook; - GtkWidget *dev_vbox, *adevice_frame, *adevice_box, *adevice; - GtkWidget *mdevice_frame, *mdevice_box, *mdevice; - GtkWidget *buffer_frame, *buffer_vbox, *buffer_table; - GtkWidget *buffer_size_box, *buffer_size_label; - GtkObject *buffer_size_adj, *buffer_pre_adj; - GtkWidget *buffer_pre_box, *buffer_pre_label; - GtkWidget *audio_alt_box, *mixer_alt_box; - GtkWidget *bbox, *ok, *cancel; - GtkWidget *mixer_table, *mixer_frame; - - if (configure_win) { - gtk_window_present(GTK_WINDOW(configure_win)); - return; - } - - configure_win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - g_signal_connect(G_OBJECT(configure_win), "destroy", - G_CALLBACK(gtk_widget_destroyed), &configure_win); - gtk_window_set_title(GTK_WINDOW(configure_win), - _("OSS Driver configuration")); - gtk_window_set_type_hint(GTK_WINDOW(configure_win), - GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_resizable(GTK_WINDOW(configure_win), FALSE); - gtk_window_set_position(GTK_WINDOW(configure_win), GTK_WIN_POS_CENTER); - gtk_container_border_width(GTK_CONTAINER(configure_win), 10); - - vbox = gtk_vbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(configure_win), vbox); - - notebook = gtk_notebook_new(); - gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); - - dev_vbox = gtk_vbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(dev_vbox), 5); - - adevice_frame = gtk_frame_new(_("Audio device:")); - gtk_box_pack_start(GTK_BOX(dev_vbox), adevice_frame, FALSE, FALSE, 0); - - adevice_box = gtk_vbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(adevice_box), 5); - gtk_container_add(GTK_CONTAINER(adevice_frame), adevice_box); - - adevice = gtk_option_menu_new(); - gtk_box_pack_start(GTK_BOX(adevice_box), adevice, TRUE, TRUE, 0); -#if defined(HAVE_NEWPCM) - scan_devices("Installed devices:", adevice, - GTK_SIGNAL_FUNC(configure_win_audio_dev_cb)); -#else - scan_devices("Audio devices:", adevice, - GTK_SIGNAL_FUNC(configure_win_audio_dev_cb)); -#endif - audio_device = oss_cfg.audio_device; - gtk_option_menu_set_history(GTK_OPTION_MENU(adevice), - oss_cfg.audio_device); - audio_alt_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start_defaults(GTK_BOX(adevice_box), audio_alt_box); - adevice_use_alt_check = - gtk_check_button_new_with_label(_("Use alternate device:")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(adevice_use_alt_check), - oss_cfg.use_alt_audio_device); - g_signal_connect(G_OBJECT(adevice_use_alt_check), "toggled", - G_CALLBACK(audio_device_toggled), adevice); - gtk_box_pack_start(GTK_BOX(audio_alt_box), adevice_use_alt_check, - FALSE, FALSE, 0); - audio_alt_device_entry = gtk_entry_new(); - if (oss_cfg.alt_audio_device != NULL) - gtk_entry_set_text(GTK_ENTRY(audio_alt_device_entry), - oss_cfg.alt_audio_device); - else - gtk_entry_set_text(GTK_ENTRY(audio_alt_device_entry), DEV_DSP); - gtk_box_pack_start_defaults(GTK_BOX(audio_alt_box), - audio_alt_device_entry); - - if (oss_cfg.use_alt_audio_device) - gtk_widget_set_sensitive(adevice, FALSE); - else - gtk_widget_set_sensitive(audio_alt_device_entry, FALSE); - - mdevice_frame = gtk_frame_new(_("Mixer device:")); - gtk_box_pack_start(GTK_BOX(dev_vbox), mdevice_frame, FALSE, FALSE, 0); - - mdevice_box = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(mdevice_box), 5); - gtk_container_add(GTK_CONTAINER(mdevice_frame), mdevice_box); - - mdevice = gtk_option_menu_new(); - gtk_box_pack_start(GTK_BOX(mdevice_box), mdevice, TRUE, TRUE, 0); -#if defined(HAVE_NEWPCM) - scan_devices("Installed devices:", mdevice, configure_win_mixer_dev_cb); -#else - scan_devices("Mixers:", mdevice, G_CALLBACK(configure_win_mixer_dev_cb)); -#endif - mixer_device = oss_cfg.mixer_device; - gtk_option_menu_set_history(GTK_OPTION_MENU(mdevice), - oss_cfg.mixer_device); - mixer_alt_box = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start_defaults(GTK_BOX(mdevice_box), mixer_alt_box); - mdevice_use_alt_check = - gtk_check_button_new_with_label(_("Use alternate device:")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mdevice_use_alt_check), - oss_cfg.use_alt_mixer_device); - g_signal_connect(G_OBJECT(mdevice_use_alt_check), "toggled", - G_CALLBACK(mixer_device_toggled), mdevice); - gtk_box_pack_start(GTK_BOX(mixer_alt_box), mdevice_use_alt_check, - FALSE, FALSE, 0); - mixer_alt_device_entry = gtk_entry_new(); - if (oss_cfg.alt_mixer_device != NULL) - gtk_entry_set_text(GTK_ENTRY(mixer_alt_device_entry), - oss_cfg.alt_mixer_device); - else - gtk_entry_set_text(GTK_ENTRY(mixer_alt_device_entry), DEV_MIXER); - gtk_box_pack_start_defaults(GTK_BOX(mixer_alt_box), - mixer_alt_device_entry); - - if (oss_cfg.use_alt_mixer_device) - gtk_widget_set_sensitive(mdevice, FALSE); - else - gtk_widget_set_sensitive(mixer_alt_device_entry, FALSE); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dev_vbox, - gtk_label_new(_("Devices"))); - - buffer_frame = gtk_frame_new(_("Buffering:")); - gtk_container_set_border_width(GTK_CONTAINER(buffer_frame), 5); - - buffer_vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(buffer_frame), buffer_vbox); - - buffer_table = gtk_table_new(2, 1, TRUE); - gtk_container_set_border_width(GTK_CONTAINER(buffer_table), 5); - gtk_box_pack_start(GTK_BOX(buffer_vbox), buffer_table, FALSE, FALSE, 0); - - buffer_size_box = gtk_hbox_new(FALSE, 5); - gtk_table_attach_defaults(GTK_TABLE(buffer_table), buffer_size_box, 0, - 1, 0, 1); - buffer_size_label = gtk_label_new(_("Buffer size (ms):")); - gtk_box_pack_start(GTK_BOX(buffer_size_box), buffer_size_label, FALSE, - FALSE, 0); - buffer_size_adj = - gtk_adjustment_new(oss_cfg.buffer_size, 200, 10000, 100, 100, 100); - buffer_size_spin = - gtk_spin_button_new(GTK_ADJUSTMENT(buffer_size_adj), 8, 0); - gtk_widget_set_usize(buffer_size_spin, 60, -1); - gtk_box_pack_start(GTK_BOX(buffer_size_box), buffer_size_spin, FALSE, - FALSE, 0); - - buffer_pre_box = gtk_hbox_new(FALSE, 5); - gtk_table_attach_defaults(GTK_TABLE(buffer_table), buffer_pre_box, 1, - 2, 0, 1); - buffer_pre_label = gtk_label_new(_("Pre-buffer (percent):")); - gtk_box_pack_start(GTK_BOX(buffer_pre_box), buffer_pre_label, FALSE, - FALSE, 0); - buffer_pre_adj = gtk_adjustment_new(oss_cfg.prebuffer, 0, 90, 1, 1, 1); - buffer_pre_spin = - gtk_spin_button_new(GTK_ADJUSTMENT(buffer_pre_adj), 1, 0); - gtk_widget_set_usize(buffer_pre_spin, 60, -1); - gtk_box_pack_start(GTK_BOX(buffer_pre_box), buffer_pre_spin, FALSE, - FALSE, 0); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), buffer_frame, - gtk_label_new(_("Buffering"))); - mixer_frame = gtk_frame_new(_("Mixer Settings:")); - gtk_container_set_border_width(GTK_CONTAINER(mixer_frame), 5); - mixer_table = gtk_table_new(3, 2, TRUE); - gtk_container_add(GTK_CONTAINER(mixer_frame), mixer_table); - gtk_container_set_border_width(GTK_CONTAINER(mixer_table), 5); - mixer_usemaster_check = - gtk_check_button_new_with_label(_("Volume controls Master not PCM")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mixer_usemaster_check), - oss_cfg.use_master); - gtk_table_attach_defaults(GTK_TABLE(mixer_table), - mixer_usemaster_check, 0, 1, 0, 1); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), mixer_frame, - gtk_label_new(_("Mixer"))); - - bbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - - cancel = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - g_signal_connect_swapped(G_OBJECT(cancel), "clicked", - G_CALLBACK(gtk_widget_destroy), - GTK_OBJECT(configure_win)); - GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); - gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0); - - ok = gtk_button_new_from_stock(GTK_STOCK_APPLY); - g_signal_connect(G_OBJECT(ok), "clicked", - G_CALLBACK(configure_win_ok_cb), NULL); - GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT); - gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0); - gtk_widget_grab_default(ok); - - gtk_widget_show_all(configure_win); -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/convert.c --- a/Plugins/Output/CoreAudio/convert.c Thu Sep 07 09:11:46 2006 -0700 +++ /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; -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/init.c --- a/Plugins/Output/CoreAudio/init.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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 -#include -#include -#include "OSS.h" - - -OSSConfig oss_cfg; - -void -oss_init(void) -{ - ConfigDb *db; - - memset(&oss_cfg, 0, sizeof(OSSConfig)); - - oss_cfg.audio_device = 0; - oss_cfg.mixer_device = 0; - oss_cfg.buffer_size = 3000; - oss_cfg.prebuffer = 25; - oss_cfg.use_alt_audio_device = FALSE; - oss_cfg.alt_audio_device = NULL; - oss_cfg.use_master = 0; - - if ((db = bmp_cfg_db_open())) { - bmp_cfg_db_get_int(db, "OSS", "audio_device", &oss_cfg.audio_device); - bmp_cfg_db_get_int(db, "OSS", "mixer_device", &oss_cfg.mixer_device); - bmp_cfg_db_get_int(db, "OSS", "buffer_size", &oss_cfg.buffer_size); - bmp_cfg_db_get_int(db, "OSS", "prebuffer", &oss_cfg.prebuffer); - bmp_cfg_db_get_bool(db, "OSS", "use_master", &oss_cfg.use_master); - bmp_cfg_db_get_bool(db, "OSS", "use_alt_audio_device", - &oss_cfg.use_alt_audio_device); - bmp_cfg_db_get_string(db, "OSS", "alt_audio_device", - &oss_cfg.alt_audio_device); - bmp_cfg_db_get_bool(db, "OSS", "use_alt_mixer_device", - &oss_cfg.use_alt_mixer_device); - bmp_cfg_db_get_string(db, "OSS", "alt_mixer_device", - &oss_cfg.alt_mixer_device); - bmp_cfg_db_close(db); - } -} diff -r a3a6f657f895 -r 09905c29250d Plugins/Output/CoreAudio/mixer.c --- a/Plugins/Output/CoreAudio/mixer.c Thu Sep 07 09:11:46 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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 -#include -#include - -#include -#include -#include -#include - -#include "OSS.h" - - -static char * -get_mixer_device(void) -{ - char *name; - - if (oss_cfg.use_alt_mixer_device && oss_cfg.alt_mixer_device) - name = g_strdup(oss_cfg.alt_mixer_device); - else if (oss_cfg.mixer_device > 0) - name = g_strdup_printf("%s%d", DEV_MIXER, oss_cfg.mixer_device); - else - name = g_strdup(DEV_MIXER); - - return name; -} - -void -oss_get_volume(int *l, int *r) -{ - int fd, v, devs; - long cmd; - gchar *devname; - - devname = get_mixer_device(); - fd = open(devname, O_RDONLY); - g_free(devname); - - /* - * We dont show any errors if this fails, as this is called - * rather often - */ - if (fd != -1) { - ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); - if ((devs & SOUND_MASK_PCM) && (oss_cfg.use_master == 0)) - cmd = SOUND_MIXER_READ_PCM; - else if ((devs & SOUND_MASK_VOLUME) && (oss_cfg.use_master == 1)) - cmd = SOUND_MIXER_READ_VOLUME; - else { - close(fd); - return; - } - ioctl(fd, cmd, &v); - *r = (v & 0xFF00) >> 8; - *l = (v & 0x00FF); - close(fd); - } -} - -void -oss_set_volume(int l, int r) -{ - int fd, v, devs; - long cmd; - gchar *devname; - - devname = get_mixer_device(); - fd = open(devname, O_RDONLY); - - if (fd != -1) { - ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs); - if ((devs & SOUND_MASK_PCM) && (oss_cfg.use_master == 0)) - cmd = SOUND_MIXER_WRITE_PCM; - else if ((devs & SOUND_MASK_VOLUME) && (oss_cfg.use_master == 1)) - cmd = SOUND_MIXER_WRITE_VOLUME; - else { - close(fd); - return; - } - v = (r << 8) | l; - ioctl(fd, cmd, &v); - close(fd); - } - else - g_warning("oss_set_volume(): Failed to open mixer device (%s): %s", - devname, strerror(errno)); - g_free(devname); -}