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