annotate playercode/unix_drv/drv_oss.c @ 9:990c9dadb348

Initial revision
author darius
date Fri, 23 Jan 1998 16:05:10 +0000
parents
children 32f80cd7bfee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9
990c9dadb348 Initial revision
darius
parents:
diff changeset
1 /*
990c9dadb348 Initial revision
darius
parents:
diff changeset
2
990c9dadb348 Initial revision
darius
parents:
diff changeset
3 Name:
990c9dadb348 Initial revision
darius
parents:
diff changeset
4 DRV_VOX.C
990c9dadb348 Initial revision
darius
parents:
diff changeset
5
990c9dadb348 Initial revision
darius
parents:
diff changeset
6 Description:
990c9dadb348 Initial revision
darius
parents:
diff changeset
7 Mikmod driver for output on linux and FreeBSD Open Sound System (OSS)
990c9dadb348 Initial revision
darius
parents:
diff changeset
8 (/dev/dsp)
990c9dadb348 Initial revision
darius
parents:
diff changeset
9
990c9dadb348 Initial revision
darius
parents:
diff changeset
10 Portability: VoxWare/SS/OSS land. Linux, FreeBSD (NetBSD & SCO?)
990c9dadb348 Initial revision
darius
parents:
diff changeset
11
990c9dadb348 Initial revision
darius
parents:
diff changeset
12 New fragment configuration code done by Rao:
990c9dadb348 Initial revision
darius
parents:
diff changeset
13 ============================================
990c9dadb348 Initial revision
darius
parents:
diff changeset
14
990c9dadb348 Initial revision
darius
parents:
diff changeset
15 You can use the environment variables 'MM_FRAGSIZE' and 'MM_NUMFRAGS' to
990c9dadb348 Initial revision
darius
parents:
diff changeset
16 override the default size & number of audio buffer fragments. If you
990c9dadb348 Initial revision
darius
parents:
diff changeset
17 experience crackles & pops, try experimenting with these values.
990c9dadb348 Initial revision
darius
parents:
diff changeset
18
990c9dadb348 Initial revision
darius
parents:
diff changeset
19 Read experimental.txt within the VoxWare package for information on these
990c9dadb348 Initial revision
darius
parents:
diff changeset
20 options. They are _VERY_ important with relation to sound popping and smooth
990c9dadb348 Initial revision
darius
parents:
diff changeset
21 playback.
990c9dadb348 Initial revision
darius
parents:
diff changeset
22
990c9dadb348 Initial revision
darius
parents:
diff changeset
23 In general, the slower your system, the higher these values need to be.
990c9dadb348 Initial revision
darius
parents:
diff changeset
24
990c9dadb348 Initial revision
darius
parents:
diff changeset
25 MM_NUMFRAGS is within the range 2 to 255 (decimal)
990c9dadb348 Initial revision
darius
parents:
diff changeset
26
990c9dadb348 Initial revision
darius
parents:
diff changeset
27 MM_FRAGSIZE is is within the range 7 to 17 (dec). The requested fragment size
990c9dadb348 Initial revision
darius
parents:
diff changeset
28 will be 2^MM_FRAGSIZE
990c9dadb348 Initial revision
darius
parents:
diff changeset
29
990c9dadb348 Initial revision
darius
parents:
diff changeset
30 - This driver DOES work with MikMod 3.0
990c9dadb348 Initial revision
darius
parents:
diff changeset
31 - modifed to use an ioctl() to figure out how much data to do with
990c9dadb348 Initial revision
darius
parents:
diff changeset
32 each write, keeps us from blocking extensivly
990c9dadb348 Initial revision
darius
parents:
diff changeset
33
990c9dadb348 Initial revision
darius
parents:
diff changeset
34 */
990c9dadb348 Initial revision
darius
parents:
diff changeset
35 #include <stdio.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
36 #include <stdlib.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
37 #include <unistd.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
38 #include <sys/types.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
39 #include <sys/time.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
40 #include <sys/stat.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
41 #include <fcntl.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
42 #ifdef __FreeBSD__
990c9dadb348 Initial revision
darius
parents:
diff changeset
43 #include <machine/soundcard.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
44 #else
990c9dadb348 Initial revision
darius
parents:
diff changeset
45 #include <sys/soundcard.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
46 #endif /* __FreeBSD__ */
990c9dadb348 Initial revision
darius
parents:
diff changeset
47 #include <sys/ioctl.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
48 #include <sys/wait.h>
990c9dadb348 Initial revision
darius
parents:
diff changeset
49 #include "mikmod.h"
990c9dadb348 Initial revision
darius
parents:
diff changeset
50 #include "mmio.h"
990c9dadb348 Initial revision
darius
parents:
diff changeset
51
990c9dadb348 Initial revision
darius
parents:
diff changeset
52 #define DEFAULT_FRAGSIZE 17
990c9dadb348 Initial revision
darius
parents:
diff changeset
53 #define DEFAULT_NUMFRAGS 4
990c9dadb348 Initial revision
darius
parents:
diff changeset
54
990c9dadb348 Initial revision
darius
parents:
diff changeset
55 static int sndfd;
990c9dadb348 Initial revision
darius
parents:
diff changeset
56 static int fragmentsize;
990c9dadb348 Initial revision
darius
parents:
diff changeset
57 static char* audiobuffer;
990c9dadb348 Initial revision
darius
parents:
diff changeset
58
990c9dadb348 Initial revision
darius
parents:
diff changeset
59
990c9dadb348 Initial revision
darius
parents:
diff changeset
60 static BOOL OSS_IsThere(void)
990c9dadb348 Initial revision
darius
parents:
diff changeset
61 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
62 return (access("/dev/dsp",W_OK)==0);
990c9dadb348 Initial revision
darius
parents:
diff changeset
63 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
64
990c9dadb348 Initial revision
darius
parents:
diff changeset
65
990c9dadb348 Initial revision
darius
parents:
diff changeset
66 static BOOL OSS_Init(void)
990c9dadb348 Initial revision
darius
parents:
diff changeset
67 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
68 char *env;
990c9dadb348 Initial revision
darius
parents:
diff changeset
69 int play_precision,play_stereo,play_rate;
990c9dadb348 Initial revision
darius
parents:
diff changeset
70 int fragsize,numfrags;
990c9dadb348 Initial revision
darius
parents:
diff changeset
71
990c9dadb348 Initial revision
darius
parents:
diff changeset
72 if((sndfd=open("/dev/dsp",O_WRONLY))<0){
990c9dadb348 Initial revision
darius
parents:
diff changeset
73 return 1;
990c9dadb348 Initial revision
darius
parents:
diff changeset
74 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
75
990c9dadb348 Initial revision
darius
parents:
diff changeset
76 fragsize=(env=getenv("MM_FRAGSIZE")) ? atoi(env) : DEFAULT_FRAGSIZE;
990c9dadb348 Initial revision
darius
parents:
diff changeset
77 numfrags=(env=getenv("MM_NUMFRAGS")) ? atoi(env) : DEFAULT_NUMFRAGS;
990c9dadb348 Initial revision
darius
parents:
diff changeset
78
990c9dadb348 Initial revision
darius
parents:
diff changeset
79 if(fragsize<7 || fragsize>17) fragsize=DEFAULT_FRAGSIZE;
990c9dadb348 Initial revision
darius
parents:
diff changeset
80 if(numfrags<2 || numfrags>255) numfrags=DEFAULT_NUMFRAGS;
990c9dadb348 Initial revision
darius
parents:
diff changeset
81
990c9dadb348 Initial revision
darius
parents:
diff changeset
82 fragmentsize=(numfrags<<16) | fragsize;
990c9dadb348 Initial revision
darius
parents:
diff changeset
83
990c9dadb348 Initial revision
darius
parents:
diff changeset
84 #ifndef __FreeBSD__
990c9dadb348 Initial revision
darius
parents:
diff changeset
85 if(ioctl(sndfd, SNDCTL_DSP_SETFRAGMENT, &fragmentsize)<0){
990c9dadb348 Initial revision
darius
parents:
diff changeset
86 close(sndfd);
990c9dadb348 Initial revision
darius
parents:
diff changeset
87 return 1;
990c9dadb348 Initial revision
darius
parents:
diff changeset
88 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
89 #endif /* __FreeBSD__ */
990c9dadb348 Initial revision
darius
parents:
diff changeset
90
990c9dadb348 Initial revision
darius
parents:
diff changeset
91 play_precision = (md_mode & DMODE_16BITS) ? 16 : 8;
990c9dadb348 Initial revision
darius
parents:
diff changeset
92 play_stereo= (md_mode & DMODE_STEREO) ? 1 : 0;
990c9dadb348 Initial revision
darius
parents:
diff changeset
93 play_rate=md_mixfreq;
990c9dadb348 Initial revision
darius
parents:
diff changeset
94
990c9dadb348 Initial revision
darius
parents:
diff changeset
95 if(ioctl(sndfd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1 ||
990c9dadb348 Initial revision
darius
parents:
diff changeset
96 ioctl(sndfd, SNDCTL_DSP_STEREO, &play_stereo) == -1 ||
990c9dadb348 Initial revision
darius
parents:
diff changeset
97 ioctl(sndfd, SNDCTL_DSP_SPEED, &play_rate) == -1){
990c9dadb348 Initial revision
darius
parents:
diff changeset
98 close(sndfd);
990c9dadb348 Initial revision
darius
parents:
diff changeset
99 return 1;
990c9dadb348 Initial revision
darius
parents:
diff changeset
100 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
101
990c9dadb348 Initial revision
darius
parents:
diff changeset
102 ioctl(sndfd, SNDCTL_DSP_GETBLKSIZE, &fragmentsize);
990c9dadb348 Initial revision
darius
parents:
diff changeset
103
990c9dadb348 Initial revision
darius
parents:
diff changeset
104 /* Lose this for now - it will confuse ncurses etc...
990c9dadb348 Initial revision
darius
parents:
diff changeset
105 printf("Fragment size is %ld\n",fragmentsize); */
990c9dadb348 Initial revision
darius
parents:
diff changeset
106
990c9dadb348 Initial revision
darius
parents:
diff changeset
107 if(VC_Init()){
990c9dadb348 Initial revision
darius
parents:
diff changeset
108 close(sndfd);
990c9dadb348 Initial revision
darius
parents:
diff changeset
109 return 1;
990c9dadb348 Initial revision
darius
parents:
diff changeset
110 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
111
990c9dadb348 Initial revision
darius
parents:
diff changeset
112 audiobuffer = (char*) _mm_malloc(fragmentsize * sizeof(char) * 2);
990c9dadb348 Initial revision
darius
parents:
diff changeset
113
990c9dadb348 Initial revision
darius
parents:
diff changeset
114 if(audiobuffer==NULL){
990c9dadb348 Initial revision
darius
parents:
diff changeset
115 VC_Exit();
990c9dadb348 Initial revision
darius
parents:
diff changeset
116 close(sndfd);
990c9dadb348 Initial revision
darius
parents:
diff changeset
117 return 1;
990c9dadb348 Initial revision
darius
parents:
diff changeset
118 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
119
990c9dadb348 Initial revision
darius
parents:
diff changeset
120 return 0;
990c9dadb348 Initial revision
darius
parents:
diff changeset
121 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
122
990c9dadb348 Initial revision
darius
parents:
diff changeset
123
990c9dadb348 Initial revision
darius
parents:
diff changeset
124 static void OSS_Exit(void)
990c9dadb348 Initial revision
darius
parents:
diff changeset
125 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
126 free(audiobuffer);
990c9dadb348 Initial revision
darius
parents:
diff changeset
127 VC_Exit();
990c9dadb348 Initial revision
darius
parents:
diff changeset
128 close(sndfd);
990c9dadb348 Initial revision
darius
parents:
diff changeset
129 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
130
990c9dadb348 Initial revision
darius
parents:
diff changeset
131
990c9dadb348 Initial revision
darius
parents:
diff changeset
132 static void OSS_Update(void)
990c9dadb348 Initial revision
darius
parents:
diff changeset
133 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
134 audio_buf_info buffinf;
990c9dadb348 Initial revision
darius
parents:
diff changeset
135 ioctl(sndfd, SNDCTL_DSP_GETOSPACE, &buffinf);
990c9dadb348 Initial revision
darius
parents:
diff changeset
136 VC_WriteBytes(audiobuffer,buffinf.fragments*buffinf.fragsize);
990c9dadb348 Initial revision
darius
parents:
diff changeset
137 write(sndfd,audiobuffer,buffinf.fragments*buffinf.fragsize);
990c9dadb348 Initial revision
darius
parents:
diff changeset
138 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
139
990c9dadb348 Initial revision
darius
parents:
diff changeset
140 BOOL OSS_Reset(void)
990c9dadb348 Initial revision
darius
parents:
diff changeset
141 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
142 ioctl(sndfd, SNDCTL_DSP_RESET);
990c9dadb348 Initial revision
darius
parents:
diff changeset
143 VC_Exit();
990c9dadb348 Initial revision
darius
parents:
diff changeset
144 return VC_Init();
990c9dadb348 Initial revision
darius
parents:
diff changeset
145 }
990c9dadb348 Initial revision
darius
parents:
diff changeset
146
990c9dadb348 Initial revision
darius
parents:
diff changeset
147
990c9dadb348 Initial revision
darius
parents:
diff changeset
148 MDRIVER drv_oss =
990c9dadb348 Initial revision
darius
parents:
diff changeset
149 {
990c9dadb348 Initial revision
darius
parents:
diff changeset
150 NULL,
990c9dadb348 Initial revision
darius
parents:
diff changeset
151 "Open Sound System (OSS)",
990c9dadb348 Initial revision
darius
parents:
diff changeset
152 "Open Sound System (OSS) Driver v1.3 - by Rao & MikMak (with a little hacking from Pete)",
990c9dadb348 Initial revision
darius
parents:
diff changeset
153 0,255,
990c9dadb348 Initial revision
darius
parents:
diff changeset
154 OSS_IsThere,
990c9dadb348 Initial revision
darius
parents:
diff changeset
155 VC_SampleLoad,
990c9dadb348 Initial revision
darius
parents:
diff changeset
156 VC_SampleUnload,
990c9dadb348 Initial revision
darius
parents:
diff changeset
157 VC_SampleSpace,
990c9dadb348 Initial revision
darius
parents:
diff changeset
158 VC_SampleLength,
990c9dadb348 Initial revision
darius
parents:
diff changeset
159 OSS_Init,
990c9dadb348 Initial revision
darius
parents:
diff changeset
160 OSS_Exit,
990c9dadb348 Initial revision
darius
parents:
diff changeset
161 OSS_Reset,
990c9dadb348 Initial revision
darius
parents:
diff changeset
162 VC_SetNumVoices,
990c9dadb348 Initial revision
darius
parents:
diff changeset
163 VC_PlayStart,
990c9dadb348 Initial revision
darius
parents:
diff changeset
164 VC_PlayStop,
990c9dadb348 Initial revision
darius
parents:
diff changeset
165 OSS_Update,
990c9dadb348 Initial revision
darius
parents:
diff changeset
166 VC_VoiceSetVolume,
990c9dadb348 Initial revision
darius
parents:
diff changeset
167 VC_VoiceSetFrequency,
990c9dadb348 Initial revision
darius
parents:
diff changeset
168 VC_VoiceSetPanning,
990c9dadb348 Initial revision
darius
parents:
diff changeset
169 VC_VoicePlay,
990c9dadb348 Initial revision
darius
parents:
diff changeset
170 VC_VoiceStop,
990c9dadb348 Initial revision
darius
parents:
diff changeset
171 VC_VoiceStopped,
990c9dadb348 Initial revision
darius
parents:
diff changeset
172 VC_VoiceReleaseSustain,
990c9dadb348 Initial revision
darius
parents:
diff changeset
173 VC_VoiceGetPosition,
990c9dadb348 Initial revision
darius
parents:
diff changeset
174 VC_VoiceRealVolume
990c9dadb348 Initial revision
darius
parents:
diff changeset
175 };