Added an audio driver that writes to disk (thanks Ryan!)
authorSam Lantinga <slouken@lokigames.com>
Sat, 16 Jun 2001 01:51:42 +0000
changeset 68ac6645260d31
parent 67 3647c809813d
child 69 280ff3af2ecc
Added an audio driver that writes to disk (thanks Ryan!)
configure.in
docs.html
src/audio/Makefile.am
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/disk/.cvsignore
src/audio/disk/Makefile.am
src/audio/disk/SDL_diskaudio.c
src/audio/disk/SDL_diskaudio.h
     1.1 --- a/configure.in	Sat Jun 16 01:32:09 2001 +0000
     1.2 +++ b/configure.in	Sat Jun 16 01:51:42 2001 +0000
     1.3 @@ -368,6 +368,21 @@
     1.4      fi
     1.5  }
     1.6  
     1.7 +
     1.8 +dnl rcg07142001 See if the user wants the disk writer audio driver...
     1.9 +CheckDiskAudio()
    1.10 +{
    1.11 +    AC_ARG_ENABLE(diskaudio,
    1.12 +[  --enable-diskaudio  	  support the disk writer audio driver [default=no]],
    1.13 +                  , enable_diskaudio=no)
    1.14 +    if test x$enable_audio = xyes -a x$enable_diskaudio = xyes; then
    1.15 +        CFLAGS="$CFLAGS -DDISKAUD_SUPPORT"
    1.16 +        AUDIO_SUBDIRS="$AUDIO_SUBDIRS disk"
    1.17 +        AUDIO_DRIVERS="$AUDIO_DRIVERS disk/libaudio_disk.la"
    1.18 +    fi
    1.19 +}
    1.20 +
    1.21 +
    1.22  dnl See if we can use x86 assembly blitters
    1.23  CheckNASM()
    1.24  {
    1.25 @@ -1085,6 +1100,7 @@
    1.26      *-*-linux*)
    1.27          ARCH=linux
    1.28          CheckDummyVideo
    1.29 +        CheckDiskAudio
    1.30          CheckNASM
    1.31          CheckOSS
    1.32          CheckALSA
    1.33 @@ -1151,6 +1167,7 @@
    1.34      *-*-bsdi*)
    1.35          ARCH=bsdi
    1.36          CheckDummyVideo
    1.37 +        CheckDiskAudio
    1.38          CheckNASM
    1.39          CheckOSS
    1.40          CheckARTSC
    1.41 @@ -1194,6 +1211,7 @@
    1.42      *-*-freebsd*)
    1.43          ARCH=freebsd
    1.44          CheckDummyVideo
    1.45 +        CheckDiskAudio
    1.46          CheckNASM
    1.47          CheckOSS
    1.48          CheckARTSC
    1.49 @@ -1246,6 +1264,7 @@
    1.50      *-*-netbsd*)
    1.51          ARCH=netbsd
    1.52          CheckDummyVideo
    1.53 +        CheckDiskAudio
    1.54          CheckNASM
    1.55          CheckOSS
    1.56          CheckARTSC
    1.57 @@ -1297,6 +1316,7 @@
    1.58      *-*-openbsd*)
    1.59          ARCH=openbsd
    1.60          CheckDummyVideo
    1.61 +        CheckDiskAudio
    1.62          CheckNASM
    1.63          CheckOSS
    1.64          CheckARTSC
    1.65 @@ -1345,6 +1365,7 @@
    1.66      *-*-sysv5*)
    1.67          ARCH=sysv5
    1.68          CheckDummyVideo
    1.69 +        CheckDiskAudio
    1.70          CheckNASM
    1.71          CheckOSS
    1.72          CheckARTSC
    1.73 @@ -1392,6 +1413,7 @@
    1.74          ARCH=solaris
    1.75          CFLAGS="$CFLAGS -D__ELF__" # Fix for nasm on Solaris x86
    1.76          CheckDummyVideo
    1.77 +        CheckDiskAudio
    1.78          CheckNASM
    1.79          CheckOSS
    1.80          CheckARTSC
    1.81 @@ -1438,6 +1460,7 @@
    1.82      *-*-irix*)
    1.83          ARCH=irix
    1.84          CheckDummyVideo
    1.85 +        CheckDiskAudio
    1.86          CheckNAS
    1.87          CheckX11
    1.88          CheckAAlib
    1.89 @@ -1496,6 +1519,7 @@
    1.90      *-*-hpux*)
    1.91          ARCH=hpux
    1.92          CheckDummyVideo
    1.93 +        CheckDiskAudio
    1.94          CheckOSS
    1.95          CheckNAS
    1.96          CheckX11
    1.97 @@ -1540,6 +1564,7 @@
    1.98      *-*-aix*)
    1.99          ARCH=aix
   1.100          CheckDummyVideo
   1.101 +        CheckDiskAudio
   1.102          CheckOSS
   1.103          CheckNAS
   1.104          CheckX11
   1.105 @@ -1583,6 +1608,7 @@
   1.106      *-*-osf*)
   1.107          ARCH=osf
   1.108          CheckDummyVideo
   1.109 +        CheckDiskAudio
   1.110          CheckNAS
   1.111          CheckX11
   1.112          CheckGGI
   1.113 @@ -1626,6 +1652,7 @@
   1.114      *-*-qnx*)
   1.115          ARCH=qnx
   1.116          CheckDummyVideo
   1.117 +        CheckDiskAudio
   1.118          CheckNAS
   1.119          CheckPHOTON
   1.120          CheckX11
   1.121 @@ -1680,6 +1707,7 @@
   1.122              fi
   1.123          fi
   1.124          CheckDummyVideo
   1.125 +        CheckDiskAudio
   1.126          CheckWIN32
   1.127          CheckDIRECTX
   1.128          CheckNASM
   1.129 @@ -1736,6 +1764,7 @@
   1.130          ARCH=beos
   1.131          ac_default_prefix=/boot/develop/tools/gnupro
   1.132          CheckDummyVideo
   1.133 +        CheckDiskAudio
   1.134          CheckNASM
   1.135          CheckBWINDOW
   1.136          CheckBeGL
   1.137 @@ -1781,6 +1810,7 @@
   1.138          # for which this case would be handy.
   1.139          ARCH=macos
   1.140          CheckDummyVideo
   1.141 +        CheckDiskAudio
   1.142          CheckTOOLBOX
   1.143          CheckMacGL
   1.144          # Set up files for the main() stub
   1.145 @@ -1824,6 +1854,7 @@
   1.146          # config.guess comes back with "darwin", so go with the flow.
   1.147          ARCH=macos
   1.148          CheckDummyVideo
   1.149 +        CheckDiskAudio
   1.150          CheckCARBON
   1.151          CheckMacGL
   1.152          CheckPTHREAD
   1.153 @@ -1973,6 +2004,7 @@
   1.154  src/audio/ums/Makefile
   1.155  src/audio/windib/Makefile
   1.156  src/audio/windx5/Makefile
   1.157 +src/audio/disk/Makefile
   1.158  src/video/Makefile
   1.159  src/video/cybergfx/Makefile
   1.160  src/video/x11/Makefile
     2.1 --- a/docs.html	Sat Jun 16 01:32:09 2001 +0000
     2.2 +++ b/docs.html	Sat Jun 16 01:51:42 2001 +0000
     2.3 @@ -16,6 +16,7 @@
     2.4  Major changes since SDL 1.0.0:
     2.5  </H2>
     2.6  <UL>
     2.7 +	<LI> 1.2.1: Added an audio driver that writes to disk (thanks Ryan!)
     2.8  	<LI> 1.2.1: Mouse wheel sends mouse button (4/5) events on Windows
     2.9  	<LI> 1.2.1: Added MacOS X Project Builder projects (thanks Darrell!)
    2.10  	<LI> 1.2.1: Added initial support for Quartz video (thanks Darrell!)
     3.1 --- a/src/audio/Makefile.am	Sat Jun 16 01:32:09 2001 +0000
     3.2 +++ b/src/audio/Makefile.am	Sat Jun 16 01:51:42 2001 +0000
     3.3 @@ -5,8 +5,7 @@
     3.4  
     3.5  # Define which subdirectories need to be built
     3.6  SUBDIRS = @AUDIO_SUBDIRS@
     3.7 -DIST_SUBDIRS = alsa arts baudio dma dmedia dsp esd macrom nas nto \
     3.8 -               openbsd paudio sun ums windib windx5
     3.9 +DIST_SUBDIRS = alsa arts baudio dma dmedia dsp esd macrom nas nto openbsd paudio sun ums windib windx5 disk
    3.10  
    3.11  DRIVERS = @AUDIO_DRIVERS@
    3.12  
     4.1 --- a/src/audio/SDL_audio.c	Sat Jun 16 01:32:09 2001 +0000
     4.2 +++ b/src/audio/SDL_audio.c	Sat Jun 16 01:51:42 2001 +0000
     4.3 @@ -81,7 +81,9 @@
     4.4  #ifdef ENABLE_AHI
     4.5  	&AHI_bootstrap,
     4.6  #endif
     4.7 -
     4.8 +#ifdef DISKAUD_SUPPORT
     4.9 +	&DISKAUD_bootstrap,
    4.10 +#endif
    4.11  	NULL
    4.12  };
    4.13  SDL_AudioDevice *current_audio = NULL;
     5.1 --- a/src/audio/SDL_sysaudio.h	Sat Jun 16 01:32:09 2001 +0000
     5.2 +++ b/src/audio/SDL_sysaudio.h	Sat Jun 16 01:51:42 2001 +0000
     5.3 @@ -140,6 +140,9 @@
     5.4  #ifdef ENABLE_AHI
     5.5  extern AudioBootStrap AHI_bootstrap;
     5.6  #endif
     5.7 +#ifdef DISKAUD_SUPPORT
     5.8 +extern AudioBootStrap DISKAUD_bootstrap;
     5.9 +#endif
    5.10  
    5.11  /* This is the current audio device */
    5.12  extern SDL_AudioDevice *current_audio;
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/audio/disk/.cvsignore	Sat Jun 16 01:51:42 2001 +0000
     6.3 @@ -0,0 +1,6 @@
     6.4 +Makefile.in
     6.5 +Makefile
     6.6 +.libs
     6.7 +*.o
     6.8 +*.lo
     6.9 +*.la
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/audio/disk/Makefile.am	Sat Jun 16 01:51:42 2001 +0000
     7.3 @@ -0,0 +1,9 @@
     7.4 +
     7.5 +## Makefile.am for SDL audio "driver" that writes to a file.
     7.6 +
     7.7 +noinst_LTLIBRARIES = libaudio_disk.la
     7.8 +libaudio_disk_la_SOURCES = $(SRCS)
     7.9 +
    7.10 +# The SDL audio driver sources
    7.11 +SRCS =	SDL_diskaudio.c	\
    7.12 +	SDL_diskaudio.h
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/audio/disk/SDL_diskaudio.c	Sat Jun 16 01:51:42 2001 +0000
     8.3 @@ -0,0 +1,222 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@devolution.com
    8.24 +
    8.25 +    This file hacked^H^H^H^H^H^Hwritten by Ryan C. Gordon
    8.26 +        (icculus@linuxgames.com)
    8.27 +*/
    8.28 +
    8.29 +#ifdef SAVE_RCSID
    8.30 +static char rcsid =
    8.31 + "@(#) $Id$";
    8.32 +#endif
    8.33 +
    8.34 +/* Output raw audio data to a file. */
    8.35 +
    8.36 +#include <stdlib.h>
    8.37 +#include <stdio.h>
    8.38 +#include <string.h>
    8.39 +#include <errno.h>
    8.40 +#include <unistd.h>
    8.41 +#include <sys/stat.h>
    8.42 +#include <sys/types.h>
    8.43 +#include <sys/stat.h>
    8.44 +#include <fcntl.h>
    8.45 +
    8.46 +
    8.47 +#include "SDL_audio.h"
    8.48 +#include "SDL_error.h"
    8.49 +#include "SDL_audiomem.h"
    8.50 +#include "SDL_audio_c.h"
    8.51 +#include "SDL_timer.h"
    8.52 +#include "SDL_audiodev_c.h"
    8.53 +#include "SDL_diskaudio.h"
    8.54 +
    8.55 +/* The tag name used by DISK audio */
    8.56 +#define DISKAUD_DRIVER_NAME         "disk"
    8.57 +
    8.58 +/* environment variables and defaults. */
    8.59 +#define DISKENVR_OUTFILE         "SDL_DISKAUDIOFILE"
    8.60 +#define DISKDEFAULT_OUTFILE      "sdlaudio.raw"
    8.61 +#define DISKENVR_WRITEDELAY      "SDL_DISKAUDIODELAY"
    8.62 +#define DISKDEFAULT_WRITEDELAY   150
    8.63 +
    8.64 +/* Audio driver functions */
    8.65 +static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec);
    8.66 +static void DISKAUD_WaitAudio(_THIS);
    8.67 +static void DISKAUD_PlayAudio(_THIS);
    8.68 +static Uint8 *DISKAUD_GetAudioBuf(_THIS);
    8.69 +static void DISKAUD_CloseAudio(_THIS);
    8.70 +
    8.71 +static const char *DISKAUD_GetOutputFilename(void)
    8.72 +{
    8.73 +    const char *envr = getenv(DISKENVR_OUTFILE);
    8.74 +    return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE);
    8.75 +}
    8.76 +
    8.77 +/* Audio driver bootstrap functions */
    8.78 +static int DISKAUD_Available(void)
    8.79 +{
    8.80 +#if 0
    8.81 +    int fd;
    8.82 +	int available;
    8.83 +    int exists = 0;
    8.84 +    struct stat statbuf;
    8.85 +    const char *fname = DISKAUD_GetOutputFilename();
    8.86 +
    8.87 +	available = 0;
    8.88 +
    8.89 +    if (stat(fname, &statbuf) == 0)
    8.90 +        exists = 1;
    8.91 +
    8.92 +    fd = open(fname, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    8.93 +	if ( fd != -1 ) {
    8.94 +		available = 1;
    8.95 +		close(fd);
    8.96 +        if (!exists) {
    8.97 +            unlink(fname);
    8.98 +        }
    8.99 +	}
   8.100 +	return(available);
   8.101 +#else
   8.102 +    return(1);
   8.103 +#endif
   8.104 +}
   8.105 +
   8.106 +static void DISKAUD_DeleteDevice(SDL_AudioDevice *device)
   8.107 +{
   8.108 +	free(device->hidden);
   8.109 +	free(device);
   8.110 +}
   8.111 +
   8.112 +static SDL_AudioDevice *DISKAUD_CreateDevice(int devindex)
   8.113 +{
   8.114 +	SDL_AudioDevice *this;
   8.115 +    const char *envr;
   8.116 +
   8.117 +	/* Initialize all variables that we clean on shutdown */
   8.118 +	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
   8.119 +	if ( this ) {
   8.120 +		memset(this, 0, (sizeof *this));
   8.121 +		this->hidden = (struct SDL_PrivateAudioData *)
   8.122 +				malloc((sizeof *this->hidden));
   8.123 +	}
   8.124 +	if ( (this == NULL) || (this->hidden == NULL) ) {
   8.125 +		SDL_OutOfMemory();
   8.126 +		if ( this ) {
   8.127 +			free(this);
   8.128 +		}
   8.129 +		return(0);
   8.130 +	}
   8.131 +	memset(this->hidden, 0, (sizeof *this->hidden));
   8.132 +
   8.133 +    envr = getenv(DISKENVR_WRITEDELAY);
   8.134 +    this->hidden->write_delay = (envr) ? atoi(envr) : DISKDEFAULT_WRITEDELAY;
   8.135 +
   8.136 +	/* Set the function pointers */
   8.137 +	this->OpenAudio = DISKAUD_OpenAudio;
   8.138 +	this->WaitAudio = DISKAUD_WaitAudio;
   8.139 +	this->PlayAudio = DISKAUD_PlayAudio;
   8.140 +	this->GetAudioBuf = DISKAUD_GetAudioBuf;
   8.141 +	this->CloseAudio = DISKAUD_CloseAudio;
   8.142 +
   8.143 +	this->free = DISKAUD_DeleteDevice;
   8.144 +
   8.145 +	return this;
   8.146 +}
   8.147 +
   8.148 +AudioBootStrap DISKAUD_bootstrap = {
   8.149 +	DISKAUD_DRIVER_NAME, "direct-to-disk audio",
   8.150 +	DISKAUD_Available, DISKAUD_CreateDevice
   8.151 +};
   8.152 +
   8.153 +/* This function waits until it is possible to write a full sound buffer */
   8.154 +static void DISKAUD_WaitAudio(_THIS)
   8.155 +{
   8.156 +    SDL_Delay(this->hidden->write_delay);
   8.157 +}
   8.158 +
   8.159 +static void DISKAUD_PlayAudio(_THIS)
   8.160 +{
   8.161 +	int written;
   8.162 +
   8.163 +	/* Write the audio data, checking for EAGAIN on broken audio drivers */
   8.164 +	do {
   8.165 +		written = write(this->hidden->audio_fd,
   8.166 +                        this->hidden->mixbuf,
   8.167 +                        this->hidden->mixlen);
   8.168 +		if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) {
   8.169 +			SDL_Delay(1);	/* Let a little CPU time go by */
   8.170 +		}
   8.171 +	} while ( (written < 0) && 
   8.172 +	          ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) );
   8.173 +
   8.174 +	/* If we couldn't write, assume fatal error for now */
   8.175 +	if ( written < 0 ) {
   8.176 +		this->enabled = 0;
   8.177 +	}
   8.178 +#ifdef DEBUG_AUDIO
   8.179 +	fprintf(stderr, "Wrote %d bytes of audio data\n", written);
   8.180 +#endif
   8.181 +}
   8.182 +
   8.183 +static Uint8 *DISKAUD_GetAudioBuf(_THIS)
   8.184 +{
   8.185 +	return(this->hidden->mixbuf);
   8.186 +}
   8.187 +
   8.188 +static void DISKAUD_CloseAudio(_THIS)
   8.189 +{
   8.190 +	if ( this->hidden->mixbuf != NULL ) {
   8.191 +		SDL_FreeAudioMem(this->hidden->mixbuf);
   8.192 +		this->hidden->mixbuf = NULL;
   8.193 +	}
   8.194 +	if ( this->hidden->audio_fd >= 0 ) {
   8.195 +		close(this->hidden->audio_fd);
   8.196 +		this->hidden->audio_fd = -1;
   8.197 +	}
   8.198 +}
   8.199 +
   8.200 +static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
   8.201 +{
   8.202 +    const char *fname = DISKAUD_GetOutputFilename();
   8.203 +
   8.204 +	/* Open the audio device */
   8.205 +    this->hidden->audio_fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
   8.206 +	if ( this->hidden->audio_fd < 0 ) {
   8.207 +		SDL_SetError("Couldn't open %s: %s", fname, strerror(errno));
   8.208 +		return(-1);
   8.209 +	}
   8.210 +
   8.211 +    fprintf(stderr, "WARNING: You are using the SDL disk writer"
   8.212 +                    " audio driver!\n Writing to file [%s].\n", fname);
   8.213 +
   8.214 +	/* Allocate mixing buffer */
   8.215 +	this->hidden->mixlen = spec->size;
   8.216 +	this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   8.217 +	if ( this->hidden->mixbuf == NULL ) {
   8.218 +		return(-1);
   8.219 +	}
   8.220 +	memset(this->hidden->mixbuf, spec->silence, spec->size);
   8.221 +
   8.222 +	/* We're ready to rock and roll. :-) */
   8.223 +	return(0);
   8.224 +}
   8.225 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/audio/disk/SDL_diskaudio.h	Sat Jun 16 01:51:42 2001 +0000
     9.3 @@ -0,0 +1,44 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Library General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Library General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Library General Public
    9.19 +    License along with this library; if not, write to the Free
    9.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@devolution.com
    9.24 +*/
    9.25 +
    9.26 +#ifdef SAVE_RCSID
    9.27 +static char rcsid =
    9.28 + "@(#) $Id$";
    9.29 +#endif
    9.30 +
    9.31 +#ifndef _SDL_diskaudio_h
    9.32 +#define _SDL_diskaudio_h
    9.33 +
    9.34 +#include "SDL_sysaudio.h"
    9.35 +
    9.36 +/* Hidden "this" pointer for the video functions */
    9.37 +#define _THIS	SDL_AudioDevice *this
    9.38 +
    9.39 +struct SDL_PrivateAudioData {
    9.40 +	/* The file descriptor for the audio device */
    9.41 +	int audio_fd;
    9.42 +    Uint8 *mixbuf;
    9.43 +    Uint32 mixlen;
    9.44 +    Uint32 write_delay;
    9.45 +};
    9.46 +
    9.47 +#endif /* _SDL_diskaudio_h */