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