- Added pluggable sound architecture for runtime loading of

sound driver modules.
This commit is contained in:
Jamie Wilkinson 2004-03-15 02:25:43 +00:00
parent 97d7b9731e
commit f4a2cc9ca2
10 changed files with 533 additions and 421 deletions

6
NEWS
View file

@ -1,6 +1,12 @@
NEWS for quake2
===============
0.x (//04)
---
* Pluggable sound driver architecture, sound output drivers configurable
at runtime.
0.2.2 (25/02/04)
-----

View file

@ -4,7 +4,7 @@ dnl stick the revision info into the resulting configure script
AC_REVISION($Revision$) dnl
AC_PREREQ(2.50)
AC_INIT(quake2, 0.2.2, quake2-devel@lists.quakeforge.net)
AC_INIT(quake2, 0.2.3, quake2-devel@lists.quakeforge.net)
AC_CONFIG_AUX_DIR(.)
AC_CONFIG_SRCDIR(src/main.c)
AM_CONFIG_HEADER(config.h)
@ -323,8 +323,38 @@ dnl ------------------
OSS_CFLAGS=""
OSS_LIBS=""
AC_CHECK_LIB([ossaudio], [_oss_ioctl], [OSS_LIBS="-lossaudio"])
AC_CHECK_HEADERS([soundcard.h sys/soundcard.h])
AC_SUBST(OSS_CFLAGS)
AC_SUBST(OSS_LIBS)
if test "x$ac_cv_header_sys_soundcard_h" = "xyes"; then
AC_MSG_CHECKING(for AFMT_S16_NE in sys/soundcard.h)
AC_EGREP_CPP([QF_maGiC_VALUE],
[ #include <sys/soundcard.h>
#ifdef AFMT_S16_NE
QF_maGiC_VALUE
#endif ],
HAVE_AFMT_S16_NE=yes
AC_MSG_RESULT(yes)
,
AC_MSG_RESULT(no)
)
else if test "x$ac_cv_header_soundcard_h" = "xyes"; then
AC_MSG_CHECKING(for AFMT_S16_NE in soundcard.h)
AC_EGREP_CPP([QF_maGiC_VALUE],
[ #include <soundcard.h>
#ifdef AFMT_S16_NE
QF_maGiC_VALUE
#endif ],
HAVE_AFMT_S16_NE=yes
AC_MSG_RESULT(yes)
,
AC_MSG_RESULT(no)
)
fi
fi
AC_SUBST(HAVE_AFMT_S16_NE)
AM_CONDITIONAL(BUILD_OSS, test x = x)
SNDDRIVERS="$SNDDRIVERS snd_oss.la"
dnl ---------------
dnl Check for libao
@ -370,6 +400,7 @@ if test "x${ac_with_ao}" != xno ; then
AC_DEFINE(HAVE_AO, 1, [Define this if you have libao])
AC_SUBST(AO_LIBS)
AC_SUBST(AO_CFLAGS)
SNDDRIVERS="$SNDDRIVERS snd_ao.la"
else
dnl if we were explicitly told to use ao and it's not there
if test "x${ac_with_ao}" = xyes ; then
@ -384,7 +415,7 @@ if test "x${ac_with_ao}" != xno ; then
else
HAVE_AO=disabled
fi
AM_CONDITIONAL(USE_AO, test "x$HAVE_AO" = xyes)
AM_CONDITIONAL(BUILD_AO, test "x$HAVE_AO" = xyes)
dnl --------------
dnl Check for ALSA
@ -420,7 +451,7 @@ if test "x${ac_with_alsa}" != xno ; then
[$ALSA_LIBS])
dnl check the header
if test "x$HAVE_ALSA" = xmaybe ; then
AC_CHECK_HEADER(sys/asoundlib.h,
AC_CHECK_HEADER(alsa/asoundlib.h,
HAVE_ALSA=yes,
HAVE_ALSA=no
)
@ -430,6 +461,7 @@ if test "x${ac_with_alsa}" != xno ; then
AC_DEFINE(HAVE_ALSA, 1, [Define this if you have ALSA])
AC_SUBST(ALSA_CFLAGS)
AC_SUBST(ALSA_LIBS)
SNDDRIVERS="$SNDDRIVERS snd_alsa.la"
else
dnl if we were explicitly told to use alsa and it's not there
if test "x${ac_with_alsa}" = xyes ; then
@ -444,19 +476,8 @@ if test "x${ac_with_alsa}" != xno ; then
else
HAVE_ALSA=disabled
fi
AM_CONDITIONAL(USE_ALSA, test "x$HAVE_ALSA" = xyes)
AM_CONDITIONAL(BUILD_ALSA, test "x$HAVE_ALSA" = xyes)
dnl -----------------------
dnl Checks for header files
dnl -----------------------
#AC_PATH_X
#AC_HEADER_DIRENT
#AC_HEADER_STDC
dnl AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([ sys/soundcard.h ])
dnl -------------------------------------------------------------
dnl Checks for typedefs, structures, and compiler characteristics
dnl -------------------------------------------------------------
@ -478,34 +499,6 @@ AC_TRY_LINK(
AC_MSG_RESULT(no)
)
if test "x$ac_cv_header_sys_soundcard_h" = "xyes"; then
AC_MSG_CHECKING(for AFMT_S16_NE in sys/soundcard.h)
AC_EGREP_CPP([QF_maGiC_VALUE],
[ #include <sys/soundcard.h>
#ifdef AFMT_S16_NE
QF_maGiC_VALUE
#endif ],
HAVE_AFMT_S16_NE=yes
AC_MSG_RESULT(yes)
,
AC_MSG_RESULT(no)
)
else if test "x$ac_cv_header_soundcard_h" = "xyes"; then
AC_MSG_CHECKING(for AFMT_S16_NE in soundcard.h)
AC_EGREP_CPP([QF_maGiC_VALUE],
[ #include <soundcard.h>
#ifdef AFMT_S16_NE
QF_maGiC_VALUE
#endif ],
HAVE_AFMT_S16_NE=yes
AC_MSG_RESULT(yes)
,
AC_MSG_RESULT(no)
)
fi
fi
AC_SUBST(HAVE_AFMT_S16_NE)
dnl -----------------------------
dnl Checks for library functions.
dnl -----------------------------
@ -567,7 +560,7 @@ AC_ARG_ENABLE(opt,
AC_MSG_RESULT(no),
AC_MSG_RESULT(yes)
USE_OPT="yes"
OPT_CFLAGS="$OPT_CFLAGS -O2 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations"
OPT_CFLAGS="$OPT_CFLAGS -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations"
)
if test "x$USE_OPT" = "xyes"; then
case "${host}" in
@ -588,6 +581,11 @@ if test "x$USE_OPT" = "xyes"; then
*)
;;
esac
else
# kill off that fucking retarded -O2 that gets bunged in by default
temp_CFLAGS=`echo $CFLAGS | sed 's/O2/O0/g'`
CFLAGS="$temp_CFLAGS"
AC_MSG_WARN([[** Compiler optimisations switched off **]])
fi
AC_SUBST(OPT_CFLAGS)
@ -596,14 +594,15 @@ dnl Compiler warnings
dnl -----------------
WARN_CFLAGS=""
dnl USE_WARN=""
AC_MSG_CHECKING(whether to abort on compiler warnings)
AC_ARG_ENABLE(warn,
[ --disable-warn don't abort on compiler warnings ],
AC_MSG_RESULT(no),
AC_MSG_RESULT(yes)
dnl USE_WARN="yes"
#WARN_CFLAGS="$WARN_CFLAGS -W -Wall -Werror"
WARN_CFLAGS="$WARN_CFLAGS -Wall -Werror"
# -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings
# -Wpointer-arith -Wundef -Wmissing-declarations -Winline -Wconversion
)
AC_SUBST(WARN_CFLAGS)
@ -764,6 +763,7 @@ AM_CONDITIONAL(BUILD_TDFX, test "x$BUILD_TDFX" = xyes)
AM_CONDITIONAL(BUILD_SDLGL, test "x$BUILD_SDLGL" = xyes)
AC_SUBST(VID_REFS)
AC_SUBST(SNDDRIVERS)
dnl -----------------------------------------------------------
dnl Configuraton tests complete -- provide a summary of results
@ -795,6 +795,7 @@ AC_CONFIG_FILES([
AC_OUTPUT
VID_REFS=`echo $VID_REFS | sed -e 's/ref_//g' -e 's/\.la//g'`
SNDDRIVERS=`echo $SNDDRIVERS | sed -e 's/snd_//g' -e 's/\.la//g'`
AC_MSG_RESULT([
Quake2Forge $VERSION: Automatic configuration OK.
@ -834,7 +835,8 @@ AC_MSG_RESULT([ SDL: ............. $HAVE_SDL])
dnl AC_MSG_RESULT([ Framebuffer: ..... $HAVE_FB])
dnl AC_MSG_RESULT([ AAlib: ........... $HAVE_AA])
AC_MSG_RESULT([ Audio drivers:])
AC_MSG_RESULT([ Sound drivers: ..... ${SNDDRIVERS- none}])
AC_MSG_RESULT([ OSS .............. yes])
AC_MSG_RESULT([ ALSA ............. $HAVE_ALSA])
if test "x${ac_with_alsa}" = xyes ; then
if test "x${HAVE_ALSA}" != xyes ; then

38
docs/README.sound Normal file
View file

@ -0,0 +1,38 @@
Quake2Forge sound
=================
Quake2Forge supports several sound output APIs.
To set your sound output driver, set the snddriver cvar, like so:
quake2 +set snddriver oss
The currently supported list of drivers are:
oss -- OSS from Linux 2.4 and earlier, and some BSDs
alsa -- ALSA 0.9 from Linux 2.6 onwards
ao -- libao audio output library
Each driver uses the snddevice cvar in different ways:
oss uses the device node for the sound card, e.g. /dev/dsp
alsa uses the pcm name, e.g. default or plughw:0,0
ao uses the name of the backend, e.g. oss or alsa09
e.g.:
quake2 +set snddriver oss +set snddevice /dev/dsp
quake2 +set snddriver alsa +set snddevice default
quake2 +set snddriver ao +set snddevice oss
Unexpected behaviour can usually be attributed to a snddevice setting from
a previous snddriver.
The sound driver can be changed at run time from within the console by
setting the two cvars above and calling 'snd_restart':
]set snddriver ao
]set snddevice oss
]snd_restart

View file

@ -4,9 +4,10 @@ std_cflags = -pipe @WARN_CFLAGS@ @OPT_CFLAGS@
module_ldflags = -module -avoid-version -rpath $(pkglibdir)
bin_PROGRAMS = quake2
pkglib_LTLIBRARIES = @VID_REFS@
pkglib_LTLIBRARIES = @VID_REFS@ @SNDDRIVERS@
EXTRA_LTLIBRARIES = ref_soft.la ref_softx.la ref_softsdl.la \
ref_glx.la ref_sdlgl.la ref_tdfx.la
ref_glx.la ref_sdlgl.la ref_tdfx.la \
snd_oss.la snd_alsa.la snd_ao.la
# Common source files
REF_GL_COMMON = q_sh.c q_shared.c q_glob.c qgl.c \
@ -42,19 +43,7 @@ else
QUAKE2_ASM=
endif
if USE_ALSA
SOUND = cd.c snd_alsa.c snd_dma.c snd_mix.c snd_mem.c
else
if USE_AO
SOUND = cd.c snd_ao.c snd_dma.c snd_mix.c snd_mem.c
else
if BUILD_SDLQUAKE2
SOUND = cd_sdl.c snd_sdl.c snd_dma.c snd_mix.c snd_mem.c
else
SOUND = cd.c snd_oss.c snd_dma.c snd_mix.c snd_mem.c
endif
endif
endif
SOUND = cd.c snd_dma.c snd_mix.c snd_mem.c
quake2_SOURCES = main.c q_sh.c vid_menu.c vid_so.c q_glob.c net_udp.c \
\
@ -92,32 +81,31 @@ EXTRA_quake2_SOURCES = snd_mixa.S cd_sdl.c snd_sdl.c snd_dma.c \
snd_mix.c snd_mem.c cd.c \
snd_oss.c snd_ao.c snd_alsa.c
if USE_ALSA
quake2_CFLAGS = $(std_cflags) @ALSA_CFLAGS@
else
if USE_AO
quake2_CFLAGS = $(std_cflags) @AO_CFLAGS@
else
if BUILD_SDLQUAKE2
quake2_CFLAGS = $(std_cflags) @SDL_CFLAGS@
else
quake2_CFLAGS = $(std_cflags) @OSS_CFLAGS@
endif
endif
quake2_CFLAGS = $(std_cflags)
quake2_LDADD = @DL_LIBS@ @SYSTEM_LIBS@ -lm
# oss sound driver
if BUILD_OSS
snd_oss_la_SOURCES = snd_oss.c
snd_oss_la_CFLAGS = $(std_cflags) -fPIC @OSS_CFLAGS@
snd_oss_la_LIBADD = @OSS_LIBS@
snd_oss_la_LDFLAGS = $(module_ldflags)
endif
if USE_ALSA
quake2_LDADD = @DL_LIBS@ @ALSA_LIBS@ @SYSTEM_LIBS@ -lm
else
if USE_AO
quake2_LDADD = @DL_LIBS@ @AO_LIBS@ @SYSTEM_LIBS@ -lm
else
if BUILD_SDLQUAKE2
quake2_LDADD = @DL_LIBS@ @SDL_LIBS@ @SYSTEM_LIBS@ -lm
else
quake2_LDADD = @DL_LIBS@ @OSS_LIBS@ @SYSTEM_LIBS@ -lm
endif
# alsa sound driver
if BUILD_ALSA
snd_alsa_la_SOURCES = snd_alsa.c
snd_alsa_la_CFLAGS = $(std_cflags) -fPIC @ALSA_CFLAGS@
snd_alsa_la_LIBADD = @ALSA_LIBS@
snd_alsa_la_LDFLAGS = $(module_ldflags)
endif
# libao sound driver
if BUILD_AO
snd_ao_la_SOURCES = snd_ao.c
snd_ao_la_CFLAGS = $(std_cflags) -fPIC @AO_CFLAGS@
snd_ao_la_LIBADD = @AO_LIBS@
snd_ao_la_LDFLAGS = $(module_ldflags)
endif
# ref_glx

View file

@ -40,7 +40,6 @@
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
/* #include <sys/vt.h> */
#include <stdarg.h>
#include <stdio.h>
#include <signal.h>
@ -66,10 +65,10 @@
#ifdef HAVE_XF86_DGA
#include <X11/extensions/xf86dga.h>
#endif // HAVE_XF86_DGA
#endif /* HAVE_XF86_DGA */
#ifdef HAVE_XF86_VIDMODE
#include <X11/extensions/xf86vmode.h>
#endif // HAVE_XF86_VIDMODE
#endif /* HAVE_XF86_VIDMODE */
#ifdef HAVE_JOYSTICK
#include <sys/types.h>
@ -1051,7 +1050,7 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole
scrnum = DefaultScreen(dpy);
root = RootWindow(dpy, scrnum);
// Get video mode list
/* Get video mode list */
MajorVersion = MinorVersion = 0;
#ifdef HAVE_XF86_VIDMODE
if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
@ -1061,7 +1060,7 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole
MajorVersion, MinorVersion);
vidmode_ext = true;
}
#endif // HAVE_XF86_VIDMODE
#endif /* HAVE_XF86_VIDMODE */
visinfo = qglXChooseVisual(dpy, scrnum, attrib);
if (!visinfo) {

View file

@ -1,199 +1,190 @@
/*
snd_alsa.c
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
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_ALSA
#include <alsa/asoundlib.h>
#endif
#include "client.h"
#include "snd_loc.h"
#define snd_buf (dma.samples * 2)
static int snd_inited;
static char *buffer;
static int snd_inited;
static snd_pcm_t *playback_handle;
static snd_pcm_hw_params_t *hw_params;
static snd_pcm_t * pcm_handle;
static snd_pcm_hw_params_t * hw_params;
cvar_t *sndbits;
cvar_t *sndspeed;
cvar_t *sndchannels;
cvar_t *snddevice;
#define BUFFER_SIZE 4096
static int tryrates[] = { 44100, 22051, 11025, 8000 };
int tryrates[] = { 44100, 22051, 11025, 8000 };
qboolean SNDDMA_Init (void)
{
int i;
int err;
if (!snddevice) {
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
snddevice = Cvar_Get("snddevice", "default", CVAR_ARCHIVE);
}
/* sound info */
static struct sndinfo * si;
err = snd_pcm_open(&playback_handle, snddevice->string,
SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
Com_Printf("ALSA snd error, cannot open device %s (%s)\n",
snddevice->string,
snd_strerror(err));
return 0;
}
err = snd_pcm_hw_params_malloc(&hw_params);
if (err < 0) {
Com_Printf("ALSA snd error, cannot allocate hw params (%s)\n",
snd_strerror(err));
return 0;
}
err = snd_pcm_hw_params_any (playback_handle, hw_params);
if (err < 0) {
Com_Printf("ALSA snd error, cannot init hw params (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
err = snd_pcm_hw_params_set_access(playback_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
Com_Printf("ALSA snd error, cannot set access (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
dma.samplebits = sndbits->value;
if (dma.samplebits == 16 || dma.samplebits != 8) {
err = snd_pcm_hw_params_set_format(playback_handle, hw_params,
SND_PCM_FORMAT_S16_LE);
if (err < 0) {
Com_Printf("ALSA snd error, 16 bit sound not supported, trying 8\n");
dma.samplebits = 8;
}
}
if (dma.samplebits == 8) {
err = snd_pcm_hw_params_set_format(playback_handle, hw_params,
SND_PCM_FORMAT_U8);
}
if (err < 0) {
Com_Printf("ALSA snd error, cannot set sample format (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
qboolean SNDDMA_Init(struct sndinfo * s) {
int i;
int err;
dma.speed = (int)sndspeed->value;
if (!dma.speed) {
for (i=0 ; i<sizeof(tryrates)/4 ; i++) {
int test = tryrates[i];
err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params,
&test, 0);
if (err < 0) {
Com_Printf("ALSA snd error, cannot set sample rate %d (%s)\n",
tryrates[i], snd_strerror(err));
}
else {
dma.speed = test;
break;
}
}
}
if (!dma.speed) {
Com_Printf("ALSA snd error couldn't set rate.\n");
snd_pcm_hw_params_free(hw_params);
return 0;
}
if (snd_inited)
return 1;
dma.channels = (int)sndchannels->value;
if (dma.channels < 1 || dma.channels > 2)
dma.channels = 2;
err = snd_pcm_hw_params_set_channels(playback_handle,hw_params,dma.channels);
if (err < 0) {
Com_Printf("ALSA snd error couldn't set channels %d (%s).\n",
dma.channels, snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
err = snd_pcm_hw_params(playback_handle, hw_params);
if (err < 0) {
Com_Printf("ALSA snd error couldn't set params (%s).\n",snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
buffer=malloc(snd_buf);
memset(buffer, 0, snd_buf);
dma.samplepos = 0;
dma.submission_chunk = 1;
dma.buffer = buffer;
snd_inited = 1;
return 1;
}
int
SNDDMA_GetDMAPos (void)
{
if(snd_inited)
return dma.samplepos;
else
Com_Printf ("Sound not inizialized\n");
return 0;
}
void
SNDDMA_Shutdown (void)
{
if (snd_inited) {
snd_pcm_close(playback_handle);
snd_inited = 0;
}
free(dma.buffer);
}
/*
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
*/
void
SNDDMA_Submit (void)
{
int written;
si = s;
si->dma->samples = 1024;
if ((err = snd_pcm_open(&pcm_handle, si->device->string,
SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
si->Com_Printf("ALSA snd error, cannot open device %s (%s)\n",
si->device->string,
snd_strerror(err));
return 0;
}
if(!snd_inited)
return;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
si->Com_Printf("ALSA snd error, cannot allocate hw params (%s)\n",
snd_strerror(err));
return 0;
}
written = snd_pcm_writei(playback_handle, dma.buffer, snd_buf);
dma.samplepos+=(written / (dma.samplebits / 8));
if ((err = snd_pcm_hw_params_any(pcm_handle, hw_params)) < 0) {
si->Com_Printf("ALSA snd error, cannot init hw params (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
if ((err = snd_pcm_hw_params_set_access(pcm_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
si->Com_Printf("ALSA snd error, cannot set access (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
si->dma->samplebits = si->bits->value;
if (si->dma->samplebits == 16 || si->dma->samplebits != 8) {
if ((err = snd_pcm_hw_params_set_format(pcm_handle, hw_params,
SND_PCM_FORMAT_S16_LE)) < 0) {
si->Com_Printf("ALSA snd error, 16 bit sound not supported, trying 8\n");
si->dma->samplebits = 8;
}
}
if (si->dma->samplebits == 8) {
if ((err = snd_pcm_hw_params_set_format(pcm_handle, hw_params,
SND_PCM_FORMAT_U8)) < 0) {
si->Com_Printf("ALSA snd error, cannot set sample format (%s)\n",
snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
}
si->dma->speed = (int)si->speed->value;
if (!si->dma->speed) {
for (i = 0; i < sizeof(tryrates); i++) {
int dir = 0;
int test = tryrates[i];
if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hw_params,
&test, &dir)) < 0) {
si->Com_Printf("ALSA snd error, cannot set sample rate %d (%s)\n",
tryrates[i], snd_strerror(err));
} else {
si->dma->speed = test;
if (dir != 0) {
si->Com_Printf("alsa: The rate %d Hz is not supported by your hardware, using %d Hz instead.\n", test, err);
}
break;
}
}
}
if (!si->dma->speed) {
si->Com_Printf("ALSA snd error couldn't set rate.\n");
snd_pcm_hw_params_free(hw_params);
return 0;
}
si->dma->channels = (int)si->channels->value;
if (si->dma->channels < 1 || si->dma->channels > 2)
si->dma->channels = 2;
if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hw_params, si->dma->channels)) < 0) {
si->Com_Printf("ALSA snd error couldn't set channels %d (%s).\n",
si->dma->channels, snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
if ((err = snd_pcm_hw_params(pcm_handle, hw_params)) < 0) {
si->Com_Printf("ALSA snd error couldn't set params (%s).\n",snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
return 0;
}
si->dma->buffer = malloc(BUFFER_SIZE);
memset(si->dma->buffer, 0, BUFFER_SIZE);
si->dma->samplepos = 0;
si->dma->samples = BUFFER_SIZE / (si->dma->samplebits / 8);
si->dma->submission_chunk = 1;
si->Com_Printf("alsa: buffer size is %d, %d samples\n", BUFFER_SIZE, si->dma->samples);
snd_inited = 1;
return 1;
}
int SNDDMA_GetDMAPos(void) {
if (snd_inited)
return si->dma->samplepos;
else
si->Com_Printf("Sound not inizialized\n");
return 0;
}
void SNDDMA_Shutdown(void) {
if (snd_inited) {
snd_pcm_drop(pcm_handle);
snd_pcm_close(pcm_handle);
snd_inited = 0;
}
free(si->dma->buffer);
si->dma->buffer = NULL;
}
/* SNDDMA_Submit
* Send sound to device if buffer isn't really the dma buffer
*/
void SNDDMA_Submit(void) {
int written;
if(!snd_inited)
return;
if ((written = snd_pcm_writei(pcm_handle, si->dma->buffer, si->dma->samples * (si->dma->samplebits / 8))) < 0) {
snd_pcm_prepare(pcm_handle);
si->Com_Printf("alsa: buffer underrun\n");
}
si->dma->samplepos += written / (si->dma->samplebits / 8);
}
void SNDDMA_BeginPainting(void)
{
void SNDDMA_BeginPainting(void) {
}

View file

@ -33,103 +33,95 @@
static int snd_inited;
static int samplesize;
cvar_t * sndbits;
cvar_t * sndspeed;
cvar_t * sndchannels;
cvar_t * snddevice;
struct sndinfo * si;
ao_device * device;
/* SNDDMA_Init: initialises cycling through a DMA bufffer and returns
* information on it
*/
qboolean SNDDMA_Init(void) {
qboolean SNDDMA_Init(struct sndinfo * s) {
int driver_id;
ao_sample_format format;
ao_option * options = NULL;
if (!snddevice) {
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
}
if (snd_inited)
return 1;
snd_inited = 0;
si = s;
ao_initialize();
#if 1
if ((driver_id = ao_default_driver_id()) == -1) {
#else
if ((driver_id = ao_driver_id("wav")) == -1) {
#endif
Com_Printf("Couldn't find a default driver for sound output\n");
return 0;
if ((driver_id = ao_driver_id(si->device->string)) == -1) {
si->Com_Printf("ao: no driver %s found, trying default\n", si->device->string);
if ((driver_id = ao_default_driver_id()) == -1) {
Com_Printf("ao: no default driver found\n");
return 0;
}
}
/*ao_append_option(&options, "debug", "");*/
format.bits = dma.samplebits = sndbits->value;
format.rate = dma.speed = 44100;
format.channels = dma.channels = sndchannels->value;
format.bits = si->dma->samplebits = si->bits->value;
format.rate = si->dma->speed = 44100;
format.channels = si->dma->channels = si->channels->value;
format.byte_format = AO_FMT_NATIVE;
switch (dma.speed) {
switch (si->dma->speed) {
case 44100:
dma.samples = 2048 * dma.channels;
si->dma->samples = 2048 * si->dma->channels;
break;
case 22050:
dma.samples = 1024 * dma.channels;
si->dma->samples = 1024 * si->dma->channels;
break;
default:
dma.samples = 512 * dma.channels;
si->dma->samples = 512 * si->dma->channels;
break;
}
#if 1
if ((device = ao_open_live(driver_id, &format, options)) == NULL) {
#else
if ((device = ao_open_file(driver_id, "foo.wav", 1, &format, options)) == NULL) {
#endif
switch (errno) {
case AO_ENODRIVER:
Com_Printf("W: No ao driver for %d\n", driver_id);
Com_Printf("ao: no driver for %d\n", driver_id);
break;
case AO_ENOTLIVE:
Com_Printf("W: Not a valid live output device\n");
Com_Printf("ao: not a valid live output device\n");
break;
case AO_EBADOPTION:
Com_Printf("W: Valid option has invalid key\n");
Com_Printf("ao: valid option has invalid key\n");
break;
case AO_EOPENDEVICE:
Com_Printf("W: Cannot open device\n");
Com_Printf("ao: cannot open device\n");
break;
case AO_EFAIL:
Com_Printf("W: Something broke during ao_open_live\n");
Com_Printf("ao: something broke during ao_open_live\n");
break;
case AO_ENOTFILE:
Com_Printf("W: Not a file\n");
Com_Printf("ao: not a file\n");
break;
case AO_EOPENFILE:
Com_Printf("W: Can't open file\n");
Com_Printf("ao: can't open file\n");
break;
case AO_EFILEEXISTS:
Com_Printf("W: File exists already\n");
Com_Printf("ao: file exists already\n");
break;
default:
Com_Printf("W: whoa, bad trip dude\n");
Com_Printf("ao: whoa, bad trip dude\n");
break;
}
return 0;
}
samplesize = dma.samplebits >> 3;
dma.buffer = malloc(dma.samples * samplesize);
memset(dma.buffer, 0, dma.samples * samplesize);
samplesize = si->dma->samplebits >> 3;
si->dma->buffer = malloc(si->dma->samples * samplesize);
memset(si->dma->buffer, 0, si->dma->samples * samplesize);
si->dma->samplepos = 0;
si->dma->submission_chunk = 1;
si->Com_Printf("ao: buffer size is %d, %d samples\n", si->dma->samples * samplesize, si->dma->samples);
snd_inited = 1;
dma.samplepos = 0;
dma.submission_chunk = 1;
return 1;
}
@ -137,7 +129,7 @@ qboolean SNDDMA_Init(void) {
*/
int SNDDMA_GetDMAPos(void) {
if (snd_inited)
return dma.samplepos;
return si->dma->samplepos;
else
Com_Printf("Sound not initialised\n");
@ -150,8 +142,8 @@ void SNDDMA_Shutdown(void) {
if (snd_inited) {
ao_close(device);
ao_shutdown();
free(dma.buffer);
dma.buffer = 0;
free(si->dma->buffer);
si->dma->buffer = 0;
snd_inited = 0;
}
}
@ -164,14 +156,14 @@ void SNDDMA_Submit(void) {
/* ao_play returns success, not number of samples successfully output
* unlike alsa or arts, so we can only assume that the whole buffer
* made it out... though this makes updating dma.samplepos easy */
if (ao_play(device, dma.buffer, dma.samples * samplesize) == 0) {
* made it out... though this makes updating si->dma->samplepos easy */
if (ao_play(device, si->dma->buffer, si->dma->samples * samplesize) == 0) {
Com_Printf("W: error occurred while playing buffer\n");
ao_close(device);
ao_shutdown();
snd_inited = 0;
}
dma.samplepos += dma.samples;
si->dma->samplepos += si->dma->samples;
}
void SNDDMA_BeginPainting(void) {

View file

@ -21,6 +21,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#ifdef HAVE_DLOPEN
# include <dlfcn.h>
#endif
#include "client.h"
#include "snd_loc.h"
@ -80,11 +93,23 @@ cvar_t *s_khz;
cvar_t *s_show;
cvar_t *s_mixahead;
cvar_t *s_primary;
cvar_t * snddriver;
int s_rawend;
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
static void * snddriver_library = NULL;
qboolean snddriver_active = 0;
/* dlsymbols */
qboolean (*SNDDMA_Init)(struct sndinfo *);
int (*SNDDMA_GetDMAPos)(void);
void (*SNDDMA_Shutdown)(void);
void (*SNDDMA_BeginPainting)(void);
void (*SNDDMA_Submit)(void);
struct sndinfo si;
// ====================================================================
// User-setable variables
@ -99,7 +124,7 @@ void S_SoundInfo_f(void)
return;
}
Com_Printf("%5d stereo\n", dma.channels - 1);
Com_Printf("%5d channels\n", dma.channels);
Com_Printf("%5d samples\n", dma.samples);
Com_Printf("%5d samplepos\n", dma.samplepos);
Com_Printf("%5d samplebits\n", dma.samplebits);
@ -134,7 +159,51 @@ void S_Init (void)
s_testsound = Cvar_Get ("s_testsound", "0", 0);
s_primary = Cvar_Get ("s_primary", "0", CVAR_ARCHIVE); // win32 specific
if (!SNDDMA_Init())
{
char fn[MAX_OSPATH];
struct stat st;
/* load sound driver */
snddriver = Cvar_Get("snddriver", "oss", CVAR_ARCHIVE);
Com_Printf("loading %s sound output driver", snddriver->string);
snprintf(fn, MAX_OSPATH, PKGLIBDIR"/snd_%s.so", snddriver->string);
if (stat(fn, &st) == -1) {
Com_Printf("\nload %s failed: %s\n", fn, strerror(errno));
return;
}
if ((snddriver_library = dlopen(fn, RTLD_LAZY)) == 0) {
Com_Printf("\nload %s failed: %s\n", fn, dlerror());
return;
}
Com_Printf(", ok\n");
if ((SNDDMA_Init = dlsym(snddriver_library, "SNDDMA_Init")) == 0)
Com_Error(ERR_FATAL, "dlsym failed loading SNDDMA_Init\n");
if ((SNDDMA_Shutdown = dlsym(snddriver_library, "SNDDMA_Shutdown")) == 0)
Com_Error(ERR_FATAL, "dlsym failed loading SNDDMA_Shutdown\n");
if ((SNDDMA_GetDMAPos = dlsym(snddriver_library, "SNDDMA_GetDMAPos")) == 0)
Com_Error(ERR_FATAL, "dlsym failed loading SNDDMA_GetDMAPos\n");
if ((SNDDMA_BeginPainting = dlsym(snddriver_library, "SNDDMA_BeginPainting")) == 0)
Com_Error(ERR_FATAL, "dlsym failed loading SNDDMA_BeginPainting\n");
if ((SNDDMA_Submit = dlsym(snddriver_library, "SNDDMA_Submit")) == 0)
Com_Error(ERR_FATAL, "dlsym failed loading SNDDMA_Submit\n");
snddriver_active = true;
}
si.dma = &dma;
si.bits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
si.speed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
si.channels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
si.device = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
si.Com_Printf = Com_Printf;
if (!SNDDMA_Init(&si))
return;
Cmd_AddCommand("play", S_Play);
@ -191,6 +260,19 @@ void S_Shutdown(void)
}
num_sfx = 0;
if (snddriver_library) {
SNDDMA_Init = NULL;
SNDDMA_Shutdown = NULL;
SNDDMA_Submit = NULL;
SNDDMA_GetDMAPos = NULL;
SNDDMA_BeginPainting = NULL;
dlclose(snddriver_library);
memset(&si, 0, sizeof(struct sndinfo));
snddriver_library = NULL;
snddriver_active = false;
memset(&dma, 0, sizeof(dma_t));
}
}
@ -776,7 +858,8 @@ void S_ClearBuffer (void)
SNDDMA_BeginPainting ();
if (dma.buffer) {
/* buffer may be read-only, clear manually */
/* memset(dma.buffer, clear, dma.samples * dma.samplebits/8); */
memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
/*
int i;
unsigned char * ptr = (unsigned char *) dma.buffer;
@ -785,6 +868,7 @@ void S_ClearBuffer (void)
*ptr = clear;
ptr++;
}
*/
}
SNDDMA_Submit ();
}

View file

@ -122,18 +122,32 @@ typedef struct {
====================================================================
*/
#if 0
// initializes cycling through a DMA buffer and returns information on it
qboolean SNDDMA_Init(void);
/* qboolean SNDDMA_Init(void); */
// gets the current DMA position
int SNDDMA_GetDMAPos(void);
// shutdown the DMA xfer.
void SNDDMA_Shutdown(void);
/* void SNDDMA_Shutdown(void); */
void SNDDMA_BeginPainting (void);
void SNDDMA_Submit(void);
#endif
/* struct for passing info to the sound driver dlls */
struct sndinfo {
dma_t * dma;
cvar_t * bits;
cvar_t * speed;
cvar_t * channels;
cvar_t * device;
void (*Com_Printf)(char * fmt, ...);
};
//====================================================================

View file

@ -78,15 +78,13 @@ static int tryrates[] = { 11025, 22051, 44100, 48000, 8000 };
#endif
cvar_t *sndbits;
cvar_t *sndspeed;
cvar_t *sndchannels;
cvar_t *snddevice;
/* irix cvars -- jaq */
cvar_t * s_loadas8bit;
cvar_t * s_khz;
qboolean SNDDMA_Init(void) {
struct sndinfo * si;
qboolean SNDDMA_Init(struct sndinfo * s) {
/* merged in from snd_irix.c -- jaq */
#ifdef __sgi
ALconfig ac = NULL;
@ -94,54 +92,54 @@ qboolean SNDDMA_Init(void) {
s_loadas8bit = Cvar_Get("s_loadas8bit", "16", CVAR_ARCHIVE);
if ((int) s_loadas8bit->value)
dma.samplebits = 8;
si->dma->samplebits = 8;
else
dma.samplebits = 16;
si->dma->samplebits = 16;
if (dma.samplebits != 16) {
Com_Printf("Don't currently support %i-bit data. Forcing 16-bit\n", dma.samplebits);
dma.samplebits = 16;
if (si->dma->samplebits != 16) {
si->Com_Printf("Don't currently support %i-bit data. Forcing 16-bit\n", si->dma->samplebits);
si->dma->samplebits = 16;
Cvar_SetValue("s_loadas8bit", false);
}
s_khz = Cvar_Get("s_khz", "0", CVAR_ARCHIVE);
switch ((int) s_khz->value) {
case 48:
dma.speed = AL_RATE_48000;
si->dma->speed = AL_RATE_48000;
break;
case 44:
dma.speed = AL_RATE_44100;
si->dma->speed = AL_RATE_44100;
break;
case 32:
dma.speed = AL_RATE_32000;
si->dma->speed = AL_RATE_32000;
break;
case 22:
dma.speed = AL_RATE_22050;
si->dma->speed = AL_RATE_22050;
break;
case 16:
dma.speed = AL_RATE_16000;
si->dma->speed = AL_RATE_16000;
break;
case 11:
dma.speed = AL_RATE_11025;
si->dma->speed = AL_RATE_11025;
break;
case 8:
dma.speed = AL_RATE_8000;
si->dma->speed = AL_RATE_8000;
break;
default:
dma.speed = AL_RATE_22050;
Com_Printf("Don't currently support %ikHz sample rate, using %i.\n", (int) s_khz->value, (int) (dma.speed/1000));
si->dma->speed = AL_RATE_22050;
si->Com_Printf("Don't currently support %ikHz sample rate, using %i.\n", (int) s_khz->value, (int) (si->dma->speed/1000));
}
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
dma.channels = (int) sndchannels->value;
if (dma.channels != 2)
Com_Printf("Don't currently support %i sound channels, try 2.\n", dma.channels);
/* si->channels = Cvar_Get("s", "2", CVAR_ARCHIVE);*/
si->dma->channels = (int) si->channels->value;
if (si->dma->channels != 2)
si->Com_Printf("Don't currently support %i sound channels, try 2.\n", si->dma->channels);
ac = alNewConfig();
alSetChannels(ac, AL_STEREO);
alSetStampFmt(ac, AL_SAMPFMT_TWOSCOMP);
alSetQueueSize(ac, QSND_BUFFER_FRAMES);
if (dma.samplebits == 8)
if (si->dma->samplebits == 8)
alSetWidth(ac, AL_SAMPLE_8);
else
alSetWidth(ac, AL_SAMPLE_16);
@ -155,19 +153,19 @@ qboolean SNDDMA_Init(void) {
pvbuf[0].param = AL_MASTER_CLOCK;
pvbuf[0].value.i = AL_CRYSTAL_MCLK_TYPE;
pvbuf[1].param = AL_RATE;
pvbuf[1].value.ll = alIntToFixed(dma.speed);
pvbuf[1].value.ll = alIntToFixed(si->dma->speed);
alSetParams(alGetResource(sgisnd_aport), pvbuf, 2);
if (pvbuf[1].sizeOut < 0)
printf("illegal sample rate %d\n", dma.speed);
printf("illegal sample rate %d\n", si->dma->speed);
sgisnd_frames_per_ns = dma.speed * 1.0e-9;
sgisnd_frames_per_ns = si->dma->speed * 1.0e-9;
dma.samples = sizeof(dma_buffer) / (dma.samplebits / 8);
dma.submission_chunk = 1;
si->dma->samples = sizeof(dma_buffer) / (si->dma->samplebits / 8);
si->dma->submission_chunk = 1;
dma.buffer = (unsigned char *) dma_buffer;
si->dma->buffer = (unsigned char *) dma_buffer;
dma.samplepos = 0;
si->dma->samplepos = 0;
alFreeConfig(ac);
return true;
@ -178,37 +176,35 @@ qboolean SNDDMA_Init(void) {
int i;
struct audio_buf_info info;
int caps;
/*
extern uid_t saved_euid;
*/
if (snd_inited)
return 1;
snd_inited = 0;
if (!snddevice) {
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
}
si = s;
// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
/* snd_bsd.c had "if (!audio_fd)" */
if (audio_fd == -1)
{
seteuid(saved_euid);
/* seteuid(saved_euid);*/
audio_fd = open(snddevice->string, O_RDWR);
audio_fd = open(si->device->string, O_RDWR);
/* moved from below in snd_bsd.c -- jaq */
seteuid(getuid());
/*seteuid(getuid());*/
if (audio_fd == -1)
{
perror(snddevice->string);
seteuid(getuid());
Com_Printf("SNDDMA_Init: Could not open %s.\n", snddevice->string);
perror(si->device->string);
/*
seteuid(getuid());*/
si->Com_Printf("SNDDMA_Init: Could not open %s.\n", si->device->string);
return 0;
}
/*
@ -219,8 +215,8 @@ qboolean SNDDMA_Init(void) {
rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
if (rc == -1) /* snd_bsd has "rc < 0" */
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not reset %s.\n", snddevice->string);
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not reset %s.\n", si->device->string);
close(audio_fd);
audio_fd = -1;
return 0;
@ -228,8 +224,8 @@ qboolean SNDDMA_Init(void) {
if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Sound driver too old.\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Sound driver too old.\n");
close(audio_fd);
audio_fd = -1;
return 0;
@ -237,7 +233,7 @@ qboolean SNDDMA_Init(void) {
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
{
Com_Printf("SNDDMA_Init: Sorry, but your soundcard doesn't support trigger or mmap. (%08x)\n", caps);
si->Com_Printf("SNDDMA_Init: Sorry, but your soundcard doesn't support trigger or mmap. (%08x)\n", caps);
close(audio_fd);
audio_fd = -1;
return 0;
@ -246,7 +242,7 @@ qboolean SNDDMA_Init(void) {
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
{
perror("GETOSPACE");
Com_Printf("SNDDMA_Init: GETOSPACE ioctl failed.\n");
si->Com_Printf("SNDDMA_Init: GETOSPACE ioctl failed.\n");
close(audio_fd);
audio_fd = -1;
return 0;
@ -254,51 +250,51 @@ qboolean SNDDMA_Init(void) {
// set sample bits & speed
dma.samplebits = (int)sndbits->value;
if (dma.samplebits != 16 && dma.samplebits != 8) {
si->dma->samplebits = (int)si->bits->value;
if (si->dma->samplebits != 16 && si->dma->samplebits != 8) {
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
#ifdef HAVE_AFMT_S16_NE
if (fmt & AFMT_S16_NE)
#else
if (fmt & AFMT_S16_LE)
#endif
dma.samplebits = 16;
else if (fmt & AFMT_U8) dma.samplebits = 8;
si->dma->samplebits = 16;
else if (fmt & AFMT_U8) si->dma->samplebits = 8;
}
/* in relnev 0.9, from here until the next RELNEV 0.9 comment has been moved
* down to the following RELNEV 0.9 comment -- jaq */
dma.speed = (int)sndspeed->value;
if (!dma.speed) {
si->dma->speed = (int)si->speed->value;
if (!si->dma->speed) {
for (i=0 ; i<sizeof(tryrates)/4 ; i++)
if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i]))
break;
dma.speed = tryrates[i];
si->dma->speed = tryrates[i];
}
dma.channels = (int)sndchannels->value;
if (dma.channels < 1 || dma.channels > 2)
dma.channels = 2;
si->dma->channels = (int)si->channels->value;
if (si->dma->channels < 1 || si->dma->channels > 2)
si->dma->channels = 2;
tmp = 0;
if (dma.channels == 2)
if (si->dma->channels == 2)
tmp = 1;
rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
if (rc < 0)
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not set %s to stereo=%d.", snddevice->string, dma.channels);
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not set %s to stereo=%d.", si->device->string, si->dma->channels);
close(audio_fd);
audio_fd = -1;
return 0;
}
if (tmp)
dma.channels = 2;
si->dma->channels = 2;
else
dma.channels = 1;
si->dma->channels = 1;
/* RELNEV 0.9 end deletion */
if (dma.samplebits == 16)
if (si->dma->samplebits == 16)
{
#ifdef HAVE_AFMT_S16_NE
rc = AFMT_S16_NE;
@ -308,21 +304,21 @@ qboolean SNDDMA_Init(void) {
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0)
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not support 16-bit data. Try 8-bit.\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not support 16-bit data. Try 8-bit.\n");
close(audio_fd);
audio_fd = -1;
return 0;
}
}
else if (dma.samplebits == 8)
else if (si->dma->samplebits == 8)
{
rc = AFMT_U8;
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0)
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not support 8-bit data.\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not support 8-bit data.\n");
close(audio_fd);
audio_fd = -1;
return 0;
@ -330,8 +326,8 @@ qboolean SNDDMA_Init(void) {
}
else
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: %d-bit sound not supported.", dma.samplebits);
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: %d-bit sound not supported.", si->dma->samplebits);
close(audio_fd);
audio_fd = -1;
return 0;
@ -339,11 +335,11 @@ qboolean SNDDMA_Init(void) {
/* RELNEV 0.9 insert some here */
rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &si->dma->speed);
if (rc < 0)
{
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not set %s speed to %d.", snddevice->string, dma.speed);
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not set %s speed to %d.", si->device->string, si->dma->speed);
close(audio_fd);
audio_fd = -1;
return 0;
@ -355,13 +351,13 @@ qboolean SNDDMA_Init(void) {
tmp = 0;
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
dma.submission_chunk = 1;
si->dma->samples = info.fragstotal * info.fragsize / (si->dma->samplebits/8);
si->dma->submission_chunk = 1;
// memory map the dma buffer
if (!dma.buffer) {
dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal * info.fragsize,
if (!si->dma->buffer) {
si->dma->buffer = (unsigned char *) mmap(NULL, info.fragstotal * info.fragsize,
#if defined(__FreeBSD__) && (__FreeBSD_version < 500000)
PROT_READ|PROT_WRITE,
#else
@ -369,17 +365,17 @@ qboolean SNDDMA_Init(void) {
#endif
MAP_FILE|MAP_SHARED, audio_fd, 0);
}
if (!dma.buffer || dma.buffer == MAP_FAILED) {
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not mmap %s.\n", snddevice->string);
if (!si->dma->buffer || si->dma->buffer == MAP_FAILED) {
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not mmap %s.\n", si->device->string);
close(audio_fd);
audio_fd = -1;
return 0;
}
if (rc < 0) {
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not toggle. (1)\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not toggle. (1)\n");
close(audio_fd);
audio_fd = -1;
return 0;
@ -387,14 +383,16 @@ qboolean SNDDMA_Init(void) {
tmp = PCM_ENABLE_OUTPUT;
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("SNDDMA_Init: Could not toggle. (2)\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_Init: Could not toggle. (2)\n");
close(audio_fd);
audio_fd = -1;
return 0;
}
dma.samplepos = 0;
si->Com_Printf("oss: buffer size is %d, %d samples\n", info.fragstotal * info.fragsize, si->dma->samples);
si->dma->samplepos = 0;
snd_inited = 1;
return 1;
#endif /* !__sgi */
@ -428,18 +426,18 @@ int SNDDMA_GetDMAPos(void) {
if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
{
perror(snddevice->string);
Com_Printf("SNDDMA_GetDMAPos: GETOPTR failed.\n");
perror(si->device->string);
si->Com_Printf("SNDDMA_GetDMAPos: GETOPTR failed.\n");
close(audio_fd);
audio_fd = -1;
snd_inited = 0;
return 0;
}
// dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
// si->dma->samplepos = (count.bytes / (si->dma->samplebits / 8)) & (si->dma->samples-1);
// fprintf(stderr, "%d \r", count.ptr);
dma.samplepos = count.ptr / (dma.samplebits / 8);
si->dma->samplepos = count.ptr / (si->dma->samplebits / 8);
return dma.samplepos;
return si->dma->samplepos;
#endif /* __sgi */
}
@ -457,8 +455,8 @@ void SNDDMA_Shutdown(void) {
}
#else
if (snd_inited) {
munmap (dma.buffer, dma.samples *dma.samplebits / 8);
dma.buffer = 0L;
munmap (si->dma->buffer, si->dma->samples *si->dma->samplebits / 8);
si->dma->buffer = 0L;
close(audio_fd);
audio_fd = -1;
@ -492,7 +490,7 @@ void SNDDMA_Submit(void) {
nFillable = alGetFillable(sgisnd_aport);
nFilled = QSND_BUFFER_FRAMES - nFillable;
nFrames = dma.samples >> (dma.channels - 1);
nFrames = si->dma->samples >> (si->dma->channels - 1);
if (paintedtime - soundtime < nFrames)
nFrames = paintedtime - soundtime;
@ -516,8 +514,8 @@ void SNDDMA_Submit(void) {
/* account for stereo */
nFramesLeft = nFrames;
if (nPos + nFrames * dma.channels > QSND_BUFFER_SIZE) {
int nFramesAtEnd = (QSND_BUFFER_SIZE - nPos) >> (dma.channels - 1);
if (nPos + nFrames * si->dma->channels > QSND_BUFFER_SIZE) {
int nFramesAtEnd = (QSND_BUFFER_SIZE - nPos) >> (si->dma->channels - 1);
alWriteFrames(sgisnd_aport, &dma_buffer[nPos], nFramesAtEnd);
nPos = 0;