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/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <unistd.h>
48
49 static char *SLAB_CONVERT_LABELS[32] = \
50 {"Master", "Bass", "Treble", "FM", "PCM", "PC Speaker", "Line", "MIC", \
51 "CD", "Mix ", "Pcm2 ", "Rec ", "Input Gain", "OGain", "none", "none", \
52 "none", "none", "none", "none", "none", "none", (char *) NULL};
53
54 extern int setAudioOSSparam(duplexDev *, int, int, int, int);
55 extern int checkAudioOSScaps(duplexDev *, int, int);
56 extern char * getOSSName(int);
57 extern int getOSSRecordability();
58 extern int getOSSCapByName();
59 extern int getOSSCapability();
60
61 #if (BRISTOL_HAS_ALSA == 1)
62 extern int setAudioALSAparam(duplexDev *, int, char *, int, int);
63 extern int checkAudioALSAcaps(duplexDev *, int);
64 extern void closeALSAmixer(duplexDev *);
65 extern int openALSAmixer(duplexDev *);
66 extern char * getAlsaName(duplexDev *, int);
67 extern int validAlsaDev(duplexDev *, int);
68
69 extern int setAlsaRecordSource();
70 extern int getAlsaRecordability();
71 extern int getAlsaMutability();
72 extern int getAlsaStereoStatus();
73 extern int getAlsaValue();
74 extern int setAlsaValue();
75 extern int setAlsaMute();
76 extern int getAlsaDeviceName();
77 extern int getAlsaCapByName();
78 extern int getAlsaCapability();
79 #endif
80
81 /*
82 * Setup audio parameters with device support.
83 */
84 void
SL_setAudioDevParam2(audioDev,devID,param,left,right)85 SL_setAudioDevParam2(audioDev, devID, param, left, right)
86 duplexDev *audioDev;
87 int param, devID;
88 short left, right;
89 {
90 if ((devID < 0) || (devID >= MAX_DEVICES))
91 return;
92 if (audioDev->cflags & SLAB_NO_CONTROLS)
93 return;
94
95 #if (BRISTOL_HAS_ALSA == 1)
96 if ((audioDev->flags & AUDIO_ALSA) != 0)
97 {
98 /*
99 * These were OSS calls. We only want to interpret a few of them.
100 if (param > 18)
101 return;
102 */
103 /*
104 * We cannot force this on ALSA, since there are likely issues the
105 * controller types - use an interpreted name.
106 */
107 setAudioALSAparam(audioDev, devID, SLAB_CONVERT_LABELS[param],
108 left, right);
109 return;
110 }
111 #endif
112
113 setAudioOSSparam(audioDev, devID, param, left, right);
114 }
115
116 void
mixerClose(audioDev)117 mixerClose(audioDev)
118 duplexDev *audioDev;
119 {
120 #if (BRISTOL_HAS_ALSA == 1)
121 if (audioDev->cflags & SLAB_AUDIODBG)
122 printf("mixerClose()\n");
123
124 if ((audioDev->flags & AUDIO_ALSA) != 0)
125 {
126 closeALSAmixer(audioDev);
127 } else
128 #endif
129 {
130 if (audioDev->mixerFD > 0)
131 close(audioDev->mixerFD);
132 }
133 audioDev->mixerFD = -1;
134 }
135
136 int
mixerOpen(audioDev)137 mixerOpen(audioDev)
138 duplexDev *audioDev;
139 {
140 #if (BRISTOL_HAS_ALSA == 1)
141 if (audioDev->cflags & SLAB_AUDIODBG)
142 printf("mixerOpen()\n");
143
144 if ((audioDev->flags & AUDIO_ALSA) != 0)
145 {
146 audioDev->monoCaps = 0;
147 audioDev->stereoCaps = 0;
148 audioDev->recordCaps = 0;
149 return(openALSAmixer(audioDev));
150 } else
151 #endif
152 {
153 if (audioDev->mixerName[0] != '\0')
154 {
155 audioDev->mixerFD = open(audioDev->mixerName, O_RDWR);
156 }
157 }
158 return(audioDev->mixerFD);
159 }
160
161 char *
getControllerName(audioDev,controller)162 getControllerName(audioDev, controller)
163 duplexDev *audioDev;
164 {
165 #if (BRISTOL_HAS_ALSA == 1)
166 if ((audioDev->flags & AUDIO_ALSA) != 0)
167 return((char *) getAlsaName(audioDev, controller));
168 #endif
169
170 return (char *) getOSSName(controller);
171 }
172
173 int
setRecordSource(audioDev,controller,position)174 setRecordSource(audioDev, controller, position)
175 duplexDev *audioDev;
176 {
177 #if (BRISTOL_HAS_ALSA == 1)
178 if ((audioDev->flags & AUDIO_ALSA) != 0)
179 return setAlsaRecordSource(audioDev, controller, position);
180 #endif
181
182 return -1;
183 }
184
185 int
getRecordability(audioDev,controller)186 getRecordability(audioDev, controller)
187 duplexDev *audioDev;
188 {
189 #if (BRISTOL_HAS_ALSA == 1)
190 if ((audioDev->flags & AUDIO_ALSA) != 0)
191 return getAlsaRecordability(audioDev, controller);
192 #endif
193
194 return getOSSRecordability(audioDev, controller);
195 }
196
197 int
getMutability(audioDev,controller)198 getMutability(audioDev, controller)
199 duplexDev *audioDev;
200 {
201 #if (BRISTOL_HAS_ALSA == 1)
202 if ((audioDev->flags & AUDIO_ALSA) != 0)
203 return getAlsaMutability(audioDev, controller);
204 #endif
205 /*
206 * -3 indicates no ALSA support
207 */
208 return -3;
209 }
210
211 int
getStereoStatus(audioDev,controller)212 getStereoStatus(audioDev, controller)
213 duplexDev *audioDev;
214 {
215 #if (BRISTOL_HAS_ALSA == 1)
216 if ((audioDev->flags & AUDIO_ALSA) != 0)
217 return getAlsaStereoStatus(audioDev, controller);
218 #endif
219 return -1;
220 }
221
222 int
getValue(audioDev,controller,side)223 getValue(audioDev, controller, side)
224 duplexDev *audioDev;
225 {
226 #if (BRISTOL_HAS_ALSA == 1)
227 if ((audioDev->flags & AUDIO_ALSA) != 0)
228 return getAlsaValue(audioDev, controller, side);
229 #endif
230 return -1;
231 }
232
233 int
setAudioValue(audioDev,controller,side,value)234 setAudioValue(audioDev, controller, side, value)
235 duplexDev *audioDev;
236 {
237 if (audioDev->cflags & SLAB_AUDIODBG)
238 printf("setAudioValue(%p, %i, %i, %i)\n", audioDev, controller, side, value);
239 if (audioDev->cflags & SLAB_NO_CONTROLS)
240 {
241 return 0;
242 }
243
244 #if (BRISTOL_HAS_ALSA == 1)
245 if ((audioDev->flags & AUDIO_ALSA) != 0)
246 return setAlsaValue(audioDev, controller, side, value);
247 #endif
248 return -1;
249 }
250
251 int
setAudioMute(audioDev,controller,value)252 setAudioMute(audioDev, controller, value)
253 duplexDev *audioDev;
254 {
255 if (audioDev->cflags & SLAB_AUDIODBG)
256 printf("setAudioMute()\n");
257
258 #if (BRISTOL_HAS_ALSA == 1)
259 if ((audioDev->flags & AUDIO_ALSA) != 0)
260 return setAlsaMute(audioDev, controller, value);
261 #endif
262 return -1;
263 }
264
265 int
getAudioCapByName(audioDev,name)266 getAudioCapByName(audioDev, name)
267 duplexDev *audioDev;
268 char *name;
269 {
270 if (audioDev->cflags & SLAB_AUDIODBG)
271 printf("getAudioCapByName(%s, %s)\n", audioDev->devName, name);
272
273 #if (BRISTOL_HAS_ALSA == 1)
274 if ((audioDev->flags & AUDIO_ALSA) != 0)
275 return getAlsaCapByName(audioDev, name);
276 #endif
277 return getOSSCapByName(audioDev, name);
278 }
279
280 int
getAudioCapability(audioDev,controller)281 getAudioCapability(audioDev, controller)
282 duplexDev *audioDev;
283 {
284 if (audioDev->cflags & SLAB_AUDIODBG)
285 printf("getAudioCapability(%s, %i)\n", audioDev->devName, controller);
286
287 #if (BRISTOL_HAS_ALSA == 1)
288 if ((audioDev->flags & AUDIO_ALSA) != 0)
289 {
290 return getAlsaCapability(audioDev, controller);
291 }
292 #endif
293 return getOSSCapability(audioDev, controller);
294 }
295
296 int
validDev(audioDev,index)297 validDev(audioDev, index)
298 duplexDev *audioDev;
299 {
300 #if (BRISTOL_HAS_ALSA == 1)
301 if ((audioDev->flags & AUDIO_ALSA) != 0)
302 return validAlsaDev(audioDev, index);
303 #endif
304 return(0);
305 }
306
307