From 9359f79732bb83c2bb421b49a8d04eb01b0222a0 Mon Sep 17 00:00:00 2001 From: taniwha Date: Tue, 17 Oct 2000 07:38:23 +0000 Subject: [PATCH] almost compiles on linux again. also bring in the latest and_alsa*.c from newtree git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@56 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 2 +- makefile | 2 +- snd_alsa.c => snd_alsa_0_5.c | 59 +++++- snd_alsa_0_6.c | 346 +++++++++++++++++++++++++++++++++++ 4 files changed, 397 insertions(+), 12 deletions(-) rename snd_alsa.c => snd_alsa_0_5.c (83%) create mode 100644 snd_alsa_0_6.c diff --git a/gl_rsurf.c b/gl_rsurf.c index 694d931a..81d3f848 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -387,7 +387,7 @@ void R_LightSurface(int *dlightbits, glpoly_t *polys, float *wvert) glpoly_t *p; for (a = 0;a < 8;a++) { - if (c = dlightbits[a]) + if ((c = dlightbits[a])) { for (b = 0;c && b < 32;b++) { diff --git a/makefile b/makefile index 4793ba1e..f73cde08 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -SND=snd_alsa.o +SND=snd_alsa_0_5.o OBJECTS= cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o cpu_noasm.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_refrag.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o net_vcr.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o OPTIMIZATIONS= -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations diff --git a/snd_alsa.c b/snd_alsa_0_5.c similarity index 83% rename from snd_alsa.c rename to snd_alsa_0_5.c index 3f957580..cf48cf40 100644 --- a/snd_alsa.c +++ b/snd_alsa_0_5.c @@ -33,8 +33,27 @@ #include "quakedef.h" -#include -#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#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 #ifndef MAP_FAILED @@ -42,7 +61,6 @@ #endif extern int soundtime; - static int snd_inited; static snd_pcm_t *pcm_handle; @@ -94,7 +112,7 @@ qboolean SNDDMA_Init(void) { int rc=0,i; char *err_msg=""; - int rate,format,bps,stereo,frag_size; + int rate=-1,format=-1,bps,stereo=-1,frag_size; unsigned int mask; mask = snd_cards_mask(); @@ -108,6 +126,27 @@ qboolean SNDDMA_Init(void) if ((i=COM_CheckParm("-snddev"))!=0) { dev=atoi(com_argv[i+1]); } + if ((i=COM_CheckParm("-sndbits")) != 0) { + i = atoi(com_argv[i+1]); + 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 ((i=COM_CheckParm("-sndspeed")) != 0) { + rate = atoi(com_argv[i+1]); + if (rate!=44100 && rate!=22050 && rate!=11025) { + Con_Printf("Error: invalid sample rate: %d\n", rate); + return 0; + } + } + if ((i=COM_CheckParm("-sndmono")) != 0) { + stereo=0; + } if (card==-1) { for (card=0; card=2) { + if (stereo && cinfo.max_voices>=2) { stereo=1; } else { stereo=0; diff --git a/snd_alsa_0_6.c b/snd_alsa_0_6.c new file mode 100644 index 00000000..1086db30 --- /dev/null +++ b/snd_alsa_0_6.c @@ -0,0 +1,346 @@ +/* + snd_alsa.c + + (description) + + 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 +#endif + +#include "quakedef.h" + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#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 + +#ifndef MAP_FAILED +# define MAP_FAILED ((void*)-1) +#endif + +extern int soundtime; +static int snd_inited; + +static snd_pcm_t *pcm_handle; +static snd_pcm_params_info_t cpinfo; +static snd_pcm_params_t params; +static snd_pcm_setup_t setup; +static snd_pcm_mmap_control_t *mmap_control = NULL; +static snd_pcm_mmap_status_t *mmap_status = NULL; +static char *mmap_data = NULL; +static int card=-1,dev=-1,subdev=-1;; + +//XXX ugh, not defined in asoundlib.h +int snd_pcm_mmap_status(snd_pcm_t *pcm, snd_pcm_mmap_status_t **status); +int snd_pcm_mmap_control(snd_pcm_t *pcm, snd_pcm_mmap_control_t **control); + +int check_card(int card) +{ + snd_ctl_t *handle; + snd_ctl_hw_info_t info; + int rc; + + if ((rc = snd_ctl_hw_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_hw_open_subdevice(&pcm_handle,card,dev,subdev, + SND_PCM_STREAM_PLAYBACK, + SND_PCM_NONBLOCK))==0) { + return 0; + } + } + } else { + if (dev>=0 && dev =2) { + stereo=1; + frame_size*=2; + } else { + stereo=0; + } + + memset(¶ms, 0, sizeof(params)); + //XXX can't support non-interleaved stereo + params.xfer_mode = stereo ? SND_PCM_XFER_INTERLEAVED + : SND_PCM_XFER_NONINTERLEAVED; + params.format.sfmt=format; + params.format.rate=rate; + params.format.channels=stereo+1; + params.start_mode = SND_PCM_START_EXPLICIT; + params.xrun_mode = SND_PCM_XRUN_NONE; + + params.buffer_size = (2<<16) / frame_size; + params.frag_size=frag_size; + params.avail_min = frag_size; + + params.xrun_max = 1024; + params.boundary = params.buffer_size; + + while (1) { + err_msg="audio params"; + if ((rc=snd_pcm_params(pcm_handle, ¶ms))<0) + goto error; + + memset(&setup, 0, sizeof(setup)); + err_msg="audio setup"; + if ((rc=snd_pcm_setup(pcm_handle, &setup))<0) + goto error; + if (setup.buffer_size == params.buffer_size) + break; + params.boundary = params.buffer_size = setup.buffer_size; + } + + err_msg="audio mmap"; + if ((rc=snd_pcm_mmap(pcm_handle, (void**)&mmap_data))<0) + goto error; + if ((rc=snd_pcm_mmap_status(pcm_handle, &mmap_status))<0) + goto error; + if ((rc=snd_pcm_mmap_control(pcm_handle, &mmap_control))<0) + goto error; + err_msg="audio prepare"; + if ((rc=snd_pcm_prepare(pcm_handle))<0) + goto error; + + shm=&sn; + memset((dma_t*)shm,0,sizeof(*shm)); + shm->splitbuffer = 0; + shm->channels=setup.format.channels; + shm->submission_chunk=frag_size; // don't mix less than this # + shm->samplepos=0; // in mono samples + shm->samplebits=setup.format.sfmt==SND_PCM_SFMT_S16_LE?16:8; + shm->samples=setup.buffer_size*shm->channels; // 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) +{ + size_t hw_ptr; + if (!snd_inited) return 0; + hw_ptr = mmap_status->hw_ptr; + //printf("%7d %7d\n", mmap_control->appl_ptr, hw_ptr); + hw_ptr *= shm->channels; + shm->samplepos = hw_ptr; + 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 rc; + + mmap_control->appl_ptr=mmap_status->hw_ptr+count; + switch (mmap_status->state) { + case SND_PCM_STATE_PREPARED: + if ((rc=snd_pcm_start(pcm_handle))<0) { + fprintf(stderr, "unable to start playback. %s\n", + snd_strerror(rc)); + exit(1); + } + break; + case SND_PCM_STATE_RUNNING: + break; + case SND_PCM_STATE_UNDERRUN: + printf("sound underrun\n"); + if ((rc=snd_pcm_prepare (pcm_handle))<0) { + fprintf(stderr, "underrun: playback channel prepare error. %s\n", + snd_strerror(rc)); + exit(1); + } + break; + } +} + -- 2.39.2