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