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