diff options
Diffstat (limited to 'WinQuake/snd_sun.c')
| -rw-r--r-- | WinQuake/snd_sun.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/WinQuake/snd_sun.c b/WinQuake/snd_sun.c new file mode 100644 index 0000000..fe9f8bb --- /dev/null +++ b/WinQuake/snd_sun.c @@ -0,0 +1,218 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. + +This program 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. + +This program 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. + +*/ +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/shm.h> +#include <sys/wait.h> +#include <stdio.h> +#include <sys/audioio.h> +#include <errno.h> +#include "quakedef.h" + +int audio_fd; +int snd_inited; + +static int bufpos; +static int wbufp; +static audio_info_t info; + +#define BUFFER_SIZE 8192 + +unsigned char dma_buffer[BUFFER_SIZE]; +unsigned char pend_buffer[BUFFER_SIZE]; +int pending; + +static int lastwrite = 0; + +qboolean SNDDMA_Init(void) +{ + int rc; + int fmt; + int tmp; + int i; + char *s; + int caps; + + if (snd_inited) { + printf("Sound already init'd\n"); + return; + } + + shm = &sn; + shm->splitbuffer = 0; + + audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY); + + if (audio_fd < 0) { + if (errno == EBUSY) { + Con_Printf("Audio device is being used by another process\n"); + } + perror("/dev/audio"); + Con_Printf("Could not open /dev/audio\n"); + return (0); + } + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + return 0; + } + + // + // set to nonblock + // + if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) { + perror("/dev/audio"); + close(audio_fd); + return 0; + } + + AUDIO_INITINFO(&info); + + shm->speed = 11025; + + // try 16 bit stereo + info.play.encoding = AUDIO_ENCODING_LINEAR; + info.play.sample_rate = 11025; + info.play.channels = 2; + info.play.precision = 16; + + if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { + info.play.encoding = AUDIO_ENCODING_LINEAR; + info.play.sample_rate = 11025; + info.play.channels = 1; + info.play.precision = 16; + if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { + Con_Printf("Incapable sound hardware.\n"); + close(audio_fd); + return 0; + } + Con_Printf("16 bit mono sound initialized\n"); + shm->samplebits = 16; + shm->channels = 1; + } else { // 16 bit stereo + Con_Printf("16 bit stereo sound initialized\n"); + shm->samplebits = 16; + shm->channels = 2; + } + + shm->soundalive = true; + shm->samples = sizeof(dma_buffer) / (shm->samplebits/8); + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *)dma_buffer; + + snd_inited = 1; + + return 1; +} + +int SNDDMA_GetDMAPos(void) +{ + if (!snd_inited) + return (0); + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + snd_inited = 0; + return (0); + } + + return ((info.play.samples*shm->channels) % shm->samples); +} + +int SNDDMA_GetSamples(void) +{ + if (!snd_inited) + return (0); + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + snd_inited = 0; + return (0); + } + + return info.play.samples; +} + +void SNDDMA_Shutdown(void) +{ + if (snd_inited) { + close(audio_fd); + snd_inited = 0; + } +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +=============== +*/ +void SNDDMA_Submit(void) +{ + int samps; + int bsize; + int bytes, b; + static unsigned char writebuf[1024]; + unsigned char *p; + int idx; + int stop = paintedtime; + extern int soundtime; + + if (paintedtime < wbufp) + wbufp = 0; // reset + + bsize = shm->channels * (shm->samplebits/8); + bytes = (paintedtime - wbufp) * bsize; + + if (!bytes) + return; + + if (bytes > sizeof(writebuf)) { + bytes = sizeof(writebuf); + stop = wbufp + bytes/bsize; + } + + p = writebuf; + idx = (wbufp*bsize) & (BUFFER_SIZE - 1); + + for (b = bytes; b; b--) { + *p++ = dma_buffer[idx]; + idx = (idx + 1) & (BUFFER_SIZE - 1); + } + + wbufp = stop; + + if (write(audio_fd, writebuf, bytes) < bytes) + printf("audio can't keep up!\n"); + +} + |
