Home | History | Annotate | Line # | Download | only in audio
      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
    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
    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
    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
    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 *
    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 *
    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 *
    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 *
    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
    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
    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
    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
    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
    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