summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_out/Makefile.am22
-rw-r--r--src/audio_out/audio_irixal_out.c400
-rw-r--r--src/audio_out/audio_irixal_out.h27
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