xref: /netbsd/sys/dev/audio/audiovar.h (revision d5abd618)
1 /*	$NetBSD: audiovar.h,v 1.13 2023/04/23 08:06:05 mlelstv 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 #include <sys/condvar.h>
71 #include <sys/proc.h>
72 #include <sys/pserialize.h>
73 #include <sys/psref.h>
74 #include <sys/queue.h>
75 
76 #include <dev/audio/audio_if.h>
77 #include <dev/audio/audiofil.h>
78 
79 /*
80  * Whether supports [US]LINEAR24/24 as userland format.
81  */
82 #define AUDIO_SUPPORT_LINEAR24
83 
84 /*
85  * Frequency range.
86  * For lower limit, there are some antique machines who supports under
87  * 4000Hz, so that we accept 1000Hz as lower limit, regardless of
88  * practicality(?).
89  * For upper limit, there are some devices who supports 384000Hz, but
90  * I don't have them. :-)
91  */
92 #define AUDIO_MIN_FREQUENCY (1000)
93 #define AUDIO_MAX_FREQUENCY (192000)
94 
95 typedef struct audio_file audio_file_t;
96 typedef struct audio_trackmixer audio_trackmixer_t;
97 
98 /* ring buffer */
99 typedef struct {
100 	audio_format2_t fmt;	/* format */
101 	int  capacity;		/* capacity by frame */
102 	int  head;		/* head position in frame */
103 	int  used;		/* used frame count */
104 	void *mem;		/* sample ptr */
105 } audio_ring_t;
106 
107 #define AUDIO_N_PORTS 4
108 
109 struct au_mixer_ports {
110 	int	index;		/* index of port-selector mixerctl */
111 	int	master;		/* index of master mixerctl */
112 	int	nports;		/* number of selectable ports */
113 	bool	isenum;		/* selector is enum type */
114 	u_int	allports;	/* all aumasks or'd */
115 	u_int	aumask[AUDIO_N_PORTS];	/* exposed value of "ports" */
116 	int	misel [AUDIO_N_PORTS];	/* ord of port, for selector */
117 	int	miport[AUDIO_N_PORTS];	/* index of port's mixerctl */
118 	bool	isdual;		/* has working mixerout */
119 	int	mixerout;	/* ord of mixerout, for dual case */
120 	int	cur_port;	/* the port that gain actually controls when
121 				   mixerout is selected, for dual case */
122 };
123 
124 struct audio_softc {
125 	/* Myself (e.g.; audio0, audio1, ...) */
126 	device_t	sc_dev;
127 
128 	/* Hardware device struct (e.g.; sb0, hdafg0, ...) */
129 	device_t	hw_dev;
130 
131 	/*
132 	 * Hardware interface and driver handle.
133 	 * hw_if == NULL means that the device is (attached but) disabled.
134 	 */
135 	const struct audio_hw_if *hw_if;
136 	void		*hw_hdl;
137 
138 	/*
139 	 * Properties obtained by get_props().
140 	 * No need any locks to read this variable.
141 	 */
142 	int sc_props;
143 
144 	/*
145 	 * List of opened descriptors.
146 	 * Must be protected by sc_lock || sc_intr_lock for traversal(FOREACH).
147 	 * Must be protected by sc_lock && sc_intr_lock for insertion/removal.
148 	 */
149 	SLIST_HEAD(, audio_file) sc_files;
150 
151 	/*
152 	 * Blocksize in msec.
153 	 * Must be protected by sc_exlock.
154 	 */
155 	int sc_blk_ms;
156 
157 	/*
158 	 * Track mixer for playback and recording.
159 	 * If null, the mixer is disabled.
160 	 * Must be protected by sc_exlock.
161 	 */
162 	audio_trackmixer_t *sc_pmixer;
163 	audio_trackmixer_t *sc_rmixer;
164 
165 	/*
166 	 * Opening track counter.
167 	 * Must be protected by sc_lock && sc_exlock for modifying.
168 	 * Must be protected by sc_lock || sc_exlock for reference.
169 	 */
170 	int sc_popens;
171 	int sc_ropens;
172 
173 	/*
174 	 * true if the track mixer is running.
175 	 * Must be protected by sc_exlock && sc_intr_lock for modifying.
176 	 * Must be protected by sc_exlock || sc_intr_lock for reference.
177 	 */
178 	bool sc_pbusy;
179 	bool sc_rbusy;
180 
181 	/*
182 	 * These four are the parameters sustained with /dev/sound.
183 	 * Must be protected by sc_exlock.
184 	 */
185 	audio_format2_t sc_sound_pparams;
186 	audio_format2_t sc_sound_rparams;
187 	bool 		sc_sound_ppause;
188 	bool		sc_sound_rpause;
189 
190 	/* recent info for /dev/sound */
191 	/* XXX TODO */
192 	struct audio_info sc_ai;
193 
194 	/*
195 	 * Playback(write)/Recording(read) selector.
196 	 * Must be protected by sc_lock.
197 	 */
198 	struct selinfo sc_wsel;
199 	struct selinfo sc_rsel;
200 
201 	/*
202 	 * Processes who want mixer SIGIO.
203 	 * sc_am is an array of pids, or NULL if empty.
204 	 * sc_am_capacity is the number of allocated elements.
205 	 * sc_am_used is the number of elements actually used.
206 	 * Must be protected by sc_exlock.
207 	 */
208 	pid_t *sc_am;
209 	int sc_am_capacity;
210 	int sc_am_used;
211 
212 	/*
213 	 * Thread lock and interrupt lock obtained by get_locks().
214 	 */
215 	kmutex_t *sc_lock;
216 	kmutex_t *sc_intr_lock;
217 
218 	/*
219 	 * Critical section.
220 	 * Must be protected by sc_lock.
221 	 */
222 	int sc_exlock;
223 	kcondvar_t sc_exlockcv;
224 
225 	/*
226 	 * Passive reference to prevent a race between detach and fileops.
227 	 * pserialize_perform(sc_psz) must be protected by sc_lock.
228 	 */
229 	pserialize_t sc_psz;
230 	struct psref_target sc_psref;
231 
232 	/*
233 	 * Must be protected by sc_lock (?)
234 	 */
235 	bool		sc_dying;
236 
237 	/*
238 	 * Indicates that about to suspend.
239 	 * Must be protected by sc_lock.
240 	 */
241 	bool		sc_suspending;
242 
243 	/*
244 	 * If multiuser is false, other users who have different euid
245 	 * than the first user cannot open this device.
246 	 * Must be protected by sc_exlock.
247 	 */
248 	bool sc_multiuser;
249 	kauth_cred_t sc_cred;
250 
251 	struct sysctllog *sc_log;
252 
253 	mixer_ctrl_t	*sc_mixer_state;
254 	int		sc_nmixer_states;
255 	struct au_mixer_ports sc_inports;
256 	struct au_mixer_ports sc_outports;
257 	int		sc_monitor_port;
258 	u_int	sc_lastgain;
259 };
260 
261 #ifdef DIAGNOSTIC
262 #define DIAGNOSTIC_filter_arg(arg) audio_diagnostic_filter_arg(__func__, (arg))
263 #define DIAGNOSTIC_format2(fmt)	audio_diagnostic_format2(__func__, (fmt))
264 extern void audio_diagnostic_filter_arg(const char *,
265 	const audio_filter_arg_t *);
266 extern void audio_diagnostic_format2(const char *, const audio_format2_t *);
267 #else
268 #define DIAGNOSTIC_filter_arg(arg)
269 #define DIAGNOSTIC_format2(fmt)
270 #endif
271 
272 /*
273  * Return true if 'fmt' is the internal format.
274  * It does not check for frequency and number of channels.
275  */
276 static __inline bool
audio_format2_is_internal(const audio_format2_t * fmt)277 audio_format2_is_internal(const audio_format2_t *fmt)
278 {
279 
280 	if (fmt->encoding != AUDIO_ENCODING_SLINEAR_NE)
281 		return false;
282 	if (fmt->precision != AUDIO_INTERNAL_BITS)
283 		return false;
284 	if (fmt->stride != AUDIO_INTERNAL_BITS)
285 		return false;
286 	return true;
287 }
288 
289 /*
290  * Return true if fmt's encoding is one of LINEAR.
291  */
292 static __inline bool
audio_format2_is_linear(const audio_format2_t * fmt)293 audio_format2_is_linear(const audio_format2_t *fmt)
294 {
295 	return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
296 	    || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE)
297 	    || (fmt->encoding == AUDIO_ENCODING_ULINEAR_LE)
298 	    || (fmt->encoding == AUDIO_ENCODING_ULINEAR_BE);
299 }
300 
301 /*
302  * Return true if fmt's encoding is one of SLINEAR.
303  */
304 static __inline bool
audio_format2_is_signed(const audio_format2_t * fmt)305 audio_format2_is_signed(const audio_format2_t *fmt)
306 {
307 	return (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE)
308 	    || (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE);
309 }
310 
311 /*
312  * Return fmt's endian as LITTLE_ENDIAN or BIG_ENDIAN.
313  */
314 static __inline int
audio_format2_endian(const audio_format2_t * fmt)315 audio_format2_endian(const audio_format2_t *fmt)
316 {
317 	if (fmt->stride == 8) {
318 		/* HOST ENDIAN */
319 		return BYTE_ORDER;
320 	}
321 
322 	if (fmt->encoding == AUDIO_ENCODING_SLINEAR_LE ||
323 	    fmt->encoding == AUDIO_ENCODING_ULINEAR_LE) {
324 		return LITTLE_ENDIAN;
325 	}
326 	if (fmt->encoding == AUDIO_ENCODING_SLINEAR_BE ||
327 	    fmt->encoding == AUDIO_ENCODING_ULINEAR_BE) {
328 		return BIG_ENDIAN;
329 	}
330 	return BYTE_ORDER;
331 }
332 
333 /* Interfaces for audiobell. */
334 int audiobellopen(dev_t, audio_file_t **);
335 int audiobellsetrate(audio_file_t *, u_int);
336 int audiobellclose(audio_file_t *);
337 int audiobellwrite(audio_file_t *, struct uio *);
338 
339 #endif /* !_SYS_DEV_AUDIO_AUDIOVAR_H_ */
340