Hello, I'm trying to get the quake 1 source to compile and work under freebsd with glx. Most of the graphics parts work, and I can play, but I can't seem to get it to mmap the dsp dma buffer like it wants to. I have ripped out part of the code to demonstrate the problem. All I had to change to get it to compile this was to include machine/soundcard.h instead of linux/soundcard.h, but that doesn't seem to be enough to get it to work. I'm running -current with newpcm as of Dec 13, I know it's not the latest, but not much has changed in the dsp code lately. I'll build a new world tomorrow, and try it out. I have attached the files snd_linux.c & sound.h When I run snd_linux I get opening /dev/dsp audio_fd /dev/dsp=3 about to map 63488 bytes to /dev/dsp shm->buffer=280eb000 Segmentation fault (core dumped) bash-2.02$ gdb has this to say about shm->buffer (what mmap returns) $3 = ( unsigned char *) 0x280eb000 <Error reading address 0x280eb000: Bad address> Thanks, for any help. -Charlie -- Charles Anderson [EMAIL PROTECTED] No quote, no nothin'
/* Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/shm.h> #include <sys/wait.h> #include <machine/soundcard.h> #include <stdio.h> #include "sound.h" int audio_fd; int snd_inited; static int tryrates[] = { 11025, 22051, 44100, 8000 }; #define Con_Printf printf dma_t *shm; qboolean SNDDMA_Init(void) { dma_t sn; int rc; int fmt; int tmp; int i; char *s; struct audio_buf_info info; int caps; snd_inited = 0; // open /dev/dsp, confirm capability to mmap, and get size of dma buffer Con_Printf("opening /dev/dsp\n"); audio_fd = open("/dev/dsp", O_RDWR); if (audio_fd < 0) { perror("/dev/dsp"); Con_Printf("Could not open /dev/dsp\n"); return 0; } Con_Printf("audio_fd /dev/dsp=%d\n", audio_fd); rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not reset /dev/dsp\n"); close(audio_fd); return 0; } if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1) { perror("/dev/dsp"); Con_Printf("Sound driver too old\n"); close(audio_fd); return 0; } if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) { Con_Printf("Sorry but your soundcard can't do this\n"); close(audio_fd); return 0; } if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) { perror("GETOSPACE"); Con_Printf("Um, can't do GETOSPACE?\n"); close(audio_fd); return 0; } shm = &sn; shm->splitbuffer = 0; // set sample bits & speed s = getenv("QUAKE_SOUND_SAMPLEBITS"); if (s) shm->samplebits = atoi(s); /* else if ((i = COM_CheckParm("-sndbits")) != 0) shm->samplebits = atoi(com_argv[i+1]); */ if (shm->samplebits != 16 && shm->samplebits != 8) { ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt); if (fmt & AFMT_S16_LE) shm->samplebits = 16; else if (fmt & AFMT_U8) shm->samplebits = 8; } s = getenv("QUAKE_SOUND_SPEED"); if (s) shm->speed = atoi(s); /* else if ((i = COM_CheckParm("-sndspeed")) != 0) shm->speed = atoi(com_argv[i+1]); */ else { for (i=0 ; i<sizeof(tryrates)/4 ; i++) if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break; shm->speed = tryrates[i]; } s = getenv("QUAKE_SOUND_CHANNELS"); if (s) shm->channels = atoi(s); /* else if ((i = COM_CheckParm("-sndmono")) != 0) shm->channels = 1; else if ((i = COM_CheckParm("-sndstereo")) != 0) shm->channels = 2; */ else shm->channels = 2; shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8); shm->submission_chunk = 1; // memory map the dma buffer Con_Printf("about to map %d bytes to /dev/dsp\n", info.fragstotal * info.fragsize); shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal * info.fragsize, PROT_WRITE, MAP_SHARED, audio_fd, 0); if (!shm->buffer || shm->buffer == (unsigned char *)-1) { perror("/dev/dsp"); Con_Printf("Could not mmap /dev/dsp\n"); close(audio_fd); return 0; } Con_Printf("shm->buffer=%lx\n", shm->buffer); tmp = 0; if (shm->channels == 2) tmp = 1; rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not set /dev/dsp to stereo=%d", shm->channels); close(audio_fd); return 0; } if (tmp) shm->channels = 2; else shm->channels = 1; rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not set /dev/dsp speed to %d", shm->speed); close(audio_fd); return 0; } if (shm->samplebits == 16) { rc = AFMT_S16_LE; rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not support 16-bit data. Try 8-bit.\n"); close(audio_fd); return 0; } } else if (shm->samplebits == 8) { rc = AFMT_U8; rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not support 8-bit data.\n"); close(audio_fd); return 0; } } else { perror("/dev/dsp"); Con_Printf("%d-bit sound not supported.", shm->samplebits); close(audio_fd); return 0; } // toggle the trigger & start her up tmp = 0; rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not toggle.\n"); close(audio_fd); return 0; } tmp = PCM_ENABLE_OUTPUT; rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); if (rc < 0) { perror("/dev/dsp"); Con_Printf("Could not toggle.\n"); close(audio_fd); return 0; } shm->samplepos = 0; snd_inited = 1; return 1; } main() { SNDDMA_Init(); memset(shm->buffer, 0, 2048); }
/* Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // sound.h -- client sound i/o functions #ifndef __SOUND__ #define __SOUND__ #define DEFAULT_SOUND_PACKET_VOLUME 255 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 typedef enum {false, true} qboolean; // !!! if this is changed, it much be changed in asm_i386.h too !!! typedef struct { int left; int right; } portable_samplepair_t; #if 0 typedef struct sfx_s { char name[MAX_QPATH]; cache_user_t cache; } sfx_t; // !!! if this is changed, it much be changed in asm_i386.h too !!! typedef struct { int length; int loopstart; int speed; int width; int stereo; byte data[1]; // variable sized } sfxcache_t; #endif typedef struct { qboolean gamealive; qboolean soundalive; qboolean splitbuffer; int channels; int samples; // mono samples in buffer int submission_chunk; // don't mix less than this # int samplepos; // in mono samples int samplebits; int speed; unsigned char *buffer; } dma_t; #if 0 // !!! if this is changed, it much be changed in asm_i386.h too !!! typedef struct { sfx_t *sfx; // sfx number int leftvol; // 0-255 volume int rightvol; // 0-255 volume int end; // end time in global paintsamples int pos; // sample position in sfx int looping; // where to loop, -1 = no looping int entnum; // to allow overriding a specific sound int entchannel; // vec3_t origin; // origin of sound effect vec_t dist_mult; // distance multiplier (attenuation/clipK) int master_vol; // 0-255 master volume } channel_t; typedef struct { int rate; int width; int channels; int loopstart; int samples; int dataofs; // chunk starts this many bytes from file start } wavinfo_t; void S_Init (void); void S_Startup (void); void S_Shutdown (void); void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation); void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); void S_StopSound (int entnum, int entchannel); void S_StopAllSounds(qboolean clear); void S_ClearBuffer (void); void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up); void S_ExtraUpdate (void); sfx_t *S_PrecacheSound (char *sample); void S_TouchSound (char *sample); void S_ClearPrecache (void); void S_BeginPrecaching (void); void S_EndPrecaching (void); void S_PaintChannels(int endtime); void S_InitPaintChannels (void); // picks a channel based on priorities, empty slots, number of channels channel_t *SND_PickChannel(int entnum, int entchannel); // spatializes a channel void SND_Spatialize(channel_t *ch); // initializes cycling through a DMA buffer and returns information on it qboolean SNDDMA_Init(void); // gets the current DMA position int SNDDMA_GetDMAPos(void); // shutdown the DMA xfer. void SNDDMA_Shutdown(void); // ==================================================================== // User-setable variables // ==================================================================== #define MAX_CHANNELS 128 #define MAX_DYNAMIC_CHANNELS 8 extern channel_t channels[MAX_CHANNELS]; // 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds // MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc // MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds extern int total_channels; // // Fake dma is a synchronous faking of the DMA progress used for // isolating performance in the renderer. The fakedma_updates is // number of times S_Update() is called per second. // extern qboolean fakedma; extern int fakedma_updates; extern int paintedtime; extern vec3_t listener_origin; extern vec3_t listener_forward; extern vec3_t listener_right; extern vec3_t listener_up; extern volatile dma_t *shm; extern volatile dma_t sn; extern vec_t sound_nominal_clip_dist; extern cvar_t loadas8bit; extern cvar_t bgmvolume; extern cvar_t volume; extern qboolean snd_initialized; extern int snd_blocked; void S_LocalSound (char *s); sfxcache_t *S_LoadSound (sfx_t *s); wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength); void SND_InitScaletable (void); void SNDDMA_Submit(void); void S_AmbientOff (void); void S_AmbientOn (void); #endif #endif