audiodef.h revision 1.14 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