From 8f36d8fbd053b9133352edf9666d6d6c3a77a8dd Mon Sep 17 00:00:00 2001
From: Stan Seibert <volsung@xiph.org>
Date: Wed, 8 Jan 2003 03:48:54 +0000
Subject: [PATCH] Patch from Stefan Tibus <sjti@gmx.net> to add support for the
 AIX audio devices.  The conditional compilation is a little messy, but I
 still need to decide a good way to do that in general.

git-svn-id: http://svn.xiph.org/trunk/ao@4214 0101bb08-14d6-0310-b084-bc0e0c8e3800
---
 configure.in    |   4 +
 include/ao/ao.h |   3 +-
 src/Makefile.am |   2 +-
 src/ao_aixs.c   | 219 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/audio_out.c |   6 ++
 5 files changed, 232 insertions(+), 2 deletions(-)
 create mode 100644 src/ao_aixs.c

diff --git a/configure.in b/configure.in
index 97855e9..6cb00e3 100644
--- a/configure.in
+++ b/configure.in
@@ -221,6 +221,10 @@ dnl Check for Sun audio
 AC_CHECK_HEADERS(sys/audioio.h)
 AM_CONDITIONAL(HAVE_SUN_AUDIO,test "${ac_cv_header_sys_audioio_h}" = yes)
 
+dnl Check for AIX audio
+
+AC_CHECK_HEADERS(sys/audio.h)
+AM_CONDITIONAL(HAVE_AIX_AUDIO,test "${ac_cv_header_sys_audio_h}" = yes)
 
 dnl Check for aRts
 
diff --git a/include/ao/ao.h b/include/ao/ao.h
index a25ad52..112e155 100644
--- a/include/ao/ao.h
+++ b/include/ao/ao.h
@@ -31,7 +31,8 @@
 extern "C"
 {
 #endif /* __cplusplus */
-	
+
+#include <stdio.h>	
 #include <stdlib.h>
 #include <errno.h>
 #include "os_types.h"
diff --git a/src/Makefile.am b/src/Makefile.am
index bff0839..3e6f3a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,7 +7,7 @@ INCLUDES = -I$(top_builddir)/include/ao -I$(top_srcdir)/include -DAO_PLUGIN_PATH
 
 lib_LTLIBRARIES = libao.la
 
-libao_la_SOURCES = audio_out.c config.c ao_null.c ao_wav.c ao_au.c ao_raw.c ao_private.h
+libao_la_SOURCES = audio_out.c config.c ao_null.c ao_wav.c ao_au.c ao_raw.c ao_aixs.c ao_private.h
 libao_la_LDFLAGS = -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@ -ldl
 
 
diff --git a/src/ao_aixs.c b/src/ao_aixs.c
new file mode 100644
index 0000000..7533be7
--- /dev/null
+++ b/src/ao_aixs.c
@@ -0,0 +1,219 @@
+/*
+ *
+ *  ao_aixs.c    AIX (5.1)
+ *
+ *      Original Copyright (C) Stefan Tibus - August 2002
+ *
+ *  libao 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, or (at your option)
+ *  any later version.
+ *
+ *  libao 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 GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_SYS_AUDIO_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/audio.h>
+
+#include <ao/ao.h>
+#include <ao/plugin.h>
+
+
+/*
+ * default audio device to be used, 
+ * possible options:
+ * /dev/paud0/1 on PCI machines with the Crystal chipset
+ * /dev/baud0/1 on MCA machines with the Crystal chipset
+ * /dev/acpa0/1 on MCA machines with the ACPA
+ */
+#ifndef AO_AIX_DEFAULT_DEV
+#define AO_AIX_DEFAULT_DEV "/dev/baud0/1"
+#endif
+
+
+static char *ao_aixs_options[] = {"dev"};
+ao_info ao_aixs_info = {
+	AO_TYPE_LIVE,
+	"AIX audio driver output",
+	"aixs",
+	"Stefan Tibus <sjti@gmx.net>",
+	"Outputs to the AIX audio system.",
+	AO_FMT_NATIVE,
+	20,
+	ao_aixs_options,
+	1
+};
+
+
+typedef struct ao_aixs_internal {
+	char *dev;
+	int fd;
+} ao_aixs_internal;
+
+
+int ao_aixs_test()
+{
+	int fd;
+
+	if ( (fd = open(AO_AIX_DEFAULT_DEV, O_WRONLY)) < 0 )
+		return 0; /* Cannot use this plugin with default parameters */
+	else {
+		close(fd);
+		return 1; /* This plugin works in default mode */
+	}
+}
+
+
+ao_info *ao_aixs_driver_info(void)
+{
+	return &ao_aixs_info;
+}
+
+
+int ao_aixs_device_init(ao_device *device)
+{
+	ao_aixs_internal *internal;
+
+	internal = (ao_aixs_internal *) malloc(sizeof(ao_aixs_internal));
+
+	if (internal == NULL)	
+		return 0; /* Could not initialize device memory */
+	
+	internal->dev = strdup(AO_AIX_DEFAULT_DEV);
+	
+	if (internal->dev == NULL) {
+		free(internal);
+		return 0;
+	}
+		
+	device->internal = internal;
+
+	return 1; /* Memory alloc successful */
+}
+
+int ao_aixs_set_option(ao_device *device, const char *key, const char *value)
+{
+	ao_aixs_internal *internal = (ao_aixs_internal *) device->internal;
+
+
+	if (!strcmp(key, "dev")) {
+		/* Free old string in case "dsp" set twice in options */
+		free(internal->dev); 
+		internal->dev = strdup(value);
+	}
+
+	return 1;
+}
+
+
+int ao_aixs_open(ao_device *device, ao_sample_format *format)
+{
+	ao_aixs_internal *internal = (ao_aixs_internal *) device->internal;
+	
+	audio_init init;
+	audio_control control;
+	audio_change change;
+
+	if ( (internal->fd = open(internal->dev, O_WRONLY)) < 0 )
+		return 0;
+
+	init.srate = format->rate;
+	init.bits_per_sample = format->bits;
+	init.channels = format->channels;
+	init.mode = AUDIO_PCM;
+	init.flags = AUDIO_BIG_ENDIAN | AUDIO_TWOS_COMPLEMENT;
+	init.operation = AUDIO_PLAY;
+
+ 	if (ioctl(internal->fd, AUDIO_INIT, &init) < 0) {
+		close(internal->fd);
+		return 0;  /* Unsupported audio format */
+	}
+
+	change.balance = 0x3fff0000;
+	change.volume = 0x3fff0000;
+	change.monitor = AUDIO_IGNORE;
+	change.input = AUDIO_IGNORE;
+	change.output = AUDIO_OUTPUT_1;
+
+	control.ioctl_request = AUDIO_CHANGE;
+	control.position = 0;
+	control.request_info = &change;
+
+	if (ioctl(internal->fd, AUDIO_CONTROL, &control) < 0) {
+		close(internal->fd);
+		return 0;
+	}
+
+	control.ioctl_request = AUDIO_START;
+	control.request_info = NULL; 
+
+	if (ioctl(internal->fd, AUDIO_CONTROL, &control) < 0) {
+		close(internal->fd);
+		return 0;
+	}
+
+	device->driver_byte_format = AO_FMT_NATIVE;
+
+	return 1;
+}
+
+
+int ao_aixs_play(ao_device *device, const char *output_samples, 
+		uint_32 num_bytes)
+{
+	ao_aixs_internal *internal = (ao_aixs_internal *) device->internal;
+	
+	if (write(internal->fd, output_samples, num_bytes) < 0)
+		return 0;
+	else
+		return 1;
+}
+
+
+int ao_aixs_close(ao_device *device)
+{
+	ao_aixs_internal *internal = (ao_aixs_internal *) device->internal;
+
+	close(internal->fd);
+
+	return 1;
+}
+
+
+void ao_aixs_device_clear(ao_device *device)
+{
+	ao_aixs_internal *internal = (ao_aixs_internal *) device->internal;
+
+	free(internal->dev);
+	free(internal);
+}
+
+ao_functions ao_aixs = {
+	ao_aixs_test,
+	ao_aixs_driver_info,
+	ao_aixs_device_init,
+	ao_aixs_set_option,
+	ao_aixs_open,
+	ao_aixs_play,
+	ao_aixs_close,
+	ao_aixs_device_clear
+};
+
+#endif
diff --git a/src/audio_out.c b/src/audio_out.c
index 9594bb1..ff9cac0 100644
--- a/src/audio_out.c
+++ b/src/audio_out.c
@@ -62,12 +62,18 @@ extern ao_functions ao_null;
 extern ao_functions ao_wav;
 extern ao_functions ao_raw;
 extern ao_functions ao_au;
+#ifdef HAVE_SYS_AUDIO_H
+extern ao_functions ao_aixs;
+#endif
 
 static ao_functions *static_drivers[] = {
 	&ao_null, /* Must have at least one static driver! */
 	&ao_wav,
 	&ao_raw,
 	&ao_au,
+#ifdef HAVE_SYS_AUDIO_H
+	&ao_aixs,
+#endif
 	NULL /* End of list */
 };
 
-- 
GitLab