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