From dcd924c35570d1329d78a69f9399707750b16e68 Mon Sep 17 00:00:00 2001 From: Adam Olsen Date: Tue, 10 Apr 2001 09:44:36 +0000 Subject: [PATCH] Removed old files --- nq/source/snd_alsa_0_5.c | 358 ----------- nq/source/snd_alsa_0_9.c | 313 ---------- nq/source/snd_disk.c | 108 ---- nq/source/snd_dma.c | 1016 ------------------------------ nq/source/snd_dos.c | 648 ------------------- nq/source/snd_gus.c | 1281 -------------------------------------- nq/source/snd_mem.c | 405 ------------ nq/source/snd_mix.c | 429 ------------- nq/source/snd_mixa.S | 232 ------- nq/source/snd_next.c | 73 --- nq/source/snd_null.c | 145 ----- nq/source/snd_oss.c | 297 --------- nq/source/snd_sdl.c | 158 ----- nq/source/snd_sgi.c | 311 --------- nq/source/snd_sun.c | 228 ------- nq/source/snd_win.c | 725 --------------------- qw/source/snd_alsa_0_5.c | 358 ----------- qw/source/snd_alsa_0_9.c | 313 ---------- qw/source/snd_disk.c | 108 ---- qw/source/snd_dma.c | 1016 ------------------------------ qw/source/snd_gus.c | 1281 -------------------------------------- qw/source/snd_mem.c | 405 ------------ qw/source/snd_mix.c | 429 ------------- qw/source/snd_mixa.S | 232 ------- qw/source/snd_null.c | 145 ----- qw/source/snd_oss.c | 297 --------- qw/source/snd_sdl.c | 158 ----- qw/source/snd_sgi.c | 311 --------- qw/source/snd_sun.c | 228 ------- qw/source/snd_win.c | 725 --------------------- 30 files changed, 12733 deletions(-) delete mode 100644 nq/source/snd_alsa_0_5.c delete mode 100644 nq/source/snd_alsa_0_9.c delete mode 100644 nq/source/snd_disk.c delete mode 100644 nq/source/snd_dma.c delete mode 100644 nq/source/snd_dos.c delete mode 100644 nq/source/snd_gus.c delete mode 100644 nq/source/snd_mem.c delete mode 100644 nq/source/snd_mix.c delete mode 100644 nq/source/snd_mixa.S delete mode 100644 nq/source/snd_next.c delete mode 100644 nq/source/snd_null.c delete mode 100644 nq/source/snd_oss.c delete mode 100644 nq/source/snd_sdl.c delete mode 100644 nq/source/snd_sgi.c delete mode 100644 nq/source/snd_sun.c delete mode 100644 nq/source/snd_win.c delete mode 100644 qw/source/snd_alsa_0_5.c delete mode 100644 qw/source/snd_alsa_0_9.c delete mode 100644 qw/source/snd_disk.c delete mode 100644 qw/source/snd_dma.c delete mode 100644 qw/source/snd_gus.c delete mode 100644 qw/source/snd_mem.c delete mode 100644 qw/source/snd_mix.c delete mode 100644 qw/source/snd_mixa.S delete mode 100644 qw/source/snd_null.c delete mode 100644 qw/source/snd_oss.c delete mode 100644 qw/source/snd_sdl.c delete mode 100644 qw/source/snd_sgi.c delete mode 100644 qw/source/snd_sun.c delete mode 100644 qw/source/snd_win.c diff --git a/nq/source/snd_alsa_0_5.c b/nq/source/snd_alsa_0_5.c deleted file mode 100644 index a59fdd9cc..000000000 --- a/nq/source/snd_alsa_0_5.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - snd_alsa_0_5.c - - Support for ALSA 0.5, the old stable version of ALSA. - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#if defined HAVE_SYS_SOUNDCARD_H -# include -#elif defined HAVE_LINUX_SOUNDCARD_H -# include -#elif HAVE_MACHINE_SOUNDCARD_H -# include -#endif - -#include - -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -#ifndef MAP_FAILED -# define MAP_FAILED ((void*)-1) -#endif - -static int snd_inited; - -static snd_pcm_t *pcm_handle; -static struct snd_pcm_channel_info cinfo; -static struct snd_pcm_channel_params params; -static struct snd_pcm_channel_setup setup; -static snd_pcm_mmap_control_t *mmap_control = NULL; -static char *mmap_data = NULL; -static int card = -1, dev = -1; - -int -check_card (int card) -{ - snd_ctl_t *handle; - snd_ctl_hw_info_t info; - int rc; - - if ((rc = snd_ctl_open (&handle, card)) < 0) { - Con_Printf ("Error: control open (%i): %s\n", card, snd_strerror (rc)); - return rc; - } - if ((rc = snd_ctl_hw_info (handle, &info)) < 0) { - Con_Printf ("Error: control hardware info (%i): %s\n", card, - snd_strerror (rc)); - snd_ctl_close (handle); - return rc; - } - snd_ctl_close (handle); - if (dev == -1) { - for (dev = 0; dev < info.pcmdevs; dev++) { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) == 0) { - return 0; - } - } - } else { - if (dev >= 0 && dev < info.pcmdevs) { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) == 0) { - return 0; - } - } - } - return 1; -} - -qboolean -SNDDMA_Init (void) -{ - int rc = 0, i; - char *err_msg = ""; - int rate = -1, format = -1, bps, stereo = -1, frag_size; - unsigned int mask; - - mask = snd_cards_mask (); - if (!mask) { - Con_Printf ("No sound cards detected\n"); - return 0; - } - if (snd_device->string[0]) { - sscanf (snd_device->string, "%d,%d", &card, &dev); - } - if (snd_bits->int_val) { - i = snd_bits->int_val; - if (i == 16) { - format = SND_PCM_SFMT_S16_LE; - } else if (i == 8) { - format = SND_PCM_SFMT_U8; - } else { - Con_Printf ("Error: invalid sample bits: %d\n", i); - return 0; - } - } - if (snd_rate->int_val) { - rate = snd_rate->int_val; - if (rate != 44100 && rate != 22050 && rate != 11025) { - Con_Printf ("Error: invalid sample rate: %d\n", rate); - return 0; - } - } - stereo = snd_stereo->int_val; - if (card == -1) { - for (card = 0; card < SND_CARDS; card++) { - if (!(mask & (1 << card))) - continue; - rc = check_card (card); - if (rc < 0) - return 0; - if (!rc) - goto dev_openned; - } - } else { - if (dev == -1) { - rc = check_card (card); - if (rc < 0) - return 0; - if (!rc) - goto dev_openned; - } else { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) < 0) { - Con_Printf ("Error: audio open error: %s\n", snd_strerror (rc)); - return 0; - } - goto dev_openned; - } - } - Con_Printf ("Error: audio open error: %s\n", snd_strerror (rc)); - return 0; - - dev_openned: - Con_Printf ("Using card %d, device %d.\n", card, dev); - memset (&cinfo, 0, sizeof (cinfo)); - cinfo.channel = SND_PCM_CHANNEL_PLAYBACK; - snd_pcm_channel_info (pcm_handle, &cinfo); - Con_Printf ("%08x %08x %08x\n", cinfo.flags, cinfo.formats, cinfo.rates); - if ((rate == -1 || rate == 44100) && cinfo.rates & SND_PCM_RATE_44100) { - rate = 44100; - frag_size = 512; /* assuming stereo 8 bit */ - } else if ((rate == -1 || rate == 22050) - && cinfo.rates & SND_PCM_RATE_22050) { - rate = 22050; - frag_size = 256; /* assuming stereo 8 bit */ - } else if ((rate == -1 || rate == 11025) - && cinfo.rates & SND_PCM_RATE_11025) { - rate = 11025; - frag_size = 128; /* assuming stereo 8 bit */ - } else { - Con_Printf ("ALSA: desired rates not supported\n"); - goto error_2; - } - if ((format == -1 || format == SND_PCM_SFMT_S16_LE) - && cinfo.formats & SND_PCM_FMT_S16_LE) { - format = SND_PCM_SFMT_S16_LE; - bps = 16; - frag_size *= 2; - } else if ((format == -1 || format == SND_PCM_SFMT_U8) - && cinfo.formats & SND_PCM_FMT_U8) { - format = SND_PCM_SFMT_U8; - bps = 8; - } else { - Con_Printf ("ALSA: desired formats not supported\n"); - goto error_2; - } - if (stereo && cinfo.max_voices >= 2) { - stereo = 1; - } else { - stereo = 0; - frag_size /= 2; - } - -// err_msg="audio flush"; -// if ((rc=snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) -// goto error; - err_msg = "audio munmap"; - if ((rc = snd_pcm_munmap (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) - goto error; - - memset (¶ms, 0, sizeof (params)); - params.channel = SND_PCM_CHANNEL_PLAYBACK; - params.mode = SND_PCM_MODE_BLOCK; - params.format.interleave = 1; - params.format.format = format; - params.format.rate = rate; - params.format.voices = stereo + 1; - params.start_mode = SND_PCM_START_GO; - params.stop_mode = SND_PCM_STOP_ROLLOVER; - params.buf.block.frag_size = frag_size; - params.buf.block.frags_min = 1; - params.buf.block.frags_max = -1; -// err_msg="audio flush"; -// if ((rc=snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) -// goto error; - err_msg = "audio params"; - if ((rc = snd_pcm_channel_params (pcm_handle, ¶ms)) < 0) - goto error; - - err_msg = "audio mmap"; - if ( - (rc = - snd_pcm_mmap (pcm_handle, SND_PCM_CHANNEL_PLAYBACK, &mmap_control, - (void **) &mmap_data)) < 0) - goto error; - err_msg = "audio prepare"; - if ((rc = snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < - 0) goto error; - - memset (&setup, 0, sizeof (setup)); - setup.mode = SND_PCM_MODE_BLOCK; - setup.channel = SND_PCM_CHANNEL_PLAYBACK; - err_msg = "audio setup"; - if ((rc = snd_pcm_channel_setup (pcm_handle, &setup)) < 0) - goto error; - - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = setup.format.voices; - shm->submission_chunk = 128; // don't mix less than this # - shm->samplepos = 0; // in mono samples - shm->samplebits = setup.format.format == SND_PCM_SFMT_S16_LE ? 16 : 8; - shm->samples = - setup.buf.block.frags * setup.buf.block.frag_size / (shm->samplebits / 8); // mono - // - // samples - // in - // buffer - shm->speed = setup.format.rate; - shm->buffer = (unsigned char *) mmap_data; - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - snd_inited = 1; - return 1; - error: - Con_Printf ("Error: %s: %s\n", err_msg, snd_strerror (rc)); - error_2: - snd_pcm_close (pcm_handle); - return 0; -} - -int -SNDDMA_GetDMAPos (void) -{ - if (!snd_inited) - return 0; - shm->samplepos = - (mmap_control->status.frag_io + - 1) * setup.buf.block.frag_size / (shm->samplebits / 8); - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - snd_pcm_close (pcm_handle); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int count = paintedtime - soundtime; - int i, s, e; - int rc; - - count += setup.buf.block.frag_size - 1; - count /= setup.buf.block.frag_size; - s = soundtime / setup.buf.block.frag_size; - e = s + count; - for (i = s; i < e; i++) - mmap_control->fragments[i % setup.buf.block.frags].data = 1; - switch (mmap_control->status.status) { - case SND_PCM_STATUS_PREPARED: - if ((rc = snd_pcm_channel_go (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) - < 0) { - fprintf (stderr, "unable to start playback. %s\n", - snd_strerror (rc)); - exit (1); - } - break; - case SND_PCM_STATUS_RUNNING: - break; - case SND_PCM_STATUS_UNDERRUN: - if ( - (rc = - snd_pcm_plugin_prepare (pcm_handle, - SND_PCM_CHANNEL_PLAYBACK)) < 0) { - fprintf (stderr, - "underrun: playback channel prepare error. %s\n", - snd_strerror (rc)); - exit (1); - } - break; - default: - break; - } -} diff --git a/nq/source/snd_alsa_0_9.c b/nq/source/snd_alsa_0_9.c deleted file mode 100644 index 8f33c54e0..000000000 --- a/nq/source/snd_alsa_0_9.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - snd_alsa_0_9.c - - Support for ALSA 0.9 sound driver (cvs development version) - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include - -#include "QF/qtypes.h" -#include "sound.h" -#include "QF/qargs.h" -#include "QF/console.h" - -static int snd_inited; - -static snd_pcm_t *pcm; -static const snd_pcm_channel_area_t *mmap_areas; -static char *pcmname = NULL; -size_t buffer_size; - -qboolean -SNDDMA_Init (void) -{ - int err; - int rate = -1, bps = -1, stereo = -1, frag_size; - snd_pcm_hw_params_t *hw; - snd_pcm_sw_params_t *sw; - - snd_pcm_hw_params_alloca (&hw); - snd_pcm_sw_params_alloca (&sw); - - if (snd_device->string[0]) - pcmname = snd_device->string; - if (snd_bits->int_val) { - bps = snd_bits->int_val; - if (bps != 16 && bps != 8) { - Con_Printf ("Error: invalid sample bits: %d\n", bps); - return 0; - } - } - if (snd_rate->int_val) { - rate = snd_rate->int_val; - if (rate != 44100 && rate != 22050 && rate != 11025) { - Con_Printf ("Error: invalid sample rate: %d\n", rate); - return 0; - } - } - stereo = snd_stereo->int_val; - if (!pcmname) - pcmname = "plug:0,0"; - if ((err = snd_pcm_open (&pcm, pcmname, - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { - Con_Printf ("Error: audio open error: %s\n", snd_strerror (err)); - return 0; - } - - Con_Printf ("Using PCM %s.\n", pcmname); - snd_pcm_hw_params_any (pcm, hw); - - - switch (rate) { - case -1: - if (snd_pcm_hw_params_set_rate_near (pcm, hw, 44100, 0) >= 0) { - frag_size = 256; /* assuming stereo 8 bit */ - rate = 44100; - } else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 22050, 0) >= 0) { - frag_size = 128; /* assuming stereo 8 bit */ - rate = 22050; - } else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 11025, 0) >= 0) { - frag_size = 64; /* assuming stereo 8 bit */ - rate = 11025; - } else { - Con_Printf ("ALSA: no useable rates\n"); - goto error; - } - break; - case 11025: - case 22050: - case 44100: - if (snd_pcm_hw_params_set_rate_near (pcm, hw, rate, 0) >= 0) { - frag_size = 64 * rate / 11025; /* assuming stereo 8 bit */ - break; - } - /* Fall through */ - default: - Con_Printf ("ALSA: desired rate not supported\n"); - goto error; - } - - switch (bps) { - case -1: - if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_S16_LE) >= - 0) { - bps = 16; - } else if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_U8) - >= 0) { - bps = 8; - } else { - Con_Printf ("ALSA: no useable formats\n"); - goto error; - } - break; - case 8: - case 16: - if (snd_pcm_hw_params_set_format (pcm, hw, - bps == 8 ? SND_PCM_FORMAT_U8 : - SND_PCM_FORMAT_S16) >= 0) { - break; - } - /* Fall through */ - default: - Con_Printf ("ALSA: desired format not supported\n"); - goto error; - } - - if (snd_pcm_hw_params_set_access (pcm, hw, - SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { - Con_Printf ("ALSA: interleaved is not supported\n"); - goto error; - } - - switch (stereo) { - case -1: - if (snd_pcm_hw_params_set_channels (pcm, hw, 2) >= 0) { - stereo = 1; - } else if (snd_pcm_hw_params_set_channels (pcm, hw, 1) >= 0) { - stereo = 0; - } else { - Con_Printf ("ALSA: no useable channels\n"); - goto error; - } - break; - case 0: - case 1: - if (snd_pcm_hw_params_set_channels (pcm, hw, stereo ? 2 : 1) >= 0) - break; - /* Fall through */ - default: - Con_Printf ("ALSA: desired channels not supported\n"); - goto error; - } - - snd_pcm_hw_params_set_period_size_near (pcm, hw, frag_size, 0); - - err = snd_pcm_hw_params (pcm, hw); - if (err < 0) { - Con_Printf ("ALSA: unable to install hw params\n"); - goto error; - } - - snd_pcm_sw_params_current (pcm, sw); - snd_pcm_sw_params_set_start_mode (pcm, sw, SND_PCM_START_EXPLICIT); - snd_pcm_sw_params_set_xrun_mode (pcm, sw, SND_PCM_XRUN_NONE); - - err = snd_pcm_sw_params (pcm, sw); - if (err < 0) { - Con_Printf ("ALSA: unable to install sw params\n"); - goto error; - } - - mmap_areas = snd_pcm_mmap_running_areas (pcm); - - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = stereo + 1; - shm->submission_chunk = snd_pcm_hw_params_get_period_size (hw, 0); // don't - // mix - // less - // than - // this - // # - shm->samplepos = 0; // in mono samples - shm->samplebits = bps; - buffer_size = snd_pcm_hw_params_get_buffer_size (hw); - shm->samples = buffer_size * shm->channels; // mono samples in buffer - shm->speed = rate; - shm->buffer = (unsigned char *) mmap_areas->addr; - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - snd_inited = 1; - return 1; - error: - snd_pcm_close (pcm); - return 0; -} - -static inline int -get_hw_ptr () -{ - size_t app_ptr; - snd_pcm_sframes_t delay; - int hw_ptr; - - if (snd_pcm_state (pcm) != SND_PCM_STATE_RUNNING) - return 0; - app_ptr = snd_pcm_mmap_offset (pcm); - snd_pcm_delay (pcm, &delay); - hw_ptr = app_ptr - delay; - if (hw_ptr < 0) - hw_ptr += buffer_size; - return hw_ptr; -} - -int -SNDDMA_GetDMAPos (void) -{ - int hw_ptr; - - if (!snd_inited) - return 0; - - hw_ptr = get_hw_ptr (); - hw_ptr *= shm->channels; - shm->samplepos = hw_ptr; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - snd_pcm_close (pcm); - snd_inited = 0; - } -} - -/* -============== -SNDDMA_Submit - -Send sound to device if buffer isn't really the dma buffer -=============== -*/ -void -SNDDMA_Submit (void) -{ - int count = paintedtime - soundtime; - int avail; - int missed; - int state; - int hw_ptr; - int offset; - - state = snd_pcm_state (pcm); - - switch (state) { - case SND_PCM_STATE_PREPARED: - snd_pcm_mmap_forward (pcm, count); - snd_pcm_start (pcm); - break; - case SND_PCM_STATE_RUNNING: - hw_ptr = get_hw_ptr (); - missed = hw_ptr - shm->samplepos / shm->channels; - if (missed < 0) - missed += buffer_size; - count -= missed; - offset = snd_pcm_mmap_offset (pcm); - if (offset > hw_ptr) - count -= (offset - hw_ptr); - else - count -= (buffer_size - hw_ptr + offset); - if (count < 0) { - snd_pcm_rewind (pcm, -count); - } else { - avail = snd_pcm_avail_update (pcm); - if (avail < 0) - avail = buffer_size; - if (count > avail) - count = avail; - snd_pcm_mmap_forward (pcm, count); - } - break; - default: - break; - } -} diff --git a/nq/source/snd_disk.c b/nq/source/snd_disk.c deleted file mode 100644 index e45b22d9a..000000000 --- a/nq/source/snd_disk.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - snd_disk.c - - write sound to a disk file - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include - -#include "QF/console.h" -#include "sound.h" -#include "QF/qargs.h" - -static int snd_inited; -QFile *snd_file; - -qboolean -SNDDMA_Init (void) -{ - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = 2; - shm->submission_chunk = 1; // don't mix less than this # - shm->samplepos = 0; // in mono samples - shm->samplebits = 16; - shm->samples = 16384; // mono samples in buffer - shm->speed = 44100; - shm->buffer = malloc (shm->samples * shm->channels * shm->samplebits / 8); - - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - if (!(snd_file = Qopen ("qf.raw", "wb"))) - return 0; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - shm->samplepos = 0; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - Qclose (snd_file); - snd_file = 0; - free (shm->buffer); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int count = (paintedtime - soundtime) * shm->samplebits / 8; - - Qwrite (snd_file, shm->buffer, count); -} diff --git a/nq/source/snd_dma.c b/nq/source/snd_dma.c deleted file mode 100644 index a1f84e945..000000000 --- a/nq/source/snd_dma.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - snd_dma.c - - main control for any streaming sound output device - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include - -#include "client.h" -#include "QF/cmd.h" -#include "QF/console.h" -#include "host.h" -#include "QF/model.h" -#include "QF/qargs.h" -#include "QF/sys.h" -#include "sound.h" - -#ifdef _WIN32 -#include "winquake.h" -#include "in_win.h" -#endif - -void S_Play (void); -void S_PlayVol (void); -void S_SoundList (void); -void S_Update_ (void); -void S_StopAllSounds (qboolean clear); -void S_StopAllSoundsC (void); - -// QuakeWorld hack... -//#define viewentity playernum+1 - -// ======================================================================= -// Internal sound data & structures -// ======================================================================= - -channel_t channels[MAX_CHANNELS]; -int total_channels; - -int snd_blocked = 0; -static qboolean snd_ambient = 1; -qboolean snd_initialized = false; - -// pointer should go away -volatile dma_t *shm = 0; -volatile dma_t sn; - -vec3_t listener_origin; -vec3_t listener_forward; -vec3_t listener_right; -vec3_t listener_up; -vec_t sound_nominal_clip_dist = 1000.0; - -int soundtime; // sample PAIRS -int paintedtime; // sample PAIRS - - -#define MAX_SFX 512 -sfx_t *known_sfx; // hunk allocated [MAX_SFX] -int num_sfx; - -sfx_t *ambient_sfx[NUM_AMBIENTS]; - -int desired_speed = 11025; -int desired_bits = 16; - -int sound_started = 0; - -cvar_t *bgmvolume; -cvar_t *volume; - -cvar_t *snd_device; -cvar_t *snd_rate; -cvar_t *snd_bits; -cvar_t *snd_stereo; -cvar_t *nosound; -cvar_t *precache; -cvar_t *loadas8bit; -cvar_t *ambient_level; -cvar_t *ambient_fade; -cvar_t *snd_noextraupdate; -cvar_t *snd_show; -cvar_t *snd_interp; -cvar_t *snd_phasesep; -cvar_t *snd_volumesep; -cvar_t *_snd_mixahead; - - -// ==================================================================== -// User-setable variables -// ==================================================================== - - -// -// Fake dma is a synchronous faking of the DMA progress used for -// isolating performance in the renderer. The fakedma_updates is -// number of times S_Update() is called per second. -// - -qboolean fakedma = false; -int fakedma_updates = 15; - - -void -S_AmbientOff (void) -{ - snd_ambient = false; -} - - -void -S_AmbientOn (void) -{ - snd_ambient = true; -} - - -void -S_SoundInfo_f (void) -{ - if (!sound_started || !shm) { - Con_Printf ("sound system not started\n"); - return; - } - - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%lx dma buffer\n", (unsigned long) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); -} - - -/* - S_Startup -*/ - -void -S_Startup (void) -{ - int rc; - - if (!snd_initialized) - return; - - if (!fakedma) { - rc = SNDDMA_Init (); - - if (!rc) { -#ifndef _WIN32 - Con_Printf ("S_Startup: SNDDMA_Init failed.\n"); -#endif - sound_started = 0; - return; - } - } - - sound_started = 1; -} - - -/* - S_Init -*/ -void -S_Init (void) -{ - - Con_Printf ("\nSound Initialization\n"); - - Cmd_AddCommand ("play", S_Play, - "Play selected sound effect (play pathto/sound.wav)"); - Cmd_AddCommand ("playvol", S_PlayVol, - "Play selected sound effect at selected volume (playvol pathto/sound.wav num"); - Cmd_AddCommand ("stopsound", S_StopAllSoundsC, - "Stops all sounds currently being played"); - Cmd_AddCommand ("soundlist", S_SoundList, - "Reports a list of sounds in the cache"); - Cmd_AddCommand ("soundinfo", S_SoundInfo_f, - "Report information on the sound system"); - - if (COM_CheckParm ("-nosound")) - return; - - if (COM_CheckParm ("-simsound")) - fakedma = true; - - if (host_parms.memsize < 0x800000) { - Cvar_Set (loadas8bit, "1"); - Con_Printf ("loading all sounds as 8bit\n"); - } - - - snd_initialized = true; - - S_Startup (); - - if (sound_started == 0) // sound startup failed? Bail out. - return; - - SND_InitScaletable (); - - known_sfx = Hunk_AllocName (MAX_SFX * sizeof (sfx_t), "sfx_t"); - - num_sfx = 0; - -// create a piece of DMA memory - - if (fakedma) { - shm = (void *) Hunk_AllocName (sizeof (*shm), "shm"); - shm->splitbuffer = 0; - shm->samplebits = 16; - shm->speed = 22050; - shm->channels = 2; - shm->samples = 32768; - shm->samplepos = 0; - shm->soundalive = true; - shm->gamealive = true; - shm->submission_chunk = 1; - shm->buffer = Hunk_AllocName (1 << 16, "shmbuf"); - } -// Con_Printf ("Sound sampling rate: %i\n", shm->speed); - - // provides a tick sound until washed clean - -// if (shm->buffer) -// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging - - ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); - ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); - - S_StopAllSounds (true); -} - -void -S_Init_Cvars (void) -{ - snd_device = Cvar_Get ("snd_device", "", CVAR_ROM, 0, - "sound device. \"\" is system default"); - snd_rate = Cvar_Get ("snd_rate", "0", CVAR_ROM, 0, - "sound playback rate. 0 is system default"); - snd_bits = Cvar_Get ("snd_bits", "0", CVAR_ROM, 0, - "sound sample depth. 0 is system default"); - snd_stereo = Cvar_Get ("snd_stereo", "1", CVAR_ROM, 0, - "sound stereo output"); - nosound = Cvar_Get ("nosound", "0", CVAR_NONE, 0, "Set to turn sound off"); - volume = - Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, 0, - "Set the volume for sound playback"); - precache = - Cvar_Get ("precache", "1", CVAR_NONE, 0, "Toggle the use of a precache"); - loadas8bit = - Cvar_Get ("loadas8bit", "0", CVAR_NONE, 0, - "Toggles if sounds are loaded as 8-bit samples"); - bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, 0, "Volume of CD music"); - ambient_level = - Cvar_Get ("ambient_level", "0.3", CVAR_NONE, 0, "Ambient sounds' volume"); - ambient_fade = - Cvar_Get ("ambient_fade", "100", CVAR_NONE, 0, - "How quickly ambient sounds fade in or out"); - snd_noextraupdate = - Cvar_Get ("snd_noextraupdate", "0", CVAR_NONE, 0, - "Toggles the correct value display in host_speeds. Usually messes up sound playback when in effect"); - snd_show = - Cvar_Get ("snd_show", "0", CVAR_NONE, 0, - "Toggles the display of sounds currently being played"); - snd_interp = - Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, 0, - "control sample interpolation"); - snd_phasesep = - Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE, 0, - "max stereo phase separation in ms. 0.6 is for 20cm head"); - snd_volumesep = - Cvar_Get ("snd_volumesep", "1.0", CVAR_ARCHIVE, 0, - "max stereo volume separation in ms. 1.0 is max"); - _snd_mixahead = - Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, 0, - "Delay time for sounds"); -} - - -// ======================================================================= -// Shutdown sound engine -// ======================================================================= - -void -S_Shutdown (void) -{ - - if (!sound_started) - return; - - if (shm) - shm->gamealive = 0; - - shm = 0; - sound_started = 0; - - if (!fakedma) { - SNDDMA_Shutdown (); - } -} - - -// ======================================================================= -// Load a sound -// ======================================================================= - -/* - S_FindName -*/ -sfx_t * -S_FindName (char *name) -{ - int i; - sfx_t *sfx; - - if (!name) - Sys_Error ("S_FindName: NULL\n"); - - if (strlen (name) >= MAX_QPATH) - Sys_Error ("Sound name too long: %s", name); - -// see if already loaded - for (i = 0; i < num_sfx; i++) - if (!strcmp (known_sfx[i].name, name)) { - return &known_sfx[i]; - } - - if (num_sfx == MAX_SFX) - Sys_Error ("S_FindName: out of sfx_t"); - - sfx = &known_sfx[i]; - strcpy (sfx->name, name); - - num_sfx++; - - return sfx; -} - - -/* - S_TouchSound -*/ -void -S_TouchSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started) - return; - - sfx = S_FindName (name); - Cache_Check (&sfx->cache); -} - -/* - S_PrecacheSound -*/ -sfx_t * -S_PrecacheSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started || nosound->int_val) - return NULL; - - sfx = S_FindName (name); - -// cache it in - if (precache->int_val) - S_LoadSound (sfx); - - return sfx; -} - - -//============================================================================= - -/* - SND_PickChannel -*/ -channel_t * -SND_PickChannel (int entnum, int entchannel) -{ - int ch_idx; - int first_to_die; - int life_left; - -// Check for replacement sound, or find the best one to replace - first_to_die = -1; - life_left = 0x7fffffff; - for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; - ch_idx++) { - if (entchannel != 0 // channel 0 never overrides - && channels[ch_idx].entnum == entnum - && (channels[ch_idx].entchannel == entchannel || entchannel == -1)) { - // always override sound from same entity - first_to_die = ch_idx; - break; - } - // don't let monster sounds override player sounds - if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity - && channels[ch_idx].sfx) - continue; - - if (channels[ch_idx].end - paintedtime < life_left) { - life_left = channels[ch_idx].end - paintedtime; - first_to_die = ch_idx; - } - } - - if (first_to_die == -1) - return NULL; - - if (channels[first_to_die].sfx) - channels[first_to_die].sfx = NULL; - - return &channels[first_to_die]; -} - -/* - SND_Spatialize -*/ -void -SND_Spatialize (channel_t *ch) -{ - vec_t dot; - vec_t dist; - int phase; // in samples - vec_t lscale, rscale, scale; - vec3_t source_vec; - sfx_t *snd; - -// anything coming from the view entity will always be full volume - if (ch->entnum == cl.viewentity) { - ch->leftvol = ch->master_vol; - ch->rightvol = ch->master_vol; - ch->phase = 0; - return; - } -// calculate stereo seperation and distance attenuation - - snd = ch->sfx; - VectorSubtract (ch->origin, listener_origin, source_vec); - - dist = VectorNormalize (source_vec) * ch->dist_mult; - - dot = DotProduct (listener_right, source_vec); - - if (shm->channels == 1) { - rscale = 1.0; - lscale = 1.0; - phase = 0; - } else { - rscale = 1.0 + dot * snd_volumesep->value; - lscale = 1.0 - dot * snd_volumesep->value; - phase = snd_phasesep->value * 0.001 * shm->speed * dot; - } - -// add in distance effect - scale = (1.0 - dist) * rscale; - ch->rightvol = (int) (ch->master_vol * scale); - if (ch->rightvol < 0) - ch->rightvol = 0; - - scale = (1.0 - dist) * lscale; - ch->leftvol = (int) (ch->master_vol * scale); - if (ch->leftvol < 0) - ch->leftvol = 0; - - ch->phase = phase; -} - - -// ======================================================================= -// Start a sound effect -// ======================================================================= - -void -S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, - float attenuation) -{ - channel_t *target_chan, *check; - sfxcache_t *sc; - int vol; - int ch_idx; - int skip; - - if (!sound_started) - return; - - if (!sfx) - return; - - if (nosound->int_val) - return; - - vol = fvol * 255; - -// pick a channel to play on - target_chan = SND_PickChannel (entnum, entchannel); - if (!target_chan) - return; - -// spatialize - memset (target_chan, 0, sizeof (*target_chan)); - VectorCopy (origin, target_chan->origin); - target_chan->dist_mult = attenuation / sound_nominal_clip_dist; - target_chan->master_vol = vol; - target_chan->entnum = entnum; - target_chan->entchannel = entchannel; - SND_Spatialize (target_chan); - - if (!target_chan->leftvol && !target_chan->rightvol) - return; // not audible at all - -// new channel - sc = S_LoadSound (sfx); - if (!sc) { - target_chan->sfx = NULL; - return; // couldn't load the sound's data - } - - target_chan->sfx = sfx; - target_chan->pos = 0.0; - target_chan->end = paintedtime + sc->length; - -// if an identical sound has also been started this frame, offset the pos -// a bit to keep it from just making the first one louder - check = &channels[NUM_AMBIENTS]; - for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; - ch_idx++, check++) { - if (check == target_chan) - continue; - if (check->sfx == sfx && !check->pos) { - skip = rand () % (int) (0.1 * shm->speed); - if (skip >= target_chan->end) - skip = target_chan->end - 1; - target_chan->pos += skip; - target_chan->end -= skip; - break; - } - - } -} - -void -S_StopSound (int entnum, int entchannel) -{ - int i; - - for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) { - if (channels[i].entnum == entnum - && channels[i].entchannel == entchannel) { - channels[i].end = 0; - channels[i].sfx = NULL; - return; - } - } -} - -void -S_StopAllSounds (qboolean clear) -{ - int i; - - if (!sound_started) - return; - - total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics - - for (i = 0; i < MAX_CHANNELS; i++) - if (channels[i].sfx) - channels[i].sfx = NULL; - - memset (channels, 0, MAX_CHANNELS * sizeof (channel_t)); - - if (clear) - S_ClearBuffer (); -} - -void -S_StopAllSoundsC (void) -{ - S_StopAllSounds (true); -} - -void -S_ClearBuffer (void) -{ - int clear; - -#ifdef _WIN32 - if (!sound_started || !shm || (!shm->buffer && !pDSBuf)) -#else - if (!sound_started || !shm || !shm->buffer) -#endif - return; - - if (shm->samplebits == 8) - clear = 0x80; - else - clear = 0; - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_ClearBuffer (clear); - else -#endif - { - memset (shm->buffer, clear, shm->samples * shm->samplebits / 8); - } -} - - -/* - S_StaticSound -*/ -void -S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) -{ - channel_t *ss; - sfxcache_t *sc; - - if (!sfx) - return; - - if (total_channels == MAX_CHANNELS) { - Con_Printf ("total_channels == MAX_CHANNELS\n"); - return; - } - - ss = &channels[total_channels]; - total_channels++; - - sc = S_LoadSound (sfx); - if (!sc) - return; - - if (sc->loopstart == -1) { - Con_Printf ("Sound %s not looped\n", sfx->name); - return; - } - - ss->sfx = sfx; - VectorCopy (origin, ss->origin); - ss->master_vol = vol; - ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist; - ss->end = paintedtime + sc->length; - - SND_Spatialize (ss); - ss->oldphase = ss->phase; -} - - -//============================================================================= - -/* - S_UpdateAmbientSounds -*/ -void -S_UpdateAmbientSounds (void) -{ - mleaf_t *l; - float vol; - int ambient_channel; - channel_t *chan; - - if (!snd_ambient) - return; - -// calc ambient sound levels - if (!cl.worldmodel) - return; - - l = Mod_PointInLeaf (listener_origin, cl.worldmodel); - if (!l || !ambient_level->value) { - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; - ambient_channel++) - channels[ambient_channel].sfx = NULL; - return; - } - - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++) { - chan = &channels[ambient_channel]; - chan->sfx = ambient_sfx[ambient_channel]; - - vol = ambient_level->value * l->ambient_sound_level[ambient_channel]; - if (vol < 8) - vol = 0; - - // don't adjust volume too fast - if (chan->master_vol < vol) { - chan->master_vol += host_frametime * ambient_fade->value; - if (chan->master_vol > vol) - chan->master_vol = vol; - } else if (chan->master_vol > vol) { - chan->master_vol -= host_frametime * ambient_fade->value; - if (chan->master_vol < vol) - chan->master_vol = vol; - } - - chan->leftvol = chan->rightvol = chan->master_vol; - } -} - - -/* - S_Update - - Called once each time through the main loop -*/ -void -S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) -{ - int i, j; - int total; - channel_t *ch; - channel_t *combine; - - if (!sound_started || (snd_blocked > 0)) - return; - - VectorCopy (origin, listener_origin); - VectorCopy (forward, listener_forward); - VectorCopy (right, listener_right); - VectorCopy (up, listener_up); - -// update general area ambient sound sources - S_UpdateAmbientSounds (); - - combine = NULL; - -// update spatialization for static and dynamic sounds - ch = channels + NUM_AMBIENTS; - for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) { - if (!ch->sfx) - continue; - ch->oldphase = ch->phase; // prepare to lerp from prev to next - // phase - SND_Spatialize (ch); // respatialize channel - if (!ch->leftvol && !ch->rightvol) - continue; - - // try to combine static sounds with a previous channel of the same - // sound effect so we don't mix five torches every frame - - if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) { - // see if it can just use the last one - if (combine && combine->sfx == ch->sfx) { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - continue; - } - // search for one - combine = channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; - for (j = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; j < i; j++, combine++) - if (combine->sfx == ch->sfx) - break; - - if (j == total_channels) { - combine = NULL; - } else { - if (combine != ch) { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - } - continue; - } - } - - - } - -// -// debugging output -// - if (snd_show->int_val) { - total = 0; - ch = channels; - for (i = 0; i < total_channels; i++, ch++) - if (ch->sfx && (ch->leftvol || ch->rightvol)) { - // Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, - // ch->sfx->name); - total++; - } - - Con_Printf ("----(%i)----\n", total); - } -// mix some sound - S_Update_ (); -} - -void -GetSoundtime (void) -{ - int samplepos; - static int buffers; - static int oldsamplepos; - int fullsamples; - - fullsamples = shm->samples / shm->channels; - -// it is possible to miscount buffers if it has wrapped twice between -// calls to S_Update. Oh well. - samplepos = SNDDMA_GetDMAPos (); - - if (samplepos < oldsamplepos) { - buffers++; // buffer wrapped - - if (paintedtime > 0x40000000) { // time to chop things off to avoid - // 32 bit limits - buffers = 0; - paintedtime = fullsamples; - S_StopAllSounds (true); - } - } - oldsamplepos = samplepos; - - soundtime = buffers * fullsamples + samplepos / shm->channels; -} - -void -S_ExtraUpdate (void) -{ - -#ifdef _WIN32 - IN_Accumulate (); -#endif - - if (snd_noextraupdate->int_val) - return; // don't pollute timings - S_Update_ (); -} - - - -void -S_Update_ (void) -{ - unsigned int endtime; - int samps; - - if (!sound_started || (snd_blocked > 0)) - return; - -// Updates DMA time - GetSoundtime (); - -// check to make sure that we haven't overshot - if (paintedtime < soundtime) { - // Con_Printf ("S_Update_ : overflow\n"); - paintedtime = soundtime; - } -// mix ahead of current position - endtime = soundtime + _snd_mixahead->value * shm->speed; - samps = shm->samples >> (shm->channels - 1); - if (endtime - soundtime > samps) - endtime = soundtime + samps; - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_Restore (); -#endif - - S_PaintChannels (endtime); - - SNDDMA_Submit (); -} - -/* - console functions -*/ - -void -S_Play (void) -{ - static int hash = 345; - int i; - char name[256]; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - strcpy (name, Cmd_Argv (i)); - strncat (name, ".wav", sizeof (name) - strlen (name)); - } else - strcpy (name, Cmd_Argv (i)); - sfx = S_PrecacheSound (name); - S_StartSound (hash++, 0, sfx, listener_origin, 1.0, 1.0); - i++; - } -} - -void -S_PlayVol (void) -{ - static int hash = 543; - int i; - float vol; - char name[256]; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - strcpy (name, Cmd_Argv (i)); - strncat (name, ".wav", sizeof (name) - strlen (name)); - } else - strcpy (name, Cmd_Argv (i)); - sfx = S_PrecacheSound (name); - vol = atof (Cmd_Argv (i + 1)); - S_StartSound (hash++, 0, sfx, listener_origin, vol, 1.0); - i += 2; - } -} - -void -S_SoundList (void) -{ - int i; - sfx_t *sfx; - sfxcache_t *sc; - int size, total; - - total = 0; - for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) { - sc = Cache_Check (&sfx->cache); - if (!sc) - continue; - size = sc->length * sc->width * (sc->stereo + 1); - total += size; - if (sc->loopstart >= 0) - Con_Printf ("L"); - else - Con_Printf (" "); - Con_Printf ("(%2db) %6i : %s\n", sc->width * 8, size, sfx->name); - } - Con_Printf ("Total resident: %i\n", total); -} - - -void -S_LocalSound (char *sound) -{ - sfx_t *sfx; - - if (nosound->int_val) - return; - if (!sound_started) - return; - - sfx = S_PrecacheSound (sound); - if (!sfx) { - Con_Printf ("S_LocalSound: can't cache %s\n", sound); - return; - } - S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); -} - - -void -S_ClearPrecache (void) -{ -} - - -void -S_BeginPrecaching (void) -{ -} - - -void -S_EndPrecaching (void) -{ -} diff --git a/nq/source/snd_dos.c b/nq/source/snd_dos.c deleted file mode 100644 index 180d3aaa3..000000000 --- a/nq/source/snd_dos.c +++ /dev/null @@ -1,648 +0,0 @@ - -/* - snd_dos.c - - @description@ - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "dosisms.h" - -int BLASTER_GetDMAPos (void); - -/* -=============================================================================== -GUS SUPPORT - -=============================================================================== -*/ - -qboolean GUS_Init (void); -int GUS_GetDMAPos (void); -void GUS_Shutdown (void); - - -/* -=============================================================================== - -BLASTER SUPPORT - -=============================================================================== -*/ - -short *dma_buffer = 0; -static int dma_size; -static int dma; - -static int dsp_port; -static int irq; -static int low_dma; -static int high_dma; -static int mixer_port; -static int mpu401_port; - -int dsp_version; -int dsp_minor_version; - -int timeconstant = -1; - - -void -PrintBits (byte b) -{ - int i; - char str[9]; - - for (i = 0; i < 8; i++) - str[i] = '0' + ((b & (1 << (7 - i))) > 0); - - str[8] = 0; - Con_Printf ("%s (%i)", str, b); -} - -void -SB_Info_f (void) -{ - Con_Printf ("BLASTER=%s\n", getenv ("BLASTER")); - Con_Printf ("dsp version=%d.%d\n", dsp_version, dsp_minor_version); - Con_Printf ("dma=%d\n", dma); - if (timeconstant != -1) - Con_Printf ("timeconstant=%d\n", timeconstant); - Con_Printf ("dma position:%i\n", BLASTER_GetDMAPos ()); -} - -// ======================================================================= -// Interprets BLASTER variable -// ======================================================================= - -int -GetBLASTER (void) -{ - char *BLASTER; - char *param; - - BLASTER = getenv ("BLASTER"); - if (!BLASTER) - return 0; - - param = strchr (BLASTER, 'A'); - if (!param) - param = strchr (BLASTER, 'a'); - if (!param) - return 0; - sscanf (param + 1, "%x", &dsp_port); - - param = strchr (BLASTER, 'I'); - if (!param) - param = strchr (BLASTER, 'i'); - if (!param) - return 0; - sscanf (param + 1, "%d", &irq); - - param = strchr (BLASTER, 'D'); - if (!param) - param = strchr (BLASTER, 'd'); - if (!param) - return 0; - sscanf (param + 1, "%d", &low_dma); - - param = strchr (BLASTER, 'H'); - if (!param) - param = strchr (BLASTER, 'h'); - if (param) - sscanf (param + 1, "%d", &high_dma); - - param = strchr (BLASTER, 'M'); - if (!param) - param = strchr (BLASTER, 'm'); - if (param) - sscanf (param + 1, "%x", &mixer_port); - else - mixer_port = dsp_port; - - param = strchr (BLASTER, 'P'); - if (!param) - param = strchr (BLASTER, 'p'); - if (param) - sscanf (param + 1, "%x", &mpu401_port); - - return 1; - -} - -// ================================================================== -// Resets DSP. Returns 0 on success. -// ================================================================== - -int -ResetDSP (void) -{ - volatile int i; - - dos_outportb (dsp_port + 6, 1); - for (i = 65536; i; i--); - dos_outportb (dsp_port + 6, 0); - for (i = 65536; i; i--) { - if (!(dos_inportb (dsp_port + 0xe) & 0x80)) - continue; - if (dos_inportb (dsp_port + 0xa) == 0xaa) - break; - } - if (i) - return 0; - else - return 1; - -} - -int -ReadDSP (void) -{ - while (!(dos_inportb (dsp_port + 0xe) & 0x80)); - return dos_inportb (dsp_port + 0xa); -} - -void -WriteDSP (int val) -{ - while ((dos_inportb (dsp_port + 0xc) & 0x80)); - dos_outportb (dsp_port + 0xc, val); -} - -int -ReadMixer (int addr) -{ - dos_outportb (mixer_port + 4, addr); - return dos_inportb (mixer_port + 5); -} - -void -WriteMixer (int addr, int val) -{ - dos_outportb (mixer_port + 4, addr); - dos_outportb (mixer_port + 5, val); -} - -int oldmixervalue; - -/* -================ -StartSB - -================ -*/ -void -StartSB (void) -{ - int i; - -// version 4.xx startup code - if (dsp_version >= 4) { - Con_Printf ("Version 4 SB startup\n"); - WriteDSP (0xd1); // turn on speaker - - WriteDSP (0x41); - - WriteDSP (shm->speed >> 8); - WriteDSP (shm->speed & 0xff); - - WriteDSP (0xb6); // 16-bit output - WriteDSP (0x30); // stereo - WriteDSP ((shm->samples - 1) & 0xff); // # of samples - 1 - WriteDSP ((shm->samples - 1) >> 8); - } -// version 3.xx startup code - else if (dsp_version == 3) { - Con_Printf ("Version 3 SB startup\n"); - WriteDSP (0xd1); // turn on speaker - - oldmixervalue = ReadMixer (0xe); - WriteMixer (0xe, oldmixervalue | 0x2); // turn on stereo - - WriteDSP (0x14); // send one byte - WriteDSP (0x0); - WriteDSP (0x0); - - for (i = 0; i < 0x10000; i++) - dos_inportb (dsp_port + 0xe); // ack the dsp - - timeconstant = 65536 - (256000000 / (shm->channels * shm->speed)); - WriteDSP (0x40); - WriteDSP (timeconstant >> 8); - - WriteMixer (0xe, ReadMixer (0xe) | 0x20); // turn off filter - - WriteDSP (0x48); - WriteDSP ((shm->samples - 1) & 0xff); // # of samples - 1 - WriteDSP ((shm->samples - 1) >> 8); - - WriteDSP (0x90); // high speed 8 bit stereo - } -// normal speed mono - else { - Con_Printf ("Version 2 SB startup\n"); - WriteDSP (0xd1); // turn on speaker - - timeconstant = 65536 - (256000000 / (shm->channels * shm->speed)); - WriteDSP (0x40); - WriteDSP (timeconstant >> 8); - - WriteDSP (0x48); - WriteDSP ((shm->samples - 1) & 0xff); // # of samples - 1 - WriteDSP ((shm->samples - 1) >> 8); - - WriteDSP (0x1c); // normal speed 8 bit mono - } -} - -static int page_reg[] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; -static int addr_reg[] = { 0, 2, 4, 6, 0xc0, 0xc4, 0xc8, 0xcc }; -static int count_reg[] = { 1, 3, 5, 7, 0xc2, 0xc6, 0xca, 0xce }; - -static int mode_reg; -static int flipflop_reg; -static int disable_reg; -static int clear_reg; - -/* -================ -StartDMA - -================ -*/ -void -StartDMA (void) -{ - int mode; - int realaddr; - - realaddr = ptr2real (dma_buffer); - -// use a high dma channel if specified - if (high_dma && dsp_version >= 4) // 8 bit snd can never use 16 bit dma - dma = high_dma; - else - dma = low_dma; - - Con_Printf ("Using DMA channel %i\n", dma); - - if (dma > 3) { - mode_reg = 0xd6; - flipflop_reg = 0xd8; - disable_reg = 0xd4; - clear_reg = 0xdc; - } else { - mode_reg = 0xb; - flipflop_reg = 0xc; - disable_reg = 0xa; - clear_reg = 0xe; - } - - dos_outportb (disable_reg, dma | 4); // disable channel - // set mode- see "undocumented pc", p.876 - mode = (1 << 6) // single-cycle - + (0 << 5) // address increment - + (1 << 4) // auto-init dma - + (2 << 2) // read - + (dma & 3); // channel # - dos_outportb (mode_reg, mode); - -// set address - // set page - dos_outportb (page_reg[dma], realaddr >> 16); - - if (dma > 3) { // address is in words - dos_outportb (flipflop_reg, 0); // prepare to send 16-bit value - dos_outportb (addr_reg[dma], (realaddr >> 1) & 0xff); - dos_outportb (addr_reg[dma], (realaddr >> 9) & 0xff); - - dos_outportb (flipflop_reg, 0); // prepare to send 16-bit value - dos_outportb (count_reg[dma], ((dma_size >> 1) - 1) & 0xff); - dos_outportb (count_reg[dma], ((dma_size >> 1) - 1) >> 8); - } else { // address is in bytes - dos_outportb (flipflop_reg, 0); // prepare to send 16-bit value - dos_outportb (addr_reg[dma], realaddr & 0xff); - dos_outportb (addr_reg[dma], (realaddr >> 8) & 0xff); - - dos_outportb (flipflop_reg, 0); // prepare to send 16-bit value - dos_outportb (count_reg[dma], (dma_size - 1) & 0xff); - dos_outportb (count_reg[dma], (dma_size - 1) >> 8); - } - - dos_outportb (clear_reg, 0); // clear write mask - dos_outportb (disable_reg, dma & ~4); -} - - -/* -================== -BLASTER_Init - -Returns false if nothing is found. -================== -*/ -qboolean -BLASTER_Init (void) -{ - int size; - int realaddr; - int rc; - int p; - - shm = 0; - rc = 0; - -// -// must have a blaster variable set -// - if (!GetBLASTER ()) { - Con_NotifyBox ("The BLASTER environment variable\n" - "is not set, sound effects are\n" - "disabled. See README.TXT for help.\n"); - return 0; - } - - if (ResetDSP ()) { - Con_Printf ("Could not reset SB"); - return 0; - } -// -// get dsp version -// - WriteDSP (0xe1); - dsp_version = ReadDSP (); - dsp_minor_version = ReadDSP (); - -// we need at least v2 for auto-init dma - if (dsp_version < 2) { - Con_Printf ("Sound blaster must be at least v2.0\n"); - return 0; - } -// allow command line parm to set quality down - p = COM_CheckParm ("-dsp"); - if (p && p < com_argc - 1) { - p = Q_atoi (com_argv[p + 1]); - if (p < 2 || p > 4) - Con_Printf ("-dsp parameter can only be 2, 3, or 4\n"); - else if (p > dsp_version) - Con_Printf ("Can't -dsp %i on v%i hardware\n", p, dsp_version); - else - dsp_version = p; - } -// everyone does 11khz sampling rate unless told otherwise - shm = &sn; - shm->speed = 11025; - rc = COM_CheckParm ("-sspeed"); - if (rc) - shm->speed = Q_atoi (com_argv[rc + 1]); - -// version 4 cards (sb 16) do 16 bit stereo - if (dsp_version >= 4) { - shm->channels = 2; - shm->samplebits = 16; - } -// version 3 cards (sb pro) do 8 bit stereo - else if (dsp_version == 3) { - shm->channels = 2; - shm->samplebits = 8; - } -// v2 cards do 8 bit mono - else { - shm->channels = 1; - shm->samplebits = 8; - } - - - Cmd_AddCommand ("sbinfo", SB_Info_f, "No Description"); - size = 4096; - -// allocate 8k and get a 4k-aligned buffer from it - dma_buffer = dos_getmemory (size * 2); - if (!dma_buffer) { - Con_Printf ("Couldn't allocate sound dma buffer"); - return false; - } - - realaddr = ptr2real (dma_buffer); - realaddr = (realaddr + size) & ~(size - 1); - dma_buffer = (short *) real2ptr (realaddr); - dma_size = size; - - memset (dma_buffer, 0, dma_size); - - shm->soundalive = true; - shm->splitbuffer = false; - - shm->samples = size / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) dma_buffer; - shm->samples = size / (shm->samplebits / 8); - - StartDMA (); - StartSB (); - - return true; -} - - -/* -============== -BLASTER_GetDMAPos - -return the current sample position (in mono samples read) -inside the recirculating dma buffer, so the mixing code will know -how many sample are required to fill it up. -=============== -*/ -int -BLASTER_GetDMAPos (void) -{ - int count; - -// this function is called often. acknowledge the transfer completions -// all the time so that it loops - if (dsp_version >= 4) - dos_inportb (dsp_port + 0xf); // 16 bit audio - else - dos_inportb (dsp_port + 0xe); // 8 bit audio - -// clear 16-bit reg flip-flop -// load the current dma count register - if (dma < 4) { - dos_outportb (0xc, 0); - count = dos_inportb (dma * 2 + 1); - count += dos_inportb (dma * 2 + 1) << 8; - if (shm->samplebits == 16) - count /= 2; - count = shm->samples - (count + 1); - } else { - dos_outportb (0xd8, 0); - count = dos_inportb (0xc0 + (dma - 4) * 4 + 2); - count += dos_inportb (0xc0 + (dma - 4) * 4 + 2) << 8; - if (shm->samplebits == 8) - count *= 2; - count = shm->samples - (count + 1); - } - -// Con_Printf("DMA pos = 0x%x\n", count); - - shm->samplepos = count & (shm->samples - 1); - return shm->samplepos; - -} - -/* -============== -BLASTER_Shutdown - -Reset the sound device for exiting -=============== -*/ -void -BLASTER_Shutdown (void) -{ - if (dsp_version >= 4) { - } else if (dsp_version == 3) { - ResetDSP (); // stop high speed mode - WriteMixer (0xe, oldmixervalue); // turn stereo off and filter on - } else { - - } - - WriteDSP (0xd3); // turn off speaker - ResetDSP (); - - dos_outportb (disable_reg, dma | 4); // disable dma channel -} - - - -/* -=============================================================================== - -INTERFACE - -=============================================================================== -*/ - -typedef enum { - dma_none, - dma_blaster, - dma_gus -} dmacard_t; - -dmacard_t dmacard; - -/* -================== -SNDDM_Init - -Try to find a sound device to mix for. -Returns false if nothing is found. -Returns true and fills in the "shm" structure with information for the mixer. -================== -*/ -qboolean -SNDDMA_Init (void) -{ - if (GUS_Init ()) { - dmacard = dma_gus; - return true; - } - if (BLASTER_Init ()) { - dmacard = dma_blaster; - return true; - } - - dmacard = dma_none; - - return false; -} - - -/* -============== -SNDDMA_GetDMAPos - -return the current sample position (in mono samples, not stereo) -inside the recirculating dma buffer, so the mixing code will know -how many sample are required to fill it up. -=============== -*/ -int -SNDDMA_GetDMAPos (void) -{ - switch (dmacard) { - case dma_blaster: - return BLASTER_GetDMAPos (); - case dma_gus: - return GUS_GetDMAPos (); - case dma_none: - break; - } - - return 0; -} - -/* -============== -SNDDMA_Shutdown - -Reset the sound device for exiting -=============== -*/ -void -SNDDMA_Shutdown (void) -{ - switch (dmacard) { - case dma_blaster: - BLASTER_Shutdown (); - break; - case dma_gus: - GUS_Shutdown (); - break; - case dma_none: - break; - } - - dmacard = dma_none; - return; -} - -/* -============== -SNDDMA_Submit - -Send sound to device if buffer isn't really the dma buffer -=============== -*/ -void -SNDDMA_Submit (void) -{ -} diff --git a/nq/source/snd_gus.c b/nq/source/snd_gus.c deleted file mode 100644 index 9eb0db4b5..000000000 --- a/nq/source/snd_gus.c +++ /dev/null @@ -1,1281 +0,0 @@ - -/* - snd_gus.c - - @description@ - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "dosisms.h" - -//============================================================================= -// Author(s): Jayeson Lee-Steere - -#define INI_STRING_SIZE 0x100 - -QFile *ini_fopen (const char *filename, const char *modes); -int ini_fclose (QFile *f); -void ini_fgets (QFile *f, const char *section, const char *field, - - char *s); - -// Routines for reading from .INI files -// The read routines are fairly efficient. -// -// Author(s): Jayeson Lee-Steere - -#define MAX_SECTION_WIDTH 20 -#define MAX_FIELD_WIDTH 20 - -#define NUM_SECTION_BUFFERS 10 -#define NUM_FIELD_BUFFERS 20 - -struct section_buffer { - long offset; - char name[MAX_SECTION_WIDTH + 1]; -}; - -struct field_buffer { - long offset; - int section; - char name[MAX_FIELD_WIDTH + 1]; -}; - -static QFile *current_file = NULL; -static int current_section; - -static int current_section_buffer = 0; -static int current_field_buffer = 0; - -static struct section_buffer section_buffers[NUM_SECTION_BUFFERS]; -static struct field_buffer field_buffers[NUM_FIELD_BUFFERS]; - -//*************************************************************************** -// Internal routines -//*************************************************************************** -static char -toupper (char c) -{ - if (c >= 'a' && c <= 'z') - c -= ('a' - 'A'); - return (c); -} - -static void -reset_buffer (QFile *f) -{ - int i; - - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - section_buffers[i].name[0] = 0; - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - field_buffers[i].name[0] = 0; - - current_file = f; -} - -// Sees if the current string is section "name" (i.e. ["name"]). -// If "name"=="*", sees if the current string is any section -// (i.e. [....]). Returns 1 if true else 0 if false. -static int -is_section (char *s, const char *name) -{ - int wild = 0; - - // See if wild search - if (strcmp ("*", name) == 0) - wild = 1; - - // Skip leading spaces - while (s[0] == ' ') - s++; - // Look for leading "[" - if (s[0] != '[') - return (0); - s++; - // Make sure name matches - while (s[0] != ']' && s[0] != 13 && s[0] != 10 && s[0] != 0 && name[0] != 0) { - if (!wild) - if (toupper (s[0]) != toupper (name[0])) - return (0); - s++; - if (!wild) - name++; - } - if (!wild) - if (name[0] != 0) - return (0); - // Skip trailing spaces - while (s[0] == ' ') - s++; - // Make sure we have trailing "]" - if (s[0] != ']') - return (0); - return (1); -} - -// Sees if the current string is field "name" (i.e. "name"=...). -// If "name"=="*", sees if the current string is any field -// (i.e. ...=...). Returns 1 if true else 0 if false. -static int -is_field (char *s, const char *name) -{ - int wild = 0; - - // See if wild search - if (strcmp ("*", name) == 0) - wild = 1; - - // Skip leading spaces - while (s[0] == ' ') - s++; - - // Make sure name matches - while (s[0] != '=' && s[0] != 13 && s[0] != 10 && s[0] != 0 && name[0] != 0) { - if (!wild) - if (toupper (s[0]) != toupper (name[0])) - return (0); - s++; - if (!wild) - name++; - } - if (!wild) - if (name[0] != 0) - return (0); - // Skip trailing spaces - while (s[0] == ' ') - s++; - // Make sure we have an "=" - if (s[0] != '=') - return (0); - - return (1); -} - -// Extracts the section name from a section heading -// e.g. in="[hey man]" gives out="hey man" -static void -get_section_name (char *out, char *in) -{ - int i = 0; - - // Skip spaces before '[' - while (in[0] == ' ') - in++; - // Make sure there is a '[' - if (in[0] != '[') { - out[0] = 0; - return; - } - // Skip past '[' - in++; - // Copy string if any to output string. - while (in[0] != ']' && in[0] != 13 && in[0] != 10 && in[0] != 0) { - if (i < MAX_SECTION_WIDTH) { - out[i] = in[0]; - i++; - } - in++; - } - // Make sure string was terminated with ']' - if (in[0] != ']') { - out[0] = 0; - return; - } - // Remove trailing spaces - while (i > 0 && out[i - 1] == ' ') - i--; - // Null terminate the output string. - out[i] = 0; -} - -// Extracts the field name from a field line -// e.g. in="sooty=life be in it" gives out="sooty" -static void -get_field_name (char *out, char *in) -{ - int i = 0; - - // Skip leading spaces - while (in[0] == ' ') - in++; - // Copy name to output string - while (in[0] != '=' && in[0] != 13 && in[0] != 10 && in[0] != 0) { - if (i < MAX_FIELD_WIDTH) { - out[i] = in[0]; - i++; - } - in++; - } - // Make sure we stopped on "=" - if (in[0] != '=') { - out[0] = 0; - return; - } - // Remove trailing spaces - while (i > 0 && out[i - 1] == ' ') - i--; - // Null terminate the output string. - out[i] = 0; -} - -// Returns the field data from string s. -// e.g. in="wally = golly man" gives out="golly man" -static void -get_field_string (char *out, char *in) -{ - int i = 0; - - // Find '=' if it exists - while (in[0] != '=' && in[0] != 13 && in[0] != 10 && in[0] != 0) - in++; - // If there is an '=', skip past it. - if (in[0] == '=') - in++; - // Skip any spaces between the '=' and string. - while (in[0] == ' ' || in[0] == '[') - in++; - // Copy string, if there is one, to the output string. - while (in[0] != 13 && in[0] != 10 && in[0] != 0 - && i < (INI_STRING_SIZE - 1)) { - out[i] = in[0]; - in++; - i++; - } - // Null terminate the output string. - out[i] = 0; -} - -// Adds a section to the buffer -static int -add_section (char *instring, long offset) -{ - int i; - char section[MAX_SECTION_WIDTH + 1]; - - // Extract section name - get_section_name (section, instring); - // See if section already exists. - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - if (strcasecmp (section, section_buffers[i].name) == 0) - return (i); - // Increment current_section_buffer - current_section_buffer++; - if (current_section_buffer > NUM_SECTION_BUFFERS) - current_section_buffer = 0; - // Delete any field buffers that correspond to this section - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == current_section_buffer) - field_buffers[i].name[0] = 0; - // Set buffer information - strcpy (section_buffers[current_section_buffer].name, section); - section_buffers[current_section_buffer].offset = offset; - return (current_section_buffer); -} - -// Adds a field to the buffer -static void -add_field (char *instring, int section, long offset) -{ - int i; - char field[MAX_FIELD_WIDTH + 1]; - - // Extract field name - get_field_name (field, instring); - // See if field already exists - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == section) - if (strcasecmp (field_buffers[i].name, field) == 0) - return; - // Increment current_field_buffer - current_field_buffer++; - if (current_field_buffer > NUM_FIELD_BUFFERS) - current_field_buffer = 0; - // Set buffer information - strcpy (field_buffers[current_field_buffer].name, field); - field_buffers[current_field_buffer].section = section; - field_buffers[current_field_buffer].offset = offset; -} - -// Identical to fgets except the string is trucated at the first ';', -// carriage return or line feed. -static char * -stripped_fgets (char *s, int n, QFile *f) -{ - int i = 0; - - if (fgets (s, n, f) == NULL) - return (NULL); - - while (s[i] != ';' && s[i] != 13 && s[i] != 10 && s[i] != 0) - i++; - s[i] = 0; - - return (s); -} - -//*************************************************************************** -// Externally accessable routines -//*************************************************************************** -// Opens an .INI file. Works like fopen -QFile * -ini_fopen (const char *filename, const char *modes) -{ - return (Qopen (filename, modes)); -} - -// Closes a .INI file. Works like fclose -int -ini_fclose (QFile *f) -{ - if (f == current_file) - reset_buffer (NULL); - return (Qclose (f)); -} - -// Puts "field" from "section" from .ini file "f" into "s". -// If "section" does not exist or "field" does not exist in -// section then s=""; -void -ini_fgets (QFile *f, const char *section, const char *field, char *s) -{ - int i; - long start_pos, string_start_pos; - char ts[INI_STRING_SIZE * 2]; - - if (f != current_file) - reset_buffer (f); - - // Default to "Not found" - s[0] = 0; - - // See if section is in buffer - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - if (strnicmp (section_buffers[i].name, section, MAX_SECTION_WIDTH) == 0) - break; - - // If section is in buffer, seek to it if necessary - if (i < NUM_SECTION_BUFFERS) { - if (i != current_section) { - current_section = i; - fseek (f, section_buffers[i].offset, SEEK_SET); - } - } - // else look through .ini file for it. - else { - // Make sure we are not at eof or this will cause trouble. - if (feof (f)) - rewind (f); - start_pos = ftell (f); - while (1) { - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - // If it is a section, add it to the section buffer - if (is_section (ts, "*")) - current_section = add_section (ts, ftell (f)); - // If it is the section we are looking for, break. - if (is_section (ts, section)) - break; - // If we reach the end of the file, rewind to the start. - if (feof (f)) - rewind (f); - if (ftell (f) == start_pos) - return; - } - } - - // See if field is in buffer - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == current_section) - if (strnicmp (field_buffers[i].name, field, MAX_FIELD_WIDTH) == 0) - break; - - // If field is in buffer, seek to it and read it - if (i < NUM_FIELD_BUFFERS) { - fseek (f, field_buffers[i].offset, SEEK_SET); - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - get_field_string (s, ts); - } else - // else search through section for field. - { - // Make sure we do not start at eof or this will cause problems. - if (feof (f)) - fseek (f, section_buffers[current_section].offset, SEEK_SET); - start_pos = ftell (f); - while (1) { - string_start_pos = ftell (f); - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - // If it is a field, add it to the buffer - if (is_field (ts, "*")) - add_field (ts, current_section, string_start_pos); - // If it is the field we are looking for, save it - if (is_field (ts, field)) { - get_field_string (s, ts); - break; - } - // If we reach the end of the section, start over - if (feof (f) || is_section (ts, "*")) - fseek (f, section_buffers[current_section].offset, SEEK_SET); - if (ftell (f) == start_pos) - return; - } - } -} - -//============================================================================= - -#define BYTE unsigned char -#define WORD unsigned short -#define DWORD unsigned long - -#define BUFFER_SIZE 4096 - -#define CODEC_ADC_INPUT_CONTROL_LEFT 0x00 -#define CODEC_ADC_INPUT_CONTROL_RIGHT 0x01 -#define CODEC_AUX1_INPUT_CONTROL_LEFT 0x02 -#define CODEC_AUX1_INPUT_CONTROL_RIGHT 0x03 -#define CODEC_AUX2_INPUT_CONTROL_LEFT 0x04 -#define CODEC_AUX2_INPUT_CONTROL_RIGHT 0x05 -#define CODEC_DAC_OUTPUT_CONTROL_LEFT 0x06 -#define CODEC_DAC_OUTPUT_CONTROL_RIGHT 0x07 -#define CODEC_FS_FORMAT 0x08 -#define CODEC_INTERFACE_CONFIG 0x09 -#define CODEC_PIN_CONTROL 0x0A -#define CODEC_ERROR_STATUS_AND_INIT 0x0B -#define CODEC_MODE_AND_ID 0x0C -#define CODEC_LOOPBACK_CONTROL 0x0D -#define CODEC_PLAYBACK_UPPER_BASE_COUNT 0x0E -#define CODEC_PLAYBACK_LOWER_BASE_COUNT 0x0F - -#define SET_CONTROL 0x00 -#define SET_FREQUENCY 0x01 -#define SET_START_HIGH 0x02 -#define SET_START_LOW 0x03 -#define SET_END_HIGH 0x04 -#define SET_END_LOW 0x05 -#define SET_VOLUME_RATE 0x06 -#define SET_VOLUME_START 0x07 -#define SET_VOLUME_END 0x08 -#define SET_CURR_VOLUME 0x09 -#define SET_VOLUME 0x09 -#define SET_ACC_HIGH 0x0A -#define SET_ACC_LOW 0x0B -#define SET_BALANCE 0x0C -#define SET_VOLUME_CONTROL 0x0D -#define SET_VOICES 0x0E - -#define DMA_CONTROL 0x41 -#define SET_DMA_ADDRESS 0x42 -#define SET_DRAM_LOW 0x43 -#define SET_DRAM_HIGH 0x44 -#define ADLIB_CONTROL 0x45 -#define ADLIB_TIMER1 0x46 -#define ADLIB_TIMER2 0x47 -#define SET_RECORD_RATE 0x48 -#define RECORD_CONTROL 0x49 -#define SET_JOYSTICK 0x4B -#define MASTER_RESET 0x4C - -#define GET_CONTROL 0x80 -#define GET_FREQUENCY 0x81 -#define GET_START_HIGH 0x82 -#define GET_START_LOW 0x83 -#define GET_END_HIGH 0x84 -#define GET_END_LOW 0x85 -#define GET_VOLUME_RATE 0x86 -#define GET_VOLUME_START 0x87 -#define GET_VOLUME_END 0x88 -#define GET_VOLUME 0x89 -#define GET_ACC_HIGH 0x8A -#define GET_ACC_LOW 0x8B -#define GET_BALANCE 0x8C -#define GET_VOLUME_CONTROL 0x8D -#define GET_VOICES 0x8E -#define GET_IRQV 0x8F - -struct CodecRateStruct { - WORD Rate; - BYTE FSVal; -}; - -struct Gf1RateStruct { - WORD Rate; - BYTE Voices; -}; - -//============================================================================= -// Reference variables in SND_DOS.C -//============================================================================= -extern short *dma_buffer; - -//============================================================================= -// GUS-only variables -//============================================================================= -static BYTE HaveCodec = 0; - -static WORD CodecRegisterSelect; -static WORD CodecData; -static WORD CodecStatus; -static WORD Gf1TimerControl; -static WORD Gf1PageRegister; -static WORD Gf1RegisterSelect; -static WORD Gf1DataLow; -static WORD Gf1DataHigh; - -static BYTE DmaChannel; - -static BYTE PageRegs[] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; -static BYTE AddrRegs[] = { 0, 2, 4, 6, 0xc0, 0xc4, 0xc8, 0xcc }; -static BYTE CountRegs[] = { 1, 3, 5, 7, 0xc2, 0xc6, 0xca, 0xce }; - -static WORD AddrReg; -static WORD CountReg; -static WORD ModeReg; -static WORD DisableReg; -static WORD ClearReg; - -static struct CodecRateStruct CodecRates[] = { - {5512, 0x01}, - {6620, 0x0F}, - {8000, 0x00}, - {9600, 0x0E}, - {11025, 0x03}, - {16000, 0x02}, - {18900, 0x05}, - {22050, 0x07}, - {27420, 0x04}, - {32000, 0x06}, - {33075, 0x0D}, - {37800, 0x09}, - {44100, 0x0B}, - {48000, 0x0C}, - {0, 0x00} // End marker -}; - -static struct Gf1RateStruct Gf1Rates[] = { - {19293, 32}, - {19916, 31}, - {20580, 30}, - {21289, 29}, - {22050, 28}, - {22866, 27}, - {23746, 26}, - {24696, 25}, - {25725, 24}, - {26843, 23}, - {28063, 22}, - {29400, 21}, - {30870, 20}, - {32494, 19}, - {34300, 18}, - {36317, 17}, - {38587, 16}, - {41160, 15}, - {44100, 14}, - {0, 0} -}; - -//============================================================================= -// Basic GF1 functions -//============================================================================= -void -SetGf18 (BYTE reg, BYTE data) -{ - dos_outportb (Gf1RegisterSelect, reg); - dos_outportb (Gf1DataHigh, data); -} - -void -SetGf116 (BYTE reg, WORD data) -{ - dos_outportb (Gf1RegisterSelect, reg); - dos_outportw (Gf1DataLow, data); -} - -BYTE -GetGf18 (BYTE reg) -{ - dos_outportb (Gf1RegisterSelect, reg); - return (dos_inportb (Gf1DataHigh)); -} - -WORD -GetGf116 (BYTE reg) -{ - dos_outportb (Gf1RegisterSelect, reg); - return (dos_inportw (Gf1DataLow)); -} - -void -Gf1Delay (void) -{ - int i; - - for (i = 0; i < 27; i++) - dos_inportb (Gf1TimerControl); -} - -DWORD -ConvertTo16 (DWORD Address) -{ - return (((Address >> 1) & 0x0001FFFF) | (Address & 0x000C0000L)); -} - -void -ClearGf1Ints (void) -{ - int i; - - SetGf18 (DMA_CONTROL, 0x00); - SetGf18 (ADLIB_CONTROL, 0x00); - SetGf18 (RECORD_CONTROL, 0x00); - - GetGf18 (DMA_CONTROL); - GetGf18 (RECORD_CONTROL); - for (i = 0; i < 32; i++); - GetGf18 (GET_IRQV); -} - - -//============================================================================= -// Get Interwave (UltraSound PnP) configuration if any -//============================================================================= -static qboolean -GUS_GetIWData (void) -{ - char *Interwave, s[INI_STRING_SIZE]; - QFile *IwFile; - int CodecBase, CodecDma, i; - - Interwave = getenv ("INTERWAVE"); - if (Interwave == NULL) - return (false); - - // Open IW.INI - IwFile = ini_fopen (Interwave, "rt"); - if (IwFile == NULL) - return (false); - - // Read codec base and codec DMA - ini_fgets (IwFile, "setup 0", "CodecBase", s); - sscanf (s, "%X", &CodecBase); - ini_fgets (IwFile, "setup 0", "DMA2", s); - sscanf (s, "%i", &CodecDma); - - ini_fclose (IwFile); - - // Make sure numbers OK - if (CodecBase == 0 || CodecDma == 0) - return (false); - - CodecRegisterSelect = CodecBase; - CodecData = CodecBase + 1; - CodecStatus = CodecBase + 2; - DmaChannel = CodecDma; - - // Make sure there is a CODEC at the CODEC base - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Wait for 'INIT' bit to clear - for (i = 0; i < 0xFFFF; i++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - break; - if (i == 0xFFFF) - return (false); - - // Get chip revision - can not be zero - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - if ((dos_inportb (CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) - return (false); - if ((dos_inportb (CodecData) & 0x0F) == 0) - return (false); - - HaveCodec = 1; - Con_Printf ("Sound Card is UltraSound PnP\n"); - return (true); -} - -//============================================================================= -// Get UltraSound MAX configuration if any -//============================================================================= -static qboolean -GUS_GetMAXData (void) -{ - char *Ultrasnd, *Ultra16; - int i; - int GusBase, Dma1, Dma2, Irq1, Irq2; - int CodecBase, CodecDma, CodecIrq, CodecType; - BYTE MaxVal; - - Ultrasnd = getenv ("ULTRASND"); - Ultra16 = getenv ("ULTRA16"); - if (Ultrasnd == NULL || Ultra16 == NULL) - return (false); - - sscanf (Ultrasnd, "%x,%i,%i,%i,%i", &GusBase, &Dma1, &Dma2, &Irq1, &Irq2); - sscanf (Ultra16, "%x,%i,%i,%i", &CodecBase, &CodecDma, &CodecIrq, - &CodecType); - - if (CodecType == 0 && CodecDma != 0) - DmaChannel = CodecDma & 0x07; - else - DmaChannel = Dma2 & 0x07; - - // Make sure there is a GUS at GUS base - dos_outportb (GusBase + 0x08, 0x55); - if (dos_inportb (GusBase + 0x0A) != 0x55) - return (false); - dos_outportb (GusBase + 0x08, 0xAA); - if (dos_inportb (GusBase + 0x0A) != 0xAA) - return (false); - - // Program CODEC control register - MaxVal = ((CodecBase & 0xF0) >> 4) | 0x40; - if (Dma1 > 3) - MaxVal |= 0x10; - if (Dma2 > 3) - MaxVal |= 0x20; - dos_outportb (GusBase + 0x106, MaxVal); - - CodecRegisterSelect = CodecBase; - CodecData = CodecBase + 1; - CodecStatus = CodecBase + 2; - - // Make sure there is a CODEC at the CODEC base - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Wait for 'INIT' bit to clear - for (i = 0; i < 0xFFFF; i++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - break; - if (i == 0xFFFF) - return (false); - - // Get chip revision - can not be zero - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - if ((dos_inportb (CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) - return (false); - if ((dos_inportb (CodecData) & 0x0F) == 0) - return (false); - - HaveCodec = 1; - Con_Printf ("Sound Card is UltraSound MAX\n"); - return (true); -} - -//============================================================================= -// Get regular UltraSound configuration if any -//============================================================================= -static qboolean -GUS_GetGUSData (void) -{ - char *Ultrasnd; - int GusBase, Dma1, Dma2, Irq1, Irq2, i; - - Ultrasnd = getenv ("ULTRASND"); - if (Ultrasnd == NULL) - return (false); - - sscanf (Ultrasnd, "%x,%i,%i,%i,%i", &GusBase, &Dma1, &Dma2, &Irq1, &Irq2); - - DmaChannel = Dma1 & 0x07; - - // Make sure there is a GUS at GUS base - dos_outportb (GusBase + 0x08, 0x55); - if (dos_inportb (GusBase + 0x0A) != 0x55) - return (false); - dos_outportb (GusBase + 0x08, 0xAA); - if (dos_inportb (GusBase + 0x0A) != 0xAA) - return (false); - - Gf1TimerControl = GusBase + 0x008; - Gf1PageRegister = GusBase + 0x102; - Gf1RegisterSelect = GusBase + 0x103; - Gf1DataLow = GusBase + 0x104; - Gf1DataHigh = GusBase + 0x105; - - // Reset the GUS - SetGf18 (MASTER_RESET, 0x00); - Gf1Delay (); - Gf1Delay (); - SetGf18 (MASTER_RESET, 0x01); - Gf1Delay (); - Gf1Delay (); - - // Set to max (32) voices - SetGf18 (SET_VOICES, 0xDF); - - // Clear any pending IRQ's - ClearGf1Ints (); - - // Set all registers to known values - for (i = 0; i < 32; i++) { - dos_outportb (Gf1PageRegister, i); - SetGf18 (SET_CONTROL, 0x03); - SetGf18 (SET_VOLUME_CONTROL, 0x03); - Gf1Delay (); - SetGf18 (SET_CONTROL, 0x03); - SetGf18 (SET_VOLUME_CONTROL, 0x03); - SetGf116 (SET_START_HIGH, 0); - SetGf116 (SET_START_LOW, 0); - SetGf116 (SET_END_HIGH, 0); - SetGf116 (SET_END_LOW, 0); - SetGf116 (SET_ACC_HIGH, 0); - SetGf116 (SET_ACC_LOW, 0); - SetGf18 (SET_VOLUME_RATE, 63); - SetGf18 (SET_VOLUME_START, 5); - SetGf18 (SET_VOLUME_END, 251); - SetGf116 (SET_VOLUME, 5 << 8); - } - - // Clear any pending IRQ's - ClearGf1Ints (); - - // Enable DAC etc. - SetGf18 (MASTER_RESET, 0x07); - - // Enable line output so we can hear something - dos_outportb (GusBase, 0x08); - - HaveCodec = 0; - Con_Printf ("Sound Card is UltraSound\n"); - return (true); -} - - -//============================================================================= -// Programs the DMA controller to start DMAing in Auto-init mode -//============================================================================= -static void -GUS_StartDMA (BYTE DmaChannel, short *dma_buffer, int count) -{ - int mode; - int RealAddr; - - RealAddr = ptr2real (dma_buffer); - - if (DmaChannel <= 3) { - ModeReg = 0x0B; - DisableReg = 0x0A; - ClearReg = 0x0E; - } else { - ModeReg = 0xD6; - DisableReg = 0xD4; - ClearReg = 0xDC; - } - CountReg = CountRegs[DmaChannel]; - AddrReg = AddrRegs[DmaChannel]; - - dos_outportb (DisableReg, DmaChannel | 4); // disable channel - - // set mode- see "undocumented pc", p.876 - mode = (1 << 6) // single-cycle - + (0 << 5) // address increment - + (1 << 4) // auto-init dma - + (2 << 2) // read - + (DmaChannel & 0x03); // channel # - dos_outportb (ModeReg, mode); - - // set page - dos_outportb (PageRegs[DmaChannel], RealAddr >> 16); - - if (DmaChannel <= 3) { // address is in bytes - dos_outportb (0x0C, 0); // prepare to send 16-bit value - dos_outportb (AddrReg, RealAddr & 0xff); - dos_outportb (AddrReg, (RealAddr >> 8) & 0xff); - - dos_outportb (0x0C, 0); // prepare to send 16-bit value - dos_outportb (CountReg, (count - 1) & 0xff); - dos_outportb (CountReg, (count - 1) >> 8); - } else { // address is in words - dos_outportb (0xD8, 0); // prepare to send 16-bit value - dos_outportb (AddrReg, (RealAddr >> 1) & 0xff); - dos_outportb (AddrReg, (RealAddr >> 9) & 0xff); - - dos_outportb (0xD8, 0); // prepare to send 16-bit value - dos_outportb (CountReg, ((count >> 1) - 1) & 0xff); - dos_outportb (CountReg, ((count >> 1) - 1) >> 8); - } - - dos_outportb (ClearReg, 0); // clear write mask - dos_outportb (DisableReg, DmaChannel & ~4); -} - -//============================================================================= -// Starts the CODEC playing -//============================================================================= -static void -GUS_StartCODEC (int count, BYTE FSVal) -{ - int i, j; - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Set mode to 2 - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - dos_outportb (CodecData, 0xC0); - - // Stop any playback or capture which may be happening - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, dos_inportb (CodecData) & 0xFC); - - // Set FS - dos_outportb (CodecRegisterSelect, CODEC_FS_FORMAT | 0x40); - dos_outportb (CodecData, FSVal | 0x50); // Or in stereo and 16 bit bits - - // Wait a bit - for (i = 0; i < 10; i++) - dos_inportb (CodecData); - - // Routine 1 to counter CODEC bug - wait for init bit to clear and then a - // bit longer (i=min loop count, j=timeout - for (i = 0, j = 0; i < 1000 && j < 0x7FFFF; j++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - i++; - - // Routine 2 to counter CODEC bug - this is from Forte's code. For me it - // does not seem to cure the problem, but is added security - // Waits till we can modify index register - for (j = 0; j < 0x7FFFF; j++) { - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - if (dos_inportb (CodecRegisterSelect) == - (CODEC_INTERFACE_CONFIG | 0x40)) break; - } - - // Perform ACAL - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - dos_outportb (CodecData, 0x08); - - // Clear MCE bit - this makes ACAL happen - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - - // Wait for ACAL to finish - for (j = 0; j < 0x7FFFF; j++) { - if ((dos_inportb (CodecRegisterSelect) & 0x80) != 0) - continue; - dos_outportb (CodecRegisterSelect, CODEC_ERROR_STATUS_AND_INIT); - if ((dos_inportb (CodecData) & 0x20) == 0) - break; - } - - // Clear ACAL bit - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - dos_outportb (CodecData, 0x00); - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - - // Set some other junk - dos_outportb (CodecRegisterSelect, CODEC_LOOPBACK_CONTROL); - dos_outportb (CodecData, 0x00); - dos_outportb (CodecRegisterSelect, CODEC_PIN_CONTROL); - dos_outportb (CodecData, 0x08); // IRQ is disabled in PIN control - - // Set count (it doesn't really matter what value we stuff in here - dos_outportb (CodecRegisterSelect, CODEC_PLAYBACK_LOWER_BASE_COUNT); - dos_outportb (CodecData, count & 0xFF); - dos_outportb (CodecRegisterSelect, CODEC_PLAYBACK_UPPER_BASE_COUNT); - dos_outportb (CodecData, count >> 8); - - // Start playback - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, 0x01); -} - -//============================================================================= -// Starts the GF1 playing -//============================================================================= -static void -GUS_StartGf1 (int count, BYTE Voices) -{ - DWORD StartAddressL, EndAddressL, StartAddressR, EndAddressR; - - // Set number of voices to give us the sampling rate we want - SetGf18 (SET_VOICES, 0xC0 | (Voices - 1)); - - // Figure out addresses - StartAddressL = ConvertTo16 (0); - EndAddressL = ConvertTo16 (count - 2 - 2); - StartAddressR = ConvertTo16 (2); - EndAddressR = ConvertTo16 (count - 2); - - // Set left voice addresses - dos_outportb (Gf1PageRegister, 0); - SetGf116 (SET_START_LOW, StartAddressL << 9); - SetGf116 (SET_START_HIGH, StartAddressL >> 7); - SetGf116 (SET_ACC_LOW, StartAddressL << 9); - SetGf116 (SET_ACC_HIGH, StartAddressL >> 7); - SetGf116 (SET_END_LOW, EndAddressL << 9); - SetGf116 (SET_END_HIGH, EndAddressL >> 7); - // Set balance to full left - SetGf18 (SET_BALANCE, 0); - // Set volume to full - SetGf116 (SET_VOLUME, 0xFFF0); - // Set FC to 2 (so we play every second sample) - SetGf116 (SET_FREQUENCY, 0x0800); - - // Set right voice addresses - dos_outportb (Gf1PageRegister, 1); - SetGf116 (SET_START_LOW, StartAddressR << 9); - SetGf116 (SET_START_HIGH, StartAddressR >> 7); - SetGf116 (SET_ACC_LOW, StartAddressR << 9); - SetGf116 (SET_ACC_HIGH, StartAddressR >> 7); - SetGf116 (SET_END_LOW, EndAddressR << 9); - SetGf116 (SET_END_HIGH, EndAddressR >> 7); - // Set balance to full right - SetGf18 (SET_BALANCE, 15); - // Set volume to full - SetGf116 (SET_VOLUME, 0xFFF0); - // Set FC to 2 (so we play every second sample) - SetGf116 (SET_FREQUENCY, 0x0800); - - // Start voices - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x0C); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x0C); - Gf1Delay (); - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x0C); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x0C); -} - - -//============================================================================= -// Figures out what kind of UltraSound we have, if any, and starts it playing -//============================================================================= -qboolean -GUS_Init (void) -{ - int rc; - int RealAddr; - BYTE FSVal, Voices; - struct CodecRateStruct *CodecRate; - struct Gf1RateStruct *Gf1Rate; - - // See what kind of UltraSound we have, if any - if (GUS_GetIWData () == false) - if (GUS_GetMAXData () == false) - if (GUS_GetGUSData () == false) - return (false); - - shm = &sn; - - if (HaveCodec) { - // do 11khz sampling rate unless command line parameter wants - // different - shm->speed = 11025; - FSVal = 0x03; - rc = COM_CheckParm ("-sspeed"); - if (rc) { - shm->speed = Q_atoi (com_argv[rc + 1]); - - // Make sure rate not too high - if (shm->speed > 48000) - shm->speed = 48000; - - // Adjust speed to match one of the possible CODEC rates - for (CodecRate = CodecRates; CodecRate->Rate != 0; CodecRate++) { - if (shm->speed <= CodecRate->Rate) { - shm->speed = CodecRate->Rate; - FSVal = CodecRate->FSVal; - break; - } - } - } - // Always do 16 bit stereo - shm->channels = 2; - shm->samplebits = 16; - - // allocate buffer twice the size we need so we can get aligned - // buffer - dma_buffer = dos_getmemory (BUFFER_SIZE * 2); - if (dma_buffer == NULL) { - Con_Printf ("Couldn't allocate sound dma buffer"); - return false; - } - - RealAddr = ptr2real (dma_buffer); - RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE - 1); - dma_buffer = (short *) real2ptr (RealAddr); - - // Zero off DMA buffer - memset (dma_buffer, 0, BUFFER_SIZE); - - shm->soundalive = true; - shm->splitbuffer = false; - - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) dma_buffer; - shm->samples = BUFFER_SIZE / (shm->samplebits / 8); - - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - GUS_StartCODEC (BUFFER_SIZE, FSVal); - } else { - // do 19khz sampling rate unless command line parameter wants - // different - shm->speed = 19293; - Voices = 32; - rc = COM_CheckParm ("-sspeed"); - if (rc) { - shm->speed = Q_atoi (com_argv[rc + 1]); - - // Make sure rate not too high - if (shm->speed > 44100) - shm->speed = 44100; - - // Adjust speed to match one of the possible GF1 rates - for (Gf1Rate = Gf1Rates; Gf1Rate->Rate != 0; Gf1Rate++) { - if (shm->speed <= Gf1Rate->Rate) { - shm->speed = Gf1Rate->Rate; - Voices = Gf1Rate->Voices; - break; - } - } - } - // Always do 16 bit stereo - shm->channels = 2; - shm->samplebits = 16; - - // allocate buffer twice the size we need so we can get aligned - // buffer - dma_buffer = dos_getmemory (BUFFER_SIZE * 2); - if (dma_buffer == NULL) { - Con_Printf ("Couldn't allocate sound dma buffer"); - return false; - } - - RealAddr = ptr2real (dma_buffer); - RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE - 1); - dma_buffer = (short *) real2ptr (RealAddr); - - // Zero off DMA buffer - memset (dma_buffer, 0, BUFFER_SIZE); - - shm->soundalive = true; - shm->splitbuffer = false; - - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) dma_buffer; - shm->samples = BUFFER_SIZE / (shm->samplebits / 8); - - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - SetGf116 (SET_DMA_ADDRESS, 0x0000); - if (DmaChannel <= 3) - SetGf18 (DMA_CONTROL, 0x41); - else - SetGf18 (DMA_CONTROL, 0x45); - GUS_StartGf1 (BUFFER_SIZE, Voices); - } - return (true); -} - -//============================================================================= -// Returns the current playback position -//============================================================================= -int -GUS_GetDMAPos (void) -{ - int count; - - if (HaveCodec) { - // clear 16-bit reg flip-flop - // load the current dma count register - if (DmaChannel < 4) { - dos_outportb (0x0C, 0); - count = dos_inportb (CountReg); - count += dos_inportb (CountReg) << 8; - if (shm->samplebits == 16) - count /= 2; - count = shm->samples - (count + 1); - } else { - dos_outportb (0xD8, 0); - count = dos_inportb (CountReg); - count += dos_inportb (CountReg) << 8; - if (shm->samplebits == 8) - count *= 2; - count = shm->samples - (count + 1); - } - - } else { - // Read current position from GF1 - dos_outportb (Gf1PageRegister, 0); - count = (GetGf116 (GET_ACC_HIGH) << 7) & 0xFFFF; - // See which half of buffer we are in. Note that since this is 16 bit - // data we are playing, position is in 16 bit samples - if (GetGf18 (DMA_CONTROL) & 0x40) { - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - SetGf116 (SET_DMA_ADDRESS, 0x0000); - if (DmaChannel <= 3) - SetGf18 (DMA_CONTROL, 0x41); - else - SetGf18 (DMA_CONTROL, 0x45); - } - } - - shm->samplepos = count & (shm->samples - 1); - return (shm->samplepos); -} - -//============================================================================= -// Stops the UltraSound playback -//============================================================================= -void -GUS_Shutdown (void) -{ - if (HaveCodec) { - // Stop CODEC - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, 0x01); - } else { - // Stop Voices - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x03); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x03); - Gf1Delay (); - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x03); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x03); - - // Stop any DMA - SetGf18 (DMA_CONTROL, 0x00); - GetGf18 (DMA_CONTROL); - } - - dos_outportb (DisableReg, DmaChannel | 4); // disable dma channel -} diff --git a/nq/source/snd_mem.c b/nq/source/snd_mem.c deleted file mode 100644 index 03f70162b..000000000 --- a/nq/source/snd_mem.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - snd_mem.c - - sound caching - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include "QF/console.h" -#include "QF/qendian.h" -#include "QF/quakefs.h" -#include "sound.h" -#include "QF/sys.h" - -int cache_full_cycle; - -byte *S_Alloc (int size); - -/* - ResampleSfx -*/ -void -ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data) -{ - int outcount; - int srcsample; - float stepscale; - int i; - int sample, samplefrac, fracstep; - sfxcache_t *sc; - short *is, *os; - unsigned char *ib, *ob; - - sc = Cache_Check (&sfx->cache); - if (!sc) - return; - - is = (short *) data; - os = (short *) sc->data; - ib = data; - ob = sc->data; - - stepscale = (float) inrate / shm->speed; // this is usually 0.5, 1, or - // - // 2 - - outcount = sc->length / stepscale; - - sc->speed = shm->speed; - if (loadas8bit->int_val) - sc->width = 1; - else - sc->width = 2; - sc->stereo = 0; - - // resample / decimate to the current source rate - if (stepscale == 1) { - if (inwidth == 1 && sc->width == 1) { - for (i = 0; i < outcount; i++) { - *ob++ = *ib++ - 128; - } - } else if (inwidth == 1 && sc->width == 2) { - for (i = 0; i < outcount; i++) { - *os++ = (*ib++ - 128) << 8; - } - } else if (inwidth == 2 && sc->width == 1) { - for (i = 0; i < outcount; i++) { - *ob++ = LittleShort (*is++) >> 8; - } - } else if (inwidth == 2 && sc->width == 2) { - for (i = 0; i < outcount; i++) { - *os++ = LittleShort (*is++); - } - } - } else { - // general case - if (snd_interp->int_val && stepscale < 1) { - int points = 1 / stepscale; - int j; - - for (i = 0; i < sc->length; i++) { - int s1, s2; - - if (inwidth == 2) { - s2 = s1 = LittleShort (is[0]); - if (i < sc->length - 1) - s2 = LittleShort (is[1]); - is++; - } else { - s2 = s1 = (ib[0] - 128) << 8; - if (i < sc->length - 1) - s2 = (ib[1] - 128) << 8; - ib++; - } - for (j = 0; j < points; j++) { - sample = s1 + (s2 - s1) * ((float) j) / points; - if (sc->width == 2) { - os[j] = sample; - } else { - ob[j] = sample >> 8; - } - } - if (sc->width == 2) { - os += points; - } else { - ob += points; - } - } - } else { - samplefrac = 0; - fracstep = stepscale * 256; - for (i = 0; i < outcount; i++) { - srcsample = samplefrac >> 8; - samplefrac += fracstep; - if (inwidth == 2) - sample = LittleShort (((short *) data)[srcsample]); - else - sample = - (int) ((unsigned char) (data[srcsample]) - 128) << 8; - if (sc->width == 2) - ((short *) sc->data)[i] = sample; - else - ((signed char *) sc->data)[i] = sample >> 8; - } - } - } - - sc->length = outcount; - if (sc->loopstart != -1) - sc->loopstart = sc->loopstart / stepscale; -} - -//============================================================================= - -/* - S_LoadSound -*/ -sfxcache_t * -S_LoadSound (sfx_t *s) -{ - char namebuffer[256]; - byte *data; - wavinfo_t info; - int len; - float stepscale; - sfxcache_t *sc; - byte stackbuf[1 * 1024]; // avoid dirtying the cache heap - -// see if still in memory - sc = Cache_Check (&s->cache); - if (sc) - return sc; - -//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); -// load it in - strcpy (namebuffer, "sound/"); - strncat (namebuffer, s->name, sizeof (namebuffer) - strlen (namebuffer)); - -// Con_Printf ("loading %s\n",namebuffer); - - data = COM_LoadStackFile (namebuffer, stackbuf, sizeof (stackbuf)); - - if (!data) { - Con_Printf ("Couldn't load %s\n", namebuffer); - return NULL; - } - - info = GetWavinfo (s->name, data, com_filesize); - if (info.channels != 1) { - Con_Printf ("%s is a stereo sample\n", s->name); - return NULL; - } - - stepscale = (float) info.rate / shm->speed; - len = info.samples / stepscale; - - if (loadas8bit->int_val) { - len = len * info.channels; - } else { - len = len * 2 * info.channels; - } - - sc = Cache_Alloc (&s->cache, len + sizeof (sfxcache_t), s->name); - - if (!sc) - return NULL; - - sc->length = info.samples; - sc->loopstart = info.loopstart; - sc->speed = info.rate; - sc->width = info.width; - sc->stereo = info.channels; - - ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); - - return sc; -} - - - -/* - WAV loading -*/ - - -byte *data_p; -byte *iff_end; -byte *last_chunk; -byte *iff_data; -int iff_chunk_len; - - -short -GetLittleShort (void) -{ - short val = 0; - - val = *data_p; - val = val + (*(data_p + 1) << 8); - data_p += 2; - return val; -} - -int -GetLittleLong (void) -{ - int val = 0; - - val = *data_p; - val = val + (*(data_p + 1) << 8); - val = val + (*(data_p + 2) << 16); - val = val + (*(data_p + 3) << 24); - data_p += 4; - return val; -} - -void -FindNextChunk (char *name) -{ - while (1) { - data_p = last_chunk; - - if (data_p >= iff_end) { // didn't find the chunk - data_p = NULL; - return; - } - - data_p += 4; - iff_chunk_len = GetLittleLong (); - if (iff_chunk_len < 0) { - data_p = NULL; - return; - } -// if (iff_chunk_len > 1024*1024) -// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); - data_p -= 8; - last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1); - if (!strncmp (data_p, name, 4)) - return; - } -} - -void -FindChunk (char *name) -{ - last_chunk = iff_data; - FindNextChunk (name); -} - - -void -DumpChunks (void) -{ - char str[5]; - - str[4] = 0; - data_p = iff_data; - do { - memcpy (str, data_p, 4); - data_p += 4; - iff_chunk_len = GetLittleLong (); - Con_Printf ("0x%x : %s (%d)\n", (int) (data_p - 4), str, iff_chunk_len); - data_p += (iff_chunk_len + 1) & ~1; - } while (data_p < iff_end); -} - -/* - GetWavinfo -*/ -wavinfo_t -GetWavinfo (char *name, byte * wav, int wavlength) -{ - wavinfo_t info; - int i; - int format; - int samples; - - memset (&info, 0, sizeof (info)); - - if (!wav) - return info; - - iff_data = wav; - iff_end = wav + wavlength; - -// find "RIFF" chunk - FindChunk ("RIFF"); - if (!(data_p && !strncmp (data_p + 8, "WAVE", 4))) { - Con_Printf ("Missing RIFF/WAVE chunks\n"); - return info; - } -// get "fmt " chunk - iff_data = data_p + 12; -// DumpChunks (); - - FindChunk ("fmt "); - if (!data_p) { - Con_Printf ("Missing fmt chunk\n"); - return info; - } - data_p += 8; - format = GetLittleShort (); - if (format != 1) { - Con_Printf ("Microsoft PCM format only\n"); - return info; - } - - info.channels = GetLittleShort (); - info.rate = GetLittleLong (); - data_p += 4 + 2; - info.width = GetLittleShort () / 8; - -// get cue chunk - FindChunk ("cue "); - if (data_p) { - data_p += 32; - info.loopstart = GetLittleLong (); -// Con_Printf("loopstart=%d\n", sfx->loopstart); - - // if the next chunk is a LIST chunk, look for a cue length marker - FindNextChunk ("LIST"); - if (data_p) { - if (!strncmp (data_p + 28, "mark", 4)) { // this is not a - // proper parse, but - // it works with - // cooledit... - data_p += 24; - i = GetLittleLong (); // samples in loop - info.samples = info.loopstart + i; -// Con_Printf("looped length: %i\n", i); - } - } - } else - info.loopstart = -1; - -// find data chunk - FindChunk ("data"); - if (!data_p) { - Con_Printf ("Missing data chunk\n"); - return info; - } - - data_p += 4; - samples = GetLittleLong () / info.width; - - if (info.samples) { - if (samples < info.samples) - Sys_Error ("Sound %s has a bad loop length", name); - } else - info.samples = samples; - - info.dataofs = data_p - wav; - - return info; -} diff --git a/nq/source/snd_mix.c b/nq/source/snd_mix.c deleted file mode 100644 index 947914c24..000000000 --- a/nq/source/snd_mix.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - snd_mix.c - - portable code to mix sounds for snd_dma.c - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include "QF/compat.h" -#include "QF/console.h" -#include "sound.h" - -#ifdef _WIN32 -# include "winquake.h" -#else -# define DWORD unsigned long -#endif - -#define PAINTBUFFER_SIZE 512 -portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2]; -int max_overpaint; // number of extra samples painted - - // due to phase shift -int snd_scaletable[32][256]; -int *snd_p, snd_linear_count, snd_vol; -short *snd_out; - -void Snd_WriteLinearBlastStereo16 (void); - -#ifndef USE_INTEL_ASM -void -Snd_WriteLinearBlastStereo16 (void) -{ - int i; - int val; - - for (i = 0; i < snd_linear_count; i += 2) { - val = (snd_p[i] * snd_vol) >> 8; - if (val > 0x7fff) - snd_out[i] = 0x7fff; - else if (val < (short) 0x8000) - snd_out[i] = (short) 0x8000; - else - snd_out[i] = val; - - val = (snd_p[i + 1] * snd_vol) >> 8; - if (val > 0x7fff) - snd_out[i + 1] = 0x7fff; - else if (val < (short) 0x8000) - snd_out[i + 1] = (short) 0x8000; - else - snd_out[i + 1] = val; - } -} -#endif - -void -S_TransferStereo16 (int endtime) -{ - int lpos; - int lpaintedtime; - DWORD *pbuf; - - snd_vol = volume->value * 256; - - snd_p = (int *) paintbuffer; - lpaintedtime = paintedtime; - -#ifdef _WIN32 - if (pDSBuf) { - pbuf = DSOUND_LockBuffer (true); - if (!pbuf) { - Con_Printf ("DSOUND_LockBuffer fails!\n"); - return; - } - } else -#endif - { - pbuf = (DWORD *) shm->buffer; - } - - while (lpaintedtime < endtime) { - // handle recirculating buffer issues - lpos = lpaintedtime & ((shm->samples >> 1) - 1); - - snd_out = (short *) pbuf + (lpos << 1); - - snd_linear_count = (shm->samples >> 1) - lpos; - if (lpaintedtime + snd_linear_count > endtime) - snd_linear_count = endtime - lpaintedtime; - - snd_linear_count <<= 1; - - // write a linear blast of samples - Snd_WriteLinearBlastStereo16 (); - - snd_p += snd_linear_count; - lpaintedtime += (snd_linear_count >> 1); - } - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_LockBuffer (false); -#endif -} - -void -S_TransferPaintBuffer (int endtime) -{ - int out_idx; - int count; - int out_mask; - int *p; - int step; - int val; - int snd_vol; - DWORD *pbuf; - - if (shm->samplebits == 16 && shm->channels == 2) { - S_TransferStereo16 (endtime); - return; - } - - p = (int *) paintbuffer; - count = (endtime - paintedtime) * shm->channels; - out_mask = shm->samples - 1; - out_idx = paintedtime * shm->channels & out_mask; - step = 3 - shm->channels; - snd_vol = volume->value * 256; - -#ifdef _WIN32 - if (pDSBuf) { - pbuf = DSOUND_LockBuffer (true); - if (!pbuf) { - Con_Printf ("DSOUND_LockBuffer fails!\n"); - return; - } - } else -#endif - { - pbuf = (DWORD *) shm->buffer; - } - - if (shm->samplebits == 16) { - short *out = (short *) pbuf; - - while (count--) { - val = (*p * snd_vol) >> 8; - p += step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short) 0x8000) - val = (short) 0x8000; - out[out_idx] = val; - out_idx = (out_idx + 1) & out_mask; - } - } else if (shm->samplebits == 8) { - unsigned char *out = (unsigned char *) pbuf; - - while (count--) { - val = (*p * snd_vol) >> 8; - p += step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short) 0x8000) - val = (short) 0x8000; - out[out_idx] = (val >> 8) + 128; - out_idx = (out_idx + 1) & out_mask; - } - } -#ifdef _WIN32 - if (pDSBuf) - DSOUND_LockBuffer (false); -#endif -} - - -/* - CHANNEL MIXING -*/ - -void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime); -void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime); - -void -S_PaintChannels (int endtime) -{ - int i; - int end; - channel_t *ch; - sfxcache_t *sc; - int ltime, count; - - while (paintedtime < endtime) { - // if paintbuffer is smaller than DMA buffer - end = endtime; - if (endtime - paintedtime > PAINTBUFFER_SIZE) - end = paintedtime + PAINTBUFFER_SIZE; - - // clear the paint buffer -// memset (paintbuffer, 0, -// (end - paintedtime) * sizeof (portable_samplepair_t)); - max_overpaint = 0; - - // paint in the channels. - ch = channels; - for (i = 0; i < total_channels; i++, ch++) { - if (!ch->sfx) - continue; - if (!ch->leftvol && !ch->rightvol) - continue; - sc = S_LoadSound (ch->sfx); - if (!sc) - continue; - - ltime = paintedtime; - - while (ltime < end) { // paint up to end - if (ch->end < end) - count = ch->end - ltime; - else - count = end - ltime; - - if (count > 0) { - if (sc->width == 1) - SND_PaintChannelFrom8 (ch, sc, count); - else - SND_PaintChannelFrom16 (ch, sc, count); - - ltime += count; - } - // if at end of loop, restart - if (ltime >= ch->end) { - if (sc->loopstart >= 0) { - ch->pos = sc->loopstart; - ch->end = ltime + sc->length - ch->pos; - } else { // channel just stopped - ch->sfx = NULL; - break; - } - } - } - - } - - // transfer out according to DMA format - S_TransferPaintBuffer (end); - - memmove (paintbuffer, paintbuffer + end - paintedtime, - max_overpaint * sizeof (paintbuffer[0])); - memset (paintbuffer + max_overpaint, 0, sizeof (paintbuffer) - - max_overpaint * sizeof (paintbuffer[0])); - - paintedtime = end; - } -} - -void -SND_InitScaletable (void) -{ - int i, j; - - for (i = 0; i < 32; i++) - for (j = 0; j < 256; j++) - snd_scaletable[i][j] = ((signed char) j) * i * 8; -} - - -#ifndef USE_INTEL_ASM - -void -SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int *lscale, *rscale; - unsigned char *sfx; - int i; - - if (ch->leftvol > 255) - ch->leftvol = 255; - if (ch->rightvol > 255) - ch->rightvol = 255; - - lscale = snd_scaletable[ch->leftvol >> 3]; - rscale = snd_scaletable[ch->rightvol >> 3]; - sfx = (signed char *) sc->data + ch->pos; - - for (i = 0; i < count; i++) { - data = sfx[i]; - paintbuffer[i].left += lscale[data]; - paintbuffer[i].right += rscale[data]; - } - - ch->pos += count; -} - -#endif // !USE_INTEL_ASM - - -void -SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int left, right; - int leftvol, rightvol; - signed short *sfx; - unsigned int i = 0; - unsigned int left_phase, right_phase; // Never allowed < 0 anyway - - leftvol = ch->leftvol; - rightvol = ch->rightvol; - - max_overpaint = max (abs (ch->phase), - max (abs (ch->oldphase), max_overpaint)); - - sfx = (signed short *) sc->data + ch->pos; - ch->pos += count; - - if (ch->phase >= 0) { - left_phase = ch->phase; - right_phase = 0; - } else { - left_phase = 0; - right_phase = -ch->phase; - } - - if (ch->oldphase != ch->phase) { - unsigned int old_phase_left, old_phase_right; - unsigned int new_phase_left, new_phase_right; - unsigned int count_left, count_right, c; - - if (ch->oldphase >= 0) { - old_phase_left = ch->oldphase; - old_phase_right = 0; - } else { - old_phase_left = 0; - old_phase_right = -ch->oldphase; - } - new_phase_left = left_phase; - new_phase_right = right_phase; - - if (new_phase_left > old_phase_left) - count_left = 2 * (new_phase_left - old_phase_left); - else - count_left = old_phase_left - new_phase_left; - - if (new_phase_right > old_phase_right) - count_right = 2 * (new_phase_right - old_phase_right); - else - count_right = old_phase_right - new_phase_right; - - c = min (count, max (count_right, count_left)); - count -= c; - while (c) { - int data = sfx[i]; - int left = (data * leftvol) >> 8; - int right = (data * rightvol) >> 8; - - if (new_phase_left < old_phase_left) { - if (!(count_left & 1)) { - paintbuffer[i + old_phase_left].left += left; - old_phase_left--; - } - count_left--; - } else if (new_phase_left > old_phase_left) { - paintbuffer[i + old_phase_left].left += left; - old_phase_left++; - paintbuffer[i + old_phase_left].left += left; - } else { - paintbuffer[i + old_phase_left].left += left; - } - - if (new_phase_right < old_phase_right) { - if (!(count_right & 1)) { - paintbuffer[i + old_phase_right].right += right; - old_phase_right--; - } - count_right--; - } else if (new_phase_right > old_phase_right) { - paintbuffer[i + old_phase_right].right += right; - old_phase_right++; - paintbuffer[i + old_phase_right].right += right; - } else { - paintbuffer[i + old_phase_right].right += right; - } - - c--; - i++; - } - } - - for (i = 0; i < count; i++) { - data = sfx[i]; - left = (data * leftvol) >> 8; - right = (data * rightvol) >> 8; - paintbuffer[i + left_phase].left += left; - paintbuffer[i + right_phase].right += right; - } -} diff --git a/nq/source/snd_mixa.S b/nq/source/snd_mixa.S deleted file mode 100644 index e135fc383..000000000 --- a/nq/source/snd_mixa.S +++ /dev/null @@ -1,232 +0,0 @@ -/* - snd_mixa.S - - x86 assembly-language sound code - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "QF/asm_i386.h" -// #include "quakeasm.h" - -#ifdef USE_INTEL_ASM - - .text - - .extern C(snd_scaletable) - .extern C(paintbuffer) - .extern C(snd_linear_count) - .extern C(snd_p) - .extern C(snd_vol) - .extern C(snd_out) - -//---------------------------------------------------------------------- -// 8-bit sound-mixing code -//---------------------------------------------------------------------- - -#define ch 4+16 -#define sc 8+16 -#define count 12+16 - -.globl C(SND_PaintChannelFrom8) -C(SND_PaintChannelFrom8): - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - pushl %ebp - -// int data; -// short *lscale, *rscale; -// unsigned char *sfx; -// int i; - - movl ch(%esp),%ebx - movl sc(%esp),%esi - -// if (ch->leftvol > 255) -// ch->leftvol = 255; -// if (ch->rightvol > 255) -// ch->rightvol = 255; - movl ch_leftvol(%ebx),%eax - movl ch_rightvol(%ebx),%edx - cmpl $255,%eax - jna LLeftSet - movl $255,%eax -LLeftSet: - cmpl $255,%edx - jna LRightSet - movl $255,%edx -LRightSet: - -// lscale = snd_scaletable[ch->leftvol >> 3]; -// rscale = snd_scaletable[ch->rightvol >> 3]; -// sfx = (signed char *)sc->data + ch->pos; -// ch->pos += count; - andl $0xF8,%eax - addl $(sfxc_data),%esi - andl $0xF8,%edx - movl ch_pos(%ebx),%edi - movl count(%esp),%ecx - addl %edi,%esi - shll $7,%eax - addl %ecx,%edi - shll $7,%edx - movl %edi,ch_pos(%ebx) - addl $(C(snd_scaletable)),%eax - addl $(C(snd_scaletable)),%edx - subl %ebx,%ebx - movb -1(%esi,%ecx,1),%bl - - testl $1,%ecx - jz LMix8Loop - - movl (%eax,%ebx,4),%edi - movl (%edx,%ebx,4),%ebp - addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi - addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp - movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size) - movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size) - movb -2(%esi,%ecx,1),%bl - - decl %ecx - jz LDone - -// for (i=0 ; i>8; -// if (val > 0x7fff) -// snd_out[i] = 0x7fff; -// else if (val < (short)0x8000) -// snd_out[i] = (short)0x8000; -// else -// snd_out[i] = val; - movl -8(%ebx,%ecx,4),%eax - imull %esi,%eax - sarl $8,%eax - cmpl $0x7FFF,%eax - jg LClampHigh - cmpl $0xFFFF8000,%eax - jnl LClampDone - movl $0xFFFF8000,%eax - jmp LClampDone -LClampHigh: - movl $0x7FFF,%eax -LClampDone: - -// val = (snd_p[i+1]*snd_vol)>>8; -// if (val > 0x7fff) -// snd_out[i+1] = 0x7fff; -// else if (val < (short)0x8000) -// snd_out[i+1] = (short)0x8000; -// else -// snd_out[i+1] = val; - movl -4(%ebx,%ecx,4),%edx - imull %esi,%edx - sarl $8,%edx - cmpl $0x7FFF,%edx - jg LClampHigh2 - cmpl $0xFFFF8000,%edx - jnl LClampDone2 - movl $0xFFFF8000,%edx - jmp LClampDone2 -LClampHigh2: - movl $0x7FFF,%edx -LClampDone2: - shll $16,%edx - andl $0xFFFF,%eax - orl %eax,%edx - movl %edx,-4(%edi,%ecx,2) - -// } - subl $2,%ecx - jnz LWLBLoopTop - -// snd_p += snd_linear_count; - - popl %ebx - popl %edi - popl %esi - - ret - - -#endif // USE_INTEL_ASM - diff --git a/nq/source/snd_next.c b/nq/source/snd_next.c deleted file mode 100644 index b8638d42c..000000000 --- a/nq/source/snd_next.c +++ /dev/null @@ -1,73 +0,0 @@ - -/* - snd_next.c - - @description@ - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - -extern int desired_speed; -extern int desired_bits; - -qboolean -SNDDMA_Init (void) -{ - int size; - - size = 16384 + sizeof (dma_t); - - shm = malloc (size); - memset ((void *) shm, 0, size); - - shm->buffer = (char *) shm + sizeof (dma_t); - - shm->channels = 2; - shm->speed = desired_speed; - shm->samplebits = desired_bits; - shm->samples = 16384 / (desired_bits / 8); - shm->submission_chunk = 1; - - return true; -} - -// return the current sample position (in mono samples read) -// inside the recirculating dma buffer -int -SNDDMA_GetDMAPos (void) -{ - shm->samplepos = - (int) (realtime * shm->speed * shm->channels) & (shm->samples - 1); - - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ -} diff --git a/nq/source/snd_null.c b/nq/source/snd_null.c deleted file mode 100644 index f7b6dc9fb..000000000 --- a/nq/source/snd_null.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - snd_null.c - - include this instead of all the other snd_* files to have no sound - code whatsoever - - Copyright (C) 1996-1997 Id Software, Inc. - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#include "QF/qtypes.h" -#include "sound.h" - -// ======================================================================= -// Various variables also defined in snd_dma.c -// FIXME - should be put in one place -// ======================================================================= -channel_t channels[MAX_CHANNELS]; -int total_channels; -volatile dma_t *shm = 0; -cvar_t *loadas8bit; -int paintedtime; // sample PAIRS - - -cvar_t *bgmvolume; -cvar_t *volume; - - -void -S_Init (void) -{ - S_Init_Cvars (); -} - -void -S_Init_Cvars (void) -{ - volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, 0, "Volume level of sounds"); - loadas8bit = - Cvar_Get ("loadas8bit", "0", CVAR_NONE, 0, "Load samples as 8-bit"); - bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, 0, "CD music volume"); -} - -void -S_AmbientOff (void) -{ -} - -void -S_AmbientOn (void) -{ -} - -void -S_Shutdown (void) -{ -} - -void -S_TouchSound (char *sample) -{ -} - -void -S_ClearBuffer (void) -{ -} - -void -S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) -{ -} - -void -S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, - float attenuation) -{ -} - -void -S_StopSound (int entnum, int entchannel) -{ -} - -sfx_t * -S_PrecacheSound (char *sample) -{ - return NULL; -} - -void -S_ClearPrecache (void) -{ -} - -void -S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up) -{ -} - -void -S_StopAllSounds (qboolean clear) -{ -} - -void -S_BeginPrecaching (void) -{ -} - -void -S_EndPrecaching (void) -{ -} - -void -S_ExtraUpdate (void) -{ -} - -void -S_LocalSound (char *s) -{ -} diff --git a/nq/source/snd_oss.c b/nq/source/snd_oss.c deleted file mode 100644 index 03dd17335..000000000 --- a/nq/source/snd_oss.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - snd_oss.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_IOCTL_H -# include -#endif - -#ifdef HAVE_SYS_MMAN_H -# include -#endif - -#if defined HAVE_SYS_SOUNDCARD_H -# include -#elif defined HAVE_LINUX_SOUNDCARD_H -# include -#elif HAVE_MACHINE_SOUNDCARD_H -# include -#endif - -#include "QF/cmd.h" -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -#ifndef MAP_FAILED -# define MAP_FAILED ((void *) -1) -#endif - -static int audio_fd; -static int snd_inited; -static char *snd_dev = "/dev/dsp"; - -static int tryrates[] = { 11025, 22050, 22051, 44100, 8000 }; - -qboolean -SNDDMA_Init (void) -{ - int rc; - int fmt; - int tmp; - int i; - struct audio_buf_info info; - int caps; - int retries = 3; - - snd_inited = 0; - - // open snd_dev, confirm capability to mmap, and get size of dma buffer - if (snd_device->string[0]) - snd_dev = snd_device->string; - - audio_fd = open (snd_dev, O_RDWR); - if (audio_fd < 0) { // Failed open, retry up to 3 times - // if it's busy - while ((audio_fd < 0) && retries-- && - ((errno == EAGAIN) || (errno == EBUSY))) { - sleep (1); - audio_fd = open (snd_dev, O_RDWR); - } - if (audio_fd < 0) { - perror (snd_dev); - Con_Printf ("Could not open %s\n", snd_dev); - return 0; - } - } - - if ((rc = ioctl (audio_fd, SNDCTL_DSP_RESET, 0)) < 0) { - perror (snd_dev); - Con_Printf ("Could not reset %s\n", snd_dev); - close (audio_fd); - return 0; - } - - if (ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) { - perror (snd_dev); - Con_Printf ("Sound driver too old\n"); - close (audio_fd); - return 0; - } - - if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) { - Con_Printf ("Sound device can't do memory-mapped I/O.\n"); - close (audio_fd); - return 0; - } - - if (ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) { - perror ("GETOSPACE"); - Con_Printf ("Um, can't do GETOSPACE?\n"); - close (audio_fd); - return 0; - } - - shm = &sn; - shm->splitbuffer = 0; - - // set sample bits & speed - shm->samplebits = snd_bits->int_val; - - if (shm->samplebits != 16 && shm->samplebits != 8) { - ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &fmt); - - if (fmt & AFMT_S16_LE) { // little-endian 16-bit signed - shm->samplebits = 16; - } else { - if (fmt & AFMT_U8) { // unsigned 8-bit ulaw - shm->samplebits = 8; - } - } - } - - if (snd_rate->int_val) { - shm->speed = snd_rate->int_val; - } else { - for (i = 0; i < (sizeof (tryrates) / 4); i++) - if (!ioctl (audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) - break; - shm->speed = tryrates[i]; - } - - if (!snd_stereo->int_val) { - shm->channels = 1; - } else { - shm->channels = 2; - } - - shm->samples = info.fragstotal * info.fragsize / (shm->samplebits / 8); - shm->submission_chunk = 1; - - // memory map the dma buffer - shm->buffer = (unsigned char *) mmap (NULL, info.fragstotal - * info.fragsize, - PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, audio_fd, 0); - - if (shm->buffer == MAP_FAILED) { - perror (snd_dev); - Con_Printf ("Could not mmap %s\n", snd_dev); - close (audio_fd); - return 0; - } - - tmp = 0; - if (shm->channels == 2) - tmp = 1; - rc = ioctl (audio_fd, SNDCTL_DSP_STEREO, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not set %s to stereo=%d", snd_dev, shm->channels); - close (audio_fd); - return 0; - } - - if (tmp) - shm->channels = 2; - else - shm->channels = 1; - - rc = ioctl (audio_fd, SNDCTL_DSP_SPEED, &shm->speed); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not set %s speed to %d", snd_dev, shm->speed); - close (audio_fd); - return 0; - } - - if (shm->samplebits == 16) { - rc = AFMT_S16_LE; - rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not support 16-bit data. Try 8-bit.\n"); - close (audio_fd); - return 0; - } - } else if (shm->samplebits == 8) { - rc = AFMT_U8; - rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not support 8-bit data.\n"); - close (audio_fd); - return 0; - } - } else { - perror (snd_dev); - Con_Printf ("%d-bit sound not supported.", shm->samplebits); - close (audio_fd); - return 0; - } - -// toggle the trigger & start her up - - tmp = 0; - rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not toggle.\n"); - close (audio_fd); - return 0; - } - tmp = PCM_ENABLE_OUTPUT; - rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not toggle.\n"); - close (audio_fd); - return 0; - } - - shm->samplepos = 0; - - snd_inited = 1; - return 1; - -} - -int -SNDDMA_GetDMAPos (void) -{ - - struct count_info count; - - if (!snd_inited) - return 0; - - if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) { - perror (snd_dev); - Con_Printf ("Uh, sound dead.\n"); - close (audio_fd); - snd_inited = 0; - return 0; - } -// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); -// fprintf(stderr, "%d \r", count.ptr); - shm->samplepos = count.ptr / (shm->samplebits / 8); - - return shm->samplepos; - -} - -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) -{ -} diff --git a/nq/source/snd_sdl.c b/nq/source/snd_sdl.c deleted file mode 100644 index a33fc6ddb..000000000 --- a/nq/source/snd_sdl.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - snd_sdl.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "QF/cmd.h" -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -static dma_t the_shm; -static int snd_inited; - -extern int desired_speed; -extern int desired_bits; - -static void -paint_audio (void *unused, Uint8 * stream, int len) -{ - if (shm) { - shm->buffer = stream; - shm->samplepos += len / (shm->samplebits / 8); - // Check for samplepos overflow? - S_PaintChannels (shm->samplepos); - } -} - -qboolean -SNDDMA_Init (void) -{ - SDL_AudioSpec desired, obtained; - - snd_inited = 0; - - /* Set up the desired format */ - desired.freq = desired_speed; - switch (desired_bits) { - case 8: - desired.format = AUDIO_U8; - break; - case 16: - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) - desired.format = AUDIO_S16MSB; - else - desired.format = AUDIO_S16LSB; - break; - default: - Con_Printf ("Unknown number of audio bits: %d\n", desired_bits); - return 0; - } - desired.channels = 2; - desired.samples = 512; - desired.callback = paint_audio; - - /* Open the audio device */ - if (SDL_OpenAudio (&desired, &obtained) < 0) { - Con_Printf ("Couldn't open SDL audio: %s\n", SDL_GetError ()); - return 0; - } - - /* Make sure we can support the audio format */ - switch (obtained.format) { - case AUDIO_U8: - /* Supported */ - break; - case AUDIO_S16LSB: - case AUDIO_S16MSB: - if (((obtained.format == AUDIO_S16LSB) && - (SDL_BYTEORDER == SDL_LIL_ENDIAN)) || - ((obtained.format == AUDIO_S16MSB) && - (SDL_BYTEORDER == SDL_BIG_ENDIAN))) { - /* Supported */ - break; - } - /* Unsupported, fall through */ ; - default: - /* Not supported -- force SDL to do our bidding */ - SDL_CloseAudio (); - if (SDL_OpenAudio (&desired, NULL) < 0) { - Con_Printf ("Couldn't open SDL audio: %s\n", SDL_GetError ()); - return 0; - } - memcpy (&obtained, &desired, sizeof (desired)); - break; - } - SDL_PauseAudio (0); - - /* Fill the audio DMA information block */ - shm = &the_shm; - shm->splitbuffer = 0; - shm->samplebits = (obtained.format & 0xFF); - shm->speed = obtained.freq; - shm->channels = obtained.channels; - shm->samples = obtained.samples * shm->channels; - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = NULL; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - SDL_CloseAudio (); - snd_inited = 0; - } -} - -/* - - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer - -*/ -void -SNDDMA_Submit (void) -{ -} diff --git a/nq/source/snd_sgi.c b/nq/source/snd_sgi.c deleted file mode 100644 index 789388761..000000000 --- a/nq/source/snd_sgi.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - snd_sgi.c - - sound support for sgi - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#include "QF/console.h" -#include "QF/qtypes.h" -#include "QF/qargs.h" -#include "sound.h" - -static int snd_inited = 0; -static ALconfig alc; -static ALport alp; - -static int tryrates[] = { 11025, 22050, 44100, 8000 }; - -static unsigned char *dma_buffer, *write_buffer; -static int bufsize; -static int wbufp; -static int framecount; - -qboolean -SNDDMA_Init (void) -{ - ALpv alpv; - int i; - char *s; - - alc = alNewConfig (); - - if (!alc) { - Con_Printf ("Could not make an new sound config: %s\n", - alGetErrorString (oserror ())); - return 0; - } - - shm = &sn; - shm->splitbuffer = 0; - - /* get & probe settings */ - /* sample format */ - if (alSetSampFmt (alc, AL_SAMPFMT_TWOSCOMP) < 0) { - Con_Printf ("Could not sample format of default output to two's " - "complement\n"); - alFreeConfig (alc); - return 0; - } - - /* sample bits */ - s = getenv ("QUAKE_SOUND_SAMPLEBITS"); - if (s) - shm->samplebits = atoi (s); - else if ((i = COM_CheckParm ("-sndbits")) != 0) - shm->samplebits = atoi (com_argv[i + 1]); - - if (shm->samplebits != 16 && shm->samplebits != 8) { - alpv.param = AL_WORDSIZE; - - if (alGetParams (AL_DEFAULT_OUTPUT, &alpv, 1) < 0) { - Con_Printf ("Could not get supported wordsize of default " - "output: %s\n", alGetErrorString (oserror ())); - return 0; - } - - if (alpv.value.i >= 16) { - shm->samplebits = 16; - } else { - if (alpv.value.i >= 8) - shm->samplebits = 8; - else { - Con_Printf ("Sound disabled since interface " - "doesn't even support 8 bit."); - alFreeConfig (alc); - return 0; - } - } - } - - /* sample rate */ - s = getenv ("QUAKE_SOUND_SPEED"); - if (s) - shm->speed = atoi (s); - else if ((i = COM_CheckParm ("-sndspeed")) != 0) - shm->speed = atoi (com_argv[i + 1]); - else { - alpv.param = AL_RATE; - - for (i = 0; i < sizeof (tryrates) / sizeof (int); i++) { - alpv.value.ll = alDoubleToFixed (tryrates[i]); - - if (alSetParams (AL_DEFAULT_OUTPUT, &alpv, 1) >= 0) - break; - } - - if (i >= sizeof (tryrates) / sizeof (int)) { - Con_Printf ("Sound disabled since interface doesn't even " - "support a sample rate of %d\n", tryrates[i - 1]); - alFreeConfig (alc); - return 0; - } - - shm->speed = tryrates[i]; - } - - /* channels */ - s = getenv ("QUAKE_SOUND_CHANNELS"); - if (s) - shm->channels = atoi (s); - else if ((i = COM_CheckParm ("-sndmono")) != 0) - shm->channels = 1; - else if ((i = COM_CheckParm ("-sndstereo")) != 0) - shm->channels = 2; - else - shm->channels = 2; - - /* set 'em */ - - /* channels */ - while (shm->channels > 0) { - if (alSetChannels (alc, shm->channels) < 0) { - Con_Printf ("Unable to set number of channels to %d, trying half\n", - shm->channels); - shm->channels /= 2; - } else - break; - } - - if (shm->channels <= 0) { - Con_Printf ("Sound disabled since interface doesn't even support 1 " - "channel\n"); - alFreeConfig (alc); - return 0; - } - - /* sample rate */ - alpv.param = AL_RATE; - alpv.value.ll = alDoubleToFixed (shm->speed); - - if (alSetParams (AL_DEFAULT_OUTPUT, &alpv, 1) < 0) { - Con_Printf ("Could not set samplerate of default output to %d: %s\n", - shm->speed, alGetErrorString (oserror ())); - alFreeConfig (alc); - return 0; - } - - /* set sizes of buffers relative to sizes of those for ** the 'standard' - frequency of 11025 ** ** use *huge* buffers since at least my indigo2 - has enough ** to do to get sound on the way anyway */ - bufsize = 32768 * (int) ((double) shm->speed / 11025.0); - - dma_buffer = malloc (bufsize); - - if (dma_buffer == NULL) { - Con_Printf ("Could not get %d bytes of memory for audio dma buffer\n", - bufsize); - alFreeConfig (alc); - return 0; - } - - write_buffer = malloc (bufsize); - - if (write_buffer == NULL) { - Con_Printf ("Could not get %d bytes of memory for audio write buffer\n", - bufsize); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - /* sample bits */ - switch (shm->samplebits) { - case 24: - i = AL_SAMPLE_24; - break; - - case 16: - i = AL_SAMPLE_16; - break; - - default: - i = AL_SAMPLE_8; - break; - } - - if (alSetWidth (alc, i) < 0) { - Con_Printf ("Could not set wordsize of default output to %d: %s\n", - shm->samplebits, alGetErrorString (oserror ())); - free (write_buffer); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - alp = alOpenPort ("quakeforge", "w", alc); - - if (!alp) { - Con_Printf ("Could not open sound port: %s\n", - alGetErrorString (oserror ())); - free (write_buffer); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - shm->soundalive = true; - shm->samples = bufsize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = dma_buffer; - - framecount = 0; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - /* Con_Printf("framecount: %d %d\n", (framecount * shm->channels) % - shm->samples, alGetFilled(alp)); */ - shm->samplepos = ((framecount - alGetFilled (alp)) - * shm->channels) % shm->samples; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - free (write_buffer); - free (dma_buffer); - alClosePort (alp); - alFreeConfig (alc); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int bsize; - int bytes, b; - unsigned char *p; - int idx; - int stop = paintedtime; - - if (paintedtime < wbufp) - wbufp = 0; // reset - - bsize = shm->channels * (shm->samplebits / 8); - bytes = (paintedtime - wbufp) * bsize; - - if (!bytes) - return; - - if (bytes > bufsize) { - bytes = bufsize; - stop = wbufp + bytes / bsize; - } - - p = write_buffer; - idx = (wbufp * bsize) & (bufsize - 1); - - for (b = bytes; b; b--) { - *p++ = dma_buffer[idx]; - idx = (idx + 1) & (bufsize - 1); - } - - wbufp = stop; - - alWriteFrames (alp, write_buffer, bytes / bsize); - framecount += bytes / bsize; -} - -/* end of file */ diff --git a/nq/source/snd_sun.c b/nq/source/snd_sun.c deleted file mode 100644 index 2a2602b65..000000000 --- a/nq/source/snd_sun.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - snd_sun.c - - (description) - - Copyright (C) 1996-1997 Id Software, Inc. - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "QF/qtypes.h" -#include "sound.h" -#include "QF/qargs.h" -#include "QF/console.h" - -int audio_fd; -int snd_inited; - -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; - -qboolean -SNDDMA_Init (void) -{ - if (snd_inited) { - printf ("Sound already init'd\n"); - return 0; - } - - 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 bsize; - int bytes, b; - static unsigned char writebuf[1024]; - unsigned char *p; - int idx; - int stop = paintedtime; - - 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"); - -} diff --git a/nq/source/snd_win.c b/nq/source/snd_win.c deleted file mode 100644 index 1b2bb086f..000000000 --- a/nq/source/snd_win.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - snd_win.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#define CINTERFACE - -#include "winquake.h" -#include "QF/qargs.h" -#include "QF/console.h" -#include "sound.h" - -#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) - -HRESULT (WINAPI * pDirectSoundCreate) (GUID FAR * lpGUID, - LPDIRECTSOUND FAR * lplpDS, - IUnknown FAR * pUnkOuter); - -// 64K is > 1 second at 16-bit, 22050 Hz -#define WAV_BUFFERS 64 -#define WAV_MASK 0x3F -#define WAV_BUFFER_SIZE 0x0400 -#define SECONDARY_BUFFER_SIZE 0x10000 - -typedef enum { SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL } sndinitstat; - -static qboolean wavonly; -static qboolean dsound_init; -static qboolean wav_init; -static qboolean snd_firsttime = true, snd_isdirect, snd_iswave; -static qboolean primary_format_set; - -static int sample16; -static int snd_sent, snd_completed; - -/* - * Global variables. Must be visible to window-procedure function - * so it can unlock and free the data block after it has been played. - */ - -HANDLE hData; -HPSTR lpData, lpData2; - -HGLOBAL hWaveHdr; -LPWAVEHDR lpWaveHdr; - -HWAVEOUT hWaveOut; - -WAVEOUTCAPS wavecaps; - -DWORD gSndBufSize; - -MMTIME mmstarttime; - -LPDIRECTSOUND pDS; -LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; - -HINSTANCE hInstDS; - -sndinitstat SNDDMA_InitDirect (void); -qboolean SNDDMA_InitWav (void); - - -/* - S_BlockSound -*/ -void -S_BlockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) { - snd_blocked++; - - if (snd_blocked == 1) - waveOutReset (hWaveOut); - } -} - - -/* - S_UnblockSound -*/ -void -S_UnblockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) { - snd_blocked--; - } -} - - -/* - FreeSound -*/ -void -FreeSound (void) -{ - int i; - - if (pDSBuf) { - IDirectSoundBuffer_Stop (pDSBuf); - IDirectSound_Release (pDSBuf); - } -// only release primary buffer if it's not also the mixing buffer we just released - if (pDSPBuf && (pDSBuf != pDSPBuf)) { - IDirectSound_Release (pDSPBuf); - } - - if (pDS) { - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); - IDirectSound_Release (pDS); - } - - if (hWaveOut) { - waveOutReset (hWaveOut); - - if (lpWaveHdr) { - for (i = 0; i < WAV_BUFFERS; i++) - waveOutUnprepareHeader (hWaveOut, lpWaveHdr + i, - sizeof (WAVEHDR)); - } - - waveOutClose (hWaveOut); - - if (hWaveHdr) { - GlobalUnlock (hWaveHdr); - GlobalFree (hWaveHdr); - } - - if (hData) { - GlobalUnlock (hData); - GlobalFree (hData); - } - - } - - pDS = NULL; - pDSBuf = NULL; - pDSPBuf = NULL; - hWaveOut = 0; - hData = 0; - hWaveHdr = 0; - lpData = NULL; - lpWaveHdr = NULL; - dsound_init = false; - wav_init = false; -} - - -/* - SNDDMA_InitDirect - - Direct-Sound support -*/ -sndinitstat SNDDMA_InitDirect (void) -{ - DSBUFFERDESC dsbuf; - DSBCAPS dsbcaps; - DWORD dwSize, dwWrite; - DSCAPS dscaps; - WAVEFORMATEX format, pformat; - HRESULT hresult; - int reps; - - memset ((void *) &sn, 0, sizeof (sn)); - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - shm->speed = 11025; - - memset (&format, 0, sizeof (format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - if (!hInstDS) { - hInstDS = LoadLibrary ("dsound.dll"); - - if (hInstDS == NULL) { - Con_Printf ("Couldn't load dsound.dll\n"); - return SIS_FAILURE; - } - - pDirectSoundCreate = - (void *) GetProcAddress (hInstDS, "DirectSoundCreate"); - - if (!pDirectSoundCreate) { - Con_Printf ("Couldn't get DS proc addr\n"); - return SIS_FAILURE; - } - } - - while ((hresult = iDirectSoundCreate (NULL, &pDS, NULL)) != DS_OK) { - if (hresult != DSERR_ALLOCATED) { - Con_Printf ("DirectSound create failed\n"); - return SIS_FAILURE; - } - Con_Printf ("DirectSoundCreate failure\n" - " hardware already in use\n"); - return SIS_NOTAVAIL; - } - - dscaps.dwSize = sizeof (dscaps); - if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { - Con_Printf ("Couldn't get DS caps\n"); - } - - if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { - Con_Printf ("No DirectSound driver installed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { - Con_Printf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } -// get access to the primary buffer, if possible, so we can set the -// sound hardware format - memset (&dsbuf, 0, sizeof (dsbuf)); - dsbuf.dwSize = sizeof (DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; - dsbuf.dwBufferBytes = 0; - dsbuf.lpwfxFormat = NULL; - - memset (&dsbcaps, 0, sizeof (dsbcaps)); - dsbcaps.dwSize = sizeof (dsbcaps); - primary_format_set = false; - - if (!COM_CheckParm ("-snoforceformat")) { - if (DS_OK == - IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL)) { - pformat = format; - - if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) { - } else - primary_format_set = true; - } - } - - if (!primary_format_set || !COM_CheckParm ("-primarysound")) { - // create the secondary buffer we'll actually work with - memset (&dsbuf, 0, sizeof (dsbuf)); - dsbuf.dwSize = sizeof (DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; - dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; - dsbuf.lpwfxFormat = &format; - - memset (&dsbcaps, 0, sizeof (dsbcaps)); - dsbcaps.dwSize = sizeof (dsbcaps); - - if (DS_OK != - IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSBuf, NULL)) { - Con_Printf ("DS:CreateSoundBuffer Failed"); - FreeSound (); - return SIS_FAILURE; - } - - shm->channels = format.nChannels; - shm->samplebits = format.wBitsPerSample; - shm->speed = format.nSamplesPerSec; - - if (DS_OK != IDirectSound_GetCaps (pDSBuf, &dsbcaps)) { - Con_Printf ("DS:GetCaps failed\n"); - FreeSound (); - return SIS_FAILURE; - } - } else { - if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, - DSSCL_WRITEPRIMARY)) { - Con_Printf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != IDirectSound_GetCaps (pDSPBuf, &dsbcaps)) { - Con_Printf ("DS:GetCaps failed\n"); - return SIS_FAILURE; - } - - pDSBuf = pDSPBuf; - } - - // Make sure mixer is active - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - gSndBufSize = dsbcaps.dwBufferBytes; - -// initialize the buffer - reps = 0; - - while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, - (LPVOID *) & lpData, &dwSize, - NULL, NULL, 0)) != DS_OK) { - if (hresult != DSERR_BUFFERLOST) { - Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (++reps > 10000) { - Con_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); - FreeSound (); - return SIS_FAILURE; - } - - } - - memset (lpData, 0, dwSize); -// lpData[4] = lpData[5] = 0x7f; // force a pop for debugging - - IDirectSoundBuffer_Unlock (pDSBuf, lpData, dwSize, NULL, 0); - - /* we don't want anyone to access the buffer directly w/o locking it - first. */ - lpData = NULL; - - IDirectSoundBuffer_Stop (pDSBuf); - IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmstarttime.u.sample, - &dwWrite); - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - shm->soundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits / 8) - 1; - - dsound_init = true; - - return SIS_SUCCESS; -} - - -/* - SNDDM_InitWav - - Crappy windows multimedia base -*/ -qboolean -SNDDMA_InitWav (void) -{ - WAVEFORMATEX format; - int i; - HRESULT hr; - - snd_sent = 0; - snd_completed = 0; - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - shm->speed = 11025; - - memset (&format, 0, sizeof (format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - /* Open a waveform device for output using window callback. */ - while ((hr = waveOutOpen ((LPHWAVEOUT) & hWaveOut, WAVE_MAPPER, - &format, 0, 0L, - CALLBACK_NULL)) != MMSYSERR_NOERROR) { - if (hr != MMSYSERR_ALLOCATED) { - Con_Printf ("waveOutOpen failed\n"); - return false; - } - Con_Printf ("waveOutOpen failure;\n" " hardware already in use\n"); - return false; - } - - /* - * Allocate and lock memory for the waveform data. The memory - * for waveform data must be globally allocated with - * GMEM_MOVEABLE and GMEM_SHARE flags. - - */ - gSndBufSize = WAV_BUFFERS * WAV_BUFFER_SIZE; - hData = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); - if (!hData) { - Con_Printf ("Sound: Out of memory.\n"); - FreeSound (); - return false; - } - lpData = GlobalLock (hData); - if (!lpData) { - Con_Printf ("Sound: Failed to lock.\n"); - FreeSound (); - return false; - } - memset (lpData, 0, gSndBufSize); - - /* - * Allocate and lock memory for the header. This memory must - * also be globally allocated with GMEM_MOVEABLE and - * GMEM_SHARE flags. - */ - hWaveHdr = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, - (DWORD) sizeof (WAVEHDR) * WAV_BUFFERS); - - if (hWaveHdr == NULL) { - Con_Printf ("Sound: Failed to Alloc header.\n"); - FreeSound (); - return false; - } - - lpWaveHdr = (LPWAVEHDR) GlobalLock (hWaveHdr); - - if (lpWaveHdr == NULL) { - Con_Printf ("Sound: Failed to lock header.\n"); - FreeSound (); - return false; - } - - memset (lpWaveHdr, 0, sizeof (WAVEHDR) * WAV_BUFFERS); - - /* After allocation, set up and prepare headers. */ - for (i = 0; i < WAV_BUFFERS; i++) { - lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE; - lpWaveHdr[i].lpData = lpData + i * WAV_BUFFER_SIZE; - - if (waveOutPrepareHeader (hWaveOut, lpWaveHdr + i, sizeof (WAVEHDR)) != - MMSYSERR_NOERROR) { - Con_Printf ("Sound: failed to prepare wave headers\n"); - FreeSound (); - return false; - } - } - - shm->soundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits / 8) - 1; - - wav_init = true; - - return true; -} - -/* - SNDDMA_Init - - Try to find a sound device to mix for. - Returns false if nothing is found. -*/ - -qboolean -SNDDMA_Init (void) -{ - sndinitstat stat; - - if (COM_CheckParm ("-wavonly")) - wavonly = true; - - dsound_init = wav_init = 0; - - stat = SIS_FAILURE; // assume DirectSound won't - // initialize - - /* Init DirectSound */ - if (!wavonly) { - if (snd_firsttime || snd_isdirect) { - stat = SNDDMA_InitDirect ();; - - if (stat == SIS_SUCCESS) { - snd_isdirect = true; - - if (snd_firsttime) - Con_Printf ("DirectSound initialized\n"); - } else { - snd_isdirect = false; - Con_Printf ("DirectSound failed to init\n"); - } - } - } -// if DirectSound didn't succeed in initializing, try to initialize -// waveOut sound, unless DirectSound failed because the hardware is -// already allocated (in which case the user has already chosen not -// to have sound) - if (!dsound_init && (stat != SIS_NOTAVAIL)) { - if (snd_firsttime || snd_iswave) { - - snd_iswave = SNDDMA_InitWav (); - - if (snd_iswave) { - if (snd_firsttime) - Con_Printf ("Wave sound initialized\n"); - } else { - Con_Printf ("Wave sound failed to init\n"); - } - } - } - - snd_firsttime = false; - - if (!dsound_init && !wav_init) { - if (snd_firsttime) - Con_Printf ("No sound device initialized\n"); - - return 0; - } - - return 1; -} - -/* - SNDDMA_GetDMAPos - - return the current sample position (in mono samples read) - inside the recirculating dma buffer, so the mixing code will know - how many sample are required to fill it up. -*/ -int -SNDDMA_GetDMAPos (void) -{ - MMTIME mmtime; - int s = 0; - DWORD dwWrite; - - if (dsound_init) { - mmtime.wType = TIME_SAMPLES; - IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmtime.u.sample, - &dwWrite); - s = mmtime.u.sample - mmstarttime.u.sample; - } else if (wav_init) { - s = snd_sent * WAV_BUFFER_SIZE; - } - - - s >>= sample16; - - s &= (shm->samples - 1); - - return s; -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - LPWAVEHDR h; - int wResult; - - if (!wav_init) - return; - - // - // find which sound blocks have completed - // - while (1) { - if (snd_completed == snd_sent) { - Con_DPrintf ("Sound overrun\n"); - break; - } - - if (!(lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE)) { - break; - } - - snd_completed++; // this buffer has been played - } - - // - // submit two new sound blocks - // - while (((snd_sent - snd_completed) >> sample16) < 4) { - h = lpWaveHdr + (snd_sent & WAV_MASK); - - snd_sent++; - /* - * Now the data block can be sent to the output device. The - * waveOutWrite function returns immediately and waveform - * data is sent to the output device in the background. - */ - wResult = waveOutWrite (hWaveOut, h, sizeof (WAVEHDR)); - - if (wResult != MMSYSERR_NOERROR) { - Con_Printf ("Failed to write block to device\n"); - FreeSound (); - return; - } - } -} - -/* - SNDDMA_Shutdown - - Reset the sound device for exiting -*/ -void -SNDDMA_Shutdown (void) -{ - FreeSound (); -} - -DWORD * -DSOUND_LockBuffer (qboolean lockit) -{ - int reps; - - static DWORD dwSize; - static DWORD dwSize2; - static DWORD *pbuf1; - static DWORD *pbuf2; - HRESULT hresult; - - if (!pDSBuf) - return NULL; - - if (lockit) { - reps = 0; - while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, - (LPVOID *) & pbuf1, &dwSize, - (LPVOID *) & pbuf2, &dwSize2, - 0)) != DS_OK) { - if (hresult != DSERR_BUFFERLOST) { - Con_Printf - ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); - S_Shutdown (); - S_Startup (); - return NULL; - } - - if (++reps > 10000) { - Con_Printf - ("S_TransferStereo16: DS: couldn't restore buffer\n"); - S_Shutdown (); - S_Startup (); - return NULL; - } - } - } else { - IDirectSoundBuffer_Unlock (pDSBuf, pbuf1, dwSize, NULL, 0); - pbuf1 = NULL; - pbuf2 = NULL; - dwSize = 0; - dwSize2 = 0; - } - return (pbuf1); -} - -void -DSOUND_ClearBuffer (int clear) -{ - DWORD *pData; - -// FIXME: this should be called with 2nd pbuf2 = NULL, dwsize =0 - pData = DSOUND_LockBuffer (true); - memset (pData, clear, shm->samples * shm->samplebits / 8); - DSOUND_LockBuffer (false); -} - -void -DSOUND_Restore (void) -{ -// if the buffer was lost or stopped, restore it and/or restart it - DWORD dwStatus; - - if (!pDSBuf) - return; - - if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DD_OK) - Con_Printf ("Couldn't get sound buffer status\n"); - - if (dwStatus & DSBSTATUS_BUFFERLOST) - IDirectSoundBuffer_Restore (pDSBuf); - - if (!(dwStatus & DSBSTATUS_PLAYING)) - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - return; -} diff --git a/qw/source/snd_alsa_0_5.c b/qw/source/snd_alsa_0_5.c deleted file mode 100644 index a59fdd9cc..000000000 --- a/qw/source/snd_alsa_0_5.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - snd_alsa_0_5.c - - Support for ALSA 0.5, the old stable version of ALSA. - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#if defined HAVE_SYS_SOUNDCARD_H -# include -#elif defined HAVE_LINUX_SOUNDCARD_H -# include -#elif HAVE_MACHINE_SOUNDCARD_H -# include -#endif - -#include - -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -#ifndef MAP_FAILED -# define MAP_FAILED ((void*)-1) -#endif - -static int snd_inited; - -static snd_pcm_t *pcm_handle; -static struct snd_pcm_channel_info cinfo; -static struct snd_pcm_channel_params params; -static struct snd_pcm_channel_setup setup; -static snd_pcm_mmap_control_t *mmap_control = NULL; -static char *mmap_data = NULL; -static int card = -1, dev = -1; - -int -check_card (int card) -{ - snd_ctl_t *handle; - snd_ctl_hw_info_t info; - int rc; - - if ((rc = snd_ctl_open (&handle, card)) < 0) { - Con_Printf ("Error: control open (%i): %s\n", card, snd_strerror (rc)); - return rc; - } - if ((rc = snd_ctl_hw_info (handle, &info)) < 0) { - Con_Printf ("Error: control hardware info (%i): %s\n", card, - snd_strerror (rc)); - snd_ctl_close (handle); - return rc; - } - snd_ctl_close (handle); - if (dev == -1) { - for (dev = 0; dev < info.pcmdevs; dev++) { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) == 0) { - return 0; - } - } - } else { - if (dev >= 0 && dev < info.pcmdevs) { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) == 0) { - return 0; - } - } - } - return 1; -} - -qboolean -SNDDMA_Init (void) -{ - int rc = 0, i; - char *err_msg = ""; - int rate = -1, format = -1, bps, stereo = -1, frag_size; - unsigned int mask; - - mask = snd_cards_mask (); - if (!mask) { - Con_Printf ("No sound cards detected\n"); - return 0; - } - if (snd_device->string[0]) { - sscanf (snd_device->string, "%d,%d", &card, &dev); - } - if (snd_bits->int_val) { - i = snd_bits->int_val; - if (i == 16) { - format = SND_PCM_SFMT_S16_LE; - } else if (i == 8) { - format = SND_PCM_SFMT_U8; - } else { - Con_Printf ("Error: invalid sample bits: %d\n", i); - return 0; - } - } - if (snd_rate->int_val) { - rate = snd_rate->int_val; - if (rate != 44100 && rate != 22050 && rate != 11025) { - Con_Printf ("Error: invalid sample rate: %d\n", rate); - return 0; - } - } - stereo = snd_stereo->int_val; - if (card == -1) { - for (card = 0; card < SND_CARDS; card++) { - if (!(mask & (1 << card))) - continue; - rc = check_card (card); - if (rc < 0) - return 0; - if (!rc) - goto dev_openned; - } - } else { - if (dev == -1) { - rc = check_card (card); - if (rc < 0) - return 0; - if (!rc) - goto dev_openned; - } else { - if ((rc = snd_pcm_open (&pcm_handle, card, dev, - SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) < 0) { - Con_Printf ("Error: audio open error: %s\n", snd_strerror (rc)); - return 0; - } - goto dev_openned; - } - } - Con_Printf ("Error: audio open error: %s\n", snd_strerror (rc)); - return 0; - - dev_openned: - Con_Printf ("Using card %d, device %d.\n", card, dev); - memset (&cinfo, 0, sizeof (cinfo)); - cinfo.channel = SND_PCM_CHANNEL_PLAYBACK; - snd_pcm_channel_info (pcm_handle, &cinfo); - Con_Printf ("%08x %08x %08x\n", cinfo.flags, cinfo.formats, cinfo.rates); - if ((rate == -1 || rate == 44100) && cinfo.rates & SND_PCM_RATE_44100) { - rate = 44100; - frag_size = 512; /* assuming stereo 8 bit */ - } else if ((rate == -1 || rate == 22050) - && cinfo.rates & SND_PCM_RATE_22050) { - rate = 22050; - frag_size = 256; /* assuming stereo 8 bit */ - } else if ((rate == -1 || rate == 11025) - && cinfo.rates & SND_PCM_RATE_11025) { - rate = 11025; - frag_size = 128; /* assuming stereo 8 bit */ - } else { - Con_Printf ("ALSA: desired rates not supported\n"); - goto error_2; - } - if ((format == -1 || format == SND_PCM_SFMT_S16_LE) - && cinfo.formats & SND_PCM_FMT_S16_LE) { - format = SND_PCM_SFMT_S16_LE; - bps = 16; - frag_size *= 2; - } else if ((format == -1 || format == SND_PCM_SFMT_U8) - && cinfo.formats & SND_PCM_FMT_U8) { - format = SND_PCM_SFMT_U8; - bps = 8; - } else { - Con_Printf ("ALSA: desired formats not supported\n"); - goto error_2; - } - if (stereo && cinfo.max_voices >= 2) { - stereo = 1; - } else { - stereo = 0; - frag_size /= 2; - } - -// err_msg="audio flush"; -// if ((rc=snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) -// goto error; - err_msg = "audio munmap"; - if ((rc = snd_pcm_munmap (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) - goto error; - - memset (¶ms, 0, sizeof (params)); - params.channel = SND_PCM_CHANNEL_PLAYBACK; - params.mode = SND_PCM_MODE_BLOCK; - params.format.interleave = 1; - params.format.format = format; - params.format.rate = rate; - params.format.voices = stereo + 1; - params.start_mode = SND_PCM_START_GO; - params.stop_mode = SND_PCM_STOP_ROLLOVER; - params.buf.block.frag_size = frag_size; - params.buf.block.frags_min = 1; - params.buf.block.frags_max = -1; -// err_msg="audio flush"; -// if ((rc=snd_pcm_channel_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) -// goto error; - err_msg = "audio params"; - if ((rc = snd_pcm_channel_params (pcm_handle, ¶ms)) < 0) - goto error; - - err_msg = "audio mmap"; - if ( - (rc = - snd_pcm_mmap (pcm_handle, SND_PCM_CHANNEL_PLAYBACK, &mmap_control, - (void **) &mmap_data)) < 0) - goto error; - err_msg = "audio prepare"; - if ((rc = snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < - 0) goto error; - - memset (&setup, 0, sizeof (setup)); - setup.mode = SND_PCM_MODE_BLOCK; - setup.channel = SND_PCM_CHANNEL_PLAYBACK; - err_msg = "audio setup"; - if ((rc = snd_pcm_channel_setup (pcm_handle, &setup)) < 0) - goto error; - - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = setup.format.voices; - shm->submission_chunk = 128; // don't mix less than this # - shm->samplepos = 0; // in mono samples - shm->samplebits = setup.format.format == SND_PCM_SFMT_S16_LE ? 16 : 8; - shm->samples = - setup.buf.block.frags * setup.buf.block.frag_size / (shm->samplebits / 8); // mono - // - // samples - // in - // buffer - shm->speed = setup.format.rate; - shm->buffer = (unsigned char *) mmap_data; - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - snd_inited = 1; - return 1; - error: - Con_Printf ("Error: %s: %s\n", err_msg, snd_strerror (rc)); - error_2: - snd_pcm_close (pcm_handle); - return 0; -} - -int -SNDDMA_GetDMAPos (void) -{ - if (!snd_inited) - return 0; - shm->samplepos = - (mmap_control->status.frag_io + - 1) * setup.buf.block.frag_size / (shm->samplebits / 8); - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - snd_pcm_close (pcm_handle); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int count = paintedtime - soundtime; - int i, s, e; - int rc; - - count += setup.buf.block.frag_size - 1; - count /= setup.buf.block.frag_size; - s = soundtime / setup.buf.block.frag_size; - e = s + count; - for (i = s; i < e; i++) - mmap_control->fragments[i % setup.buf.block.frags].data = 1; - switch (mmap_control->status.status) { - case SND_PCM_STATUS_PREPARED: - if ((rc = snd_pcm_channel_go (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) - < 0) { - fprintf (stderr, "unable to start playback. %s\n", - snd_strerror (rc)); - exit (1); - } - break; - case SND_PCM_STATUS_RUNNING: - break; - case SND_PCM_STATUS_UNDERRUN: - if ( - (rc = - snd_pcm_plugin_prepare (pcm_handle, - SND_PCM_CHANNEL_PLAYBACK)) < 0) { - fprintf (stderr, - "underrun: playback channel prepare error. %s\n", - snd_strerror (rc)); - exit (1); - } - break; - default: - break; - } -} diff --git a/qw/source/snd_alsa_0_9.c b/qw/source/snd_alsa_0_9.c deleted file mode 100644 index 8f33c54e0..000000000 --- a/qw/source/snd_alsa_0_9.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - snd_alsa_0_9.c - - Support for ALSA 0.9 sound driver (cvs development version) - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include - -#include "QF/qtypes.h" -#include "sound.h" -#include "QF/qargs.h" -#include "QF/console.h" - -static int snd_inited; - -static snd_pcm_t *pcm; -static const snd_pcm_channel_area_t *mmap_areas; -static char *pcmname = NULL; -size_t buffer_size; - -qboolean -SNDDMA_Init (void) -{ - int err; - int rate = -1, bps = -1, stereo = -1, frag_size; - snd_pcm_hw_params_t *hw; - snd_pcm_sw_params_t *sw; - - snd_pcm_hw_params_alloca (&hw); - snd_pcm_sw_params_alloca (&sw); - - if (snd_device->string[0]) - pcmname = snd_device->string; - if (snd_bits->int_val) { - bps = snd_bits->int_val; - if (bps != 16 && bps != 8) { - Con_Printf ("Error: invalid sample bits: %d\n", bps); - return 0; - } - } - if (snd_rate->int_val) { - rate = snd_rate->int_val; - if (rate != 44100 && rate != 22050 && rate != 11025) { - Con_Printf ("Error: invalid sample rate: %d\n", rate); - return 0; - } - } - stereo = snd_stereo->int_val; - if (!pcmname) - pcmname = "plug:0,0"; - if ((err = snd_pcm_open (&pcm, pcmname, - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { - Con_Printf ("Error: audio open error: %s\n", snd_strerror (err)); - return 0; - } - - Con_Printf ("Using PCM %s.\n", pcmname); - snd_pcm_hw_params_any (pcm, hw); - - - switch (rate) { - case -1: - if (snd_pcm_hw_params_set_rate_near (pcm, hw, 44100, 0) >= 0) { - frag_size = 256; /* assuming stereo 8 bit */ - rate = 44100; - } else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 22050, 0) >= 0) { - frag_size = 128; /* assuming stereo 8 bit */ - rate = 22050; - } else if (snd_pcm_hw_params_set_rate_near (pcm, hw, 11025, 0) >= 0) { - frag_size = 64; /* assuming stereo 8 bit */ - rate = 11025; - } else { - Con_Printf ("ALSA: no useable rates\n"); - goto error; - } - break; - case 11025: - case 22050: - case 44100: - if (snd_pcm_hw_params_set_rate_near (pcm, hw, rate, 0) >= 0) { - frag_size = 64 * rate / 11025; /* assuming stereo 8 bit */ - break; - } - /* Fall through */ - default: - Con_Printf ("ALSA: desired rate not supported\n"); - goto error; - } - - switch (bps) { - case -1: - if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_S16_LE) >= - 0) { - bps = 16; - } else if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_U8) - >= 0) { - bps = 8; - } else { - Con_Printf ("ALSA: no useable formats\n"); - goto error; - } - break; - case 8: - case 16: - if (snd_pcm_hw_params_set_format (pcm, hw, - bps == 8 ? SND_PCM_FORMAT_U8 : - SND_PCM_FORMAT_S16) >= 0) { - break; - } - /* Fall through */ - default: - Con_Printf ("ALSA: desired format not supported\n"); - goto error; - } - - if (snd_pcm_hw_params_set_access (pcm, hw, - SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { - Con_Printf ("ALSA: interleaved is not supported\n"); - goto error; - } - - switch (stereo) { - case -1: - if (snd_pcm_hw_params_set_channels (pcm, hw, 2) >= 0) { - stereo = 1; - } else if (snd_pcm_hw_params_set_channels (pcm, hw, 1) >= 0) { - stereo = 0; - } else { - Con_Printf ("ALSA: no useable channels\n"); - goto error; - } - break; - case 0: - case 1: - if (snd_pcm_hw_params_set_channels (pcm, hw, stereo ? 2 : 1) >= 0) - break; - /* Fall through */ - default: - Con_Printf ("ALSA: desired channels not supported\n"); - goto error; - } - - snd_pcm_hw_params_set_period_size_near (pcm, hw, frag_size, 0); - - err = snd_pcm_hw_params (pcm, hw); - if (err < 0) { - Con_Printf ("ALSA: unable to install hw params\n"); - goto error; - } - - snd_pcm_sw_params_current (pcm, sw); - snd_pcm_sw_params_set_start_mode (pcm, sw, SND_PCM_START_EXPLICIT); - snd_pcm_sw_params_set_xrun_mode (pcm, sw, SND_PCM_XRUN_NONE); - - err = snd_pcm_sw_params (pcm, sw); - if (err < 0) { - Con_Printf ("ALSA: unable to install sw params\n"); - goto error; - } - - mmap_areas = snd_pcm_mmap_running_areas (pcm); - - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = stereo + 1; - shm->submission_chunk = snd_pcm_hw_params_get_period_size (hw, 0); // don't - // mix - // less - // than - // this - // # - shm->samplepos = 0; // in mono samples - shm->samplebits = bps; - buffer_size = snd_pcm_hw_params_get_buffer_size (hw); - shm->samples = buffer_size * shm->channels; // mono samples in buffer - shm->speed = rate; - shm->buffer = (unsigned char *) mmap_areas->addr; - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - snd_inited = 1; - return 1; - error: - snd_pcm_close (pcm); - return 0; -} - -static inline int -get_hw_ptr () -{ - size_t app_ptr; - snd_pcm_sframes_t delay; - int hw_ptr; - - if (snd_pcm_state (pcm) != SND_PCM_STATE_RUNNING) - return 0; - app_ptr = snd_pcm_mmap_offset (pcm); - snd_pcm_delay (pcm, &delay); - hw_ptr = app_ptr - delay; - if (hw_ptr < 0) - hw_ptr += buffer_size; - return hw_ptr; -} - -int -SNDDMA_GetDMAPos (void) -{ - int hw_ptr; - - if (!snd_inited) - return 0; - - hw_ptr = get_hw_ptr (); - hw_ptr *= shm->channels; - shm->samplepos = hw_ptr; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - snd_pcm_close (pcm); - snd_inited = 0; - } -} - -/* -============== -SNDDMA_Submit - -Send sound to device if buffer isn't really the dma buffer -=============== -*/ -void -SNDDMA_Submit (void) -{ - int count = paintedtime - soundtime; - int avail; - int missed; - int state; - int hw_ptr; - int offset; - - state = snd_pcm_state (pcm); - - switch (state) { - case SND_PCM_STATE_PREPARED: - snd_pcm_mmap_forward (pcm, count); - snd_pcm_start (pcm); - break; - case SND_PCM_STATE_RUNNING: - hw_ptr = get_hw_ptr (); - missed = hw_ptr - shm->samplepos / shm->channels; - if (missed < 0) - missed += buffer_size; - count -= missed; - offset = snd_pcm_mmap_offset (pcm); - if (offset > hw_ptr) - count -= (offset - hw_ptr); - else - count -= (buffer_size - hw_ptr + offset); - if (count < 0) { - snd_pcm_rewind (pcm, -count); - } else { - avail = snd_pcm_avail_update (pcm); - if (avail < 0) - avail = buffer_size; - if (count > avail) - count = avail; - snd_pcm_mmap_forward (pcm, count); - } - break; - default: - break; - } -} diff --git a/qw/source/snd_disk.c b/qw/source/snd_disk.c deleted file mode 100644 index e45b22d9a..000000000 --- a/qw/source/snd_disk.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - snd_disk.c - - write sound to a disk file - - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include - -#include "QF/console.h" -#include "sound.h" -#include "QF/qargs.h" - -static int snd_inited; -QFile *snd_file; - -qboolean -SNDDMA_Init (void) -{ - shm = &sn; - memset ((dma_t *) shm, 0, sizeof (*shm)); - shm->splitbuffer = 0; - shm->channels = 2; - shm->submission_chunk = 1; // don't mix less than this # - shm->samplepos = 0; // in mono samples - shm->samplebits = 16; - shm->samples = 16384; // mono samples in buffer - shm->speed = 44100; - shm->buffer = malloc (shm->samples * shm->channels * shm->samplebits / 8); - - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%x dma buffer\n", (int) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); - - if (!(snd_file = Qopen ("qf.raw", "wb"))) - return 0; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - shm->samplepos = 0; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - Qclose (snd_file); - snd_file = 0; - free (shm->buffer); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int count = (paintedtime - soundtime) * shm->samplebits / 8; - - Qwrite (snd_file, shm->buffer, count); -} diff --git a/qw/source/snd_dma.c b/qw/source/snd_dma.c deleted file mode 100644 index a1f84e945..000000000 --- a/qw/source/snd_dma.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - snd_dma.c - - main control for any streaming sound output device - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include - -#include "client.h" -#include "QF/cmd.h" -#include "QF/console.h" -#include "host.h" -#include "QF/model.h" -#include "QF/qargs.h" -#include "QF/sys.h" -#include "sound.h" - -#ifdef _WIN32 -#include "winquake.h" -#include "in_win.h" -#endif - -void S_Play (void); -void S_PlayVol (void); -void S_SoundList (void); -void S_Update_ (void); -void S_StopAllSounds (qboolean clear); -void S_StopAllSoundsC (void); - -// QuakeWorld hack... -//#define viewentity playernum+1 - -// ======================================================================= -// Internal sound data & structures -// ======================================================================= - -channel_t channels[MAX_CHANNELS]; -int total_channels; - -int snd_blocked = 0; -static qboolean snd_ambient = 1; -qboolean snd_initialized = false; - -// pointer should go away -volatile dma_t *shm = 0; -volatile dma_t sn; - -vec3_t listener_origin; -vec3_t listener_forward; -vec3_t listener_right; -vec3_t listener_up; -vec_t sound_nominal_clip_dist = 1000.0; - -int soundtime; // sample PAIRS -int paintedtime; // sample PAIRS - - -#define MAX_SFX 512 -sfx_t *known_sfx; // hunk allocated [MAX_SFX] -int num_sfx; - -sfx_t *ambient_sfx[NUM_AMBIENTS]; - -int desired_speed = 11025; -int desired_bits = 16; - -int sound_started = 0; - -cvar_t *bgmvolume; -cvar_t *volume; - -cvar_t *snd_device; -cvar_t *snd_rate; -cvar_t *snd_bits; -cvar_t *snd_stereo; -cvar_t *nosound; -cvar_t *precache; -cvar_t *loadas8bit; -cvar_t *ambient_level; -cvar_t *ambient_fade; -cvar_t *snd_noextraupdate; -cvar_t *snd_show; -cvar_t *snd_interp; -cvar_t *snd_phasesep; -cvar_t *snd_volumesep; -cvar_t *_snd_mixahead; - - -// ==================================================================== -// User-setable variables -// ==================================================================== - - -// -// Fake dma is a synchronous faking of the DMA progress used for -// isolating performance in the renderer. The fakedma_updates is -// number of times S_Update() is called per second. -// - -qboolean fakedma = false; -int fakedma_updates = 15; - - -void -S_AmbientOff (void) -{ - snd_ambient = false; -} - - -void -S_AmbientOn (void) -{ - snd_ambient = true; -} - - -void -S_SoundInfo_f (void) -{ - if (!sound_started || !shm) { - Con_Printf ("sound system not started\n"); - return; - } - - Con_Printf ("%5d stereo\n", shm->channels - 1); - Con_Printf ("%5d samples\n", shm->samples); - Con_Printf ("%5d samplepos\n", shm->samplepos); - Con_Printf ("%5d samplebits\n", shm->samplebits); - Con_Printf ("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf ("%5d speed\n", shm->speed); - Con_Printf ("0x%lx dma buffer\n", (unsigned long) shm->buffer); - Con_Printf ("%5d total_channels\n", total_channels); -} - - -/* - S_Startup -*/ - -void -S_Startup (void) -{ - int rc; - - if (!snd_initialized) - return; - - if (!fakedma) { - rc = SNDDMA_Init (); - - if (!rc) { -#ifndef _WIN32 - Con_Printf ("S_Startup: SNDDMA_Init failed.\n"); -#endif - sound_started = 0; - return; - } - } - - sound_started = 1; -} - - -/* - S_Init -*/ -void -S_Init (void) -{ - - Con_Printf ("\nSound Initialization\n"); - - Cmd_AddCommand ("play", S_Play, - "Play selected sound effect (play pathto/sound.wav)"); - Cmd_AddCommand ("playvol", S_PlayVol, - "Play selected sound effect at selected volume (playvol pathto/sound.wav num"); - Cmd_AddCommand ("stopsound", S_StopAllSoundsC, - "Stops all sounds currently being played"); - Cmd_AddCommand ("soundlist", S_SoundList, - "Reports a list of sounds in the cache"); - Cmd_AddCommand ("soundinfo", S_SoundInfo_f, - "Report information on the sound system"); - - if (COM_CheckParm ("-nosound")) - return; - - if (COM_CheckParm ("-simsound")) - fakedma = true; - - if (host_parms.memsize < 0x800000) { - Cvar_Set (loadas8bit, "1"); - Con_Printf ("loading all sounds as 8bit\n"); - } - - - snd_initialized = true; - - S_Startup (); - - if (sound_started == 0) // sound startup failed? Bail out. - return; - - SND_InitScaletable (); - - known_sfx = Hunk_AllocName (MAX_SFX * sizeof (sfx_t), "sfx_t"); - - num_sfx = 0; - -// create a piece of DMA memory - - if (fakedma) { - shm = (void *) Hunk_AllocName (sizeof (*shm), "shm"); - shm->splitbuffer = 0; - shm->samplebits = 16; - shm->speed = 22050; - shm->channels = 2; - shm->samples = 32768; - shm->samplepos = 0; - shm->soundalive = true; - shm->gamealive = true; - shm->submission_chunk = 1; - shm->buffer = Hunk_AllocName (1 << 16, "shmbuf"); - } -// Con_Printf ("Sound sampling rate: %i\n", shm->speed); - - // provides a tick sound until washed clean - -// if (shm->buffer) -// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging - - ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); - ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); - - S_StopAllSounds (true); -} - -void -S_Init_Cvars (void) -{ - snd_device = Cvar_Get ("snd_device", "", CVAR_ROM, 0, - "sound device. \"\" is system default"); - snd_rate = Cvar_Get ("snd_rate", "0", CVAR_ROM, 0, - "sound playback rate. 0 is system default"); - snd_bits = Cvar_Get ("snd_bits", "0", CVAR_ROM, 0, - "sound sample depth. 0 is system default"); - snd_stereo = Cvar_Get ("snd_stereo", "1", CVAR_ROM, 0, - "sound stereo output"); - nosound = Cvar_Get ("nosound", "0", CVAR_NONE, 0, "Set to turn sound off"); - volume = - Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, 0, - "Set the volume for sound playback"); - precache = - Cvar_Get ("precache", "1", CVAR_NONE, 0, "Toggle the use of a precache"); - loadas8bit = - Cvar_Get ("loadas8bit", "0", CVAR_NONE, 0, - "Toggles if sounds are loaded as 8-bit samples"); - bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, 0, "Volume of CD music"); - ambient_level = - Cvar_Get ("ambient_level", "0.3", CVAR_NONE, 0, "Ambient sounds' volume"); - ambient_fade = - Cvar_Get ("ambient_fade", "100", CVAR_NONE, 0, - "How quickly ambient sounds fade in or out"); - snd_noextraupdate = - Cvar_Get ("snd_noextraupdate", "0", CVAR_NONE, 0, - "Toggles the correct value display in host_speeds. Usually messes up sound playback when in effect"); - snd_show = - Cvar_Get ("snd_show", "0", CVAR_NONE, 0, - "Toggles the display of sounds currently being played"); - snd_interp = - Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, 0, - "control sample interpolation"); - snd_phasesep = - Cvar_Get ("snd_phasesep", "0.0", CVAR_ARCHIVE, 0, - "max stereo phase separation in ms. 0.6 is for 20cm head"); - snd_volumesep = - Cvar_Get ("snd_volumesep", "1.0", CVAR_ARCHIVE, 0, - "max stereo volume separation in ms. 1.0 is max"); - _snd_mixahead = - Cvar_Get ("_snd_mixahead", "0.1", CVAR_ARCHIVE, 0, - "Delay time for sounds"); -} - - -// ======================================================================= -// Shutdown sound engine -// ======================================================================= - -void -S_Shutdown (void) -{ - - if (!sound_started) - return; - - if (shm) - shm->gamealive = 0; - - shm = 0; - sound_started = 0; - - if (!fakedma) { - SNDDMA_Shutdown (); - } -} - - -// ======================================================================= -// Load a sound -// ======================================================================= - -/* - S_FindName -*/ -sfx_t * -S_FindName (char *name) -{ - int i; - sfx_t *sfx; - - if (!name) - Sys_Error ("S_FindName: NULL\n"); - - if (strlen (name) >= MAX_QPATH) - Sys_Error ("Sound name too long: %s", name); - -// see if already loaded - for (i = 0; i < num_sfx; i++) - if (!strcmp (known_sfx[i].name, name)) { - return &known_sfx[i]; - } - - if (num_sfx == MAX_SFX) - Sys_Error ("S_FindName: out of sfx_t"); - - sfx = &known_sfx[i]; - strcpy (sfx->name, name); - - num_sfx++; - - return sfx; -} - - -/* - S_TouchSound -*/ -void -S_TouchSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started) - return; - - sfx = S_FindName (name); - Cache_Check (&sfx->cache); -} - -/* - S_PrecacheSound -*/ -sfx_t * -S_PrecacheSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started || nosound->int_val) - return NULL; - - sfx = S_FindName (name); - -// cache it in - if (precache->int_val) - S_LoadSound (sfx); - - return sfx; -} - - -//============================================================================= - -/* - SND_PickChannel -*/ -channel_t * -SND_PickChannel (int entnum, int entchannel) -{ - int ch_idx; - int first_to_die; - int life_left; - -// Check for replacement sound, or find the best one to replace - first_to_die = -1; - life_left = 0x7fffffff; - for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; - ch_idx++) { - if (entchannel != 0 // channel 0 never overrides - && channels[ch_idx].entnum == entnum - && (channels[ch_idx].entchannel == entchannel || entchannel == -1)) { - // always override sound from same entity - first_to_die = ch_idx; - break; - } - // don't let monster sounds override player sounds - if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity - && channels[ch_idx].sfx) - continue; - - if (channels[ch_idx].end - paintedtime < life_left) { - life_left = channels[ch_idx].end - paintedtime; - first_to_die = ch_idx; - } - } - - if (first_to_die == -1) - return NULL; - - if (channels[first_to_die].sfx) - channels[first_to_die].sfx = NULL; - - return &channels[first_to_die]; -} - -/* - SND_Spatialize -*/ -void -SND_Spatialize (channel_t *ch) -{ - vec_t dot; - vec_t dist; - int phase; // in samples - vec_t lscale, rscale, scale; - vec3_t source_vec; - sfx_t *snd; - -// anything coming from the view entity will always be full volume - if (ch->entnum == cl.viewentity) { - ch->leftvol = ch->master_vol; - ch->rightvol = ch->master_vol; - ch->phase = 0; - return; - } -// calculate stereo seperation and distance attenuation - - snd = ch->sfx; - VectorSubtract (ch->origin, listener_origin, source_vec); - - dist = VectorNormalize (source_vec) * ch->dist_mult; - - dot = DotProduct (listener_right, source_vec); - - if (shm->channels == 1) { - rscale = 1.0; - lscale = 1.0; - phase = 0; - } else { - rscale = 1.0 + dot * snd_volumesep->value; - lscale = 1.0 - dot * snd_volumesep->value; - phase = snd_phasesep->value * 0.001 * shm->speed * dot; - } - -// add in distance effect - scale = (1.0 - dist) * rscale; - ch->rightvol = (int) (ch->master_vol * scale); - if (ch->rightvol < 0) - ch->rightvol = 0; - - scale = (1.0 - dist) * lscale; - ch->leftvol = (int) (ch->master_vol * scale); - if (ch->leftvol < 0) - ch->leftvol = 0; - - ch->phase = phase; -} - - -// ======================================================================= -// Start a sound effect -// ======================================================================= - -void -S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, - float attenuation) -{ - channel_t *target_chan, *check; - sfxcache_t *sc; - int vol; - int ch_idx; - int skip; - - if (!sound_started) - return; - - if (!sfx) - return; - - if (nosound->int_val) - return; - - vol = fvol * 255; - -// pick a channel to play on - target_chan = SND_PickChannel (entnum, entchannel); - if (!target_chan) - return; - -// spatialize - memset (target_chan, 0, sizeof (*target_chan)); - VectorCopy (origin, target_chan->origin); - target_chan->dist_mult = attenuation / sound_nominal_clip_dist; - target_chan->master_vol = vol; - target_chan->entnum = entnum; - target_chan->entchannel = entchannel; - SND_Spatialize (target_chan); - - if (!target_chan->leftvol && !target_chan->rightvol) - return; // not audible at all - -// new channel - sc = S_LoadSound (sfx); - if (!sc) { - target_chan->sfx = NULL; - return; // couldn't load the sound's data - } - - target_chan->sfx = sfx; - target_chan->pos = 0.0; - target_chan->end = paintedtime + sc->length; - -// if an identical sound has also been started this frame, offset the pos -// a bit to keep it from just making the first one louder - check = &channels[NUM_AMBIENTS]; - for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; - ch_idx++, check++) { - if (check == target_chan) - continue; - if (check->sfx == sfx && !check->pos) { - skip = rand () % (int) (0.1 * shm->speed); - if (skip >= target_chan->end) - skip = target_chan->end - 1; - target_chan->pos += skip; - target_chan->end -= skip; - break; - } - - } -} - -void -S_StopSound (int entnum, int entchannel) -{ - int i; - - for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) { - if (channels[i].entnum == entnum - && channels[i].entchannel == entchannel) { - channels[i].end = 0; - channels[i].sfx = NULL; - return; - } - } -} - -void -S_StopAllSounds (qboolean clear) -{ - int i; - - if (!sound_started) - return; - - total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics - - for (i = 0; i < MAX_CHANNELS; i++) - if (channels[i].sfx) - channels[i].sfx = NULL; - - memset (channels, 0, MAX_CHANNELS * sizeof (channel_t)); - - if (clear) - S_ClearBuffer (); -} - -void -S_StopAllSoundsC (void) -{ - S_StopAllSounds (true); -} - -void -S_ClearBuffer (void) -{ - int clear; - -#ifdef _WIN32 - if (!sound_started || !shm || (!shm->buffer && !pDSBuf)) -#else - if (!sound_started || !shm || !shm->buffer) -#endif - return; - - if (shm->samplebits == 8) - clear = 0x80; - else - clear = 0; - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_ClearBuffer (clear); - else -#endif - { - memset (shm->buffer, clear, shm->samples * shm->samplebits / 8); - } -} - - -/* - S_StaticSound -*/ -void -S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) -{ - channel_t *ss; - sfxcache_t *sc; - - if (!sfx) - return; - - if (total_channels == MAX_CHANNELS) { - Con_Printf ("total_channels == MAX_CHANNELS\n"); - return; - } - - ss = &channels[total_channels]; - total_channels++; - - sc = S_LoadSound (sfx); - if (!sc) - return; - - if (sc->loopstart == -1) { - Con_Printf ("Sound %s not looped\n", sfx->name); - return; - } - - ss->sfx = sfx; - VectorCopy (origin, ss->origin); - ss->master_vol = vol; - ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist; - ss->end = paintedtime + sc->length; - - SND_Spatialize (ss); - ss->oldphase = ss->phase; -} - - -//============================================================================= - -/* - S_UpdateAmbientSounds -*/ -void -S_UpdateAmbientSounds (void) -{ - mleaf_t *l; - float vol; - int ambient_channel; - channel_t *chan; - - if (!snd_ambient) - return; - -// calc ambient sound levels - if (!cl.worldmodel) - return; - - l = Mod_PointInLeaf (listener_origin, cl.worldmodel); - if (!l || !ambient_level->value) { - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; - ambient_channel++) - channels[ambient_channel].sfx = NULL; - return; - } - - for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++) { - chan = &channels[ambient_channel]; - chan->sfx = ambient_sfx[ambient_channel]; - - vol = ambient_level->value * l->ambient_sound_level[ambient_channel]; - if (vol < 8) - vol = 0; - - // don't adjust volume too fast - if (chan->master_vol < vol) { - chan->master_vol += host_frametime * ambient_fade->value; - if (chan->master_vol > vol) - chan->master_vol = vol; - } else if (chan->master_vol > vol) { - chan->master_vol -= host_frametime * ambient_fade->value; - if (chan->master_vol < vol) - chan->master_vol = vol; - } - - chan->leftvol = chan->rightvol = chan->master_vol; - } -} - - -/* - S_Update - - Called once each time through the main loop -*/ -void -S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) -{ - int i, j; - int total; - channel_t *ch; - channel_t *combine; - - if (!sound_started || (snd_blocked > 0)) - return; - - VectorCopy (origin, listener_origin); - VectorCopy (forward, listener_forward); - VectorCopy (right, listener_right); - VectorCopy (up, listener_up); - -// update general area ambient sound sources - S_UpdateAmbientSounds (); - - combine = NULL; - -// update spatialization for static and dynamic sounds - ch = channels + NUM_AMBIENTS; - for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) { - if (!ch->sfx) - continue; - ch->oldphase = ch->phase; // prepare to lerp from prev to next - // phase - SND_Spatialize (ch); // respatialize channel - if (!ch->leftvol && !ch->rightvol) - continue; - - // try to combine static sounds with a previous channel of the same - // sound effect so we don't mix five torches every frame - - if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) { - // see if it can just use the last one - if (combine && combine->sfx == ch->sfx) { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - continue; - } - // search for one - combine = channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; - for (j = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; j < i; j++, combine++) - if (combine->sfx == ch->sfx) - break; - - if (j == total_channels) { - combine = NULL; - } else { - if (combine != ch) { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - } - continue; - } - } - - - } - -// -// debugging output -// - if (snd_show->int_val) { - total = 0; - ch = channels; - for (i = 0; i < total_channels; i++, ch++) - if (ch->sfx && (ch->leftvol || ch->rightvol)) { - // Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, - // ch->sfx->name); - total++; - } - - Con_Printf ("----(%i)----\n", total); - } -// mix some sound - S_Update_ (); -} - -void -GetSoundtime (void) -{ - int samplepos; - static int buffers; - static int oldsamplepos; - int fullsamples; - - fullsamples = shm->samples / shm->channels; - -// it is possible to miscount buffers if it has wrapped twice between -// calls to S_Update. Oh well. - samplepos = SNDDMA_GetDMAPos (); - - if (samplepos < oldsamplepos) { - buffers++; // buffer wrapped - - if (paintedtime > 0x40000000) { // time to chop things off to avoid - // 32 bit limits - buffers = 0; - paintedtime = fullsamples; - S_StopAllSounds (true); - } - } - oldsamplepos = samplepos; - - soundtime = buffers * fullsamples + samplepos / shm->channels; -} - -void -S_ExtraUpdate (void) -{ - -#ifdef _WIN32 - IN_Accumulate (); -#endif - - if (snd_noextraupdate->int_val) - return; // don't pollute timings - S_Update_ (); -} - - - -void -S_Update_ (void) -{ - unsigned int endtime; - int samps; - - if (!sound_started || (snd_blocked > 0)) - return; - -// Updates DMA time - GetSoundtime (); - -// check to make sure that we haven't overshot - if (paintedtime < soundtime) { - // Con_Printf ("S_Update_ : overflow\n"); - paintedtime = soundtime; - } -// mix ahead of current position - endtime = soundtime + _snd_mixahead->value * shm->speed; - samps = shm->samples >> (shm->channels - 1); - if (endtime - soundtime > samps) - endtime = soundtime + samps; - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_Restore (); -#endif - - S_PaintChannels (endtime); - - SNDDMA_Submit (); -} - -/* - console functions -*/ - -void -S_Play (void) -{ - static int hash = 345; - int i; - char name[256]; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - strcpy (name, Cmd_Argv (i)); - strncat (name, ".wav", sizeof (name) - strlen (name)); - } else - strcpy (name, Cmd_Argv (i)); - sfx = S_PrecacheSound (name); - S_StartSound (hash++, 0, sfx, listener_origin, 1.0, 1.0); - i++; - } -} - -void -S_PlayVol (void) -{ - static int hash = 543; - int i; - float vol; - char name[256]; - sfx_t *sfx; - - i = 1; - while (i < Cmd_Argc ()) { - if (!strrchr (Cmd_Argv (i), '.')) { - strcpy (name, Cmd_Argv (i)); - strncat (name, ".wav", sizeof (name) - strlen (name)); - } else - strcpy (name, Cmd_Argv (i)); - sfx = S_PrecacheSound (name); - vol = atof (Cmd_Argv (i + 1)); - S_StartSound (hash++, 0, sfx, listener_origin, vol, 1.0); - i += 2; - } -} - -void -S_SoundList (void) -{ - int i; - sfx_t *sfx; - sfxcache_t *sc; - int size, total; - - total = 0; - for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) { - sc = Cache_Check (&sfx->cache); - if (!sc) - continue; - size = sc->length * sc->width * (sc->stereo + 1); - total += size; - if (sc->loopstart >= 0) - Con_Printf ("L"); - else - Con_Printf (" "); - Con_Printf ("(%2db) %6i : %s\n", sc->width * 8, size, sfx->name); - } - Con_Printf ("Total resident: %i\n", total); -} - - -void -S_LocalSound (char *sound) -{ - sfx_t *sfx; - - if (nosound->int_val) - return; - if (!sound_started) - return; - - sfx = S_PrecacheSound (sound); - if (!sfx) { - Con_Printf ("S_LocalSound: can't cache %s\n", sound); - return; - } - S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); -} - - -void -S_ClearPrecache (void) -{ -} - - -void -S_BeginPrecaching (void) -{ -} - - -void -S_EndPrecaching (void) -{ -} diff --git a/qw/source/snd_gus.c b/qw/source/snd_gus.c deleted file mode 100644 index 9eb0db4b5..000000000 --- a/qw/source/snd_gus.c +++ /dev/null @@ -1,1281 +0,0 @@ - -/* - snd_gus.c - - @description@ - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "dosisms.h" - -//============================================================================= -// Author(s): Jayeson Lee-Steere - -#define INI_STRING_SIZE 0x100 - -QFile *ini_fopen (const char *filename, const char *modes); -int ini_fclose (QFile *f); -void ini_fgets (QFile *f, const char *section, const char *field, - - char *s); - -// Routines for reading from .INI files -// The read routines are fairly efficient. -// -// Author(s): Jayeson Lee-Steere - -#define MAX_SECTION_WIDTH 20 -#define MAX_FIELD_WIDTH 20 - -#define NUM_SECTION_BUFFERS 10 -#define NUM_FIELD_BUFFERS 20 - -struct section_buffer { - long offset; - char name[MAX_SECTION_WIDTH + 1]; -}; - -struct field_buffer { - long offset; - int section; - char name[MAX_FIELD_WIDTH + 1]; -}; - -static QFile *current_file = NULL; -static int current_section; - -static int current_section_buffer = 0; -static int current_field_buffer = 0; - -static struct section_buffer section_buffers[NUM_SECTION_BUFFERS]; -static struct field_buffer field_buffers[NUM_FIELD_BUFFERS]; - -//*************************************************************************** -// Internal routines -//*************************************************************************** -static char -toupper (char c) -{ - if (c >= 'a' && c <= 'z') - c -= ('a' - 'A'); - return (c); -} - -static void -reset_buffer (QFile *f) -{ - int i; - - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - section_buffers[i].name[0] = 0; - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - field_buffers[i].name[0] = 0; - - current_file = f; -} - -// Sees if the current string is section "name" (i.e. ["name"]). -// If "name"=="*", sees if the current string is any section -// (i.e. [....]). Returns 1 if true else 0 if false. -static int -is_section (char *s, const char *name) -{ - int wild = 0; - - // See if wild search - if (strcmp ("*", name) == 0) - wild = 1; - - // Skip leading spaces - while (s[0] == ' ') - s++; - // Look for leading "[" - if (s[0] != '[') - return (0); - s++; - // Make sure name matches - while (s[0] != ']' && s[0] != 13 && s[0] != 10 && s[0] != 0 && name[0] != 0) { - if (!wild) - if (toupper (s[0]) != toupper (name[0])) - return (0); - s++; - if (!wild) - name++; - } - if (!wild) - if (name[0] != 0) - return (0); - // Skip trailing spaces - while (s[0] == ' ') - s++; - // Make sure we have trailing "]" - if (s[0] != ']') - return (0); - return (1); -} - -// Sees if the current string is field "name" (i.e. "name"=...). -// If "name"=="*", sees if the current string is any field -// (i.e. ...=...). Returns 1 if true else 0 if false. -static int -is_field (char *s, const char *name) -{ - int wild = 0; - - // See if wild search - if (strcmp ("*", name) == 0) - wild = 1; - - // Skip leading spaces - while (s[0] == ' ') - s++; - - // Make sure name matches - while (s[0] != '=' && s[0] != 13 && s[0] != 10 && s[0] != 0 && name[0] != 0) { - if (!wild) - if (toupper (s[0]) != toupper (name[0])) - return (0); - s++; - if (!wild) - name++; - } - if (!wild) - if (name[0] != 0) - return (0); - // Skip trailing spaces - while (s[0] == ' ') - s++; - // Make sure we have an "=" - if (s[0] != '=') - return (0); - - return (1); -} - -// Extracts the section name from a section heading -// e.g. in="[hey man]" gives out="hey man" -static void -get_section_name (char *out, char *in) -{ - int i = 0; - - // Skip spaces before '[' - while (in[0] == ' ') - in++; - // Make sure there is a '[' - if (in[0] != '[') { - out[0] = 0; - return; - } - // Skip past '[' - in++; - // Copy string if any to output string. - while (in[0] != ']' && in[0] != 13 && in[0] != 10 && in[0] != 0) { - if (i < MAX_SECTION_WIDTH) { - out[i] = in[0]; - i++; - } - in++; - } - // Make sure string was terminated with ']' - if (in[0] != ']') { - out[0] = 0; - return; - } - // Remove trailing spaces - while (i > 0 && out[i - 1] == ' ') - i--; - // Null terminate the output string. - out[i] = 0; -} - -// Extracts the field name from a field line -// e.g. in="sooty=life be in it" gives out="sooty" -static void -get_field_name (char *out, char *in) -{ - int i = 0; - - // Skip leading spaces - while (in[0] == ' ') - in++; - // Copy name to output string - while (in[0] != '=' && in[0] != 13 && in[0] != 10 && in[0] != 0) { - if (i < MAX_FIELD_WIDTH) { - out[i] = in[0]; - i++; - } - in++; - } - // Make sure we stopped on "=" - if (in[0] != '=') { - out[0] = 0; - return; - } - // Remove trailing spaces - while (i > 0 && out[i - 1] == ' ') - i--; - // Null terminate the output string. - out[i] = 0; -} - -// Returns the field data from string s. -// e.g. in="wally = golly man" gives out="golly man" -static void -get_field_string (char *out, char *in) -{ - int i = 0; - - // Find '=' if it exists - while (in[0] != '=' && in[0] != 13 && in[0] != 10 && in[0] != 0) - in++; - // If there is an '=', skip past it. - if (in[0] == '=') - in++; - // Skip any spaces between the '=' and string. - while (in[0] == ' ' || in[0] == '[') - in++; - // Copy string, if there is one, to the output string. - while (in[0] != 13 && in[0] != 10 && in[0] != 0 - && i < (INI_STRING_SIZE - 1)) { - out[i] = in[0]; - in++; - i++; - } - // Null terminate the output string. - out[i] = 0; -} - -// Adds a section to the buffer -static int -add_section (char *instring, long offset) -{ - int i; - char section[MAX_SECTION_WIDTH + 1]; - - // Extract section name - get_section_name (section, instring); - // See if section already exists. - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - if (strcasecmp (section, section_buffers[i].name) == 0) - return (i); - // Increment current_section_buffer - current_section_buffer++; - if (current_section_buffer > NUM_SECTION_BUFFERS) - current_section_buffer = 0; - // Delete any field buffers that correspond to this section - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == current_section_buffer) - field_buffers[i].name[0] = 0; - // Set buffer information - strcpy (section_buffers[current_section_buffer].name, section); - section_buffers[current_section_buffer].offset = offset; - return (current_section_buffer); -} - -// Adds a field to the buffer -static void -add_field (char *instring, int section, long offset) -{ - int i; - char field[MAX_FIELD_WIDTH + 1]; - - // Extract field name - get_field_name (field, instring); - // See if field already exists - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == section) - if (strcasecmp (field_buffers[i].name, field) == 0) - return; - // Increment current_field_buffer - current_field_buffer++; - if (current_field_buffer > NUM_FIELD_BUFFERS) - current_field_buffer = 0; - // Set buffer information - strcpy (field_buffers[current_field_buffer].name, field); - field_buffers[current_field_buffer].section = section; - field_buffers[current_field_buffer].offset = offset; -} - -// Identical to fgets except the string is trucated at the first ';', -// carriage return or line feed. -static char * -stripped_fgets (char *s, int n, QFile *f) -{ - int i = 0; - - if (fgets (s, n, f) == NULL) - return (NULL); - - while (s[i] != ';' && s[i] != 13 && s[i] != 10 && s[i] != 0) - i++; - s[i] = 0; - - return (s); -} - -//*************************************************************************** -// Externally accessable routines -//*************************************************************************** -// Opens an .INI file. Works like fopen -QFile * -ini_fopen (const char *filename, const char *modes) -{ - return (Qopen (filename, modes)); -} - -// Closes a .INI file. Works like fclose -int -ini_fclose (QFile *f) -{ - if (f == current_file) - reset_buffer (NULL); - return (Qclose (f)); -} - -// Puts "field" from "section" from .ini file "f" into "s". -// If "section" does not exist or "field" does not exist in -// section then s=""; -void -ini_fgets (QFile *f, const char *section, const char *field, char *s) -{ - int i; - long start_pos, string_start_pos; - char ts[INI_STRING_SIZE * 2]; - - if (f != current_file) - reset_buffer (f); - - // Default to "Not found" - s[0] = 0; - - // See if section is in buffer - for (i = 0; i < NUM_SECTION_BUFFERS; i++) - if (strnicmp (section_buffers[i].name, section, MAX_SECTION_WIDTH) == 0) - break; - - // If section is in buffer, seek to it if necessary - if (i < NUM_SECTION_BUFFERS) { - if (i != current_section) { - current_section = i; - fseek (f, section_buffers[i].offset, SEEK_SET); - } - } - // else look through .ini file for it. - else { - // Make sure we are not at eof or this will cause trouble. - if (feof (f)) - rewind (f); - start_pos = ftell (f); - while (1) { - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - // If it is a section, add it to the section buffer - if (is_section (ts, "*")) - current_section = add_section (ts, ftell (f)); - // If it is the section we are looking for, break. - if (is_section (ts, section)) - break; - // If we reach the end of the file, rewind to the start. - if (feof (f)) - rewind (f); - if (ftell (f) == start_pos) - return; - } - } - - // See if field is in buffer - for (i = 0; i < NUM_FIELD_BUFFERS; i++) - if (field_buffers[i].section == current_section) - if (strnicmp (field_buffers[i].name, field, MAX_FIELD_WIDTH) == 0) - break; - - // If field is in buffer, seek to it and read it - if (i < NUM_FIELD_BUFFERS) { - fseek (f, field_buffers[i].offset, SEEK_SET); - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - get_field_string (s, ts); - } else - // else search through section for field. - { - // Make sure we do not start at eof or this will cause problems. - if (feof (f)) - fseek (f, section_buffers[current_section].offset, SEEK_SET); - start_pos = ftell (f); - while (1) { - string_start_pos = ftell (f); - stripped_fgets (ts, INI_STRING_SIZE * 2, f); - // If it is a field, add it to the buffer - if (is_field (ts, "*")) - add_field (ts, current_section, string_start_pos); - // If it is the field we are looking for, save it - if (is_field (ts, field)) { - get_field_string (s, ts); - break; - } - // If we reach the end of the section, start over - if (feof (f) || is_section (ts, "*")) - fseek (f, section_buffers[current_section].offset, SEEK_SET); - if (ftell (f) == start_pos) - return; - } - } -} - -//============================================================================= - -#define BYTE unsigned char -#define WORD unsigned short -#define DWORD unsigned long - -#define BUFFER_SIZE 4096 - -#define CODEC_ADC_INPUT_CONTROL_LEFT 0x00 -#define CODEC_ADC_INPUT_CONTROL_RIGHT 0x01 -#define CODEC_AUX1_INPUT_CONTROL_LEFT 0x02 -#define CODEC_AUX1_INPUT_CONTROL_RIGHT 0x03 -#define CODEC_AUX2_INPUT_CONTROL_LEFT 0x04 -#define CODEC_AUX2_INPUT_CONTROL_RIGHT 0x05 -#define CODEC_DAC_OUTPUT_CONTROL_LEFT 0x06 -#define CODEC_DAC_OUTPUT_CONTROL_RIGHT 0x07 -#define CODEC_FS_FORMAT 0x08 -#define CODEC_INTERFACE_CONFIG 0x09 -#define CODEC_PIN_CONTROL 0x0A -#define CODEC_ERROR_STATUS_AND_INIT 0x0B -#define CODEC_MODE_AND_ID 0x0C -#define CODEC_LOOPBACK_CONTROL 0x0D -#define CODEC_PLAYBACK_UPPER_BASE_COUNT 0x0E -#define CODEC_PLAYBACK_LOWER_BASE_COUNT 0x0F - -#define SET_CONTROL 0x00 -#define SET_FREQUENCY 0x01 -#define SET_START_HIGH 0x02 -#define SET_START_LOW 0x03 -#define SET_END_HIGH 0x04 -#define SET_END_LOW 0x05 -#define SET_VOLUME_RATE 0x06 -#define SET_VOLUME_START 0x07 -#define SET_VOLUME_END 0x08 -#define SET_CURR_VOLUME 0x09 -#define SET_VOLUME 0x09 -#define SET_ACC_HIGH 0x0A -#define SET_ACC_LOW 0x0B -#define SET_BALANCE 0x0C -#define SET_VOLUME_CONTROL 0x0D -#define SET_VOICES 0x0E - -#define DMA_CONTROL 0x41 -#define SET_DMA_ADDRESS 0x42 -#define SET_DRAM_LOW 0x43 -#define SET_DRAM_HIGH 0x44 -#define ADLIB_CONTROL 0x45 -#define ADLIB_TIMER1 0x46 -#define ADLIB_TIMER2 0x47 -#define SET_RECORD_RATE 0x48 -#define RECORD_CONTROL 0x49 -#define SET_JOYSTICK 0x4B -#define MASTER_RESET 0x4C - -#define GET_CONTROL 0x80 -#define GET_FREQUENCY 0x81 -#define GET_START_HIGH 0x82 -#define GET_START_LOW 0x83 -#define GET_END_HIGH 0x84 -#define GET_END_LOW 0x85 -#define GET_VOLUME_RATE 0x86 -#define GET_VOLUME_START 0x87 -#define GET_VOLUME_END 0x88 -#define GET_VOLUME 0x89 -#define GET_ACC_HIGH 0x8A -#define GET_ACC_LOW 0x8B -#define GET_BALANCE 0x8C -#define GET_VOLUME_CONTROL 0x8D -#define GET_VOICES 0x8E -#define GET_IRQV 0x8F - -struct CodecRateStruct { - WORD Rate; - BYTE FSVal; -}; - -struct Gf1RateStruct { - WORD Rate; - BYTE Voices; -}; - -//============================================================================= -// Reference variables in SND_DOS.C -//============================================================================= -extern short *dma_buffer; - -//============================================================================= -// GUS-only variables -//============================================================================= -static BYTE HaveCodec = 0; - -static WORD CodecRegisterSelect; -static WORD CodecData; -static WORD CodecStatus; -static WORD Gf1TimerControl; -static WORD Gf1PageRegister; -static WORD Gf1RegisterSelect; -static WORD Gf1DataLow; -static WORD Gf1DataHigh; - -static BYTE DmaChannel; - -static BYTE PageRegs[] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; -static BYTE AddrRegs[] = { 0, 2, 4, 6, 0xc0, 0xc4, 0xc8, 0xcc }; -static BYTE CountRegs[] = { 1, 3, 5, 7, 0xc2, 0xc6, 0xca, 0xce }; - -static WORD AddrReg; -static WORD CountReg; -static WORD ModeReg; -static WORD DisableReg; -static WORD ClearReg; - -static struct CodecRateStruct CodecRates[] = { - {5512, 0x01}, - {6620, 0x0F}, - {8000, 0x00}, - {9600, 0x0E}, - {11025, 0x03}, - {16000, 0x02}, - {18900, 0x05}, - {22050, 0x07}, - {27420, 0x04}, - {32000, 0x06}, - {33075, 0x0D}, - {37800, 0x09}, - {44100, 0x0B}, - {48000, 0x0C}, - {0, 0x00} // End marker -}; - -static struct Gf1RateStruct Gf1Rates[] = { - {19293, 32}, - {19916, 31}, - {20580, 30}, - {21289, 29}, - {22050, 28}, - {22866, 27}, - {23746, 26}, - {24696, 25}, - {25725, 24}, - {26843, 23}, - {28063, 22}, - {29400, 21}, - {30870, 20}, - {32494, 19}, - {34300, 18}, - {36317, 17}, - {38587, 16}, - {41160, 15}, - {44100, 14}, - {0, 0} -}; - -//============================================================================= -// Basic GF1 functions -//============================================================================= -void -SetGf18 (BYTE reg, BYTE data) -{ - dos_outportb (Gf1RegisterSelect, reg); - dos_outportb (Gf1DataHigh, data); -} - -void -SetGf116 (BYTE reg, WORD data) -{ - dos_outportb (Gf1RegisterSelect, reg); - dos_outportw (Gf1DataLow, data); -} - -BYTE -GetGf18 (BYTE reg) -{ - dos_outportb (Gf1RegisterSelect, reg); - return (dos_inportb (Gf1DataHigh)); -} - -WORD -GetGf116 (BYTE reg) -{ - dos_outportb (Gf1RegisterSelect, reg); - return (dos_inportw (Gf1DataLow)); -} - -void -Gf1Delay (void) -{ - int i; - - for (i = 0; i < 27; i++) - dos_inportb (Gf1TimerControl); -} - -DWORD -ConvertTo16 (DWORD Address) -{ - return (((Address >> 1) & 0x0001FFFF) | (Address & 0x000C0000L)); -} - -void -ClearGf1Ints (void) -{ - int i; - - SetGf18 (DMA_CONTROL, 0x00); - SetGf18 (ADLIB_CONTROL, 0x00); - SetGf18 (RECORD_CONTROL, 0x00); - - GetGf18 (DMA_CONTROL); - GetGf18 (RECORD_CONTROL); - for (i = 0; i < 32; i++); - GetGf18 (GET_IRQV); -} - - -//============================================================================= -// Get Interwave (UltraSound PnP) configuration if any -//============================================================================= -static qboolean -GUS_GetIWData (void) -{ - char *Interwave, s[INI_STRING_SIZE]; - QFile *IwFile; - int CodecBase, CodecDma, i; - - Interwave = getenv ("INTERWAVE"); - if (Interwave == NULL) - return (false); - - // Open IW.INI - IwFile = ini_fopen (Interwave, "rt"); - if (IwFile == NULL) - return (false); - - // Read codec base and codec DMA - ini_fgets (IwFile, "setup 0", "CodecBase", s); - sscanf (s, "%X", &CodecBase); - ini_fgets (IwFile, "setup 0", "DMA2", s); - sscanf (s, "%i", &CodecDma); - - ini_fclose (IwFile); - - // Make sure numbers OK - if (CodecBase == 0 || CodecDma == 0) - return (false); - - CodecRegisterSelect = CodecBase; - CodecData = CodecBase + 1; - CodecStatus = CodecBase + 2; - DmaChannel = CodecDma; - - // Make sure there is a CODEC at the CODEC base - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Wait for 'INIT' bit to clear - for (i = 0; i < 0xFFFF; i++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - break; - if (i == 0xFFFF) - return (false); - - // Get chip revision - can not be zero - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - if ((dos_inportb (CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) - return (false); - if ((dos_inportb (CodecData) & 0x0F) == 0) - return (false); - - HaveCodec = 1; - Con_Printf ("Sound Card is UltraSound PnP\n"); - return (true); -} - -//============================================================================= -// Get UltraSound MAX configuration if any -//============================================================================= -static qboolean -GUS_GetMAXData (void) -{ - char *Ultrasnd, *Ultra16; - int i; - int GusBase, Dma1, Dma2, Irq1, Irq2; - int CodecBase, CodecDma, CodecIrq, CodecType; - BYTE MaxVal; - - Ultrasnd = getenv ("ULTRASND"); - Ultra16 = getenv ("ULTRA16"); - if (Ultrasnd == NULL || Ultra16 == NULL) - return (false); - - sscanf (Ultrasnd, "%x,%i,%i,%i,%i", &GusBase, &Dma1, &Dma2, &Irq1, &Irq2); - sscanf (Ultra16, "%x,%i,%i,%i", &CodecBase, &CodecDma, &CodecIrq, - &CodecType); - - if (CodecType == 0 && CodecDma != 0) - DmaChannel = CodecDma & 0x07; - else - DmaChannel = Dma2 & 0x07; - - // Make sure there is a GUS at GUS base - dos_outportb (GusBase + 0x08, 0x55); - if (dos_inportb (GusBase + 0x0A) != 0x55) - return (false); - dos_outportb (GusBase + 0x08, 0xAA); - if (dos_inportb (GusBase + 0x0A) != 0xAA) - return (false); - - // Program CODEC control register - MaxVal = ((CodecBase & 0xF0) >> 4) | 0x40; - if (Dma1 > 3) - MaxVal |= 0x10; - if (Dma2 > 3) - MaxVal |= 0x20; - dos_outportb (GusBase + 0x106, MaxVal); - - CodecRegisterSelect = CodecBase; - CodecData = CodecBase + 1; - CodecStatus = CodecBase + 2; - - // Make sure there is a CODEC at the CODEC base - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Wait for 'INIT' bit to clear - for (i = 0; i < 0xFFFF; i++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - break; - if (i == 0xFFFF) - return (false); - - // Get chip revision - can not be zero - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - if ((dos_inportb (CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) - return (false); - if ((dos_inportb (CodecData) & 0x0F) == 0) - return (false); - - HaveCodec = 1; - Con_Printf ("Sound Card is UltraSound MAX\n"); - return (true); -} - -//============================================================================= -// Get regular UltraSound configuration if any -//============================================================================= -static qboolean -GUS_GetGUSData (void) -{ - char *Ultrasnd; - int GusBase, Dma1, Dma2, Irq1, Irq2, i; - - Ultrasnd = getenv ("ULTRASND"); - if (Ultrasnd == NULL) - return (false); - - sscanf (Ultrasnd, "%x,%i,%i,%i,%i", &GusBase, &Dma1, &Dma2, &Irq1, &Irq2); - - DmaChannel = Dma1 & 0x07; - - // Make sure there is a GUS at GUS base - dos_outportb (GusBase + 0x08, 0x55); - if (dos_inportb (GusBase + 0x0A) != 0x55) - return (false); - dos_outportb (GusBase + 0x08, 0xAA); - if (dos_inportb (GusBase + 0x0A) != 0xAA) - return (false); - - Gf1TimerControl = GusBase + 0x008; - Gf1PageRegister = GusBase + 0x102; - Gf1RegisterSelect = GusBase + 0x103; - Gf1DataLow = GusBase + 0x104; - Gf1DataHigh = GusBase + 0x105; - - // Reset the GUS - SetGf18 (MASTER_RESET, 0x00); - Gf1Delay (); - Gf1Delay (); - SetGf18 (MASTER_RESET, 0x01); - Gf1Delay (); - Gf1Delay (); - - // Set to max (32) voices - SetGf18 (SET_VOICES, 0xDF); - - // Clear any pending IRQ's - ClearGf1Ints (); - - // Set all registers to known values - for (i = 0; i < 32; i++) { - dos_outportb (Gf1PageRegister, i); - SetGf18 (SET_CONTROL, 0x03); - SetGf18 (SET_VOLUME_CONTROL, 0x03); - Gf1Delay (); - SetGf18 (SET_CONTROL, 0x03); - SetGf18 (SET_VOLUME_CONTROL, 0x03); - SetGf116 (SET_START_HIGH, 0); - SetGf116 (SET_START_LOW, 0); - SetGf116 (SET_END_HIGH, 0); - SetGf116 (SET_END_LOW, 0); - SetGf116 (SET_ACC_HIGH, 0); - SetGf116 (SET_ACC_LOW, 0); - SetGf18 (SET_VOLUME_RATE, 63); - SetGf18 (SET_VOLUME_START, 5); - SetGf18 (SET_VOLUME_END, 251); - SetGf116 (SET_VOLUME, 5 << 8); - } - - // Clear any pending IRQ's - ClearGf1Ints (); - - // Enable DAC etc. - SetGf18 (MASTER_RESET, 0x07); - - // Enable line output so we can hear something - dos_outportb (GusBase, 0x08); - - HaveCodec = 0; - Con_Printf ("Sound Card is UltraSound\n"); - return (true); -} - - -//============================================================================= -// Programs the DMA controller to start DMAing in Auto-init mode -//============================================================================= -static void -GUS_StartDMA (BYTE DmaChannel, short *dma_buffer, int count) -{ - int mode; - int RealAddr; - - RealAddr = ptr2real (dma_buffer); - - if (DmaChannel <= 3) { - ModeReg = 0x0B; - DisableReg = 0x0A; - ClearReg = 0x0E; - } else { - ModeReg = 0xD6; - DisableReg = 0xD4; - ClearReg = 0xDC; - } - CountReg = CountRegs[DmaChannel]; - AddrReg = AddrRegs[DmaChannel]; - - dos_outportb (DisableReg, DmaChannel | 4); // disable channel - - // set mode- see "undocumented pc", p.876 - mode = (1 << 6) // single-cycle - + (0 << 5) // address increment - + (1 << 4) // auto-init dma - + (2 << 2) // read - + (DmaChannel & 0x03); // channel # - dos_outportb (ModeReg, mode); - - // set page - dos_outportb (PageRegs[DmaChannel], RealAddr >> 16); - - if (DmaChannel <= 3) { // address is in bytes - dos_outportb (0x0C, 0); // prepare to send 16-bit value - dos_outportb (AddrReg, RealAddr & 0xff); - dos_outportb (AddrReg, (RealAddr >> 8) & 0xff); - - dos_outportb (0x0C, 0); // prepare to send 16-bit value - dos_outportb (CountReg, (count - 1) & 0xff); - dos_outportb (CountReg, (count - 1) >> 8); - } else { // address is in words - dos_outportb (0xD8, 0); // prepare to send 16-bit value - dos_outportb (AddrReg, (RealAddr >> 1) & 0xff); - dos_outportb (AddrReg, (RealAddr >> 9) & 0xff); - - dos_outportb (0xD8, 0); // prepare to send 16-bit value - dos_outportb (CountReg, ((count >> 1) - 1) & 0xff); - dos_outportb (CountReg, ((count >> 1) - 1) >> 8); - } - - dos_outportb (ClearReg, 0); // clear write mask - dos_outportb (DisableReg, DmaChannel & ~4); -} - -//============================================================================= -// Starts the CODEC playing -//============================================================================= -static void -GUS_StartCODEC (int count, BYTE FSVal) -{ - int i, j; - - // Clear any pending IRQs - dos_inportb (CodecStatus); - dos_outportb (CodecStatus, 0); - - // Set mode to 2 - dos_outportb (CodecRegisterSelect, CODEC_MODE_AND_ID); - dos_outportb (CodecData, 0xC0); - - // Stop any playback or capture which may be happening - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, dos_inportb (CodecData) & 0xFC); - - // Set FS - dos_outportb (CodecRegisterSelect, CODEC_FS_FORMAT | 0x40); - dos_outportb (CodecData, FSVal | 0x50); // Or in stereo and 16 bit bits - - // Wait a bit - for (i = 0; i < 10; i++) - dos_inportb (CodecData); - - // Routine 1 to counter CODEC bug - wait for init bit to clear and then a - // bit longer (i=min loop count, j=timeout - for (i = 0, j = 0; i < 1000 && j < 0x7FFFF; j++) - if ((dos_inportb (CodecRegisterSelect) & 0x80) == 0) - i++; - - // Routine 2 to counter CODEC bug - this is from Forte's code. For me it - // does not seem to cure the problem, but is added security - // Waits till we can modify index register - for (j = 0; j < 0x7FFFF; j++) { - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - if (dos_inportb (CodecRegisterSelect) == - (CODEC_INTERFACE_CONFIG | 0x40)) break; - } - - // Perform ACAL - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - dos_outportb (CodecData, 0x08); - - // Clear MCE bit - this makes ACAL happen - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - - // Wait for ACAL to finish - for (j = 0; j < 0x7FFFF; j++) { - if ((dos_inportb (CodecRegisterSelect) & 0x80) != 0) - continue; - dos_outportb (CodecRegisterSelect, CODEC_ERROR_STATUS_AND_INIT); - if ((dos_inportb (CodecData) & 0x20) == 0) - break; - } - - // Clear ACAL bit - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG | 0x40); - dos_outportb (CodecData, 0x00); - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - - // Set some other junk - dos_outportb (CodecRegisterSelect, CODEC_LOOPBACK_CONTROL); - dos_outportb (CodecData, 0x00); - dos_outportb (CodecRegisterSelect, CODEC_PIN_CONTROL); - dos_outportb (CodecData, 0x08); // IRQ is disabled in PIN control - - // Set count (it doesn't really matter what value we stuff in here - dos_outportb (CodecRegisterSelect, CODEC_PLAYBACK_LOWER_BASE_COUNT); - dos_outportb (CodecData, count & 0xFF); - dos_outportb (CodecRegisterSelect, CODEC_PLAYBACK_UPPER_BASE_COUNT); - dos_outportb (CodecData, count >> 8); - - // Start playback - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, 0x01); -} - -//============================================================================= -// Starts the GF1 playing -//============================================================================= -static void -GUS_StartGf1 (int count, BYTE Voices) -{ - DWORD StartAddressL, EndAddressL, StartAddressR, EndAddressR; - - // Set number of voices to give us the sampling rate we want - SetGf18 (SET_VOICES, 0xC0 | (Voices - 1)); - - // Figure out addresses - StartAddressL = ConvertTo16 (0); - EndAddressL = ConvertTo16 (count - 2 - 2); - StartAddressR = ConvertTo16 (2); - EndAddressR = ConvertTo16 (count - 2); - - // Set left voice addresses - dos_outportb (Gf1PageRegister, 0); - SetGf116 (SET_START_LOW, StartAddressL << 9); - SetGf116 (SET_START_HIGH, StartAddressL >> 7); - SetGf116 (SET_ACC_LOW, StartAddressL << 9); - SetGf116 (SET_ACC_HIGH, StartAddressL >> 7); - SetGf116 (SET_END_LOW, EndAddressL << 9); - SetGf116 (SET_END_HIGH, EndAddressL >> 7); - // Set balance to full left - SetGf18 (SET_BALANCE, 0); - // Set volume to full - SetGf116 (SET_VOLUME, 0xFFF0); - // Set FC to 2 (so we play every second sample) - SetGf116 (SET_FREQUENCY, 0x0800); - - // Set right voice addresses - dos_outportb (Gf1PageRegister, 1); - SetGf116 (SET_START_LOW, StartAddressR << 9); - SetGf116 (SET_START_HIGH, StartAddressR >> 7); - SetGf116 (SET_ACC_LOW, StartAddressR << 9); - SetGf116 (SET_ACC_HIGH, StartAddressR >> 7); - SetGf116 (SET_END_LOW, EndAddressR << 9); - SetGf116 (SET_END_HIGH, EndAddressR >> 7); - // Set balance to full right - SetGf18 (SET_BALANCE, 15); - // Set volume to full - SetGf116 (SET_VOLUME, 0xFFF0); - // Set FC to 2 (so we play every second sample) - SetGf116 (SET_FREQUENCY, 0x0800); - - // Start voices - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x0C); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x0C); - Gf1Delay (); - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x0C); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x0C); -} - - -//============================================================================= -// Figures out what kind of UltraSound we have, if any, and starts it playing -//============================================================================= -qboolean -GUS_Init (void) -{ - int rc; - int RealAddr; - BYTE FSVal, Voices; - struct CodecRateStruct *CodecRate; - struct Gf1RateStruct *Gf1Rate; - - // See what kind of UltraSound we have, if any - if (GUS_GetIWData () == false) - if (GUS_GetMAXData () == false) - if (GUS_GetGUSData () == false) - return (false); - - shm = &sn; - - if (HaveCodec) { - // do 11khz sampling rate unless command line parameter wants - // different - shm->speed = 11025; - FSVal = 0x03; - rc = COM_CheckParm ("-sspeed"); - if (rc) { - shm->speed = Q_atoi (com_argv[rc + 1]); - - // Make sure rate not too high - if (shm->speed > 48000) - shm->speed = 48000; - - // Adjust speed to match one of the possible CODEC rates - for (CodecRate = CodecRates; CodecRate->Rate != 0; CodecRate++) { - if (shm->speed <= CodecRate->Rate) { - shm->speed = CodecRate->Rate; - FSVal = CodecRate->FSVal; - break; - } - } - } - // Always do 16 bit stereo - shm->channels = 2; - shm->samplebits = 16; - - // allocate buffer twice the size we need so we can get aligned - // buffer - dma_buffer = dos_getmemory (BUFFER_SIZE * 2); - if (dma_buffer == NULL) { - Con_Printf ("Couldn't allocate sound dma buffer"); - return false; - } - - RealAddr = ptr2real (dma_buffer); - RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE - 1); - dma_buffer = (short *) real2ptr (RealAddr); - - // Zero off DMA buffer - memset (dma_buffer, 0, BUFFER_SIZE); - - shm->soundalive = true; - shm->splitbuffer = false; - - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) dma_buffer; - shm->samples = BUFFER_SIZE / (shm->samplebits / 8); - - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - GUS_StartCODEC (BUFFER_SIZE, FSVal); - } else { - // do 19khz sampling rate unless command line parameter wants - // different - shm->speed = 19293; - Voices = 32; - rc = COM_CheckParm ("-sspeed"); - if (rc) { - shm->speed = Q_atoi (com_argv[rc + 1]); - - // Make sure rate not too high - if (shm->speed > 44100) - shm->speed = 44100; - - // Adjust speed to match one of the possible GF1 rates - for (Gf1Rate = Gf1Rates; Gf1Rate->Rate != 0; Gf1Rate++) { - if (shm->speed <= Gf1Rate->Rate) { - shm->speed = Gf1Rate->Rate; - Voices = Gf1Rate->Voices; - break; - } - } - } - // Always do 16 bit stereo - shm->channels = 2; - shm->samplebits = 16; - - // allocate buffer twice the size we need so we can get aligned - // buffer - dma_buffer = dos_getmemory (BUFFER_SIZE * 2); - if (dma_buffer == NULL) { - Con_Printf ("Couldn't allocate sound dma buffer"); - return false; - } - - RealAddr = ptr2real (dma_buffer); - RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE - 1); - dma_buffer = (short *) real2ptr (RealAddr); - - // Zero off DMA buffer - memset (dma_buffer, 0, BUFFER_SIZE); - - shm->soundalive = true; - shm->splitbuffer = false; - - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) dma_buffer; - shm->samples = BUFFER_SIZE / (shm->samplebits / 8); - - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - SetGf116 (SET_DMA_ADDRESS, 0x0000); - if (DmaChannel <= 3) - SetGf18 (DMA_CONTROL, 0x41); - else - SetGf18 (DMA_CONTROL, 0x45); - GUS_StartGf1 (BUFFER_SIZE, Voices); - } - return (true); -} - -//============================================================================= -// Returns the current playback position -//============================================================================= -int -GUS_GetDMAPos (void) -{ - int count; - - if (HaveCodec) { - // clear 16-bit reg flip-flop - // load the current dma count register - if (DmaChannel < 4) { - dos_outportb (0x0C, 0); - count = dos_inportb (CountReg); - count += dos_inportb (CountReg) << 8; - if (shm->samplebits == 16) - count /= 2; - count = shm->samples - (count + 1); - } else { - dos_outportb (0xD8, 0); - count = dos_inportb (CountReg); - count += dos_inportb (CountReg) << 8; - if (shm->samplebits == 8) - count *= 2; - count = shm->samples - (count + 1); - } - - } else { - // Read current position from GF1 - dos_outportb (Gf1PageRegister, 0); - count = (GetGf116 (GET_ACC_HIGH) << 7) & 0xFFFF; - // See which half of buffer we are in. Note that since this is 16 bit - // data we are playing, position is in 16 bit samples - if (GetGf18 (DMA_CONTROL) & 0x40) { - GUS_StartDMA (DmaChannel, dma_buffer, BUFFER_SIZE); - SetGf116 (SET_DMA_ADDRESS, 0x0000); - if (DmaChannel <= 3) - SetGf18 (DMA_CONTROL, 0x41); - else - SetGf18 (DMA_CONTROL, 0x45); - } - } - - shm->samplepos = count & (shm->samples - 1); - return (shm->samplepos); -} - -//============================================================================= -// Stops the UltraSound playback -//============================================================================= -void -GUS_Shutdown (void) -{ - if (HaveCodec) { - // Stop CODEC - dos_outportb (CodecRegisterSelect, CODEC_INTERFACE_CONFIG); - dos_outportb (CodecData, 0x01); - } else { - // Stop Voices - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x03); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x03); - Gf1Delay (); - dos_outportb (Gf1PageRegister, 0); - SetGf18 (SET_CONTROL, 0x03); - dos_outportb (Gf1PageRegister, 1); - SetGf18 (SET_CONTROL, 0x03); - - // Stop any DMA - SetGf18 (DMA_CONTROL, 0x00); - GetGf18 (DMA_CONTROL); - } - - dos_outportb (DisableReg, DmaChannel | 4); // disable dma channel -} diff --git a/qw/source/snd_mem.c b/qw/source/snd_mem.c deleted file mode 100644 index 03f70162b..000000000 --- a/qw/source/snd_mem.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - snd_mem.c - - sound caching - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include "QF/console.h" -#include "QF/qendian.h" -#include "QF/quakefs.h" -#include "sound.h" -#include "QF/sys.h" - -int cache_full_cycle; - -byte *S_Alloc (int size); - -/* - ResampleSfx -*/ -void -ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte * data) -{ - int outcount; - int srcsample; - float stepscale; - int i; - int sample, samplefrac, fracstep; - sfxcache_t *sc; - short *is, *os; - unsigned char *ib, *ob; - - sc = Cache_Check (&sfx->cache); - if (!sc) - return; - - is = (short *) data; - os = (short *) sc->data; - ib = data; - ob = sc->data; - - stepscale = (float) inrate / shm->speed; // this is usually 0.5, 1, or - // - // 2 - - outcount = sc->length / stepscale; - - sc->speed = shm->speed; - if (loadas8bit->int_val) - sc->width = 1; - else - sc->width = 2; - sc->stereo = 0; - - // resample / decimate to the current source rate - if (stepscale == 1) { - if (inwidth == 1 && sc->width == 1) { - for (i = 0; i < outcount; i++) { - *ob++ = *ib++ - 128; - } - } else if (inwidth == 1 && sc->width == 2) { - for (i = 0; i < outcount; i++) { - *os++ = (*ib++ - 128) << 8; - } - } else if (inwidth == 2 && sc->width == 1) { - for (i = 0; i < outcount; i++) { - *ob++ = LittleShort (*is++) >> 8; - } - } else if (inwidth == 2 && sc->width == 2) { - for (i = 0; i < outcount; i++) { - *os++ = LittleShort (*is++); - } - } - } else { - // general case - if (snd_interp->int_val && stepscale < 1) { - int points = 1 / stepscale; - int j; - - for (i = 0; i < sc->length; i++) { - int s1, s2; - - if (inwidth == 2) { - s2 = s1 = LittleShort (is[0]); - if (i < sc->length - 1) - s2 = LittleShort (is[1]); - is++; - } else { - s2 = s1 = (ib[0] - 128) << 8; - if (i < sc->length - 1) - s2 = (ib[1] - 128) << 8; - ib++; - } - for (j = 0; j < points; j++) { - sample = s1 + (s2 - s1) * ((float) j) / points; - if (sc->width == 2) { - os[j] = sample; - } else { - ob[j] = sample >> 8; - } - } - if (sc->width == 2) { - os += points; - } else { - ob += points; - } - } - } else { - samplefrac = 0; - fracstep = stepscale * 256; - for (i = 0; i < outcount; i++) { - srcsample = samplefrac >> 8; - samplefrac += fracstep; - if (inwidth == 2) - sample = LittleShort (((short *) data)[srcsample]); - else - sample = - (int) ((unsigned char) (data[srcsample]) - 128) << 8; - if (sc->width == 2) - ((short *) sc->data)[i] = sample; - else - ((signed char *) sc->data)[i] = sample >> 8; - } - } - } - - sc->length = outcount; - if (sc->loopstart != -1) - sc->loopstart = sc->loopstart / stepscale; -} - -//============================================================================= - -/* - S_LoadSound -*/ -sfxcache_t * -S_LoadSound (sfx_t *s) -{ - char namebuffer[256]; - byte *data; - wavinfo_t info; - int len; - float stepscale; - sfxcache_t *sc; - byte stackbuf[1 * 1024]; // avoid dirtying the cache heap - -// see if still in memory - sc = Cache_Check (&s->cache); - if (sc) - return sc; - -//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); -// load it in - strcpy (namebuffer, "sound/"); - strncat (namebuffer, s->name, sizeof (namebuffer) - strlen (namebuffer)); - -// Con_Printf ("loading %s\n",namebuffer); - - data = COM_LoadStackFile (namebuffer, stackbuf, sizeof (stackbuf)); - - if (!data) { - Con_Printf ("Couldn't load %s\n", namebuffer); - return NULL; - } - - info = GetWavinfo (s->name, data, com_filesize); - if (info.channels != 1) { - Con_Printf ("%s is a stereo sample\n", s->name); - return NULL; - } - - stepscale = (float) info.rate / shm->speed; - len = info.samples / stepscale; - - if (loadas8bit->int_val) { - len = len * info.channels; - } else { - len = len * 2 * info.channels; - } - - sc = Cache_Alloc (&s->cache, len + sizeof (sfxcache_t), s->name); - - if (!sc) - return NULL; - - sc->length = info.samples; - sc->loopstart = info.loopstart; - sc->speed = info.rate; - sc->width = info.width; - sc->stereo = info.channels; - - ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); - - return sc; -} - - - -/* - WAV loading -*/ - - -byte *data_p; -byte *iff_end; -byte *last_chunk; -byte *iff_data; -int iff_chunk_len; - - -short -GetLittleShort (void) -{ - short val = 0; - - val = *data_p; - val = val + (*(data_p + 1) << 8); - data_p += 2; - return val; -} - -int -GetLittleLong (void) -{ - int val = 0; - - val = *data_p; - val = val + (*(data_p + 1) << 8); - val = val + (*(data_p + 2) << 16); - val = val + (*(data_p + 3) << 24); - data_p += 4; - return val; -} - -void -FindNextChunk (char *name) -{ - while (1) { - data_p = last_chunk; - - if (data_p >= iff_end) { // didn't find the chunk - data_p = NULL; - return; - } - - data_p += 4; - iff_chunk_len = GetLittleLong (); - if (iff_chunk_len < 0) { - data_p = NULL; - return; - } -// if (iff_chunk_len > 1024*1024) -// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); - data_p -= 8; - last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1); - if (!strncmp (data_p, name, 4)) - return; - } -} - -void -FindChunk (char *name) -{ - last_chunk = iff_data; - FindNextChunk (name); -} - - -void -DumpChunks (void) -{ - char str[5]; - - str[4] = 0; - data_p = iff_data; - do { - memcpy (str, data_p, 4); - data_p += 4; - iff_chunk_len = GetLittleLong (); - Con_Printf ("0x%x : %s (%d)\n", (int) (data_p - 4), str, iff_chunk_len); - data_p += (iff_chunk_len + 1) & ~1; - } while (data_p < iff_end); -} - -/* - GetWavinfo -*/ -wavinfo_t -GetWavinfo (char *name, byte * wav, int wavlength) -{ - wavinfo_t info; - int i; - int format; - int samples; - - memset (&info, 0, sizeof (info)); - - if (!wav) - return info; - - iff_data = wav; - iff_end = wav + wavlength; - -// find "RIFF" chunk - FindChunk ("RIFF"); - if (!(data_p && !strncmp (data_p + 8, "WAVE", 4))) { - Con_Printf ("Missing RIFF/WAVE chunks\n"); - return info; - } -// get "fmt " chunk - iff_data = data_p + 12; -// DumpChunks (); - - FindChunk ("fmt "); - if (!data_p) { - Con_Printf ("Missing fmt chunk\n"); - return info; - } - data_p += 8; - format = GetLittleShort (); - if (format != 1) { - Con_Printf ("Microsoft PCM format only\n"); - return info; - } - - info.channels = GetLittleShort (); - info.rate = GetLittleLong (); - data_p += 4 + 2; - info.width = GetLittleShort () / 8; - -// get cue chunk - FindChunk ("cue "); - if (data_p) { - data_p += 32; - info.loopstart = GetLittleLong (); -// Con_Printf("loopstart=%d\n", sfx->loopstart); - - // if the next chunk is a LIST chunk, look for a cue length marker - FindNextChunk ("LIST"); - if (data_p) { - if (!strncmp (data_p + 28, "mark", 4)) { // this is not a - // proper parse, but - // it works with - // cooledit... - data_p += 24; - i = GetLittleLong (); // samples in loop - info.samples = info.loopstart + i; -// Con_Printf("looped length: %i\n", i); - } - } - } else - info.loopstart = -1; - -// find data chunk - FindChunk ("data"); - if (!data_p) { - Con_Printf ("Missing data chunk\n"); - return info; - } - - data_p += 4; - samples = GetLittleLong () / info.width; - - if (info.samples) { - if (samples < info.samples) - Sys_Error ("Sound %s has a bad loop length", name); - } else - info.samples = samples; - - info.dataofs = data_p - wav; - - return info; -} diff --git a/qw/source/snd_mix.c b/qw/source/snd_mix.c deleted file mode 100644 index 947914c24..000000000 --- a/qw/source/snd_mix.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - snd_mix.c - - portable code to mix sounds for snd_dma.c - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include "QF/compat.h" -#include "QF/console.h" -#include "sound.h" - -#ifdef _WIN32 -# include "winquake.h" -#else -# define DWORD unsigned long -#endif - -#define PAINTBUFFER_SIZE 512 -portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2]; -int max_overpaint; // number of extra samples painted - - // due to phase shift -int snd_scaletable[32][256]; -int *snd_p, snd_linear_count, snd_vol; -short *snd_out; - -void Snd_WriteLinearBlastStereo16 (void); - -#ifndef USE_INTEL_ASM -void -Snd_WriteLinearBlastStereo16 (void) -{ - int i; - int val; - - for (i = 0; i < snd_linear_count; i += 2) { - val = (snd_p[i] * snd_vol) >> 8; - if (val > 0x7fff) - snd_out[i] = 0x7fff; - else if (val < (short) 0x8000) - snd_out[i] = (short) 0x8000; - else - snd_out[i] = val; - - val = (snd_p[i + 1] * snd_vol) >> 8; - if (val > 0x7fff) - snd_out[i + 1] = 0x7fff; - else if (val < (short) 0x8000) - snd_out[i + 1] = (short) 0x8000; - else - snd_out[i + 1] = val; - } -} -#endif - -void -S_TransferStereo16 (int endtime) -{ - int lpos; - int lpaintedtime; - DWORD *pbuf; - - snd_vol = volume->value * 256; - - snd_p = (int *) paintbuffer; - lpaintedtime = paintedtime; - -#ifdef _WIN32 - if (pDSBuf) { - pbuf = DSOUND_LockBuffer (true); - if (!pbuf) { - Con_Printf ("DSOUND_LockBuffer fails!\n"); - return; - } - } else -#endif - { - pbuf = (DWORD *) shm->buffer; - } - - while (lpaintedtime < endtime) { - // handle recirculating buffer issues - lpos = lpaintedtime & ((shm->samples >> 1) - 1); - - snd_out = (short *) pbuf + (lpos << 1); - - snd_linear_count = (shm->samples >> 1) - lpos; - if (lpaintedtime + snd_linear_count > endtime) - snd_linear_count = endtime - lpaintedtime; - - snd_linear_count <<= 1; - - // write a linear blast of samples - Snd_WriteLinearBlastStereo16 (); - - snd_p += snd_linear_count; - lpaintedtime += (snd_linear_count >> 1); - } - -#ifdef _WIN32 - if (pDSBuf) - DSOUND_LockBuffer (false); -#endif -} - -void -S_TransferPaintBuffer (int endtime) -{ - int out_idx; - int count; - int out_mask; - int *p; - int step; - int val; - int snd_vol; - DWORD *pbuf; - - if (shm->samplebits == 16 && shm->channels == 2) { - S_TransferStereo16 (endtime); - return; - } - - p = (int *) paintbuffer; - count = (endtime - paintedtime) * shm->channels; - out_mask = shm->samples - 1; - out_idx = paintedtime * shm->channels & out_mask; - step = 3 - shm->channels; - snd_vol = volume->value * 256; - -#ifdef _WIN32 - if (pDSBuf) { - pbuf = DSOUND_LockBuffer (true); - if (!pbuf) { - Con_Printf ("DSOUND_LockBuffer fails!\n"); - return; - } - } else -#endif - { - pbuf = (DWORD *) shm->buffer; - } - - if (shm->samplebits == 16) { - short *out = (short *) pbuf; - - while (count--) { - val = (*p * snd_vol) >> 8; - p += step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short) 0x8000) - val = (short) 0x8000; - out[out_idx] = val; - out_idx = (out_idx + 1) & out_mask; - } - } else if (shm->samplebits == 8) { - unsigned char *out = (unsigned char *) pbuf; - - while (count--) { - val = (*p * snd_vol) >> 8; - p += step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short) 0x8000) - val = (short) 0x8000; - out[out_idx] = (val >> 8) + 128; - out_idx = (out_idx + 1) & out_mask; - } - } -#ifdef _WIN32 - if (pDSBuf) - DSOUND_LockBuffer (false); -#endif -} - - -/* - CHANNEL MIXING -*/ - -void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime); -void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime); - -void -S_PaintChannels (int endtime) -{ - int i; - int end; - channel_t *ch; - sfxcache_t *sc; - int ltime, count; - - while (paintedtime < endtime) { - // if paintbuffer is smaller than DMA buffer - end = endtime; - if (endtime - paintedtime > PAINTBUFFER_SIZE) - end = paintedtime + PAINTBUFFER_SIZE; - - // clear the paint buffer -// memset (paintbuffer, 0, -// (end - paintedtime) * sizeof (portable_samplepair_t)); - max_overpaint = 0; - - // paint in the channels. - ch = channels; - for (i = 0; i < total_channels; i++, ch++) { - if (!ch->sfx) - continue; - if (!ch->leftvol && !ch->rightvol) - continue; - sc = S_LoadSound (ch->sfx); - if (!sc) - continue; - - ltime = paintedtime; - - while (ltime < end) { // paint up to end - if (ch->end < end) - count = ch->end - ltime; - else - count = end - ltime; - - if (count > 0) { - if (sc->width == 1) - SND_PaintChannelFrom8 (ch, sc, count); - else - SND_PaintChannelFrom16 (ch, sc, count); - - ltime += count; - } - // if at end of loop, restart - if (ltime >= ch->end) { - if (sc->loopstart >= 0) { - ch->pos = sc->loopstart; - ch->end = ltime + sc->length - ch->pos; - } else { // channel just stopped - ch->sfx = NULL; - break; - } - } - } - - } - - // transfer out according to DMA format - S_TransferPaintBuffer (end); - - memmove (paintbuffer, paintbuffer + end - paintedtime, - max_overpaint * sizeof (paintbuffer[0])); - memset (paintbuffer + max_overpaint, 0, sizeof (paintbuffer) - - max_overpaint * sizeof (paintbuffer[0])); - - paintedtime = end; - } -} - -void -SND_InitScaletable (void) -{ - int i, j; - - for (i = 0; i < 32; i++) - for (j = 0; j < 256; j++) - snd_scaletable[i][j] = ((signed char) j) * i * 8; -} - - -#ifndef USE_INTEL_ASM - -void -SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int *lscale, *rscale; - unsigned char *sfx; - int i; - - if (ch->leftvol > 255) - ch->leftvol = 255; - if (ch->rightvol > 255) - ch->rightvol = 255; - - lscale = snd_scaletable[ch->leftvol >> 3]; - rscale = snd_scaletable[ch->rightvol >> 3]; - sfx = (signed char *) sc->data + ch->pos; - - for (i = 0; i < count; i++) { - data = sfx[i]; - paintbuffer[i].left += lscale[data]; - paintbuffer[i].right += rscale[data]; - } - - ch->pos += count; -} - -#endif // !USE_INTEL_ASM - - -void -SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int left, right; - int leftvol, rightvol; - signed short *sfx; - unsigned int i = 0; - unsigned int left_phase, right_phase; // Never allowed < 0 anyway - - leftvol = ch->leftvol; - rightvol = ch->rightvol; - - max_overpaint = max (abs (ch->phase), - max (abs (ch->oldphase), max_overpaint)); - - sfx = (signed short *) sc->data + ch->pos; - ch->pos += count; - - if (ch->phase >= 0) { - left_phase = ch->phase; - right_phase = 0; - } else { - left_phase = 0; - right_phase = -ch->phase; - } - - if (ch->oldphase != ch->phase) { - unsigned int old_phase_left, old_phase_right; - unsigned int new_phase_left, new_phase_right; - unsigned int count_left, count_right, c; - - if (ch->oldphase >= 0) { - old_phase_left = ch->oldphase; - old_phase_right = 0; - } else { - old_phase_left = 0; - old_phase_right = -ch->oldphase; - } - new_phase_left = left_phase; - new_phase_right = right_phase; - - if (new_phase_left > old_phase_left) - count_left = 2 * (new_phase_left - old_phase_left); - else - count_left = old_phase_left - new_phase_left; - - if (new_phase_right > old_phase_right) - count_right = 2 * (new_phase_right - old_phase_right); - else - count_right = old_phase_right - new_phase_right; - - c = min (count, max (count_right, count_left)); - count -= c; - while (c) { - int data = sfx[i]; - int left = (data * leftvol) >> 8; - int right = (data * rightvol) >> 8; - - if (new_phase_left < old_phase_left) { - if (!(count_left & 1)) { - paintbuffer[i + old_phase_left].left += left; - old_phase_left--; - } - count_left--; - } else if (new_phase_left > old_phase_left) { - paintbuffer[i + old_phase_left].left += left; - old_phase_left++; - paintbuffer[i + old_phase_left].left += left; - } else { - paintbuffer[i + old_phase_left].left += left; - } - - if (new_phase_right < old_phase_right) { - if (!(count_right & 1)) { - paintbuffer[i + old_phase_right].right += right; - old_phase_right--; - } - count_right--; - } else if (new_phase_right > old_phase_right) { - paintbuffer[i + old_phase_right].right += right; - old_phase_right++; - paintbuffer[i + old_phase_right].right += right; - } else { - paintbuffer[i + old_phase_right].right += right; - } - - c--; - i++; - } - } - - for (i = 0; i < count; i++) { - data = sfx[i]; - left = (data * leftvol) >> 8; - right = (data * rightvol) >> 8; - paintbuffer[i + left_phase].left += left; - paintbuffer[i + right_phase].right += right; - } -} diff --git a/qw/source/snd_mixa.S b/qw/source/snd_mixa.S deleted file mode 100644 index e135fc383..000000000 --- a/qw/source/snd_mixa.S +++ /dev/null @@ -1,232 +0,0 @@ -/* - snd_mixa.S - - x86 assembly-language sound code - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "QF/asm_i386.h" -// #include "quakeasm.h" - -#ifdef USE_INTEL_ASM - - .text - - .extern C(snd_scaletable) - .extern C(paintbuffer) - .extern C(snd_linear_count) - .extern C(snd_p) - .extern C(snd_vol) - .extern C(snd_out) - -//---------------------------------------------------------------------- -// 8-bit sound-mixing code -//---------------------------------------------------------------------- - -#define ch 4+16 -#define sc 8+16 -#define count 12+16 - -.globl C(SND_PaintChannelFrom8) -C(SND_PaintChannelFrom8): - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - pushl %ebp - -// int data; -// short *lscale, *rscale; -// unsigned char *sfx; -// int i; - - movl ch(%esp),%ebx - movl sc(%esp),%esi - -// if (ch->leftvol > 255) -// ch->leftvol = 255; -// if (ch->rightvol > 255) -// ch->rightvol = 255; - movl ch_leftvol(%ebx),%eax - movl ch_rightvol(%ebx),%edx - cmpl $255,%eax - jna LLeftSet - movl $255,%eax -LLeftSet: - cmpl $255,%edx - jna LRightSet - movl $255,%edx -LRightSet: - -// lscale = snd_scaletable[ch->leftvol >> 3]; -// rscale = snd_scaletable[ch->rightvol >> 3]; -// sfx = (signed char *)sc->data + ch->pos; -// ch->pos += count; - andl $0xF8,%eax - addl $(sfxc_data),%esi - andl $0xF8,%edx - movl ch_pos(%ebx),%edi - movl count(%esp),%ecx - addl %edi,%esi - shll $7,%eax - addl %ecx,%edi - shll $7,%edx - movl %edi,ch_pos(%ebx) - addl $(C(snd_scaletable)),%eax - addl $(C(snd_scaletable)),%edx - subl %ebx,%ebx - movb -1(%esi,%ecx,1),%bl - - testl $1,%ecx - jz LMix8Loop - - movl (%eax,%ebx,4),%edi - movl (%edx,%ebx,4),%ebp - addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi - addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp - movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size) - movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size) - movb -2(%esi,%ecx,1),%bl - - decl %ecx - jz LDone - -// for (i=0 ; i>8; -// if (val > 0x7fff) -// snd_out[i] = 0x7fff; -// else if (val < (short)0x8000) -// snd_out[i] = (short)0x8000; -// else -// snd_out[i] = val; - movl -8(%ebx,%ecx,4),%eax - imull %esi,%eax - sarl $8,%eax - cmpl $0x7FFF,%eax - jg LClampHigh - cmpl $0xFFFF8000,%eax - jnl LClampDone - movl $0xFFFF8000,%eax - jmp LClampDone -LClampHigh: - movl $0x7FFF,%eax -LClampDone: - -// val = (snd_p[i+1]*snd_vol)>>8; -// if (val > 0x7fff) -// snd_out[i+1] = 0x7fff; -// else if (val < (short)0x8000) -// snd_out[i+1] = (short)0x8000; -// else -// snd_out[i+1] = val; - movl -4(%ebx,%ecx,4),%edx - imull %esi,%edx - sarl $8,%edx - cmpl $0x7FFF,%edx - jg LClampHigh2 - cmpl $0xFFFF8000,%edx - jnl LClampDone2 - movl $0xFFFF8000,%edx - jmp LClampDone2 -LClampHigh2: - movl $0x7FFF,%edx -LClampDone2: - shll $16,%edx - andl $0xFFFF,%eax - orl %eax,%edx - movl %edx,-4(%edi,%ecx,2) - -// } - subl $2,%ecx - jnz LWLBLoopTop - -// snd_p += snd_linear_count; - - popl %ebx - popl %edi - popl %esi - - ret - - -#endif // USE_INTEL_ASM - diff --git a/qw/source/snd_null.c b/qw/source/snd_null.c deleted file mode 100644 index f7b6dc9fb..000000000 --- a/qw/source/snd_null.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - snd_null.c - - include this instead of all the other snd_* files to have no sound - code whatsoever - - Copyright (C) 1996-1997 Id Software, Inc. - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#include "QF/qtypes.h" -#include "sound.h" - -// ======================================================================= -// Various variables also defined in snd_dma.c -// FIXME - should be put in one place -// ======================================================================= -channel_t channels[MAX_CHANNELS]; -int total_channels; -volatile dma_t *shm = 0; -cvar_t *loadas8bit; -int paintedtime; // sample PAIRS - - -cvar_t *bgmvolume; -cvar_t *volume; - - -void -S_Init (void) -{ - S_Init_Cvars (); -} - -void -S_Init_Cvars (void) -{ - volume = Cvar_Get ("volume", "0.7", CVAR_ARCHIVE, 0, "Volume level of sounds"); - loadas8bit = - Cvar_Get ("loadas8bit", "0", CVAR_NONE, 0, "Load samples as 8-bit"); - bgmvolume = Cvar_Get ("bgmvolume", "1", CVAR_ARCHIVE, 0, "CD music volume"); -} - -void -S_AmbientOff (void) -{ -} - -void -S_AmbientOn (void) -{ -} - -void -S_Shutdown (void) -{ -} - -void -S_TouchSound (char *sample) -{ -} - -void -S_ClearBuffer (void) -{ -} - -void -S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) -{ -} - -void -S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, - float attenuation) -{ -} - -void -S_StopSound (int entnum, int entchannel) -{ -} - -sfx_t * -S_PrecacheSound (char *sample) -{ - return NULL; -} - -void -S_ClearPrecache (void) -{ -} - -void -S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up) -{ -} - -void -S_StopAllSounds (qboolean clear) -{ -} - -void -S_BeginPrecaching (void) -{ -} - -void -S_EndPrecaching (void) -{ -} - -void -S_ExtraUpdate (void) -{ -} - -void -S_LocalSound (char *s) -{ -} diff --git a/qw/source/snd_oss.c b/qw/source/snd_oss.c deleted file mode 100644 index 03dd17335..000000000 --- a/qw/source/snd_oss.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - snd_oss.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_IOCTL_H -# include -#endif - -#ifdef HAVE_SYS_MMAN_H -# include -#endif - -#if defined HAVE_SYS_SOUNDCARD_H -# include -#elif defined HAVE_LINUX_SOUNDCARD_H -# include -#elif HAVE_MACHINE_SOUNDCARD_H -# include -#endif - -#include "QF/cmd.h" -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -#ifndef MAP_FAILED -# define MAP_FAILED ((void *) -1) -#endif - -static int audio_fd; -static int snd_inited; -static char *snd_dev = "/dev/dsp"; - -static int tryrates[] = { 11025, 22050, 22051, 44100, 8000 }; - -qboolean -SNDDMA_Init (void) -{ - int rc; - int fmt; - int tmp; - int i; - struct audio_buf_info info; - int caps; - int retries = 3; - - snd_inited = 0; - - // open snd_dev, confirm capability to mmap, and get size of dma buffer - if (snd_device->string[0]) - snd_dev = snd_device->string; - - audio_fd = open (snd_dev, O_RDWR); - if (audio_fd < 0) { // Failed open, retry up to 3 times - // if it's busy - while ((audio_fd < 0) && retries-- && - ((errno == EAGAIN) || (errno == EBUSY))) { - sleep (1); - audio_fd = open (snd_dev, O_RDWR); - } - if (audio_fd < 0) { - perror (snd_dev); - Con_Printf ("Could not open %s\n", snd_dev); - return 0; - } - } - - if ((rc = ioctl (audio_fd, SNDCTL_DSP_RESET, 0)) < 0) { - perror (snd_dev); - Con_Printf ("Could not reset %s\n", snd_dev); - close (audio_fd); - return 0; - } - - if (ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) { - perror (snd_dev); - Con_Printf ("Sound driver too old\n"); - close (audio_fd); - return 0; - } - - if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) { - Con_Printf ("Sound device can't do memory-mapped I/O.\n"); - close (audio_fd); - return 0; - } - - if (ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) { - perror ("GETOSPACE"); - Con_Printf ("Um, can't do GETOSPACE?\n"); - close (audio_fd); - return 0; - } - - shm = &sn; - shm->splitbuffer = 0; - - // set sample bits & speed - shm->samplebits = snd_bits->int_val; - - if (shm->samplebits != 16 && shm->samplebits != 8) { - ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &fmt); - - if (fmt & AFMT_S16_LE) { // little-endian 16-bit signed - shm->samplebits = 16; - } else { - if (fmt & AFMT_U8) { // unsigned 8-bit ulaw - shm->samplebits = 8; - } - } - } - - if (snd_rate->int_val) { - shm->speed = snd_rate->int_val; - } else { - for (i = 0; i < (sizeof (tryrates) / 4); i++) - if (!ioctl (audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) - break; - shm->speed = tryrates[i]; - } - - if (!snd_stereo->int_val) { - shm->channels = 1; - } else { - shm->channels = 2; - } - - shm->samples = info.fragstotal * info.fragsize / (shm->samplebits / 8); - shm->submission_chunk = 1; - - // memory map the dma buffer - shm->buffer = (unsigned char *) mmap (NULL, info.fragstotal - * info.fragsize, - PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, audio_fd, 0); - - if (shm->buffer == MAP_FAILED) { - perror (snd_dev); - Con_Printf ("Could not mmap %s\n", snd_dev); - close (audio_fd); - return 0; - } - - tmp = 0; - if (shm->channels == 2) - tmp = 1; - rc = ioctl (audio_fd, SNDCTL_DSP_STEREO, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not set %s to stereo=%d", snd_dev, shm->channels); - close (audio_fd); - return 0; - } - - if (tmp) - shm->channels = 2; - else - shm->channels = 1; - - rc = ioctl (audio_fd, SNDCTL_DSP_SPEED, &shm->speed); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not set %s speed to %d", snd_dev, shm->speed); - close (audio_fd); - return 0; - } - - if (shm->samplebits == 16) { - rc = AFMT_S16_LE; - rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not support 16-bit data. Try 8-bit.\n"); - close (audio_fd); - return 0; - } - } else if (shm->samplebits == 8) { - rc = AFMT_U8; - rc = ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not support 8-bit data.\n"); - close (audio_fd); - return 0; - } - } else { - perror (snd_dev); - Con_Printf ("%d-bit sound not supported.", shm->samplebits); - close (audio_fd); - return 0; - } - -// toggle the trigger & start her up - - tmp = 0; - rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not toggle.\n"); - close (audio_fd); - return 0; - } - tmp = PCM_ENABLE_OUTPUT; - rc = ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); - if (rc < 0) { - perror (snd_dev); - Con_Printf ("Could not toggle.\n"); - close (audio_fd); - return 0; - } - - shm->samplepos = 0; - - snd_inited = 1; - return 1; - -} - -int -SNDDMA_GetDMAPos (void) -{ - - struct count_info count; - - if (!snd_inited) - return 0; - - if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) { - perror (snd_dev); - Con_Printf ("Uh, sound dead.\n"); - close (audio_fd); - snd_inited = 0; - return 0; - } -// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); -// fprintf(stderr, "%d \r", count.ptr); - shm->samplepos = count.ptr / (shm->samplebits / 8); - - return shm->samplepos; - -} - -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) -{ -} diff --git a/qw/source/snd_sdl.c b/qw/source/snd_sdl.c deleted file mode 100644 index a33fc6ddb..000000000 --- a/qw/source/snd_sdl.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - snd_sdl.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "QF/cmd.h" -#include "QF/console.h" -#include "QF/qargs.h" -#include "sound.h" - -static dma_t the_shm; -static int snd_inited; - -extern int desired_speed; -extern int desired_bits; - -static void -paint_audio (void *unused, Uint8 * stream, int len) -{ - if (shm) { - shm->buffer = stream; - shm->samplepos += len / (shm->samplebits / 8); - // Check for samplepos overflow? - S_PaintChannels (shm->samplepos); - } -} - -qboolean -SNDDMA_Init (void) -{ - SDL_AudioSpec desired, obtained; - - snd_inited = 0; - - /* Set up the desired format */ - desired.freq = desired_speed; - switch (desired_bits) { - case 8: - desired.format = AUDIO_U8; - break; - case 16: - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) - desired.format = AUDIO_S16MSB; - else - desired.format = AUDIO_S16LSB; - break; - default: - Con_Printf ("Unknown number of audio bits: %d\n", desired_bits); - return 0; - } - desired.channels = 2; - desired.samples = 512; - desired.callback = paint_audio; - - /* Open the audio device */ - if (SDL_OpenAudio (&desired, &obtained) < 0) { - Con_Printf ("Couldn't open SDL audio: %s\n", SDL_GetError ()); - return 0; - } - - /* Make sure we can support the audio format */ - switch (obtained.format) { - case AUDIO_U8: - /* Supported */ - break; - case AUDIO_S16LSB: - case AUDIO_S16MSB: - if (((obtained.format == AUDIO_S16LSB) && - (SDL_BYTEORDER == SDL_LIL_ENDIAN)) || - ((obtained.format == AUDIO_S16MSB) && - (SDL_BYTEORDER == SDL_BIG_ENDIAN))) { - /* Supported */ - break; - } - /* Unsupported, fall through */ ; - default: - /* Not supported -- force SDL to do our bidding */ - SDL_CloseAudio (); - if (SDL_OpenAudio (&desired, NULL) < 0) { - Con_Printf ("Couldn't open SDL audio: %s\n", SDL_GetError ()); - return 0; - } - memcpy (&obtained, &desired, sizeof (desired)); - break; - } - SDL_PauseAudio (0); - - /* Fill the audio DMA information block */ - shm = &the_shm; - shm->splitbuffer = 0; - shm->samplebits = (obtained.format & 0xFF); - shm->speed = obtained.freq; - shm->channels = obtained.channels; - shm->samples = obtained.samples * shm->channels; - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = NULL; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - SDL_CloseAudio (); - snd_inited = 0; - } -} - -/* - - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer - -*/ -void -SNDDMA_Submit (void) -{ -} diff --git a/qw/source/snd_sgi.c b/qw/source/snd_sgi.c deleted file mode 100644 index 789388761..000000000 --- a/qw/source/snd_sgi.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - snd_sgi.c - - sound support for sgi - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#include "QF/console.h" -#include "QF/qtypes.h" -#include "QF/qargs.h" -#include "sound.h" - -static int snd_inited = 0; -static ALconfig alc; -static ALport alp; - -static int tryrates[] = { 11025, 22050, 44100, 8000 }; - -static unsigned char *dma_buffer, *write_buffer; -static int bufsize; -static int wbufp; -static int framecount; - -qboolean -SNDDMA_Init (void) -{ - ALpv alpv; - int i; - char *s; - - alc = alNewConfig (); - - if (!alc) { - Con_Printf ("Could not make an new sound config: %s\n", - alGetErrorString (oserror ())); - return 0; - } - - shm = &sn; - shm->splitbuffer = 0; - - /* get & probe settings */ - /* sample format */ - if (alSetSampFmt (alc, AL_SAMPFMT_TWOSCOMP) < 0) { - Con_Printf ("Could not sample format of default output to two's " - "complement\n"); - alFreeConfig (alc); - return 0; - } - - /* sample bits */ - s = getenv ("QUAKE_SOUND_SAMPLEBITS"); - if (s) - shm->samplebits = atoi (s); - else if ((i = COM_CheckParm ("-sndbits")) != 0) - shm->samplebits = atoi (com_argv[i + 1]); - - if (shm->samplebits != 16 && shm->samplebits != 8) { - alpv.param = AL_WORDSIZE; - - if (alGetParams (AL_DEFAULT_OUTPUT, &alpv, 1) < 0) { - Con_Printf ("Could not get supported wordsize of default " - "output: %s\n", alGetErrorString (oserror ())); - return 0; - } - - if (alpv.value.i >= 16) { - shm->samplebits = 16; - } else { - if (alpv.value.i >= 8) - shm->samplebits = 8; - else { - Con_Printf ("Sound disabled since interface " - "doesn't even support 8 bit."); - alFreeConfig (alc); - return 0; - } - } - } - - /* sample rate */ - s = getenv ("QUAKE_SOUND_SPEED"); - if (s) - shm->speed = atoi (s); - else if ((i = COM_CheckParm ("-sndspeed")) != 0) - shm->speed = atoi (com_argv[i + 1]); - else { - alpv.param = AL_RATE; - - for (i = 0; i < sizeof (tryrates) / sizeof (int); i++) { - alpv.value.ll = alDoubleToFixed (tryrates[i]); - - if (alSetParams (AL_DEFAULT_OUTPUT, &alpv, 1) >= 0) - break; - } - - if (i >= sizeof (tryrates) / sizeof (int)) { - Con_Printf ("Sound disabled since interface doesn't even " - "support a sample rate of %d\n", tryrates[i - 1]); - alFreeConfig (alc); - return 0; - } - - shm->speed = tryrates[i]; - } - - /* channels */ - s = getenv ("QUAKE_SOUND_CHANNELS"); - if (s) - shm->channels = atoi (s); - else if ((i = COM_CheckParm ("-sndmono")) != 0) - shm->channels = 1; - else if ((i = COM_CheckParm ("-sndstereo")) != 0) - shm->channels = 2; - else - shm->channels = 2; - - /* set 'em */ - - /* channels */ - while (shm->channels > 0) { - if (alSetChannels (alc, shm->channels) < 0) { - Con_Printf ("Unable to set number of channels to %d, trying half\n", - shm->channels); - shm->channels /= 2; - } else - break; - } - - if (shm->channels <= 0) { - Con_Printf ("Sound disabled since interface doesn't even support 1 " - "channel\n"); - alFreeConfig (alc); - return 0; - } - - /* sample rate */ - alpv.param = AL_RATE; - alpv.value.ll = alDoubleToFixed (shm->speed); - - if (alSetParams (AL_DEFAULT_OUTPUT, &alpv, 1) < 0) { - Con_Printf ("Could not set samplerate of default output to %d: %s\n", - shm->speed, alGetErrorString (oserror ())); - alFreeConfig (alc); - return 0; - } - - /* set sizes of buffers relative to sizes of those for ** the 'standard' - frequency of 11025 ** ** use *huge* buffers since at least my indigo2 - has enough ** to do to get sound on the way anyway */ - bufsize = 32768 * (int) ((double) shm->speed / 11025.0); - - dma_buffer = malloc (bufsize); - - if (dma_buffer == NULL) { - Con_Printf ("Could not get %d bytes of memory for audio dma buffer\n", - bufsize); - alFreeConfig (alc); - return 0; - } - - write_buffer = malloc (bufsize); - - if (write_buffer == NULL) { - Con_Printf ("Could not get %d bytes of memory for audio write buffer\n", - bufsize); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - /* sample bits */ - switch (shm->samplebits) { - case 24: - i = AL_SAMPLE_24; - break; - - case 16: - i = AL_SAMPLE_16; - break; - - default: - i = AL_SAMPLE_8; - break; - } - - if (alSetWidth (alc, i) < 0) { - Con_Printf ("Could not set wordsize of default output to %d: %s\n", - shm->samplebits, alGetErrorString (oserror ())); - free (write_buffer); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - alp = alOpenPort ("quakeforge", "w", alc); - - if (!alp) { - Con_Printf ("Could not open sound port: %s\n", - alGetErrorString (oserror ())); - free (write_buffer); - free (dma_buffer); - alFreeConfig (alc); - return 0; - } - - shm->soundalive = true; - shm->samples = bufsize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = dma_buffer; - - framecount = 0; - - snd_inited = 1; - return 1; -} - -int -SNDDMA_GetDMAPos (void) -{ - /* Con_Printf("framecount: %d %d\n", (framecount * shm->channels) % - shm->samples, alGetFilled(alp)); */ - shm->samplepos = ((framecount - alGetFilled (alp)) - * shm->channels) % shm->samples; - return shm->samplepos; -} - -void -SNDDMA_Shutdown (void) -{ - if (snd_inited) { - free (write_buffer); - free (dma_buffer); - alClosePort (alp); - alFreeConfig (alc); - snd_inited = 0; - } -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - int bsize; - int bytes, b; - unsigned char *p; - int idx; - int stop = paintedtime; - - if (paintedtime < wbufp) - wbufp = 0; // reset - - bsize = shm->channels * (shm->samplebits / 8); - bytes = (paintedtime - wbufp) * bsize; - - if (!bytes) - return; - - if (bytes > bufsize) { - bytes = bufsize; - stop = wbufp + bytes / bsize; - } - - p = write_buffer; - idx = (wbufp * bsize) & (bufsize - 1); - - for (b = bytes; b; b--) { - *p++ = dma_buffer[idx]; - idx = (idx + 1) & (bufsize - 1); - } - - wbufp = stop; - - alWriteFrames (alp, write_buffer, bytes / bsize); - framecount += bytes / bsize; -} - -/* end of file */ diff --git a/qw/source/snd_sun.c b/qw/source/snd_sun.c deleted file mode 100644 index 2a2602b65..000000000 --- a/qw/source/snd_sun.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - snd_sun.c - - (description) - - Copyright (C) 1996-1997 Id Software, Inc. - Copyright (C) 1999,2000 contributors of the QuakeForge project - Please see the file "AUTHORS" for a list of contributors - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "QF/qtypes.h" -#include "sound.h" -#include "QF/qargs.h" -#include "QF/console.h" - -int audio_fd; -int snd_inited; - -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; - -qboolean -SNDDMA_Init (void) -{ - if (snd_inited) { - printf ("Sound already init'd\n"); - return 0; - } - - 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 bsize; - int bytes, b; - static unsigned char writebuf[1024]; - unsigned char *p; - int idx; - int stop = paintedtime; - - 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"); - -} diff --git a/qw/source/snd_win.c b/qw/source/snd_win.c deleted file mode 100644 index 1b2bb086f..000000000 --- a/qw/source/snd_win.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - snd_win.c - - (description) - - 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: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - - $Id$ -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#define CINTERFACE - -#include "winquake.h" -#include "QF/qargs.h" -#include "QF/console.h" -#include "sound.h" - -#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) - -HRESULT (WINAPI * pDirectSoundCreate) (GUID FAR * lpGUID, - LPDIRECTSOUND FAR * lplpDS, - IUnknown FAR * pUnkOuter); - -// 64K is > 1 second at 16-bit, 22050 Hz -#define WAV_BUFFERS 64 -#define WAV_MASK 0x3F -#define WAV_BUFFER_SIZE 0x0400 -#define SECONDARY_BUFFER_SIZE 0x10000 - -typedef enum { SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL } sndinitstat; - -static qboolean wavonly; -static qboolean dsound_init; -static qboolean wav_init; -static qboolean snd_firsttime = true, snd_isdirect, snd_iswave; -static qboolean primary_format_set; - -static int sample16; -static int snd_sent, snd_completed; - -/* - * Global variables. Must be visible to window-procedure function - * so it can unlock and free the data block after it has been played. - */ - -HANDLE hData; -HPSTR lpData, lpData2; - -HGLOBAL hWaveHdr; -LPWAVEHDR lpWaveHdr; - -HWAVEOUT hWaveOut; - -WAVEOUTCAPS wavecaps; - -DWORD gSndBufSize; - -MMTIME mmstarttime; - -LPDIRECTSOUND pDS; -LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; - -HINSTANCE hInstDS; - -sndinitstat SNDDMA_InitDirect (void); -qboolean SNDDMA_InitWav (void); - - -/* - S_BlockSound -*/ -void -S_BlockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) { - snd_blocked++; - - if (snd_blocked == 1) - waveOutReset (hWaveOut); - } -} - - -/* - S_UnblockSound -*/ -void -S_UnblockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) { - snd_blocked--; - } -} - - -/* - FreeSound -*/ -void -FreeSound (void) -{ - int i; - - if (pDSBuf) { - IDirectSoundBuffer_Stop (pDSBuf); - IDirectSound_Release (pDSBuf); - } -// only release primary buffer if it's not also the mixing buffer we just released - if (pDSPBuf && (pDSBuf != pDSPBuf)) { - IDirectSound_Release (pDSPBuf); - } - - if (pDS) { - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); - IDirectSound_Release (pDS); - } - - if (hWaveOut) { - waveOutReset (hWaveOut); - - if (lpWaveHdr) { - for (i = 0; i < WAV_BUFFERS; i++) - waveOutUnprepareHeader (hWaveOut, lpWaveHdr + i, - sizeof (WAVEHDR)); - } - - waveOutClose (hWaveOut); - - if (hWaveHdr) { - GlobalUnlock (hWaveHdr); - GlobalFree (hWaveHdr); - } - - if (hData) { - GlobalUnlock (hData); - GlobalFree (hData); - } - - } - - pDS = NULL; - pDSBuf = NULL; - pDSPBuf = NULL; - hWaveOut = 0; - hData = 0; - hWaveHdr = 0; - lpData = NULL; - lpWaveHdr = NULL; - dsound_init = false; - wav_init = false; -} - - -/* - SNDDMA_InitDirect - - Direct-Sound support -*/ -sndinitstat SNDDMA_InitDirect (void) -{ - DSBUFFERDESC dsbuf; - DSBCAPS dsbcaps; - DWORD dwSize, dwWrite; - DSCAPS dscaps; - WAVEFORMATEX format, pformat; - HRESULT hresult; - int reps; - - memset ((void *) &sn, 0, sizeof (sn)); - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - shm->speed = 11025; - - memset (&format, 0, sizeof (format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - if (!hInstDS) { - hInstDS = LoadLibrary ("dsound.dll"); - - if (hInstDS == NULL) { - Con_Printf ("Couldn't load dsound.dll\n"); - return SIS_FAILURE; - } - - pDirectSoundCreate = - (void *) GetProcAddress (hInstDS, "DirectSoundCreate"); - - if (!pDirectSoundCreate) { - Con_Printf ("Couldn't get DS proc addr\n"); - return SIS_FAILURE; - } - } - - while ((hresult = iDirectSoundCreate (NULL, &pDS, NULL)) != DS_OK) { - if (hresult != DSERR_ALLOCATED) { - Con_Printf ("DirectSound create failed\n"); - return SIS_FAILURE; - } - Con_Printf ("DirectSoundCreate failure\n" - " hardware already in use\n"); - return SIS_NOTAVAIL; - } - - dscaps.dwSize = sizeof (dscaps); - if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { - Con_Printf ("Couldn't get DS caps\n"); - } - - if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { - Con_Printf ("No DirectSound driver installed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { - Con_Printf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } -// get access to the primary buffer, if possible, so we can set the -// sound hardware format - memset (&dsbuf, 0, sizeof (dsbuf)); - dsbuf.dwSize = sizeof (DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; - dsbuf.dwBufferBytes = 0; - dsbuf.lpwfxFormat = NULL; - - memset (&dsbcaps, 0, sizeof (dsbcaps)); - dsbcaps.dwSize = sizeof (dsbcaps); - primary_format_set = false; - - if (!COM_CheckParm ("-snoforceformat")) { - if (DS_OK == - IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL)) { - pformat = format; - - if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) { - } else - primary_format_set = true; - } - } - - if (!primary_format_set || !COM_CheckParm ("-primarysound")) { - // create the secondary buffer we'll actually work with - memset (&dsbuf, 0, sizeof (dsbuf)); - dsbuf.dwSize = sizeof (DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; - dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; - dsbuf.lpwfxFormat = &format; - - memset (&dsbcaps, 0, sizeof (dsbcaps)); - dsbcaps.dwSize = sizeof (dsbcaps); - - if (DS_OK != - IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSBuf, NULL)) { - Con_Printf ("DS:CreateSoundBuffer Failed"); - FreeSound (); - return SIS_FAILURE; - } - - shm->channels = format.nChannels; - shm->samplebits = format.wBitsPerSample; - shm->speed = format.nSamplesPerSec; - - if (DS_OK != IDirectSound_GetCaps (pDSBuf, &dsbcaps)) { - Con_Printf ("DS:GetCaps failed\n"); - FreeSound (); - return SIS_FAILURE; - } - } else { - if (DS_OK != - IDirectSound_SetCooperativeLevel (pDS, mainwindow, - DSSCL_WRITEPRIMARY)) { - Con_Printf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != IDirectSound_GetCaps (pDSPBuf, &dsbcaps)) { - Con_Printf ("DS:GetCaps failed\n"); - return SIS_FAILURE; - } - - pDSBuf = pDSPBuf; - } - - // Make sure mixer is active - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - gSndBufSize = dsbcaps.dwBufferBytes; - -// initialize the buffer - reps = 0; - - while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, - (LPVOID *) & lpData, &dwSize, - NULL, NULL, 0)) != DS_OK) { - if (hresult != DSERR_BUFFERLOST) { - Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (++reps > 10000) { - Con_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); - FreeSound (); - return SIS_FAILURE; - } - - } - - memset (lpData, 0, dwSize); -// lpData[4] = lpData[5] = 0x7f; // force a pop for debugging - - IDirectSoundBuffer_Unlock (pDSBuf, lpData, dwSize, NULL, 0); - - /* we don't want anyone to access the buffer directly w/o locking it - first. */ - lpData = NULL; - - IDirectSoundBuffer_Stop (pDSBuf); - IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmstarttime.u.sample, - &dwWrite); - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - shm->soundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits / 8) - 1; - - dsound_init = true; - - return SIS_SUCCESS; -} - - -/* - SNDDM_InitWav - - Crappy windows multimedia base -*/ -qboolean -SNDDMA_InitWav (void) -{ - WAVEFORMATEX format; - int i; - HRESULT hr; - - snd_sent = 0; - snd_completed = 0; - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - shm->speed = 11025; - - memset (&format, 0, sizeof (format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - /* Open a waveform device for output using window callback. */ - while ((hr = waveOutOpen ((LPHWAVEOUT) & hWaveOut, WAVE_MAPPER, - &format, 0, 0L, - CALLBACK_NULL)) != MMSYSERR_NOERROR) { - if (hr != MMSYSERR_ALLOCATED) { - Con_Printf ("waveOutOpen failed\n"); - return false; - } - Con_Printf ("waveOutOpen failure;\n" " hardware already in use\n"); - return false; - } - - /* - * Allocate and lock memory for the waveform data. The memory - * for waveform data must be globally allocated with - * GMEM_MOVEABLE and GMEM_SHARE flags. - - */ - gSndBufSize = WAV_BUFFERS * WAV_BUFFER_SIZE; - hData = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); - if (!hData) { - Con_Printf ("Sound: Out of memory.\n"); - FreeSound (); - return false; - } - lpData = GlobalLock (hData); - if (!lpData) { - Con_Printf ("Sound: Failed to lock.\n"); - FreeSound (); - return false; - } - memset (lpData, 0, gSndBufSize); - - /* - * Allocate and lock memory for the header. This memory must - * also be globally allocated with GMEM_MOVEABLE and - * GMEM_SHARE flags. - */ - hWaveHdr = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, - (DWORD) sizeof (WAVEHDR) * WAV_BUFFERS); - - if (hWaveHdr == NULL) { - Con_Printf ("Sound: Failed to Alloc header.\n"); - FreeSound (); - return false; - } - - lpWaveHdr = (LPWAVEHDR) GlobalLock (hWaveHdr); - - if (lpWaveHdr == NULL) { - Con_Printf ("Sound: Failed to lock header.\n"); - FreeSound (); - return false; - } - - memset (lpWaveHdr, 0, sizeof (WAVEHDR) * WAV_BUFFERS); - - /* After allocation, set up and prepare headers. */ - for (i = 0; i < WAV_BUFFERS; i++) { - lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE; - lpWaveHdr[i].lpData = lpData + i * WAV_BUFFER_SIZE; - - if (waveOutPrepareHeader (hWaveOut, lpWaveHdr + i, sizeof (WAVEHDR)) != - MMSYSERR_NOERROR) { - Con_Printf ("Sound: failed to prepare wave headers\n"); - FreeSound (); - return false; - } - } - - shm->soundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize / (shm->samplebits / 8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits / 8) - 1; - - wav_init = true; - - return true; -} - -/* - SNDDMA_Init - - Try to find a sound device to mix for. - Returns false if nothing is found. -*/ - -qboolean -SNDDMA_Init (void) -{ - sndinitstat stat; - - if (COM_CheckParm ("-wavonly")) - wavonly = true; - - dsound_init = wav_init = 0; - - stat = SIS_FAILURE; // assume DirectSound won't - // initialize - - /* Init DirectSound */ - if (!wavonly) { - if (snd_firsttime || snd_isdirect) { - stat = SNDDMA_InitDirect ();; - - if (stat == SIS_SUCCESS) { - snd_isdirect = true; - - if (snd_firsttime) - Con_Printf ("DirectSound initialized\n"); - } else { - snd_isdirect = false; - Con_Printf ("DirectSound failed to init\n"); - } - } - } -// if DirectSound didn't succeed in initializing, try to initialize -// waveOut sound, unless DirectSound failed because the hardware is -// already allocated (in which case the user has already chosen not -// to have sound) - if (!dsound_init && (stat != SIS_NOTAVAIL)) { - if (snd_firsttime || snd_iswave) { - - snd_iswave = SNDDMA_InitWav (); - - if (snd_iswave) { - if (snd_firsttime) - Con_Printf ("Wave sound initialized\n"); - } else { - Con_Printf ("Wave sound failed to init\n"); - } - } - } - - snd_firsttime = false; - - if (!dsound_init && !wav_init) { - if (snd_firsttime) - Con_Printf ("No sound device initialized\n"); - - return 0; - } - - return 1; -} - -/* - SNDDMA_GetDMAPos - - return the current sample position (in mono samples read) - inside the recirculating dma buffer, so the mixing code will know - how many sample are required to fill it up. -*/ -int -SNDDMA_GetDMAPos (void) -{ - MMTIME mmtime; - int s = 0; - DWORD dwWrite; - - if (dsound_init) { - mmtime.wType = TIME_SAMPLES; - IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmtime.u.sample, - &dwWrite); - s = mmtime.u.sample - mmstarttime.u.sample; - } else if (wav_init) { - s = snd_sent * WAV_BUFFER_SIZE; - } - - - s >>= sample16; - - s &= (shm->samples - 1); - - return s; -} - -/* - SNDDMA_Submit - - Send sound to device if buffer isn't really the dma buffer -*/ -void -SNDDMA_Submit (void) -{ - LPWAVEHDR h; - int wResult; - - if (!wav_init) - return; - - // - // find which sound blocks have completed - // - while (1) { - if (snd_completed == snd_sent) { - Con_DPrintf ("Sound overrun\n"); - break; - } - - if (!(lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE)) { - break; - } - - snd_completed++; // this buffer has been played - } - - // - // submit two new sound blocks - // - while (((snd_sent - snd_completed) >> sample16) < 4) { - h = lpWaveHdr + (snd_sent & WAV_MASK); - - snd_sent++; - /* - * Now the data block can be sent to the output device. The - * waveOutWrite function returns immediately and waveform - * data is sent to the output device in the background. - */ - wResult = waveOutWrite (hWaveOut, h, sizeof (WAVEHDR)); - - if (wResult != MMSYSERR_NOERROR) { - Con_Printf ("Failed to write block to device\n"); - FreeSound (); - return; - } - } -} - -/* - SNDDMA_Shutdown - - Reset the sound device for exiting -*/ -void -SNDDMA_Shutdown (void) -{ - FreeSound (); -} - -DWORD * -DSOUND_LockBuffer (qboolean lockit) -{ - int reps; - - static DWORD dwSize; - static DWORD dwSize2; - static DWORD *pbuf1; - static DWORD *pbuf2; - HRESULT hresult; - - if (!pDSBuf) - return NULL; - - if (lockit) { - reps = 0; - while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, - (LPVOID *) & pbuf1, &dwSize, - (LPVOID *) & pbuf2, &dwSize2, - 0)) != DS_OK) { - if (hresult != DSERR_BUFFERLOST) { - Con_Printf - ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); - S_Shutdown (); - S_Startup (); - return NULL; - } - - if (++reps > 10000) { - Con_Printf - ("S_TransferStereo16: DS: couldn't restore buffer\n"); - S_Shutdown (); - S_Startup (); - return NULL; - } - } - } else { - IDirectSoundBuffer_Unlock (pDSBuf, pbuf1, dwSize, NULL, 0); - pbuf1 = NULL; - pbuf2 = NULL; - dwSize = 0; - dwSize2 = 0; - } - return (pbuf1); -} - -void -DSOUND_ClearBuffer (int clear) -{ - DWORD *pData; - -// FIXME: this should be called with 2nd pbuf2 = NULL, dwsize =0 - pData = DSOUND_LockBuffer (true); - memset (pData, clear, shm->samples * shm->samplebits / 8); - DSOUND_LockBuffer (false); -} - -void -DSOUND_Restore (void) -{ -// if the buffer was lost or stopped, restore it and/or restart it - DWORD dwStatus; - - if (!pDSBuf) - return; - - if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DD_OK) - Con_Printf ("Couldn't get sound buffer status\n"); - - if (dwStatus & DSBSTATUS_BUFFERLOST) - IDirectSoundBuffer_Restore (pDSBuf); - - if (!(dwStatus & DSBSTATUS_PLAYING)) - IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); - - return; -}