1
2 /*
3 * Diverse SLab audio routines.
4 * Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22
23 /*
24 * These are largely device specific operations for the audio devices. Some of
25 * the calls are general, but may eventually be used by several of the SLab
26 * applications.
27 *
28 * The operations for audio control are rather ugly. The application sets up
29 * a number of values in the controlBuffer, and the engine intermittanly looks
30 * to see if these values are initialised. If so, it acts on the values, and
31 * then clears them. The reason we have to use this indirection is that the
32 * front end applications do not own the audio device, this is under control
33 * of the engine.
34 *
35 * Jul 28th 96 - Only LINUX code is active.
36 */
37
38 /*
39 * Audio device structure format definitions.
40 */
41 #include "slabrevisions.h"
42 #include "slabaudiodev.h"
43
44 #include <sys/ioctl.h>
45 #include <string.h>
46
47 #ifdef DEBUG
48 #include <stdio.h>
49 #endif
50 #include <unistd.h>
51 #include <fcntl.h>
52 #include <stdlib.h>
53 #ifndef __FreeBSD__
54 #include <malloc.h>
55 #endif
56
57 static int setAudioOSS(int, duplexDev *, int, int, int);
58
59 #if (BRISTOL_HAS_OSS == 1)
60 /*
61 * This may want to be /usr/lib/oss/include/sys/soundcard.h if someone has
62 * purchased the 4Front drivers?
63 */
64 #include <sys/soundcard.h>
65 audio_buf_info bufferInfo;
66 mixer_info mInfo;
67
68 static char *SLAB_SND_LABELS[SLAB_NRDEVICES] = SOUND_DEVICE_LABELS;
69 #endif
70
71 /*
72 * Setup audio parameters with device support.
73 */
74 void
setAudioOSSparam(audioDev,devID,param,left,right)75 setAudioOSSparam(audioDev, devID, param, left, right)
76 duplexDev *audioDev;
77 int param, devID;
78 short left, right;
79 {
80 if (audioDev->mixerFD > 0)
81 setAudioOSS(audioDev->mixerFD, audioDev, param, left, right);
82 }
83
84 /*
85 * Binned since alsa support was implemented.
86 *
87 * This is a device specific routine. We take the fd, parameter, and left
88 * right values, and configure the device. These routines should be used by the
89 * engine to do the actual audio horsework.
90 *
91 * This is actually an internal routine, it should not be called from outside
92 * of this file.
93 */
94 static int
setAudioOSS(fd,audioDev,param,valueL,valueR)95 setAudioOSS(fd, audioDev, param, valueL, valueR)
96 duplexDev *audioDev;
97 {
98 #if (BRISTOL_HAS_OSS == 1)
99 int value, command;
100
101 switch(param) {
102 case SLAB_REC_SRC:
103 case SLAB_MM_CD:
104 case SLAB_MM_MIC:
105 case SLAB_MM_LINE:
106 case SLAB_MM_LINE1:
107 case SLAB_MM_LINE2:
108 case SLAB_MM_LINE3:
109 case SLAB_MM_SYNTH:
110 case SLAB_MM_PCM:
111 case SLAB_TREBLE:
112 case SLAB_BASS:
113 case SLAB_MID:
114 case SLAB_INPUT_GAIN:
115 case SLAB_VOL_CD:
116 case SLAB_VOL_MIC:
117 case SLAB_VOL_LINE:
118 case SLAB_VOL_LINE1:
119 case SLAB_VOL_LINE2:
120 case SLAB_VOL_LINE3:
121 case SLAB_VOL_SYNTH:
122 case SLAB_VOL_PCM:
123 default:
124 /*
125 * These are all the rest, which should be from the microMixer,
126 * scaled to 100 already.
127 */
128 command = param & SLAB_MM_MASK;
129 value = (valueR << 8) +
130 valueL;
131 }
132 #endif /* linux */
133
134 #ifdef DEBUG
135 printf("Command: %x, value: %x\n", command, value);
136 #endif
137
138 #if (BRISTOL_HAS_OSS == 1)
139 #ifdef IOCTL_DBG
140 if (audioDev->cflags & SLAB_AUDIODBG)
141 printf("ioctl(%i, MIXER_WRITE(%i), %i)\n", fd, command, value);
142 #endif
143 if (ioctl(fd, MIXER_WRITE(command), &value) == -1) {
144 /*
145 printf("Error setting audio parameter %s\n",
146 SLAB_SND_LABELS[command]);
147 */
148 return(0);
149 }
150 #endif
151
152 return(0);
153 }
154
155 void
checkAudioOSScaps(audioDev,devID,fd)156 checkAudioOSScaps(audioDev, devID, fd)
157 duplexDev *audioDev;
158 int devID, fd;
159 {
160 #if (BRISTOL_HAS_OSS == 1)
161 int stereodevs = 0;
162
163 #ifdef DEBUG
164 printf("checkAudioCaps2(%i, %i)\n", devID, fd);
165 #endif
166
167 if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1)
168 {
169 #ifdef IOCTL_DBG
170 if (audioDev->cflags & SLAB_AUDIODBG)
171 #endif
172 printf("Failed to get stereo capabilities: %08x\n", stereodevs);
173 } else {
174 #ifdef IOCTL_DBG
175 if (audioDev->cflags & SLAB_AUDIODBG)
176 printf("Capabilities: %08x\n", stereodevs);
177 #endif
178 audioDev->stereoCaps = stereodevs;
179 }
180
181
182 #ifdef DEBUG
183 for (i = 1; i < 131072; i = i << 1) {
184 if (i & stereodevs)
185 printf("Found stereo dev %08x\n", i);
186 }
187 #endif
188
189 stereodevs = 0;
190 if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &stereodevs) == -1)
191 {
192 #ifdef IOCTL_DBG
193 if (audioDev->cflags & SLAB_AUDIODBG)
194 #endif
195 printf("Failed to get audio capabilities: %08x\n", stereodevs);
196 } else {
197 #ifdef IOCTL_DBG
198 if (audioDev->cflags & SLAB_AUDIODBG)
199 printf("Mono Capabilities: %08x\n", stereodevs);
200 #endif
201 audioDev->monoCaps = stereodevs;
202 }
203
204
205 stereodevs = 0;
206 if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &stereodevs) == -1)
207 {
208 #ifdef IOCTL_DBG
209 if (audioDev->cflags & SLAB_AUDIODBG)
210 #endif
211 printf("Failed to get record capabilities: %08x\n", stereodevs);
212 } else {
213 #ifdef IOCTL_DBG
214 if (audioDev->cflags & SLAB_AUDIODBG)
215 printf("Record Caps: %08x\n", stereodevs);
216 #endif
217 audioDev->recordCaps = stereodevs;
218 }
219
220 #ifdef DEBUG
221 for (i = 1; i < 131072; i = i << 1) {
222 if (i & stereodevs)
223 printf("Found mono dev %08x\n", i);
224 }
225 #endif /* DEBUG */
226 #endif /* linux */
227 }
228
229 char *
getOSSName(controller)230 getOSSName(controller)
231 int controller;
232 {
233 char *name = NULL;
234
235 #if (BRISTOL_HAS_OSS == 1)
236 if ((controller < 0) || (controller > SOUND_MIXER_NRDEVICES))
237 return("none");
238
239 name = SLAB_SND_LABELS[controller];
240 #endif
241 return(name);
242 }
243
244 int
getOSSCapByName(audioDev,name)245 getOSSCapByName(audioDev, name)
246 duplexDev *audioDev;
247 char *name;
248 {
249 #if (BRISTOL_HAS_OSS == 1)
250 int i;
251
252 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
253 {
254 if (strcmp(SLAB_SND_LABELS[i], name) == 0)
255 return i;
256 }
257 #endif
258 return(-1);
259 }
260
261 int
getOSSCapability(audioDev,controller)262 getOSSCapability(audioDev, controller)
263 duplexDev *audioDev;
264 {
265 if ((audioDev->stereoCaps | audioDev->monoCaps) & (1 << controller))
266 return controller;
267 return(-1);
268 }
269
270 int
getOSSRecordability(audioDev,cont)271 getOSSRecordability(audioDev, cont)
272 duplexDev *audioDev;
273 {
274 if (audioDev->cflags & SLAB_AUDIODBG)
275 printf("getOSSRecordability(%i, %i)\n", audioDev->devID, cont);
276
277 if (audioDev->recordCaps & (1<<cont))
278 return(1);
279 /*
280 * -2 indicates no support
281 */
282 return(-2);
283 }
284
285