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
+};