diff --git a/NEWS b/NEWS index 8745d59..1aacd5f 100644 --- a/NEWS +++ b/NEWS @@ -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) ----- diff --git a/configure.in b/configure.in index 9094a8a..a609632 100644 --- a/configure.in +++ b/configure.in @@ -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 + #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 + #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 - #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 - #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 diff --git a/docs/README.sound b/docs/README.sound new file mode 100644 index 0000000..40fc189 --- /dev/null +++ b/docs/README.sound @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index d7c97c8..8c1b782 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/gl_glx.c b/src/gl_glx.c index 7143aee..4ab200a 100644 --- a/src/gl_glx.c +++ b/src/gl_glx.c @@ -40,7 +40,6 @@ #include #include #include -/* #include */ #include #include #include @@ -66,10 +65,10 @@ #ifdef HAVE_XF86_DGA #include -#endif // HAVE_XF86_DGA +#endif /* HAVE_XF86_DGA */ #ifdef HAVE_XF86_VIDMODE #include -#endif // HAVE_XF86_VIDMODE +#endif /* HAVE_XF86_VIDMODE */ #ifdef HAVE_JOYSTICK #include @@ -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) { diff --git a/src/snd_alsa.c b/src/snd_alsa.c index e2e6bba..3a394e1 100644 --- a/src/snd_alsa.c +++ b/src/snd_alsa.c @@ -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 +#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 ; ivalue; - 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) { } diff --git a/src/snd_ao.c b/src/snd_ao.c index aa2c222..a4c2a14 100644 --- a/src/snd_ao.c +++ b/src/snd_ao.c @@ -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) { diff --git a/src/snd_dma.c b/src/snd_dma.c index ede0057..145ab7d 100644 --- a/src/snd_dma.c +++ b/src/snd_dma.c @@ -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 +#include +#include +#include + +#ifdef HAVE_DLOPEN +# include +#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 (); } diff --git a/src/snd_loc.h b/src/snd_loc.h index 41172a9..d0306f0 100644 --- a/src/snd_loc.h +++ b/src/snd_loc.h @@ -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, ...); +}; + //==================================================================== diff --git a/src/snd_oss.c b/src/snd_oss.c index 82fffbf..5115408 100644 --- a/src/snd_oss.c +++ b/src/snd_oss.c @@ -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 ; idma->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;