xref: /netbsd-src/sys/dev/audio/audiodef.h (revision de41ebe0c0c4d5eb9b5d9a26c73f2f2e847d34e8)
1 /*	$NetBSD: audiodef.h,v 1.20 2022/08/13 06:47:41 isaki Exp $	*/
2 
3 /*
4  * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
5  * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef _SYS_DEV_AUDIO_AUDIODEF_H_
30 #define _SYS_DEV_AUDIO_AUDIODEF_H_
31 
32 #ifdef _KERNEL_OPT
33 #include "opt_audio.h"
34 #endif
35 
36 /* Number of blocks in HW buffer. */
37 #define NBLKHW (3)
38 
39 /* Number of blocks in output buffer on playback track.  Must be > NBLKHW */
40 #define NBLKOUT	(4)
41 
42 /*
43  * Number of blocks in input buffer on recording track.
44  *
45  * For references:
46  *  On 48000Hz/2ch (blk_ms=10), the buffer time is 160 [msec], and
47  *  the input buffer size is 30720 [bytes] (= 1920 [byte/block] * 16).
48  *
49  *  On 192000Hz/12ch (blk_ms=10), the buffer time is 160 [msec], and
50  *  the input buffer size is 737280 [bytes] (= 46080 [byte/block] * 16).
51  *
52  *  On 8000Hz/1ch (blk_ms=40), the buffer time is 640 [msec], and
53  *  the input buffer size = 10240 [bytes] (= 640 [byte/block] * 16).
54  */
55 #define NBLKIN	(16)
56 
57 /* Minimum number of blocks in usrbuf on playback track. */
58 #define AUMINNOBLK	(3)
59 
60 /*
61  * Whether the playback mixer use single buffer mode.
62  * It reduces the latency one block but needs machine power.
63  * In case of the double buffer (as default), it increases the latency
64  * but can be expected to stabilize even on slower machines.
65  */
66 /* #define AUDIO_HW_SINGLE_BUFFER */
67 
68 /*
69  * Whether supports per-track volume.
70  * For now, there are no user interfaces to get/set it.
71  */
72 /* #define AUDIO_SUPPORT_TRACK_VOLUME */
73 
74 /*
75  * AUDIO_SCALEDOWN()
76  * This macro should be used for audio wave data only.
77  *
78  * The arithmetic shift right (ASR) (in other words, floor()) is good for
79  * this purpose, and will be faster than division on the most platform.
80  * The division (in other words, truncate()) is not so bad alternate for
81  * this purpose, and will be fast enough.
82  * (Using ASR is 1.9 times faster than division on my amd64, and 1.3 times
83  * faster on my m68k.  -- isaki 201801.)
84  *
85  * However, the right shift operator ('>>') for negative integer is
86  * "implementation defined" behavior in C (note that it's not "undefined"
87  * behavior).  So only if implementation defines '>>' as ASR, we use it.
88  */
89 #if defined(__GNUC__)
90 /* gcc defines '>>' as ASR. */
91 #define AUDIO_SCALEDOWN(value, bits)	((value) >> (bits))
92 #else
93 #define AUDIO_SCALEDOWN(value, bits)	((value) / (1 << (bits)))
94 #endif
95 
96 #if defined(_KERNEL)
97 
98 /* conversion stage */
99 typedef struct {
100 	audio_ring_t srcbuf;
101 	audio_ring_t *dst;
102 	audio_filter_t filter;
103 	audio_filter_arg_t arg;
104 } audio_stage_t;
105 
106 typedef enum {
107 	AUDIO_STATE_CLEAR,	/* no data, no need to drain */
108 	AUDIO_STATE_RUNNING,	/* need to drain */
109 	AUDIO_STATE_DRAINING,	/* now draining */
110 } audio_state_t;
111 
112 struct audio_track {
113 	/*
114 	 * AUMODE_PLAY for playback track, or
115 	 * AUMODE_RECORD for recording track.
116 	 * Note that AUMODE_PLAY_ALL is maintained by file->mode, not here.
117 	 */
118 	int mode;
119 
120 	audio_ring_t	usrbuf;		/* user i/o buffer */
121 	u_int		usrbuf_blksize;	/* usrbuf block size in bytes */
122 	u_int		usrbuf_allocsize; /* allocation size in bytes */
123 	bool		mmapped;	/* device is mmap()-ed */
124 	u_int		usrbuf_usedhigh;/* high water mark in bytes */
125 	u_int		usrbuf_usedlow;	/* low water mark in bytes */
126 
127 	/*
128 	 * Track input format.  It means usrbuf.fmt for playback, or
129 	 * mixer->trackfmt for recording.
130 	 */
131 	audio_format2_t	inputfmt;
132 
133 	/*
134 	 * Pointer to track (conversion stage's) input buffer.
135 	 * Must be protected by track lock (only for recording track).
136 	 */
137 	audio_ring_t	*input;
138 	/*
139 	 * Track (conversion stage's) output buffer.
140 	 * Must be protected by track lock (only for playback track).
141 	 */
142 	audio_ring_t	outbuf;
143 
144 	audio_stage_t	codec;		/* encoding conversion stage */
145 	audio_stage_t	chvol;		/* channel volume stage */
146 	audio_stage_t	chmix;		/* channel mix stage */
147 	audio_stage_t	freq;		/* frequency conversion stage */
148 
149 	/* Work area for frequency conversion.  */
150 	u_int		freq_step;	/* src/dst ratio */
151 	u_int		freq_current;	/* counter */
152 	u_int		freq_leap;	/* correction counter per block */
153 	aint_t		freq_prev[AUDIO_MAX_CHANNELS];	/* previous values */
154 	aint_t		freq_curr[AUDIO_MAX_CHANNELS];	/* current values */
155 
156 	/* Per-channel volumes (0..256) */
157 	uint16_t ch_volume[AUDIO_MAX_CHANNELS];
158 #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
159 	/* Track volume (0..256) */
160 	u_int		volume;
161 #endif
162 
163 	/*
164 	 * For AUDIO_GET[IO]OFFS.
165 	 * No locks are required for these.
166 	 */
167 	u_int		stamp;		/* number of transferred blocks */
168 	u_int		last_stamp;
169 
170 	audio_trackmixer_t *mixer;	/* connected track mixer */
171 
172 	/* Sequence number picked up by track mixer. */
173 	uint64_t	seq;
174 
175 	audio_state_t	pstate;		/* playback state */
176 	bool		is_pause;
177 
178 	uint64_t	dropframes;	/* number of dropped frames */
179 	int		eofcounter;	/* count of zero-sized write */
180 
181 	/*
182 	 * Non-zero if the track is in use.
183 	 * Must access atomically.
184 	 */
185 	volatile uint	lock;
186 
187 	int		id;		/* track id for debug */
188 };
189 #endif /* _KERNEL */
190 
191 typedef struct audio_track audio_track_t;
192 
193 struct audio_file {
194 	struct audio_softc *sc;
195 	dev_t		dev;
196 
197 	/*
198 	 * Playback and recording track, or NULL if the track is unavailable.
199 	 */
200 	audio_track_t	*ptrack;
201 	audio_track_t	*rtrack;
202 
203 	/*
204 	 * Indicates the operation mode of this file.
205 	 * AUMODE_PLAY means playback is requested.
206 	 * AUMODE_RECORD means recording is requested.
207 	 * AUMODE_PLAY_ALL affects nothing but can be get/set for backward
208 	 * compatibility.
209 	 */
210 	int		mode;
211 
212 	/* process who wants audio SIGIO. */
213 	pid_t		async_audio;
214 
215 	/* true when closing */
216 	bool		dying;
217 
218 	SLIST_ENTRY(audio_file) entry;
219 };
220 
221 #if defined(_KERNEL)
222 
223 struct audio_trackmixer {
224 	struct audio_softc *sc;
225 
226 	int		mode;		/* AUMODE_PLAY or AUMODE_RECORD */
227 	audio_format2_t	track_fmt;	/* track <-> trackmixer format */
228 
229 	int		frames_per_block; /* number of frames in a block */
230 
231 	/*
232 	 * software master volume (0..256)
233 	 * Must be protected by sc_intr_lock.
234 	 */
235 	u_int		volume;
236 	/*
237 	 * Volume recovery timer in auto gain control.
238 	 * Must be protected by sc_intr_lock.
239 	 */
240 	int		voltimer;
241 
242 	audio_format2_t	mixfmt;
243 	void		*mixsample;	/* mixing buf in double-sized int */
244 
245 	/*
246 	 * true if trackmixer does LE<->BE conversion.
247 	 * Generally an encoding conversion should be done by each hardware
248 	 * driver but for most modern little endian drivers which support
249 	 * only linear PCM it's troublesome issue to consider about big endian
250 	 * arch.  Therefore, we do this conversion here only if the hardware
251 	 * format is SLINEAR_OE:16.
252 	 */
253 	bool		swap_endian;
254 
255 	audio_filter_t	codec;		/* hardware codec */
256 	audio_filter_arg_t codecarg;	/* and its argument */
257 	audio_ring_t	codecbuf;	/* also used for wide->int conversion */
258 
259 	audio_ring_t	hwbuf;		/* HW I/O buf */
260 
261 	void		*sih;		/* softint cookie */
262 
263 	/* Must be protected by sc_lock. */
264 	kcondvar_t	outcv;
265 
266 	uint64_t	mixseq;		/* seq# currently being mixed */
267 	uint64_t	hwseq;		/* seq# HW output completed */
268 
269 	/* initial blktime n/d = AUDIO_BLK_MS / 1000 */
270 	int		blktime_n;	/* blk time numerator */
271 	int		blktime_d;	/* blk time denominator */
272 
273 	/* XXX */
274 	uint64_t	hw_complete_counter;
275 };
276 
277 /*
278  * Audio Ring Buffer.
279  */
280 
281 #ifdef DIAGNOSTIC
282 #define DIAGNOSTIC_ring(ring)	audio_diagnostic_ring(__func__, (ring))
283 extern void audio_diagnostic_ring(const char *, const audio_ring_t *);
284 #else
285 #define DIAGNOSTIC_ring(ring)
286 #endif
287 
288 /*
289  * Convert number of frames to number of bytes.
290  */
291 static __inline int
frametobyte(const audio_format2_t * fmt,int frames)292 frametobyte(const audio_format2_t *fmt, int frames)
293 {
294 	return frames * fmt->channels * fmt->stride / NBBY;
295 }
296 
297 /*
298  * Return the number of frames per block.
299  */
300 static __inline int
frame_per_block(const audio_trackmixer_t * mixer,const audio_format2_t * fmt)301 frame_per_block(const audio_trackmixer_t *mixer, const audio_format2_t *fmt)
302 {
303 	return (fmt->sample_rate * mixer->blktime_n + mixer->blktime_d - 1) /
304 	    mixer->blktime_d;
305 }
306 
307 /*
308  * Round idx.  idx must be non-negative and less than 2 * capacity.
309  */
310 static __inline int
auring_round(const audio_ring_t * ring,int idx)311 auring_round(const audio_ring_t *ring, int idx)
312 {
313 	DIAGNOSTIC_ring(ring);
314 	KASSERTMSG(idx >= 0, "idx=%d", idx);
315 	KASSERTMSG(idx < ring->capacity * 2,
316 	    "idx=%d ring->capacity=%d", idx, ring->capacity);
317 
318 	if (idx < ring->capacity) {
319 		return idx;
320 	} else {
321 		return idx - ring->capacity;
322 	}
323 }
324 
325 /*
326  * Return ring's tail (= head + used) position.
327  * This position indicates next frame of the last valid frames.
328  */
329 static __inline int
auring_tail(const audio_ring_t * ring)330 auring_tail(const audio_ring_t *ring)
331 {
332 	return auring_round(ring, ring->head + ring->used);
333 }
334 
335 /*
336  * Return ring's head pointer.
337  * This function can be used only if the stride of the 'ring' is equal to
338  * the internal stride.  Don't use this for hw buffer.
339  */
340 static __inline aint_t *
auring_headptr_aint(const audio_ring_t * ring)341 auring_headptr_aint(const audio_ring_t *ring)
342 {
343 	KASSERTMSG(ring->fmt.stride == sizeof(aint_t) * NBBY,
344 	    "ring->fmt.stride=%d sizeof(aint_t)*NBBY=%zd",
345 	    ring->fmt.stride, sizeof(aint_t) * NBBY);
346 
347 	return (aint_t *)ring->mem + ring->head * ring->fmt.channels;
348 }
349 
350 /*
351  * Return ring's tail (= head + used) pointer.
352  * This function can be used only if the stride of the 'ring' is equal to
353  * the internal stride.  Don't use this for hw buffer.
354  */
355 static __inline aint_t *
auring_tailptr_aint(const audio_ring_t * ring)356 auring_tailptr_aint(const audio_ring_t *ring)
357 {
358 	KASSERTMSG(ring->fmt.stride == sizeof(aint_t) * NBBY,
359 	    "ring->fmt.stride=%d sizeof(aint_t)*NBBY=%zd",
360 	    ring->fmt.stride, sizeof(aint_t) * NBBY);
361 
362 	return (aint_t *)ring->mem + auring_tail(ring) * ring->fmt.channels;
363 }
364 
365 /*
366  * Return ring's head pointer.
367  * This function can be used even if the stride of the 'ring' is equal to
368  * or not equal to the internal stride.
369  */
370 static __inline uint8_t *
auring_headptr(const audio_ring_t * ring)371 auring_headptr(const audio_ring_t *ring)
372 {
373 	return (uint8_t *)ring->mem +
374 	    ring->head * ring->fmt.channels * ring->fmt.stride / NBBY;
375 }
376 
377 /*
378  * Return ring's tail pointer.
379  * It points the next position of the last valid frames.
380  * This function can be used even if the stride of the 'ring' is equal to
381  * or not equal to the internal stride.
382  */
383 static __inline uint8_t *
auring_tailptr(audio_ring_t * ring)384 auring_tailptr(audio_ring_t *ring)
385 {
386 	return (uint8_t *)ring->mem +
387 	    auring_tail(ring) * ring->fmt.channels * ring->fmt.stride / NBBY;
388 }
389 
390 /*
391  * Return ring's capacity in bytes.
392  */
393 static __inline int
auring_bytelen(const audio_ring_t * ring)394 auring_bytelen(const audio_ring_t *ring)
395 {
396 	return frametobyte(&ring->fmt, ring->capacity);
397 }
398 
399 /*
400  * Take out n frames from head of ring.
401  * This function only manipurates counters.  It doesn't manipurate any
402  * actual buffer data.
403  */
404 #define auring_take(ring, n)	auring_take_(__func__, __LINE__, ring, n)
405 static __inline void
auring_take_(const char * func,int line,audio_ring_t * ring,int n)406 auring_take_(const char *func, int line, audio_ring_t *ring, int n)
407 {
408 	DIAGNOSTIC_ring(ring);
409 	KASSERTMSG(n >= 0, "called from %s:%d: n=%d", func, line, n);
410 	KASSERTMSG(ring->used >= n, "called from %s:%d: ring->used=%d n=%d",
411 	    func, line, ring->used, n);
412 
413 	ring->head = auring_round(ring, ring->head + n);
414 	ring->used -= n;
415 }
416 
417 /*
418  * Append n frames into tail of ring.
419  * This function only manipurates counters.  It doesn't manipurate any
420  * actual buffer data.
421  */
422 #define auring_push(ring, n)	auring_push_(__func__, __LINE__, ring, n)
423 static __inline void
auring_push_(const char * func,int line,audio_ring_t * ring,int n)424 auring_push_(const char *func, int line, audio_ring_t *ring, int n)
425 {
426 	DIAGNOSTIC_ring(ring);
427 	KASSERT(n >= 0);
428 	KASSERTMSG(ring->used + n <= ring->capacity,
429 	    "called from %s:%d: ring->used=%d n=%d ring->capacity=%d",
430 	    func, line, ring->used, n, ring->capacity);
431 
432 	ring->used += n;
433 }
434 
435 /*
436  * Return the number of contiguous frames in used.
437  */
438 static __inline int
auring_get_contig_used(const audio_ring_t * ring)439 auring_get_contig_used(const audio_ring_t *ring)
440 {
441 	DIAGNOSTIC_ring(ring);
442 
443 	if (ring->head + ring->used <= ring->capacity) {
444 		return ring->used;
445 	} else {
446 		return ring->capacity - ring->head;
447 	}
448 }
449 
450 /*
451  * Return the number of contiguous free frames.
452  */
453 static __inline int
auring_get_contig_free(const audio_ring_t * ring)454 auring_get_contig_free(const audio_ring_t *ring)
455 {
456 	DIAGNOSTIC_ring(ring);
457 
458 	if (ring->head + ring->used < ring->capacity) {
459 		return ring->capacity - (ring->head + ring->used);
460 	} else {
461 		return ring->capacity - ring->used;
462 	}
463 }
464 
465 #endif /* _KERNEL */
466 
467 #endif /* !_SYS_DEV_AUDIO_AUDIODEF_H_ */
468