audiovar.h revision 1.4.2.3 1 /* $NetBSD: audiovar.h,v 1.4.2.3 2020/04/30 16:05:18 martin Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by TAMURA Kent
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without
50 * specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * From: Header: audiovar.h,v 1.3 93/07/18 14:07:25 mccanne Exp (LBL)
65 */
66
67 #ifndef _SYS_DEV_AUDIO_AUDIOVAR_H_
68 #define _SYS_DEV_AUDIO_AUDIOVAR_H_
69
70 #if defined(_KERNEL)
71 #include <sys/condvar.h>
72 #include <sys/proc.h>
73 #include <sys/pserialize.h>
74 #include <sys/psref.h>
75 #include <sys/queue.h>
76
77 #include <dev/audio/audio_if.h>
78 #include <dev/audio/audiofil.h>
79 #else
80 #include <stdint.h>
81 #include <stdbool.h>
82 #include "compat.h"
83 #include "userland.h"
84 #include "audiofil.h"
85 #endif /* _KERNEL */
86
87 /*
88 * Whether supports [US]LINEAR24/24 as userland format.
89 */
90 /* #define AUDIO_SUPPORT_LINEAR24 */
91
92 /*
93 * Frequency range.
94 * For lower limit, there are some antique machines who supports under
95 * 4000Hz, so that we accept 1000Hz as lower limit, regardless of
96 * practicality(?).
97 * For upper limit, there are some devices who supports 384000Hz, but
98 * I don't have them. :-)
99 */
100 #define AUDIO_MIN_FREQUENCY (1000)
101 #define AUDIO_MAX_FREQUENCY (192000)
102
103 typedef struct audio_file audio_file_t;
104 typedef struct audio_trackmixer audio_trackmixer_t;
105
106 /* ring buffer */
107 typedef struct {
108 audio_format2_t fmt; /* format */
109 int capacity; /* capacity by frame */
110 int head; /* head position in frame */
111 int used; /* used frame count */
112 void *mem; /* sample ptr */
113 } audio_ring_t;
114
115 #define AUDIO_N_PORTS 4
116
117 struct au_mixer_ports {
118 int index; /* index of port-selector mixerctl */
119 int master; /* index of master mixerctl */
120 int nports; /* number of selectable ports */
121 bool isenum; /* selector is enum type */
122 u_int allports; /* all aumasks or'd */
123 u_int aumask[AUDIO_N_PORTS]; /* exposed value of "ports" */
124 int misel [AUDIO_N_PORTS]; /* ord of port, for selector */
125 int miport[AUDIO_N_PORTS]; /* index of port's mixerctl */
126 bool isdual; /* has working mixerout */
127 int mixerout; /* ord of mixerout, for dual case */
128 int cur_port; /* the port that gain actually controls when
129 mixerout is selected, for dual case */
130 };
131
132 struct audio_softc {
133 /* Myself (e.g.; audio0, audio1, ...) */
134 device_t sc_dev;
135
136 /* Hardware device struct (e.g.; sb0, hdafg0, ...) */
137 device_t hw_dev;
138
139 /*
140 * Hardware interface and driver handle.
141 * hw_if == NULL means that the device is (attached but) disabled.
142 */
143 const struct audio_hw_if *hw_if;
144 void *hw_hdl;
145
146 /*
147 * Properties obtained by get_props().
148 * No need any locks to read this variable.
149 */
150 int sc_props;
151
152 /*
153 * List of opened descriptors.
154 * Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH).
155 * Must be protected by sc_lock && sc_intr_lock for insertion/removal.
156 */
157 SLIST_HEAD(, audio_file) sc_files;
158
159 /*
160 * Blocksize in msec.
161 * Must be protected by sc_exlock.
162 */
163 int sc_blk_ms;
164
165 /*
166 * Track mixer for playback and recording.
167 * If null, the mixer is disabled.
168 * Must be protected by sc_exlock.
169 */
170 audio_trackmixer_t *sc_pmixer;
171 audio_trackmixer_t *sc_rmixer;
172
173 /*
174 * Opening track counter.
175 * Must be protected by sc_lock && sc_exlock for modifying.
176 * Must be protected by sc_lock || sc_exlock for reference.
177 */
178 int sc_popens;
179 int sc_ropens;
180
181 /*
182 * true if the track mixer is running.
183 * Must be protected by sc_exlock && sc_intr_lock for modifying.
184 * Must be protected by sc_exlock || sc_intr_lock for reference.
185 */
186 bool sc_pbusy;
187 bool sc_rbusy;
188
189 /*
190 * These four are the parameters sustained with /dev/sound.
191 * Must be protected by sc_exlock.
192 */
193 audio_format2_t sc_sound_pparams;
194 audio_format2_t sc_sound_rparams;
195 bool sc_sound_ppause;
196 bool sc_sound_rpause;
197
198 /* recent info for /dev/sound */
199 /* XXX TODO */
200 struct audio_info sc_ai;
201
202 /*
203 * Playback(write)/Recording(read) selector.
204 * Must be protected by sc_lock.
205 */
206 struct selinfo sc_wsel;
207 struct selinfo sc_rsel;
208
209 /*
210 * Processes who want mixer SIGIO.
211 * sc_am is an array of pids, or NULL if empty.
212 * sc_am_capacity is the number of allocated elements.
213 * sc_am_used is the number of elements actually used.
214 * Must be protected by sc_exlock.
215 */
216 pid_t *sc_am;
217 int sc_am_capacity;
218 int sc_am_used;
219
220 /*
221 * Thread lock and interrupt lock obtained by get_locks().
222 */
223 kmutex_t *sc_lock;
224 kmutex_t *sc_intr_lock;
225
226 /*
227 * Critical section.
228 * Must be protected by sc_lock.
229 */
230 int sc_exlock;
231 kcondvar_t sc_exlockcv;
232
233 /*
234 * Passive reference to prevent a race between detach and fileops.
235 * pserialize_perform(sc_psz) must be protected by sc_lock.
236 */
237 pserialize_t sc_psz;
238 struct psref_target sc_psref;
239
240 /*
241 * Must be protected by sc_lock (?)
242 */
243 bool sc_dying;
244
245 /*
246 * If multiuser is false, other users who have different euid
247 * than the first user cannot open this device.
248 * Must be protected by sc_exlock.
249 */
250 bool sc_multiuser;
251 kauth_cred_t sc_cred;
252
253 struct sysctllog *sc_log;
254
255 mixer_ctrl_t *sc_mixer_state;
256 int sc_nmixer_states;
257 struct au_mixer_ports sc_inports;
258 struct au_mixer_ports sc_outports;
259 int sc_monitor_port;
260 u_int sc_lastgain;
261 };
262
263 #ifdef DIAGNOSTIC
264 #define DIAGNOSTIC_filter_arg(arg) audio_diagnostic_filter_arg(__func__, (arg))
265 #define DIAGNOSTIC_format2(fmt) audio_diagnostic_format2(__func__, (fmt))
266 extern void audio_diagnostic_filter_arg(const char *,
267 const audio_filter_arg_t *);
268 extern void audio_diagnostic_format2(const char *, const audio_format2_t *);
269 #else
270 #define DIAGNOSTIC_filter_arg(arg)
271 #define DIAGNOSTIC_format2(fmt)
272 #endif
273
274 /*
275 * Return true if 'fmt' is the internal format.
276 * It does not check for frequency and number of channels.
277 */
278 static __inline bool
279 audio_format2_is_internal(const audio_format2_t *fmt)
280 {
281
282 if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE)
283 return false;
284 if (fmt->precision != AUDIO_INTERNAL_BITS)
285 return false;
286 if (fmt->stride != AUDIO_INTERNAL_BITS)
287 return false;
288 return true;
289 }
290
291 /*
292 * Return true if fmt's encoding is one of LINEAR.
293 */
294 static __inline bool
295 audio_format2_is_linear(const audio_format2_t *fmt)
296 {
297 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
298 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE)
299 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_LE)
300 || (fmt->encoding == AUDIO_ENCODING_ULINEAR_BE);
301 }
302
303 /*
304 * Return true if fmt's encoding is one of SLINEAR.
305 */
306 static __inline bool
307 audio_format2_is_signed(const audio_format2_t *fmt)
308 {
309 return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
310 || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE);
311 }
312
313 /*
314 * Return fmt's endian as LITTLE_ENDIAN or BIG_ENDIAN.
315 */
316 static __inline int
317 audio_format2_endian(const audio_format2_t *fmt)
318 {
319 if (fmt->stride == 8) {
320 /* HOST ENDIAN */
321 return BYTE_ORDER;
322 }
323
324 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE ||
325 fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) {
326 return LITTLE_ENDIAN;
327 }
328 if (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE ||
329 fmt->encoding == AUDIO_ENCODING_ULINEAR_BE) {
330 return BIG_ENDIAN;
331 }
332 return BYTE_ORDER;
333 }
334
335 /* Interfaces for audiobell. */
336 int audiobellopen(dev_t, audio_file_t **);
337 int audiobellsetrate(audio_file_t *, u_int);
338 int audiobellclose(audio_file_t *);
339 int audiobellwrite(audio_file_t *, struct uio *);
340
341 #endif /* !_SYS_DEV_AUDIO_AUDIOVAR_H_ */
342