From owner-freebsd-current Tue Dec 28 21:58:43 1999 Delivered-To: freebsd-current@freebsd.org Received: from hurricane.columbus.rr.com (m4.columbus.rr.com [204.210.252.19]) by hub.freebsd.org (Postfix) with ESMTP id 96CEA155BC; Tue, 28 Dec 1999 21:58:11 -0800 (PST) (envelope-from caa@columbus.rr.com) Received: from columbus.rr.com ([24.95.60.151]) by hurricane.columbus.rr.com (Post.Office MTA v3.5.3 release 223 ID# 0-53939U80000L80000S0V35) with ESMTP id com; Wed, 29 Dec 1999 00:58:09 -0500 Received: (from caa@localhost) by columbus.rr.com (8.9.3/8.9.3) id AAA81203; Wed, 29 Dec 1999 00:58:10 -0500 (EST) (envelope-from caa) Date: Wed, 29 Dec 1999 00:58:10 -0500 From: "Charles Anderson" To: freebsd-multimedia@freebsd.org, FreeBSD Current Subject: mmaping /dev/dsp problems Message-ID: <19991229005714.C79763@midgard.dhs.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="H+4ONPRPur6+Ovig" X-Mailer: Mutt 1.0i Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --H+4ONPRPur6+Ovig Content-Type: text/plain; charset=us-ascii 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 Thanks, for any help. -Charlie -- Charles Anderson caa@columbus.rr.com No quote, no nothin' --H+4ONPRPur6+Ovig Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="snd_linux.c" /* Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #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 ; ispeed = 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); } --H+4ONPRPur6+Ovig Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sound.h" /* 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 --H+4ONPRPur6+Ovig-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message