audiodef.h revision 1.17 1 1.17 isaki /* $NetBSD: audiodef.h,v 1.17 2022/04/20 06:05:22 isaki Exp $ */
2 1.2 isaki
3 1.2 isaki /*
4 1.2 isaki * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
5 1.2 isaki * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved.
6 1.2 isaki *
7 1.2 isaki * Redistribution and use in source and binary forms, with or without
8 1.2 isaki * modification, are permitted provided that the following conditions
9 1.2 isaki * are met:
10 1.2 isaki * 1. Redistributions of source code must retain the above copyright
11 1.2 isaki * notice, this list of conditions and the following disclaimer.
12 1.2 isaki * 2. Redistributions in binary form must reproduce the above copyright
13 1.2 isaki * notice, this list of conditions and the following disclaimer in the
14 1.2 isaki * documentation and/or other materials provided with the distribution.
15 1.2 isaki *
16 1.2 isaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.2 isaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.2 isaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.2 isaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.2 isaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 1.2 isaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 1.2 isaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 1.2 isaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 1.2 isaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.2 isaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.2 isaki * SUCH DAMAGE.
27 1.2 isaki */
28 1.2 isaki
29 1.2 isaki #ifndef _SYS_DEV_AUDIO_AUDIODEF_H_
30 1.2 isaki #define _SYS_DEV_AUDIO_AUDIODEF_H_
31 1.2 isaki
32 1.8 jmcneill #ifdef _KERNEL_OPT
33 1.8 jmcneill #include "opt_audio.h"
34 1.8 jmcneill #endif
35 1.8 jmcneill
36 1.17 isaki /* Number of blocks in HW buffer. */
37 1.2 isaki #define NBLKHW (3)
38 1.2 isaki
39 1.17 isaki /* Number of blocks in output buffer on playback track. Must be > NBLKHW */
40 1.2 isaki #define NBLKOUT (4)
41 1.2 isaki
42 1.17 isaki /*
43 1.17 isaki * Number of blocks in input buffer on recording track.
44 1.17 isaki *
45 1.17 isaki * For references:
46 1.17 isaki * On 48000Hz/2ch (blk_ms=10), the buffer time is 160 [msec], and
47 1.17 isaki * the input buffer size is 30720 [bytes] (= 1920 [byte/block] * 16).
48 1.17 isaki *
49 1.17 isaki * On 192000Hz/12ch (blk_ms=10), the buffer time is 160 [msec], and
50 1.17 isaki * the input buffer size is 737280 [bytes] (= 46080 [byte/block] * 16).
51 1.17 isaki *
52 1.17 isaki * On 8000Hz/1ch (blk_ms=40), the buffer time is 640 [msec], and
53 1.17 isaki * the input buffer size = 10240 [bytes] (= 640 [byte/block] * 16).
54 1.17 isaki */
55 1.17 isaki #define NBLKIN (16)
56 1.17 isaki
57 1.17 isaki /* Minimum number of blocks in usrbuf on playback track. */
58 1.2 isaki #define AUMINNOBLK (3)
59 1.2 isaki
60 1.2 isaki /*
61 1.2 isaki * Whether the playback mixer use single buffer mode.
62 1.2 isaki * It reduces the latency one block but needs machine power.
63 1.2 isaki * In case of the double buffer (as default), it increases the latency
64 1.2 isaki * but can be expected to stabilize even on slower machines.
65 1.2 isaki */
66 1.2 isaki /* #define AUDIO_HW_SINGLE_BUFFER */
67 1.2 isaki
68 1.2 isaki /*
69 1.2 isaki * Whether supports per-track volume.
70 1.2 isaki * For now, there are no user interfaces to get/set it.
71 1.2 isaki */
72 1.2 isaki /* #define AUDIO_SUPPORT_TRACK_VOLUME */
73 1.2 isaki
74 1.6 isaki /*
75 1.6 isaki * AUDIO_SCALEDOWN()
76 1.6 isaki * This macro should be used for audio wave data only.
77 1.6 isaki *
78 1.6 isaki * The arithmetic shift right (ASR) (in other words, floor()) is good for
79 1.6 isaki * this purpose, and will be faster than division on the most platform.
80 1.6 isaki * The division (in other words, truncate()) is not so bad alternate for
81 1.6 isaki * this purpose, and will be fast enough.
82 1.6 isaki * (Using ASR is 1.9 times faster than division on my amd64, and 1.3 times
83 1.6 isaki * faster on my m68k. -- isaki 201801.)
84 1.6 isaki *
85 1.6 isaki * However, the right shift operator ('>>') for negative integer is
86 1.6 isaki * "implementation defined" behavior in C (note that it's not "undefined"
87 1.6 isaki * behavior). So only if implementation defines '>>' as ASR, we use it.
88 1.6 isaki */
89 1.6 isaki #if defined(__GNUC__)
90 1.6 isaki /* gcc defines '>>' as ASR. */
91 1.6 isaki #define AUDIO_SCALEDOWN(value, bits) ((value) >> (bits))
92 1.6 isaki #else
93 1.6 isaki #define AUDIO_SCALEDOWN(value, bits) ((value) / (1 << (bits)))
94 1.6 isaki #endif
95 1.6 isaki
96 1.15 isaki #if defined(_KERNEL)
97 1.15 isaki
98 1.2 isaki /* conversion stage */
99 1.2 isaki typedef struct {
100 1.2 isaki audio_ring_t srcbuf;
101 1.2 isaki audio_ring_t *dst;
102 1.2 isaki audio_filter_t filter;
103 1.2 isaki audio_filter_arg_t arg;
104 1.2 isaki } audio_stage_t;
105 1.2 isaki
106 1.2 isaki typedef enum {
107 1.2 isaki AUDIO_STATE_CLEAR, /* no data, no need to drain */
108 1.2 isaki AUDIO_STATE_RUNNING, /* need to drain */
109 1.2 isaki AUDIO_STATE_DRAINING, /* now draining */
110 1.2 isaki } audio_state_t;
111 1.2 isaki
112 1.15 isaki struct audio_track {
113 1.2 isaki /*
114 1.2 isaki * AUMODE_PLAY for playback track, or
115 1.16 andvar * AUMODE_RECORD for recording track.
116 1.2 isaki * Note that AUMODE_PLAY_ALL is maintained by file->mode, not here.
117 1.2 isaki */
118 1.2 isaki int mode;
119 1.2 isaki
120 1.2 isaki audio_ring_t usrbuf; /* user i/o buffer */
121 1.2 isaki u_int usrbuf_blksize; /* usrbuf block size in bytes */
122 1.2 isaki struct uvm_object *uobj;
123 1.2 isaki bool mmapped; /* device is mmap()-ed */
124 1.2 isaki u_int usrbuf_stamp; /* transferred bytes from/to stage */
125 1.2 isaki u_int usrbuf_stamp_last; /* last stamp */
126 1.2 isaki u_int usrbuf_usedhigh;/* high water mark in bytes */
127 1.2 isaki u_int usrbuf_usedlow; /* low water mark in bytes */
128 1.2 isaki
129 1.2 isaki /*
130 1.2 isaki * Track input format. It means usrbuf.fmt for playback, or
131 1.2 isaki * mixer->trackfmt for recording.
132 1.2 isaki */
133 1.2 isaki audio_format2_t inputfmt;
134 1.2 isaki
135 1.2 isaki /*
136 1.2 isaki * Pointer to track (conversion stage's) input buffer.
137 1.2 isaki * Must be protected by track lock (only for recording track).
138 1.2 isaki */
139 1.2 isaki audio_ring_t *input;
140 1.2 isaki /*
141 1.2 isaki * Track (conversion stage's) output buffer.
142 1.2 isaki * Must be protected by track lock (only for playback track).
143 1.2 isaki */
144 1.2 isaki audio_ring_t outbuf;
145 1.2 isaki
146 1.2 isaki audio_stage_t codec; /* encoding conversion stage */
147 1.2 isaki audio_stage_t chvol; /* channel volume stage */
148 1.2 isaki audio_stage_t chmix; /* channel mix stage */
149 1.2 isaki audio_stage_t freq; /* frequency conversion stage */
150 1.2 isaki
151 1.2 isaki /* Work area for frequency conversion. */
152 1.2 isaki u_int freq_step; /* src/dst ratio */
153 1.2 isaki u_int freq_current; /* counter */
154 1.2 isaki u_int freq_leap; /* correction counter per block */
155 1.2 isaki aint_t freq_prev[AUDIO_MAX_CHANNELS]; /* previous values */
156 1.2 isaki aint_t freq_curr[AUDIO_MAX_CHANNELS]; /* current values */
157 1.2 isaki
158 1.2 isaki /* Per-channel volumes (0..256) */
159 1.2 isaki uint16_t ch_volume[AUDIO_MAX_CHANNELS];
160 1.2 isaki #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
161 1.2 isaki /* Track volume (0..256) */
162 1.2 isaki u_int volume;
163 1.2 isaki #endif
164 1.2 isaki
165 1.2 isaki audio_trackmixer_t *mixer; /* connected track mixer */
166 1.2 isaki
167 1.2 isaki /* Sequence number picked up by track mixer. */
168 1.2 isaki uint64_t seq;
169 1.2 isaki
170 1.2 isaki audio_state_t pstate; /* playback state */
171 1.2 isaki bool is_pause;
172 1.2 isaki
173 1.2 isaki /* Statistic counters. */
174 1.2 isaki uint64_t inputcounter; /* # of frames input to track */
175 1.2 isaki uint64_t outputcounter; /* # of frames output from track */
176 1.2 isaki uint64_t useriobytes; /* # of bytes xfer to/from userland */
177 1.2 isaki uint64_t dropframes; /* # of frames dropped */
178 1.2 isaki int eofcounter; /* count of zero-sized write */
179 1.2 isaki
180 1.2 isaki /*
181 1.2 isaki * Non-zero if the track is in use.
182 1.2 isaki * Must access atomically.
183 1.2 isaki */
184 1.2 isaki volatile uint lock;
185 1.2 isaki
186 1.2 isaki int id; /* track id for debug */
187 1.15 isaki };
188 1.15 isaki #endif /* _KERNEL */
189 1.15 isaki
190 1.15 isaki typedef struct audio_track audio_track_t;
191 1.2 isaki
192 1.2 isaki struct audio_file {
193 1.2 isaki struct audio_softc *sc;
194 1.2 isaki dev_t dev;
195 1.2 isaki
196 1.2 isaki /*
197 1.2 isaki * Playback and recording track, or NULL if the track is unavailable.
198 1.2 isaki */
199 1.2 isaki audio_track_t *ptrack;
200 1.2 isaki audio_track_t *rtrack;
201 1.2 isaki
202 1.2 isaki /*
203 1.2 isaki * Indicates the operation mode of this file.
204 1.2 isaki * AUMODE_PLAY means playback is requested.
205 1.2 isaki * AUMODE_RECORD means recording is requested.
206 1.2 isaki * AUMODE_PLAY_ALL affects nothing but can be get/set for backward
207 1.2 isaki * compatibility.
208 1.2 isaki */
209 1.2 isaki int mode;
210 1.2 isaki
211 1.2 isaki /* process who wants audio SIGIO. */
212 1.2 isaki pid_t async_audio;
213 1.2 isaki
214 1.10 isaki /* true when closing */
215 1.10 isaki bool dying;
216 1.10 isaki
217 1.2 isaki SLIST_ENTRY(audio_file) entry;
218 1.2 isaki };
219 1.2 isaki
220 1.15 isaki #if defined(_KERNEL)
221 1.15 isaki
222 1.2 isaki struct audio_trackmixer {
223 1.2 isaki struct audio_softc *sc;
224 1.2 isaki
225 1.2 isaki int mode; /* AUMODE_PLAY or AUMODE_RECORD */
226 1.2 isaki audio_format2_t track_fmt; /* track <-> trackmixer format */
227 1.2 isaki
228 1.2 isaki int frames_per_block; /* number of frames in a block */
229 1.2 isaki
230 1.5 isaki /*
231 1.5 isaki * software master volume (0..256)
232 1.5 isaki * Must be protected by sc_intr_lock.
233 1.5 isaki */
234 1.5 isaki u_int volume;
235 1.7 isaki /*
236 1.7 isaki * Volume recovery timer in auto gain control.
237 1.7 isaki * Must be protected by sc_intr_lock.
238 1.7 isaki */
239 1.7 isaki int voltimer;
240 1.2 isaki
241 1.2 isaki audio_format2_t mixfmt;
242 1.2 isaki void *mixsample; /* mixing buf in double-sized int */
243 1.2 isaki
244 1.2 isaki /*
245 1.2 isaki * true if trackmixer does LE<->BE conversion.
246 1.2 isaki * Generally an encoding conversion should be done by each hardware
247 1.2 isaki * driver but for most modern little endian drivers which support
248 1.2 isaki * only linear PCM it's troublesome issue to consider about big endian
249 1.2 isaki * arch. Therefore, we do this conversion here only if the hardware
250 1.2 isaki * format is SLINEAR_OE:16.
251 1.2 isaki */
252 1.2 isaki bool swap_endian;
253 1.2 isaki
254 1.2 isaki audio_filter_t codec; /* hardware codec */
255 1.2 isaki audio_filter_arg_t codecarg; /* and its argument */
256 1.2 isaki audio_ring_t codecbuf; /* also used for wide->int conversion */
257 1.2 isaki
258 1.2 isaki audio_ring_t hwbuf; /* HW I/O buf */
259 1.2 isaki
260 1.2 isaki void *sih; /* softint cookie */
261 1.2 isaki
262 1.2 isaki /* Must be protected by sc_lock. */
263 1.2 isaki kcondvar_t outcv;
264 1.2 isaki
265 1.2 isaki uint64_t mixseq; /* seq# currently being mixed */
266 1.2 isaki uint64_t hwseq; /* seq# HW output completed */
267 1.2 isaki
268 1.2 isaki /* initial blktime n/d = AUDIO_BLK_MS / 1000 */
269 1.2 isaki int blktime_n; /* blk time numerator */
270 1.2 isaki int blktime_d; /* blk time denominator */
271 1.2 isaki
272 1.2 isaki /* XXX */
273 1.2 isaki uint64_t hw_complete_counter;
274 1.2 isaki };
275 1.2 isaki
276 1.2 isaki /*
277 1.2 isaki * Audio Ring Buffer.
278 1.2 isaki */
279 1.2 isaki
280 1.2 isaki #ifdef DIAGNOSTIC
281 1.2 isaki #define DIAGNOSTIC_ring(ring) audio_diagnostic_ring(__func__, (ring))
282 1.2 isaki extern void audio_diagnostic_ring(const char *, const audio_ring_t *);
283 1.2 isaki #else
284 1.2 isaki #define DIAGNOSTIC_ring(ring)
285 1.2 isaki #endif
286 1.2 isaki
287 1.2 isaki /*
288 1.2 isaki * Convert number of frames to number of bytes.
289 1.2 isaki */
290 1.2 isaki static __inline int
291 1.2 isaki frametobyte(const audio_format2_t *fmt, int frames)
292 1.2 isaki {
293 1.2 isaki return frames * fmt->channels * fmt->stride / NBBY;
294 1.2 isaki }
295 1.2 isaki
296 1.2 isaki /*
297 1.2 isaki * Return the number of frames per block.
298 1.2 isaki */
299 1.2 isaki static __inline int
300 1.2 isaki frame_per_block(const audio_trackmixer_t *mixer, const audio_format2_t *fmt)
301 1.2 isaki {
302 1.2 isaki return (fmt->sample_rate * mixer->blktime_n + mixer->blktime_d - 1) /
303 1.2 isaki mixer->blktime_d;
304 1.2 isaki }
305 1.2 isaki
306 1.2 isaki /*
307 1.2 isaki * Round idx. idx must be non-negative and less than 2 * capacity.
308 1.2 isaki */
309 1.2 isaki static __inline int
310 1.2 isaki auring_round(const audio_ring_t *ring, int idx)
311 1.2 isaki {
312 1.2 isaki DIAGNOSTIC_ring(ring);
313 1.9 isaki KASSERTMSG(idx >= 0, "idx=%d", idx);
314 1.9 isaki KASSERTMSG(idx < ring->capacity * 2,
315 1.9 isaki "idx=%d ring->capacity=%d", idx, ring->capacity);
316 1.2 isaki
317 1.2 isaki if (idx < ring->capacity) {
318 1.2 isaki return idx;
319 1.2 isaki } else {
320 1.2 isaki return idx - ring->capacity;
321 1.2 isaki }
322 1.2 isaki }
323 1.2 isaki
324 1.2 isaki /*
325 1.2 isaki * Return ring's tail (= head + used) position.
326 1.2 isaki * This position indicates next frame of the last valid frames.
327 1.2 isaki */
328 1.2 isaki static __inline int
329 1.2 isaki auring_tail(const audio_ring_t *ring)
330 1.2 isaki {
331 1.2 isaki return auring_round(ring, ring->head + ring->used);
332 1.2 isaki }
333 1.2 isaki
334 1.2 isaki /*
335 1.2 isaki * Return ring's head pointer.
336 1.2 isaki * This function can be used only if the stride of the 'ring' is equal to
337 1.2 isaki * the internal stride. Don't use this for hw buffer.
338 1.2 isaki */
339 1.2 isaki static __inline aint_t *
340 1.2 isaki auring_headptr_aint(const audio_ring_t *ring)
341 1.2 isaki {
342 1.9 isaki KASSERTMSG(ring->fmt.stride == sizeof(aint_t) * NBBY,
343 1.9 isaki "ring->fmt.stride=%d sizeof(aint_t)*NBBY=%zd",
344 1.9 isaki ring->fmt.stride, sizeof(aint_t) * NBBY);
345 1.2 isaki
346 1.2 isaki return (aint_t *)ring->mem + ring->head * ring->fmt.channels;
347 1.2 isaki }
348 1.2 isaki
349 1.2 isaki /*
350 1.2 isaki * Return ring's tail (= head + used) pointer.
351 1.2 isaki * This function can be used only if the stride of the 'ring' is equal to
352 1.2 isaki * the internal stride. Don't use this for hw buffer.
353 1.2 isaki */
354 1.2 isaki static __inline aint_t *
355 1.2 isaki auring_tailptr_aint(const audio_ring_t *ring)
356 1.2 isaki {
357 1.9 isaki KASSERTMSG(ring->fmt.stride == sizeof(aint_t) * NBBY,
358 1.9 isaki "ring->fmt.stride=%d sizeof(aint_t)*NBBY=%zd",
359 1.9 isaki ring->fmt.stride, sizeof(aint_t) * NBBY);
360 1.2 isaki
361 1.2 isaki return (aint_t *)ring->mem + auring_tail(ring) * ring->fmt.channels;
362 1.2 isaki }
363 1.2 isaki
364 1.2 isaki /*
365 1.2 isaki * Return ring's head pointer.
366 1.2 isaki * This function can be used even if the stride of the 'ring' is equal to
367 1.2 isaki * or not equal to the internal stride.
368 1.2 isaki */
369 1.2 isaki static __inline uint8_t *
370 1.2 isaki auring_headptr(const audio_ring_t *ring)
371 1.2 isaki {
372 1.2 isaki return (uint8_t *)ring->mem +
373 1.2 isaki ring->head * ring->fmt.channels * ring->fmt.stride / NBBY;
374 1.2 isaki }
375 1.2 isaki
376 1.2 isaki /*
377 1.2 isaki * Return ring's tail pointer.
378 1.2 isaki * It points the next position of the last valid frames.
379 1.2 isaki * This function can be used even if the stride of the 'ring' is equal to
380 1.2 isaki * or not equal to the internal stride.
381 1.2 isaki */
382 1.2 isaki static __inline uint8_t *
383 1.2 isaki auring_tailptr(audio_ring_t *ring)
384 1.2 isaki {
385 1.2 isaki return (uint8_t *)ring->mem +
386 1.2 isaki auring_tail(ring) * ring->fmt.channels * ring->fmt.stride / NBBY;
387 1.2 isaki }
388 1.2 isaki
389 1.2 isaki /*
390 1.2 isaki * Return ring's capacity in bytes.
391 1.2 isaki */
392 1.2 isaki static __inline int
393 1.2 isaki auring_bytelen(const audio_ring_t *ring)
394 1.2 isaki {
395 1.2 isaki return frametobyte(&ring->fmt, ring->capacity);
396 1.2 isaki }
397 1.2 isaki
398 1.2 isaki /*
399 1.2 isaki * Take out n frames from head of ring.
400 1.2 isaki * This function only manipurates counters. It doesn't manipurate any
401 1.2 isaki * actual buffer data.
402 1.2 isaki */
403 1.2 isaki #define auring_take(ring, n) auring_take_(__func__, __LINE__, ring, n)
404 1.2 isaki static __inline void
405 1.2 isaki auring_take_(const char *func, int line, audio_ring_t *ring, int n)
406 1.2 isaki {
407 1.2 isaki DIAGNOSTIC_ring(ring);
408 1.2 isaki KASSERTMSG(n >= 0, "called from %s:%d: n=%d", func, line, n);
409 1.2 isaki KASSERTMSG(ring->used >= n, "called from %s:%d: ring->used=%d n=%d",
410 1.2 isaki func, line, ring->used, n);
411 1.2 isaki
412 1.2 isaki ring->head = auring_round(ring, ring->head + n);
413 1.2 isaki ring->used -= n;
414 1.2 isaki }
415 1.2 isaki
416 1.2 isaki /*
417 1.2 isaki * Append n frames into tail of ring.
418 1.2 isaki * This function only manipurates counters. It doesn't manipurate any
419 1.2 isaki * actual buffer data.
420 1.2 isaki */
421 1.2 isaki #define auring_push(ring, n) auring_push_(__func__, __LINE__, ring, n)
422 1.2 isaki static __inline void
423 1.2 isaki auring_push_(const char *func, int line, audio_ring_t *ring, int n)
424 1.2 isaki {
425 1.2 isaki DIAGNOSTIC_ring(ring);
426 1.2 isaki KASSERT(n >= 0);
427 1.2 isaki KASSERTMSG(ring->used + n <= ring->capacity,
428 1.2 isaki "called from %s:%d: ring->used=%d n=%d ring->capacity=%d",
429 1.2 isaki func, line, ring->used, n, ring->capacity);
430 1.2 isaki
431 1.2 isaki ring->used += n;
432 1.2 isaki }
433 1.2 isaki
434 1.2 isaki /*
435 1.2 isaki * Return the number of contiguous frames in used.
436 1.2 isaki */
437 1.2 isaki static __inline int
438 1.2 isaki auring_get_contig_used(const audio_ring_t *ring)
439 1.2 isaki {
440 1.2 isaki DIAGNOSTIC_ring(ring);
441 1.2 isaki
442 1.2 isaki if (ring->head + ring->used <= ring->capacity) {
443 1.2 isaki return ring->used;
444 1.2 isaki } else {
445 1.2 isaki return ring->capacity - ring->head;
446 1.2 isaki }
447 1.2 isaki }
448 1.2 isaki
449 1.2 isaki /*
450 1.2 isaki * Return the number of contiguous free frames.
451 1.2 isaki */
452 1.2 isaki static __inline int
453 1.2 isaki auring_get_contig_free(const audio_ring_t *ring)
454 1.2 isaki {
455 1.2 isaki DIAGNOSTIC_ring(ring);
456 1.2 isaki
457 1.2 isaki if (ring->head + ring->used < ring->capacity) {
458 1.2 isaki return ring->capacity - (ring->head + ring->used);
459 1.2 isaki } else {
460 1.2 isaki return ring->capacity - ring->used;
461 1.2 isaki }
462 1.2 isaki }
463 1.2 isaki
464 1.15 isaki #endif /* _KERNEL */
465 1.15 isaki
466 1.2 isaki #endif /* !_SYS_DEV_AUDIO_AUDIODEF_H_ */
467