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 */
99typedef 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
106typedef 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
112struct 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
191typedef struct audio_track audio_track_t;
192
193struct 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
223struct 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))
283extern 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 */
291static __inline int
292frametobyte(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 */
300static __inline int
301frame_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 */
310static __inline int
311auring_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 */
329static __inline int
330auring_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 */
340static __inline aint_t *
341auring_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 */
355static __inline aint_t *
356auring_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 */
370static __inline uint8_t *
371auring_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 */
383static __inline uint8_t *
384auring_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 */
393static __inline int
394auring_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)
405static __inline void
406auring_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)
423static __inline void
424auring_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 */
438static __inline int
439auring_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 */
453static __inline int
454auring_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