Mercurial > ~darius > hgwebdir.cgi > mikmod
diff playercode/unix_drv/drv_oss.c @ 9:990c9dadb348
Initial revision
author | darius |
---|---|
date | Fri, 23 Jan 1998 16:05:10 +0000 |
parents | |
children | 32f80cd7bfee |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/playercode/unix_drv/drv_oss.c Fri Jan 23 16:05:10 1998 +0000 @@ -0,0 +1,175 @@ +/* + +Name: +DRV_VOX.C + +Description: +Mikmod driver for output on linux and FreeBSD Open Sound System (OSS) +(/dev/dsp) + +Portability: VoxWare/SS/OSS land. Linux, FreeBSD (NetBSD & SCO?) + +New fragment configuration code done by Rao: +============================================ + +You can use the environment variables 'MM_FRAGSIZE' and 'MM_NUMFRAGS' to +override the default size & number of audio buffer fragments. If you +experience crackles & pops, try experimenting with these values. + +Read experimental.txt within the VoxWare package for information on these +options. They are _VERY_ important with relation to sound popping and smooth +playback. + +In general, the slower your system, the higher these values need to be. + +MM_NUMFRAGS is within the range 2 to 255 (decimal) + +MM_FRAGSIZE is is within the range 7 to 17 (dec). The requested fragment size +will be 2^MM_FRAGSIZE + +- This driver DOES work with MikMod 3.0 +- modifed to use an ioctl() to figure out how much data to do with + each write, keeps us from blocking extensivly + +*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <fcntl.h> +#ifdef __FreeBSD__ +#include <machine/soundcard.h> +#else +#include <sys/soundcard.h> +#endif /* __FreeBSD__ */ +#include <sys/ioctl.h> +#include <sys/wait.h> +#include "mikmod.h" +#include "mmio.h" + +#define DEFAULT_FRAGSIZE 17 +#define DEFAULT_NUMFRAGS 4 + +static int sndfd; +static int fragmentsize; +static char* audiobuffer; + + +static BOOL OSS_IsThere(void) +{ + return (access("/dev/dsp",W_OK)==0); +} + + +static BOOL OSS_Init(void) +{ + char *env; + int play_precision,play_stereo,play_rate; + int fragsize,numfrags; + + if((sndfd=open("/dev/dsp",O_WRONLY))<0){ + return 1; + } + + fragsize=(env=getenv("MM_FRAGSIZE")) ? atoi(env) : DEFAULT_FRAGSIZE; + numfrags=(env=getenv("MM_NUMFRAGS")) ? atoi(env) : DEFAULT_NUMFRAGS; + + if(fragsize<7 || fragsize>17) fragsize=DEFAULT_FRAGSIZE; + if(numfrags<2 || numfrags>255) numfrags=DEFAULT_NUMFRAGS; + + fragmentsize=(numfrags<<16) | fragsize; + +#ifndef __FreeBSD__ + if(ioctl(sndfd, SNDCTL_DSP_SETFRAGMENT, &fragmentsize)<0){ + close(sndfd); + return 1; + } +#endif /* __FreeBSD__ */ + + play_precision = (md_mode & DMODE_16BITS) ? 16 : 8; + play_stereo= (md_mode & DMODE_STEREO) ? 1 : 0; + play_rate=md_mixfreq; + + if(ioctl(sndfd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1 || + ioctl(sndfd, SNDCTL_DSP_STEREO, &play_stereo) == -1 || + ioctl(sndfd, SNDCTL_DSP_SPEED, &play_rate) == -1){ + close(sndfd); + return 1; + } + + ioctl(sndfd, SNDCTL_DSP_GETBLKSIZE, &fragmentsize); + +/* Lose this for now - it will confuse ncurses etc... + printf("Fragment size is %ld\n",fragmentsize); */ + + if(VC_Init()){ + close(sndfd); + return 1; + } + + audiobuffer = (char*) _mm_malloc(fragmentsize * sizeof(char) * 2); + + if(audiobuffer==NULL){ + VC_Exit(); + close(sndfd); + return 1; + } + + return 0; +} + + +static void OSS_Exit(void) +{ + free(audiobuffer); + VC_Exit(); + close(sndfd); +} + + +static void OSS_Update(void) +{ + audio_buf_info buffinf; + ioctl(sndfd, SNDCTL_DSP_GETOSPACE, &buffinf); + VC_WriteBytes(audiobuffer,buffinf.fragments*buffinf.fragsize); + write(sndfd,audiobuffer,buffinf.fragments*buffinf.fragsize); +} + +BOOL OSS_Reset(void) +{ + ioctl(sndfd, SNDCTL_DSP_RESET); + VC_Exit(); + return VC_Init(); +} + + +MDRIVER drv_oss = +{ + NULL, + "Open Sound System (OSS)", + "Open Sound System (OSS) Driver v1.3 - by Rao & MikMak (with a little hacking from Pete)", + 0,255, + OSS_IsThere, + VC_SampleLoad, + VC_SampleUnload, + VC_SampleSpace, + VC_SampleLength, + OSS_Init, + OSS_Exit, + OSS_Reset, + VC_SetNumVoices, + VC_PlayStart, + VC_PlayStop, + OSS_Update, + VC_VoiceSetVolume, + VC_VoiceSetFrequency, + VC_VoiceSetPanning, + VC_VoicePlay, + VC_VoiceStop, + VC_VoiceStopped, + VC_VoiceReleaseSustain, + VC_VoiceGetPosition, + VC_VoiceRealVolume +};