diff options
Diffstat (limited to 'apps/plugins/sdl/progs/quake/snd_linux.c')
-rw-r--r-- | apps/plugins/sdl/progs/quake/snd_linux.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/snd_linux.c b/apps/plugins/sdl/progs/quake/snd_linux.c new file mode 100644 index 0000000000..4579e40d64 --- /dev/null +++ b/apps/plugins/sdl/progs/quake/snd_linux.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | Copyright (C) 1996-1997 Id Software, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License | ||
6 | as published by the Free Software Foundation; either version 2 | ||
7 | of the License, or (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
12 | |||
13 | See the GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | */ | ||
20 | #include <unistd.h> | ||
21 | #include <fcntl.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/ioctl.h> | ||
25 | #include <sys/mman.h> | ||
26 | #include <sys/shm.h> | ||
27 | #include <sys/wait.h> | ||
28 | #include <linux/soundcard.h> | ||
29 | #include <stdio.h> | ||
30 | #include "quakedef.h" | ||
31 | |||
32 | int audio_fd; | ||
33 | int snd_inited; | ||
34 | |||
35 | static int tryrates[] = { 11025, 22051, 44100, 8000 }; | ||
36 | |||
37 | qboolean SNDDMA_Init(void) | ||
38 | { | ||
39 | |||
40 | int rc; | ||
41 | int fmt; | ||
42 | int tmp; | ||
43 | int i; | ||
44 | char *s; | ||
45 | struct audio_buf_info info; | ||
46 | int caps; | ||
47 | |||
48 | snd_inited = 0; | ||
49 | |||
50 | // open /dev/dsp, confirm capability to mmap, and get size of dma buffer | ||
51 | |||
52 | audio_fd = open("/dev/dsp", O_RDWR); | ||
53 | if (audio_fd < 0) | ||
54 | { | ||
55 | perror("/dev/dsp"); | ||
56 | Con_Printf("Could not open /dev/dsp\n"); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0); | ||
61 | if (rc < 0) | ||
62 | { | ||
63 | perror("/dev/dsp"); | ||
64 | Con_Printf("Could not reset /dev/dsp\n"); | ||
65 | close(audio_fd); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1) | ||
70 | { | ||
71 | perror("/dev/dsp"); | ||
72 | Con_Printf("Sound driver too old\n"); | ||
73 | close(audio_fd); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) | ||
78 | { | ||
79 | Con_Printf("Sorry but your soundcard can't do this\n"); | ||
80 | close(audio_fd); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) | ||
85 | { | ||
86 | perror("GETOSPACE"); | ||
87 | Con_Printf("Um, can't do GETOSPACE?\n"); | ||
88 | close(audio_fd); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | shm = &sn; | ||
93 | shm->splitbuffer = 0; | ||
94 | |||
95 | // set sample bits & speed | ||
96 | |||
97 | s = getenv("QUAKE_SOUND_SAMPLEBITS"); | ||
98 | if (s) shm->samplebits = atoi(s); | ||
99 | else if ((i = COM_CheckParm("-sndbits")) != 0) | ||
100 | shm->samplebits = atoi(com_argv[i+1]); | ||
101 | if (shm->samplebits != 16 && shm->samplebits != 8) | ||
102 | { | ||
103 | ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt); | ||
104 | if (fmt & AFMT_S16_LE) shm->samplebits = 16; | ||
105 | else if (fmt & AFMT_U8) shm->samplebits = 8; | ||
106 | } | ||
107 | |||
108 | s = getenv("QUAKE_SOUND_SPEED"); | ||
109 | if (s) shm->speed = atoi(s); | ||
110 | else if ((i = COM_CheckParm("-sndspeed")) != 0) | ||
111 | shm->speed = atoi(com_argv[i+1]); | ||
112 | else | ||
113 | { | ||
114 | for (i=0 ; i<sizeof(tryrates)/4 ; i++) | ||
115 | if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break; | ||
116 | shm->speed = tryrates[i]; | ||
117 | } | ||
118 | |||
119 | s = getenv("QUAKE_SOUND_CHANNELS"); | ||
120 | if (s) shm->channels = atoi(s); | ||
121 | else if ((i = COM_CheckParm("-sndmono")) != 0) | ||
122 | shm->channels = 1; | ||
123 | else if ((i = COM_CheckParm("-sndstereo")) != 0) | ||
124 | shm->channels = 2; | ||
125 | else shm->channels = 2; | ||
126 | |||
127 | shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8); | ||
128 | shm->submission_chunk = 1; | ||
129 | |||
130 | // memory map the dma buffer | ||
131 | |||
132 | shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal | ||
133 | * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0); | ||
134 | if (!shm->buffer || shm->buffer == (unsigned char *)-1) | ||
135 | { | ||
136 | perror("/dev/dsp"); | ||
137 | Con_Printf("Could not mmap /dev/dsp\n"); | ||
138 | close(audio_fd); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | tmp = 0; | ||
143 | if (shm->channels == 2) | ||
144 | tmp = 1; | ||
145 | rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); | ||
146 | if (rc < 0) | ||
147 | { | ||
148 | perror("/dev/dsp"); | ||
149 | Con_Printf("Could not set /dev/dsp to stereo=%d", shm->channels); | ||
150 | close(audio_fd); | ||
151 | return 0; | ||
152 | } | ||
153 | if (tmp) | ||
154 | shm->channels = 2; | ||
155 | else | ||
156 | shm->channels = 1; | ||
157 | |||
158 | rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed); | ||
159 | if (rc < 0) | ||
160 | { | ||
161 | perror("/dev/dsp"); | ||
162 | Con_Printf("Could not set /dev/dsp speed to %d", shm->speed); | ||
163 | close(audio_fd); | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | if (shm->samplebits == 16) | ||
168 | { | ||
169 | rc = AFMT_S16_LE; | ||
170 | rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); | ||
171 | if (rc < 0) | ||
172 | { | ||
173 | perror("/dev/dsp"); | ||
174 | Con_Printf("Could not support 16-bit data. Try 8-bit.\n"); | ||
175 | close(audio_fd); | ||
176 | return 0; | ||
177 | } | ||
178 | } | ||
179 | else if (shm->samplebits == 8) | ||
180 | { | ||
181 | rc = AFMT_U8; | ||
182 | rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); | ||
183 | if (rc < 0) | ||
184 | { | ||
185 | perror("/dev/dsp"); | ||
186 | Con_Printf("Could not support 8-bit data.\n"); | ||
187 | close(audio_fd); | ||
188 | return 0; | ||
189 | } | ||
190 | } | ||
191 | else | ||
192 | { | ||
193 | perror("/dev/dsp"); | ||
194 | Con_Printf("%d-bit sound not supported.", shm->samplebits); | ||
195 | close(audio_fd); | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | // toggle the trigger & start her up | ||
200 | |||
201 | tmp = 0; | ||
202 | rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); | ||
203 | if (rc < 0) | ||
204 | { | ||
205 | perror("/dev/dsp"); | ||
206 | Con_Printf("Could not toggle.\n"); | ||
207 | close(audio_fd); | ||
208 | return 0; | ||
209 | } | ||
210 | tmp = PCM_ENABLE_OUTPUT; | ||
211 | rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); | ||
212 | if (rc < 0) | ||
213 | { | ||
214 | perror("/dev/dsp"); | ||
215 | Con_Printf("Could not toggle.\n"); | ||
216 | close(audio_fd); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | shm->samplepos = 0; | ||
221 | |||
222 | snd_inited = 1; | ||
223 | return 1; | ||
224 | |||
225 | } | ||
226 | |||
227 | int SNDDMA_GetDMAPos(void) | ||
228 | { | ||
229 | |||
230 | struct count_info count; | ||
231 | |||
232 | if (!snd_inited) return 0; | ||
233 | |||
234 | if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1) | ||
235 | { | ||
236 | perror("/dev/dsp"); | ||
237 | Con_Printf("Uh, sound dead.\n"); | ||
238 | close(audio_fd); | ||
239 | snd_inited = 0; | ||
240 | return 0; | ||
241 | } | ||
242 | // shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); | ||
243 | // fprintf(stderr, "%d \r", count.ptr); | ||
244 | shm->samplepos = count.ptr / (shm->samplebits / 8); | ||
245 | |||
246 | return shm->samplepos; | ||
247 | |||
248 | } | ||
249 | |||
250 | void SNDDMA_Shutdown(void) | ||
251 | { | ||
252 | if (snd_inited) | ||
253 | { | ||
254 | close(audio_fd); | ||
255 | snd_inited = 0; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | ============== | ||
261 | SNDDMA_Submit | ||
262 | |||
263 | Send sound to device if buffer isn't really the dma buffer | ||
264 | =============== | ||
265 | */ | ||
266 | void SNDDMA_Submit(void) | ||
267 | { | ||
268 | } | ||
269 | |||