changeset 8:b30908f9d9f9

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:10 +0000
parents de95ce2eacfd
children 990c9dadb348
files playercode/drv_raw.c playercode/mdreg.c playercode/mlreg.c playercode/unix_drv/drv_AF.c playercode/unix_drv/drv_aix.c playercode/unix_drv/drv_hp.c playercode/unix_drv/drv_sgi.c
diffstat 7 files changed, 917 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/drv_raw.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,111 @@
+/*
+
+Name:
+DRV_RAW.C
+
+Description:
+Mikmod driver for output to a file called MUSIC.RAW
+
+MS-DOS Programmers:
+ !! DO NOT CALL MD_UPDATE FROM A INTERRUPT IF YOU USE THIS DRIVER !!
+
+Portability:
+
+MSDOS:  BC(y)   Watcom(y)   DJGPP(y)
+Win95:  BC(y)
+Linux:  y
+
+(y) - yes
+(n) - no (not possible or not useful)
+(?) - may be possible, but not tested
+
+*/
+
+#include "mikmod.h"
+
+#ifdef __GNUC__
+#include <sys/types.h>
+#else
+#include <io.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define RAWBUFFERSIZE 8192
+
+static int rawout;
+
+static SBYTE RAW_DMABUF[RAWBUFFERSIZE];
+
+
+static BOOL RAW_IsThere(void)
+{
+    return 1;
+}
+
+
+static BOOL RAW_Init(void)
+{
+    if(-1 == (rawout = open("music.raw", 
+#ifndef __GNUC__
+                O_BINARY | 
+#endif
+                O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE)))
+        return 1;
+
+    md_mode |= DMODE_SOFT_MUSIC | DMODE_SOFT_SNDFX;
+
+    if(VC_Init()) return 1;
+
+    return 0;
+}
+
+
+static void RAW_Exit(void)
+{
+    VC_Exit();
+    close(rawout);
+}
+
+
+static void RAW_Update(void)
+{
+    VC_WriteBytes(RAW_DMABUF, RAWBUFFERSIZE);
+    write(rawout, RAW_DMABUF, RAWBUFFERSIZE);
+}
+
+
+static BOOL RAW_Reset(void)
+{
+    return 0;
+}
+
+
+MDRIVER drv_raw =
+{   NULL,
+    "music.raw file",
+    "RAW [music.raw] file output driver v1.0",
+    0,255,
+    RAW_IsThere,
+    VC_SampleLoad,
+    VC_SampleUnload,
+    VC_SampleSpace,
+    VC_SampleLength,
+    RAW_Init,
+    RAW_Exit,
+    RAW_Reset,
+    VC_SetNumVoices,
+    VC_PlayStart,
+    VC_PlayStop,
+    RAW_Update,
+    VC_VoiceSetVolume,
+    VC_VoiceSetFrequency,
+    VC_VoiceSetPanning,
+    VC_VoicePlay,
+    VC_VoiceStop,
+    VC_VoiceStopped,
+    VC_VoiceReleaseSustain,
+    VC_VoiceGetPosition,
+    VC_VoiceRealVolume
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/mdreg.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,61 @@
+/*
+
+ Name:  MDREG.C
+
+ Description:
+ A single routine for registering all drivers in MikMod for the current
+ platform.
+
+ Portability:
+ DOS, WIN95, OS2, SunOS, Solaris,
+ Linux, HPUX, AIX, SGI, Alpha
+
+ Anything not listed above is assumed to not be supported by this procedure!
+
+ All Others: n
+
+ - all compilers!
+
+*/
+
+#include "mikmod.h"
+
+void MikMod_RegisterAllDrivers(void)
+{
+
+#ifdef SUN
+    MikMod_RegisterDriver(drv_sun);
+#elif defined(SOLARIS)
+    MikMod_RegisterDriver(drv_sun);
+#elif defined(__alpha)
+    MikMod_RegisterDriver(drv_AF);
+#elif defined(OSS)
+    MikMod_RegisterDriver(drv_oss);
+    #ifdef ULTRA
+       MikMod_RegisterDriver(drv_ultra);
+    #endif /* ULTRA */
+#elif defined(__hpux)
+    MikMod_RegisterDriver(drv_hp);
+#elif defined(AIX)
+    MikMod_RegisterDriver(drv_aix);
+#elif defined(SGI)
+    MikMod_RegisterDriver(drv_sgi);
+#elif defined(__OS2__)
+    MikMod_RegisterDriver(drv_os2);
+#elif defined(__WIN32__)
+    MikMod_RegisterDriver(drv_w95);
+#else
+    MikMod_RegisterDriver(drv_awe);
+    MikMod_RegisterDriver(drv_gus);
+//    MikMod_RegisterDriver(drv_gus2);     // use for hardware mixing only (smaller / faster)
+    MikMod_RegisterDriver(drv_pas);
+    MikMod_RegisterDriver(drv_wss);
+    MikMod_RegisterDriver(drv_ss);
+    MikMod_RegisterDriver(drv_sb16);
+    MikMod_RegisterDriver(drv_sbpro);
+    MikMod_RegisterDriver(drv_sb);
+#endif
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/mlreg.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,30 @@
+/*
+
+ Name:  MLREG.C
+
+ Description:
+ A single routine for registering all loaders in MikMod for the current
+ platform.
+
+ Portability:
+ All systems - all compilers
+
+*/
+
+#include "mikmod.h"
+
+void MikMod_RegisterAllLoaders(void)
+{
+   MikMod_RegisterLoader(load_uni);
+   MikMod_RegisterLoader(load_it);
+   MikMod_RegisterLoader(load_xm);
+   MikMod_RegisterLoader(load_s3m);
+   MikMod_RegisterLoader(load_mod);
+   MikMod_RegisterLoader(load_mtm);
+   MikMod_RegisterLoader(load_stm);
+   MikMod_RegisterLoader(load_dsm);
+   MikMod_RegisterLoader(load_med);
+   MikMod_RegisterLoader(load_far);
+   MikMod_RegisterLoader(load_ult);
+   MikMod_RegisterLoader(load_669);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/unix_drv/drv_AF.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,201 @@
+/*
+
+  Name:
+  DRV_AF.C
+
+  Description:
+  Mikmod driver for output on AF audio server.
+  
+  Written by Roine Gustafsson <e93_rog@e.kth.se> Oct 25, 1995
+  
+  Portability:
+  Unixes running Digital AudioFile library, available from
+  ftp://crl.dec.com/pub/DEC/AF
+
+  Usage:
+  Run the audio server (Aaxp&, Amsb&, whatever)
+  Set environment variable AUDIOFILE to something like 'mymachine:0'.
+  Remember, stereo is default! See commandline switches.
+
+  I have a version which uses 2 computers for stereo.
+  Contact me if you want it.
+  
+  THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+  NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+  History:
+    ver 1.21 Bugfix: AFFragmentSize could end up uneven.
+		Thanks to Marcus Sundberg <e94_msu@e.kth.se>
+    ver 1.22 Compatibility: change "AFBuffer" to "audiobuffer"
+		Steve McIntyre <stevem@chiark.greenend.org.uk>
+    ver 1.30 Compatibility: Use new driver API
+		Steve McIntyre <stevem@chiark.greenend.org.uk>
+*/
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <AF/AFlib.h>
+
+#include "mikmod.h"
+
+/* Global variables */
+
+SBYTE *audiobuffer;
+static int AFFragmentSize;
+AFAudioConn *AFaud;
+ATime AFtime;
+AC AFac;
+AFDeviceDescriptor *AFdesc;
+
+BOOL AF_IsThere(void)
+{
+
+  /* I'll think of a detection routine ... somtime */
+  
+  return 1;
+
+}
+
+BOOL AF_Init(void)
+{
+  unsigned long mask;
+  AFSetACAttributes attributes;
+  int srate;
+  ADevice device;
+  unsigned int channels;
+  AEncodeType type;
+  char *server;
+  int n;
+  
+  AFaud = AFOpenAudioConn( "" );
+  if ( AFaud == NULL ) {
+    myerr="Cannot open sounddevice.";
+    return 0;
+  }
+
+  /* Search for a suitable device */
+  device = -1;
+  for ( n = 0; n < AFaud->ndevices; n++ ) {
+    AFdesc = AAudioDeviceDescriptor( AFaud, n );
+    if ( AFdesc->playNchannels == 2 && md_mode&DMODE_STEREO ) {
+      device = n;
+      break;
+    }
+    if ( AFdesc->playNchannels == 1 && !(md_mode&DMODE_STEREO) ) {
+      device = n;
+      break;
+    }
+  }
+  if ( device == -1 ) {
+    myerr="Cannot find suitable audio port!";
+    AFCloseAudioConn( AFaud );      
+    return 0;
+  }
+
+  attributes.preempt = Mix;
+  attributes.start_timeout = 0;
+  attributes.end_silence = 0;
+  attributes.type = LIN16;  /* In case of an 8bit device, the AF converts the 16 bit data to 8 bit */
+  attributes.channels = (md_mode&DMODE_STEREO)? Stereo: Mono;
+
+  mask = ACPreemption | ACEncodingType | ACStartTimeout | ACEndSilence | ACChannels;
+  AFac = AFCreateAC( AFaud, device, mask, &attributes );
+  srate=AFac->device->playSampleFreq;
+
+  md_mode|=DMODE_16BITS;   /* This driver only handles 16bits */
+  AFFragmentSize = (srate/40)*8;    /* Update 5 times/sec */
+  md_mixfreq=srate;        /* set mixing freq */
+
+  if ( md_mode & DMODE_STEREO ) {
+    if ( ( audiobuffer = (SBYTE *)malloc( 2*2*AFFragmentSize ) ) == NULL ) {
+      myerr="Out of memory!";
+      AFCloseAudioConn( AFaud );      
+      return 0;
+    }
+    
+  } else {
+    if ( ( audiobuffer = (SBYTE *)malloc( 2*AFFragmentSize ) ) == NULL ) {
+      myerr="Out of memory!";
+      AFCloseAudioConn( AFaud );      
+      return 0;
+    }
+  }
+  
+  if ( !VC_Init() ) {
+    AFCloseAudioConn( AFaud );
+    free( audiobuffer );
+    return 0;
+  }
+
+  return 1;
+}
+
+void AF_PlayStart( void )
+{
+
+  AFtime = AFGetTime( AFac );
+  VC_PlayStart();
+
+}
+
+
+void AF_Exit(void)
+{
+
+  VC_Exit();
+  AFCloseAudioConn(AFaud);
+  free( AFBuffer );
+  
+}
+
+void AF_Update(void)
+{
+
+  UWORD *p,*l,*r;
+  int i;
+  
+  
+  VC_WriteBytes( AFBuffer, AFFragmentSize );
+  if ( md_mode & DMODE_STEREO ) {
+    AFPlaySamples( AFac, AFtime, AFFragmentSize, (unsigned char *)AFBuffer );
+    AFtime+=AFFragmentSize/4;
+//    while ( AFGetTime( AFac ) < AFtime-1000 );
+  } else {
+    AFPlaySamples( AFac, AFtime, AFFragmentSize, (unsigned char *)AFBuffer );
+    AFtime+=AFFragmentSize/2;
+//    while ( AFGetTime( AFac ) < AFtime-1000 );
+  }
+  
+}
+
+
+DRIVER drv_AF={
+  NULL,
+  "AF driver",
+  "MikMod AudioFile Driver v1.22",
+  AF_IsThere,
+  VC_SampleLoad,
+  VC_SampleUnload,
+  VC_SampleSpace,
+  VC_SampleLength,
+  AF_Init,
+  AF_Exit,
+  VC_SetNumChannels,
+  AF_PlayStart,
+  VC_PlayStop,
+  AF_Update,
+  VC_VoiceSetVolume,
+  VC_VoiceSetFrequency,
+  VC_VoiceSetPanning,
+  VC_VoicePlay,
+	VC_VoiceStop,
+	VC_VoiceStopped,
+	VC_VoiceReleaseSustain,
+	VC_VoiceGetPosition,
+	VC_RealVolume
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/unix_drv/drv_aix.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,173 @@
+/*
+
+Name:
+drv_aix.c
+
+Description:
+Mikmod driver for output to AIX series audio device
+
+Portability:
+
+AIX >= 3.25 with appropriate audio hardware.
+
+Written by Lutz Vieweg <lkv@mania.robin.de>
+based on drv_raw.c
+
+Feel free to distribute just as you like.
+No warranties at all.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/audio.h>
+
+#include "mikmod.h"
+
+struct _track_info
+{
+        unsigned short master_volume;
+        unsigned short dither_percent;
+        unsigned short reserved[3];
+} t_info;
+audio_init a_init;
+audio_control a_control;
+audio_change a_change;
+
+
+static int fd;
+#define RAWBUFFERSIZE 32768
+static char RAW_DMABUF[RAWBUFFERSIZE];
+
+static BOOL AIX_IsThere(void)
+{
+	return 1;
+}
+
+static BOOL AIX_Init(void)
+{
+	float volume = (float)1.0;
+	int flags;
+	
+	if (! (md_mode & DMODE_16BITS)) {
+		myerr = "sorry, this driver supports 16-bit linear output only";
+		return 0;
+	}
+	
+   if ((fd = open ("/dev/acpa0/1", O_WRONLY)) < 3)
+     if ((fd = open ("/dev/paud0/1", O_WRONLY)) < 3)
+       if ((fd = open ("/dev/baud0/1", O_WRONLY)) < 3)
+       {
+         myerr = "unable to open audio-device";
+         return 0;
+       }
+	
+	
+  t_info.master_volume=0x7fff;
+  t_info.dither_percent=0;
+	
+  a_init.srate=md_mixfreq;
+  a_init.bits_per_sample=16;
+  a_init.channels=(md_mode & DMODE_STEREO)? 2 : 1;
+  a_init.mode=PCM;
+  a_init.flags=FIXED | BIG_ENDIAN | TWOS_COMPLEMENT;
+  a_init.operation=PLAY;
+	
+  a_change.balance=0x3fff0000;
+  a_change.balance_delay=0;
+  a_change.volume=(long)(volume * (float)0x7FFFFFFF);
+  a_change.volume_delay=0;
+  a_change.monitor=AUDIO_IGNORE;
+  a_change.input=AUDIO_IGNORE;
+  a_change.output=OUTPUT_1;
+  a_change.dev_info=&t_info;
+
+  a_control.ioctl_request=AUDIO_CHANGE;
+  a_control.position=0;
+  a_control.request_info=&a_change;
+
+  if (ioctl(fd, AUDIO_INIT, &a_init) == -1 )
+  {
+    myerr = "configuration (init) of audio device failed";
+    return 0;
+  }
+  if (ioctl(fd, AUDIO_CONTROL, &a_control) == -1 )
+  {
+    myerr = "configuration (control) of audio device failed";
+    return 0;
+  }
+
+  a_control.ioctl_request=AUDIO_START;
+  a_control.request_info=NULL;
+  if (ioctl(fd, AUDIO_CONTROL, &a_control) == -1 )
+  {
+    myerr = "configuration (start) of audio device failed";
+    return 0;
+  }
+	
+#if 0
+	if ((flags = fcntl (fd, F_GETFL, 0)) < 0) {
+		myerr = "unable to set non-blocking mode for /dev/audio";
+		return 0;
+	}
+	flags |= O_NDELAY;
+	if (fcntl (fd, F_SETFL, flags) < 0) {
+		myerr = "unable to set non-blocking mode for /dev/audio";
+		return 0;
+	}
+#endif
+	
+	if(!VC_Init()){
+		close(fd);
+		return 0;
+	}
+
+	return 1;
+}
+
+
+
+static void AIX_Exit(void)
+{
+	VC_Exit();
+	close(fd);
+}
+
+
+static void AIX_Update(void)
+{
+	VC_WriteBytes(RAW_DMABUF,RAWBUFFERSIZE);
+	write(fd, RAW_DMABUF, RAWBUFFERSIZE);
+}
+
+
+DRIVER drv_aix={
+	NULL,
+	"AIX audio-device",
+	"MikMod AIX audio-device driver v1.10",
+	AIX_IsThere,
+	VC_SampleLoad,
+	VC_SampleUnload,
+	VC_SampleSpace,
+	VC_SampleLength,
+	AIX_Init,
+	AIX_Exit,
+	VC_SetNumChannels,
+	VC_PlayStart,
+	VC_PlayStop,
+	AIX_Update,
+	VC_VoiceSetVolume,
+	VC_VoiceSetFrequency,
+	VC_VoiceSetPanning,
+	VC_VoicePlay,
+	VC_VoiceStop,
+	VC_VoiceStopped,
+	VC_VoiceReleaseSustain,
+	VC_VoiceGetPosition,
+	VC_RealVolume
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/unix_drv/drv_hp.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,167 @@
+/*
+
+Name:
+drv_hp.c
+
+Description:
+Mikmod driver for output to HP 9000 series /dev/audio
+
+Portability:
+
+HP-UX only
+
+Written by Lutz Vieweg <lkv@mania.robin.de>
+based on drv_raw.c
+
+Feel free to distribute just as you like.
+No warranties at all.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/audio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "mikmod.h"
+
+static int fd;
+#define RAWBUFFERSIZE 16384
+static char RAW_DMABUF[RAWBUFFERSIZE];
+
+static BOOL HP_IsThere(void)
+{
+	return 1;
+}
+
+static BOOL HP_Init(void)
+{
+	int flags;
+	
+	if (! (md_mode & DMODE_16BITS)) {
+		myerr = "sorry, this driver supports 16-bit linear output only";
+		return 0;
+	}
+	
+	if ((fd = open("/dev/audio", O_WRONLY | O_NDELAY, 0)) < 0) {
+		myerr = "unable to open /dev/audio";
+		return 0;
+	}
+	
+	if ((flags = fcntl (fd, F_GETFL, 0)) < 0) {
+		myerr = "unable to set non-blocking mode for /dev/audio";
+		return 0;
+	}
+	flags |= O_NDELAY;
+	if (fcntl (fd, F_SETFL, flags) < 0) {
+		myerr = "unable to set non-blocking mode for /dev/audio";
+		return 0;
+	}
+	
+	if (ioctl(fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) {
+		myerr = "unable to select 16bit-linear sample format";
+		return 0;
+	}
+	
+	if (ioctl(fd, AUDIO_SET_SAMPLE_RATE, md_mixfreq)) {
+		myerr = "unable to select requested sample-rate";
+		return 0;
+	}
+	
+	if (ioctl(fd, AUDIO_SET_CHANNELS, (md_mode & DMODE_STEREO)? 2 : 1)) {
+		myerr = "unable to select requested number of channels";
+		return 0;
+	}
+	
+	/*
+	  choose between:
+	  AUDIO_OUT_SPEAKER
+	  AUDIO_OUT_HEADPHONE
+	  AUDIO_OUT_LINE
+	*/
+	if (ioctl(fd, AUDIO_SET_OUTPUT, 
+	              AUDIO_OUT_SPEAKER | AUDIO_OUT_HEADPHONE | AUDIO_OUT_LINE)) {
+		myerr = "unable to select audio output";
+		return 0;
+	}
+
+	{
+		struct audio_describe description;
+		struct audio_gains gains;
+		float volume = 1.0;
+		if (ioctl(fd, AUDIO_DESCRIBE, &description)) {
+			myerr = "unable to get audio description";
+			return 0;
+		}
+		if (ioctl (fd, AUDIO_GET_GAINS, &gains)) {
+			myerr = "unable to get gain values";
+			return 0;
+		}
+		
+		gains.transmit_gain = (int)((float)description.min_transmit_gain +
+                                  (float)(description.max_transmit_gain
+                                          - description.min_transmit_gain)
+                                          * volume);
+		if (ioctl (fd, AUDIO_SET_GAINS, &gains)) {
+			myerr = "unable to set gain values";
+			return 0;
+		}
+	}
+	
+	if (ioctl(fd, AUDIO_SET_TXBUFSIZE, RAWBUFFERSIZE*8)) {
+		myerr = "unable to set transmission buffer size";
+		return 0;
+	}
+	
+	if(!VC_Init()){
+		close(fd);
+		return 0;
+	}
+
+	return 1;
+}
+
+
+
+static void HP_Exit(void)
+{
+	VC_Exit();
+	close(fd);
+}
+
+
+static void HP_Update(void)
+{
+	VC_WriteBytes(RAW_DMABUF,RAWBUFFERSIZE);
+	write(fd, RAW_DMABUF, RAWBUFFERSIZE);
+}
+
+
+DRIVER drv_hp={
+	NULL,
+	"HP-UX /dev/audio",
+	"MikMod HP-UX /dev/audio driver v1.10",
+	HP_IsThere,
+	VC_SampleLoad,
+	VC_SampleUnload,
+	VC_SampleSpace,
+	VC_SampleLength,
+	HP_Init,
+	HP_Exit,
+	VC_SetNumChannels,
+	VC_PlayStart,
+	VC_PlayStop,
+	HP_Update,
+	VC_VoiceSetVolume,
+	VC_VoiceSetFrequency,
+	VC_VoiceSetPanning,
+	VC_VoicePlay,
+	VC_VoiceStop,
+	VC_VoiceStopped,
+	VC_VoiceReleaseSustain,
+	VC_VoiceGetPosition,
+	VC_RealVolume
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playercode/unix_drv/drv_sgi.c	Fri Jan 23 16:05:10 1998 +0000
@@ -0,0 +1,174 @@
+/*
+
+Name:
+DRV_SGI.C, version 0.2
+Copyright 1996 by Stephan Kanthak, kanthak@i6.informatik.rwth-aachen.de
+
+Version 0.2 - updated to use new driver API
+
+Description:
+Mikmod driver for output on SGI audio system (needs libaudio from the
+dmedia package).
+
+Portability:
+SGI only. Mainly based on voxware driver.
+
+Fragment configuration:
+=======================
+
+You can use the environment variables 'MM_SGI_FRAGSIZE' and
+'MM_SGI_BUFSIZE' to override the default size of the audio buffer. If you
+experience crackles & pops, try experimenting with these values.
+
+Please read README.SGI first before contacting the author because there are
+some things to know about the specials of the SGI audio driver.
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dmedia/audio.h>
+#include "mikmod.h"
+
+#define DEFAULT_SGI_FRAGSIZE  5000
+#define DEFAULT_SGI_BUFSIZE   10000
+
+static ALconfig sgi_config;
+static ALport sgi_port;
+static int sample_factor;
+static int sgi_fragsize;
+static int sgi_bufsize;
+static char* audiobuffer;
+
+
+static BOOL SGI_IsThere(void)
+{
+	long params[] = { AL_OUTPUT_RATE, 0 };
+
+	ALqueryparams(AL_DEFAULT_DEVICE, params, 2);
+	if (params[1] != 0) return 1;
+	else return 0;
+}
+
+static BOOL SGI_Init(void)
+{
+	char *env;
+	int play_rate;
+	int fragsize,numfrags;
+	long chpars[] = { AL_OUTPUT_RATE, AL_RATE_22050 };
+
+	printf("SGI audio driver: ");
+	switch(md_mixfreq) {
+	case 22050:
+		chpars[1] = AL_RATE_22050;
+		break;
+	case 44100:
+		chpars[1] = AL_RATE_44100;
+		break;
+	default:
+		printf("mixing rate not supported.\n");
+		return 0;
+		break;
+	}
+	ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);
+
+	if ((sgi_config = ALnewconfig()) == 0) {
+		printf("cannot configure sound device.\n");
+		return 0;
+	}
+	
+	if (md_mode & DMODE_16BITS) {
+		if (ALsetwidth(sgi_config, AL_SAMPLE_16) < 0) {
+			printf("samplesize of 16 bits not supported.\n");
+			return 0;
+		}
+		sample_factor = 2;
+	} else {
+		if (ALsetwidth(sgi_config, AL_SAMPLE_8) < 0) {
+			printf("samplesize of 8 bits not supported.\n");
+			return 0;
+		}
+		sample_factor = 1;
+	}
+
+	if (md_mode & DMODE_STEREO) {
+		if (ALsetchannels(sgi_config, AL_STEREO) < 0) {
+			printf("stereo mode not supported.\n");
+			return 0;
+		}
+	} else{
+		if (ALsetchannels(sgi_config, AL_MONO) < 0) {
+			printf("mono mode not supported.\n");
+			return 0;
+		}
+	}
+
+	if(!VC_Init()){
+		return 0;
+	}
+
+	sgi_fragsize=(env=getenv("MM_SGI_FRAGSIZE")) ? atol(env) : DEFAULT_SGI_BUFSIZE;
+	sgi_bufsize=(env=getenv("MM_SGI_BUFSIZE")) ? atol(env) : DEFAULT_SGI_BUFSIZE;
+
+	ALsetqueuesize(sgi_config, sgi_bufsize);
+	if ((sgi_port = ALopenport("Mod4X", "w", sgi_config)) == 0) {
+		printf("cannot open SGI audio port.\n");
+		return 0;
+	}
+	printf("%dHz/%dBits/", md_mixfreq, 8*sample_factor);
+	if (md_mode & DMODE_STEREO) printf("stereo.\n");
+	else printf("mono.\n");
+
+
+	audiobuffer = (char*) MyMalloc(sgi_fragsize * sizeof(char));
+
+	if(audiobuffer==NULL){
+		VC_Exit();
+		return 0;
+	}
+	
+	return 1;
+}
+
+
+static void SGI_Exit(void)
+{
+	free(audiobuffer);
+	VC_Exit();
+}
+
+
+static void SGI_Update(void)
+{
+	VC_WriteBytes(audiobuffer, sgi_fragsize);
+	ALwritesamps(sgi_port,audiobuffer, sgi_fragsize/sample_factor);
+}
+
+
+DRIVER drv_sgi={
+	NULL,
+	"SGI Audio System",
+	"SGI Audio System Driver v0.2 - by Stephan Kanthak",
+	SGI_IsThere,
+	VC_SampleLoad,
+	VC_SampleUnload,
+	VC_SampleSpace,
+	VC_SampleLength,
+	SGI_Init,
+	SGI_Exit,
+	VC_SetNumChannels,
+        VC_PlayStart,
+        VC_PlayStop,
+	SGI_Update,
+	VC_VoiceSetVolume,
+	VC_VoiceSetFrequency,
+	VC_VoiceSetPanning,
+	VC_VoicePlay,
+	VC_VoiceStop,
+	VC_VoiceStopped,
+	VC_VoiceReleaseSustain,
+	VC_VoiceGetPosition,
+	VC_RealVolume
+};