diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/audio_out/Makefile.am | 22 | ||||
-rw-r--r-- | src/audio_out/audio_irixal_out.c | 400 | ||||
-rw-r--r-- | src/audio_out/audio_irixal_out.h | 27 |
3 files changed, 436 insertions, 13 deletions
diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 7ac547bd7..81401173f 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -1,8 +1,7 @@ CFLAGS = @GLOBAL_CFLAGS@ -DXINE_COMPILE $(ALSA_CFLAGS) $(ESD_CFLAGS) $(IRIXAL_CFLAGS) $(ARTS_CFLAGS) EXTRA_DIST = audio_alsa_out.c audio_alsa05_out.c audio_esd_out.c \ - audio_sun_out.c audio_arts_out.c -# audio_irixal_out.c + audio_sun_out.c audio_arts_out.c audio_irixal_out.c LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic @@ -33,9 +32,9 @@ if HAVE_SUNAUDIO sun_module = xineplug_ao_out_sun.la endif -## if HAVE_IRIXAL -## irixal_module = xineplug_ao_out_irixal.la -## endif +if HAVE_IRIXAL +irixal_module = xineplug_ao_out_irixal.la +endif if HAVE_ARTS arts_module = xineplug_ao_out_arts.la @@ -51,9 +50,7 @@ endif # $(arts_module) $(esd_module) lib_LTLIBRARIES = $(oss_module) $(alsa_module) $(esd_module) $(sun_module) $(arts_module) \ - $(alsa05_module) - -## $(irixal_module) + $(alsa05_module) $(irixal_module) xineplug_ao_out_oss_la_SOURCES = audio_oss_out.c xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module @@ -73,17 +70,16 @@ xineplug_ao_out_esd_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module -## xineplug_ao_out_irixal_la_SOURCES = audio_irixal_out.c -## xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) -## xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module +xineplug_ao_out_irixal_la_SOURCES = audio_irixal_out.c +xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) +xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module xineplug_ao_out_arts_la_SOURCES = audio_arts_out.c xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module noinst_HEADERS = audio_oss_out.h audio_alsa_out.h audio_esd_out.h \ - audio_sun_out.h audio_arts_out.h -## audio_irixal_out.h + audio_sun_out.h audio_arts_out.h audio_irixal_out.h debug: diff --git a/src/audio_out/audio_irixal_out.c b/src/audio_out/audio_irixal_out.c new file mode 100644 index 000000000..e74c0cd37 --- /dev/null +++ b/src/audio_out/audio_irixal_out.c @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2000, 2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine 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. + * + * xine 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: audio_irixal_out.c,v 1.1 2001/09/06 17:12:38 mshopf Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <math.h> +#include <sys/ioctl.h> +#include <inttypes.h> + +#include <dmedia/audio.h> + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +#define error(...) do {\ + fprintf(stderr, "XINE lib %s:%d:(%s) ", __FILE__, __LINE__, __FUNCTION__); \ + fprintf(stderr, __VA_ARGS__); \ + putc('\n', stderr); \ +} while (0) +#else +#define error(args...) do {\ + fprintf(stderr, "XINE lib %s:%d:(%s) ", __FILE__, __LINE__, __FUNCTION__); \ + fprintf(stderr, ##args); \ + putc('\n', stderr); \ +} while (0) +#endif + + +#include "xine_internal.h" +#include "monitor.h" +#include "audio_out.h" +#include "utils.h" + +//#ifndef AFMT_S16_NE +//# if defined(sparc) || defined(__sparc__) || defined(PPC) +///* Big endian machines */ +//# define AFMT_S16_NE AFMT_S16_BE +//# else +//# define AFMT_S16_NE AFMT_S16_LE +//# endif +//#endif + +#define DEFAULT_GAP_TOLERANCE 5000 + +typedef struct irixal_driver_s { + + ao_driver_t ao_driver; + + ALport port; + + int capabilities; + int open_mode; + int gap_tolerance; + + int32_t output_sample_rate, input_sample_rate; + uint32_t num_channels; + uint32_t bits_per_sample; + uint32_t bytes_per_frame; + stamp_t frames_in_buffer; /* number of frames writen to audio hardware */ + +} irixal_driver_t; + +// static snd_output_t *jcd_out; +/* + * open the audio device for writing to + */ +static int ao_irixal_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + int resource; + ALconfig config; + ALpv parvalue; + + /* + * Init config for audio port + */ + switch (mode) { + case AO_CAP_MODE_MONO: + this->num_channels = 1; + break; + case AO_CAP_MODE_STEREO: + this->num_channels = 2; + break; + /* not tested so far (missing an Onyx with multichannel output...) */ + case AO_CAP_MODE_4CHANNEL: + this->num_channels = 4; + break; +#if 0 +/* unsupported so far */ + case AO_CAP_MODE_5CHANNEL: + this->num_channels = 5; + break; + case AO_CAP_MODE_5_1CHANNEL: + this->num_channels = 6; + break; + case AO_CAP_MODE_A52: + this->num_channels = 2; + break; +#endif + default: + error ("irixal Driver does not support the requested mode: 0x%x",mode); + return 0; + } + + if (! (config = alNewConfig ())) + { + error ("cannot get new config: %s", strerror (oserror())); + return 0; + } + if ( (alSetChannels (config, this->num_channels)) == -1) + { + error ("cannot set to %d channels: %s", this->num_channels, strerror (oserror())); + alFreeConfig (config); + return 0; + } + + switch (bits) { + case 8: + if ( (alSetWidth (config, AL_SAMPLE_8)) == -1) + { + error ("cannot set 8bit mode: %s", strerror (oserror())); + alFreeConfig (config); + return 0; + } + break; + case 16: + /* Default format is 16bit PCM */ + break; + default: + error ("irixal Driver does not support %dbit audio", bits); + alFreeConfig (config); + return 0; + } + + printf("audio_irixal_out: channels=%d, bits=%d\n", this->num_channels, bits); + + /* + * Try to open audio port + */ + if (! (this->port = alOpenPort ("xine", "w", config))) { + error ("irixal Driver does not support the audio configuration"); + alFreeConfig (config); + return 0; + } + alFreeConfig (config); + resource = alGetResource (this->port); + this->open_mode = mode; + this->input_sample_rate = rate; + this->bits_per_sample = bits; + /* FIXME: Can use an irixal function here ?!? */ + this->bytes_per_frame = (this->bits_per_sample*this->num_channels) / 8; + this->frames_in_buffer = 0; + + + /* TODO: not yet settable (see alParams (3dm)): AL_INTERFACE, AL_CLOCK_GEN */ + /* + * Try to adapt sample rate of audio port + */ + parvalue.param = AL_MASTER_CLOCK; + parvalue.value.i = AL_CRYSTAL_MCLK_TYPE; + if (alSetParams (resource, &parvalue, 1) == -1) + printf ("audio_irixal: FYI: cannot set audio master clock to crystal based clock\n"); + + parvalue.param = AL_RATE; + parvalue.value.ll = alIntToFixed (rate); + if (alSetParams (resource, &parvalue, 1) == -1) + printf ("audio_irixal: FYI: cannot set sample rate, using software resampling\n"); + if (alGetParams (resource, &parvalue, 1) == -1) + { + error ("cannot ask for current sample rate, assuming everything worked..."); + this->output_sample_rate = this->input_sample_rate; + } + else + this->output_sample_rate = alFixedToInt (parvalue.value.ll); + + if (this->input_sample_rate != this->output_sample_rate) + printf ("audio_irixal: FYI: sample_rate in %d, out %d\n", + this->input_sample_rate, this->output_sample_rate); + + return this->output_sample_rate; +} + +static int ao_irixal_num_channels(ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + return this->num_channels; +} + +static int ao_irixal_bytes_per_frame(ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + return this->bytes_per_frame; +} + +static int ao_irixal_get_gap_tolerance (ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + return this->gap_tolerance; /* ??? */ +} + +static int ao_irixal_delay (ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + stamp_t stamp, time; + int frames_left; + + if (alGetFrameTime (this->port, &stamp, &time) == -1) + error ("alGetFrameNumber failed"); + frames_left = this->frames_in_buffer - stamp; + if (frames_left <= 0) /* buffer ran dry */ + frames_left = 0; + + return frames_left; +} + +static int ao_irixal_write(ao_driver_t *this_gen,int16_t *data, uint32_t num_frames) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + stamp_t stamp; + + /* Grmbf. IRIX audio does not tell us, wenn we run dry. + * We have to detect this ourself. */ + /* get absolute number of samples played so far + * note: this counts up when run dry as well... */ + if (alGetFrameNumber (this->port, &stamp) == -1) + error ("alGetFrameNumber failed"); + if (this->frames_in_buffer < stamp) /* dry run */ + { + if (this->frames_in_buffer > 0) + printf ("audio_irixal: audio buffer dry run detected, buffer %llu should be > %llu!\n", + this->frames_in_buffer, stamp); + this->frames_in_buffer = stamp; + } + /* FIXME: what to do when the call would block? + * We have to write things out anyway... + * alGetFillable() would tell us, whether space was available */ + alWriteFrames (this->port, data, num_frames); + this->frames_in_buffer += num_frames; + + return num_frames; +} + +static void ao_irixal_close(ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + if (this->port) + alClosePort (this->port); + this->port = NULL; +} + +static uint32_t ao_irixal_get_capabilities (ao_driver_t *this_gen) { + irixal_driver_t *this = (irixal_driver_t *) this_gen; + return this->capabilities; +} + +static void ao_irixal_exit(ao_driver_t *this_gen) +{ + irixal_driver_t *this = (irixal_driver_t *) this_gen; + ao_irixal_close (this_gen); + free (this); +} + +static int ao_irixal_get_property (ao_driver_t *this, int property) { + /* FIXME: implement some properties */ + return 0; +} + +/* + * + */ +static int ao_irixal_set_property (ao_driver_t *this, int property, int value) { + + /* FIXME: Implement property support */ + return ~value; +} + +ao_driver_t *init_audio_out_plugin (config_values_t *config) +{ + irixal_driver_t *this; + ALvalue values [32]; + ALpv parvalue; + char name[32]; + int i, numvalues; + int useresource = -1; + + printf ("audio_irixal: init...\n"); + + /* Check available outputs */ + /* TODO: this is verbose information only right now, output is not selectable */ + if ( (numvalues = alQueryValues (AL_SYSTEM, AL_DEFAULT_OUTPUT, values, 32, NULL, 0)) > 0) + { + useresource = values [0].i; + for (i = 0; i < numvalues; i++) + { + parvalue.param = AL_NAME; + parvalue.value.ptr = name; + parvalue.sizeIn = 32; + if (alGetParams (values [i].i, &parvalue, 1) != -1) + printf (" available Output: %s\n", name); + } + } + if (useresource == -1) + { + error ("cannot find output resource"); + return NULL; + } + +#if 0 + /* TODO */ + device = config->lookup_str(config,"irixal_default_device", "default"); +#endif + + /* allocate struct */ + this = (irixal_driver_t *) calloc (sizeof (irixal_driver_t), 1); + + /* get capabilities */ + if ( (numvalues = alQueryValues (useresource, AL_CHANNELS, values, 32, NULL, 0)) > 0) + { + for (i = 0; i < numvalues; i++) + { + switch (values[i].i) { + case 1: + this->capabilities |= AO_CAP_MODE_MONO; + break; + case 2: + this->capabilities |= AO_CAP_MODE_STEREO; + break; + /* not tested so far (missing an Onyx with multichannel output...) */ + case 4: + this->capabilities |= AO_CAP_MODE_4CHANNEL; + break; +#if 0 +/* unsupported so far */ + case AO_CAP_MODE_5CHANNEL: + case AO_CAP_MODE_5_1CHANNEL: + case AO_CAP_MODE_A52: +#endif + default: + printf (" unsupported %d channel config available on system\n", values[i].i); + } + } + } + + printf (" capabilities 0x%X\n",this->capabilities); + + this->gap_tolerance = config->lookup_int (config, "irixal_gap_tolerance", DEFAULT_GAP_TOLERANCE); + + this->ao_driver.get_capabilities = ao_irixal_get_capabilities; + this->ao_driver.get_property = ao_irixal_get_property; + this->ao_driver.set_property = ao_irixal_set_property; + this->ao_driver.open = ao_irixal_open; + this->ao_driver.num_channels = ao_irixal_num_channels; + this->ao_driver.bytes_per_frame = ao_irixal_bytes_per_frame; + this->ao_driver.delay = ao_irixal_delay; + this->ao_driver.write = ao_irixal_write; + this->ao_driver.close = ao_irixal_close; + this->ao_driver.exit = ao_irixal_exit; + this->ao_driver.get_gap_tolerance = ao_irixal_get_gap_tolerance; + + return &this->ao_driver; +} + +static ao_info_t ao_info_irixal = +{ + AUDIO_OUT_IFACE_VERSION, + "irixal", + "xine audio output plugin using IRIX libaudio", + 10 +}; + +ao_info_t *get_audio_out_plugin_info() +{ + return &ao_info_irixal; +} + diff --git a/src/audio_out/audio_irixal_out.h b/src/audio_out/audio_irixal_out.h new file mode 100644 index 000000000..6b68025c7 --- /dev/null +++ b/src/audio_out/audio_irixal_out.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2000 the xine project + * + * This file is part of xine, a unix video player. + * + * xine 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. + * + * xine 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: audio_irixal_out.h,v 1.1 2001/09/06 17:12:38 mshopf Exp $ + */ +#ifndef _AUDIO_IRIXAL_OUT_H_ +#define _AUDIO_IRIXAL_OUT_H_ 1 + +ao_functions_t *audio_irixalout_init(void); + +#endif |