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