Thu Jan 2 09:18:15 2020 UTC ()
Pull up following revision(s) (requested by isaki in ticket #593):

	sys/dev/audio/audio.c: revision 1.34
	sys/dev/audio/audio.c: revision 1.35

Use M_WAITOK instead of M_NOWAIT.
These allocations don't require NOWAIT constraints.

Will fix PR kern/54796.

 -

Improve and simplify around audio_realloc().


(martin)
diff -r1.28.2.4 -r1.28.2.5 src/sys/dev/audio/audio.c

cvs diff -r1.28.2.4 -r1.28.2.5 src/sys/dev/audio/audio.c (switch to unified diff)

--- src/sys/dev/audio/audio.c 2019/11/19 12:58:29 1.28.2.4
+++ src/sys/dev/audio/audio.c 2020/01/02 09:18:15 1.28.2.5
@@ -1,1144 +1,1144 @@ @@ -1,1144 +1,1144 @@
1/* $NetBSD: audio.c,v 1.28.2.4 2019/11/19 12:58:29 martin Exp $ */ 1/* $NetBSD: audio.c,v 1.28.2.5 2020/01/02 09:18:15 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1991-1993 Regents of the University of California. 33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems 46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory. 47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used 48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without 49 * to endorse or promote products derived from this software without
50 * specific prior written permission. 50 * specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 */ 63 */
64 64
65/* 65/*
66 * Locking: there are three locks per device. 66 * Locking: there are three locks per device.
67 * 67 *
68 * - sc_lock, provided by the underlying driver. This is an adaptive lock, 68 * - sc_lock, provided by the underlying driver. This is an adaptive lock,
69 * returned in the second parameter to hw_if->get_locks(). It is known 69 * returned in the second parameter to hw_if->get_locks(). It is known
70 * as the "thread lock". 70 * as the "thread lock".
71 * 71 *
72 * It serializes access to state in all places except the 72 * It serializes access to state in all places except the
73 * driver's interrupt service routine. This lock is taken from process 73 * driver's interrupt service routine. This lock is taken from process
74 * context (example: access to /dev/audio). It is also taken from soft 74 * context (example: access to /dev/audio). It is also taken from soft
75 * interrupt handlers in this module, primarily to serialize delivery of 75 * interrupt handlers in this module, primarily to serialize delivery of
76 * wakeups. This lock may be used/provided by modules external to the 76 * wakeups. This lock may be used/provided by modules external to the
77 * audio subsystem, so take care not to introduce a lock order problem. 77 * audio subsystem, so take care not to introduce a lock order problem.
78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD. 78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD.
79 * 79 *
80 * - sc_intr_lock, provided by the underlying driver. This may be either a 80 * - sc_intr_lock, provided by the underlying driver. This may be either a
81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or 81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or
82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It 82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It
83 * is known as the "interrupt lock". 83 * is known as the "interrupt lock".
84 * 84 *
85 * It provides atomic access to the device's hardware state, and to audio 85 * It provides atomic access to the device's hardware state, and to audio
86 * channel data that may be accessed by the hardware driver's ISR. 86 * channel data that may be accessed by the hardware driver's ISR.
87 * In all places outside the ISR, sc_lock must be held before taking 87 * In all places outside the ISR, sc_lock must be held before taking
88 * sc_intr_lock. This is to ensure that groups of hardware operations are 88 * sc_intr_lock. This is to ensure that groups of hardware operations are
89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD. 89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD.
90 * 90 *
91 * - sc_exlock, private to this module. This is a variable protected by 91 * - sc_exlock, private to this module. This is a variable protected by
92 * sc_lock. It is known as the "critical section". 92 * sc_lock. It is known as the "critical section".
93 * Some operations release sc_lock in order to allocate memory, to wait 93 * Some operations release sc_lock in order to allocate memory, to wait
94 * for in-flight I/O to complete, to copy to/from user context, etc. 94 * for in-flight I/O to complete, to copy to/from user context, etc.
95 * sc_exlock provides a critical section even under the circumstance. 95 * sc_exlock provides a critical section even under the circumstance.
96 * "+" in following list indicates the interfaces which necessary to be 96 * "+" in following list indicates the interfaces which necessary to be
97 * protected by sc_exlock. 97 * protected by sc_exlock.
98 * 98 *
99 * List of hardware interface methods, and which locks are held when each 99 * List of hardware interface methods, and which locks are held when each
100 * is called by this module: 100 * is called by this module:
101 * 101 *
102 * METHOD INTR THREAD NOTES 102 * METHOD INTR THREAD NOTES
103 * ----------------------- ------- ------- ------------------------- 103 * ----------------------- ------- ------- -------------------------
104 * open x x + 104 * open x x +
105 * close x x + 105 * close x x +
106 * query_format - x 106 * query_format - x
107 * set_format - x 107 * set_format - x
108 * round_blocksize - x 108 * round_blocksize - x
109 * commit_settings - x 109 * commit_settings - x
110 * init_output x x 110 * init_output x x
111 * init_input x x 111 * init_input x x
112 * start_output x x + 112 * start_output x x +
113 * start_input x x + 113 * start_input x x +
114 * halt_output x x + 114 * halt_output x x +
115 * halt_input x x + 115 * halt_input x x +
116 * speaker_ctl x x 116 * speaker_ctl x x
117 * getdev - x 117 * getdev - x
118 * set_port - x + 118 * set_port - x +
119 * get_port - x + 119 * get_port - x +
120 * query_devinfo - x 120 * query_devinfo - x
121 * allocm - - + (*1) 121 * allocm - - + (*1)
122 * freem - - + (*1) 122 * freem - - + (*1)
123 * round_buffersize - x 123 * round_buffersize - x
124 * get_props - x Called at attach time 124 * get_props - x Called at attach time
125 * trigger_output x x + 125 * trigger_output x x +
126 * trigger_input x x + 126 * trigger_input x x +
127 * dev_ioctl - x 127 * dev_ioctl - x
128 * get_locks - - Called at attach time 128 * get_locks - - Called at attach time
129 * 129 *
130 * *1 Note: Before 8.0, since these have been called only at attach time, 130 * *1 Note: Before 8.0, since these have been called only at attach time,
131 * neither lock were necessary. Currently, on the other hand, since 131 * neither lock were necessary. Currently, on the other hand, since
132 * these may be also called after attach, the thread lock is required. 132 * these may be also called after attach, the thread lock is required.
133 * 133 *
134 * In addition, there is an additional lock. 134 * In addition, there is an additional lock.
135 * 135 *
136 * - track->lock. This is an atomic variable and is similar to the 136 * - track->lock. This is an atomic variable and is similar to the
137 * "interrupt lock". This is one for each track. If any thread context 137 * "interrupt lock". This is one for each track. If any thread context
138 * (and software interrupt context) and hardware interrupt context who 138 * (and software interrupt context) and hardware interrupt context who
139 * want to access some variables on this track, they must acquire this 139 * want to access some variables on this track, they must acquire this
140 * lock before. It protects track's consistency between hardware 140 * lock before. It protects track's consistency between hardware
141 * interrupt context and others. 141 * interrupt context and others.
142 */ 142 */
143 143
144#include <sys/cdefs.h> 144#include <sys/cdefs.h>
145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.4 2019/11/19 12:58:29 martin Exp $"); 145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.5 2020/01/02 09:18:15 martin Exp $");
146 146
147#ifdef _KERNEL_OPT 147#ifdef _KERNEL_OPT
148#include "audio.h" 148#include "audio.h"
149#include "midi.h" 149#include "midi.h"
150#endif 150#endif
151 151
152#if NAUDIO > 0 152#if NAUDIO > 0
153 153
154#ifdef _KERNEL 154#ifdef _KERNEL
155 155
156#include <sys/types.h> 156#include <sys/types.h>
157#include <sys/param.h> 157#include <sys/param.h>
158#include <sys/atomic.h> 158#include <sys/atomic.h>
159#include <sys/audioio.h> 159#include <sys/audioio.h>
160#include <sys/conf.h> 160#include <sys/conf.h>
161#include <sys/cpu.h> 161#include <sys/cpu.h>
162#include <sys/device.h> 162#include <sys/device.h>
163#include <sys/fcntl.h> 163#include <sys/fcntl.h>
164#include <sys/file.h> 164#include <sys/file.h>
165#include <sys/filedesc.h> 165#include <sys/filedesc.h>
166#include <sys/intr.h> 166#include <sys/intr.h>
167#include <sys/ioctl.h> 167#include <sys/ioctl.h>
168#include <sys/kauth.h> 168#include <sys/kauth.h>
169#include <sys/kernel.h> 169#include <sys/kernel.h>
170#include <sys/kmem.h> 170#include <sys/kmem.h>
171#include <sys/malloc.h> 171#include <sys/malloc.h>
172#include <sys/mman.h> 172#include <sys/mman.h>
173#include <sys/module.h> 173#include <sys/module.h>
174#include <sys/poll.h> 174#include <sys/poll.h>
175#include <sys/proc.h> 175#include <sys/proc.h>
176#include <sys/queue.h> 176#include <sys/queue.h>
177#include <sys/select.h> 177#include <sys/select.h>
178#include <sys/signalvar.h> 178#include <sys/signalvar.h>
179#include <sys/stat.h> 179#include <sys/stat.h>
180#include <sys/sysctl.h> 180#include <sys/sysctl.h>
181#include <sys/systm.h> 181#include <sys/systm.h>
182#include <sys/syslog.h> 182#include <sys/syslog.h>
183#include <sys/vnode.h> 183#include <sys/vnode.h>
184 184
185#include <dev/audio/audio_if.h> 185#include <dev/audio/audio_if.h>
186#include <dev/audio/audiovar.h> 186#include <dev/audio/audiovar.h>
187#include <dev/audio/audiodef.h> 187#include <dev/audio/audiodef.h>
188#include <dev/audio/linear.h> 188#include <dev/audio/linear.h>
189#include <dev/audio/mulaw.h> 189#include <dev/audio/mulaw.h>
190 190
191#include <machine/endian.h> 191#include <machine/endian.h>
192 192
193#include <uvm/uvm.h> 193#include <uvm/uvm.h>
194 194
195#include "ioconf.h" 195#include "ioconf.h"
196#endif /* _KERNEL */ 196#endif /* _KERNEL */
197 197
198/* 198/*
199 * 0: No debug logs 199 * 0: No debug logs
200 * 1: action changes like open/close/set_format... 200 * 1: action changes like open/close/set_format...
201 * 2: + normal operations like read/write/ioctl... 201 * 2: + normal operations like read/write/ioctl...
202 * 3: + TRACEs except interrupt 202 * 3: + TRACEs except interrupt
203 * 4: + TRACEs including interrupt 203 * 4: + TRACEs including interrupt
204 */ 204 */
205//#define AUDIO_DEBUG 1 205//#define AUDIO_DEBUG 1
206 206
207#if defined(AUDIO_DEBUG) 207#if defined(AUDIO_DEBUG)
208 208
209int audiodebug = AUDIO_DEBUG; 209int audiodebug = AUDIO_DEBUG;
210static void audio_vtrace(struct audio_softc *sc, const char *, const char *, 210static void audio_vtrace(struct audio_softc *sc, const char *, const char *,
211 const char *, va_list); 211 const char *, va_list);
212static void audio_trace(struct audio_softc *sc, const char *, const char *, ...) 212static void audio_trace(struct audio_softc *sc, const char *, const char *, ...)
213 __printflike(3, 4); 213 __printflike(3, 4);
214static void audio_tracet(const char *, audio_track_t *, const char *, ...) 214static void audio_tracet(const char *, audio_track_t *, const char *, ...)
215 __printflike(3, 4); 215 __printflike(3, 4);
216static void audio_tracef(const char *, audio_file_t *, const char *, ...) 216static void audio_tracef(const char *, audio_file_t *, const char *, ...)
217 __printflike(3, 4); 217 __printflike(3, 4);
218 218
219/* XXX sloppy memory logger */ 219/* XXX sloppy memory logger */
220static void audio_mlog_init(void); 220static void audio_mlog_init(void);
221static void audio_mlog_free(void); 221static void audio_mlog_free(void);
222static void audio_mlog_softintr(void *); 222static void audio_mlog_softintr(void *);
223extern void audio_mlog_flush(void); 223extern void audio_mlog_flush(void);
224extern void audio_mlog_printf(const char *, ...); 224extern void audio_mlog_printf(const char *, ...);
225 225
226static int mlog_refs; /* reference counter */ 226static int mlog_refs; /* reference counter */
227static char *mlog_buf[2]; /* double buffer */ 227static char *mlog_buf[2]; /* double buffer */
228static int mlog_buflen; /* buffer length */ 228static int mlog_buflen; /* buffer length */
229static int mlog_used; /* used length */ 229static int mlog_used; /* used length */
230static int mlog_full; /* number of dropped lines by buffer full */ 230static int mlog_full; /* number of dropped lines by buffer full */
231static int mlog_drop; /* number of dropped lines by busy */ 231static int mlog_drop; /* number of dropped lines by busy */
232static volatile uint32_t mlog_inuse; /* in-use */ 232static volatile uint32_t mlog_inuse; /* in-use */
233static int mlog_wpage; /* active page */ 233static int mlog_wpage; /* active page */
234static void *mlog_sih; /* softint handle */ 234static void *mlog_sih; /* softint handle */
235 235
236static void 236static void
237audio_mlog_init(void) 237audio_mlog_init(void)
238{ 238{
239 mlog_refs++; 239 mlog_refs++;
240 if (mlog_refs > 1) 240 if (mlog_refs > 1)
241 return; 241 return;
242 mlog_buflen = 4096; 242 mlog_buflen = 4096;
243 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP); 243 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP);
244 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP); 244 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP);
245 mlog_used = 0; 245 mlog_used = 0;
246 mlog_full = 0; 246 mlog_full = 0;
247 mlog_drop = 0; 247 mlog_drop = 0;
248 mlog_inuse = 0; 248 mlog_inuse = 0;
249 mlog_wpage = 0; 249 mlog_wpage = 0;
250 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL); 250 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL);
251 if (mlog_sih == NULL) 251 if (mlog_sih == NULL)
252 printf("%s: softint_establish failed\n", __func__); 252 printf("%s: softint_establish failed\n", __func__);
253} 253}
254 254
255static void 255static void
256audio_mlog_free(void) 256audio_mlog_free(void)
257{ 257{
258 mlog_refs--; 258 mlog_refs--;
259 if (mlog_refs > 0) 259 if (mlog_refs > 0)
260 return; 260 return;
261 261
262 audio_mlog_flush(); 262 audio_mlog_flush();
263 if (mlog_sih) 263 if (mlog_sih)
264 softint_disestablish(mlog_sih); 264 softint_disestablish(mlog_sih);
265 kmem_free(mlog_buf[0], mlog_buflen); 265 kmem_free(mlog_buf[0], mlog_buflen);
266 kmem_free(mlog_buf[1], mlog_buflen); 266 kmem_free(mlog_buf[1], mlog_buflen);
267} 267}
268 268
269/* 269/*
270 * Flush memory buffer. 270 * Flush memory buffer.
271 * It must not be called from hardware interrupt context. 271 * It must not be called from hardware interrupt context.
272 */ 272 */
273void 273void
274audio_mlog_flush(void) 274audio_mlog_flush(void)
275{ 275{
276 if (mlog_refs == 0) 276 if (mlog_refs == 0)
277 return; 277 return;
278 278
279 /* Nothing to do if already in use ? */ 279 /* Nothing to do if already in use ? */
280 if (atomic_swap_32(&mlog_inuse, 1) == 1) 280 if (atomic_swap_32(&mlog_inuse, 1) == 1)
281 return; 281 return;
282 282
283 int rpage = mlog_wpage; 283 int rpage = mlog_wpage;
284 mlog_wpage ^= 1; 284 mlog_wpage ^= 1;
285 mlog_buf[mlog_wpage][0] = '\0'; 285 mlog_buf[mlog_wpage][0] = '\0';
286 mlog_used = 0; 286 mlog_used = 0;
287 287
288 atomic_swap_32(&mlog_inuse, 0); 288 atomic_swap_32(&mlog_inuse, 0);
289 289
290 if (mlog_buf[rpage][0] != '\0') { 290 if (mlog_buf[rpage][0] != '\0') {
291 printf("%s", mlog_buf[rpage]); 291 printf("%s", mlog_buf[rpage]);
292 if (mlog_drop > 0) 292 if (mlog_drop > 0)
293 printf("mlog_drop %d\n", mlog_drop); 293 printf("mlog_drop %d\n", mlog_drop);
294 if (mlog_full > 0) 294 if (mlog_full > 0)
295 printf("mlog_full %d\n", mlog_full); 295 printf("mlog_full %d\n", mlog_full);
296 } 296 }
297 mlog_full = 0; 297 mlog_full = 0;
298 mlog_drop = 0; 298 mlog_drop = 0;
299} 299}
300 300
301static void 301static void
302audio_mlog_softintr(void *cookie) 302audio_mlog_softintr(void *cookie)
303{ 303{
304 audio_mlog_flush(); 304 audio_mlog_flush();
305} 305}
306 306
307void 307void
308audio_mlog_printf(const char *fmt, ...) 308audio_mlog_printf(const char *fmt, ...)
309{ 309{
310 int len; 310 int len;
311 va_list ap; 311 va_list ap;
312 312
313 if (atomic_swap_32(&mlog_inuse, 1) == 1) { 313 if (atomic_swap_32(&mlog_inuse, 1) == 1) {
314 /* already inuse */ 314 /* already inuse */
315 mlog_drop++; 315 mlog_drop++;
316 return; 316 return;
317 } 317 }
318 318
319 va_start(ap, fmt); 319 va_start(ap, fmt);
320 len = vsnprintf( 320 len = vsnprintf(
321 mlog_buf[mlog_wpage] + mlog_used, 321 mlog_buf[mlog_wpage] + mlog_used,
322 mlog_buflen - mlog_used, 322 mlog_buflen - mlog_used,
323 fmt, ap); 323 fmt, ap);
324 va_end(ap); 324 va_end(ap);
325 325
326 mlog_used += len; 326 mlog_used += len;
327 if (mlog_buflen - mlog_used <= 1) { 327 if (mlog_buflen - mlog_used <= 1) {
328 mlog_full++; 328 mlog_full++;
329 } 329 }
330 330
331 atomic_swap_32(&mlog_inuse, 0); 331 atomic_swap_32(&mlog_inuse, 0);
332 332
333 if (mlog_sih) 333 if (mlog_sih)
334 softint_schedule(mlog_sih); 334 softint_schedule(mlog_sih);
335} 335}
336 336
337/* trace functions */ 337/* trace functions */
338static void 338static void
339audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header, 339audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header,
340 const char *fmt, va_list ap) 340 const char *fmt, va_list ap)
341{ 341{
342 char buf[256]; 342 char buf[256];
343 int n; 343 int n;
344 344
345 n = 0; 345 n = 0;
346 buf[0] = '\0'; 346 buf[0] = '\0';
347 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s", 347 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s",
348 funcname, device_unit(sc->sc_dev), header); 348 funcname, device_unit(sc->sc_dev), header);
349 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap); 349 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
350 350
351 if (cpu_intr_p()) { 351 if (cpu_intr_p()) {
352 audio_mlog_printf("%s\n", buf); 352 audio_mlog_printf("%s\n", buf);
353 } else { 353 } else {
354 audio_mlog_flush(); 354 audio_mlog_flush();
355 printf("%s\n", buf); 355 printf("%s\n", buf);
356 } 356 }
357} 357}
358 358
359static void 359static void
360audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...) 360audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...)
361{ 361{
362 va_list ap; 362 va_list ap;
363 363
364 va_start(ap, fmt); 364 va_start(ap, fmt);
365 audio_vtrace(sc, funcname, "", fmt, ap); 365 audio_vtrace(sc, funcname, "", fmt, ap);
366 va_end(ap); 366 va_end(ap);
367} 367}
368 368
369static void 369static void
370audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...) 370audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...)
371{ 371{
372 char hdr[16]; 372 char hdr[16];
373 va_list ap; 373 va_list ap;
374 374
375 snprintf(hdr, sizeof(hdr), "#%d ", track->id); 375 snprintf(hdr, sizeof(hdr), "#%d ", track->id);
376 va_start(ap, fmt); 376 va_start(ap, fmt);
377 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap); 377 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap);
378 va_end(ap); 378 va_end(ap);
379} 379}
380 380
381static void 381static void
382audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...) 382audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...)
383{ 383{
384 char hdr[32]; 384 char hdr[32];
385 char phdr[16], rhdr[16]; 385 char phdr[16], rhdr[16];
386 va_list ap; 386 va_list ap;
387 387
388 phdr[0] = '\0'; 388 phdr[0] = '\0';
389 rhdr[0] = '\0'; 389 rhdr[0] = '\0';
390 if (file->ptrack) 390 if (file->ptrack)
391 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id); 391 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id);
392 if (file->rtrack) 392 if (file->rtrack)
393 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id); 393 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id);
394 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr); 394 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr);
395 395
396 va_start(ap, fmt); 396 va_start(ap, fmt);
397 audio_vtrace(file->sc, funcname, hdr, fmt, ap); 397 audio_vtrace(file->sc, funcname, hdr, fmt, ap);
398 va_end(ap); 398 va_end(ap);
399} 399}
400 400
401#define DPRINTF(n, fmt...) do { \ 401#define DPRINTF(n, fmt...) do { \
402 if (audiodebug >= (n)) { \ 402 if (audiodebug >= (n)) { \
403 audio_mlog_flush(); \ 403 audio_mlog_flush(); \
404 printf(fmt); \ 404 printf(fmt); \
405 } \ 405 } \
406} while (0) 406} while (0)
407#define TRACE(n, fmt...) do { \ 407#define TRACE(n, fmt...) do { \
408 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \ 408 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \
409} while (0) 409} while (0)
410#define TRACET(n, t, fmt...) do { \ 410#define TRACET(n, t, fmt...) do { \
411 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \ 411 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \
412} while (0) 412} while (0)
413#define TRACEF(n, f, fmt...) do { \ 413#define TRACEF(n, f, fmt...) do { \
414 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \ 414 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \
415} while (0) 415} while (0)
416 416
417struct audio_track_debugbuf { 417struct audio_track_debugbuf {
418 char usrbuf[32]; 418 char usrbuf[32];
419 char codec[32]; 419 char codec[32];
420 char chvol[32]; 420 char chvol[32];
421 char chmix[32]; 421 char chmix[32];
422 char freq[32]; 422 char freq[32];
423 char outbuf[32]; 423 char outbuf[32];
424}; 424};
425 425
426static void 426static void
427audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf) 427audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf)
428{ 428{
429 429
430 memset(buf, 0, sizeof(*buf)); 430 memset(buf, 0, sizeof(*buf));
431 431
432 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d", 432 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d",
433 track->outbuf.head, track->outbuf.used, track->outbuf.capacity); 433 track->outbuf.head, track->outbuf.used, track->outbuf.capacity);
434 if (track->freq.filter) 434 if (track->freq.filter)
435 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d", 435 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d",
436 track->freq.srcbuf.head, 436 track->freq.srcbuf.head,
437 track->freq.srcbuf.used, 437 track->freq.srcbuf.used,
438 track->freq.srcbuf.capacity); 438 track->freq.srcbuf.capacity);
439 if (track->chmix.filter) 439 if (track->chmix.filter)
440 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d", 440 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d",
441 track->chmix.srcbuf.used); 441 track->chmix.srcbuf.used);
442 if (track->chvol.filter) 442 if (track->chvol.filter)
443 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d", 443 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d",
444 track->chvol.srcbuf.used); 444 track->chvol.srcbuf.used);
445 if (track->codec.filter) 445 if (track->codec.filter)
446 snprintf(buf->codec, sizeof(buf->codec), " e=%d", 446 snprintf(buf->codec, sizeof(buf->codec), " e=%d",
447 track->codec.srcbuf.used); 447 track->codec.srcbuf.used);
448 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d", 448 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d",
449 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh); 449 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh);
450} 450}
451#else 451#else
452#define DPRINTF(n, fmt...) do { } while (0) 452#define DPRINTF(n, fmt...) do { } while (0)
453#define TRACE(n, fmt, ...) do { } while (0) 453#define TRACE(n, fmt, ...) do { } while (0)
454#define TRACET(n, t, fmt, ...) do { } while (0) 454#define TRACET(n, t, fmt, ...) do { } while (0)
455#define TRACEF(n, f, fmt, ...) do { } while (0) 455#define TRACEF(n, f, fmt, ...) do { } while (0)
456#endif 456#endif
457 457
458#define SPECIFIED(x) ((x) != ~0) 458#define SPECIFIED(x) ((x) != ~0)
459#define SPECIFIED_CH(x) ((x) != (u_char)~0) 459#define SPECIFIED_CH(x) ((x) != (u_char)~0)
460 460
461/* Device timeout in msec */ 461/* Device timeout in msec */
462#define AUDIO_TIMEOUT (3000) 462#define AUDIO_TIMEOUT (3000)
463 463
464/* #define AUDIO_PM_IDLE */ 464/* #define AUDIO_PM_IDLE */
465#ifdef AUDIO_PM_IDLE 465#ifdef AUDIO_PM_IDLE
466int audio_idle_timeout = 30; 466int audio_idle_timeout = 30;
467#endif 467#endif
468 468
469struct portname { 469struct portname {
470 const char *name; 470 const char *name;
471 int mask; 471 int mask;
472}; 472};
473 473
474static int audiomatch(device_t, cfdata_t, void *); 474static int audiomatch(device_t, cfdata_t, void *);
475static void audioattach(device_t, device_t, void *); 475static void audioattach(device_t, device_t, void *);
476static int audiodetach(device_t, int); 476static int audiodetach(device_t, int);
477static int audioactivate(device_t, enum devact); 477static int audioactivate(device_t, enum devact);
478static void audiochilddet(device_t, device_t); 478static void audiochilddet(device_t, device_t);
479static int audiorescan(device_t, const char *, const int *); 479static int audiorescan(device_t, const char *, const int *);
480 480
481static int audio_modcmd(modcmd_t, void *); 481static int audio_modcmd(modcmd_t, void *);
482 482
483#ifdef AUDIO_PM_IDLE 483#ifdef AUDIO_PM_IDLE
484static void audio_idle(void *); 484static void audio_idle(void *);
485static void audio_activity(device_t, devactive_t); 485static void audio_activity(device_t, devactive_t);
486#endif 486#endif
487 487
488static bool audio_suspend(device_t dv, const pmf_qual_t *); 488static bool audio_suspend(device_t dv, const pmf_qual_t *);
489static bool audio_resume(device_t dv, const pmf_qual_t *); 489static bool audio_resume(device_t dv, const pmf_qual_t *);
490static void audio_volume_down(device_t); 490static void audio_volume_down(device_t);
491static void audio_volume_up(device_t); 491static void audio_volume_up(device_t);
492static void audio_volume_toggle(device_t); 492static void audio_volume_toggle(device_t);
493 493
494static void audio_mixer_capture(struct audio_softc *); 494static void audio_mixer_capture(struct audio_softc *);
495static void audio_mixer_restore(struct audio_softc *); 495static void audio_mixer_restore(struct audio_softc *);
496 496
497static void audio_softintr_rd(void *); 497static void audio_softintr_rd(void *);
498static void audio_softintr_wr(void *); 498static void audio_softintr_wr(void *);
499 499
500static int audio_enter_exclusive(struct audio_softc *); 500static int audio_enter_exclusive(struct audio_softc *);
501static void audio_exit_exclusive(struct audio_softc *); 501static void audio_exit_exclusive(struct audio_softc *);
502static int audio_track_waitio(struct audio_softc *, audio_track_t *); 502static int audio_track_waitio(struct audio_softc *, audio_track_t *);
503 503
504static int audioclose(struct file *); 504static int audioclose(struct file *);
505static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int); 505static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
506static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int); 506static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
507static int audioioctl(struct file *, u_long, void *); 507static int audioioctl(struct file *, u_long, void *);
508static int audiopoll(struct file *, int); 508static int audiopoll(struct file *, int);
509static int audiokqfilter(struct file *, struct knote *); 509static int audiokqfilter(struct file *, struct knote *);
510static int audiommap(struct file *, off_t *, size_t, int, int *, int *, 510static int audiommap(struct file *, off_t *, size_t, int, int *, int *,
511 struct uvm_object **, int *); 511 struct uvm_object **, int *);
512static int audiostat(struct file *, struct stat *); 512static int audiostat(struct file *, struct stat *);
513 513
514static void filt_audiowrite_detach(struct knote *); 514static void filt_audiowrite_detach(struct knote *);
515static int filt_audiowrite_event(struct knote *, long); 515static int filt_audiowrite_event(struct knote *, long);
516static void filt_audioread_detach(struct knote *); 516static void filt_audioread_detach(struct knote *);
517static int filt_audioread_event(struct knote *, long); 517static int filt_audioread_event(struct knote *, long);
518 518
519static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *, 519static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
520 audio_file_t **); 520 audio_file_t **);
521static int audio_close(struct audio_softc *, audio_file_t *); 521static int audio_close(struct audio_softc *, audio_file_t *);
522static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *); 522static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *);
523static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *); 523static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *);
524static void audio_file_clear(struct audio_softc *, audio_file_t *); 524static void audio_file_clear(struct audio_softc *, audio_file_t *);
525static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, 525static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
526 struct lwp *, audio_file_t *); 526 struct lwp *, audio_file_t *);
527static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *); 527static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *);
528static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *); 528static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *);
529static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *, 529static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
530 struct uvm_object **, int *, audio_file_t *); 530 struct uvm_object **, int *, audio_file_t *);
531 531
532static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *); 532static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *);
533 533
534static void audio_pintr(void *); 534static void audio_pintr(void *);
535static void audio_rintr(void *); 535static void audio_rintr(void *);
536 536
537static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *); 537static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
538 538
539static __inline int audio_track_readablebytes(const audio_track_t *); 539static __inline int audio_track_readablebytes(const audio_track_t *);
540static int audio_file_setinfo(struct audio_softc *, audio_file_t *, 540static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
541 const struct audio_info *); 541 const struct audio_info *);
542static int audio_track_setinfo_check(audio_format2_t *, 542static int audio_track_setinfo_check(audio_format2_t *,
543 const struct audio_prinfo *); 543 const struct audio_prinfo *);
544static void audio_track_setinfo_water(audio_track_t *, 544static void audio_track_setinfo_water(audio_track_t *,
545 const struct audio_info *); 545 const struct audio_info *);
546static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *, 546static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
547 struct audio_info *); 547 struct audio_info *);
548static int audio_hw_set_format(struct audio_softc *, int, 548static int audio_hw_set_format(struct audio_softc *, int,
549 audio_format2_t *, audio_format2_t *, 549 audio_format2_t *, audio_format2_t *,
550 audio_filter_reg_t *, audio_filter_reg_t *); 550 audio_filter_reg_t *, audio_filter_reg_t *);
551static int audiogetinfo(struct audio_softc *, struct audio_info *, int, 551static int audiogetinfo(struct audio_softc *, struct audio_info *, int,
552 audio_file_t *); 552 audio_file_t *);
553static bool audio_can_playback(struct audio_softc *); 553static bool audio_can_playback(struct audio_softc *);
554static bool audio_can_capture(struct audio_softc *); 554static bool audio_can_capture(struct audio_softc *);
555static int audio_check_params(audio_format2_t *); 555static int audio_check_params(audio_format2_t *);
556static int audio_mixers_init(struct audio_softc *sc, int, 556static int audio_mixers_init(struct audio_softc *sc, int,
557 const audio_format2_t *, const audio_format2_t *, 557 const audio_format2_t *, const audio_format2_t *,
558 const audio_filter_reg_t *, const audio_filter_reg_t *); 558 const audio_filter_reg_t *, const audio_filter_reg_t *);
559static int audio_select_freq(const struct audio_format *); 559static int audio_select_freq(const struct audio_format *);
560static int audio_hw_probe(struct audio_softc *, int, int *, 560static int audio_hw_probe(struct audio_softc *, int, int *,
561 audio_format2_t *, audio_format2_t *); 561 audio_format2_t *, audio_format2_t *);
562static int audio_hw_probe_fmt(struct audio_softc *, audio_format2_t *, int); 562static int audio_hw_probe_fmt(struct audio_softc *, audio_format2_t *, int);
563static int audio_hw_validate_format(struct audio_softc *, int, 563static int audio_hw_validate_format(struct audio_softc *, int,
564 const audio_format2_t *); 564 const audio_format2_t *);
565static int audio_mixers_set_format(struct audio_softc *, 565static int audio_mixers_set_format(struct audio_softc *,
566 const struct audio_info *); 566 const struct audio_info *);
567static void audio_mixers_get_format(struct audio_softc *, struct audio_info *); 567static void audio_mixers_get_format(struct audio_softc *, struct audio_info *);
568static int audio_sysctl_blk_ms(SYSCTLFN_PROTO); 568static int audio_sysctl_blk_ms(SYSCTLFN_PROTO);
569static int audio_sysctl_multiuser(SYSCTLFN_PROTO); 569static int audio_sysctl_multiuser(SYSCTLFN_PROTO);
570#if defined(AUDIO_DEBUG) 570#if defined(AUDIO_DEBUG)
571static int audio_sysctl_debug(SYSCTLFN_PROTO); 571static int audio_sysctl_debug(SYSCTLFN_PROTO);
572static void audio_format2_tostr(char *, size_t, const audio_format2_t *); 572static void audio_format2_tostr(char *, size_t, const audio_format2_t *);
573static void audio_print_format2(const char *, const audio_format2_t *) __unused; 573static void audio_print_format2(const char *, const audio_format2_t *) __unused;
574#endif 574#endif
575 575
576static void *audio_realloc(void *, size_t); 576static void *audio_realloc(void *, size_t);
577static int audio_realloc_usrbuf(audio_track_t *, int); 577static int audio_realloc_usrbuf(audio_track_t *, int);
578static void audio_free_usrbuf(audio_track_t *); 578static void audio_free_usrbuf(audio_track_t *);
579 579
580static audio_track_t *audio_track_create(struct audio_softc *, 580static audio_track_t *audio_track_create(struct audio_softc *,
581 audio_trackmixer_t *); 581 audio_trackmixer_t *);
582static void audio_track_destroy(audio_track_t *); 582static void audio_track_destroy(audio_track_t *);
583static audio_filter_t audio_track_get_codec(audio_track_t *, 583static audio_filter_t audio_track_get_codec(audio_track_t *,
584 const audio_format2_t *, const audio_format2_t *); 584 const audio_format2_t *, const audio_format2_t *);
585static int audio_track_set_format(audio_track_t *, audio_format2_t *); 585static int audio_track_set_format(audio_track_t *, audio_format2_t *);
586static void audio_track_play(audio_track_t *); 586static void audio_track_play(audio_track_t *);
587static int audio_track_drain(struct audio_softc *, audio_track_t *); 587static int audio_track_drain(struct audio_softc *, audio_track_t *);
588static void audio_track_record(audio_track_t *); 588static void audio_track_record(audio_track_t *);
589static void audio_track_clear(struct audio_softc *, audio_track_t *); 589static void audio_track_clear(struct audio_softc *, audio_track_t *);
590 590
591static int audio_mixer_init(struct audio_softc *, int, 591static int audio_mixer_init(struct audio_softc *, int,
592 const audio_format2_t *, const audio_filter_reg_t *); 592 const audio_format2_t *, const audio_filter_reg_t *);
593static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *); 593static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *);
594static void audio_pmixer_start(struct audio_softc *, bool); 594static void audio_pmixer_start(struct audio_softc *, bool);
595static void audio_pmixer_process(struct audio_softc *); 595static void audio_pmixer_process(struct audio_softc *);
596static void audio_pmixer_agc(audio_trackmixer_t *, int); 596static void audio_pmixer_agc(audio_trackmixer_t *, int);
597static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int); 597static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int);
598static void audio_pmixer_output(struct audio_softc *); 598static void audio_pmixer_output(struct audio_softc *);
599static int audio_pmixer_halt(struct audio_softc *); 599static int audio_pmixer_halt(struct audio_softc *);
600static void audio_rmixer_start(struct audio_softc *); 600static void audio_rmixer_start(struct audio_softc *);
601static void audio_rmixer_process(struct audio_softc *); 601static void audio_rmixer_process(struct audio_softc *);
602static void audio_rmixer_input(struct audio_softc *); 602static void audio_rmixer_input(struct audio_softc *);
603static int audio_rmixer_halt(struct audio_softc *); 603static int audio_rmixer_halt(struct audio_softc *);
604 604
605static void mixer_init(struct audio_softc *); 605static void mixer_init(struct audio_softc *);
606static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *); 606static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
607static int mixer_close(struct audio_softc *, audio_file_t *); 607static int mixer_close(struct audio_softc *, audio_file_t *);
608static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *); 608static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
609static void mixer_remove(struct audio_softc *); 609static void mixer_remove(struct audio_softc *);
610static void mixer_signal(struct audio_softc *); 610static void mixer_signal(struct audio_softc *);
611 611
612static int au_portof(struct audio_softc *, char *, int); 612static int au_portof(struct audio_softc *, char *, int);
613 613
614static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *, 614static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
615 mixer_devinfo_t *, const struct portname *); 615 mixer_devinfo_t *, const struct portname *);
616static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int); 616static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int);
617static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *); 617static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *);
618static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int); 618static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int);
619static void au_get_gain(struct audio_softc *, struct au_mixer_ports *, 619static void au_get_gain(struct audio_softc *, struct au_mixer_ports *,
620 u_int *, u_char *); 620 u_int *, u_char *);
621static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int); 621static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int);
622static int au_get_port(struct audio_softc *, struct au_mixer_ports *); 622static int au_get_port(struct audio_softc *, struct au_mixer_ports *);
623static int au_set_monitor_gain(struct audio_softc *, int); 623static int au_set_monitor_gain(struct audio_softc *, int);
624static int au_get_monitor_gain(struct audio_softc *); 624static int au_get_monitor_gain(struct audio_softc *);
625static int audio_get_port(struct audio_softc *, mixer_ctrl_t *); 625static int audio_get_port(struct audio_softc *, mixer_ctrl_t *);
626static int audio_set_port(struct audio_softc *, mixer_ctrl_t *); 626static int audio_set_port(struct audio_softc *, mixer_ctrl_t *);
627 627
628static __inline struct audio_params 628static __inline struct audio_params
629format2_to_params(const audio_format2_t *f2) 629format2_to_params(const audio_format2_t *f2)
630{ 630{
631 audio_params_t p; 631 audio_params_t p;
632 632
633 /* validbits/precision <-> precision/stride */ 633 /* validbits/precision <-> precision/stride */
634 p.sample_rate = f2->sample_rate; 634 p.sample_rate = f2->sample_rate;
635 p.channels = f2->channels; 635 p.channels = f2->channels;
636 p.encoding = f2->encoding; 636 p.encoding = f2->encoding;
637 p.validbits = f2->precision; 637 p.validbits = f2->precision;
638 p.precision = f2->stride; 638 p.precision = f2->stride;
639 return p; 639 return p;
640} 640}
641 641
642static __inline audio_format2_t 642static __inline audio_format2_t
643params_to_format2(const struct audio_params *p) 643params_to_format2(const struct audio_params *p)
644{ 644{
645 audio_format2_t f2; 645 audio_format2_t f2;
646 646
647 /* precision/stride <-> validbits/precision */ 647 /* precision/stride <-> validbits/precision */
648 f2.sample_rate = p->sample_rate; 648 f2.sample_rate = p->sample_rate;
649 f2.channels = p->channels; 649 f2.channels = p->channels;
650 f2.encoding = p->encoding; 650 f2.encoding = p->encoding;
651 f2.precision = p->validbits; 651 f2.precision = p->validbits;
652 f2.stride = p->precision; 652 f2.stride = p->precision;
653 return f2; 653 return f2;
654} 654}
655 655
656/* Return true if this track is a playback track. */ 656/* Return true if this track is a playback track. */
657static __inline bool 657static __inline bool
658audio_track_is_playback(const audio_track_t *track) 658audio_track_is_playback(const audio_track_t *track)
659{ 659{
660 660
661 return ((track->mode & AUMODE_PLAY) != 0); 661 return ((track->mode & AUMODE_PLAY) != 0);
662} 662}
663 663
664/* Return true if this track is a recording track. */ 664/* Return true if this track is a recording track. */
665static __inline bool 665static __inline bool
666audio_track_is_record(const audio_track_t *track) 666audio_track_is_record(const audio_track_t *track)
667{ 667{
668 668
669 return ((track->mode & AUMODE_RECORD) != 0); 669 return ((track->mode & AUMODE_RECORD) != 0);
670} 670}
671 671
672#if 0 /* XXX Not used yet */ 672#if 0 /* XXX Not used yet */
673/* 673/*
674 * Convert 0..255 volume used in userland to internal presentation 0..256. 674 * Convert 0..255 volume used in userland to internal presentation 0..256.
675 */ 675 */
676static __inline u_int 676static __inline u_int
677audio_volume_to_inner(u_int v) 677audio_volume_to_inner(u_int v)
678{ 678{
679 679
680 return v < 127 ? v : v + 1; 680 return v < 127 ? v : v + 1;
681} 681}
682 682
683/* 683/*
684 * Convert 0..256 internal presentation to 0..255 volume used in userland. 684 * Convert 0..256 internal presentation to 0..255 volume used in userland.
685 */ 685 */
686static __inline u_int 686static __inline u_int
687audio_volume_to_outer(u_int v) 687audio_volume_to_outer(u_int v)
688{ 688{
689 689
690 return v < 127 ? v : v - 1; 690 return v < 127 ? v : v - 1;
691} 691}
692#endif /* 0 */ 692#endif /* 0 */
693 693
694static dev_type_open(audioopen); 694static dev_type_open(audioopen);
695/* XXXMRG use more dev_type_xxx */ 695/* XXXMRG use more dev_type_xxx */
696 696
697const struct cdevsw audio_cdevsw = { 697const struct cdevsw audio_cdevsw = {
698 .d_open = audioopen, 698 .d_open = audioopen,
699 .d_close = noclose, 699 .d_close = noclose,
700 .d_read = noread, 700 .d_read = noread,
701 .d_write = nowrite, 701 .d_write = nowrite,
702 .d_ioctl = noioctl, 702 .d_ioctl = noioctl,
703 .d_stop = nostop, 703 .d_stop = nostop,
704 .d_tty = notty, 704 .d_tty = notty,
705 .d_poll = nopoll, 705 .d_poll = nopoll,
706 .d_mmap = nommap, 706 .d_mmap = nommap,
707 .d_kqfilter = nokqfilter, 707 .d_kqfilter = nokqfilter,
708 .d_discard = nodiscard, 708 .d_discard = nodiscard,
709 .d_flag = D_OTHER | D_MPSAFE 709 .d_flag = D_OTHER | D_MPSAFE
710}; 710};
711 711
712const struct fileops audio_fileops = { 712const struct fileops audio_fileops = {
713 .fo_name = "audio", 713 .fo_name = "audio",
714 .fo_read = audioread, 714 .fo_read = audioread,
715 .fo_write = audiowrite, 715 .fo_write = audiowrite,
716 .fo_ioctl = audioioctl, 716 .fo_ioctl = audioioctl,
717 .fo_fcntl = fnullop_fcntl, 717 .fo_fcntl = fnullop_fcntl,
718 .fo_stat = audiostat, 718 .fo_stat = audiostat,
719 .fo_poll = audiopoll, 719 .fo_poll = audiopoll,
720 .fo_close = audioclose, 720 .fo_close = audioclose,
721 .fo_mmap = audiommap, 721 .fo_mmap = audiommap,
722 .fo_kqfilter = audiokqfilter, 722 .fo_kqfilter = audiokqfilter,
723 .fo_restart = fnullop_restart 723 .fo_restart = fnullop_restart
724}; 724};
725 725
726/* The default audio mode: 8 kHz mono mu-law */ 726/* The default audio mode: 8 kHz mono mu-law */
727static const struct audio_params audio_default = { 727static const struct audio_params audio_default = {
728 .sample_rate = 8000, 728 .sample_rate = 8000,
729 .encoding = AUDIO_ENCODING_ULAW, 729 .encoding = AUDIO_ENCODING_ULAW,
730 .precision = 8, 730 .precision = 8,
731 .validbits = 8, 731 .validbits = 8,
732 .channels = 1, 732 .channels = 1,
733}; 733};
734 734
735static const char *encoding_names[] = { 735static const char *encoding_names[] = {
736 "none", 736 "none",
737 AudioEmulaw, 737 AudioEmulaw,
738 AudioEalaw, 738 AudioEalaw,
739 "pcm16", 739 "pcm16",
740 "pcm8", 740 "pcm8",
741 AudioEadpcm, 741 AudioEadpcm,
742 AudioEslinear_le, 742 AudioEslinear_le,
743 AudioEslinear_be, 743 AudioEslinear_be,
744 AudioEulinear_le, 744 AudioEulinear_le,
745 AudioEulinear_be, 745 AudioEulinear_be,
746 AudioEslinear, 746 AudioEslinear,
747 AudioEulinear, 747 AudioEulinear,
748 AudioEmpeg_l1_stream, 748 AudioEmpeg_l1_stream,
749 AudioEmpeg_l1_packets, 749 AudioEmpeg_l1_packets,
750 AudioEmpeg_l1_system, 750 AudioEmpeg_l1_system,
751 AudioEmpeg_l2_stream, 751 AudioEmpeg_l2_stream,
752 AudioEmpeg_l2_packets, 752 AudioEmpeg_l2_packets,
753 AudioEmpeg_l2_system, 753 AudioEmpeg_l2_system,
754 AudioEac3, 754 AudioEac3,
755}; 755};
756 756
757/* 757/*
758 * Returns encoding name corresponding to AUDIO_ENCODING_*. 758 * Returns encoding name corresponding to AUDIO_ENCODING_*.
759 * Note that it may return a local buffer because it is mainly for debugging. 759 * Note that it may return a local buffer because it is mainly for debugging.
760 */ 760 */
761const char * 761const char *
762audio_encoding_name(int encoding) 762audio_encoding_name(int encoding)
763{ 763{
764 static char buf[16]; 764 static char buf[16];
765 765
766 if (0 <= encoding && encoding < __arraycount(encoding_names)) { 766 if (0 <= encoding && encoding < __arraycount(encoding_names)) {
767 return encoding_names[encoding]; 767 return encoding_names[encoding];
768 } else { 768 } else {
769 snprintf(buf, sizeof(buf), "enc=%d", encoding); 769 snprintf(buf, sizeof(buf), "enc=%d", encoding);
770 return buf; 770 return buf;
771 } 771 }
772} 772}
773 773
774/* 774/*
775 * Supported encodings used by AUDIO_GETENC. 775 * Supported encodings used by AUDIO_GETENC.
776 * index and flags are set by code. 776 * index and flags are set by code.
777 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ? 777 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ?
778 */ 778 */
779static const audio_encoding_t audio_encodings[] = { 779static const audio_encoding_t audio_encodings[] = {
780 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 }, 780 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 },
781 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 }, 781 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 },
782 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 }, 782 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 },
783 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 783 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 },
784 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 784 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 },
785 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 }, 785 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 },
786 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 }, 786 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 },
787 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 }, 787 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 },
788#if defined(AUDIO_SUPPORT_LINEAR24) 788#if defined(AUDIO_SUPPORT_LINEAR24)
789 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 }, 789 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 },
790 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 }, 790 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 },
791 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 }, 791 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 },
792 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 }, 792 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 },
793#endif 793#endif
794 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 }, 794 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 },
795 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 }, 795 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 },
796 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 }, 796 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 },
797 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 }, 797 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 },
798}; 798};
799 799
800static const struct portname itable[] = { 800static const struct portname itable[] = {
801 { AudioNmicrophone, AUDIO_MICROPHONE }, 801 { AudioNmicrophone, AUDIO_MICROPHONE },
802 { AudioNline, AUDIO_LINE_IN }, 802 { AudioNline, AUDIO_LINE_IN },
803 { AudioNcd, AUDIO_CD }, 803 { AudioNcd, AUDIO_CD },
804 { 0, 0 } 804 { 0, 0 }
805}; 805};
806static const struct portname otable[] = { 806static const struct portname otable[] = {
807 { AudioNspeaker, AUDIO_SPEAKER }, 807 { AudioNspeaker, AUDIO_SPEAKER },
808 { AudioNheadphone, AUDIO_HEADPHONE }, 808 { AudioNheadphone, AUDIO_HEADPHONE },
809 { AudioNline, AUDIO_LINE_OUT }, 809 { AudioNline, AUDIO_LINE_OUT },
810 { 0, 0 } 810 { 0, 0 }
811}; 811};
812 812
813CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc), 813CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
814 audiomatch, audioattach, audiodetach, audioactivate, audiorescan, 814 audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
815 audiochilddet, DVF_DETACH_SHUTDOWN); 815 audiochilddet, DVF_DETACH_SHUTDOWN);
816 816
817static int 817static int
818audiomatch(device_t parent, cfdata_t match, void *aux) 818audiomatch(device_t parent, cfdata_t match, void *aux)
819{ 819{
820 struct audio_attach_args *sa; 820 struct audio_attach_args *sa;
821 821
822 sa = aux; 822 sa = aux;
823 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n", 823 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n",
824 __func__, sa->type, sa, sa->hwif); 824 __func__, sa->type, sa, sa->hwif);
825 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 825 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
826} 826}
827 827
828static void 828static void
829audioattach(device_t parent, device_t self, void *aux) 829audioattach(device_t parent, device_t self, void *aux)
830{ 830{
831 struct audio_softc *sc; 831 struct audio_softc *sc;
832 struct audio_attach_args *sa; 832 struct audio_attach_args *sa;
833 const struct audio_hw_if *hw_if; 833 const struct audio_hw_if *hw_if;
834 audio_format2_t phwfmt; 834 audio_format2_t phwfmt;
835 audio_format2_t rhwfmt; 835 audio_format2_t rhwfmt;
836 audio_filter_reg_t pfil; 836 audio_filter_reg_t pfil;
837 audio_filter_reg_t rfil; 837 audio_filter_reg_t rfil;
838 const struct sysctlnode *node; 838 const struct sysctlnode *node;
839 void *hdlp; 839 void *hdlp;
840 bool has_playback; 840 bool has_playback;
841 bool has_capture; 841 bool has_capture;
842 bool has_indep; 842 bool has_indep;
843 bool has_fulldup; 843 bool has_fulldup;
844 int mode; 844 int mode;
845 int error; 845 int error;
846 846
847 sc = device_private(self); 847 sc = device_private(self);
848 sc->sc_dev = self; 848 sc->sc_dev = self;
849 sa = (struct audio_attach_args *)aux; 849 sa = (struct audio_attach_args *)aux;
850 hw_if = sa->hwif; 850 hw_if = sa->hwif;
851 hdlp = sa->hdl; 851 hdlp = sa->hdl;
852 852
853 if (hw_if == NULL || hw_if->get_locks == NULL) { 853 if (hw_if == NULL || hw_if->get_locks == NULL) {
854 panic("audioattach: missing hw_if method"); 854 panic("audioattach: missing hw_if method");
855 } 855 }
856 856
857 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock); 857 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock);
858 858
859#ifdef DIAGNOSTIC 859#ifdef DIAGNOSTIC
860 if (hw_if->query_format == NULL || 860 if (hw_if->query_format == NULL ||
861 hw_if->set_format == NULL || 861 hw_if->set_format == NULL ||
862 (hw_if->start_output == NULL && hw_if->trigger_output == NULL) || 862 (hw_if->start_output == NULL && hw_if->trigger_output == NULL) ||
863 (hw_if->start_input == NULL && hw_if->trigger_input == NULL) || 863 (hw_if->start_input == NULL && hw_if->trigger_input == NULL) ||
864 hw_if->halt_output == NULL || 864 hw_if->halt_output == NULL ||
865 hw_if->halt_input == NULL || 865 hw_if->halt_input == NULL ||
866 hw_if->getdev == NULL || 866 hw_if->getdev == NULL ||
867 hw_if->set_port == NULL || 867 hw_if->set_port == NULL ||
868 hw_if->get_port == NULL || 868 hw_if->get_port == NULL ||
869 hw_if->query_devinfo == NULL || 869 hw_if->query_devinfo == NULL ||
870 hw_if->get_props == NULL) { 870 hw_if->get_props == NULL) {
871 aprint_error(": missing method\n"); 871 aprint_error(": missing method\n");
872 return; 872 return;
873 } 873 }
874#endif 874#endif
875 875
876 sc->hw_if = hw_if; 876 sc->hw_if = hw_if;
877 sc->hw_hdl = hdlp; 877 sc->hw_hdl = hdlp;
878 sc->hw_dev = parent; 878 sc->hw_dev = parent;
879 879
880 sc->sc_blk_ms = AUDIO_BLK_MS; 880 sc->sc_blk_ms = AUDIO_BLK_MS;
881 SLIST_INIT(&sc->sc_files); 881 SLIST_INIT(&sc->sc_files);
882 cv_init(&sc->sc_exlockcv, "audiolk"); 882 cv_init(&sc->sc_exlockcv, "audiolk");
883 883
884 mutex_enter(sc->sc_lock); 884 mutex_enter(sc->sc_lock);
885 sc->sc_props = hw_if->get_props(sc->hw_hdl); 885 sc->sc_props = hw_if->get_props(sc->hw_hdl);
886 mutex_exit(sc->sc_lock); 886 mutex_exit(sc->sc_lock);
887 887
888 /* MMAP is now supported by upper layer. */ 888 /* MMAP is now supported by upper layer. */
889 sc->sc_props |= AUDIO_PROP_MMAP; 889 sc->sc_props |= AUDIO_PROP_MMAP;
890 890
891 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK); 891 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK);
892 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE); 892 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE);
893 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT); 893 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT);
894 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX); 894 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
895 895
896 KASSERT(has_playback || has_capture); 896 KASSERT(has_playback || has_capture);
897 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */ 897 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */
898 if (!has_playback || !has_capture) { 898 if (!has_playback || !has_capture) {
899 KASSERT(!has_indep); 899 KASSERT(!has_indep);
900 KASSERT(!has_fulldup); 900 KASSERT(!has_fulldup);
901 } 901 }
902 902
903 mode = 0; 903 mode = 0;
904 if (has_playback) { 904 if (has_playback) {
905 aprint_normal(": playback"); 905 aprint_normal(": playback");
906 mode |= AUMODE_PLAY; 906 mode |= AUMODE_PLAY;
907 } 907 }
908 if (has_capture) { 908 if (has_capture) {
909 aprint_normal("%c capture", has_playback ? ',' : ':'); 909 aprint_normal("%c capture", has_playback ? ',' : ':');
910 mode |= AUMODE_RECORD; 910 mode |= AUMODE_RECORD;
911 } 911 }
912 if (has_playback && has_capture) { 912 if (has_playback && has_capture) {
913 if (has_fulldup) 913 if (has_fulldup)
914 aprint_normal(", full duplex"); 914 aprint_normal(", full duplex");
915 else 915 else
916 aprint_normal(", half duplex"); 916 aprint_normal(", half duplex");
917 917
918 if (has_indep) 918 if (has_indep)
919 aprint_normal(", independent"); 919 aprint_normal(", independent");
920 } 920 }
921 921
922 aprint_naive("\n"); 922 aprint_naive("\n");
923 aprint_normal("\n"); 923 aprint_normal("\n");
924 924
925 /* probe hw params */ 925 /* probe hw params */
926 memset(&phwfmt, 0, sizeof(phwfmt)); 926 memset(&phwfmt, 0, sizeof(phwfmt));
927 memset(&rhwfmt, 0, sizeof(rhwfmt)); 927 memset(&rhwfmt, 0, sizeof(rhwfmt));
928 memset(&pfil, 0, sizeof(pfil)); 928 memset(&pfil, 0, sizeof(pfil));
929 memset(&rfil, 0, sizeof(rfil)); 929 memset(&rfil, 0, sizeof(rfil));
930 mutex_enter(sc->sc_lock); 930 mutex_enter(sc->sc_lock);
931 error = audio_hw_probe(sc, has_indep, &mode, &phwfmt, &rhwfmt); 931 error = audio_hw_probe(sc, has_indep, &mode, &phwfmt, &rhwfmt);
932 if (error) { 932 if (error) {
933 mutex_exit(sc->sc_lock); 933 mutex_exit(sc->sc_lock);
934 aprint_error_dev(self, "audio_hw_probe failed, " 934 aprint_error_dev(self, "audio_hw_probe failed, "
935 "error = %d\n", error); 935 "error = %d\n", error);
936 goto bad; 936 goto bad;
937 } 937 }
938 if (mode == 0) { 938 if (mode == 0) {
939 mutex_exit(sc->sc_lock); 939 mutex_exit(sc->sc_lock);
940 aprint_error_dev(self, "audio_hw_probe failed, no mode\n"); 940 aprint_error_dev(self, "audio_hw_probe failed, no mode\n");
941 goto bad; 941 goto bad;
942 } 942 }
943 /* Init hardware. */ 943 /* Init hardware. */
944 /* hw_probe() also validates [pr]hwfmt. */ 944 /* hw_probe() also validates [pr]hwfmt. */
945 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 945 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
946 if (error) { 946 if (error) {
947 mutex_exit(sc->sc_lock); 947 mutex_exit(sc->sc_lock);
948 aprint_error_dev(self, "audio_hw_set_format failed, " 948 aprint_error_dev(self, "audio_hw_set_format failed, "
949 "error = %d\n", error); 949 "error = %d\n", error);
950 goto bad; 950 goto bad;
951 } 951 }
952 952
953 /* 953 /*
954 * Init track mixers. If at least one direction is available on 954 * Init track mixers. If at least one direction is available on
955 * attach time, we assume a success. 955 * attach time, we assume a success.
956 */ 956 */
957 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 957 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
958 mutex_exit(sc->sc_lock); 958 mutex_exit(sc->sc_lock);
959 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) { 959 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) {
960 aprint_error_dev(self, "audio_mixers_init failed, " 960 aprint_error_dev(self, "audio_mixers_init failed, "
961 "error = %d\n", error); 961 "error = %d\n", error);
962 goto bad; 962 goto bad;
963 } 963 }
964 964
965 selinit(&sc->sc_wsel); 965 selinit(&sc->sc_wsel);
966 selinit(&sc->sc_rsel); 966 selinit(&sc->sc_rsel);
967 967
968 /* Initial parameter of /dev/sound */ 968 /* Initial parameter of /dev/sound */
969 sc->sc_sound_pparams = params_to_format2(&audio_default); 969 sc->sc_sound_pparams = params_to_format2(&audio_default);
970 sc->sc_sound_rparams = params_to_format2(&audio_default); 970 sc->sc_sound_rparams = params_to_format2(&audio_default);
971 sc->sc_sound_ppause = false; 971 sc->sc_sound_ppause = false;
972 sc->sc_sound_rpause = false; 972 sc->sc_sound_rpause = false;
973 973
974 /* XXX TODO: consider about sc_ai */ 974 /* XXX TODO: consider about sc_ai */
975 975
976 mixer_init(sc); 976 mixer_init(sc);
977 TRACE(2, "inputs ports=0x%x, input master=%d, " 977 TRACE(2, "inputs ports=0x%x, input master=%d, "
978 "output ports=0x%x, output master=%d", 978 "output ports=0x%x, output master=%d",
979 sc->sc_inports.allports, sc->sc_inports.master, 979 sc->sc_inports.allports, sc->sc_inports.master,
980 sc->sc_outports.allports, sc->sc_outports.master); 980 sc->sc_outports.allports, sc->sc_outports.master);
981 981
982 sysctl_createv(&sc->sc_log, 0, NULL, &node, 982 sysctl_createv(&sc->sc_log, 0, NULL, &node,
983 0, 983 0,
984 CTLTYPE_NODE, device_xname(sc->sc_dev), 984 CTLTYPE_NODE, device_xname(sc->sc_dev),
985 SYSCTL_DESCR("audio test"), 985 SYSCTL_DESCR("audio test"),
986 NULL, 0, 986 NULL, 0,
987 NULL, 0, 987 NULL, 0,
988 CTL_HW, 988 CTL_HW,
989 CTL_CREATE, CTL_EOL); 989 CTL_CREATE, CTL_EOL);
990 990
991 if (node != NULL) { 991 if (node != NULL) {
992 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 992 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
993 CTLFLAG_READWRITE, 993 CTLFLAG_READWRITE,
994 CTLTYPE_INT, "blk_ms", 994 CTLTYPE_INT, "blk_ms",
995 SYSCTL_DESCR("blocksize in msec"), 995 SYSCTL_DESCR("blocksize in msec"),
996 audio_sysctl_blk_ms, 0, (void *)sc, 0, 996 audio_sysctl_blk_ms, 0, (void *)sc, 0,
997 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 997 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
998 998
999 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 999 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1000 CTLFLAG_READWRITE, 1000 CTLFLAG_READWRITE,
1001 CTLTYPE_BOOL, "multiuser", 1001 CTLTYPE_BOOL, "multiuser",
1002 SYSCTL_DESCR("allow multiple user access"), 1002 SYSCTL_DESCR("allow multiple user access"),
1003 audio_sysctl_multiuser, 0, (void *)sc, 0, 1003 audio_sysctl_multiuser, 0, (void *)sc, 0,
1004 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1004 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1005 1005
1006#if defined(AUDIO_DEBUG) 1006#if defined(AUDIO_DEBUG)
1007 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 1007 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1008 CTLFLAG_READWRITE, 1008 CTLFLAG_READWRITE,
1009 CTLTYPE_INT, "debug", 1009 CTLTYPE_INT, "debug",
1010 SYSCTL_DESCR("debug level (0..4)"), 1010 SYSCTL_DESCR("debug level (0..4)"),
1011 audio_sysctl_debug, 0, (void *)sc, 0, 1011 audio_sysctl_debug, 0, (void *)sc, 0,
1012 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1012 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1013#endif 1013#endif
1014 } 1014 }
1015 1015
1016#ifdef AUDIO_PM_IDLE 1016#ifdef AUDIO_PM_IDLE
1017 callout_init(&sc->sc_idle_counter, 0); 1017 callout_init(&sc->sc_idle_counter, 0);
1018 callout_setfunc(&sc->sc_idle_counter, audio_idle, self); 1018 callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
1019#endif 1019#endif
1020 1020
1021 if (!pmf_device_register(self, audio_suspend, audio_resume)) 1021 if (!pmf_device_register(self, audio_suspend, audio_resume))
1022 aprint_error_dev(self, "couldn't establish power handler\n"); 1022 aprint_error_dev(self, "couldn't establish power handler\n");
1023#ifdef AUDIO_PM_IDLE 1023#ifdef AUDIO_PM_IDLE
1024 if (!device_active_register(self, audio_activity)) 1024 if (!device_active_register(self, audio_activity))
1025 aprint_error_dev(self, "couldn't register activity handler\n"); 1025 aprint_error_dev(self, "couldn't register activity handler\n");
1026#endif 1026#endif
1027 1027
1028 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN, 1028 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
1029 audio_volume_down, true)) 1029 audio_volume_down, true))
1030 aprint_error_dev(self, "couldn't add volume down handler\n"); 1030 aprint_error_dev(self, "couldn't add volume down handler\n");
1031 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP, 1031 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
1032 audio_volume_up, true)) 1032 audio_volume_up, true))
1033 aprint_error_dev(self, "couldn't add volume up handler\n"); 1033 aprint_error_dev(self, "couldn't add volume up handler\n");
1034 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE, 1034 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
1035 audio_volume_toggle, true)) 1035 audio_volume_toggle, true))
1036 aprint_error_dev(self, "couldn't add volume toggle handler\n"); 1036 aprint_error_dev(self, "couldn't add volume toggle handler\n");
1037 1037
1038#ifdef AUDIO_PM_IDLE 1038#ifdef AUDIO_PM_IDLE
1039 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz); 1039 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
1040#endif 1040#endif
1041 1041
1042#if defined(AUDIO_DEBUG) 1042#if defined(AUDIO_DEBUG)
1043 audio_mlog_init(); 1043 audio_mlog_init();
1044#endif 1044#endif
1045 1045
1046 audiorescan(self, "audio", NULL); 1046 audiorescan(self, "audio", NULL);
1047 return; 1047 return;
1048 1048
1049bad: 1049bad:
1050 /* Clearing hw_if means that device is attached but disabled. */ 1050 /* Clearing hw_if means that device is attached but disabled. */
1051 sc->hw_if = NULL; 1051 sc->hw_if = NULL;
1052 aprint_error_dev(sc->sc_dev, "disabled\n"); 1052 aprint_error_dev(sc->sc_dev, "disabled\n");
1053 return; 1053 return;
1054} 1054}
1055 1055
1056/* 1056/*
1057 * Initialize hardware mixer. 1057 * Initialize hardware mixer.
1058 * This function is called from audioattach(). 1058 * This function is called from audioattach().
1059 */ 1059 */
1060static void 1060static void
1061mixer_init(struct audio_softc *sc) 1061mixer_init(struct audio_softc *sc)
1062{ 1062{
1063 mixer_devinfo_t mi; 1063 mixer_devinfo_t mi;
1064 int iclass, mclass, oclass, rclass; 1064 int iclass, mclass, oclass, rclass;
1065 int record_master_found, record_source_found; 1065 int record_master_found, record_source_found;
1066 1066
1067 iclass = mclass = oclass = rclass = -1; 1067 iclass = mclass = oclass = rclass = -1;
1068 sc->sc_inports.index = -1; 1068 sc->sc_inports.index = -1;
1069 sc->sc_inports.master = -1; 1069 sc->sc_inports.master = -1;
1070 sc->sc_inports.nports = 0; 1070 sc->sc_inports.nports = 0;
1071 sc->sc_inports.isenum = false; 1071 sc->sc_inports.isenum = false;
1072 sc->sc_inports.allports = 0; 1072 sc->sc_inports.allports = 0;
1073 sc->sc_inports.isdual = false; 1073 sc->sc_inports.isdual = false;
1074 sc->sc_inports.mixerout = -1; 1074 sc->sc_inports.mixerout = -1;
1075 sc->sc_inports.cur_port = -1; 1075 sc->sc_inports.cur_port = -1;
1076 sc->sc_outports.index = -1; 1076 sc->sc_outports.index = -1;
1077 sc->sc_outports.master = -1; 1077 sc->sc_outports.master = -1;
1078 sc->sc_outports.nports = 0; 1078 sc->sc_outports.nports = 0;
1079 sc->sc_outports.isenum = false; 1079 sc->sc_outports.isenum = false;
1080 sc->sc_outports.allports = 0; 1080 sc->sc_outports.allports = 0;
1081 sc->sc_outports.isdual = false; 1081 sc->sc_outports.isdual = false;
1082 sc->sc_outports.mixerout = -1; 1082 sc->sc_outports.mixerout = -1;
1083 sc->sc_outports.cur_port = -1; 1083 sc->sc_outports.cur_port = -1;
1084 sc->sc_monitor_port = -1; 1084 sc->sc_monitor_port = -1;
1085 /* 1085 /*
1086 * Read through the underlying driver's list, picking out the class 1086 * Read through the underlying driver's list, picking out the class
1087 * names from the mixer descriptions. We'll need them to decode the 1087 * names from the mixer descriptions. We'll need them to decode the
1088 * mixer descriptions on the next pass through the loop. 1088 * mixer descriptions on the next pass through the loop.
1089 */ 1089 */
1090 mutex_enter(sc->sc_lock); 1090 mutex_enter(sc->sc_lock);
1091 for(mi.index = 0; ; mi.index++) { 1091 for(mi.index = 0; ; mi.index++) {
1092 if (audio_query_devinfo(sc, &mi) != 0) 1092 if (audio_query_devinfo(sc, &mi) != 0)
1093 break; 1093 break;
1094 /* 1094 /*
1095 * The type of AUDIO_MIXER_CLASS merely introduces a class. 1095 * The type of AUDIO_MIXER_CLASS merely introduces a class.
1096 * All the other types describe an actual mixer. 1096 * All the other types describe an actual mixer.
1097 */ 1097 */
1098 if (mi.type == AUDIO_MIXER_CLASS) { 1098 if (mi.type == AUDIO_MIXER_CLASS) {
1099 if (strcmp(mi.label.name, AudioCinputs) == 0) 1099 if (strcmp(mi.label.name, AudioCinputs) == 0)
1100 iclass = mi.mixer_class; 1100 iclass = mi.mixer_class;
1101 if (strcmp(mi.label.name, AudioCmonitor) == 0) 1101 if (strcmp(mi.label.name, AudioCmonitor) == 0)
1102 mclass = mi.mixer_class; 1102 mclass = mi.mixer_class;
1103 if (strcmp(mi.label.name, AudioCoutputs) == 0) 1103 if (strcmp(mi.label.name, AudioCoutputs) == 0)
1104 oclass = mi.mixer_class; 1104 oclass = mi.mixer_class;
1105 if (strcmp(mi.label.name, AudioCrecord) == 0) 1105 if (strcmp(mi.label.name, AudioCrecord) == 0)
1106 rclass = mi.mixer_class; 1106 rclass = mi.mixer_class;
1107 } 1107 }
1108 } 1108 }
1109 mutex_exit(sc->sc_lock); 1109 mutex_exit(sc->sc_lock);
1110 1110
1111 /* Allocate save area. Ensure non-zero allocation. */ 1111 /* Allocate save area. Ensure non-zero allocation. */
1112 sc->sc_nmixer_states = mi.index; 1112 sc->sc_nmixer_states = mi.index;
1113 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) * 1113 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) *
1114 (sc->sc_nmixer_states + 1), KM_SLEEP); 1114 (sc->sc_nmixer_states + 1), KM_SLEEP);
1115 1115
1116 /* 1116 /*
1117 * This is where we assign each control in the "audio" model, to the 1117 * This is where we assign each control in the "audio" model, to the
1118 * underlying "mixer" control. We walk through the whole list once, 1118 * underlying "mixer" control. We walk through the whole list once,
1119 * assigning likely candidates as we come across them. 1119 * assigning likely candidates as we come across them.
1120 */ 1120 */
1121 record_master_found = 0; 1121 record_master_found = 0;
1122 record_source_found = 0; 1122 record_source_found = 0;
1123 mutex_enter(sc->sc_lock); 1123 mutex_enter(sc->sc_lock);
1124 for(mi.index = 0; ; mi.index++) { 1124 for(mi.index = 0; ; mi.index++) {
1125 if (audio_query_devinfo(sc, &mi) != 0) 1125 if (audio_query_devinfo(sc, &mi) != 0)
1126 break; 1126 break;
1127 KASSERT(mi.index < sc->sc_nmixer_states); 1127 KASSERT(mi.index < sc->sc_nmixer_states);
1128 if (mi.type == AUDIO_MIXER_CLASS) 1128 if (mi.type == AUDIO_MIXER_CLASS)
1129 continue; 1129 continue;
1130 if (mi.mixer_class == iclass) { 1130 if (mi.mixer_class == iclass) {
1131 /* 1131 /*
1132 * AudioCinputs is only a fallback, when we don't 1132 * AudioCinputs is only a fallback, when we don't
1133 * find what we're looking for in AudioCrecord, so 1133 * find what we're looking for in AudioCrecord, so
1134 * check the flags before accepting one of these. 1134 * check the flags before accepting one of these.
1135 */ 1135 */
1136 if (strcmp(mi.label.name, AudioNmaster) == 0 1136 if (strcmp(mi.label.name, AudioNmaster) == 0
1137 && record_master_found == 0) 1137 && record_master_found == 0)
1138 sc->sc_inports.master = mi.index; 1138 sc->sc_inports.master = mi.index;
1139 if (strcmp(mi.label.name, AudioNsource) == 0 1139 if (strcmp(mi.label.name, AudioNsource) == 0
1140 && record_source_found == 0) { 1140 && record_source_found == 0) {
1141 if (mi.type == AUDIO_MIXER_ENUM) { 1141 if (mi.type == AUDIO_MIXER_ENUM) {
1142 int i; 1142 int i;
1143 for(i = 0; i < mi.un.e.num_mem; i++) 1143 for(i = 0; i < mi.un.e.num_mem; i++)
1144 if (strcmp(mi.un.e.member[i].label.name, 1144 if (strcmp(mi.un.e.member[i].label.name,
@@ -2065,3672 +2065,3614 @@ audio_open(dev_t dev, struct audio_softc @@ -2065,3672 +2065,3614 @@ audio_open(dev_t dev, struct audio_softc
2065 error = fd_clone(fp, fd, flags, &audio_fileops, af); 2065 error = fd_clone(fp, fd, flags, &audio_fileops, af);
2066 KASSERT(error == EMOVEFD); 2066 KASSERT(error == EMOVEFD);
2067 } 2067 }
2068 2068
2069 TRACEF(3, af, "done"); 2069 TRACEF(3, af, "done");
2070 return error; 2070 return error;
2071 2071
2072 /* 2072 /*
2073 * Since track here is not yet linked to sc_files, 2073 * Since track here is not yet linked to sc_files,
2074 * you can call track_destroy() without sc_intr_lock. 2074 * you can call track_destroy() without sc_intr_lock.
2075 */ 2075 */
2076bad3: 2076bad3:
2077 if (sc->sc_popens + sc->sc_ropens == 0) { 2077 if (sc->sc_popens + sc->sc_ropens == 0) {
2078 if (sc->hw_if->close) { 2078 if (sc->hw_if->close) {
2079 mutex_enter(sc->sc_intr_lock); 2079 mutex_enter(sc->sc_intr_lock);
2080 sc->hw_if->close(sc->hw_hdl); 2080 sc->hw_if->close(sc->hw_hdl);
2081 mutex_exit(sc->sc_intr_lock); 2081 mutex_exit(sc->sc_intr_lock);
2082 } 2082 }
2083 } 2083 }
2084bad2: 2084bad2:
2085 if (af->rtrack) { 2085 if (af->rtrack) {
2086 audio_track_destroy(af->rtrack); 2086 audio_track_destroy(af->rtrack);
2087 af->rtrack = NULL; 2087 af->rtrack = NULL;
2088 } 2088 }
2089 if (af->ptrack) { 2089 if (af->ptrack) {
2090 audio_track_destroy(af->ptrack); 2090 audio_track_destroy(af->ptrack);
2091 af->ptrack = NULL; 2091 af->ptrack = NULL;
2092 } 2092 }
2093bad1: 2093bad1:
2094 kmem_free(af, sizeof(*af)); 2094 kmem_free(af, sizeof(*af));
2095 return error; 2095 return error;
2096} 2096}
2097 2097
2098/* 2098/*
2099 * Must NOT called with sc_lock nor sc_exlock held. 2099 * Must NOT called with sc_lock nor sc_exlock held.
2100 */ 2100 */
2101int 2101int
2102audio_close(struct audio_softc *sc, audio_file_t *file) 2102audio_close(struct audio_softc *sc, audio_file_t *file)
2103{ 2103{
2104 audio_track_t *oldtrack; 2104 audio_track_t *oldtrack;
2105 int error; 2105 int error;
2106 2106
2107 KASSERT(!mutex_owned(sc->sc_lock)); 2107 KASSERT(!mutex_owned(sc->sc_lock));
2108 2108
2109 TRACEF(1, file, "%spid=%d.%d po=%d ro=%d", 2109 TRACEF(1, file, "%spid=%d.%d po=%d ro=%d",
2110 (audiodebug >= 3) ? "start " : "", 2110 (audiodebug >= 3) ? "start " : "",
2111 (int)curproc->p_pid, (int)curlwp->l_lid, 2111 (int)curproc->p_pid, (int)curlwp->l_lid,
2112 sc->sc_popens, sc->sc_ropens); 2112 sc->sc_popens, sc->sc_ropens);
2113 KASSERTMSG(sc->sc_popens + sc->sc_ropens > 0, 2113 KASSERTMSG(sc->sc_popens + sc->sc_ropens > 0,
2114 "sc->sc_popens=%d, sc->sc_ropens=%d", 2114 "sc->sc_popens=%d, sc->sc_ropens=%d",
2115 sc->sc_popens, sc->sc_ropens); 2115 sc->sc_popens, sc->sc_ropens);
2116 2116
2117 /* 2117 /*
2118 * Drain first. 2118 * Drain first.
2119 * It must be done before acquiring exclusive lock. 2119 * It must be done before acquiring exclusive lock.
2120 */ 2120 */
2121 if (file->ptrack) { 2121 if (file->ptrack) {
2122 mutex_enter(sc->sc_lock); 2122 mutex_enter(sc->sc_lock);
2123 audio_track_drain(sc, file->ptrack); 2123 audio_track_drain(sc, file->ptrack);
2124 mutex_exit(sc->sc_lock); 2124 mutex_exit(sc->sc_lock);
2125 } 2125 }
2126 2126
2127 /* Then, acquire exclusive lock to protect counters. */ 2127 /* Then, acquire exclusive lock to protect counters. */
2128 /* XXX what should I do when an error occurs? */ 2128 /* XXX what should I do when an error occurs? */
2129 error = audio_enter_exclusive(sc); 2129 error = audio_enter_exclusive(sc);
2130 if (error) 2130 if (error)
2131 return error; 2131 return error;
2132 2132
2133 if (file->ptrack) { 2133 if (file->ptrack) {
2134 /* Call hw halt_output if this is the last playback track. */ 2134 /* Call hw halt_output if this is the last playback track. */
2135 if (sc->sc_popens == 1 && sc->sc_pbusy) { 2135 if (sc->sc_popens == 1 && sc->sc_pbusy) {
2136 error = audio_pmixer_halt(sc); 2136 error = audio_pmixer_halt(sc);
2137 if (error) { 2137 if (error) {
2138 device_printf(sc->sc_dev, 2138 device_printf(sc->sc_dev,
2139 "halt_output failed with %d\n", error); 2139 "halt_output failed with %d\n", error);
2140 } 2140 }
2141 } 2141 }
2142 2142
2143 /* Destroy the track. */ 2143 /* Destroy the track. */
2144 oldtrack = file->ptrack; 2144 oldtrack = file->ptrack;
2145 mutex_enter(sc->sc_intr_lock); 2145 mutex_enter(sc->sc_intr_lock);
2146 file->ptrack = NULL; 2146 file->ptrack = NULL;
2147 mutex_exit(sc->sc_intr_lock); 2147 mutex_exit(sc->sc_intr_lock);
2148 TRACET(3, oldtrack, "dropframes=%" PRIu64, 2148 TRACET(3, oldtrack, "dropframes=%" PRIu64,
2149 oldtrack->dropframes); 2149 oldtrack->dropframes);
2150 audio_track_destroy(oldtrack); 2150 audio_track_destroy(oldtrack);
2151 2151
2152 KASSERT(sc->sc_popens > 0); 2152 KASSERT(sc->sc_popens > 0);
2153 sc->sc_popens--; 2153 sc->sc_popens--;
2154 2154
2155 /* Restore mixing volume if all tracks are gone. */ 2155 /* Restore mixing volume if all tracks are gone. */
2156 if (sc->sc_popens == 0) { 2156 if (sc->sc_popens == 0) {
2157 mutex_enter(sc->sc_intr_lock); 2157 mutex_enter(sc->sc_intr_lock);
2158 sc->sc_pmixer->volume = 256; 2158 sc->sc_pmixer->volume = 256;
2159 sc->sc_pmixer->voltimer = 0; 2159 sc->sc_pmixer->voltimer = 0;
2160 mutex_exit(sc->sc_intr_lock); 2160 mutex_exit(sc->sc_intr_lock);
2161 } 2161 }
2162 } 2162 }
2163 if (file->rtrack) { 2163 if (file->rtrack) {
2164 /* Call hw halt_input if this is the last recording track. */ 2164 /* Call hw halt_input if this is the last recording track. */
2165 if (sc->sc_ropens == 1 && sc->sc_rbusy) { 2165 if (sc->sc_ropens == 1 && sc->sc_rbusy) {
2166 error = audio_rmixer_halt(sc); 2166 error = audio_rmixer_halt(sc);
2167 if (error) { 2167 if (error) {
2168 device_printf(sc->sc_dev, 2168 device_printf(sc->sc_dev,
2169 "halt_input failed with %d\n", error); 2169 "halt_input failed with %d\n", error);
2170 } 2170 }
2171 } 2171 }
2172 2172
2173 /* Destroy the track. */ 2173 /* Destroy the track. */
2174 oldtrack = file->rtrack; 2174 oldtrack = file->rtrack;
2175 mutex_enter(sc->sc_intr_lock); 2175 mutex_enter(sc->sc_intr_lock);
2176 file->rtrack = NULL; 2176 file->rtrack = NULL;
2177 mutex_exit(sc->sc_intr_lock); 2177 mutex_exit(sc->sc_intr_lock);
2178 TRACET(3, oldtrack, "dropframes=%" PRIu64, 2178 TRACET(3, oldtrack, "dropframes=%" PRIu64,
2179 oldtrack->dropframes); 2179 oldtrack->dropframes);
2180 audio_track_destroy(oldtrack); 2180 audio_track_destroy(oldtrack);
2181 2181
2182 KASSERT(sc->sc_ropens > 0); 2182 KASSERT(sc->sc_ropens > 0);
2183 sc->sc_ropens--; 2183 sc->sc_ropens--;
2184 } 2184 }
2185 2185
2186 /* Call hw close if this is the last track. */ 2186 /* Call hw close if this is the last track. */
2187 if (sc->sc_popens + sc->sc_ropens == 0) { 2187 if (sc->sc_popens + sc->sc_ropens == 0) {
2188 if (sc->hw_if->close) { 2188 if (sc->hw_if->close) {
2189 TRACE(2, "hw_if close"); 2189 TRACE(2, "hw_if close");
2190 mutex_enter(sc->sc_intr_lock); 2190 mutex_enter(sc->sc_intr_lock);
2191 sc->hw_if->close(sc->hw_hdl); 2191 sc->hw_if->close(sc->hw_hdl);
2192 mutex_exit(sc->sc_intr_lock); 2192 mutex_exit(sc->sc_intr_lock);
2193 } 2193 }
2194 2194
2195 kauth_cred_free(sc->sc_cred); 2195 kauth_cred_free(sc->sc_cred);
2196 } 2196 }
2197 2197
2198 mutex_enter(sc->sc_intr_lock); 2198 mutex_enter(sc->sc_intr_lock);
2199 SLIST_REMOVE(&sc->sc_files, file, audio_file, entry); 2199 SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
2200 mutex_exit(sc->sc_intr_lock); 2200 mutex_exit(sc->sc_intr_lock);
2201 2201
2202 TRACE(3, "done"); 2202 TRACE(3, "done");
2203 audio_exit_exclusive(sc); 2203 audio_exit_exclusive(sc);
2204 return 0; 2204 return 0;
2205} 2205}
2206 2206
2207int 2207int
2208audio_read(struct audio_softc *sc, struct uio *uio, int ioflag, 2208audio_read(struct audio_softc *sc, struct uio *uio, int ioflag,
2209 audio_file_t *file) 2209 audio_file_t *file)
2210{ 2210{
2211 audio_track_t *track; 2211 audio_track_t *track;
2212 audio_ring_t *usrbuf; 2212 audio_ring_t *usrbuf;
2213 audio_ring_t *input; 2213 audio_ring_t *input;
2214 int error; 2214 int error;
2215 2215
2216 KASSERT(!mutex_owned(sc->sc_lock)); 2216 KASSERT(!mutex_owned(sc->sc_lock));
2217 2217
2218 /* 2218 /*
2219 * On half-duplex hardware, O_RDWR is treated as O_WRONLY. 2219 * On half-duplex hardware, O_RDWR is treated as O_WRONLY.
2220 * However read() system call itself can be called because it's 2220 * However read() system call itself can be called because it's
2221 * opened with O_RDWR. So in this case, deny this read(). 2221 * opened with O_RDWR. So in this case, deny this read().
2222 */ 2222 */
2223 track = file->rtrack; 2223 track = file->rtrack;
2224 if (track == NULL) { 2224 if (track == NULL) {
2225 return EBADF; 2225 return EBADF;
2226 } 2226 }
2227 2227
2228 /* I think it's better than EINVAL. */ 2228 /* I think it's better than EINVAL. */
2229 if (track->mmapped) 2229 if (track->mmapped)
2230 return EPERM; 2230 return EPERM;
2231 2231
2232 TRACET(2, track, "resid=%zd", uio->uio_resid); 2232 TRACET(2, track, "resid=%zd", uio->uio_resid);
2233 2233
2234#ifdef AUDIO_PM_IDLE 2234#ifdef AUDIO_PM_IDLE
2235 mutex_enter(sc->sc_lock); 2235 mutex_enter(sc->sc_lock);
2236 if (device_is_active(&sc->sc_dev) || sc->sc_idle) 2236 if (device_is_active(&sc->sc_dev) || sc->sc_idle)
2237 device_active(&sc->sc_dev, DVA_SYSTEM); 2237 device_active(&sc->sc_dev, DVA_SYSTEM);
2238 mutex_exit(sc->sc_lock); 2238 mutex_exit(sc->sc_lock);
2239#endif 2239#endif
2240 2240
2241 usrbuf = &track->usrbuf; 2241 usrbuf = &track->usrbuf;
2242 input = track->input; 2242 input = track->input;
2243 2243
2244 /* 2244 /*
2245 * The first read starts rmixer. 2245 * The first read starts rmixer.
2246 */ 2246 */
2247 error = audio_enter_exclusive(sc); 2247 error = audio_enter_exclusive(sc);
2248 if (error) 2248 if (error)
2249 return error; 2249 return error;
2250 if (sc->sc_rbusy == false) 2250 if (sc->sc_rbusy == false)
2251 audio_rmixer_start(sc); 2251 audio_rmixer_start(sc);
2252 audio_exit_exclusive(sc); 2252 audio_exit_exclusive(sc);
2253 2253
2254 error = 0; 2254 error = 0;
2255 while (uio->uio_resid > 0 && error == 0) { 2255 while (uio->uio_resid > 0 && error == 0) {
2256 int bytes; 2256 int bytes;
2257 2257
2258 TRACET(3, track, 2258 TRACET(3, track,
2259 "while resid=%zd input=%d/%d/%d usrbuf=%d/%d/H%d", 2259 "while resid=%zd input=%d/%d/%d usrbuf=%d/%d/H%d",
2260 uio->uio_resid, 2260 uio->uio_resid,
2261 input->head, input->used, input->capacity, 2261 input->head, input->used, input->capacity,
2262 usrbuf->head, usrbuf->used, track->usrbuf_usedhigh); 2262 usrbuf->head, usrbuf->used, track->usrbuf_usedhigh);
2263 2263
2264 /* Wait when buffers are empty. */ 2264 /* Wait when buffers are empty. */
2265 mutex_enter(sc->sc_lock); 2265 mutex_enter(sc->sc_lock);
2266 for (;;) { 2266 for (;;) {
2267 bool empty; 2267 bool empty;
2268 audio_track_lock_enter(track); 2268 audio_track_lock_enter(track);
2269 empty = (input->used == 0 && usrbuf->used == 0); 2269 empty = (input->used == 0 && usrbuf->used == 0);
2270 audio_track_lock_exit(track); 2270 audio_track_lock_exit(track);
2271 if (!empty) 2271 if (!empty)
2272 break; 2272 break;
2273 2273
2274 if ((ioflag & IO_NDELAY)) { 2274 if ((ioflag & IO_NDELAY)) {
2275 mutex_exit(sc->sc_lock); 2275 mutex_exit(sc->sc_lock);
2276 return EWOULDBLOCK; 2276 return EWOULDBLOCK;
2277 } 2277 }
2278 2278
2279 TRACET(3, track, "sleep"); 2279 TRACET(3, track, "sleep");
2280 error = audio_track_waitio(sc, track); 2280 error = audio_track_waitio(sc, track);
2281 if (error) { 2281 if (error) {
2282 mutex_exit(sc->sc_lock); 2282 mutex_exit(sc->sc_lock);
2283 return error; 2283 return error;
2284 } 2284 }
2285 } 2285 }
2286 mutex_exit(sc->sc_lock); 2286 mutex_exit(sc->sc_lock);
2287 2287
2288 audio_track_lock_enter(track); 2288 audio_track_lock_enter(track);
2289 audio_track_record(track); 2289 audio_track_record(track);
2290 2290
2291 /* uiomove from usrbuf as much as possible. */ 2291 /* uiomove from usrbuf as much as possible. */
2292 bytes = uimin(usrbuf->used, uio->uio_resid); 2292 bytes = uimin(usrbuf->used, uio->uio_resid);
2293 while (bytes > 0) { 2293 while (bytes > 0) {
2294 int head = usrbuf->head; 2294 int head = usrbuf->head;
2295 int len = uimin(bytes, usrbuf->capacity - head); 2295 int len = uimin(bytes, usrbuf->capacity - head);
2296 error = uiomove((uint8_t *)usrbuf->mem + head, len, 2296 error = uiomove((uint8_t *)usrbuf->mem + head, len,
2297 uio); 2297 uio);
2298 if (error) { 2298 if (error) {
2299 audio_track_lock_exit(track); 2299 audio_track_lock_exit(track);
2300 device_printf(sc->sc_dev, 2300 device_printf(sc->sc_dev,
2301 "uiomove(len=%d) failed with %d\n", 2301 "uiomove(len=%d) failed with %d\n",
2302 len, error); 2302 len, error);
2303 goto abort; 2303 goto abort;
2304 } 2304 }
2305 auring_take(usrbuf, len); 2305 auring_take(usrbuf, len);
2306 track->useriobytes += len; 2306 track->useriobytes += len;
2307 TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d", 2307 TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d",
2308 len, 2308 len,
2309 usrbuf->head, usrbuf->used, usrbuf->capacity); 2309 usrbuf->head, usrbuf->used, usrbuf->capacity);
2310 bytes -= len; 2310 bytes -= len;
2311 } 2311 }
2312 2312
2313 audio_track_lock_exit(track); 2313 audio_track_lock_exit(track);
2314 } 2314 }
2315 2315
2316abort: 2316abort:
2317 return error; 2317 return error;
2318} 2318}
2319 2319
2320 2320
2321/* 2321/*
2322 * Clear file's playback and/or record track buffer immediately. 2322 * Clear file's playback and/or record track buffer immediately.
2323 */ 2323 */
2324static void 2324static void
2325audio_file_clear(struct audio_softc *sc, audio_file_t *file) 2325audio_file_clear(struct audio_softc *sc, audio_file_t *file)
2326{ 2326{
2327 2327
2328 if (file->ptrack) 2328 if (file->ptrack)
2329 audio_track_clear(sc, file->ptrack); 2329 audio_track_clear(sc, file->ptrack);
2330 if (file->rtrack) 2330 if (file->rtrack)
2331 audio_track_clear(sc, file->rtrack); 2331 audio_track_clear(sc, file->rtrack);
2332} 2332}
2333 2333
2334int 2334int
2335audio_write(struct audio_softc *sc, struct uio *uio, int ioflag, 2335audio_write(struct audio_softc *sc, struct uio *uio, int ioflag,
2336 audio_file_t *file) 2336 audio_file_t *file)
2337{ 2337{
2338 audio_track_t *track; 2338 audio_track_t *track;
2339 audio_ring_t *usrbuf; 2339 audio_ring_t *usrbuf;
2340 audio_ring_t *outbuf; 2340 audio_ring_t *outbuf;
2341 int error; 2341 int error;
2342 2342
2343 KASSERT(!mutex_owned(sc->sc_lock)); 2343 KASSERT(!mutex_owned(sc->sc_lock));
2344 2344
2345 track = file->ptrack; 2345 track = file->ptrack;
2346 KASSERT(track); 2346 KASSERT(track);
2347 2347
2348 /* I think it's better than EINVAL. */ 2348 /* I think it's better than EINVAL. */
2349 if (track->mmapped) 2349 if (track->mmapped)
2350 return EPERM; 2350 return EPERM;
2351 2351
2352 TRACET(2, track, "%sresid=%zd pid=%d.%d ioflag=0x%x", 2352 TRACET(2, track, "%sresid=%zd pid=%d.%d ioflag=0x%x",
2353 audiodebug >= 3 ? "begin " : "", 2353 audiodebug >= 3 ? "begin " : "",
2354 uio->uio_resid, (int)curproc->p_pid, (int)curlwp->l_lid, ioflag); 2354 uio->uio_resid, (int)curproc->p_pid, (int)curlwp->l_lid, ioflag);
2355 2355
2356 if (uio->uio_resid == 0) { 2356 if (uio->uio_resid == 0) {
2357 track->eofcounter++; 2357 track->eofcounter++;
2358 return 0; 2358 return 0;
2359 } 2359 }
2360 2360
2361#ifdef AUDIO_PM_IDLE 2361#ifdef AUDIO_PM_IDLE
2362 mutex_enter(sc->sc_lock); 2362 mutex_enter(sc->sc_lock);
2363 if (device_is_active(&sc->sc_dev) || sc->sc_idle) 2363 if (device_is_active(&sc->sc_dev) || sc->sc_idle)
2364 device_active(&sc->sc_dev, DVA_SYSTEM); 2364 device_active(&sc->sc_dev, DVA_SYSTEM);
2365 mutex_exit(sc->sc_lock); 2365 mutex_exit(sc->sc_lock);
2366#endif 2366#endif
2367 2367
2368 usrbuf = &track->usrbuf; 2368 usrbuf = &track->usrbuf;
2369 outbuf = &track->outbuf; 2369 outbuf = &track->outbuf;
2370 2370
2371 /* 2371 /*
2372 * The first write starts pmixer. 2372 * The first write starts pmixer.
2373 */ 2373 */
2374 error = audio_enter_exclusive(sc); 2374 error = audio_enter_exclusive(sc);
2375 if (error) 2375 if (error)
2376 return error; 2376 return error;
2377 if (sc->sc_pbusy == false) 2377 if (sc->sc_pbusy == false)
2378 audio_pmixer_start(sc, false); 2378 audio_pmixer_start(sc, false);
2379 audio_exit_exclusive(sc); 2379 audio_exit_exclusive(sc);
2380 2380
2381 track->pstate = AUDIO_STATE_RUNNING; 2381 track->pstate = AUDIO_STATE_RUNNING;
2382 error = 0; 2382 error = 0;
2383 while (uio->uio_resid > 0 && error == 0) { 2383 while (uio->uio_resid > 0 && error == 0) {
2384 int bytes; 2384 int bytes;
2385 2385
2386 TRACET(3, track, "while resid=%zd usrbuf=%d/%d/H%d", 2386 TRACET(3, track, "while resid=%zd usrbuf=%d/%d/H%d",
2387 uio->uio_resid, 2387 uio->uio_resid,
2388 usrbuf->head, usrbuf->used, track->usrbuf_usedhigh); 2388 usrbuf->head, usrbuf->used, track->usrbuf_usedhigh);
2389 2389
2390 /* Wait when buffers are full. */ 2390 /* Wait when buffers are full. */
2391 mutex_enter(sc->sc_lock); 2391 mutex_enter(sc->sc_lock);
2392 for (;;) { 2392 for (;;) {
2393 bool full; 2393 bool full;
2394 audio_track_lock_enter(track); 2394 audio_track_lock_enter(track);
2395 full = (usrbuf->used >= track->usrbuf_usedhigh && 2395 full = (usrbuf->used >= track->usrbuf_usedhigh &&
2396 outbuf->used >= outbuf->capacity); 2396 outbuf->used >= outbuf->capacity);
2397 audio_track_lock_exit(track); 2397 audio_track_lock_exit(track);
2398 if (!full) 2398 if (!full)
2399 break; 2399 break;
2400 2400
2401 if ((ioflag & IO_NDELAY)) { 2401 if ((ioflag & IO_NDELAY)) {
2402 error = EWOULDBLOCK; 2402 error = EWOULDBLOCK;
2403 mutex_exit(sc->sc_lock); 2403 mutex_exit(sc->sc_lock);
2404 goto abort; 2404 goto abort;
2405 } 2405 }
2406 2406
2407 TRACET(3, track, "sleep usrbuf=%d/H%d", 2407 TRACET(3, track, "sleep usrbuf=%d/H%d",
2408 usrbuf->used, track->usrbuf_usedhigh); 2408 usrbuf->used, track->usrbuf_usedhigh);
2409 error = audio_track_waitio(sc, track); 2409 error = audio_track_waitio(sc, track);
2410 if (error) { 2410 if (error) {
2411 mutex_exit(sc->sc_lock); 2411 mutex_exit(sc->sc_lock);
2412 goto abort; 2412 goto abort;
2413 } 2413 }
2414 } 2414 }
2415 mutex_exit(sc->sc_lock); 2415 mutex_exit(sc->sc_lock);
2416 2416
2417 audio_track_lock_enter(track); 2417 audio_track_lock_enter(track);
2418 2418
2419 /* uiomove to usrbuf as much as possible. */ 2419 /* uiomove to usrbuf as much as possible. */
2420 bytes = uimin(track->usrbuf_usedhigh - usrbuf->used, 2420 bytes = uimin(track->usrbuf_usedhigh - usrbuf->used,
2421 uio->uio_resid); 2421 uio->uio_resid);
2422 while (bytes > 0) { 2422 while (bytes > 0) {
2423 int tail = auring_tail(usrbuf); 2423 int tail = auring_tail(usrbuf);
2424 int len = uimin(bytes, usrbuf->capacity - tail); 2424 int len = uimin(bytes, usrbuf->capacity - tail);
2425 error = uiomove((uint8_t *)usrbuf->mem + tail, len, 2425 error = uiomove((uint8_t *)usrbuf->mem + tail, len,
2426 uio); 2426 uio);
2427 if (error) { 2427 if (error) {
2428 audio_track_lock_exit(track); 2428 audio_track_lock_exit(track);
2429 device_printf(sc->sc_dev, 2429 device_printf(sc->sc_dev,
2430 "uiomove(len=%d) failed with %d\n", 2430 "uiomove(len=%d) failed with %d\n",
2431 len, error); 2431 len, error);
2432 goto abort; 2432 goto abort;
2433 } 2433 }
2434 auring_push(usrbuf, len); 2434 auring_push(usrbuf, len);
2435 track->useriobytes += len; 2435 track->useriobytes += len;
2436 TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d", 2436 TRACET(3, track, "uiomove(len=%d) usrbuf=%d/%d/C%d",
2437 len, 2437 len,
2438 usrbuf->head, usrbuf->used, usrbuf->capacity); 2438 usrbuf->head, usrbuf->used, usrbuf->capacity);
2439 bytes -= len; 2439 bytes -= len;
2440 } 2440 }
2441 2441
2442 /* Convert them as much as possible. */ 2442 /* Convert them as much as possible. */
2443 while (usrbuf->used >= track->usrbuf_blksize && 2443 while (usrbuf->used >= track->usrbuf_blksize &&
2444 outbuf->used < outbuf->capacity) { 2444 outbuf->used < outbuf->capacity) {
2445 audio_track_play(track); 2445 audio_track_play(track);
2446 } 2446 }
2447 2447
2448 audio_track_lock_exit(track); 2448 audio_track_lock_exit(track);
2449 } 2449 }
2450 2450
2451abort: 2451abort:
2452 TRACET(3, track, "done error=%d", error); 2452 TRACET(3, track, "done error=%d", error);
2453 return error; 2453 return error;
2454} 2454}
2455 2455
2456int 2456int
2457audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag, 2457audio_ioctl(dev_t dev, struct audio_softc *sc, u_long cmd, void *addr, int flag,
2458 struct lwp *l, audio_file_t *file) 2458 struct lwp *l, audio_file_t *file)
2459{ 2459{
2460 struct audio_offset *ao; 2460 struct audio_offset *ao;
2461 struct audio_info ai; 2461 struct audio_info ai;
2462 audio_track_t *track; 2462 audio_track_t *track;
2463 audio_encoding_t *ae; 2463 audio_encoding_t *ae;
2464 audio_format_query_t *query; 2464 audio_format_query_t *query;
2465 u_int stamp; 2465 u_int stamp;
2466 u_int offs; 2466 u_int offs;
2467 int fd; 2467 int fd;
2468 int index; 2468 int index;
2469 int error; 2469 int error;
2470 2470
2471 KASSERT(!mutex_owned(sc->sc_lock)); 2471 KASSERT(!mutex_owned(sc->sc_lock));
2472 2472
2473#if defined(AUDIO_DEBUG) 2473#if defined(AUDIO_DEBUG)
2474 const char *ioctlnames[] = { 2474 const char *ioctlnames[] = {
2475 " AUDIO_GETINFO", /* 21 */ 2475 " AUDIO_GETINFO", /* 21 */
2476 " AUDIO_SETINFO", /* 22 */ 2476 " AUDIO_SETINFO", /* 22 */
2477 " AUDIO_DRAIN", /* 23 */ 2477 " AUDIO_DRAIN", /* 23 */
2478 " AUDIO_FLUSH", /* 24 */ 2478 " AUDIO_FLUSH", /* 24 */
2479 " AUDIO_WSEEK", /* 25 */ 2479 " AUDIO_WSEEK", /* 25 */
2480 " AUDIO_RERROR", /* 26 */ 2480 " AUDIO_RERROR", /* 26 */
2481 " AUDIO_GETDEV", /* 27 */ 2481 " AUDIO_GETDEV", /* 27 */
2482 " AUDIO_GETENC", /* 28 */ 2482 " AUDIO_GETENC", /* 28 */
2483 " AUDIO_GETFD", /* 29 */ 2483 " AUDIO_GETFD", /* 29 */
2484 " AUDIO_SETFD", /* 30 */ 2484 " AUDIO_SETFD", /* 30 */
2485 " AUDIO_PERROR", /* 31 */ 2485 " AUDIO_PERROR", /* 31 */
2486 " AUDIO_GETIOFFS", /* 32 */ 2486 " AUDIO_GETIOFFS", /* 32 */
2487 " AUDIO_GETOOFFS", /* 33 */ 2487 " AUDIO_GETOOFFS", /* 33 */
2488 " AUDIO_GETPROPS", /* 34 */ 2488 " AUDIO_GETPROPS", /* 34 */
2489 " AUDIO_GETBUFINFO", /* 35 */ 2489 " AUDIO_GETBUFINFO", /* 35 */
2490 " AUDIO_SETCHAN", /* 36 */ 2490 " AUDIO_SETCHAN", /* 36 */
2491 " AUDIO_GETCHAN", /* 37 */ 2491 " AUDIO_GETCHAN", /* 37 */
2492 " AUDIO_QUERYFORMAT", /* 38 */ 2492 " AUDIO_QUERYFORMAT", /* 38 */
2493 " AUDIO_GETFORMAT", /* 39 */ 2493 " AUDIO_GETFORMAT", /* 39 */
2494 " AUDIO_SETFORMAT", /* 40 */ 2494 " AUDIO_SETFORMAT", /* 40 */
2495 }; 2495 };
2496 int nameidx = (cmd & 0xff); 2496 int nameidx = (cmd & 0xff);
2497 const char *ioctlname = ""; 2497 const char *ioctlname = "";
2498 if (21 <= nameidx && nameidx <= 21 + __arraycount(ioctlnames)) 2498 if (21 <= nameidx && nameidx <= 21 + __arraycount(ioctlnames))
2499 ioctlname = ioctlnames[nameidx - 21]; 2499 ioctlname = ioctlnames[nameidx - 21];
2500 TRACEF(2, file, "(%lu,'%c',%lu)%s pid=%d.%d", 2500 TRACEF(2, file, "(%lu,'%c',%lu)%s pid=%d.%d",
2501 IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname, 2501 IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname,
2502 (int)curproc->p_pid, (int)l->l_lid); 2502 (int)curproc->p_pid, (int)l->l_lid);
2503#endif 2503#endif
2504 2504
2505 error = 0; 2505 error = 0;
2506 switch (cmd) { 2506 switch (cmd) {
2507 case FIONBIO: 2507 case FIONBIO:
2508 /* All handled in the upper FS layer. */ 2508 /* All handled in the upper FS layer. */
2509 break; 2509 break;
2510 2510
2511 case FIONREAD: 2511 case FIONREAD:
2512 /* Get the number of bytes that can be read. */ 2512 /* Get the number of bytes that can be read. */
2513 if (file->rtrack) { 2513 if (file->rtrack) {
2514 *(int *)addr = audio_track_readablebytes(file->rtrack); 2514 *(int *)addr = audio_track_readablebytes(file->rtrack);
2515 } else { 2515 } else {
2516 *(int *)addr = 0; 2516 *(int *)addr = 0;
2517 } 2517 }
2518 break; 2518 break;
2519 2519
2520 case FIOASYNC: 2520 case FIOASYNC:
2521 /* Set/Clear ASYNC I/O. */ 2521 /* Set/Clear ASYNC I/O. */
2522 if (*(int *)addr) { 2522 if (*(int *)addr) {
2523 file->async_audio = curproc->p_pid; 2523 file->async_audio = curproc->p_pid;
2524 TRACEF(2, file, "FIOASYNC pid %d", file->async_audio); 2524 TRACEF(2, file, "FIOASYNC pid %d", file->async_audio);
2525 } else { 2525 } else {
2526 file->async_audio = 0; 2526 file->async_audio = 0;
2527 TRACEF(2, file, "FIOASYNC off"); 2527 TRACEF(2, file, "FIOASYNC off");
2528 } 2528 }
2529 break; 2529 break;
2530 2530
2531 case AUDIO_FLUSH: 2531 case AUDIO_FLUSH:
2532 /* XXX TODO: clear errors and restart? */ 2532 /* XXX TODO: clear errors and restart? */
2533 audio_file_clear(sc, file); 2533 audio_file_clear(sc, file);
2534 break; 2534 break;
2535 2535
2536 case AUDIO_RERROR: 2536 case AUDIO_RERROR:
2537 /* 2537 /*
2538 * Number of read bytes dropped. We don't know where 2538 * Number of read bytes dropped. We don't know where
2539 * or when they were dropped (including conversion stage). 2539 * or when they were dropped (including conversion stage).
2540 * Therefore, the number of accurate bytes or samples is 2540 * Therefore, the number of accurate bytes or samples is
2541 * also unknown. 2541 * also unknown.
2542 */ 2542 */
2543 track = file->rtrack; 2543 track = file->rtrack;
2544 if (track) { 2544 if (track) {
2545 *(int *)addr = frametobyte(&track->usrbuf.fmt, 2545 *(int *)addr = frametobyte(&track->usrbuf.fmt,
2546 track->dropframes); 2546 track->dropframes);
2547 } 2547 }
2548 break; 2548 break;
2549 2549
2550 case AUDIO_PERROR: 2550 case AUDIO_PERROR:
2551 /* 2551 /*
2552 * Number of write bytes dropped. We don't know where 2552 * Number of write bytes dropped. We don't know where
2553 * or when they were dropped (including conversion stage). 2553 * or when they were dropped (including conversion stage).
2554 * Therefore, the number of accurate bytes or samples is 2554 * Therefore, the number of accurate bytes or samples is
2555 * also unknown. 2555 * also unknown.
2556 */ 2556 */
2557 track = file->ptrack; 2557 track = file->ptrack;
2558 if (track) { 2558 if (track) {
2559 *(int *)addr = frametobyte(&track->usrbuf.fmt, 2559 *(int *)addr = frametobyte(&track->usrbuf.fmt,
2560 track->dropframes); 2560 track->dropframes);
2561 } 2561 }
2562 break; 2562 break;
2563 2563
2564 case AUDIO_GETIOFFS: 2564 case AUDIO_GETIOFFS:
2565 /* XXX TODO */ 2565 /* XXX TODO */
2566 ao = (struct audio_offset *)addr; 2566 ao = (struct audio_offset *)addr;
2567 ao->samples = 0; 2567 ao->samples = 0;
2568 ao->deltablks = 0; 2568 ao->deltablks = 0;
2569 ao->offset = 0; 2569 ao->offset = 0;
2570 break; 2570 break;
2571 2571
2572 case AUDIO_GETOOFFS: 2572 case AUDIO_GETOOFFS:
2573 ao = (struct audio_offset *)addr; 2573 ao = (struct audio_offset *)addr;
2574 track = file->ptrack; 2574 track = file->ptrack;
2575 if (track == NULL) { 2575 if (track == NULL) {
2576 ao->samples = 0; 2576 ao->samples = 0;
2577 ao->deltablks = 0; 2577 ao->deltablks = 0;
2578 ao->offset = 0; 2578 ao->offset = 0;
2579 break; 2579 break;
2580 } 2580 }
2581 mutex_enter(sc->sc_lock); 2581 mutex_enter(sc->sc_lock);
2582 mutex_enter(sc->sc_intr_lock); 2582 mutex_enter(sc->sc_intr_lock);
2583 /* figure out where next DMA will start */ 2583 /* figure out where next DMA will start */
2584 stamp = track->usrbuf_stamp; 2584 stamp = track->usrbuf_stamp;
2585 offs = track->usrbuf.head; 2585 offs = track->usrbuf.head;
2586 mutex_exit(sc->sc_intr_lock); 2586 mutex_exit(sc->sc_intr_lock);
2587 mutex_exit(sc->sc_lock); 2587 mutex_exit(sc->sc_lock);
2588 2588
2589 ao->samples = stamp; 2589 ao->samples = stamp;
2590 ao->deltablks = (stamp / track->usrbuf_blksize) - 2590 ao->deltablks = (stamp / track->usrbuf_blksize) -
2591 (track->usrbuf_stamp_last / track->usrbuf_blksize); 2591 (track->usrbuf_stamp_last / track->usrbuf_blksize);
2592 track->usrbuf_stamp_last = stamp; 2592 track->usrbuf_stamp_last = stamp;
2593 offs = rounddown(offs, track->usrbuf_blksize) 2593 offs = rounddown(offs, track->usrbuf_blksize)
2594 + track->usrbuf_blksize; 2594 + track->usrbuf_blksize;
2595 if (offs >= track->usrbuf.capacity) 2595 if (offs >= track->usrbuf.capacity)
2596 offs -= track->usrbuf.capacity; 2596 offs -= track->usrbuf.capacity;
2597 ao->offset = offs; 2597 ao->offset = offs;
2598 2598
2599 TRACET(3, track, "GETOOFFS: samples=%u deltablks=%u offset=%u", 2599 TRACET(3, track, "GETOOFFS: samples=%u deltablks=%u offset=%u",
2600 ao->samples, ao->deltablks, ao->offset); 2600 ao->samples, ao->deltablks, ao->offset);
2601 break; 2601 break;
2602 2602
2603 case AUDIO_WSEEK: 2603 case AUDIO_WSEEK:
2604 /* XXX return value does not include outbuf one. */ 2604 /* XXX return value does not include outbuf one. */
2605 if (file->ptrack) 2605 if (file->ptrack)
2606 *(u_long *)addr = file->ptrack->usrbuf.used; 2606 *(u_long *)addr = file->ptrack->usrbuf.used;
2607 break; 2607 break;
2608 2608
2609 case AUDIO_SETINFO: 2609 case AUDIO_SETINFO:
2610 error = audio_enter_exclusive(sc); 2610 error = audio_enter_exclusive(sc);
2611 if (error) 2611 if (error)
2612 break; 2612 break;
2613 error = audio_file_setinfo(sc, file, (struct audio_info *)addr); 2613 error = audio_file_setinfo(sc, file, (struct audio_info *)addr);
2614 if (error) { 2614 if (error) {
2615 audio_exit_exclusive(sc); 2615 audio_exit_exclusive(sc);
2616 break; 2616 break;
2617 } 2617 }
2618 /* XXX TODO: update last_ai if /dev/sound ? */ 2618 /* XXX TODO: update last_ai if /dev/sound ? */
2619 if (ISDEVSOUND(dev)) 2619 if (ISDEVSOUND(dev))
2620 error = audiogetinfo(sc, &sc->sc_ai, 0, file); 2620 error = audiogetinfo(sc, &sc->sc_ai, 0, file);
2621 audio_exit_exclusive(sc); 2621 audio_exit_exclusive(sc);
2622 break; 2622 break;
2623 2623
2624 case AUDIO_GETINFO: 2624 case AUDIO_GETINFO:
2625 error = audio_enter_exclusive(sc); 2625 error = audio_enter_exclusive(sc);
2626 if (error) 2626 if (error)
2627 break; 2627 break;
2628 error = audiogetinfo(sc, (struct audio_info *)addr, 1, file); 2628 error = audiogetinfo(sc, (struct audio_info *)addr, 1, file);
2629 audio_exit_exclusive(sc); 2629 audio_exit_exclusive(sc);
2630 break; 2630 break;
2631 2631
2632 case AUDIO_GETBUFINFO: 2632 case AUDIO_GETBUFINFO:
2633 mutex_enter(sc->sc_lock); 2633 mutex_enter(sc->sc_lock);
2634 error = audiogetinfo(sc, (struct audio_info *)addr, 0, file); 2634 error = audiogetinfo(sc, (struct audio_info *)addr, 0, file);
2635 mutex_exit(sc->sc_lock); 2635 mutex_exit(sc->sc_lock);
2636 break; 2636 break;
2637 2637
2638 case AUDIO_DRAIN: 2638 case AUDIO_DRAIN:
2639 if (file->ptrack) { 2639 if (file->ptrack) {
2640 mutex_enter(sc->sc_lock); 2640 mutex_enter(sc->sc_lock);
2641 error = audio_track_drain(sc, file->ptrack); 2641 error = audio_track_drain(sc, file->ptrack);
2642 mutex_exit(sc->sc_lock); 2642 mutex_exit(sc->sc_lock);
2643 } 2643 }
2644 break; 2644 break;
2645 2645
2646 case AUDIO_GETDEV: 2646 case AUDIO_GETDEV:
2647 mutex_enter(sc->sc_lock); 2647 mutex_enter(sc->sc_lock);
2648 error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr); 2648 error = sc->hw_if->getdev(sc->hw_hdl, (audio_device_t *)addr);
2649 mutex_exit(sc->sc_lock); 2649 mutex_exit(sc->sc_lock);
2650 break; 2650 break;
2651 2651
2652 case AUDIO_GETENC: 2652 case AUDIO_GETENC:
2653 ae = (audio_encoding_t *)addr; 2653 ae = (audio_encoding_t *)addr;
2654 index = ae->index; 2654 index = ae->index;
2655 if (index < 0 || index >= __arraycount(audio_encodings)) { 2655 if (index < 0 || index >= __arraycount(audio_encodings)) {
2656 error = EINVAL; 2656 error = EINVAL;
2657 break; 2657 break;
2658 } 2658 }
2659 *ae = audio_encodings[index]; 2659 *ae = audio_encodings[index];
2660 ae->index = index; 2660 ae->index = index;
2661 /* 2661 /*
2662 * EMULATED always. 2662 * EMULATED always.
2663 * EMULATED flag at that time used to mean that it could 2663 * EMULATED flag at that time used to mean that it could
2664 * not be passed directly to the hardware as-is. But 2664 * not be passed directly to the hardware as-is. But
2665 * currently, all formats including hardware native is not 2665 * currently, all formats including hardware native is not
2666 * passed directly to the hardware. So I set EMULATED 2666 * passed directly to the hardware. So I set EMULATED
2667 * flag for all formats. 2667 * flag for all formats.
2668 */ 2668 */
2669 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 2669 ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
2670 break; 2670 break;
2671 2671
2672 case AUDIO_GETFD: 2672 case AUDIO_GETFD:
2673 /* 2673 /*
2674 * Returns the current setting of full duplex mode. 2674 * Returns the current setting of full duplex mode.
2675 * If HW has full duplex mode and there are two mixers, 2675 * If HW has full duplex mode and there are two mixers,
2676 * it is full duplex. Otherwise half duplex. 2676 * it is full duplex. Otherwise half duplex.
2677 */ 2677 */
2678 mutex_enter(sc->sc_lock); 2678 mutex_enter(sc->sc_lock);
2679 fd = (sc->sc_props & AUDIO_PROP_FULLDUPLEX) 2679 fd = (sc->sc_props & AUDIO_PROP_FULLDUPLEX)
2680 && (sc->sc_pmixer && sc->sc_rmixer); 2680 && (sc->sc_pmixer && sc->sc_rmixer);
2681 mutex_exit(sc->sc_lock); 2681 mutex_exit(sc->sc_lock);
2682 *(int *)addr = fd; 2682 *(int *)addr = fd;
2683 break; 2683 break;
2684 2684
2685 case AUDIO_GETPROPS: 2685 case AUDIO_GETPROPS:
2686 *(int *)addr = sc->sc_props; 2686 *(int *)addr = sc->sc_props;
2687 break; 2687 break;
2688 2688
2689 case AUDIO_QUERYFORMAT: 2689 case AUDIO_QUERYFORMAT:
2690 query = (audio_format_query_t *)addr; 2690 query = (audio_format_query_t *)addr;
2691 if (sc->hw_if->query_format) { 2691 if (sc->hw_if->query_format) {
2692 mutex_enter(sc->sc_lock); 2692 mutex_enter(sc->sc_lock);
2693 error = sc->hw_if->query_format(sc->hw_hdl, query); 2693 error = sc->hw_if->query_format(sc->hw_hdl, query);
2694 mutex_exit(sc->sc_lock); 2694 mutex_exit(sc->sc_lock);
2695 /* Hide internal infomations */ 2695 /* Hide internal infomations */
2696 query->fmt.driver_data = NULL; 2696 query->fmt.driver_data = NULL;
2697 } else { 2697 } else {
2698 error = ENODEV; 2698 error = ENODEV;
2699 } 2699 }
2700 break; 2700 break;
2701 2701
2702 case AUDIO_GETFORMAT: 2702 case AUDIO_GETFORMAT:
2703 audio_mixers_get_format(sc, (struct audio_info *)addr); 2703 audio_mixers_get_format(sc, (struct audio_info *)addr);
2704 break; 2704 break;
2705 2705
2706 case AUDIO_SETFORMAT: 2706 case AUDIO_SETFORMAT:
2707 mutex_enter(sc->sc_lock); 2707 mutex_enter(sc->sc_lock);
2708 audio_mixers_get_format(sc, &ai); 2708 audio_mixers_get_format(sc, &ai);
2709 error = audio_mixers_set_format(sc, (struct audio_info *)addr); 2709 error = audio_mixers_set_format(sc, (struct audio_info *)addr);
2710 if (error) { 2710 if (error) {
2711 /* Rollback */ 2711 /* Rollback */
2712 audio_mixers_set_format(sc, &ai); 2712 audio_mixers_set_format(sc, &ai);
2713 } 2713 }
2714 mutex_exit(sc->sc_lock); 2714 mutex_exit(sc->sc_lock);
2715 break; 2715 break;
2716 2716
2717 case AUDIO_SETFD: 2717 case AUDIO_SETFD:
2718 case AUDIO_SETCHAN: 2718 case AUDIO_SETCHAN:
2719 case AUDIO_GETCHAN: 2719 case AUDIO_GETCHAN:
2720 /* Obsoleted */ 2720 /* Obsoleted */
2721 break; 2721 break;
2722 2722
2723 default: 2723 default:
2724 if (sc->hw_if->dev_ioctl) { 2724 if (sc->hw_if->dev_ioctl) {
2725 error = audio_enter_exclusive(sc); 2725 error = audio_enter_exclusive(sc);
2726 if (error) 2726 if (error)
2727 break; 2727 break;
2728 error = sc->hw_if->dev_ioctl(sc->hw_hdl, 2728 error = sc->hw_if->dev_ioctl(sc->hw_hdl,
2729 cmd, addr, flag, l); 2729 cmd, addr, flag, l);
2730 audio_exit_exclusive(sc); 2730 audio_exit_exclusive(sc);
2731 } else { 2731 } else {
2732 TRACEF(2, file, "unknown ioctl"); 2732 TRACEF(2, file, "unknown ioctl");
2733 error = EINVAL; 2733 error = EINVAL;
2734 } 2734 }
2735 break; 2735 break;
2736 } 2736 }
2737 TRACEF(2, file, "(%lu,'%c',%lu)%s result %d", 2737 TRACEF(2, file, "(%lu,'%c',%lu)%s result %d",
2738 IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname, 2738 IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd&0xff, ioctlname,
2739 error); 2739 error);
2740 return error; 2740 return error;
2741} 2741}
2742 2742
2743/* 2743/*
2744 * Returns the number of bytes that can be read on recording buffer. 2744 * Returns the number of bytes that can be read on recording buffer.
2745 */ 2745 */
2746static __inline int 2746static __inline int
2747audio_track_readablebytes(const audio_track_t *track) 2747audio_track_readablebytes(const audio_track_t *track)
2748{ 2748{
2749 int bytes; 2749 int bytes;
2750 2750
2751 KASSERT(track); 2751 KASSERT(track);
2752 KASSERT(track->mode == AUMODE_RECORD); 2752 KASSERT(track->mode == AUMODE_RECORD);
2753 2753
2754 /* 2754 /*
2755 * Although usrbuf is primarily readable data, recorded data 2755 * Although usrbuf is primarily readable data, recorded data
2756 * also stays in track->input until reading. So it is necessary 2756 * also stays in track->input until reading. So it is necessary
2757 * to add it. track->input is in frame, usrbuf is in byte. 2757 * to add it. track->input is in frame, usrbuf is in byte.
2758 */ 2758 */
2759 bytes = track->usrbuf.used + 2759 bytes = track->usrbuf.used +
2760 track->input->used * frametobyte(&track->usrbuf.fmt, 1); 2760 track->input->used * frametobyte(&track->usrbuf.fmt, 1);
2761 return bytes; 2761 return bytes;
2762} 2762}
2763 2763
2764int 2764int
2765audio_poll(struct audio_softc *sc, int events, struct lwp *l, 2765audio_poll(struct audio_softc *sc, int events, struct lwp *l,
2766 audio_file_t *file) 2766 audio_file_t *file)
2767{ 2767{
2768 audio_track_t *track; 2768 audio_track_t *track;
2769 int revents; 2769 int revents;
2770 bool in_is_valid; 2770 bool in_is_valid;
2771 bool out_is_valid; 2771 bool out_is_valid;
2772 2772
2773 KASSERT(!mutex_owned(sc->sc_lock)); 2773 KASSERT(!mutex_owned(sc->sc_lock));
2774 2774
2775#if defined(AUDIO_DEBUG) 2775#if defined(AUDIO_DEBUG)
2776#define POLLEV_BITMAP "\177\020" \ 2776#define POLLEV_BITMAP "\177\020" \
2777 "b\10WRBAND\0" \ 2777 "b\10WRBAND\0" \
2778 "b\7RDBAND\0" "b\6RDNORM\0" "b\5NVAL\0" "b\4HUP\0" \ 2778 "b\7RDBAND\0" "b\6RDNORM\0" "b\5NVAL\0" "b\4HUP\0" \
2779 "b\3ERR\0" "b\2OUT\0" "b\1PRI\0" "b\0IN\0" 2779 "b\3ERR\0" "b\2OUT\0" "b\1PRI\0" "b\0IN\0"
2780 char evbuf[64]; 2780 char evbuf[64];
2781 snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, events); 2781 snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, events);
2782 TRACEF(2, file, "pid=%d.%d events=%s", 2782 TRACEF(2, file, "pid=%d.%d events=%s",
2783 (int)curproc->p_pid, (int)l->l_lid, evbuf); 2783 (int)curproc->p_pid, (int)l->l_lid, evbuf);
2784#endif 2784#endif
2785 2785
2786 revents = 0; 2786 revents = 0;
2787 in_is_valid = false; 2787 in_is_valid = false;
2788 out_is_valid = false; 2788 out_is_valid = false;
2789 if (events & (POLLIN | POLLRDNORM)) { 2789 if (events & (POLLIN | POLLRDNORM)) {
2790 track = file->rtrack; 2790 track = file->rtrack;
2791 if (track) { 2791 if (track) {
2792 int used; 2792 int used;
2793 in_is_valid = true; 2793 in_is_valid = true;
2794 used = audio_track_readablebytes(track); 2794 used = audio_track_readablebytes(track);
2795 if (used > 0) 2795 if (used > 0)
2796 revents |= events & (POLLIN | POLLRDNORM); 2796 revents |= events & (POLLIN | POLLRDNORM);
2797 } 2797 }
2798 } 2798 }
2799 if (events & (POLLOUT | POLLWRNORM)) { 2799 if (events & (POLLOUT | POLLWRNORM)) {
2800 track = file->ptrack; 2800 track = file->ptrack;
2801 if (track) { 2801 if (track) {
2802 out_is_valid = true; 2802 out_is_valid = true;
2803 if (track->usrbuf.used <= track->usrbuf_usedlow) 2803 if (track->usrbuf.used <= track->usrbuf_usedlow)
2804 revents |= events & (POLLOUT | POLLWRNORM); 2804 revents |= events & (POLLOUT | POLLWRNORM);
2805 } 2805 }
2806 } 2806 }
2807 2807
2808 if (revents == 0) { 2808 if (revents == 0) {
2809 mutex_enter(sc->sc_lock); 2809 mutex_enter(sc->sc_lock);
2810 if (in_is_valid) { 2810 if (in_is_valid) {
2811 TRACEF(3, file, "selrecord rsel"); 2811 TRACEF(3, file, "selrecord rsel");
2812 selrecord(l, &sc->sc_rsel); 2812 selrecord(l, &sc->sc_rsel);
2813 } 2813 }
2814 if (out_is_valid) { 2814 if (out_is_valid) {
2815 TRACEF(3, file, "selrecord wsel"); 2815 TRACEF(3, file, "selrecord wsel");
2816 selrecord(l, &sc->sc_wsel); 2816 selrecord(l, &sc->sc_wsel);
2817 } 2817 }
2818 mutex_exit(sc->sc_lock); 2818 mutex_exit(sc->sc_lock);
2819 } 2819 }
2820 2820
2821#if defined(AUDIO_DEBUG) 2821#if defined(AUDIO_DEBUG)
2822 snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, revents); 2822 snprintb(evbuf, sizeof(evbuf), POLLEV_BITMAP, revents);
2823 TRACEF(2, file, "revents=%s", evbuf); 2823 TRACEF(2, file, "revents=%s", evbuf);
2824#endif 2824#endif
2825 return revents; 2825 return revents;
2826} 2826}
2827 2827
2828static const struct filterops audioread_filtops = { 2828static const struct filterops audioread_filtops = {
2829 .f_isfd = 1, 2829 .f_isfd = 1,
2830 .f_attach = NULL, 2830 .f_attach = NULL,
2831 .f_detach = filt_audioread_detach, 2831 .f_detach = filt_audioread_detach,
2832 .f_event = filt_audioread_event, 2832 .f_event = filt_audioread_event,
2833}; 2833};
2834 2834
2835static void 2835static void
2836filt_audioread_detach(struct knote *kn) 2836filt_audioread_detach(struct knote *kn)
2837{ 2837{
2838 struct audio_softc *sc; 2838 struct audio_softc *sc;
2839 audio_file_t *file; 2839 audio_file_t *file;
2840 2840
2841 file = kn->kn_hook; 2841 file = kn->kn_hook;
2842 sc = file->sc; 2842 sc = file->sc;
2843 TRACEF(3, file, ""); 2843 TRACEF(3, file, "");
2844 2844
2845 mutex_enter(sc->sc_lock); 2845 mutex_enter(sc->sc_lock);
2846 SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext); 2846 SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
2847 mutex_exit(sc->sc_lock); 2847 mutex_exit(sc->sc_lock);
2848} 2848}
2849 2849
2850static int 2850static int
2851filt_audioread_event(struct knote *kn, long hint) 2851filt_audioread_event(struct knote *kn, long hint)
2852{ 2852{
2853 audio_file_t *file; 2853 audio_file_t *file;
2854 audio_track_t *track; 2854 audio_track_t *track;
2855 2855
2856 file = kn->kn_hook; 2856 file = kn->kn_hook;
2857 track = file->rtrack; 2857 track = file->rtrack;
2858 2858
2859 /* 2859 /*
2860 * kn_data must contain the number of bytes can be read. 2860 * kn_data must contain the number of bytes can be read.
2861 * The return value indicates whether the event occurs or not. 2861 * The return value indicates whether the event occurs or not.
2862 */ 2862 */
2863 2863
2864 if (track == NULL) { 2864 if (track == NULL) {
2865 /* can not read with this descriptor. */ 2865 /* can not read with this descriptor. */
2866 kn->kn_data = 0; 2866 kn->kn_data = 0;
2867 return 0; 2867 return 0;
2868 } 2868 }
2869 2869
2870 kn->kn_data = audio_track_readablebytes(track); 2870 kn->kn_data = audio_track_readablebytes(track);
2871 TRACEF(3, file, "data=%" PRId64, kn->kn_data); 2871 TRACEF(3, file, "data=%" PRId64, kn->kn_data);
2872 return kn->kn_data > 0; 2872 return kn->kn_data > 0;
2873} 2873}
2874 2874
2875static const struct filterops audiowrite_filtops = { 2875static const struct filterops audiowrite_filtops = {
2876 .f_isfd = 1, 2876 .f_isfd = 1,
2877 .f_attach = NULL, 2877 .f_attach = NULL,
2878 .f_detach = filt_audiowrite_detach, 2878 .f_detach = filt_audiowrite_detach,
2879 .f_event = filt_audiowrite_event, 2879 .f_event = filt_audiowrite_event,
2880}; 2880};
2881 2881
2882static void 2882static void
2883filt_audiowrite_detach(struct knote *kn) 2883filt_audiowrite_detach(struct knote *kn)
2884{ 2884{
2885 struct audio_softc *sc; 2885 struct audio_softc *sc;
2886 audio_file_t *file; 2886 audio_file_t *file;
2887 2887
2888 file = kn->kn_hook; 2888 file = kn->kn_hook;
2889 sc = file->sc; 2889 sc = file->sc;
2890 TRACEF(3, file, ""); 2890 TRACEF(3, file, "");
2891 2891
2892 mutex_enter(sc->sc_lock); 2892 mutex_enter(sc->sc_lock);
2893 SLIST_REMOVE(&sc->sc_wsel.sel_klist, kn, knote, kn_selnext); 2893 SLIST_REMOVE(&sc->sc_wsel.sel_klist, kn, knote, kn_selnext);
2894 mutex_exit(sc->sc_lock); 2894 mutex_exit(sc->sc_lock);
2895} 2895}
2896 2896
2897static int 2897static int
2898filt_audiowrite_event(struct knote *kn, long hint) 2898filt_audiowrite_event(struct knote *kn, long hint)
2899{ 2899{
2900 audio_file_t *file; 2900 audio_file_t *file;
2901 audio_track_t *track; 2901 audio_track_t *track;
2902 2902
2903 file = kn->kn_hook; 2903 file = kn->kn_hook;
2904 track = file->ptrack; 2904 track = file->ptrack;
2905 2905
2906 /* 2906 /*
2907 * kn_data must contain the number of bytes can be write. 2907 * kn_data must contain the number of bytes can be write.
2908 * The return value indicates whether the event occurs or not. 2908 * The return value indicates whether the event occurs or not.
2909 */ 2909 */
2910 2910
2911 if (track == NULL) { 2911 if (track == NULL) {
2912 /* can not write with this descriptor. */ 2912 /* can not write with this descriptor. */
2913 kn->kn_data = 0; 2913 kn->kn_data = 0;
2914 return 0; 2914 return 0;
2915 } 2915 }
2916 2916
2917 kn->kn_data = track->usrbuf_usedhigh - track->usrbuf.used; 2917 kn->kn_data = track->usrbuf_usedhigh - track->usrbuf.used;
2918 TRACEF(3, file, "data=%" PRId64, kn->kn_data); 2918 TRACEF(3, file, "data=%" PRId64, kn->kn_data);
2919 return (track->usrbuf.used < track->usrbuf_usedlow); 2919 return (track->usrbuf.used < track->usrbuf_usedlow);
2920} 2920}
2921 2921
2922int 2922int
2923audio_kqfilter(struct audio_softc *sc, audio_file_t *file, struct knote *kn) 2923audio_kqfilter(struct audio_softc *sc, audio_file_t *file, struct knote *kn)
2924{ 2924{
2925 struct klist *klist; 2925 struct klist *klist;
2926 2926
2927 KASSERT(!mutex_owned(sc->sc_lock)); 2927 KASSERT(!mutex_owned(sc->sc_lock));
2928 2928
2929 TRACEF(3, file, "kn=%p kn_filter=%x", kn, (int)kn->kn_filter); 2929 TRACEF(3, file, "kn=%p kn_filter=%x", kn, (int)kn->kn_filter);
2930 2930
2931 switch (kn->kn_filter) { 2931 switch (kn->kn_filter) {
2932 case EVFILT_READ: 2932 case EVFILT_READ:
2933 klist = &sc->sc_rsel.sel_klist; 2933 klist = &sc->sc_rsel.sel_klist;
2934 kn->kn_fop = &audioread_filtops; 2934 kn->kn_fop = &audioread_filtops;
2935 break; 2935 break;
2936 2936
2937 case EVFILT_WRITE: 2937 case EVFILT_WRITE:
2938 klist = &sc->sc_wsel.sel_klist; 2938 klist = &sc->sc_wsel.sel_klist;
2939 kn->kn_fop = &audiowrite_filtops; 2939 kn->kn_fop = &audiowrite_filtops;
2940 break; 2940 break;
2941 2941
2942 default: 2942 default:
2943 return EINVAL; 2943 return EINVAL;
2944 } 2944 }
2945 2945
2946 kn->kn_hook = file; 2946 kn->kn_hook = file;
2947 2947
2948 mutex_enter(sc->sc_lock); 2948 mutex_enter(sc->sc_lock);
2949 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 2949 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
2950 mutex_exit(sc->sc_lock); 2950 mutex_exit(sc->sc_lock);
2951 2951
2952 return 0; 2952 return 0;
2953} 2953}
2954 2954
2955int 2955int
2956audio_mmap(struct audio_softc *sc, off_t *offp, size_t len, int prot, 2956audio_mmap(struct audio_softc *sc, off_t *offp, size_t len, int prot,
2957 int *flagsp, int *advicep, struct uvm_object **uobjp, int *maxprotp, 2957 int *flagsp, int *advicep, struct uvm_object **uobjp, int *maxprotp,
2958 audio_file_t *file) 2958 audio_file_t *file)
2959{ 2959{
2960 audio_track_t *track; 2960 audio_track_t *track;
2961 vsize_t vsize; 2961 vsize_t vsize;
2962 int error; 2962 int error;
2963 2963
2964 KASSERT(!mutex_owned(sc->sc_lock)); 2964 KASSERT(!mutex_owned(sc->sc_lock));
2965 2965
2966 TRACEF(2, file, "off=%lld, prot=%d", (long long)(*offp), prot); 2966 TRACEF(2, file, "off=%lld, prot=%d", (long long)(*offp), prot);
2967 2967
2968 if (*offp < 0) 2968 if (*offp < 0)
2969 return EINVAL; 2969 return EINVAL;
2970 2970
2971#if 0 2971#if 0
2972 /* XXX 2972 /* XXX
2973 * The idea here was to use the protection to determine if 2973 * The idea here was to use the protection to determine if
2974 * we are mapping the read or write buffer, but it fails. 2974 * we are mapping the read or write buffer, but it fails.
2975 * The VM system is broken in (at least) two ways. 2975 * The VM system is broken in (at least) two ways.
2976 * 1) If you map memory VM_PROT_WRITE you SIGSEGV 2976 * 1) If you map memory VM_PROT_WRITE you SIGSEGV
2977 * when writing to it, so VM_PROT_READ|VM_PROT_WRITE 2977 * when writing to it, so VM_PROT_READ|VM_PROT_WRITE
2978 * has to be used for mmapping the play buffer. 2978 * has to be used for mmapping the play buffer.
2979 * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE 2979 * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
2980 * audio_mmap will get called at some point with VM_PROT_READ 2980 * audio_mmap will get called at some point with VM_PROT_READ
2981 * only. 2981 * only.
2982 * So, alas, we always map the play buffer for now. 2982 * So, alas, we always map the play buffer for now.
2983 */ 2983 */
2984 if (prot == (VM_PROT_READ|VM_PROT_WRITE) || 2984 if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
2985 prot == VM_PROT_WRITE) 2985 prot == VM_PROT_WRITE)
2986 track = file->ptrack; 2986 track = file->ptrack;
2987 else if (prot == VM_PROT_READ) 2987 else if (prot == VM_PROT_READ)
2988 track = file->rtrack; 2988 track = file->rtrack;
2989 else 2989 else
2990 return EINVAL; 2990 return EINVAL;
2991#else 2991#else
2992 track = file->ptrack; 2992 track = file->ptrack;
2993#endif 2993#endif
2994 if (track == NULL) 2994 if (track == NULL)
2995 return EACCES; 2995 return EACCES;
2996 2996
2997 vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE); 2997 vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE);
2998 if (len > vsize) 2998 if (len > vsize)
2999 return EOVERFLOW; 2999 return EOVERFLOW;
3000 if (*offp > (uint)(vsize - len)) 3000 if (*offp > (uint)(vsize - len))
3001 return EOVERFLOW; 3001 return EOVERFLOW;
3002 3002
3003 /* XXX TODO: what happens when mmap twice. */ 3003 /* XXX TODO: what happens when mmap twice. */
3004 if (!track->mmapped) { 3004 if (!track->mmapped) {
3005 track->mmapped = true; 3005 track->mmapped = true;
3006 3006
3007 if (!track->is_pause) { 3007 if (!track->is_pause) {
3008 error = audio_enter_exclusive(sc); 3008 error = audio_enter_exclusive(sc);
3009 if (error) 3009 if (error)
3010 return error; 3010 return error;
3011 if (sc->sc_pbusy == false) 3011 if (sc->sc_pbusy == false)
3012 audio_pmixer_start(sc, true); 3012 audio_pmixer_start(sc, true);
3013 audio_exit_exclusive(sc); 3013 audio_exit_exclusive(sc);
3014 } 3014 }
3015 /* XXX mmapping record buffer is not supported */ 3015 /* XXX mmapping record buffer is not supported */
3016 } 3016 }
3017 3017
3018 /* get ringbuffer */ 3018 /* get ringbuffer */
3019 *uobjp = track->uobj; 3019 *uobjp = track->uobj;
3020 3020
3021 /* Acquire a reference for the mmap. munmap will release. */ 3021 /* Acquire a reference for the mmap. munmap will release. */
3022 uao_reference(*uobjp); 3022 uao_reference(*uobjp);
3023 *maxprotp = prot; 3023 *maxprotp = prot;
3024 *advicep = UVM_ADV_RANDOM; 3024 *advicep = UVM_ADV_RANDOM;
3025 *flagsp = MAP_SHARED; 3025 *flagsp = MAP_SHARED;
3026 return 0; 3026 return 0;
3027} 3027}
3028 3028
3029/* 3029/*
3030 * /dev/audioctl has to be able to open at any time without interference 3030 * /dev/audioctl has to be able to open at any time without interference
3031 * with any /dev/audio or /dev/sound. 3031 * with any /dev/audio or /dev/sound.
3032 */ 3032 */
3033static int 3033static int
3034audioctl_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 3034audioctl_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
3035 struct lwp *l) 3035 struct lwp *l)
3036{ 3036{
3037 struct file *fp; 3037 struct file *fp;
3038 audio_file_t *af; 3038 audio_file_t *af;
3039 int fd; 3039 int fd;
3040 int error; 3040 int error;
3041 3041
3042 KASSERT(mutex_owned(sc->sc_lock)); 3042 KASSERT(mutex_owned(sc->sc_lock));
3043 KASSERT(sc->sc_exlock); 3043 KASSERT(sc->sc_exlock);
3044 3044
3045 TRACE(1, ""); 3045 TRACE(1, "");
3046 3046
3047 error = fd_allocfile(&fp, &fd); 3047 error = fd_allocfile(&fp, &fd);
3048 if (error) 3048 if (error)
3049 return error; 3049 return error;
3050 3050
3051 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP); 3051 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
3052 af->sc = sc; 3052 af->sc = sc;
3053 af->dev = dev; 3053 af->dev = dev;
3054 3054
3055 /* Not necessary to insert sc_files. */ 3055 /* Not necessary to insert sc_files. */
3056 3056
3057 error = fd_clone(fp, fd, flags, &audio_fileops, af); 3057 error = fd_clone(fp, fd, flags, &audio_fileops, af);
3058 KASSERT(error == EMOVEFD); 3058 KASSERT(error == EMOVEFD);
3059 3059
3060 return error; 3060 return error;
3061} 3061}
3062 3062
3063/* 3063/*
3064 * Reallocate 'memblock' with specified 'bytes' if 'bytes' > 0. 
3065 * Or free 'memblock' and return NULL if 'byte' is zero. 
3066 */ 
3067static void * 
3068audio_realloc(void *memblock, size_t bytes) 
3069{ 
3070 
3071 if (memblock != NULL) { 
3072 if (bytes != 0) { 
3073 return kern_realloc(memblock, bytes, M_NOWAIT); 
3074 } else { 
3075 kern_free(memblock); 
3076 return NULL; 
3077 } 
3078 } else { 
3079 if (bytes != 0) { 
3080 return kern_malloc(bytes, M_NOWAIT); 
3081 } else { 
3082 return NULL; 
3083 } 
3084 } 
3085} 
3086 
3087/* 
3088 * Free 'mem' if available, and initialize the pointer. 3064 * Free 'mem' if available, and initialize the pointer.
3089 * For this reason, this is implemented as macro. 3065 * For this reason, this is implemented as macro.
3090 */ 3066 */
3091#define audio_free(mem) do { \ 3067#define audio_free(mem) do { \
3092 if (mem != NULL) { \ 3068 if (mem != NULL) { \
3093 kern_free(mem); \ 3069 kern_free(mem); \
3094 mem = NULL; \ 3070 mem = NULL; \
3095 } \ 3071 } \
3096} while (0) 3072} while (0)
3097 3073
3098/* 3074/*
 3075 * (Re)allocate 'memblock' with specified 'bytes'.
 3076 * bytes must not be 0.
 3077 * This function never returns NULL.
 3078 */
 3079static void *
 3080audio_realloc(void *memblock, size_t bytes)
 3081{
 3082
 3083 KASSERT(bytes != 0);
 3084 audio_free(memblock);
 3085 return kern_malloc(bytes, M_WAITOK);
 3086}
 3087
 3088/*
3099 * (Re)allocate usrbuf with 'newbufsize' bytes. 3089 * (Re)allocate usrbuf with 'newbufsize' bytes.
3100 * Use this function for usrbuf because only usrbuf can be mmapped. 3090 * Use this function for usrbuf because only usrbuf can be mmapped.
3101 * If successful, it updates track->usrbuf.mem, track->usrbuf.capacity and 3091 * If successful, it updates track->usrbuf.mem, track->usrbuf.capacity and
3102 * returns 0. Otherwise, it clears track->usrbuf.mem, track->usrbuf.capacity 3092 * returns 0. Otherwise, it clears track->usrbuf.mem, track->usrbuf.capacity
3103 * and returns errno. 3093 * and returns errno.
3104 * It must be called before updating usrbuf.capacity. 3094 * It must be called before updating usrbuf.capacity.
3105 */ 3095 */
3106static int 3096static int
3107audio_realloc_usrbuf(audio_track_t *track, int newbufsize) 3097audio_realloc_usrbuf(audio_track_t *track, int newbufsize)
3108{ 3098{
3109 struct audio_softc *sc; 3099 struct audio_softc *sc;
3110 vaddr_t vstart; 3100 vaddr_t vstart;
3111 vsize_t oldvsize; 3101 vsize_t oldvsize;
3112 vsize_t newvsize; 3102 vsize_t newvsize;
3113 int error; 3103 int error;
3114 3104
3115 KASSERT(newbufsize > 0); 3105 KASSERT(newbufsize > 0);
3116 sc = track->mixer->sc; 3106 sc = track->mixer->sc;
3117 3107
3118 /* Get a nonzero multiple of PAGE_SIZE */ 3108 /* Get a nonzero multiple of PAGE_SIZE */
3119 newvsize = roundup2(MAX(newbufsize, PAGE_SIZE), PAGE_SIZE); 3109 newvsize = roundup2(MAX(newbufsize, PAGE_SIZE), PAGE_SIZE);
3120 3110
3121 if (track->usrbuf.mem != NULL) { 3111 if (track->usrbuf.mem != NULL) {
3122 oldvsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), 3112 oldvsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE),
3123 PAGE_SIZE); 3113 PAGE_SIZE);
3124 if (oldvsize == newvsize) { 3114 if (oldvsize == newvsize) {
3125 track->usrbuf.capacity = newbufsize; 3115 track->usrbuf.capacity = newbufsize;
3126 return 0; 3116 return 0;
3127 } 3117 }
3128 vstart = (vaddr_t)track->usrbuf.mem; 3118 vstart = (vaddr_t)track->usrbuf.mem;
3129 uvm_unmap(kernel_map, vstart, vstart + oldvsize); 3119 uvm_unmap(kernel_map, vstart, vstart + oldvsize);
3130 /* uvm_unmap also detach uobj */ 3120 /* uvm_unmap also detach uobj */
3131 track->uobj = NULL; /* paranoia */ 3121 track->uobj = NULL; /* paranoia */
3132 track->usrbuf.mem = NULL; 3122 track->usrbuf.mem = NULL;
3133 } 3123 }
3134 3124
3135 /* Create a uvm anonymous object */ 3125 /* Create a uvm anonymous object */
3136 track->uobj = uao_create(newvsize, 0); 3126 track->uobj = uao_create(newvsize, 0);
3137 3127
3138 /* Map it into the kernel virtual address space */ 3128 /* Map it into the kernel virtual address space */
3139 vstart = 0; 3129 vstart = 0;
3140 error = uvm_map(kernel_map, &vstart, newvsize, track->uobj, 0, 0, 3130 error = uvm_map(kernel_map, &vstart, newvsize, track->uobj, 0, 0,
3141 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_NONE, 3131 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_NONE,
3142 UVM_ADV_RANDOM, 0)); 3132 UVM_ADV_RANDOM, 0));
3143 if (error) { 3133 if (error) {
3144 device_printf(sc->sc_dev, "uvm_map failed with %d\n", error); 3134 device_printf(sc->sc_dev, "uvm_map failed with %d\n", error);
3145 uao_detach(track->uobj); /* release reference */ 3135 uao_detach(track->uobj); /* release reference */
3146 goto abort; 3136 goto abort;
3147 } 3137 }
3148 3138
3149 error = uvm_map_pageable(kernel_map, vstart, vstart + newvsize, 3139 error = uvm_map_pageable(kernel_map, vstart, vstart + newvsize,
3150 false, 0); 3140 false, 0);
3151 if (error) { 3141 if (error) {
3152 device_printf(sc->sc_dev, "uvm_map_pageable failed with %d\n", 3142 device_printf(sc->sc_dev, "uvm_map_pageable failed with %d\n",
3153 error); 3143 error);
3154 uvm_unmap(kernel_map, vstart, vstart + newvsize); 3144 uvm_unmap(kernel_map, vstart, vstart + newvsize);
3155 /* uvm_unmap also detach uobj */ 3145 /* uvm_unmap also detach uobj */
3156 goto abort; 3146 goto abort;
3157 } 3147 }
3158 3148
3159 track->usrbuf.mem = (void *)vstart; 3149 track->usrbuf.mem = (void *)vstart;
3160 track->usrbuf.capacity = newbufsize; 3150 track->usrbuf.capacity = newbufsize;
3161 memset(track->usrbuf.mem, 0, newvsize); 3151 memset(track->usrbuf.mem, 0, newvsize);
3162 return 0; 3152 return 0;
3163 3153
3164 /* failure */ 3154 /* failure */
3165abort: 3155abort:
3166 track->uobj = NULL; /* paranoia */ 3156 track->uobj = NULL; /* paranoia */
3167 track->usrbuf.mem = NULL; 3157 track->usrbuf.mem = NULL;
3168 track->usrbuf.capacity = 0; 3158 track->usrbuf.capacity = 0;
3169 return error; 3159 return error;
3170} 3160}
3171 3161
3172/* 3162/*
3173 * Free usrbuf (if available). 3163 * Free usrbuf (if available).
3174 */ 3164 */
3175static void 3165static void
3176audio_free_usrbuf(audio_track_t *track) 3166audio_free_usrbuf(audio_track_t *track)
3177{ 3167{
3178 vaddr_t vstart; 3168 vaddr_t vstart;
3179 vsize_t vsize; 3169 vsize_t vsize;
3180 3170
3181 vstart = (vaddr_t)track->usrbuf.mem; 3171 vstart = (vaddr_t)track->usrbuf.mem;
3182 vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE); 3172 vsize = roundup2(MAX(track->usrbuf.capacity, PAGE_SIZE), PAGE_SIZE);
3183 if (track->usrbuf.mem != NULL) { 3173 if (track->usrbuf.mem != NULL) {
3184 /* 3174 /*
3185 * Unmap the kernel mapping. uvm_unmap releases the 3175 * Unmap the kernel mapping. uvm_unmap releases the
3186 * reference to the uvm object, and this should be the 3176 * reference to the uvm object, and this should be the
3187 * last virtual mapping of the uvm object, so no need 3177 * last virtual mapping of the uvm object, so no need
3188 * to explicitly release (`detach') the object. 3178 * to explicitly release (`detach') the object.
3189 */ 3179 */
3190 uvm_unmap(kernel_map, vstart, vstart + vsize); 3180 uvm_unmap(kernel_map, vstart, vstart + vsize);
3191 3181
3192 track->uobj = NULL; 3182 track->uobj = NULL;
3193 track->usrbuf.mem = NULL; 3183 track->usrbuf.mem = NULL;
3194 track->usrbuf.capacity = 0; 3184 track->usrbuf.capacity = 0;
3195 } 3185 }
3196} 3186}
3197 3187
3198/* 3188/*
3199 * This filter changes the volume for each channel. 3189 * This filter changes the volume for each channel.
3200 * arg->context points track->ch_volume[]. 3190 * arg->context points track->ch_volume[].
3201 */ 3191 */
3202static void 3192static void
3203audio_track_chvol(audio_filter_arg_t *arg) 3193audio_track_chvol(audio_filter_arg_t *arg)
3204{ 3194{
3205 int16_t *ch_volume; 3195 int16_t *ch_volume;
3206 const aint_t *s; 3196 const aint_t *s;
3207 aint_t *d; 3197 aint_t *d;
3208 u_int i; 3198 u_int i;
3209 u_int ch; 3199 u_int ch;
3210 u_int channels; 3200 u_int channels;
3211 3201
3212 DIAGNOSTIC_filter_arg(arg); 3202 DIAGNOSTIC_filter_arg(arg);
3213 KASSERT(arg->srcfmt->channels == arg->dstfmt->channels); 3203 KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
3214 KASSERT(arg->context != NULL); 3204 KASSERT(arg->context != NULL);
3215 KASSERT(arg->srcfmt->channels <= AUDIO_MAX_CHANNELS); 3205 KASSERT(arg->srcfmt->channels <= AUDIO_MAX_CHANNELS);
3216 3206
3217 s = arg->src; 3207 s = arg->src;
3218 d = arg->dst; 3208 d = arg->dst;
3219 ch_volume = arg->context; 3209 ch_volume = arg->context;
3220 3210
3221 channels = arg->srcfmt->channels; 3211 channels = arg->srcfmt->channels;
3222 for (i = 0; i < arg->count; i++) { 3212 for (i = 0; i < arg->count; i++) {
3223 for (ch = 0; ch < channels; ch++) { 3213 for (ch = 0; ch < channels; ch++) {
3224 aint2_t val; 3214 aint2_t val;
3225 val = *s++; 3215 val = *s++;
3226 val = AUDIO_SCALEDOWN(val * ch_volume[ch], 8); 3216 val = AUDIO_SCALEDOWN(val * ch_volume[ch], 8);
3227 *d++ = (aint_t)val; 3217 *d++ = (aint_t)val;
3228 } 3218 }
3229 } 3219 }
3230} 3220}
3231 3221
3232/* 3222/*
3233 * This filter performs conversion from stereo (or more channels) to mono. 3223 * This filter performs conversion from stereo (or more channels) to mono.
3234 */ 3224 */
3235static void 3225static void
3236audio_track_chmix_mixLR(audio_filter_arg_t *arg) 3226audio_track_chmix_mixLR(audio_filter_arg_t *arg)
3237{ 3227{
3238 const aint_t *s; 3228 const aint_t *s;
3239 aint_t *d; 3229 aint_t *d;
3240 u_int i; 3230 u_int i;
3241 3231
3242 DIAGNOSTIC_filter_arg(arg); 3232 DIAGNOSTIC_filter_arg(arg);
3243 3233
3244 s = arg->src; 3234 s = arg->src;
3245 d = arg->dst; 3235 d = arg->dst;
3246 3236
3247 for (i = 0; i < arg->count; i++) { 3237 for (i = 0; i < arg->count; i++) {
3248 *d++ = AUDIO_SCALEDOWN(s[0], 1) + AUDIO_SCALEDOWN(s[1], 1); 3238 *d++ = AUDIO_SCALEDOWN(s[0], 1) + AUDIO_SCALEDOWN(s[1], 1);
3249 s += arg->srcfmt->channels; 3239 s += arg->srcfmt->channels;
3250 } 3240 }
3251} 3241}
3252 3242
3253/* 3243/*
3254 * This filter performs conversion from mono to stereo (or more channels). 3244 * This filter performs conversion from mono to stereo (or more channels).
3255 */ 3245 */
3256static void 3246static void
3257audio_track_chmix_dupLR(audio_filter_arg_t *arg) 3247audio_track_chmix_dupLR(audio_filter_arg_t *arg)
3258{ 3248{
3259 const aint_t *s; 3249 const aint_t *s;
3260 aint_t *d; 3250 aint_t *d;
3261 u_int i; 3251 u_int i;
3262 u_int ch; 3252 u_int ch;
3263 u_int dstchannels; 3253 u_int dstchannels;
3264 3254
3265 DIAGNOSTIC_filter_arg(arg); 3255 DIAGNOSTIC_filter_arg(arg);
3266 3256
3267 s = arg->src; 3257 s = arg->src;
3268 d = arg->dst; 3258 d = arg->dst;
3269 dstchannels = arg->dstfmt->channels; 3259 dstchannels = arg->dstfmt->channels;
3270 3260
3271 for (i = 0; i < arg->count; i++) { 3261 for (i = 0; i < arg->count; i++) {
3272 d[0] = s[0]; 3262 d[0] = s[0];
3273 d[1] = s[0]; 3263 d[1] = s[0];
3274 s++; 3264 s++;
3275 d += dstchannels; 3265 d += dstchannels;
3276 } 3266 }
3277 if (dstchannels > 2) { 3267 if (dstchannels > 2) {
3278 d = arg->dst; 3268 d = arg->dst;
3279 for (i = 0; i < arg->count; i++) { 3269 for (i = 0; i < arg->count; i++) {
3280 for (ch = 2; ch < dstchannels; ch++) { 3270 for (ch = 2; ch < dstchannels; ch++) {
3281 d[ch] = 0; 3271 d[ch] = 0;
3282 } 3272 }
3283 d += dstchannels; 3273 d += dstchannels;
3284 } 3274 }
3285 } 3275 }
3286} 3276}
3287 3277
3288/* 3278/*
3289 * This filter shrinks M channels into N channels. 3279 * This filter shrinks M channels into N channels.
3290 * Extra channels are discarded. 3280 * Extra channels are discarded.
3291 */ 3281 */
3292static void 3282static void
3293audio_track_chmix_shrink(audio_filter_arg_t *arg) 3283audio_track_chmix_shrink(audio_filter_arg_t *arg)
3294{ 3284{
3295 const aint_t *s; 3285 const aint_t *s;
3296 aint_t *d; 3286 aint_t *d;
3297 u_int i; 3287 u_int i;
3298 u_int ch; 3288 u_int ch;
3299 3289
3300 DIAGNOSTIC_filter_arg(arg); 3290 DIAGNOSTIC_filter_arg(arg);
3301 3291
3302 s = arg->src; 3292 s = arg->src;
3303 d = arg->dst; 3293 d = arg->dst;
3304 3294
3305 for (i = 0; i < arg->count; i++) { 3295 for (i = 0; i < arg->count; i++) {
3306 for (ch = 0; ch < arg->dstfmt->channels; ch++) { 3296 for (ch = 0; ch < arg->dstfmt->channels; ch++) {
3307 *d++ = s[ch]; 3297 *d++ = s[ch];
3308 } 3298 }
3309 s += arg->srcfmt->channels; 3299 s += arg->srcfmt->channels;
3310 } 3300 }
3311} 3301}
3312 3302
3313/* 3303/*
3314 * This filter expands M channels into N channels. 3304 * This filter expands M channels into N channels.
3315 * Silence is inserted for missing channels. 3305 * Silence is inserted for missing channels.
3316 */ 3306 */
3317static void 3307static void
3318audio_track_chmix_expand(audio_filter_arg_t *arg) 3308audio_track_chmix_expand(audio_filter_arg_t *arg)
3319{ 3309{
3320 const aint_t *s; 3310 const aint_t *s;
3321 aint_t *d; 3311 aint_t *d;
3322 u_int i; 3312 u_int i;
3323 u_int ch; 3313 u_int ch;
3324 u_int srcchannels; 3314 u_int srcchannels;
3325 u_int dstchannels; 3315 u_int dstchannels;
3326 3316
3327 DIAGNOSTIC_filter_arg(arg); 3317 DIAGNOSTIC_filter_arg(arg);
3328 3318
3329 s = arg->src; 3319 s = arg->src;
3330 d = arg->dst; 3320 d = arg->dst;
3331 3321
3332 srcchannels = arg->srcfmt->channels; 3322 srcchannels = arg->srcfmt->channels;
3333 dstchannels = arg->dstfmt->channels; 3323 dstchannels = arg->dstfmt->channels;
3334 for (i = 0; i < arg->count; i++) { 3324 for (i = 0; i < arg->count; i++) {
3335 for (ch = 0; ch < srcchannels; ch++) { 3325 for (ch = 0; ch < srcchannels; ch++) {
3336 *d++ = *s++; 3326 *d++ = *s++;
3337 } 3327 }
3338 for (; ch < dstchannels; ch++) { 3328 for (; ch < dstchannels; ch++) {
3339 *d++ = 0; 3329 *d++ = 0;
3340 } 3330 }
3341 } 3331 }
3342} 3332}
3343 3333
3344/* 3334/*
3345 * This filter performs frequency conversion (up sampling). 3335 * This filter performs frequency conversion (up sampling).
3346 * It uses linear interpolation. 3336 * It uses linear interpolation.
3347 */ 3337 */
3348static void 3338static void
3349audio_track_freq_up(audio_filter_arg_t *arg) 3339audio_track_freq_up(audio_filter_arg_t *arg)
3350{ 3340{
3351 audio_track_t *track; 3341 audio_track_t *track;
3352 audio_ring_t *src; 3342 audio_ring_t *src;
3353 audio_ring_t *dst; 3343 audio_ring_t *dst;
3354 const aint_t *s; 3344 const aint_t *s;
3355 aint_t *d; 3345 aint_t *d;
3356 aint_t prev[AUDIO_MAX_CHANNELS]; 3346 aint_t prev[AUDIO_MAX_CHANNELS];
3357 aint_t curr[AUDIO_MAX_CHANNELS]; 3347 aint_t curr[AUDIO_MAX_CHANNELS];
3358 aint_t grad[AUDIO_MAX_CHANNELS]; 3348 aint_t grad[AUDIO_MAX_CHANNELS];
3359 u_int i; 3349 u_int i;
3360 u_int t; 3350 u_int t;
3361 u_int step; 3351 u_int step;
3362 u_int channels; 3352 u_int channels;
3363 u_int ch; 3353 u_int ch;
3364 int srcused; 3354 int srcused;
3365 3355
3366 track = arg->context; 3356 track = arg->context;
3367 KASSERT(track); 3357 KASSERT(track);
3368 src = &track->freq.srcbuf; 3358 src = &track->freq.srcbuf;
3369 dst = track->freq.dst; 3359 dst = track->freq.dst;
3370 DIAGNOSTIC_ring(dst); 3360 DIAGNOSTIC_ring(dst);
3371 DIAGNOSTIC_ring(src); 3361 DIAGNOSTIC_ring(src);
3372 KASSERT(src->used > 0); 3362 KASSERT(src->used > 0);
3373 KASSERT(src->fmt.channels == dst->fmt.channels); 3363 KASSERT(src->fmt.channels == dst->fmt.channels);
3374 KASSERT(src->head % track->mixer->frames_per_block == 0); 3364 KASSERT(src->head % track->mixer->frames_per_block == 0);
3375 3365
3376 s = arg->src; 3366 s = arg->src;
3377 d = arg->dst; 3367 d = arg->dst;
3378 3368
3379 /* 3369 /*
3380 * In order to faciliate interpolation for each block, slide (delay) 3370 * In order to faciliate interpolation for each block, slide (delay)
3381 * input by one sample. As a result, strictly speaking, the output 3371 * input by one sample. As a result, strictly speaking, the output
3382 * phase is delayed by 1/dstfreq. However, I believe there is no 3372 * phase is delayed by 1/dstfreq. However, I believe there is no
3383 * observable impact. 3373 * observable impact.
3384 * 3374 *
3385 * Example) 3375 * Example)
3386 * srcfreq:dstfreq = 1:3 3376 * srcfreq:dstfreq = 1:3
3387 * 3377 *
3388 * A - - 3378 * A - -
3389 * | 3379 * |
3390 * | 3380 * |
3391 * | B - - 3381 * | B - -
3392 * +-----+-----> input timeframe 3382 * +-----+-----> input timeframe
3393 * 0 1 3383 * 0 1
3394 * 3384 *
3395 * 0 1 3385 * 0 1
3396 * +-----+-----> input timeframe 3386 * +-----+-----> input timeframe
3397 * | A 3387 * | A
3398 * | x x 3388 * | x x
3399 * | x x 3389 * | x x
3400 * x (B) 3390 * x (B)
3401 * +-+-+-+-+-+-> output timeframe 3391 * +-+-+-+-+-+-> output timeframe
3402 * 0 1 2 3 4 5 3392 * 0 1 2 3 4 5
3403 */ 3393 */
3404 3394
3405 /* Last samples in previous block */ 3395 /* Last samples in previous block */
3406 channels = src->fmt.channels; 3396 channels = src->fmt.channels;
3407 for (ch = 0; ch < channels; ch++) { 3397 for (ch = 0; ch < channels; ch++) {
3408 prev[ch] = track->freq_prev[ch]; 3398 prev[ch] = track->freq_prev[ch];
3409 curr[ch] = track->freq_curr[ch]; 3399 curr[ch] = track->freq_curr[ch];
3410 grad[ch] = curr[ch] - prev[ch]; 3400 grad[ch] = curr[ch] - prev[ch];
3411 } 3401 }
3412 3402
3413 step = track->freq_step; 3403 step = track->freq_step;
3414 t = track->freq_current; 3404 t = track->freq_current;
3415//#define FREQ_DEBUG 3405//#define FREQ_DEBUG
3416#if defined(FREQ_DEBUG) 3406#if defined(FREQ_DEBUG)
3417#define PRINTF(fmt...) printf(fmt) 3407#define PRINTF(fmt...) printf(fmt)
3418#else 3408#else
3419#define PRINTF(fmt...) do { } while (0) 3409#define PRINTF(fmt...) do { } while (0)
3420#endif 3410#endif
3421 srcused = src->used; 3411 srcused = src->used;
3422 PRINTF("upstart step=%d leap=%d", step, track->freq_leap); 3412 PRINTF("upstart step=%d leap=%d", step, track->freq_leap);
3423 PRINTF(" srcused=%d arg->count=%u", src->used, arg->count); 3413 PRINTF(" srcused=%d arg->count=%u", src->used, arg->count);
3424 PRINTF(" prev=%d curr=%d grad=%d", prev[0], curr[0], grad[0]); 3414 PRINTF(" prev=%d curr=%d grad=%d", prev[0], curr[0], grad[0]);
3425 PRINTF(" t=%d\n", t); 3415 PRINTF(" t=%d\n", t);
3426 3416
3427 for (i = 0; i < arg->count; i++) { 3417 for (i = 0; i < arg->count; i++) {
3428 PRINTF("i=%d t=%5d", i, t); 3418 PRINTF("i=%d t=%5d", i, t);
3429 if (t >= 65536) { 3419 if (t >= 65536) {
3430 for (ch = 0; ch < channels; ch++) { 3420 for (ch = 0; ch < channels; ch++) {
3431 prev[ch] = curr[ch]; 3421 prev[ch] = curr[ch];
3432 curr[ch] = *s++; 3422 curr[ch] = *s++;
3433 grad[ch] = curr[ch] - prev[ch]; 3423 grad[ch] = curr[ch] - prev[ch];
3434 } 3424 }
3435 PRINTF(" prev=%d s[%d]=%d", 3425 PRINTF(" prev=%d s[%d]=%d",
3436 prev[0], src->used - srcused, curr[0]); 3426 prev[0], src->used - srcused, curr[0]);
3437 3427
3438 /* Update */ 3428 /* Update */
3439 t -= 65536; 3429 t -= 65536;
3440 srcused--; 3430 srcused--;
3441 if (srcused < 0) { 3431 if (srcused < 0) {
3442 PRINTF(" break\n"); 3432 PRINTF(" break\n");
3443 break; 3433 break;
3444 } 3434 }
3445 } 3435 }
3446 3436
3447 for (ch = 0; ch < channels; ch++) { 3437 for (ch = 0; ch < channels; ch++) {
3448 *d++ = prev[ch] + (aint2_t)grad[ch] * t / 65536; 3438 *d++ = prev[ch] + (aint2_t)grad[ch] * t / 65536;
3449#if defined(FREQ_DEBUG) 3439#if defined(FREQ_DEBUG)
3450 if (ch == 0) 3440 if (ch == 0)
3451 printf(" t=%5d *d=%d", t, d[-1]); 3441 printf(" t=%5d *d=%d", t, d[-1]);
3452#endif 3442#endif
3453 } 3443 }
3454 t += step; 3444 t += step;
3455 3445
3456 PRINTF("\n"); 3446 PRINTF("\n");
3457 } 3447 }
3458 PRINTF("end prev=%d curr=%d\n", prev[0], curr[0]); 3448 PRINTF("end prev=%d curr=%d\n", prev[0], curr[0]);
3459 3449
3460 auring_take(src, src->used); 3450 auring_take(src, src->used);
3461 auring_push(dst, i); 3451 auring_push(dst, i);
3462 3452
3463 /* Adjust */ 3453 /* Adjust */
3464 t += track->freq_leap; 3454 t += track->freq_leap;
3465 3455
3466 track->freq_current = t; 3456 track->freq_current = t;
3467 for (ch = 0; ch < channels; ch++) { 3457 for (ch = 0; ch < channels; ch++) {
3468 track->freq_prev[ch] = prev[ch]; 3458 track->freq_prev[ch] = prev[ch];
3469 track->freq_curr[ch] = curr[ch]; 3459 track->freq_curr[ch] = curr[ch];
3470 } 3460 }
3471} 3461}
3472 3462
3473/* 3463/*
3474 * This filter performs frequency conversion (down sampling). 3464 * This filter performs frequency conversion (down sampling).
3475 * It uses simple thinning. 3465 * It uses simple thinning.
3476 */ 3466 */
3477static void 3467static void
3478audio_track_freq_down(audio_filter_arg_t *arg) 3468audio_track_freq_down(audio_filter_arg_t *arg)
3479{ 3469{
3480 audio_track_t *track; 3470 audio_track_t *track;
3481 audio_ring_t *src; 3471 audio_ring_t *src;
3482 audio_ring_t *dst; 3472 audio_ring_t *dst;
3483 const aint_t *s0; 3473 const aint_t *s0;
3484 aint_t *d; 3474 aint_t *d;
3485 u_int i; 3475 u_int i;
3486 u_int t; 3476 u_int t;
3487 u_int step; 3477 u_int step;
3488 u_int ch; 3478 u_int ch;
3489 u_int channels; 3479 u_int channels;
3490 3480
3491 track = arg->context; 3481 track = arg->context;
3492 KASSERT(track); 3482 KASSERT(track);
3493 src = &track->freq.srcbuf; 3483 src = &track->freq.srcbuf;
3494 dst = track->freq.dst; 3484 dst = track->freq.dst;
3495 3485
3496 DIAGNOSTIC_ring(dst); 3486 DIAGNOSTIC_ring(dst);
3497 DIAGNOSTIC_ring(src); 3487 DIAGNOSTIC_ring(src);
3498 KASSERT(src->used > 0); 3488 KASSERT(src->used > 0);
3499 KASSERT(src->fmt.channels == dst->fmt.channels); 3489 KASSERT(src->fmt.channels == dst->fmt.channels);
3500 KASSERTMSG(src->head % track->mixer->frames_per_block == 0, 3490 KASSERTMSG(src->head % track->mixer->frames_per_block == 0,
3501 "src->head=%d fpb=%d", 3491 "src->head=%d fpb=%d",
3502 src->head, track->mixer->frames_per_block); 3492 src->head, track->mixer->frames_per_block);
3503 3493
3504 s0 = arg->src; 3494 s0 = arg->src;
3505 d = arg->dst; 3495 d = arg->dst;
3506 t = track->freq_current; 3496 t = track->freq_current;
3507 step = track->freq_step; 3497 step = track->freq_step;
3508 channels = dst->fmt.channels; 3498 channels = dst->fmt.channels;
3509 PRINTF("downstart step=%d leap=%d", step, track->freq_leap); 3499 PRINTF("downstart step=%d leap=%d", step, track->freq_leap);
3510 PRINTF(" srcused=%d arg->count=%u", src->used, arg->count); 3500 PRINTF(" srcused=%d arg->count=%u", src->used, arg->count);
3511 PRINTF(" t=%d\n", t); 3501 PRINTF(" t=%d\n", t);
3512 3502
3513 for (i = 0; i < arg->count && t / 65536 < src->used; i++) { 3503 for (i = 0; i < arg->count && t / 65536 < src->used; i++) {
3514 const aint_t *s; 3504 const aint_t *s;
3515 PRINTF("i=%4d t=%10d", i, t); 3505 PRINTF("i=%4d t=%10d", i, t);
3516 s = s0 + (t / 65536) * channels; 3506 s = s0 + (t / 65536) * channels;
3517 PRINTF(" s=%5ld", (s - s0) / channels); 3507 PRINTF(" s=%5ld", (s - s0) / channels);
3518 for (ch = 0; ch < channels; ch++) { 3508 for (ch = 0; ch < channels; ch++) {
3519 if (ch == 0) PRINTF(" *s=%d", s[ch]); 3509 if (ch == 0) PRINTF(" *s=%d", s[ch]);
3520 *d++ = s[ch]; 3510 *d++ = s[ch];
3521 } 3511 }
3522 PRINTF("\n"); 3512 PRINTF("\n");
3523 t += step; 3513 t += step;
3524 } 3514 }
3525 t += track->freq_leap; 3515 t += track->freq_leap;
3526 PRINTF("end t=%d\n", t); 3516 PRINTF("end t=%d\n", t);
3527 auring_take(src, src->used); 3517 auring_take(src, src->used);
3528 auring_push(dst, i); 3518 auring_push(dst, i);
3529 track->freq_current = t % 65536; 3519 track->freq_current = t % 65536;
3530} 3520}
3531 3521
3532/* 3522/*
3533 * Creates track and returns it. 3523 * Creates track and returns it.
3534 */ 3524 */
3535audio_track_t * 3525audio_track_t *
3536audio_track_create(struct audio_softc *sc, audio_trackmixer_t *mixer) 3526audio_track_create(struct audio_softc *sc, audio_trackmixer_t *mixer)
3537{ 3527{
3538 audio_track_t *track; 3528 audio_track_t *track;
3539 static int newid = 0; 3529 static int newid = 0;
3540 3530
3541 track = kmem_zalloc(sizeof(*track), KM_SLEEP); 3531 track = kmem_zalloc(sizeof(*track), KM_SLEEP);
3542 3532
3543 track->id = newid++; 3533 track->id = newid++;
3544 track->mixer = mixer; 3534 track->mixer = mixer;
3545 track->mode = mixer->mode; 3535 track->mode = mixer->mode;
3546 3536
3547 /* Do TRACE after id is assigned. */ 3537 /* Do TRACE after id is assigned. */
3548 TRACET(3, track, "for %s", 3538 TRACET(3, track, "for %s",
3549 mixer->mode == AUMODE_PLAY ? "playback" : "recording"); 3539 mixer->mode == AUMODE_PLAY ? "playback" : "recording");
3550 3540
3551#if defined(AUDIO_SUPPORT_TRACK_VOLUME) 3541#if defined(AUDIO_SUPPORT_TRACK_VOLUME)
3552 track->volume = 256; 3542 track->volume = 256;
3553#endif 3543#endif
3554 for (int i = 0; i < AUDIO_MAX_CHANNELS; i++) { 3544 for (int i = 0; i < AUDIO_MAX_CHANNELS; i++) {
3555 track->ch_volume[i] = 256; 3545 track->ch_volume[i] = 256;
3556 } 3546 }
3557 3547
3558 return track; 3548 return track;
3559} 3549}
3560 3550
3561/* 3551/*
3562 * Release all resources of the track and track itself. 3552 * Release all resources of the track and track itself.
3563 * track must not be NULL. Don't specify the track within the file 3553 * track must not be NULL. Don't specify the track within the file
3564 * structure linked from sc->sc_files. 3554 * structure linked from sc->sc_files.
3565 */ 3555 */
3566static void 3556static void
3567audio_track_destroy(audio_track_t *track) 3557audio_track_destroy(audio_track_t *track)
3568{ 3558{
3569 3559
3570 KASSERT(track); 3560 KASSERT(track);
3571 3561
3572 audio_free_usrbuf(track); 3562 audio_free_usrbuf(track);
3573 audio_free(track->codec.srcbuf.mem); 3563 audio_free(track->codec.srcbuf.mem);
3574 audio_free(track->chvol.srcbuf.mem); 3564 audio_free(track->chvol.srcbuf.mem);
3575 audio_free(track->chmix.srcbuf.mem); 3565 audio_free(track->chmix.srcbuf.mem);
3576 audio_free(track->freq.srcbuf.mem); 3566 audio_free(track->freq.srcbuf.mem);
3577 audio_free(track->outbuf.mem); 3567 audio_free(track->outbuf.mem);
3578 3568
3579 kmem_free(track, sizeof(*track)); 3569 kmem_free(track, sizeof(*track));
3580} 3570}
3581 3571
3582/* 3572/*
3583 * It returns encoding conversion filter according to src and dst format. 3573 * It returns encoding conversion filter according to src and dst format.
3584 * If it is not a convertible pair, it returns NULL. Either src or dst 3574 * If it is not a convertible pair, it returns NULL. Either src or dst
3585 * must be internal format. 3575 * must be internal format.
3586 */ 3576 */
3587static audio_filter_t 3577static audio_filter_t
3588audio_track_get_codec(audio_track_t *track, const audio_format2_t *src, 3578audio_track_get_codec(audio_track_t *track, const audio_format2_t *src,
3589 const audio_format2_t *dst) 3579 const audio_format2_t *dst)
3590{ 3580{
3591 3581
3592 if (audio_format2_is_internal(src)) { 3582 if (audio_format2_is_internal(src)) {
3593 if (dst->encoding == AUDIO_ENCODING_ULAW) { 3583 if (dst->encoding == AUDIO_ENCODING_ULAW) {
3594 return audio_internal_to_mulaw; 3584 return audio_internal_to_mulaw;
3595 } else if (dst->encoding == AUDIO_ENCODING_ALAW) { 3585 } else if (dst->encoding == AUDIO_ENCODING_ALAW) {
3596 return audio_internal_to_alaw; 3586 return audio_internal_to_alaw;
3597 } else if (audio_format2_is_linear(dst)) { 3587 } else if (audio_format2_is_linear(dst)) {
3598 switch (dst->stride) { 3588 switch (dst->stride) {
3599 case 8: 3589 case 8:
3600 return audio_internal_to_linear8; 3590 return audio_internal_to_linear8;
3601 case 16: 3591 case 16:
3602 return audio_internal_to_linear16; 3592 return audio_internal_to_linear16;
3603#if defined(AUDIO_SUPPORT_LINEAR24) 3593#if defined(AUDIO_SUPPORT_LINEAR24)
3604 case 24: 3594 case 24:
3605 return audio_internal_to_linear24; 3595 return audio_internal_to_linear24;
3606#endif 3596#endif
3607 case 32: 3597 case 32:
3608 return audio_internal_to_linear32; 3598 return audio_internal_to_linear32;
3609 default: 3599 default:
3610 TRACET(1, track, "unsupported %s stride %d", 3600 TRACET(1, track, "unsupported %s stride %d",
3611 "dst", dst->stride); 3601 "dst", dst->stride);
3612 goto abort; 3602 goto abort;
3613 } 3603 }
3614 } 3604 }
3615 } else if (audio_format2_is_internal(dst)) { 3605 } else if (audio_format2_is_internal(dst)) {
3616 if (src->encoding == AUDIO_ENCODING_ULAW) { 3606 if (src->encoding == AUDIO_ENCODING_ULAW) {
3617 return audio_mulaw_to_internal; 3607 return audio_mulaw_to_internal;
3618 } else if (src->encoding == AUDIO_ENCODING_ALAW) { 3608 } else if (src->encoding == AUDIO_ENCODING_ALAW) {
3619 return audio_alaw_to_internal; 3609 return audio_alaw_to_internal;
3620 } else if (audio_format2_is_linear(src)) { 3610 } else if (audio_format2_is_linear(src)) {
3621 switch (src->stride) { 3611 switch (src->stride) {
3622 case 8: 3612 case 8:
3623 return audio_linear8_to_internal; 3613 return audio_linear8_to_internal;
3624 case 16: 3614 case 16:
3625 return audio_linear16_to_internal; 3615 return audio_linear16_to_internal;
3626#if defined(AUDIO_SUPPORT_LINEAR24) 3616#if defined(AUDIO_SUPPORT_LINEAR24)
3627 case 24: 3617 case 24:
3628 return audio_linear24_to_internal; 3618 return audio_linear24_to_internal;
3629#endif 3619#endif
3630 case 32: 3620 case 32:
3631 return audio_linear32_to_internal; 3621 return audio_linear32_to_internal;
3632 default: 3622 default:
3633 TRACET(1, track, "unsupported %s stride %d", 3623 TRACET(1, track, "unsupported %s stride %d",
3634 "src", src->stride); 3624 "src", src->stride);
3635 goto abort; 3625 goto abort;
3636 } 3626 }
3637 } 3627 }
3638 } 3628 }
3639 3629
3640 TRACET(1, track, "unsupported encoding"); 3630 TRACET(1, track, "unsupported encoding");
3641abort: 3631abort:
3642#if defined(AUDIO_DEBUG) 3632#if defined(AUDIO_DEBUG)
3643 if (audiodebug >= 2) { 3633 if (audiodebug >= 2) {
3644 char buf[100]; 3634 char buf[100];
3645 audio_format2_tostr(buf, sizeof(buf), src); 3635 audio_format2_tostr(buf, sizeof(buf), src);
3646 TRACET(2, track, "src %s", buf); 3636 TRACET(2, track, "src %s", buf);
3647 audio_format2_tostr(buf, sizeof(buf), dst); 3637 audio_format2_tostr(buf, sizeof(buf), dst);
3648 TRACET(2, track, "dst %s", buf); 3638 TRACET(2, track, "dst %s", buf);
3649 } 3639 }
3650#endif 3640#endif
3651 return NULL; 3641 return NULL;
3652} 3642}
3653 3643
3654/* 3644/*
3655 * Initialize the codec stage of this track as necessary. 3645 * Initialize the codec stage of this track as necessary.
3656 * If successful, it initializes the codec stage as necessary, stores updated 3646 * If successful, it initializes the codec stage as necessary, stores updated
3657 * last_dst in *last_dstp in any case, and returns 0. 3647 * last_dst in *last_dstp in any case, and returns 0.
3658 * Otherwise, it returns errno without modifying *last_dstp. 3648 * Otherwise, it returns errno without modifying *last_dstp.
3659 */ 3649 */
3660static int 3650static int
3661audio_track_init_codec(audio_track_t *track, audio_ring_t **last_dstp) 3651audio_track_init_codec(audio_track_t *track, audio_ring_t **last_dstp)
3662{ 3652{
3663 struct audio_softc *sc; 
3664 audio_ring_t *last_dst; 3653 audio_ring_t *last_dst;
3665 audio_ring_t *srcbuf; 3654 audio_ring_t *srcbuf;
3666 audio_format2_t *srcfmt; 3655 audio_format2_t *srcfmt;
3667 audio_format2_t *dstfmt; 3656 audio_format2_t *dstfmt;
3668 audio_filter_arg_t *arg; 3657 audio_filter_arg_t *arg;
3669 u_int len; 3658 u_int len;
3670 int error; 3659 int error;
3671 3660
3672 KASSERT(track); 3661 KASSERT(track);
3673 3662
3674 sc = track->mixer->sc; 
3675 last_dst = *last_dstp; 3663 last_dst = *last_dstp;
3676 dstfmt = &last_dst->fmt; 3664 dstfmt = &last_dst->fmt;
3677 srcfmt = &track->inputfmt; 3665 srcfmt = &track->inputfmt;
3678 srcbuf = &track->codec.srcbuf; 3666 srcbuf = &track->codec.srcbuf;
3679 error = 0; 3667 error = 0;
3680 3668
3681 if (srcfmt->encoding != dstfmt->encoding 3669 if (srcfmt->encoding != dstfmt->encoding
3682 || srcfmt->precision != dstfmt->precision 3670 || srcfmt->precision != dstfmt->precision
3683 || srcfmt->stride != dstfmt->stride) { 3671 || srcfmt->stride != dstfmt->stride) {
3684 track->codec.dst = last_dst; 3672 track->codec.dst = last_dst;
3685 3673
3686 srcbuf->fmt = *dstfmt; 3674 srcbuf->fmt = *dstfmt;
3687 srcbuf->fmt.encoding = srcfmt->encoding; 3675 srcbuf->fmt.encoding = srcfmt->encoding;
3688 srcbuf->fmt.precision = srcfmt->precision; 3676 srcbuf->fmt.precision = srcfmt->precision;
3689 srcbuf->fmt.stride = srcfmt->stride; 3677 srcbuf->fmt.stride = srcfmt->stride;
3690 3678
3691 track->codec.filter = audio_track_get_codec(track, 3679 track->codec.filter = audio_track_get_codec(track,
3692 &srcbuf->fmt, dstfmt); 3680 &srcbuf->fmt, dstfmt);
3693 if (track->codec.filter == NULL) { 3681 if (track->codec.filter == NULL) {
3694 error = EINVAL; 3682 error = EINVAL;
3695 goto abort; 3683 goto abort;
3696 } 3684 }
3697 3685
3698 srcbuf->head = 0; 3686 srcbuf->head = 0;
3699 srcbuf->used = 0; 3687 srcbuf->used = 0;
3700 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3688 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3701 len = auring_bytelen(srcbuf); 3689 len = auring_bytelen(srcbuf);
3702 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3690 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3703 if (srcbuf->mem == NULL) { 
3704 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3705 __func__, len); 
3706 error = ENOMEM; 
3707 goto abort; 
3708 } 
3709 3691
3710 arg = &track->codec.arg; 3692 arg = &track->codec.arg;
3711 arg->srcfmt = &srcbuf->fmt; 3693 arg->srcfmt = &srcbuf->fmt;
3712 arg->dstfmt = dstfmt; 3694 arg->dstfmt = dstfmt;
3713 arg->context = NULL; 3695 arg->context = NULL;
3714 3696
3715 *last_dstp = srcbuf; 3697 *last_dstp = srcbuf;
3716 return 0; 3698 return 0;
3717 } 3699 }
3718 3700
3719abort: 3701abort:
3720 track->codec.filter = NULL; 3702 track->codec.filter = NULL;
3721 audio_free(srcbuf->mem); 3703 audio_free(srcbuf->mem);
3722 return error; 3704 return error;
3723} 3705}
3724 3706
3725/* 3707/*
3726 * Initialize the chvol stage of this track as necessary. 3708 * Initialize the chvol stage of this track as necessary.
3727 * If successful, it initializes the chvol stage as necessary, stores updated 3709 * If successful, it initializes the chvol stage as necessary, stores updated
3728 * last_dst in *last_dstp in any case, and returns 0. 3710 * last_dst in *last_dstp in any case, and returns 0.
3729 * Otherwise, it returns errno without modifying *last_dstp. 3711 * Otherwise, it returns errno without modifying *last_dstp.
3730 */ 3712 */
3731static int 3713static int
3732audio_track_init_chvol(audio_track_t *track, audio_ring_t **last_dstp) 3714audio_track_init_chvol(audio_track_t *track, audio_ring_t **last_dstp)
3733{ 3715{
3734 struct audio_softc *sc; 
3735 audio_ring_t *last_dst; 3716 audio_ring_t *last_dst;
3736 audio_ring_t *srcbuf; 3717 audio_ring_t *srcbuf;
3737 audio_format2_t *srcfmt; 3718 audio_format2_t *srcfmt;
3738 audio_format2_t *dstfmt; 3719 audio_format2_t *dstfmt;
3739 audio_filter_arg_t *arg; 3720 audio_filter_arg_t *arg;
3740 u_int len; 3721 u_int len;
3741 int error; 3722 int error;
3742 3723
3743 KASSERT(track); 3724 KASSERT(track);
3744 3725
3745 sc = track->mixer->sc; 
3746 last_dst = *last_dstp; 3726 last_dst = *last_dstp;
3747 dstfmt = &last_dst->fmt; 3727 dstfmt = &last_dst->fmt;
3748 srcfmt = &track->inputfmt; 3728 srcfmt = &track->inputfmt;
3749 srcbuf = &track->chvol.srcbuf; 3729 srcbuf = &track->chvol.srcbuf;
3750 error = 0; 3730 error = 0;
3751 3731
3752 /* Check whether channel volume conversion is necessary. */ 3732 /* Check whether channel volume conversion is necessary. */
3753 bool use_chvol = false; 3733 bool use_chvol = false;
3754 for (int ch = 0; ch < srcfmt->channels; ch++) { 3734 for (int ch = 0; ch < srcfmt->channels; ch++) {
3755 if (track->ch_volume[ch] != 256) { 3735 if (track->ch_volume[ch] != 256) {
3756 use_chvol = true; 3736 use_chvol = true;
3757 break; 3737 break;
3758 } 3738 }
3759 } 3739 }
3760 3740
3761 if (use_chvol == true) { 3741 if (use_chvol == true) {
3762 track->chvol.dst = last_dst; 3742 track->chvol.dst = last_dst;
3763 track->chvol.filter = audio_track_chvol; 3743 track->chvol.filter = audio_track_chvol;
3764 3744
3765 srcbuf->fmt = *dstfmt; 3745 srcbuf->fmt = *dstfmt;
3766 /* no format conversion occurs */ 3746 /* no format conversion occurs */
3767 3747
3768 srcbuf->head = 0; 3748 srcbuf->head = 0;
3769 srcbuf->used = 0; 3749 srcbuf->used = 0;
3770 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3750 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3771 len = auring_bytelen(srcbuf); 3751 len = auring_bytelen(srcbuf);
3772 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3752 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3773 if (srcbuf->mem == NULL) { 
3774 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3775 __func__, len); 
3776 error = ENOMEM; 
3777 goto abort; 
3778 } 
3779 3753
3780 arg = &track->chvol.arg; 3754 arg = &track->chvol.arg;
3781 arg->srcfmt = &srcbuf->fmt; 3755 arg->srcfmt = &srcbuf->fmt;
3782 arg->dstfmt = dstfmt; 3756 arg->dstfmt = dstfmt;
3783 arg->context = track->ch_volume; 3757 arg->context = track->ch_volume;
3784 3758
3785 *last_dstp = srcbuf; 3759 *last_dstp = srcbuf;
3786 return 0; 3760 return 0;
3787 } 3761 }
3788 3762
3789abort: 
3790 track->chvol.filter = NULL; 3763 track->chvol.filter = NULL;
3791 audio_free(srcbuf->mem); 3764 audio_free(srcbuf->mem);
3792 return error; 3765 return error;
3793} 3766}
3794 3767
3795/* 3768/*
3796 * Initialize the chmix stage of this track as necessary. 3769 * Initialize the chmix stage of this track as necessary.
3797 * If successful, it initializes the chmix stage as necessary, stores updated 3770 * If successful, it initializes the chmix stage as necessary, stores updated
3798 * last_dst in *last_dstp in any case, and returns 0. 3771 * last_dst in *last_dstp in any case, and returns 0.
3799 * Otherwise, it returns errno without modifying *last_dstp. 3772 * Otherwise, it returns errno without modifying *last_dstp.
3800 */ 3773 */
3801static int 3774static int
3802audio_track_init_chmix(audio_track_t *track, audio_ring_t **last_dstp) 3775audio_track_init_chmix(audio_track_t *track, audio_ring_t **last_dstp)
3803{ 3776{
3804 struct audio_softc *sc; 
3805 audio_ring_t *last_dst; 3777 audio_ring_t *last_dst;
3806 audio_ring_t *srcbuf; 3778 audio_ring_t *srcbuf;
3807 audio_format2_t *srcfmt; 3779 audio_format2_t *srcfmt;
3808 audio_format2_t *dstfmt; 3780 audio_format2_t *dstfmt;
3809 audio_filter_arg_t *arg; 3781 audio_filter_arg_t *arg;
3810 u_int srcch; 3782 u_int srcch;
3811 u_int dstch; 3783 u_int dstch;
3812 u_int len; 3784 u_int len;
3813 int error; 3785 int error;
3814 3786
3815 KASSERT(track); 3787 KASSERT(track);
3816 3788
3817 sc = track->mixer->sc; 
3818 last_dst = *last_dstp; 3789 last_dst = *last_dstp;
3819 dstfmt = &last_dst->fmt; 3790 dstfmt = &last_dst->fmt;
3820 srcfmt = &track->inputfmt; 3791 srcfmt = &track->inputfmt;
3821 srcbuf = &track->chmix.srcbuf; 3792 srcbuf = &track->chmix.srcbuf;
3822 error = 0; 3793 error = 0;
3823 3794
3824 srcch = srcfmt->channels; 3795 srcch = srcfmt->channels;
3825 dstch = dstfmt->channels; 3796 dstch = dstfmt->channels;
3826 if (srcch != dstch) { 3797 if (srcch != dstch) {
3827 track->chmix.dst = last_dst; 3798 track->chmix.dst = last_dst;
3828 3799
3829 if (srcch >= 2 && dstch == 1) { 3800 if (srcch >= 2 && dstch == 1) {
3830 track->chmix.filter = audio_track_chmix_mixLR; 3801 track->chmix.filter = audio_track_chmix_mixLR;
3831 } else if (srcch == 1 && dstch >= 2) { 3802 } else if (srcch == 1 && dstch >= 2) {
3832 track->chmix.filter = audio_track_chmix_dupLR; 3803 track->chmix.filter = audio_track_chmix_dupLR;
3833 } else if (srcch > dstch) { 3804 } else if (srcch > dstch) {
3834 track->chmix.filter = audio_track_chmix_shrink; 3805 track->chmix.filter = audio_track_chmix_shrink;
3835 } else { 3806 } else {
3836 track->chmix.filter = audio_track_chmix_expand; 3807 track->chmix.filter = audio_track_chmix_expand;
3837 } 3808 }
3838 3809
3839 srcbuf->fmt = *dstfmt; 3810 srcbuf->fmt = *dstfmt;
3840 srcbuf->fmt.channels = srcch; 3811 srcbuf->fmt.channels = srcch;
3841 3812
3842 srcbuf->head = 0; 3813 srcbuf->head = 0;
3843 srcbuf->used = 0; 3814 srcbuf->used = 0;
3844 /* XXX The buffer size should be able to calculate. */ 3815 /* XXX The buffer size should be able to calculate. */
3845 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3816 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3846 len = auring_bytelen(srcbuf); 3817 len = auring_bytelen(srcbuf);
3847 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3818 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3848 if (srcbuf->mem == NULL) { 
3849 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3850 __func__, len); 
3851 error = ENOMEM; 
3852 goto abort; 
3853 } 
3854 3819
3855 arg = &track->chmix.arg; 3820 arg = &track->chmix.arg;
3856 arg->srcfmt = &srcbuf->fmt; 3821 arg->srcfmt = &srcbuf->fmt;
3857 arg->dstfmt = dstfmt; 3822 arg->dstfmt = dstfmt;
3858 arg->context = NULL; 3823 arg->context = NULL;
3859 3824
3860 *last_dstp = srcbuf; 3825 *last_dstp = srcbuf;
3861 return 0; 3826 return 0;
3862 } 3827 }
3863 3828
3864abort: 
3865 track->chmix.filter = NULL; 3829 track->chmix.filter = NULL;
3866 audio_free(srcbuf->mem); 3830 audio_free(srcbuf->mem);
3867 return error; 3831 return error;
3868} 3832}
3869 3833
3870/* 3834/*
3871 * Initialize the freq stage of this track as necessary. 3835 * Initialize the freq stage of this track as necessary.
3872 * If successful, it initializes the freq stage as necessary, stores updated 3836 * If successful, it initializes the freq stage as necessary, stores updated
3873 * last_dst in *last_dstp in any case, and returns 0. 3837 * last_dst in *last_dstp in any case, and returns 0.
3874 * Otherwise, it returns errno without modifying *last_dstp. 3838 * Otherwise, it returns errno without modifying *last_dstp.
3875 */ 3839 */
3876static int 3840static int
3877audio_track_init_freq(audio_track_t *track, audio_ring_t **last_dstp) 3841audio_track_init_freq(audio_track_t *track, audio_ring_t **last_dstp)
3878{ 3842{
3879 struct audio_softc *sc; 
3880 audio_ring_t *last_dst; 3843 audio_ring_t *last_dst;
3881 audio_ring_t *srcbuf; 3844 audio_ring_t *srcbuf;
3882 audio_format2_t *srcfmt; 3845 audio_format2_t *srcfmt;
3883 audio_format2_t *dstfmt; 3846 audio_format2_t *dstfmt;
3884 audio_filter_arg_t *arg; 3847 audio_filter_arg_t *arg;
3885 uint32_t srcfreq; 3848 uint32_t srcfreq;
3886 uint32_t dstfreq; 3849 uint32_t dstfreq;
3887 u_int dst_capacity; 3850 u_int dst_capacity;
3888 u_int mod; 3851 u_int mod;
3889 u_int len; 3852 u_int len;
3890 int error; 3853 int error;
3891 3854
3892 KASSERT(track); 3855 KASSERT(track);
3893 3856
3894 sc = track->mixer->sc; 
3895 last_dst = *last_dstp; 3857 last_dst = *last_dstp;
3896 dstfmt = &last_dst->fmt; 3858 dstfmt = &last_dst->fmt;
3897 srcfmt = &track->inputfmt; 3859 srcfmt = &track->inputfmt;
3898 srcbuf = &track->freq.srcbuf; 3860 srcbuf = &track->freq.srcbuf;
3899 error = 0; 3861 error = 0;
3900 3862
3901 srcfreq = srcfmt->sample_rate; 3863 srcfreq = srcfmt->sample_rate;
3902 dstfreq = dstfmt->sample_rate; 3864 dstfreq = dstfmt->sample_rate;
3903 if (srcfreq != dstfreq) { 3865 if (srcfreq != dstfreq) {
3904 track->freq.dst = last_dst; 3866 track->freq.dst = last_dst;
3905 3867
3906 memset(track->freq_prev, 0, sizeof(track->freq_prev)); 3868 memset(track->freq_prev, 0, sizeof(track->freq_prev));
3907 memset(track->freq_curr, 0, sizeof(track->freq_curr)); 3869 memset(track->freq_curr, 0, sizeof(track->freq_curr));
3908 3870
3909 /* freq_step is the ratio of src/dst when let dst 65536. */ 3871 /* freq_step is the ratio of src/dst when let dst 65536. */
3910 track->freq_step = (uint64_t)srcfreq * 65536 / dstfreq; 3872 track->freq_step = (uint64_t)srcfreq * 65536 / dstfreq;
3911 3873
3912 dst_capacity = frame_per_block(track->mixer, dstfmt); 3874 dst_capacity = frame_per_block(track->mixer, dstfmt);
3913 mod = (uint64_t)srcfreq * 65536 % dstfreq; 3875 mod = (uint64_t)srcfreq * 65536 % dstfreq;
3914 track->freq_leap = (mod * dst_capacity + dstfreq / 2) / dstfreq; 3876 track->freq_leap = (mod * dst_capacity + dstfreq / 2) / dstfreq;
3915 3877
3916 if (track->freq_step < 65536) { 3878 if (track->freq_step < 65536) {
3917 track->freq.filter = audio_track_freq_up; 3879 track->freq.filter = audio_track_freq_up;
3918 /* In order to carry at the first time. */ 3880 /* In order to carry at the first time. */
3919 track->freq_current = 65536; 3881 track->freq_current = 65536;
3920 } else { 3882 } else {
3921 track->freq.filter = audio_track_freq_down; 3883 track->freq.filter = audio_track_freq_down;
3922 track->freq_current = 0; 3884 track->freq_current = 0;
3923 } 3885 }
3924 3886
3925 srcbuf->fmt = *dstfmt; 3887 srcbuf->fmt = *dstfmt;
3926 srcbuf->fmt.sample_rate = srcfreq; 3888 srcbuf->fmt.sample_rate = srcfreq;
3927 3889
3928 srcbuf->head = 0; 3890 srcbuf->head = 0;
3929 srcbuf->used = 0; 3891 srcbuf->used = 0;
3930 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3892 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3931 len = auring_bytelen(srcbuf); 3893 len = auring_bytelen(srcbuf);
3932 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3894 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3933 if (srcbuf->mem == NULL) { 
3934 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3935 __func__, len); 
3936 error = ENOMEM; 
3937 goto abort; 
3938 } 
3939 3895
3940 arg = &track->freq.arg; 3896 arg = &track->freq.arg;
3941 arg->srcfmt = &srcbuf->fmt; 3897 arg->srcfmt = &srcbuf->fmt;
3942 arg->dstfmt = dstfmt;/*&last_dst->fmt;*/ 3898 arg->dstfmt = dstfmt;/*&last_dst->fmt;*/
3943 arg->context = track; 3899 arg->context = track;
3944 3900
3945 *last_dstp = srcbuf; 3901 *last_dstp = srcbuf;
3946 return 0; 3902 return 0;
3947 } 3903 }
3948 3904
3949abort: 
3950 track->freq.filter = NULL; 3905 track->freq.filter = NULL;
3951 audio_free(srcbuf->mem); 3906 audio_free(srcbuf->mem);
3952 return error; 3907 return error;
3953} 3908}
3954 3909
3955/* 3910/*
3956 * When playing back: (e.g. if codec and freq stage are valid) 3911 * When playing back: (e.g. if codec and freq stage are valid)
3957 * 3912 *
3958 * write 3913 * write
3959 * | uiomove 3914 * | uiomove
3960 * v 3915 * v
3961 * usrbuf [...............] byte ring buffer (mmap-able) 3916 * usrbuf [...............] byte ring buffer (mmap-able)
3962 * | memcpy 3917 * | memcpy
3963 * v 3918 * v
3964 * codec.srcbuf[....] 1 block (ring) buffer <-- stage input 3919 * codec.srcbuf[....] 1 block (ring) buffer <-- stage input
3965 * .dst ----+ 3920 * .dst ----+
3966 * | convert 3921 * | convert
3967 * v 3922 * v
3968 * freq.srcbuf [....] 1 block (ring) buffer 3923 * freq.srcbuf [....] 1 block (ring) buffer
3969 * .dst ----+ 3924 * .dst ----+
3970 * | convert 3925 * | convert
3971 * v 3926 * v
3972 * outbuf [...............] NBLKOUT blocks ring buffer 3927 * outbuf [...............] NBLKOUT blocks ring buffer
3973 * 3928 *
3974 * 3929 *
3975 * When recording: 3930 * When recording:
3976 * 3931 *
3977 * freq.srcbuf [...............] NBLKOUT blocks ring buffer <-- stage input 3932 * freq.srcbuf [...............] NBLKOUT blocks ring buffer <-- stage input
3978 * .dst ----+ 3933 * .dst ----+
3979 * | convert 3934 * | convert
3980 * v 3935 * v
3981 * codec.srcbuf[.....] 1 block (ring) buffer 3936 * codec.srcbuf[.....] 1 block (ring) buffer
3982 * .dst ----+ 3937 * .dst ----+
3983 * | convert 3938 * | convert
3984 * v 3939 * v
3985 * outbuf [.....] 1 block (ring) buffer 3940 * outbuf [.....] 1 block (ring) buffer
3986 * | memcpy 3941 * | memcpy
3987 * v 3942 * v
3988 * usrbuf [...............] byte ring buffer (mmap-able *) 3943 * usrbuf [...............] byte ring buffer (mmap-able *)
3989 * | uiomove 3944 * | uiomove
3990 * v 3945 * v
3991 * read 3946 * read
3992 * 3947 *
3993 * *: usrbuf for recording is also mmap-able due to symmetry with 3948 * *: usrbuf for recording is also mmap-able due to symmetry with
3994 * playback buffer, but for now mmap will never happen for recording. 3949 * playback buffer, but for now mmap will never happen for recording.
3995 */ 3950 */
3996 3951
3997/* 3952/*
3998 * Set the userland format of this track. 3953 * Set the userland format of this track.
3999 * usrfmt argument should be parameter verified with audio_check_params(). 3954 * usrfmt argument should be parameter verified with audio_check_params().
4000 * It will release and reallocate all internal conversion buffers. 3955 * It will release and reallocate all internal conversion buffers.
4001 * It returns 0 if successful. Otherwise it returns errno with clearing all 3956 * It returns 0 if successful. Otherwise it returns errno with clearing all
4002 * internal buffers. 3957 * internal buffers.
4003 * It must be called without sc_intr_lock since uvm_* routines require non 3958 * It must be called without sc_intr_lock since uvm_* routines require non
4004 * intr_lock state. 3959 * intr_lock state.
4005 * It must be called with track lock held since it may release and reallocate 3960 * It must be called with track lock held since it may release and reallocate
4006 * outbuf. 3961 * outbuf.
4007 */ 3962 */
4008static int 3963static int
4009audio_track_set_format(audio_track_t *track, audio_format2_t *usrfmt) 3964audio_track_set_format(audio_track_t *track, audio_format2_t *usrfmt)
4010{ 3965{
4011 struct audio_softc *sc; 3966 struct audio_softc *sc;
4012 u_int newbufsize; 3967 u_int newbufsize;
4013 u_int oldblksize; 3968 u_int oldblksize;
4014 u_int len; 3969 u_int len;
4015 int error; 3970 int error;
4016 3971
4017 KASSERT(track); 3972 KASSERT(track);
4018 sc = track->mixer->sc; 3973 sc = track->mixer->sc;
4019 3974
4020 /* usrbuf is the closest buffer to the userland. */ 3975 /* usrbuf is the closest buffer to the userland. */
4021 track->usrbuf.fmt = *usrfmt; 3976 track->usrbuf.fmt = *usrfmt;
4022 3977
4023 /* 3978 /*
4024 * For references, one block size (in 40msec) is: 3979 * For references, one block size (in 40msec) is:
4025 * 320 bytes = 204 blocks/64KB for mulaw/8kHz/1ch 3980 * 320 bytes = 204 blocks/64KB for mulaw/8kHz/1ch
4026 * 7680 bytes = 8 blocks/64KB for s16/48kHz/2ch 3981 * 7680 bytes = 8 blocks/64KB for s16/48kHz/2ch
4027 * 30720 bytes = 90 KB/3blocks for s16/48kHz/8ch 3982 * 30720 bytes = 90 KB/3blocks for s16/48kHz/8ch
4028 * 61440 bytes = 180 KB/3blocks for s16/96kHz/8ch 3983 * 61440 bytes = 180 KB/3blocks for s16/96kHz/8ch
4029 * 245760 bytes = 720 KB/3blocks for s32/192kHz/8ch 3984 * 245760 bytes = 720 KB/3blocks for s32/192kHz/8ch
4030 * 3985 *
4031 * For example, 3986 * For example,
4032 * 1) If usrbuf_blksize = 7056 (s16/44.1k/2ch) and PAGE_SIZE = 8192, 3987 * 1) If usrbuf_blksize = 7056 (s16/44.1k/2ch) and PAGE_SIZE = 8192,
4033 * newbufsize = rounddown(65536 / 7056) = 63504 3988 * newbufsize = rounddown(65536 / 7056) = 63504
4034 * newvsize = roundup2(63504, PAGE_SIZE) = 65536 3989 * newvsize = roundup2(63504, PAGE_SIZE) = 65536
4035 * Therefore it maps 8 * 8K pages and usrbuf->capacity = 63504. 3990 * Therefore it maps 8 * 8K pages and usrbuf->capacity = 63504.
4036 * 3991 *
4037 * 2) If usrbuf_blksize = 7680 (s16/48k/2ch) and PAGE_SIZE = 4096, 3992 * 2) If usrbuf_blksize = 7680 (s16/48k/2ch) and PAGE_SIZE = 4096,
4038 * newbufsize = rounddown(65536 / 7680) = 61440 3993 * newbufsize = rounddown(65536 / 7680) = 61440
4039 * newvsize = roundup2(61440, PAGE_SIZE) = 61440 (= 15 pages) 3994 * newvsize = roundup2(61440, PAGE_SIZE) = 61440 (= 15 pages)
4040 * Therefore it maps 15 * 4K pages and usrbuf->capacity = 61440. 3995 * Therefore it maps 15 * 4K pages and usrbuf->capacity = 61440.
4041 */ 3996 */
4042 oldblksize = track->usrbuf_blksize; 3997 oldblksize = track->usrbuf_blksize;
4043 track->usrbuf_blksize = frametobyte(&track->usrbuf.fmt, 3998 track->usrbuf_blksize = frametobyte(&track->usrbuf.fmt,
4044 frame_per_block(track->mixer, &track->usrbuf.fmt)); 3999 frame_per_block(track->mixer, &track->usrbuf.fmt));
4045 track->usrbuf.head = 0; 4000 track->usrbuf.head = 0;
4046 track->usrbuf.used = 0; 4001 track->usrbuf.used = 0;
4047 newbufsize = MAX(track->usrbuf_blksize * AUMINNOBLK, 65536); 4002 newbufsize = MAX(track->usrbuf_blksize * AUMINNOBLK, 65536);
4048 newbufsize = rounddown(newbufsize, track->usrbuf_blksize); 4003 newbufsize = rounddown(newbufsize, track->usrbuf_blksize);
4049 error = audio_realloc_usrbuf(track, newbufsize); 4004 error = audio_realloc_usrbuf(track, newbufsize);
4050 if (error) { 4005 if (error) {
4051 device_printf(sc->sc_dev, "malloc usrbuf(%d) failed\n", 4006 device_printf(sc->sc_dev, "malloc usrbuf(%d) failed\n",
4052 newbufsize); 4007 newbufsize);
4053 goto error; 4008 goto error;
4054 } 4009 }
4055 4010
4056 /* Recalc water mark. */ 4011 /* Recalc water mark. */
4057 if (track->usrbuf_blksize != oldblksize) { 4012 if (track->usrbuf_blksize != oldblksize) {
4058 if (audio_track_is_playback(track)) { 4013 if (audio_track_is_playback(track)) {
4059 /* Set high at 100%, low at 75%. */ 4014 /* Set high at 100%, low at 75%. */
4060 track->usrbuf_usedhigh = track->usrbuf.capacity; 4015 track->usrbuf_usedhigh = track->usrbuf.capacity;
4061 track->usrbuf_usedlow = track->usrbuf.capacity * 3 / 4; 4016 track->usrbuf_usedlow = track->usrbuf.capacity * 3 / 4;
4062 } else { 4017 } else {
4063 /* Set high at 100% minus 1block(?), low at 0% */ 4018 /* Set high at 100% minus 1block(?), low at 0% */
4064 track->usrbuf_usedhigh = track->usrbuf.capacity - 4019 track->usrbuf_usedhigh = track->usrbuf.capacity -
4065 track->usrbuf_blksize; 4020 track->usrbuf_blksize;
4066 track->usrbuf_usedlow = 0; 4021 track->usrbuf_usedlow = 0;
4067 } 4022 }
4068 } 4023 }
4069 4024
4070 /* Stage buffer */ 4025 /* Stage buffer */
4071 audio_ring_t *last_dst = &track->outbuf; 4026 audio_ring_t *last_dst = &track->outbuf;
4072 if (audio_track_is_playback(track)) { 4027 if (audio_track_is_playback(track)) {
4073 /* On playback, initialize from the mixer side in order. */ 4028 /* On playback, initialize from the mixer side in order. */
4074 track->inputfmt = *usrfmt; 4029 track->inputfmt = *usrfmt;
4075 track->outbuf.fmt = track->mixer->track_fmt; 4030 track->outbuf.fmt = track->mixer->track_fmt;
4076 4031
4077 if ((error = audio_track_init_freq(track, &last_dst)) != 0) 4032 if ((error = audio_track_init_freq(track, &last_dst)) != 0)
4078 goto error; 4033 goto error;
4079 if ((error = audio_track_init_chmix(track, &last_dst)) != 0) 4034 if ((error = audio_track_init_chmix(track, &last_dst)) != 0)
4080 goto error; 4035 goto error;
4081 if ((error = audio_track_init_chvol(track, &last_dst)) != 0) 4036 if ((error = audio_track_init_chvol(track, &last_dst)) != 0)
4082 goto error; 4037 goto error;
4083 if ((error = audio_track_init_codec(track, &last_dst)) != 0) 4038 if ((error = audio_track_init_codec(track, &last_dst)) != 0)
4084 goto error; 4039 goto error;
4085 } else { 4040 } else {
4086 /* On recording, initialize from userland side in order. */ 4041 /* On recording, initialize from userland side in order. */
4087 track->inputfmt = track->mixer->track_fmt; 4042 track->inputfmt = track->mixer->track_fmt;
4088 track->outbuf.fmt = *usrfmt; 4043 track->outbuf.fmt = *usrfmt;
4089 4044
4090 if ((error = audio_track_init_codec(track, &last_dst)) != 0) 4045 if ((error = audio_track_init_codec(track, &last_dst)) != 0)
4091 goto error; 4046 goto error;
4092 if ((error = audio_track_init_chvol(track, &last_dst)) != 0) 4047 if ((error = audio_track_init_chvol(track, &last_dst)) != 0)
4093 goto error; 4048 goto error;
4094 if ((error = audio_track_init_chmix(track, &last_dst)) != 0) 4049 if ((error = audio_track_init_chmix(track, &last_dst)) != 0)
4095 goto error; 4050 goto error;
4096 if ((error = audio_track_init_freq(track, &last_dst)) != 0) 4051 if ((error = audio_track_init_freq(track, &last_dst)) != 0)
4097 goto error; 4052 goto error;
4098 } 4053 }
4099#if 0 4054#if 0
4100 /* debug */ 4055 /* debug */
4101 if (track->freq.filter) { 4056 if (track->freq.filter) {
4102 audio_print_format2("freq src", &track->freq.srcbuf.fmt); 4057 audio_print_format2("freq src", &track->freq.srcbuf.fmt);
4103 audio_print_format2("freq dst", &track->freq.dst->fmt); 4058 audio_print_format2("freq dst", &track->freq.dst->fmt);
4104 } 4059 }
4105 if (track->chmix.filter) { 4060 if (track->chmix.filter) {
4106 audio_print_format2("chmix src", &track->chmix.srcbuf.fmt); 4061 audio_print_format2("chmix src", &track->chmix.srcbuf.fmt);
4107 audio_print_format2("chmix dst", &track->chmix.dst->fmt); 4062 audio_print_format2("chmix dst", &track->chmix.dst->fmt);
4108 } 4063 }
4109 if (track->chvol.filter) { 4064 if (track->chvol.filter) {
4110 audio_print_format2("chvol src", &track->chvol.srcbuf.fmt); 4065 audio_print_format2("chvol src", &track->chvol.srcbuf.fmt);
4111 audio_print_format2("chvol dst", &track->chvol.dst->fmt); 4066 audio_print_format2("chvol dst", &track->chvol.dst->fmt);
4112 } 4067 }
4113 if (track->codec.filter) { 4068 if (track->codec.filter) {
4114 audio_print_format2("codec src", &track->codec.srcbuf.fmt); 4069 audio_print_format2("codec src", &track->codec.srcbuf.fmt);
4115 audio_print_format2("codec dst", &track->codec.dst->fmt); 4070 audio_print_format2("codec dst", &track->codec.dst->fmt);
4116 } 4071 }
4117#endif 4072#endif
4118 4073
4119 /* Stage input buffer */ 4074 /* Stage input buffer */
4120 track->input = last_dst; 4075 track->input = last_dst;
4121 4076
4122 /* 4077 /*
4123 * On the recording track, make the first stage a ring buffer. 4078 * On the recording track, make the first stage a ring buffer.
4124 * XXX is there a better way? 4079 * XXX is there a better way?
4125 */ 4080 */
4126 if (audio_track_is_record(track)) { 4081 if (audio_track_is_record(track)) {
4127 track->input->capacity = NBLKOUT * 4082 track->input->capacity = NBLKOUT *
4128 frame_per_block(track->mixer, &track->input->fmt); 4083 frame_per_block(track->mixer, &track->input->fmt);
4129 len = auring_bytelen(track->input); 4084 len = auring_bytelen(track->input);
4130 track->input->mem = audio_realloc(track->input->mem, len); 4085 track->input->mem = audio_realloc(track->input->mem, len);
4131 if (track->input->mem == NULL) { 
4132 device_printf(sc->sc_dev, "malloc input(%d) failed\n", 
4133 len); 
4134 error = ENOMEM; 
4135 goto error; 
4136 } 
4137 } 4086 }
4138 4087
4139 /* 4088 /*
4140 * Output buffer. 4089 * Output buffer.
4141 * On the playback track, its capacity is NBLKOUT blocks. 4090 * On the playback track, its capacity is NBLKOUT blocks.
4142 * On the recording track, its capacity is 1 block. 4091 * On the recording track, its capacity is 1 block.
4143 */ 4092 */
4144 track->outbuf.head = 0; 4093 track->outbuf.head = 0;
4145 track->outbuf.used = 0; 4094 track->outbuf.used = 0;
4146 track->outbuf.capacity = frame_per_block(track->mixer, 4095 track->outbuf.capacity = frame_per_block(track->mixer,
4147 &track->outbuf.fmt); 4096 &track->outbuf.fmt);
4148 if (audio_track_is_playback(track)) 4097 if (audio_track_is_playback(track))
4149 track->outbuf.capacity *= NBLKOUT; 4098 track->outbuf.capacity *= NBLKOUT;
4150 len = auring_bytelen(&track->outbuf); 4099 len = auring_bytelen(&track->outbuf);
4151 track->outbuf.mem = audio_realloc(track->outbuf.mem, len); 4100 track->outbuf.mem = audio_realloc(track->outbuf.mem, len);
4152 if (track->outbuf.mem == NULL) { 4101 if (track->outbuf.mem == NULL) {
4153 device_printf(sc->sc_dev, "malloc outbuf(%d) failed\n", len); 4102 device_printf(sc->sc_dev, "malloc outbuf(%d) failed\n", len);
4154 error = ENOMEM; 4103 error = ENOMEM;
4155 goto error; 4104 goto error;
4156 } 4105 }
4157 4106
4158#if defined(AUDIO_DEBUG) 4107#if defined(AUDIO_DEBUG)
4159 if (audiodebug >= 3) { 4108 if (audiodebug >= 3) {
4160 struct audio_track_debugbuf m; 4109 struct audio_track_debugbuf m;
4161 4110
4162 memset(&m, 0, sizeof(m)); 4111 memset(&m, 0, sizeof(m));
4163 snprintf(m.outbuf, sizeof(m.outbuf), " out=%d", 4112 snprintf(m.outbuf, sizeof(m.outbuf), " out=%d",
4164 track->outbuf.capacity * frametobyte(&track->outbuf.fmt,1)); 4113 track->outbuf.capacity * frametobyte(&track->outbuf.fmt,1));
4165 if (track->freq.filter) 4114 if (track->freq.filter)
4166 snprintf(m.freq, sizeof(m.freq), " freq=%d", 4115 snprintf(m.freq, sizeof(m.freq), " freq=%d",
4167 track->freq.srcbuf.capacity * 4116 track->freq.srcbuf.capacity *
4168 frametobyte(&track->freq.srcbuf.fmt, 1)); 4117 frametobyte(&track->freq.srcbuf.fmt, 1));
4169 if (track->chmix.filter) 4118 if (track->chmix.filter)
4170 snprintf(m.chmix, sizeof(m.chmix), " chmix=%d", 4119 snprintf(m.chmix, sizeof(m.chmix), " chmix=%d",
4171 track->chmix.srcbuf.capacity * 4120 track->chmix.srcbuf.capacity *
4172 frametobyte(&track->chmix.srcbuf.fmt, 1)); 4121 frametobyte(&track->chmix.srcbuf.fmt, 1));
4173 if (track->chvol.filter) 4122 if (track->chvol.filter)
4174 snprintf(m.chvol, sizeof(m.chvol), " chvol=%d", 4123 snprintf(m.chvol, sizeof(m.chvol), " chvol=%d",
4175 track->chvol.srcbuf.capacity * 4124 track->chvol.srcbuf.capacity *
4176 frametobyte(&track->chvol.srcbuf.fmt, 1)); 4125 frametobyte(&track->chvol.srcbuf.fmt, 1));
4177 if (track->codec.filter) 4126 if (track->codec.filter)
4178 snprintf(m.codec, sizeof(m.codec), " codec=%d", 4127 snprintf(m.codec, sizeof(m.codec), " codec=%d",
4179 track->codec.srcbuf.capacity * 4128 track->codec.srcbuf.capacity *
4180 frametobyte(&track->codec.srcbuf.fmt, 1)); 4129 frametobyte(&track->codec.srcbuf.fmt, 1));
4181 snprintf(m.usrbuf, sizeof(m.usrbuf), 4130 snprintf(m.usrbuf, sizeof(m.usrbuf),
4182 " usr=%d", track->usrbuf.capacity); 4131 " usr=%d", track->usrbuf.capacity);
4183 4132
4184 if (audio_track_is_playback(track)) { 4133 if (audio_track_is_playback(track)) {
4185 TRACET(0, track, "bufsize%s%s%s%s%s%s", 4134 TRACET(0, track, "bufsize%s%s%s%s%s%s",
4186 m.outbuf, m.freq, m.chmix, 4135 m.outbuf, m.freq, m.chmix,
4187 m.chvol, m.codec, m.usrbuf); 4136 m.chvol, m.codec, m.usrbuf);
4188 } else { 4137 } else {
4189 TRACET(0, track, "bufsize%s%s%s%s%s%s", 4138 TRACET(0, track, "bufsize%s%s%s%s%s%s",
4190 m.freq, m.chmix, m.chvol, 4139 m.freq, m.chmix, m.chvol,
4191 m.codec, m.outbuf, m.usrbuf); 4140 m.codec, m.outbuf, m.usrbuf);
4192 } 4141 }
4193 } 4142 }
4194#endif 4143#endif
4195 return 0; 4144 return 0;
4196 4145
4197error: 4146error:
4198 audio_free_usrbuf(track); 4147 audio_free_usrbuf(track);
4199 audio_free(track->codec.srcbuf.mem); 4148 audio_free(track->codec.srcbuf.mem);
4200 audio_free(track->chvol.srcbuf.mem); 4149 audio_free(track->chvol.srcbuf.mem);
4201 audio_free(track->chmix.srcbuf.mem); 4150 audio_free(track->chmix.srcbuf.mem);
4202 audio_free(track->freq.srcbuf.mem); 4151 audio_free(track->freq.srcbuf.mem);
4203 audio_free(track->outbuf.mem); 4152 audio_free(track->outbuf.mem);
4204 return error; 4153 return error;
4205} 4154}
4206 4155
4207/* 4156/*
4208 * Fill silence frames (as the internal format) up to 1 block 4157 * Fill silence frames (as the internal format) up to 1 block
4209 * if the ring is not empty and less than 1 block. 4158 * if the ring is not empty and less than 1 block.
4210 * It returns the number of appended frames. 4159 * It returns the number of appended frames.
4211 */ 4160 */
4212static int 4161static int
4213audio_append_silence(audio_track_t *track, audio_ring_t *ring) 4162audio_append_silence(audio_track_t *track, audio_ring_t *ring)
4214{ 4163{
4215 int fpb; 4164 int fpb;
4216 int n; 4165 int n;
4217 4166
4218 KASSERT(track); 4167 KASSERT(track);
4219 KASSERT(audio_format2_is_internal(&ring->fmt)); 4168 KASSERT(audio_format2_is_internal(&ring->fmt));
4220 4169
4221 /* XXX is n correct? */ 4170 /* XXX is n correct? */
4222 /* XXX memset uses frametobyte()? */ 4171 /* XXX memset uses frametobyte()? */
4223 4172
4224 if (ring->used == 0) 4173 if (ring->used == 0)
4225 return 0; 4174 return 0;
4226 4175
4227 fpb = frame_per_block(track->mixer, &ring->fmt); 4176 fpb = frame_per_block(track->mixer, &ring->fmt);
4228 if (ring->used >= fpb) 4177 if (ring->used >= fpb)
4229 return 0; 4178 return 0;
4230 4179
4231 n = (ring->capacity - ring->used) % fpb; 4180 n = (ring->capacity - ring->used) % fpb;
4232 4181
4233 KASSERT(auring_get_contig_free(ring) >= n); 4182 KASSERT(auring_get_contig_free(ring) >= n);
4234 4183
4235 memset(auring_tailptr_aint(ring), 0, 4184 memset(auring_tailptr_aint(ring), 0,
4236 n * ring->fmt.channels * sizeof(aint_t)); 4185 n * ring->fmt.channels * sizeof(aint_t));
4237 auring_push(ring, n); 4186 auring_push(ring, n);
4238 return n; 4187 return n;
4239} 4188}
4240 4189
4241/* 4190/*
4242 * Execute the conversion stage. 4191 * Execute the conversion stage.
4243 * It prepares arg from this stage and executes stage->filter. 4192 * It prepares arg from this stage and executes stage->filter.
4244 * It must be called only if stage->filter is not NULL. 4193 * It must be called only if stage->filter is not NULL.
4245 * 4194 *
4246 * For stages other than frequency conversion, the function increments 4195 * For stages other than frequency conversion, the function increments
4247 * src and dst counters here. For frequency conversion stage, on the 4196 * src and dst counters here. For frequency conversion stage, on the
4248 * other hand, the function does not touch src and dst counters and 4197 * other hand, the function does not touch src and dst counters and
4249 * filter side has to increment them. 4198 * filter side has to increment them.
4250 */ 4199 */
4251static void 4200static void
4252audio_apply_stage(audio_track_t *track, audio_stage_t *stage, bool isfreq) 4201audio_apply_stage(audio_track_t *track, audio_stage_t *stage, bool isfreq)
4253{ 4202{
4254 audio_filter_arg_t *arg; 4203 audio_filter_arg_t *arg;
4255 int srccount; 4204 int srccount;
4256 int dstcount; 4205 int dstcount;
4257 int count; 4206 int count;
4258 4207
4259 KASSERT(track); 4208 KASSERT(track);
4260 KASSERT(stage->filter); 4209 KASSERT(stage->filter);
4261 4210
4262 srccount = auring_get_contig_used(&stage->srcbuf); 4211 srccount = auring_get_contig_used(&stage->srcbuf);
4263 dstcount = auring_get_contig_free(stage->dst); 4212 dstcount = auring_get_contig_free(stage->dst);
4264 4213
4265 if (isfreq) { 4214 if (isfreq) {
4266 KASSERTMSG(srccount > 0, "freq but srccount == %d", srccount); 4215 KASSERTMSG(srccount > 0, "freq but srccount == %d", srccount);
4267 count = uimin(dstcount, track->mixer->frames_per_block); 4216 count = uimin(dstcount, track->mixer->frames_per_block);
4268 } else { 4217 } else {
4269 count = uimin(srccount, dstcount); 4218 count = uimin(srccount, dstcount);
4270 } 4219 }
4271 4220
4272 if (count > 0) { 4221 if (count > 0) {
4273 arg = &stage->arg; 4222 arg = &stage->arg;
4274 arg->src = auring_headptr(&stage->srcbuf); 4223 arg->src = auring_headptr(&stage->srcbuf);
4275 arg->dst = auring_tailptr(stage->dst); 4224 arg->dst = auring_tailptr(stage->dst);
4276 arg->count = count; 4225 arg->count = count;
4277 4226
4278 stage->filter(arg); 4227 stage->filter(arg);
4279 4228
4280 if (!isfreq) { 4229 if (!isfreq) {
4281 auring_take(&stage->srcbuf, count); 4230 auring_take(&stage->srcbuf, count);
4282 auring_push(stage->dst, count); 4231 auring_push(stage->dst, count);
4283 } 4232 }
4284 } 4233 }
4285} 4234}
4286 4235
4287/* 4236/*
4288 * Produce output buffer for playback from user input buffer. 4237 * Produce output buffer for playback from user input buffer.
4289 * It must be called only if usrbuf is not empty and outbuf is 4238 * It must be called only if usrbuf is not empty and outbuf is
4290 * available at least one free block. 4239 * available at least one free block.
4291 */ 4240 */
4292static void 4241static void
4293audio_track_play(audio_track_t *track) 4242audio_track_play(audio_track_t *track)
4294{ 4243{
4295 audio_ring_t *usrbuf; 4244 audio_ring_t *usrbuf;
4296 audio_ring_t *input; 4245 audio_ring_t *input;
4297 int count; 4246 int count;
4298 int framesize; 4247 int framesize;
4299 int bytes; 4248 int bytes;
4300 4249
4301 KASSERT(track); 4250 KASSERT(track);
4302 KASSERT(track->lock); 4251 KASSERT(track->lock);
4303 TRACET(4, track, "start pstate=%d", track->pstate); 4252 TRACET(4, track, "start pstate=%d", track->pstate);
4304 4253
4305 /* At this point usrbuf must not be empty. */ 4254 /* At this point usrbuf must not be empty. */
4306 KASSERT(track->usrbuf.used > 0); 4255 KASSERT(track->usrbuf.used > 0);
4307 /* Also, outbuf must be available at least one block. */ 4256 /* Also, outbuf must be available at least one block. */
4308 count = auring_get_contig_free(&track->outbuf); 4257 count = auring_get_contig_free(&track->outbuf);
4309 KASSERTMSG(count >= frame_per_block(track->mixer, &track->outbuf.fmt), 4258 KASSERTMSG(count >= frame_per_block(track->mixer, &track->outbuf.fmt),
4310 "count=%d fpb=%d", 4259 "count=%d fpb=%d",
4311 count, frame_per_block(track->mixer, &track->outbuf.fmt)); 4260 count, frame_per_block(track->mixer, &track->outbuf.fmt));
4312 4261
4313 /* XXX TODO: is this necessary for now? */ 4262 /* XXX TODO: is this necessary for now? */
4314 int track_count_0 = track->outbuf.used; 4263 int track_count_0 = track->outbuf.used;
4315 4264
4316 usrbuf = &track->usrbuf; 4265 usrbuf = &track->usrbuf;
4317 input = track->input; 4266 input = track->input;
4318 4267
4319 /* 4268 /*
4320 * framesize is always 1 byte or more since all formats supported as 4269 * framesize is always 1 byte or more since all formats supported as
4321 * usrfmt(=input) have 8bit or more stride. 4270 * usrfmt(=input) have 8bit or more stride.
4322 */ 4271 */
4323 framesize = frametobyte(&input->fmt, 1); 4272 framesize = frametobyte(&input->fmt, 1);
4324 KASSERT(framesize >= 1); 4273 KASSERT(framesize >= 1);
4325 4274
4326 /* The next stage of usrbuf (=input) must be available. */ 4275 /* The next stage of usrbuf (=input) must be available. */
4327 KASSERT(auring_get_contig_free(input) > 0); 4276 KASSERT(auring_get_contig_free(input) > 0);
4328 4277
4329 /* 4278 /*
4330 * Copy usrbuf up to 1block to input buffer. 4279 * Copy usrbuf up to 1block to input buffer.
4331 * count is the number of frames to copy from usrbuf. 4280 * count is the number of frames to copy from usrbuf.
4332 * bytes is the number of bytes to copy from usrbuf. However it is 4281 * bytes is the number of bytes to copy from usrbuf. However it is
4333 * not copied less than one frame. 4282 * not copied less than one frame.
4334 */ 4283 */
4335 count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize; 4284 count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize;
4336 bytes = count * framesize; 4285 bytes = count * framesize;
4337 4286
4338 track->usrbuf_stamp += bytes; 4287 track->usrbuf_stamp += bytes;
4339 4288
4340 if (usrbuf->head + bytes < usrbuf->capacity) { 4289 if (usrbuf->head + bytes < usrbuf->capacity) {
4341 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize, 4290 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
4342 (uint8_t *)usrbuf->mem + usrbuf->head, 4291 (uint8_t *)usrbuf->mem + usrbuf->head,
4343 bytes); 4292 bytes);
4344 auring_push(input, count); 4293 auring_push(input, count);
4345 auring_take(usrbuf, bytes); 4294 auring_take(usrbuf, bytes);
4346 } else { 4295 } else {
4347 int bytes1; 4296 int bytes1;
4348 int bytes2; 4297 int bytes2;
4349 4298
4350 bytes1 = auring_get_contig_used(usrbuf); 4299 bytes1 = auring_get_contig_used(usrbuf);
4351 KASSERT(bytes1 % framesize == 0); 4300 KASSERT(bytes1 % framesize == 0);
4352 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize, 4301 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
4353 (uint8_t *)usrbuf->mem + usrbuf->head, 4302 (uint8_t *)usrbuf->mem + usrbuf->head,
4354 bytes1); 4303 bytes1);
4355 auring_push(input, bytes1 / framesize); 4304 auring_push(input, bytes1 / framesize);
4356 auring_take(usrbuf, bytes1); 4305 auring_take(usrbuf, bytes1);
4357 4306
4358 bytes2 = bytes - bytes1; 4307 bytes2 = bytes - bytes1;
4359 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize, 4308 memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
4360 (uint8_t *)usrbuf->mem + usrbuf->head, 4309 (uint8_t *)usrbuf->mem + usrbuf->head,
4361 bytes2); 4310 bytes2);
4362 auring_push(input, bytes2 / framesize); 4311 auring_push(input, bytes2 / framesize);
4363 auring_take(usrbuf, bytes2); 4312 auring_take(usrbuf, bytes2);
4364 } 4313 }
4365 4314
4366 /* Encoding conversion */ 4315 /* Encoding conversion */
4367 if (track->codec.filter) 4316 if (track->codec.filter)
4368 audio_apply_stage(track, &track->codec, false); 4317 audio_apply_stage(track, &track->codec, false);
4369 4318
4370 /* Channel volume */ 4319 /* Channel volume */
4371 if (track->chvol.filter) 4320 if (track->chvol.filter)
4372 audio_apply_stage(track, &track->chvol, false); 4321 audio_apply_stage(track, &track->chvol, false);
4373 4322
4374 /* Channel mix */ 4323 /* Channel mix */
4375 if (track->chmix.filter) 4324 if (track->chmix.filter)
4376 audio_apply_stage(track, &track->chmix, false); 4325 audio_apply_stage(track, &track->chmix, false);
4377 4326
4378 /* Frequency conversion */ 4327 /* Frequency conversion */
4379 /* 4328 /*
4380 * Since the frequency conversion needs correction for each block, 4329 * Since the frequency conversion needs correction for each block,
4381 * it rounds up to 1 block. 4330 * it rounds up to 1 block.
4382 */ 4331 */
4383 if (track->freq.filter) { 4332 if (track->freq.filter) {
4384 int n; 4333 int n;
4385 n = audio_append_silence(track, &track->freq.srcbuf); 4334 n = audio_append_silence(track, &track->freq.srcbuf);
4386 if (n > 0) { 4335 if (n > 0) {
4387 TRACET(4, track, 4336 TRACET(4, track,
4388 "freq.srcbuf add silence %d -> %d/%d/%d", 4337 "freq.srcbuf add silence %d -> %d/%d/%d",
4389 n, 4338 n,
4390 track->freq.srcbuf.head, 4339 track->freq.srcbuf.head,
4391 track->freq.srcbuf.used, 4340 track->freq.srcbuf.used,
4392 track->freq.srcbuf.capacity); 4341 track->freq.srcbuf.capacity);
4393 } 4342 }
4394 if (track->freq.srcbuf.used > 0) { 4343 if (track->freq.srcbuf.used > 0) {
4395 audio_apply_stage(track, &track->freq, true); 4344 audio_apply_stage(track, &track->freq, true);
4396 } 4345 }
4397 } 4346 }
4398 4347
4399 if (bytes < track->usrbuf_blksize) { 4348 if (bytes < track->usrbuf_blksize) {
4400 /* 4349 /*
4401 * Clear all conversion buffer pointer if the conversion was 4350 * Clear all conversion buffer pointer if the conversion was
4402 * not exactly one block. These conversion stage buffers are 4351 * not exactly one block. These conversion stage buffers are
4403 * certainly circular buffers because of symmetry with the 4352 * certainly circular buffers because of symmetry with the
4404 * previous and next stage buffer. However, since they are 4353 * previous and next stage buffer. However, since they are
4405 * treated as simple contiguous buffers in operation, so head 4354 * treated as simple contiguous buffers in operation, so head
4406 * always should point 0. This may happen during drain-age. 4355 * always should point 0. This may happen during drain-age.
4407 */ 4356 */
4408 TRACET(4, track, "reset stage"); 4357 TRACET(4, track, "reset stage");
4409 if (track->codec.filter) { 4358 if (track->codec.filter) {
4410 KASSERT(track->codec.srcbuf.used == 0); 4359 KASSERT(track->codec.srcbuf.used == 0);
4411 track->codec.srcbuf.head = 0; 4360 track->codec.srcbuf.head = 0;
4412 } 4361 }
4413 if (track->chvol.filter) { 4362 if (track->chvol.filter) {
4414 KASSERT(track->chvol.srcbuf.used == 0); 4363 KASSERT(track->chvol.srcbuf.used == 0);
4415 track->chvol.srcbuf.head = 0; 4364 track->chvol.srcbuf.head = 0;
4416 } 4365 }
4417 if (track->chmix.filter) { 4366 if (track->chmix.filter) {
4418 KASSERT(track->chmix.srcbuf.used == 0); 4367 KASSERT(track->chmix.srcbuf.used == 0);
4419 track->chmix.srcbuf.head = 0; 4368 track->chmix.srcbuf.head = 0;
4420 } 4369 }
4421 if (track->freq.filter) { 4370 if (track->freq.filter) {
4422 KASSERT(track->freq.srcbuf.used == 0); 4371 KASSERT(track->freq.srcbuf.used == 0);
4423 track->freq.srcbuf.head = 0; 4372 track->freq.srcbuf.head = 0;
4424 } 4373 }
4425 } 4374 }
4426 4375
4427 if (track->input == &track->outbuf) { 4376 if (track->input == &track->outbuf) {
4428 track->outputcounter = track->inputcounter; 4377 track->outputcounter = track->inputcounter;
4429 } else { 4378 } else {
4430 track->outputcounter += track->outbuf.used - track_count_0; 4379 track->outputcounter += track->outbuf.used - track_count_0;
4431 } 4380 }
4432 4381
4433#if defined(AUDIO_DEBUG) 4382#if defined(AUDIO_DEBUG)
4434 if (audiodebug >= 3) { 4383 if (audiodebug >= 3) {
4435 struct audio_track_debugbuf m; 4384 struct audio_track_debugbuf m;
4436 audio_track_bufstat(track, &m); 4385 audio_track_bufstat(track, &m);
4437 TRACET(0, track, "end%s%s%s%s%s%s", 4386 TRACET(0, track, "end%s%s%s%s%s%s",
4438 m.outbuf, m.freq, m.chvol, m.chmix, m.codec, m.usrbuf); 4387 m.outbuf, m.freq, m.chvol, m.chmix, m.codec, m.usrbuf);
4439 } 4388 }
4440#endif 4389#endif
4441} 4390}
4442 4391
4443/* 4392/*
4444 * Produce user output buffer for recording from input buffer. 4393 * Produce user output buffer for recording from input buffer.
4445 */ 4394 */
4446static void 4395static void
4447audio_track_record(audio_track_t *track) 4396audio_track_record(audio_track_t *track)
4448{ 4397{
4449 audio_ring_t *outbuf; 4398 audio_ring_t *outbuf;
4450 audio_ring_t *usrbuf; 4399 audio_ring_t *usrbuf;
4451 int count; 4400 int count;
4452 int bytes; 4401 int bytes;
4453 int framesize; 4402 int framesize;
4454 4403
4455 KASSERT(track); 4404 KASSERT(track);
4456 KASSERT(track->lock); 4405 KASSERT(track->lock);
4457 4406
4458 /* Number of frames to process */ 4407 /* Number of frames to process */
4459 count = auring_get_contig_used(track->input); 4408 count = auring_get_contig_used(track->input);
4460 count = uimin(count, track->mixer->frames_per_block); 4409 count = uimin(count, track->mixer->frames_per_block);
4461 if (count == 0) { 4410 if (count == 0) {
4462 TRACET(4, track, "count == 0"); 4411 TRACET(4, track, "count == 0");
4463 return; 4412 return;
4464 } 4413 }
4465 4414
4466 /* Frequency conversion */ 4415 /* Frequency conversion */
4467 if (track->freq.filter) { 4416 if (track->freq.filter) {
4468 if (track->freq.srcbuf.used > 0) { 4417 if (track->freq.srcbuf.used > 0) {
4469 audio_apply_stage(track, &track->freq, true); 4418 audio_apply_stage(track, &track->freq, true);
4470 /* XXX should input of freq be from beginning of buf? */ 4419 /* XXX should input of freq be from beginning of buf? */
4471 } 4420 }
4472 } 4421 }
4473 4422
4474 /* Channel mix */ 4423 /* Channel mix */
4475 if (track->chmix.filter) 4424 if (track->chmix.filter)
4476 audio_apply_stage(track, &track->chmix, false); 4425 audio_apply_stage(track, &track->chmix, false);
4477 4426
4478 /* Channel volume */ 4427 /* Channel volume */
4479 if (track->chvol.filter) 4428 if (track->chvol.filter)
4480 audio_apply_stage(track, &track->chvol, false); 4429 audio_apply_stage(track, &track->chvol, false);
4481 4430
4482 /* Encoding conversion */ 4431 /* Encoding conversion */
4483 if (track->codec.filter) 4432 if (track->codec.filter)
4484 audio_apply_stage(track, &track->codec, false); 4433 audio_apply_stage(track, &track->codec, false);
4485 4434
4486 /* Copy outbuf to usrbuf */ 4435 /* Copy outbuf to usrbuf */
4487 outbuf = &track->outbuf; 4436 outbuf = &track->outbuf;
4488 usrbuf = &track->usrbuf; 4437 usrbuf = &track->usrbuf;
4489 /* 4438 /*
4490 * framesize is always 1 byte or more since all formats supported 4439 * framesize is always 1 byte or more since all formats supported
4491 * as usrfmt(=output) have 8bit or more stride. 4440 * as usrfmt(=output) have 8bit or more stride.
4492 */ 4441 */
4493 framesize = frametobyte(&outbuf->fmt, 1); 4442 framesize = frametobyte(&outbuf->fmt, 1);
4494 KASSERT(framesize >= 1); 4443 KASSERT(framesize >= 1);
4495 /* 4444 /*
4496 * count is the number of frames to copy to usrbuf. 4445 * count is the number of frames to copy to usrbuf.
4497 * bytes is the number of bytes to copy to usrbuf. 4446 * bytes is the number of bytes to copy to usrbuf.
4498 */ 4447 */
4499 count = outbuf->used; 4448 count = outbuf->used;
4500 count = uimin(count, 4449 count = uimin(count,
4501 (track->usrbuf_usedhigh - usrbuf->used) / framesize); 4450 (track->usrbuf_usedhigh - usrbuf->used) / framesize);
4502 bytes = count * framesize; 4451 bytes = count * framesize;
4503 if (auring_tail(usrbuf) + bytes < usrbuf->capacity) { 4452 if (auring_tail(usrbuf) + bytes < usrbuf->capacity) {
4504 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf), 4453 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
4505 (uint8_t *)outbuf->mem + outbuf->head * framesize, 4454 (uint8_t *)outbuf->mem + outbuf->head * framesize,
4506 bytes); 4455 bytes);
4507 auring_push(usrbuf, bytes); 4456 auring_push(usrbuf, bytes);
4508 auring_take(outbuf, count); 4457 auring_take(outbuf, count);
4509 } else { 4458 } else {
4510 int bytes1; 4459 int bytes1;
4511 int bytes2; 4460 int bytes2;
4512 4461
4513 bytes1 = auring_get_contig_free(usrbuf); 4462 bytes1 = auring_get_contig_free(usrbuf);
4514 KASSERT(bytes1 % framesize == 0); 4463 KASSERT(bytes1 % framesize == 0);
4515 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf), 4464 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
4516 (uint8_t *)outbuf->mem + outbuf->head * framesize, 4465 (uint8_t *)outbuf->mem + outbuf->head * framesize,
4517 bytes1); 4466 bytes1);
4518 auring_push(usrbuf, bytes1); 4467 auring_push(usrbuf, bytes1);
4519 auring_take(outbuf, bytes1 / framesize); 4468 auring_take(outbuf, bytes1 / framesize);
4520 4469
4521 bytes2 = bytes - bytes1; 4470 bytes2 = bytes - bytes1;
4522 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf), 4471 memcpy((uint8_t *)usrbuf->mem + auring_tail(usrbuf),
4523 (uint8_t *)outbuf->mem + outbuf->head * framesize, 4472 (uint8_t *)outbuf->mem + outbuf->head * framesize,
4524 bytes2); 4473 bytes2);
4525 auring_push(usrbuf, bytes2); 4474 auring_push(usrbuf, bytes2);
4526 auring_take(outbuf, bytes2 / framesize); 4475 auring_take(outbuf, bytes2 / framesize);
4527 } 4476 }
4528 4477
4529 /* XXX TODO: any counters here? */ 4478 /* XXX TODO: any counters here? */
4530 4479
4531#if defined(AUDIO_DEBUG) 4480#if defined(AUDIO_DEBUG)
4532 if (audiodebug >= 3) { 4481 if (audiodebug >= 3) {
4533 struct audio_track_debugbuf m; 4482 struct audio_track_debugbuf m;
4534 audio_track_bufstat(track, &m); 4483 audio_track_bufstat(track, &m);
4535 TRACET(0, track, "end%s%s%s%s%s%s", 4484 TRACET(0, track, "end%s%s%s%s%s%s",
4536 m.freq, m.chvol, m.chmix, m.codec, m.outbuf, m.usrbuf); 4485 m.freq, m.chvol, m.chmix, m.codec, m.outbuf, m.usrbuf);
4537 } 4486 }
4538#endif 4487#endif
4539} 4488}
4540 4489
4541/* 4490/*
4542 * Calcurate blktime [msec] from mixer(.hwbuf.fmt). 4491 * Calcurate blktime [msec] from mixer(.hwbuf.fmt).
4543 * Must be called with sc_lock held. 4492 * Must be called with sc_lock held.
4544 */ 4493 */
4545static u_int 4494static u_int
4546audio_mixer_calc_blktime(struct audio_softc *sc, audio_trackmixer_t *mixer) 4495audio_mixer_calc_blktime(struct audio_softc *sc, audio_trackmixer_t *mixer)
4547{ 4496{
4548 audio_format2_t *fmt; 4497 audio_format2_t *fmt;
4549 u_int blktime; 4498 u_int blktime;
4550 u_int frames_per_block; 4499 u_int frames_per_block;
4551 4500
4552 KASSERT(mutex_owned(sc->sc_lock)); 4501 KASSERT(mutex_owned(sc->sc_lock));
4553 4502
4554 fmt = &mixer->hwbuf.fmt; 4503 fmt = &mixer->hwbuf.fmt;
4555 blktime = sc->sc_blk_ms; 4504 blktime = sc->sc_blk_ms;
4556 4505
4557 /* 4506 /*
4558 * If stride is not multiples of 8, special treatment is necessary. 4507 * If stride is not multiples of 8, special treatment is necessary.
4559 * For now, it is only x68k's vs(4), 4 bit/sample ADPCM. 4508 * For now, it is only x68k's vs(4), 4 bit/sample ADPCM.
4560 */ 4509 */
4561 if (fmt->stride == 4) { 4510 if (fmt->stride == 4) {
4562 frames_per_block = fmt->sample_rate * blktime / 1000; 4511 frames_per_block = fmt->sample_rate * blktime / 1000;
4563 if ((frames_per_block & 1) != 0) 4512 if ((frames_per_block & 1) != 0)
4564 blktime *= 2; 4513 blktime *= 2;
4565 } 4514 }
4566#ifdef DIAGNOSTIC 4515#ifdef DIAGNOSTIC
4567 else if (fmt->stride % NBBY != 0) { 4516 else if (fmt->stride % NBBY != 0) {
4568 panic("unsupported HW stride %d", fmt->stride); 4517 panic("unsupported HW stride %d", fmt->stride);
4569 } 4518 }
4570#endif 4519#endif
4571 4520
4572 return blktime; 4521 return blktime;
4573} 4522}
4574 4523
4575/* 4524/*
4576 * Initialize the mixer corresponding to the mode. 4525 * Initialize the mixer corresponding to the mode.
4577 * Set AUMODE_PLAY to the 'mode' for playback or AUMODE_RECORD for recording. 4526 * Set AUMODE_PLAY to the 'mode' for playback or AUMODE_RECORD for recording.
4578 * sc->sc_[pr]mixer (corresponding to the 'mode') must be zero-filled. 4527 * sc->sc_[pr]mixer (corresponding to the 'mode') must be zero-filled.
4579 * This function returns 0 on sucessful. Otherwise returns errno. 4528 * This function returns 0 on sucessful. Otherwise returns errno.
4580 * Must be called with sc_lock held. 4529 * Must be called with sc_lock held.
4581 */ 4530 */
4582static int 4531static int
4583audio_mixer_init(struct audio_softc *sc, int mode, 4532audio_mixer_init(struct audio_softc *sc, int mode,
4584 const audio_format2_t *hwfmt, const audio_filter_reg_t *reg) 4533 const audio_format2_t *hwfmt, const audio_filter_reg_t *reg)
4585{ 4534{
4586 char codecbuf[64]; 4535 char codecbuf[64];
4587 audio_trackmixer_t *mixer; 4536 audio_trackmixer_t *mixer;
4588 void (*softint_handler)(void *); 4537 void (*softint_handler)(void *);
4589 int len; 4538 int len;
4590 int blksize; 4539 int blksize;
4591 int capacity; 4540 int capacity;
4592 size_t bufsize; 4541 size_t bufsize;
4593 int hwblks; 4542 int hwblks;
4594 int blkms; 4543 int blkms;
4595 int error; 4544 int error;
4596 4545
4597 KASSERT(hwfmt != NULL); 4546 KASSERT(hwfmt != NULL);
4598 KASSERT(reg != NULL); 4547 KASSERT(reg != NULL);
4599 KASSERT(mutex_owned(sc->sc_lock)); 4548 KASSERT(mutex_owned(sc->sc_lock));
4600 4549
4601 error = 0; 4550 error = 0;
4602 if (mode == AUMODE_PLAY) 4551 if (mode == AUMODE_PLAY)
4603 mixer = sc->sc_pmixer; 4552 mixer = sc->sc_pmixer;
4604 else 4553 else
4605 mixer = sc->sc_rmixer; 4554 mixer = sc->sc_rmixer;
4606 4555
4607 mixer->sc = sc; 4556 mixer->sc = sc;
4608 mixer->mode = mode; 4557 mixer->mode = mode;
4609 4558
4610 mixer->hwbuf.fmt = *hwfmt; 4559 mixer->hwbuf.fmt = *hwfmt;
4611 mixer->volume = 256; 4560 mixer->volume = 256;
4612 mixer->blktime_d = 1000; 4561 mixer->blktime_d = 1000;
4613 mixer->blktime_n = audio_mixer_calc_blktime(sc, mixer); 4562 mixer->blktime_n = audio_mixer_calc_blktime(sc, mixer);
4614 sc->sc_blk_ms = mixer->blktime_n; 4563 sc->sc_blk_ms = mixer->blktime_n;
4615 hwblks = NBLKHW; 4564 hwblks = NBLKHW;
4616 4565
4617 mixer->frames_per_block = frame_per_block(mixer, &mixer->hwbuf.fmt); 4566 mixer->frames_per_block = frame_per_block(mixer, &mixer->hwbuf.fmt);
4618 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); 4567 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
4619 if (sc->hw_if->round_blocksize) { 4568 if (sc->hw_if->round_blocksize) {
4620 int rounded; 4569 int rounded;
4621 audio_params_t p = format2_to_params(&mixer->hwbuf.fmt); 4570 audio_params_t p = format2_to_params(&mixer->hwbuf.fmt);
4622 rounded = sc->hw_if->round_blocksize(sc->hw_hdl, blksize, 4571 rounded = sc->hw_if->round_blocksize(sc->hw_hdl, blksize,
4623 mode, &p); 4572 mode, &p);
4624 TRACE(1, "round_blocksize %d -> %d", blksize, rounded); 4573 TRACE(1, "round_blocksize %d -> %d", blksize, rounded);
4625 if (rounded != blksize) { 4574 if (rounded != blksize) {
4626 if ((rounded * NBBY) % (mixer->hwbuf.fmt.stride * 4575 if ((rounded * NBBY) % (mixer->hwbuf.fmt.stride *
4627 mixer->hwbuf.fmt.channels) != 0) { 4576 mixer->hwbuf.fmt.channels) != 0) {
4628 device_printf(sc->sc_dev, 4577 device_printf(sc->sc_dev,
4629 "blksize not configured %d -> %d\n", 4578 "blksize not configured %d -> %d\n",
4630 blksize, rounded); 4579 blksize, rounded);
4631 return EINVAL; 4580 return EINVAL;
4632 } 4581 }
4633 /* Recalculation */ 4582 /* Recalculation */
4634 blksize = rounded; 4583 blksize = rounded;
4635 mixer->frames_per_block = blksize * NBBY / 4584 mixer->frames_per_block = blksize * NBBY /
4636 (mixer->hwbuf.fmt.stride * 4585 (mixer->hwbuf.fmt.stride *
4637 mixer->hwbuf.fmt.channels); 4586 mixer->hwbuf.fmt.channels);
4638 } 4587 }
4639 } 4588 }
4640 mixer->blktime_n = mixer->frames_per_block; 4589 mixer->blktime_n = mixer->frames_per_block;
4641 mixer->blktime_d = mixer->hwbuf.fmt.sample_rate; 4590 mixer->blktime_d = mixer->hwbuf.fmt.sample_rate;
4642 4591
4643 capacity = mixer->frames_per_block * hwblks; 4592 capacity = mixer->frames_per_block * hwblks;
4644 bufsize = frametobyte(&mixer->hwbuf.fmt, capacity); 4593 bufsize = frametobyte(&mixer->hwbuf.fmt, capacity);
4645 if (sc->hw_if->round_buffersize) { 4594 if (sc->hw_if->round_buffersize) {
4646 size_t rounded; 4595 size_t rounded;
4647 rounded = sc->hw_if->round_buffersize(sc->hw_hdl, mode, 4596 rounded = sc->hw_if->round_buffersize(sc->hw_hdl, mode,
4648 bufsize); 4597 bufsize);
4649 TRACE(1, "round_buffersize %zd -> %zd", bufsize, rounded); 4598 TRACE(1, "round_buffersize %zd -> %zd", bufsize, rounded);
4650 if (rounded < bufsize) { 4599 if (rounded < bufsize) {
4651 /* buffersize needs NBLKHW blocks at least. */ 4600 /* buffersize needs NBLKHW blocks at least. */
4652 device_printf(sc->sc_dev, 4601 device_printf(sc->sc_dev,
4653 "buffersize too small: buffersize=%zd blksize=%d\n", 4602 "buffersize too small: buffersize=%zd blksize=%d\n",
4654 rounded, blksize); 4603 rounded, blksize);
4655 return EINVAL; 4604 return EINVAL;
4656 } 4605 }
4657 if (rounded % blksize != 0) { 4606 if (rounded % blksize != 0) {
4658 /* buffersize/blksize constraint mismatch? */ 4607 /* buffersize/blksize constraint mismatch? */
4659 device_printf(sc->sc_dev, 4608 device_printf(sc->sc_dev,
4660 "buffersize must be multiple of blksize: " 4609 "buffersize must be multiple of blksize: "
4661 "buffersize=%zu blksize=%d\n", 4610 "buffersize=%zu blksize=%d\n",
4662 rounded, blksize); 4611 rounded, blksize);
4663 return EINVAL; 4612 return EINVAL;
4664 } 4613 }
4665 if (rounded != bufsize) { 4614 if (rounded != bufsize) {
4666 /* Recalcuration */ 4615 /* Recalcuration */
4667 bufsize = rounded; 4616 bufsize = rounded;
4668 hwblks = bufsize / blksize; 4617 hwblks = bufsize / blksize;
4669 capacity = mixer->frames_per_block * hwblks; 4618 capacity = mixer->frames_per_block * hwblks;
4670 } 4619 }
4671 } 4620 }
4672 TRACE(1, "buffersize for %s = %zu", 4621 TRACE(1, "buffersize for %s = %zu",
4673 (mode == AUMODE_PLAY) ? "playback" : "recording", 4622 (mode == AUMODE_PLAY) ? "playback" : "recording",
4674 bufsize); 4623 bufsize);
4675 mixer->hwbuf.capacity = capacity; 4624 mixer->hwbuf.capacity = capacity;
4676 4625
4677 /* 4626 /*
4678 * XXX need to release sc_lock for compatibility? 4627 * XXX need to release sc_lock for compatibility?
4679 */ 4628 */
4680 if (sc->hw_if->allocm) { 4629 if (sc->hw_if->allocm) {
4681 mixer->hwbuf.mem = sc->hw_if->allocm(sc->hw_hdl, mode, bufsize); 4630 mixer->hwbuf.mem = sc->hw_if->allocm(sc->hw_hdl, mode, bufsize);
4682 if (mixer->hwbuf.mem == NULL) { 4631 if (mixer->hwbuf.mem == NULL) {
4683 device_printf(sc->sc_dev, "%s: allocm(%zu) failed\n", 4632 device_printf(sc->sc_dev, "%s: allocm(%zu) failed\n",
4684 __func__, bufsize); 4633 __func__, bufsize);
4685 return ENOMEM; 4634 return ENOMEM;
4686 } 4635 }
4687 } else { 4636 } else {
4688 mixer->hwbuf.mem = kmem_alloc(bufsize, KM_SLEEP); 4637 mixer->hwbuf.mem = kmem_alloc(bufsize, KM_SLEEP);
4689 } 4638 }
4690 4639
4691 /* From here, audio_mixer_destroy is necessary to exit. */ 4640 /* From here, audio_mixer_destroy is necessary to exit. */
4692 if (mode == AUMODE_PLAY) { 4641 if (mode == AUMODE_PLAY) {
4693 cv_init(&mixer->outcv, "audiowr"); 4642 cv_init(&mixer->outcv, "audiowr");
4694 } else { 4643 } else {
4695 cv_init(&mixer->outcv, "audiord"); 4644 cv_init(&mixer->outcv, "audiord");
4696 } 4645 }
4697 4646
4698 if (mode == AUMODE_PLAY) { 4647 if (mode == AUMODE_PLAY) {
4699 softint_handler = audio_softintr_wr; 4648 softint_handler = audio_softintr_wr;
4700 } else { 4649 } else {
4701 softint_handler = audio_softintr_rd; 4650 softint_handler = audio_softintr_rd;
4702 } 4651 }
4703 mixer->sih = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE, 4652 mixer->sih = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
4704 softint_handler, sc); 4653 softint_handler, sc);
4705 if (mixer->sih == NULL) { 4654 if (mixer->sih == NULL) {
4706 device_printf(sc->sc_dev, "softint_establish failed\n"); 4655 device_printf(sc->sc_dev, "softint_establish failed\n");
4707 goto abort; 4656 goto abort;
4708 } 4657 }
4709 4658
4710 mixer->track_fmt.encoding = AUDIO_ENCODING_SLINEAR_NE; 4659 mixer->track_fmt.encoding = AUDIO_ENCODING_SLINEAR_NE;
4711 mixer->track_fmt.precision = AUDIO_INTERNAL_BITS; 4660 mixer->track_fmt.precision = AUDIO_INTERNAL_BITS;
4712 mixer->track_fmt.stride = AUDIO_INTERNAL_BITS; 4661 mixer->track_fmt.stride = AUDIO_INTERNAL_BITS;
4713 mixer->track_fmt.channels = mixer->hwbuf.fmt.channels; 4662 mixer->track_fmt.channels = mixer->hwbuf.fmt.channels;
4714 mixer->track_fmt.sample_rate = mixer->hwbuf.fmt.sample_rate; 4663 mixer->track_fmt.sample_rate = mixer->hwbuf.fmt.sample_rate;
4715 4664
4716 if (mixer->hwbuf.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE && 4665 if (mixer->hwbuf.fmt.encoding == AUDIO_ENCODING_SLINEAR_OE &&
4717 mixer->hwbuf.fmt.precision == AUDIO_INTERNAL_BITS) { 4666 mixer->hwbuf.fmt.precision == AUDIO_INTERNAL_BITS) {
4718 mixer->swap_endian = true; 4667 mixer->swap_endian = true;
4719 TRACE(1, "swap_endian"); 4668 TRACE(1, "swap_endian");
4720 } 4669 }
4721 4670
4722 if (mode == AUMODE_PLAY) { 4671 if (mode == AUMODE_PLAY) {
4723 /* Mixing buffer */ 4672 /* Mixing buffer */
4724 mixer->mixfmt = mixer->track_fmt; 4673 mixer->mixfmt = mixer->track_fmt;
4725 mixer->mixfmt.precision *= 2; 4674 mixer->mixfmt.precision *= 2;
4726 mixer->mixfmt.stride *= 2; 4675 mixer->mixfmt.stride *= 2;
4727 /* XXX TODO: use some macros? */ 4676 /* XXX TODO: use some macros? */
4728 len = mixer->frames_per_block * mixer->mixfmt.channels * 4677 len = mixer->frames_per_block * mixer->mixfmt.channels *
4729 mixer->mixfmt.stride / NBBY; 4678 mixer->mixfmt.stride / NBBY;
4730 mixer->mixsample = audio_realloc(mixer->mixsample, len); 4679 mixer->mixsample = audio_realloc(mixer->mixsample, len);
4731 if (mixer->mixsample == NULL) { 
4732 device_printf(sc->sc_dev, 
4733 "%s: malloc mixsample(%d) failed\n", 
4734 __func__, len); 
4735 error = ENOMEM; 
4736 goto abort; 
4737 } 
4738 } else { 4680 } else {
4739 /* No mixing buffer for recording */ 4681 /* No mixing buffer for recording */
4740 } 4682 }
4741 4683
4742 if (reg->codec) { 4684 if (reg->codec) {
4743 mixer->codec = reg->codec; 4685 mixer->codec = reg->codec;
4744 mixer->codecarg.context = reg->context; 4686 mixer->codecarg.context = reg->context;
4745 if (mode == AUMODE_PLAY) { 4687 if (mode == AUMODE_PLAY) {
4746 mixer->codecarg.srcfmt = &mixer->track_fmt; 4688 mixer->codecarg.srcfmt = &mixer->track_fmt;
4747 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt; 4689 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt;
4748 } else { 4690 } else {
4749 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt; 4691 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt;
4750 mixer->codecarg.dstfmt = &mixer->track_fmt; 4692 mixer->codecarg.dstfmt = &mixer->track_fmt;
4751 } 4693 }
4752 mixer->codecbuf.fmt = mixer->track_fmt; 4694 mixer->codecbuf.fmt = mixer->track_fmt;
4753 mixer->codecbuf.capacity = mixer->frames_per_block; 4695 mixer->codecbuf.capacity = mixer->frames_per_block;
4754 len = auring_bytelen(&mixer->codecbuf); 4696 len = auring_bytelen(&mixer->codecbuf);
4755 mixer->codecbuf.mem = audio_realloc(mixer->codecbuf.mem, len); 4697 mixer->codecbuf.mem = audio_realloc(mixer->codecbuf.mem, len);
4756 if (mixer->codecbuf.mem == NULL) { 4698 if (mixer->codecbuf.mem == NULL) {
4757 device_printf(sc->sc_dev, 4699 device_printf(sc->sc_dev,
4758 "%s: malloc codecbuf(%d) failed\n", 4700 "%s: malloc codecbuf(%d) failed\n",
4759 __func__, len); 4701 __func__, len);
4760 error = ENOMEM; 4702 error = ENOMEM;
4761 goto abort; 4703 goto abort;
4762 } 4704 }
4763 } 4705 }
4764 4706
4765 /* Succeeded so display it. */ 4707 /* Succeeded so display it. */
4766 codecbuf[0] = '\0'; 4708 codecbuf[0] = '\0';
4767 if (mixer->codec || mixer->swap_endian) { 4709 if (mixer->codec || mixer->swap_endian) {
4768 snprintf(codecbuf, sizeof(codecbuf), " %s %s:%d", 4710 snprintf(codecbuf, sizeof(codecbuf), " %s %s:%d",
4769 (mode == AUMODE_PLAY) ? "->" : "<-", 4711 (mode == AUMODE_PLAY) ? "->" : "<-",
4770 audio_encoding_name(mixer->hwbuf.fmt.encoding), 4712 audio_encoding_name(mixer->hwbuf.fmt.encoding),
4771 mixer->hwbuf.fmt.precision); 4713 mixer->hwbuf.fmt.precision);
4772 } 4714 }
4773 blkms = mixer->blktime_n * 1000 / mixer->blktime_d; 4715 blkms = mixer->blktime_n * 1000 / mixer->blktime_d;
4774 aprint_normal_dev(sc->sc_dev, "%s:%d%s %dch %dHz, blk %dms for %s\n", 4716 aprint_normal_dev(sc->sc_dev, "%s:%d%s %dch %dHz, blk %dms for %s\n",
4775 audio_encoding_name(mixer->track_fmt.encoding), 4717 audio_encoding_name(mixer->track_fmt.encoding),
4776 mixer->track_fmt.precision, 4718 mixer->track_fmt.precision,
4777 codecbuf, 4719 codecbuf,
4778 mixer->track_fmt.channels, 4720 mixer->track_fmt.channels,
4779 mixer->track_fmt.sample_rate, 4721 mixer->track_fmt.sample_rate,
4780 blkms, 4722 blkms,
4781 (mode == AUMODE_PLAY) ? "playback" : "recording"); 4723 (mode == AUMODE_PLAY) ? "playback" : "recording");
4782 4724
4783 return 0; 4725 return 0;
4784 4726
4785abort: 4727abort:
4786 audio_mixer_destroy(sc, mixer); 4728 audio_mixer_destroy(sc, mixer);
4787 return error; 4729 return error;
4788} 4730}
4789 4731
4790/* 4732/*
4791 * Releases all resources of 'mixer'. 4733 * Releases all resources of 'mixer'.
4792 * Note that it does not release the memory area of 'mixer' itself. 4734 * Note that it does not release the memory area of 'mixer' itself.
4793 * Must be called with sc_lock held. 4735 * Must be called with sc_lock held.
4794 */ 4736 */
4795static void 4737static void
4796audio_mixer_destroy(struct audio_softc *sc, audio_trackmixer_t *mixer) 4738audio_mixer_destroy(struct audio_softc *sc, audio_trackmixer_t *mixer)
4797{ 4739{
4798 int bufsize; 4740 int bufsize;
4799 4741
4800 KASSERT(mutex_owned(sc->sc_lock)); 4742 KASSERT(mutex_owned(sc->sc_lock));
4801 4743
4802 bufsize = frametobyte(&mixer->hwbuf.fmt, mixer->hwbuf.capacity); 4744 bufsize = frametobyte(&mixer->hwbuf.fmt, mixer->hwbuf.capacity);
4803 4745
4804 if (mixer->hwbuf.mem != NULL) { 4746 if (mixer->hwbuf.mem != NULL) {
4805 if (sc->hw_if->freem) { 4747 if (sc->hw_if->freem) {
4806 sc->hw_if->freem(sc->hw_hdl, mixer->hwbuf.mem, bufsize); 4748 sc->hw_if->freem(sc->hw_hdl, mixer->hwbuf.mem, bufsize);
4807 } else { 4749 } else {
4808 kmem_free(mixer->hwbuf.mem, bufsize); 4750 kmem_free(mixer->hwbuf.mem, bufsize);
4809 } 4751 }
4810 mixer->hwbuf.mem = NULL; 4752 mixer->hwbuf.mem = NULL;
4811 } 4753 }
4812 4754
4813 audio_free(mixer->codecbuf.mem); 4755 audio_free(mixer->codecbuf.mem);
4814 audio_free(mixer->mixsample); 4756 audio_free(mixer->mixsample);
4815 4757
4816 cv_destroy(&mixer->outcv); 4758 cv_destroy(&mixer->outcv);
4817 4759
4818 if (mixer->sih) { 4760 if (mixer->sih) {
4819 softint_disestablish(mixer->sih); 4761 softint_disestablish(mixer->sih);
4820 mixer->sih = NULL; 4762 mixer->sih = NULL;
4821 } 4763 }
4822} 4764}
4823 4765
4824/* 4766/*
4825 * Starts playback mixer. 4767 * Starts playback mixer.
4826 * Must be called only if sc_pbusy is false. 4768 * Must be called only if sc_pbusy is false.
4827 * Must be called with sc_lock held. 4769 * Must be called with sc_lock held.
4828 * Must not be called from the interrupt context. 4770 * Must not be called from the interrupt context.
4829 */ 4771 */
4830static void 4772static void
4831audio_pmixer_start(struct audio_softc *sc, bool force) 4773audio_pmixer_start(struct audio_softc *sc, bool force)
4832{ 4774{
4833 audio_trackmixer_t *mixer; 4775 audio_trackmixer_t *mixer;
4834 int minimum; 4776 int minimum;
4835 4777
4836 KASSERT(mutex_owned(sc->sc_lock)); 4778 KASSERT(mutex_owned(sc->sc_lock));
4837 KASSERT(sc->sc_pbusy == false); 4779 KASSERT(sc->sc_pbusy == false);
4838 4780
4839 mutex_enter(sc->sc_intr_lock); 4781 mutex_enter(sc->sc_intr_lock);
4840 4782
4841 mixer = sc->sc_pmixer; 4783 mixer = sc->sc_pmixer;
4842 TRACE(2, "%smixseq=%d hwseq=%d hwbuf=%d/%d/%d%s", 4784 TRACE(2, "%smixseq=%d hwseq=%d hwbuf=%d/%d/%d%s",
4843 (audiodebug >= 3) ? "begin " : "", 4785 (audiodebug >= 3) ? "begin " : "",
4844 (int)mixer->mixseq, (int)mixer->hwseq, 4786 (int)mixer->mixseq, (int)mixer->hwseq,
4845 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity, 4787 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
4846 force ? " force" : ""); 4788 force ? " force" : "");
4847 4789
4848 /* Need two blocks to start normally. */ 4790 /* Need two blocks to start normally. */
4849 minimum = (force) ? 1 : 2; 4791 minimum = (force) ? 1 : 2;
4850 while (mixer->hwbuf.used < mixer->frames_per_block * minimum) { 4792 while (mixer->hwbuf.used < mixer->frames_per_block * minimum) {
4851 audio_pmixer_process(sc); 4793 audio_pmixer_process(sc);
4852 } 4794 }
4853 4795
4854 /* Start output */ 4796 /* Start output */
4855 audio_pmixer_output(sc); 4797 audio_pmixer_output(sc);
4856 sc->sc_pbusy = true; 4798 sc->sc_pbusy = true;
4857 4799
4858 TRACE(3, "end mixseq=%d hwseq=%d hwbuf=%d/%d/%d", 4800 TRACE(3, "end mixseq=%d hwseq=%d hwbuf=%d/%d/%d",
4859 (int)mixer->mixseq, (int)mixer->hwseq, 4801 (int)mixer->mixseq, (int)mixer->hwseq,
4860 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 4802 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
4861 4803
4862 mutex_exit(sc->sc_intr_lock); 4804 mutex_exit(sc->sc_intr_lock);
4863} 4805}
4864 4806
4865/* 4807/*
4866 * When playing back with MD filter: 4808 * When playing back with MD filter:
4867 * 4809 *
4868 * track track ... 4810 * track track ...
4869 * v v 4811 * v v
4870 * + mix (with aint2_t) 4812 * + mix (with aint2_t)
4871 * | master volume (with aint2_t) 4813 * | master volume (with aint2_t)
4872 * v 4814 * v
4873 * mixsample [::::] wide-int 1 block (ring) buffer 4815 * mixsample [::::] wide-int 1 block (ring) buffer
4874 * | 4816 * |
4875 * | convert aint2_t -> aint_t 4817 * | convert aint2_t -> aint_t
4876 * v 4818 * v
4877 * codecbuf [....] 1 block (ring) buffer 4819 * codecbuf [....] 1 block (ring) buffer
4878 * | 4820 * |
4879 * | convert to hw format 4821 * | convert to hw format
4880 * v 4822 * v
4881 * hwbuf [............] NBLKHW blocks ring buffer 4823 * hwbuf [............] NBLKHW blocks ring buffer
4882 * 4824 *
4883 * When playing back without MD filter: 4825 * When playing back without MD filter:
4884 * 4826 *
4885 * mixsample [::::] wide-int 1 block (ring) buffer 4827 * mixsample [::::] wide-int 1 block (ring) buffer
4886 * | 4828 * |
4887 * | convert aint2_t -> aint_t 4829 * | convert aint2_t -> aint_t
4888 * | (with byte swap if necessary) 4830 * | (with byte swap if necessary)
4889 * v 4831 * v
4890 * hwbuf [............] NBLKHW blocks ring buffer 4832 * hwbuf [............] NBLKHW blocks ring buffer
4891 * 4833 *
4892 * mixsample: slinear_NE, wide internal precision, HW ch, HW freq. 4834 * mixsample: slinear_NE, wide internal precision, HW ch, HW freq.
4893 * codecbuf: slinear_NE, internal precision, HW ch, HW freq. 4835 * codecbuf: slinear_NE, internal precision, HW ch, HW freq.
4894 * hwbuf: HW encoding, HW precision, HW ch, HW freq. 4836 * hwbuf: HW encoding, HW precision, HW ch, HW freq.
4895 */ 4837 */
4896 4838
4897/* 4839/*
4898 * Performs track mixing and converts it to hwbuf. 4840 * Performs track mixing and converts it to hwbuf.
4899 * Note that this function doesn't transfer hwbuf to hardware. 4841 * Note that this function doesn't transfer hwbuf to hardware.
4900 * Must be called with sc_intr_lock held. 4842 * Must be called with sc_intr_lock held.
4901 */ 4843 */
4902static void 4844static void
4903audio_pmixer_process(struct audio_softc *sc) 4845audio_pmixer_process(struct audio_softc *sc)
4904{ 4846{
4905 audio_trackmixer_t *mixer; 4847 audio_trackmixer_t *mixer;
4906 audio_file_t *f; 4848 audio_file_t *f;
4907 int frame_count; 4849 int frame_count;
4908 int sample_count; 4850 int sample_count;
4909 int mixed; 4851 int mixed;
4910 int i; 4852 int i;
4911 aint2_t *m; 4853 aint2_t *m;
4912 aint_t *h; 4854 aint_t *h;
4913 4855
4914 mixer = sc->sc_pmixer; 4856 mixer = sc->sc_pmixer;
4915 4857
4916 frame_count = mixer->frames_per_block; 4858 frame_count = mixer->frames_per_block;
4917 KASSERT(auring_get_contig_free(&mixer->hwbuf) >= frame_count); 4859 KASSERT(auring_get_contig_free(&mixer->hwbuf) >= frame_count);
4918 sample_count = frame_count * mixer->mixfmt.channels; 4860 sample_count = frame_count * mixer->mixfmt.channels;
4919 4861
4920 mixer->mixseq++; 4862 mixer->mixseq++;
4921 4863
4922 /* Mix all tracks */ 4864 /* Mix all tracks */
4923 mixed = 0; 4865 mixed = 0;
4924 SLIST_FOREACH(f, &sc->sc_files, entry) { 4866 SLIST_FOREACH(f, &sc->sc_files, entry) {
4925 audio_track_t *track = f->ptrack; 4867 audio_track_t *track = f->ptrack;
4926 4868
4927 if (track == NULL) 4869 if (track == NULL)
4928 continue; 4870 continue;
4929 4871
4930 if (track->is_pause) { 4872 if (track->is_pause) {
4931 TRACET(4, track, "skip; paused"); 4873 TRACET(4, track, "skip; paused");
4932 continue; 4874 continue;
4933 } 4875 }
4934 4876
4935 /* Skip if the track is used by process context. */ 4877 /* Skip if the track is used by process context. */
4936 if (audio_track_lock_tryenter(track) == false) { 4878 if (audio_track_lock_tryenter(track) == false) {
4937 TRACET(4, track, "skip; in use"); 4879 TRACET(4, track, "skip; in use");
4938 continue; 4880 continue;
4939 } 4881 }
4940 4882
4941 /* Emulate mmap'ped track */ 4883 /* Emulate mmap'ped track */
4942 if (track->mmapped) { 4884 if (track->mmapped) {
4943 auring_push(&track->usrbuf, track->usrbuf_blksize); 4885 auring_push(&track->usrbuf, track->usrbuf_blksize);
4944 TRACET(4, track, "mmap; usr=%d/%d/C%d", 4886 TRACET(4, track, "mmap; usr=%d/%d/C%d",
4945 track->usrbuf.head, 4887 track->usrbuf.head,
4946 track->usrbuf.used, 4888 track->usrbuf.used,
4947 track->usrbuf.capacity); 4889 track->usrbuf.capacity);
4948 } 4890 }
4949 4891
4950 if (track->outbuf.used < mixer->frames_per_block && 4892 if (track->outbuf.used < mixer->frames_per_block &&
4951 track->usrbuf.used > 0) { 4893 track->usrbuf.used > 0) {
4952 TRACET(4, track, "process"); 4894 TRACET(4, track, "process");
4953 audio_track_play(track); 4895 audio_track_play(track);
4954 } 4896 }
4955 4897
4956 if (track->outbuf.used > 0) { 4898 if (track->outbuf.used > 0) {
4957 mixed = audio_pmixer_mix_track(mixer, track, mixed); 4899 mixed = audio_pmixer_mix_track(mixer, track, mixed);
4958 } else { 4900 } else {
4959 TRACET(4, track, "skip; empty"); 4901 TRACET(4, track, "skip; empty");
4960 } 4902 }
4961 4903
4962 audio_track_lock_exit(track); 4904 audio_track_lock_exit(track);
4963 } 4905 }
4964 4906
4965 if (mixed == 0) { 4907 if (mixed == 0) {
4966 /* Silence */ 4908 /* Silence */
4967 memset(mixer->mixsample, 0, 4909 memset(mixer->mixsample, 0,
4968 frametobyte(&mixer->mixfmt, frame_count)); 4910 frametobyte(&mixer->mixfmt, frame_count));
4969 } else { 4911 } else {
4970 if (mixed > 1) { 4912 if (mixed > 1) {
4971 /* If there are multiple tracks, do auto gain control */ 4913 /* If there are multiple tracks, do auto gain control */
4972 audio_pmixer_agc(mixer, sample_count); 4914 audio_pmixer_agc(mixer, sample_count);
4973 } 4915 }
4974 4916
4975 /* Apply master volume */ 4917 /* Apply master volume */
4976 if (mixer->volume < 256) { 4918 if (mixer->volume < 256) {
4977 m = mixer->mixsample; 4919 m = mixer->mixsample;
4978 for (i = 0; i < sample_count; i++) { 4920 for (i = 0; i < sample_count; i++) {
4979 *m = AUDIO_SCALEDOWN(*m * mixer->volume, 8); 4921 *m = AUDIO_SCALEDOWN(*m * mixer->volume, 8);
4980 m++; 4922 m++;
4981 } 4923 }
4982 4924
4983 /* 4925 /*
4984 * Recover the volume gradually at the pace of 4926 * Recover the volume gradually at the pace of
4985 * several times per second. If it's too fast, you 4927 * several times per second. If it's too fast, you
4986 * can recognize that the volume changes up and down 4928 * can recognize that the volume changes up and down
4987 * quickly and it's not so comfortable. 4929 * quickly and it's not so comfortable.
4988 */ 4930 */
4989 mixer->voltimer += mixer->blktime_n; 4931 mixer->voltimer += mixer->blktime_n;
4990 if (mixer->voltimer * 4 >= mixer->blktime_d) { 4932 if (mixer->voltimer * 4 >= mixer->blktime_d) {
4991 mixer->volume++; 4933 mixer->volume++;
4992 mixer->voltimer = 0; 4934 mixer->voltimer = 0;
4993#if defined(AUDIO_DEBUG_AGC) 4935#if defined(AUDIO_DEBUG_AGC)
4994 TRACE(1, "volume recover: %d", mixer->volume); 4936 TRACE(1, "volume recover: %d", mixer->volume);
4995#endif 4937#endif
4996 } 4938 }
4997 } 4939 }
4998 } 4940 }
4999 4941
5000 /* 4942 /*
5001 * The rest is the hardware part. 4943 * The rest is the hardware part.
5002 */ 4944 */
5003 4945
5004 if (mixer->codec) { 4946 if (mixer->codec) {
5005 h = auring_tailptr_aint(&mixer->codecbuf); 4947 h = auring_tailptr_aint(&mixer->codecbuf);
5006 } else { 4948 } else {
5007 h = auring_tailptr_aint(&mixer->hwbuf); 4949 h = auring_tailptr_aint(&mixer->hwbuf);
5008 } 4950 }
5009 4951
5010 m = mixer->mixsample; 4952 m = mixer->mixsample;
5011 if (mixer->swap_endian) { 4953 if (mixer->swap_endian) {
5012 for (i = 0; i < sample_count; i++) { 4954 for (i = 0; i < sample_count; i++) {
5013 *h++ = bswap16(*m++); 4955 *h++ = bswap16(*m++);
5014 } 4956 }
5015 } else { 4957 } else {
5016 for (i = 0; i < sample_count; i++) { 4958 for (i = 0; i < sample_count; i++) {
5017 *h++ = *m++; 4959 *h++ = *m++;
5018 } 4960 }
5019 } 4961 }
5020 4962
5021 /* Hardware driver's codec */ 4963 /* Hardware driver's codec */
5022 if (mixer->codec) { 4964 if (mixer->codec) {
5023 auring_push(&mixer->codecbuf, frame_count); 4965 auring_push(&mixer->codecbuf, frame_count);
5024 mixer->codecarg.src = auring_headptr(&mixer->codecbuf); 4966 mixer->codecarg.src = auring_headptr(&mixer->codecbuf);
5025 mixer->codecarg.dst = auring_tailptr(&mixer->hwbuf); 4967 mixer->codecarg.dst = auring_tailptr(&mixer->hwbuf);
5026 mixer->codecarg.count = frame_count; 4968 mixer->codecarg.count = frame_count;
5027 mixer->codec(&mixer->codecarg); 4969 mixer->codec(&mixer->codecarg);
5028 auring_take(&mixer->codecbuf, mixer->codecarg.count); 4970 auring_take(&mixer->codecbuf, mixer->codecarg.count);
5029 } 4971 }
5030 4972
5031 auring_push(&mixer->hwbuf, frame_count); 4973 auring_push(&mixer->hwbuf, frame_count);
5032 4974
5033 TRACE(4, "done mixseq=%d hwbuf=%d/%d/%d%s", 4975 TRACE(4, "done mixseq=%d hwbuf=%d/%d/%d%s",
5034 (int)mixer->mixseq, 4976 (int)mixer->mixseq,
5035 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity, 4977 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity,
5036 (mixed == 0) ? " silent" : ""); 4978 (mixed == 0) ? " silent" : "");
5037} 4979}
5038 4980
5039/* 4981/*
5040 * Do auto gain control. 4982 * Do auto gain control.
5041 * Must be called sc_intr_lock held. 4983 * Must be called sc_intr_lock held.
5042 */ 4984 */
5043static void 4985static void
5044audio_pmixer_agc(audio_trackmixer_t *mixer, int sample_count) 4986audio_pmixer_agc(audio_trackmixer_t *mixer, int sample_count)
5045{ 4987{
5046 struct audio_softc *sc __unused; 4988 struct audio_softc *sc __unused;
5047 aint2_t val; 4989 aint2_t val;
5048 aint2_t maxval; 4990 aint2_t maxval;
5049 aint2_t minval; 4991 aint2_t minval;
5050 aint2_t over_plus; 4992 aint2_t over_plus;
5051 aint2_t over_minus; 4993 aint2_t over_minus;
5052 aint2_t *m; 4994 aint2_t *m;
5053 int newvol; 4995 int newvol;
5054 int i; 4996 int i;
5055 4997
5056 sc = mixer->sc; 4998 sc = mixer->sc;
5057 4999
5058 /* Overflow detection */ 5000 /* Overflow detection */
5059 maxval = AINT_T_MAX; 5001 maxval = AINT_T_MAX;
5060 minval = AINT_T_MIN; 5002 minval = AINT_T_MIN;
5061 m = mixer->mixsample; 5003 m = mixer->mixsample;
5062 for (i = 0; i < sample_count; i++) { 5004 for (i = 0; i < sample_count; i++) {
5063 val = *m++; 5005 val = *m++;
5064 if (val > maxval) 5006 if (val > maxval)
5065 maxval = val; 5007 maxval = val;
5066 else if (val < minval) 5008 else if (val < minval)
5067 minval = val; 5009 minval = val;
5068 } 5010 }
5069 5011
5070 /* Absolute value of overflowed amount */ 5012 /* Absolute value of overflowed amount */
5071 over_plus = maxval - AINT_T_MAX; 5013 over_plus = maxval - AINT_T_MAX;
5072 over_minus = AINT_T_MIN - minval; 5014 over_minus = AINT_T_MIN - minval;
5073 5015
5074 if (over_plus > 0 || over_minus > 0) { 5016 if (over_plus > 0 || over_minus > 0) {
5075 if (over_plus > over_minus) { 5017 if (over_plus > over_minus) {
5076 newvol = (int)((aint2_t)AINT_T_MAX * 256 / maxval); 5018 newvol = (int)((aint2_t)AINT_T_MAX * 256 / maxval);
5077 } else { 5019 } else {
5078 newvol = (int)((aint2_t)AINT_T_MIN * 256 / minval); 5020 newvol = (int)((aint2_t)AINT_T_MIN * 256 / minval);
5079 } 5021 }
5080 5022
5081 /* 5023 /*
5082 * Change the volume only if new one is smaller. 5024 * Change the volume only if new one is smaller.
5083 * Reset the timer even if the volume isn't changed. 5025 * Reset the timer even if the volume isn't changed.
5084 */ 5026 */
5085 if (newvol <= mixer->volume) { 5027 if (newvol <= mixer->volume) {
5086 mixer->volume = newvol; 5028 mixer->volume = newvol;
5087 mixer->voltimer = 0; 5029 mixer->voltimer = 0;
5088#if defined(AUDIO_DEBUG_AGC) 5030#if defined(AUDIO_DEBUG_AGC)
5089 TRACE(1, "auto volume adjust: %d", mixer->volume); 5031 TRACE(1, "auto volume adjust: %d", mixer->volume);
5090#endif 5032#endif
5091 } 5033 }
5092 } 5034 }
5093} 5035}
5094 5036
5095/* 5037/*
5096 * Mix one track. 5038 * Mix one track.
5097 * 'mixed' specifies the number of tracks mixed so far. 5039 * 'mixed' specifies the number of tracks mixed so far.
5098 * It returns the number of tracks mixed. In other words, it returns 5040 * It returns the number of tracks mixed. In other words, it returns
5099 * mixed + 1 if this track is mixed. 5041 * mixed + 1 if this track is mixed.
5100 */ 5042 */
5101static int 5043static int
5102audio_pmixer_mix_track(audio_trackmixer_t *mixer, audio_track_t *track, 5044audio_pmixer_mix_track(audio_trackmixer_t *mixer, audio_track_t *track,
5103 int mixed) 5045 int mixed)
5104{ 5046{
5105 int count; 5047 int count;
5106 int sample_count; 5048 int sample_count;
5107 int remain; 5049 int remain;
5108 int i; 5050 int i;
5109 const aint_t *s; 5051 const aint_t *s;
5110 aint2_t *d; 5052 aint2_t *d;
5111 5053
5112 /* XXX TODO: Is this necessary for now? */ 5054 /* XXX TODO: Is this necessary for now? */
5113 if (mixer->mixseq < track->seq) 5055 if (mixer->mixseq < track->seq)
5114 return mixed; 5056 return mixed;
5115 5057
5116 count = auring_get_contig_used(&track->outbuf); 5058 count = auring_get_contig_used(&track->outbuf);
5117 count = uimin(count, mixer->frames_per_block); 5059 count = uimin(count, mixer->frames_per_block);
5118 5060
5119 s = auring_headptr_aint(&track->outbuf); 5061 s = auring_headptr_aint(&track->outbuf);
5120 d = mixer->mixsample; 5062 d = mixer->mixsample;
5121 5063
5122 /* 5064 /*
5123 * Apply track volume with double-sized integer and perform 5065 * Apply track volume with double-sized integer and perform
5124 * additive synthesis. 5066 * additive synthesis.
5125 * 5067 *
5126 * XXX If you limit the track volume to 1.0 or less (<= 256), 5068 * XXX If you limit the track volume to 1.0 or less (<= 256),
5127 * it would be better to do this in the track conversion stage 5069 * it would be better to do this in the track conversion stage
5128 * rather than here. However, if you accept the volume to 5070 * rather than here. However, if you accept the volume to
5129 * be greater than 1.0 (> 256), it's better to do it here. 5071 * be greater than 1.0 (> 256), it's better to do it here.
5130 * Because the operation here is done by double-sized integer. 5072 * Because the operation here is done by double-sized integer.
5131 */ 5073 */
5132 sample_count = count * mixer->mixfmt.channels; 5074 sample_count = count * mixer->mixfmt.channels;
5133 if (mixed == 0) { 5075 if (mixed == 0) {
5134 /* If this is the first track, assignment can be used. */ 5076 /* If this is the first track, assignment can be used. */
5135#if defined(AUDIO_SUPPORT_TRACK_VOLUME) 5077#if defined(AUDIO_SUPPORT_TRACK_VOLUME)
5136 if (track->volume != 256) { 5078 if (track->volume != 256) {
5137 for (i = 0; i < sample_count; i++) { 5079 for (i = 0; i < sample_count; i++) {
5138 aint2_t v; 5080 aint2_t v;
5139 v = *s++; 5081 v = *s++;
5140 *d++ = AUDIO_SCALEDOWN(v * track->volume, 8) 5082 *d++ = AUDIO_SCALEDOWN(v * track->volume, 8)
5141 } 5083 }
5142 } else 5084 } else
5143#endif 5085#endif
5144 { 5086 {
5145 for (i = 0; i < sample_count; i++) { 5087 for (i = 0; i < sample_count; i++) {
5146 *d++ = ((aint2_t)*s++); 5088 *d++ = ((aint2_t)*s++);
5147 } 5089 }
5148 } 5090 }
5149 /* Fill silence if the first track is not filled. */ 5091 /* Fill silence if the first track is not filled. */
5150 for (; i < mixer->frames_per_block * mixer->mixfmt.channels; i++) 5092 for (; i < mixer->frames_per_block * mixer->mixfmt.channels; i++)
5151 *d++ = 0; 5093 *d++ = 0;
5152 } else { 5094 } else {
5153 /* If this is the second or later, add it. */ 5095 /* If this is the second or later, add it. */
5154#if defined(AUDIO_SUPPORT_TRACK_VOLUME) 5096#if defined(AUDIO_SUPPORT_TRACK_VOLUME)
5155 if (track->volume != 256) { 5097 if (track->volume != 256) {
5156 for (i = 0; i < sample_count; i++) { 5098 for (i = 0; i < sample_count; i++) {
5157 aint2_t v; 5099 aint2_t v;
5158 v = *s++; 5100 v = *s++;
5159 *d++ += AUDIO_SCALEDOWN(v * track->volume, 8); 5101 *d++ += AUDIO_SCALEDOWN(v * track->volume, 8);
5160 } 5102 }
5161 } else 5103 } else
5162#endif 5104#endif
5163 { 5105 {
5164 for (i = 0; i < sample_count; i++) { 5106 for (i = 0; i < sample_count; i++) {
5165 *d++ += ((aint2_t)*s++); 5107 *d++ += ((aint2_t)*s++);
5166 } 5108 }
5167 } 5109 }
5168 } 5110 }
5169 5111
5170 auring_take(&track->outbuf, count); 5112 auring_take(&track->outbuf, count);
5171 /* 5113 /*
5172 * The counters have to align block even if outbuf is less than 5114 * The counters have to align block even if outbuf is less than
5173 * one block. XXX Is this still necessary? 5115 * one block. XXX Is this still necessary?
5174 */ 5116 */
5175 remain = mixer->frames_per_block - count; 5117 remain = mixer->frames_per_block - count;
5176 if (__predict_false(remain != 0)) { 5118 if (__predict_false(remain != 0)) {
5177 auring_push(&track->outbuf, remain); 5119 auring_push(&track->outbuf, remain);
5178 auring_take(&track->outbuf, remain); 5120 auring_take(&track->outbuf, remain);
5179 } 5121 }
5180 5122
5181 /* 5123 /*
5182 * Update track sequence. 5124 * Update track sequence.
5183 * mixseq has previous value yet at this point. 5125 * mixseq has previous value yet at this point.
5184 */ 5126 */
5185 track->seq = mixer->mixseq + 1; 5127 track->seq = mixer->mixseq + 1;
5186 5128
5187 return mixed + 1; 5129 return mixed + 1;
5188} 5130}
5189 5131
5190/* 5132/*
5191 * Output one block from hwbuf to HW. 5133 * Output one block from hwbuf to HW.
5192 * Must be called with sc_intr_lock held. 5134 * Must be called with sc_intr_lock held.
5193 */ 5135 */
5194static void 5136static void
5195audio_pmixer_output(struct audio_softc *sc) 5137audio_pmixer_output(struct audio_softc *sc)
5196{ 5138{
5197 audio_trackmixer_t *mixer; 5139 audio_trackmixer_t *mixer;
5198 audio_params_t params; 5140 audio_params_t params;
5199 void *start; 5141 void *start;
5200 void *end; 5142 void *end;
5201 int blksize; 5143 int blksize;
5202 int error; 5144 int error;
5203 5145
5204 mixer = sc->sc_pmixer; 5146 mixer = sc->sc_pmixer;
5205 TRACE(4, "pbusy=%d hwbuf=%d/%d/%d", 5147 TRACE(4, "pbusy=%d hwbuf=%d/%d/%d",
5206 sc->sc_pbusy, 5148 sc->sc_pbusy,
5207 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5149 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5208 KASSERT(mixer->hwbuf.used >= mixer->frames_per_block); 5150 KASSERT(mixer->hwbuf.used >= mixer->frames_per_block);
5209 5151
5210 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); 5152 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
5211 5153
5212 if (sc->hw_if->trigger_output) { 5154 if (sc->hw_if->trigger_output) {
5213 /* trigger (at once) */ 5155 /* trigger (at once) */
5214 if (!sc->sc_pbusy) { 5156 if (!sc->sc_pbusy) {
5215 start = mixer->hwbuf.mem; 5157 start = mixer->hwbuf.mem;
5216 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf); 5158 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
5217 params = format2_to_params(&mixer->hwbuf.fmt); 5159 params = format2_to_params(&mixer->hwbuf.fmt);
5218 5160
5219 error = sc->hw_if->trigger_output(sc->hw_hdl, 5161 error = sc->hw_if->trigger_output(sc->hw_hdl,
5220 start, end, blksize, audio_pintr, sc, &params); 5162 start, end, blksize, audio_pintr, sc, &params);
5221 if (error) { 5163 if (error) {
5222 device_printf(sc->sc_dev, 5164 device_printf(sc->sc_dev,
5223 "trigger_output failed with %d\n", error); 5165 "trigger_output failed with %d\n", error);
5224 return; 5166 return;
5225 } 5167 }
5226 } 5168 }
5227 } else { 5169 } else {
5228 /* start (everytime) */ 5170 /* start (everytime) */
5229 start = auring_headptr(&mixer->hwbuf); 5171 start = auring_headptr(&mixer->hwbuf);
5230 5172
5231 error = sc->hw_if->start_output(sc->hw_hdl, 5173 error = sc->hw_if->start_output(sc->hw_hdl,
5232 start, blksize, audio_pintr, sc); 5174 start, blksize, audio_pintr, sc);
5233 if (error) { 5175 if (error) {
5234 device_printf(sc->sc_dev, 5176 device_printf(sc->sc_dev,
5235 "start_output failed with %d\n", error); 5177 "start_output failed with %d\n", error);
5236 return; 5178 return;
5237 } 5179 }
5238 } 5180 }
5239} 5181}
5240 5182
5241/* 5183/*
5242 * This is an interrupt handler for playback. 5184 * This is an interrupt handler for playback.
5243 * It is called with sc_intr_lock held. 5185 * It is called with sc_intr_lock held.
5244 * 5186 *
5245 * It is usually called from hardware interrupt. However, note that 5187 * It is usually called from hardware interrupt. However, note that
5246 * for some drivers (e.g. uaudio) it is called from software interrupt. 5188 * for some drivers (e.g. uaudio) it is called from software interrupt.
5247 */ 5189 */
5248static void 5190static void
5249audio_pintr(void *arg) 5191audio_pintr(void *arg)
5250{ 5192{
5251 struct audio_softc *sc; 5193 struct audio_softc *sc;
5252 audio_trackmixer_t *mixer; 5194 audio_trackmixer_t *mixer;
5253 5195
5254 sc = arg; 5196 sc = arg;
5255 KASSERT(mutex_owned(sc->sc_intr_lock)); 5197 KASSERT(mutex_owned(sc->sc_intr_lock));
5256 5198
5257 if (sc->sc_dying) 5199 if (sc->sc_dying)
5258 return; 5200 return;
5259#if defined(DIAGNOSTIC) 5201#if defined(DIAGNOSTIC)
5260 if (sc->sc_pbusy == false) { 5202 if (sc->sc_pbusy == false) {
5261 device_printf(sc->sc_dev, "stray interrupt\n"); 5203 device_printf(sc->sc_dev, "stray interrupt\n");
5262 return; 5204 return;
5263 } 5205 }
5264#endif 5206#endif
5265 5207
5266 mixer = sc->sc_pmixer; 5208 mixer = sc->sc_pmixer;
5267 mixer->hw_complete_counter += mixer->frames_per_block; 5209 mixer->hw_complete_counter += mixer->frames_per_block;
5268 mixer->hwseq++; 5210 mixer->hwseq++;
5269 5211
5270 auring_take(&mixer->hwbuf, mixer->frames_per_block); 5212 auring_take(&mixer->hwbuf, mixer->frames_per_block);
5271 5213
5272 TRACE(4, 5214 TRACE(4,
5273 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d", 5215 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
5274 mixer->hwseq, mixer->hw_complete_counter, 5216 mixer->hwseq, mixer->hw_complete_counter,
5275 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5217 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5276 5218
5277#if !defined(_KERNEL) 5219#if !defined(_KERNEL)
5278 /* This is a debug code for userland test. */ 5220 /* This is a debug code for userland test. */
5279 return; 5221 return;
5280#endif 5222#endif
5281 5223
5282#if defined(AUDIO_HW_SINGLE_BUFFER) 5224#if defined(AUDIO_HW_SINGLE_BUFFER)
5283 /* 5225 /*
5284 * Create a new block here and output it immediately. 5226 * Create a new block here and output it immediately.
5285 * It makes a latency lower but needs machine power. 5227 * It makes a latency lower but needs machine power.
5286 */ 5228 */
5287 audio_pmixer_process(sc); 5229 audio_pmixer_process(sc);
5288 audio_pmixer_output(sc); 5230 audio_pmixer_output(sc);
5289#else 5231#else
5290 /* 5232 /*
5291 * It is called when block N output is done. 5233 * It is called when block N output is done.
5292 * Output immediately block N+1 created by the last interrupt. 5234 * Output immediately block N+1 created by the last interrupt.
5293 * And then create block N+2 for the next interrupt. 5235 * And then create block N+2 for the next interrupt.
5294 * This method makes playback robust even on slower machines. 5236 * This method makes playback robust even on slower machines.
5295 * Instead the latency is increased by one block. 5237 * Instead the latency is increased by one block.
5296 */ 5238 */
5297 5239
5298 /* At first, output ready block. */ 5240 /* At first, output ready block. */
5299 if (mixer->hwbuf.used >= mixer->frames_per_block) { 5241 if (mixer->hwbuf.used >= mixer->frames_per_block) {
5300 audio_pmixer_output(sc); 5242 audio_pmixer_output(sc);
5301 } 5243 }
5302 5244
5303 bool later = false; 5245 bool later = false;
5304 5246
5305 if (mixer->hwbuf.used < mixer->frames_per_block) { 5247 if (mixer->hwbuf.used < mixer->frames_per_block) {
5306 later = true; 5248 later = true;
5307 } 5249 }
5308 5250
5309 /* Then, process next block. */ 5251 /* Then, process next block. */
5310 audio_pmixer_process(sc); 5252 audio_pmixer_process(sc);
5311 5253
5312 if (later) { 5254 if (later) {
5313 audio_pmixer_output(sc); 5255 audio_pmixer_output(sc);
5314 } 5256 }
5315#endif 5257#endif
5316 5258
5317 /* 5259 /*
5318 * When this interrupt is the real hardware interrupt, disabling 5260 * When this interrupt is the real hardware interrupt, disabling
5319 * preemption here is not necessary. But some drivers (e.g. uaudio) 5261 * preemption here is not necessary. But some drivers (e.g. uaudio)
5320 * emulate it by software interrupt, so kpreempt_disable is necessary. 5262 * emulate it by software interrupt, so kpreempt_disable is necessary.
5321 */ 5263 */
5322 kpreempt_disable(); 5264 kpreempt_disable();
5323 softint_schedule(mixer->sih); 5265 softint_schedule(mixer->sih);
5324 kpreempt_enable(); 5266 kpreempt_enable();
5325} 5267}
5326 5268
5327/* 5269/*
5328 * Starts record mixer. 5270 * Starts record mixer.
5329 * Must be called only if sc_rbusy is false. 5271 * Must be called only if sc_rbusy is false.
5330 * Must be called with sc_lock held. 5272 * Must be called with sc_lock held.
5331 * Must not be called from the interrupt context. 5273 * Must not be called from the interrupt context.
5332 */ 5274 */
5333static void 5275static void
5334audio_rmixer_start(struct audio_softc *sc) 5276audio_rmixer_start(struct audio_softc *sc)
5335{ 5277{
5336 5278
5337 KASSERT(mutex_owned(sc->sc_lock)); 5279 KASSERT(mutex_owned(sc->sc_lock));
5338 KASSERT(sc->sc_rbusy == false); 5280 KASSERT(sc->sc_rbusy == false);
5339 5281
5340 mutex_enter(sc->sc_intr_lock); 5282 mutex_enter(sc->sc_intr_lock);
5341 5283
5342 TRACE(2, "%s", (audiodebug >= 3) ? "begin" : ""); 5284 TRACE(2, "%s", (audiodebug >= 3) ? "begin" : "");
5343 audio_rmixer_input(sc); 5285 audio_rmixer_input(sc);
5344 sc->sc_rbusy = true; 5286 sc->sc_rbusy = true;
5345 TRACE(3, "end"); 5287 TRACE(3, "end");
5346 5288
5347 mutex_exit(sc->sc_intr_lock); 5289 mutex_exit(sc->sc_intr_lock);
5348} 5290}
5349 5291
5350/* 5292/*
5351 * When recording with MD filter: 5293 * When recording with MD filter:
5352 * 5294 *
5353 * hwbuf [............] NBLKHW blocks ring buffer 5295 * hwbuf [............] NBLKHW blocks ring buffer
5354 * | 5296 * |
5355 * | convert from hw format 5297 * | convert from hw format
5356 * v 5298 * v
5357 * codecbuf [....] 1 block (ring) buffer 5299 * codecbuf [....] 1 block (ring) buffer
5358 * | | 5300 * | |
5359 * v v 5301 * v v
5360 * track track ... 5302 * track track ...
5361 * 5303 *
5362 * When recording without MD filter: 5304 * When recording without MD filter:
5363 * 5305 *
5364 * hwbuf [............] NBLKHW blocks ring buffer 5306 * hwbuf [............] NBLKHW blocks ring buffer
5365 * | | 5307 * | |
5366 * v v 5308 * v v
5367 * track track ... 5309 * track track ...
5368 * 5310 *
5369 * hwbuf: HW encoding, HW precision, HW ch, HW freq. 5311 * hwbuf: HW encoding, HW precision, HW ch, HW freq.
5370 * codecbuf: slinear_NE, internal precision, HW ch, HW freq. 5312 * codecbuf: slinear_NE, internal precision, HW ch, HW freq.
5371 */ 5313 */
5372 5314
5373/* 5315/*
5374 * Distribute a recorded block to all recording tracks. 5316 * Distribute a recorded block to all recording tracks.
5375 */ 5317 */
5376static void 5318static void
5377audio_rmixer_process(struct audio_softc *sc) 5319audio_rmixer_process(struct audio_softc *sc)
5378{ 5320{
5379 audio_trackmixer_t *mixer; 5321 audio_trackmixer_t *mixer;
5380 audio_ring_t *mixersrc; 5322 audio_ring_t *mixersrc;
5381 audio_file_t *f; 5323 audio_file_t *f;
5382 aint_t *p; 5324 aint_t *p;
5383 int count; 5325 int count;
5384 int bytes; 5326 int bytes;
5385 int i; 5327 int i;
5386 5328
5387 mixer = sc->sc_rmixer; 5329 mixer = sc->sc_rmixer;
5388 5330
5389 /* 5331 /*
5390 * count is the number of frames to be retrieved this time. 5332 * count is the number of frames to be retrieved this time.
5391 * count should be one block. 5333 * count should be one block.
5392 */ 5334 */
5393 count = auring_get_contig_used(&mixer->hwbuf); 5335 count = auring_get_contig_used(&mixer->hwbuf);
5394 count = uimin(count, mixer->frames_per_block); 5336 count = uimin(count, mixer->frames_per_block);
5395 if (count <= 0) { 5337 if (count <= 0) {
5396 TRACE(4, "count %d: too short", count); 5338 TRACE(4, "count %d: too short", count);
5397 return; 5339 return;
5398 } 5340 }
5399 bytes = frametobyte(&mixer->track_fmt, count); 5341 bytes = frametobyte(&mixer->track_fmt, count);
5400 5342
5401 /* Hardware driver's codec */ 5343 /* Hardware driver's codec */
5402 if (mixer->codec) { 5344 if (mixer->codec) {
5403 mixer->codecarg.src = auring_headptr(&mixer->hwbuf); 5345 mixer->codecarg.src = auring_headptr(&mixer->hwbuf);
5404 mixer->codecarg.dst = auring_tailptr(&mixer->codecbuf); 5346 mixer->codecarg.dst = auring_tailptr(&mixer->codecbuf);
5405 mixer->codecarg.count = count; 5347 mixer->codecarg.count = count;
5406 mixer->codec(&mixer->codecarg); 5348 mixer->codec(&mixer->codecarg);
5407 auring_take(&mixer->hwbuf, mixer->codecarg.count); 5349 auring_take(&mixer->hwbuf, mixer->codecarg.count);
5408 auring_push(&mixer->codecbuf, mixer->codecarg.count); 5350 auring_push(&mixer->codecbuf, mixer->codecarg.count);
5409 mixersrc = &mixer->codecbuf; 5351 mixersrc = &mixer->codecbuf;
5410 } else { 5352 } else {
5411 mixersrc = &mixer->hwbuf; 5353 mixersrc = &mixer->hwbuf;
5412 } 5354 }
5413 5355
5414 if (mixer->swap_endian) { 5356 if (mixer->swap_endian) {
5415 /* inplace conversion */ 5357 /* inplace conversion */
5416 p = auring_headptr_aint(mixersrc); 5358 p = auring_headptr_aint(mixersrc);
5417 for (i = 0; i < count * mixer->track_fmt.channels; i++, p++) { 5359 for (i = 0; i < count * mixer->track_fmt.channels; i++, p++) {
5418 *p = bswap16(*p); 5360 *p = bswap16(*p);
5419 } 5361 }
5420 } 5362 }
5421 5363
5422 /* Distribute to all tracks. */ 5364 /* Distribute to all tracks. */
5423 SLIST_FOREACH(f, &sc->sc_files, entry) { 5365 SLIST_FOREACH(f, &sc->sc_files, entry) {
5424 audio_track_t *track = f->rtrack; 5366 audio_track_t *track = f->rtrack;
5425 audio_ring_t *input; 5367 audio_ring_t *input;
5426 5368
5427 if (track == NULL) 5369 if (track == NULL)
5428 continue; 5370 continue;
5429 5371
5430 if (track->is_pause) { 5372 if (track->is_pause) {
5431 TRACET(4, track, "skip; paused"); 5373 TRACET(4, track, "skip; paused");
5432 continue; 5374 continue;
5433 } 5375 }
5434 5376
5435 if (audio_track_lock_tryenter(track) == false) { 5377 if (audio_track_lock_tryenter(track) == false) {
5436 TRACET(4, track, "skip; in use"); 5378 TRACET(4, track, "skip; in use");
5437 continue; 5379 continue;
5438 } 5380 }
5439 5381
5440 /* If the track buffer is full, discard the oldest one? */ 5382 /* If the track buffer is full, discard the oldest one? */
5441 input = track->input; 5383 input = track->input;
5442 if (input->capacity - input->used < mixer->frames_per_block) { 5384 if (input->capacity - input->used < mixer->frames_per_block) {
5443 int drops = mixer->frames_per_block - 5385 int drops = mixer->frames_per_block -
5444 (input->capacity - input->used); 5386 (input->capacity - input->used);
5445 track->dropframes += drops; 5387 track->dropframes += drops;
5446 TRACET(4, track, "drop %d frames: inp=%d/%d/%d", 5388 TRACET(4, track, "drop %d frames: inp=%d/%d/%d",
5447 drops, 5389 drops,
5448 input->head, input->used, input->capacity); 5390 input->head, input->used, input->capacity);
5449 auring_take(input, drops); 5391 auring_take(input, drops);
5450 } 5392 }
5451 KASSERT(input->used % mixer->frames_per_block == 0); 5393 KASSERT(input->used % mixer->frames_per_block == 0);
5452 5394
5453 memcpy(auring_tailptr_aint(input), 5395 memcpy(auring_tailptr_aint(input),
5454 auring_headptr_aint(mixersrc), 5396 auring_headptr_aint(mixersrc),
5455 bytes); 5397 bytes);
5456 auring_push(input, count); 5398 auring_push(input, count);
5457 5399
5458 /* XXX sequence counter? */ 5400 /* XXX sequence counter? */
5459 5401
5460 audio_track_lock_exit(track); 5402 audio_track_lock_exit(track);
5461 } 5403 }
5462 5404
5463 auring_take(mixersrc, count); 5405 auring_take(mixersrc, count);
5464} 5406}
5465 5407
5466/* 5408/*
5467 * Input one block from HW to hwbuf. 5409 * Input one block from HW to hwbuf.
5468 * Must be called with sc_intr_lock held. 5410 * Must be called with sc_intr_lock held.
5469 */ 5411 */
5470static void 5412static void
5471audio_rmixer_input(struct audio_softc *sc) 5413audio_rmixer_input(struct audio_softc *sc)
5472{ 5414{
5473 audio_trackmixer_t *mixer; 5415 audio_trackmixer_t *mixer;
5474 audio_params_t params; 5416 audio_params_t params;
5475 void *start; 5417 void *start;
5476 void *end; 5418 void *end;
5477 int blksize; 5419 int blksize;
5478 int error; 5420 int error;
5479 5421
5480 mixer = sc->sc_rmixer; 5422 mixer = sc->sc_rmixer;
5481 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block); 5423 blksize = frametobyte(&mixer->hwbuf.fmt, mixer->frames_per_block);
5482 5424
5483 if (sc->hw_if->trigger_input) { 5425 if (sc->hw_if->trigger_input) {
5484 /* trigger (at once) */ 5426 /* trigger (at once) */
5485 if (!sc->sc_rbusy) { 5427 if (!sc->sc_rbusy) {
5486 start = mixer->hwbuf.mem; 5428 start = mixer->hwbuf.mem;
5487 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf); 5429 end = (uint8_t *)start + auring_bytelen(&mixer->hwbuf);
5488 params = format2_to_params(&mixer->hwbuf.fmt); 5430 params = format2_to_params(&mixer->hwbuf.fmt);
5489 5431
5490 error = sc->hw_if->trigger_input(sc->hw_hdl, 5432 error = sc->hw_if->trigger_input(sc->hw_hdl,
5491 start, end, blksize, audio_rintr, sc, &params); 5433 start, end, blksize, audio_rintr, sc, &params);
5492 if (error) { 5434 if (error) {
5493 device_printf(sc->sc_dev, 5435 device_printf(sc->sc_dev,
5494 "trigger_input failed with %d\n", error); 5436 "trigger_input failed with %d\n", error);
5495 return; 5437 return;
5496 } 5438 }
5497 } 5439 }
5498 } else { 5440 } else {
5499 /* start (everytime) */ 5441 /* start (everytime) */
5500 start = auring_tailptr(&mixer->hwbuf); 5442 start = auring_tailptr(&mixer->hwbuf);
5501 5443
5502 error = sc->hw_if->start_input(sc->hw_hdl, 5444 error = sc->hw_if->start_input(sc->hw_hdl,
5503 start, blksize, audio_rintr, sc); 5445 start, blksize, audio_rintr, sc);
5504 if (error) { 5446 if (error) {
5505 device_printf(sc->sc_dev, 5447 device_printf(sc->sc_dev,
5506 "start_input failed with %d\n", error); 5448 "start_input failed with %d\n", error);
5507 return; 5449 return;
5508 } 5450 }
5509 } 5451 }
5510} 5452}
5511 5453
5512/* 5454/*
5513 * This is an interrupt handler for recording. 5455 * This is an interrupt handler for recording.
5514 * It is called with sc_intr_lock. 5456 * It is called with sc_intr_lock.
5515 * 5457 *
5516 * It is usually called from hardware interrupt. However, note that 5458 * It is usually called from hardware interrupt. However, note that
5517 * for some drivers (e.g. uaudio) it is called from software interrupt. 5459 * for some drivers (e.g. uaudio) it is called from software interrupt.
5518 */ 5460 */
5519static void 5461static void
5520audio_rintr(void *arg) 5462audio_rintr(void *arg)
5521{ 5463{
5522 struct audio_softc *sc; 5464 struct audio_softc *sc;
5523 audio_trackmixer_t *mixer; 5465 audio_trackmixer_t *mixer;
5524 5466
5525 sc = arg; 5467 sc = arg;
5526 KASSERT(mutex_owned(sc->sc_intr_lock)); 5468 KASSERT(mutex_owned(sc->sc_intr_lock));
5527 5469
5528 if (sc->sc_dying) 5470 if (sc->sc_dying)
5529 return; 5471 return;
5530#if defined(DIAGNOSTIC) 5472#if defined(DIAGNOSTIC)
5531 if (sc->sc_rbusy == false) { 5473 if (sc->sc_rbusy == false) {
5532 device_printf(sc->sc_dev, "stray interrupt\n"); 5474 device_printf(sc->sc_dev, "stray interrupt\n");
5533 return; 5475 return;
5534 } 5476 }
5535#endif 5477#endif
5536 5478
5537 mixer = sc->sc_rmixer; 5479 mixer = sc->sc_rmixer;
5538 mixer->hw_complete_counter += mixer->frames_per_block; 5480 mixer->hw_complete_counter += mixer->frames_per_block;
5539 mixer->hwseq++; 5481 mixer->hwseq++;
5540 5482
5541 auring_push(&mixer->hwbuf, mixer->frames_per_block); 5483 auring_push(&mixer->hwbuf, mixer->frames_per_block);
5542 5484
5543 TRACE(4, 5485 TRACE(4,
5544 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d", 5486 "HW_INT ++hwseq=%" PRIu64 " cmplcnt=%" PRIu64 " hwbuf=%d/%d/%d",
5545 mixer->hwseq, mixer->hw_complete_counter, 5487 mixer->hwseq, mixer->hw_complete_counter,
5546 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity); 5488 mixer->hwbuf.head, mixer->hwbuf.used, mixer->hwbuf.capacity);
5547 5489
5548 /* Distrubute recorded block */ 5490 /* Distrubute recorded block */
5549 audio_rmixer_process(sc); 5491 audio_rmixer_process(sc);
5550 5492
5551 /* Request next block */ 5493 /* Request next block */
5552 audio_rmixer_input(sc); 5494 audio_rmixer_input(sc);
5553 5495
5554 /* 5496 /*
5555 * When this interrupt is the real hardware interrupt, disabling 5497 * When this interrupt is the real hardware interrupt, disabling
5556 * preemption here is not necessary. But some drivers (e.g. uaudio) 5498 * preemption here is not necessary. But some drivers (e.g. uaudio)
5557 * emulate it by software interrupt, so kpreempt_disable is necessary. 5499 * emulate it by software interrupt, so kpreempt_disable is necessary.
5558 */ 5500 */
5559 kpreempt_disable(); 5501 kpreempt_disable();
5560 softint_schedule(mixer->sih); 5502 softint_schedule(mixer->sih);
5561 kpreempt_enable(); 5503 kpreempt_enable();
5562} 5504}
5563 5505
5564/* 5506/*
5565 * Halts playback mixer. 5507 * Halts playback mixer.
5566 * This function also clears related parameters, so call this function 5508 * This function also clears related parameters, so call this function
5567 * instead of calling halt_output directly. 5509 * instead of calling halt_output directly.
5568 * Must be called only if sc_pbusy is true. 5510 * Must be called only if sc_pbusy is true.
5569 * Must be called with sc_lock && sc_exlock held. 5511 * Must be called with sc_lock && sc_exlock held.
5570 */ 5512 */
5571static int 5513static int
5572audio_pmixer_halt(struct audio_softc *sc) 5514audio_pmixer_halt(struct audio_softc *sc)
5573{ 5515{
5574 int error; 5516 int error;
5575 5517
5576 TRACE(2, ""); 5518 TRACE(2, "");
5577 KASSERT(mutex_owned(sc->sc_lock)); 5519 KASSERT(mutex_owned(sc->sc_lock));
5578 KASSERT(sc->sc_exlock); 5520 KASSERT(sc->sc_exlock);
5579 5521
5580 mutex_enter(sc->sc_intr_lock); 5522 mutex_enter(sc->sc_intr_lock);
5581 error = sc->hw_if->halt_output(sc->hw_hdl); 5523 error = sc->hw_if->halt_output(sc->hw_hdl);
5582 mutex_exit(sc->sc_intr_lock); 5524 mutex_exit(sc->sc_intr_lock);
5583 5525
5584 /* Halts anyway even if some error has occurred. */ 5526 /* Halts anyway even if some error has occurred. */
5585 sc->sc_pbusy = false; 5527 sc->sc_pbusy = false;
5586 sc->sc_pmixer->hwbuf.head = 0; 5528 sc->sc_pmixer->hwbuf.head = 0;
5587 sc->sc_pmixer->hwbuf.used = 0; 5529 sc->sc_pmixer->hwbuf.used = 0;
5588 sc->sc_pmixer->mixseq = 0; 5530 sc->sc_pmixer->mixseq = 0;
5589 sc->sc_pmixer->hwseq = 0; 5531 sc->sc_pmixer->hwseq = 0;
5590 5532
5591 return error; 5533 return error;
5592} 5534}
5593 5535
5594/* 5536/*
5595 * Halts recording mixer. 5537 * Halts recording mixer.
5596 * This function also clears related parameters, so call this function 5538 * This function also clears related parameters, so call this function
5597 * instead of calling halt_input directly. 5539 * instead of calling halt_input directly.
5598 * Must be called only if sc_rbusy is true. 5540 * Must be called only if sc_rbusy is true.
5599 * Must be called with sc_lock && sc_exlock held. 5541 * Must be called with sc_lock && sc_exlock held.
5600 */ 5542 */
5601static int 5543static int
5602audio_rmixer_halt(struct audio_softc *sc) 5544audio_rmixer_halt(struct audio_softc *sc)
5603{ 5545{
5604 int error; 5546 int error;
5605 5547
5606 TRACE(2, ""); 5548 TRACE(2, "");
5607 KASSERT(mutex_owned(sc->sc_lock)); 5549 KASSERT(mutex_owned(sc->sc_lock));
5608 KASSERT(sc->sc_exlock); 5550 KASSERT(sc->sc_exlock);
5609 5551
5610 mutex_enter(sc->sc_intr_lock); 5552 mutex_enter(sc->sc_intr_lock);
5611 error = sc->hw_if->halt_input(sc->hw_hdl); 5553 error = sc->hw_if->halt_input(sc->hw_hdl);
5612 mutex_exit(sc->sc_intr_lock); 5554 mutex_exit(sc->sc_intr_lock);
5613 5555
5614 /* Halts anyway even if some error has occurred. */ 5556 /* Halts anyway even if some error has occurred. */
5615 sc->sc_rbusy = false; 5557 sc->sc_rbusy = false;
5616 sc->sc_rmixer->hwbuf.head = 0; 5558 sc->sc_rmixer->hwbuf.head = 0;
5617 sc->sc_rmixer->hwbuf.used = 0; 5559 sc->sc_rmixer->hwbuf.used = 0;
5618 sc->sc_rmixer->mixseq = 0; 5560 sc->sc_rmixer->mixseq = 0;
5619 sc->sc_rmixer->hwseq = 0; 5561 sc->sc_rmixer->hwseq = 0;
5620 5562
5621 return error; 5563 return error;
5622} 5564}
5623 5565
5624/* 5566/*
5625 * Flush this track. 5567 * Flush this track.
5626 * Halts all operations, clears all buffers, reset error counters. 5568 * Halts all operations, clears all buffers, reset error counters.
5627 * XXX I'm not sure... 5569 * XXX I'm not sure...
5628 */ 5570 */
5629static void 5571static void
5630audio_track_clear(struct audio_softc *sc, audio_track_t *track) 5572audio_track_clear(struct audio_softc *sc, audio_track_t *track)
5631{ 5573{
5632 5574
5633 KASSERT(track); 5575 KASSERT(track);
5634 TRACET(3, track, "clear"); 5576 TRACET(3, track, "clear");
5635 5577
5636 audio_track_lock_enter(track); 5578 audio_track_lock_enter(track);
5637 5579
5638 track->usrbuf.used = 0; 5580 track->usrbuf.used = 0;
5639 /* Clear all internal parameters. */ 5581 /* Clear all internal parameters. */
5640 if (track->codec.filter) { 5582 if (track->codec.filter) {
5641 track->codec.srcbuf.used = 0; 5583 track->codec.srcbuf.used = 0;
5642 track->codec.srcbuf.head = 0; 5584 track->codec.srcbuf.head = 0;
5643 } 5585 }
5644 if (track->chvol.filter) { 5586 if (track->chvol.filter) {
5645 track->chvol.srcbuf.used = 0; 5587 track->chvol.srcbuf.used = 0;
5646 track->chvol.srcbuf.head = 0; 5588 track->chvol.srcbuf.head = 0;
5647 } 5589 }
5648 if (track->chmix.filter) { 5590 if (track->chmix.filter) {
5649 track->chmix.srcbuf.used = 0; 5591 track->chmix.srcbuf.used = 0;
5650 track->chmix.srcbuf.head = 0; 5592 track->chmix.srcbuf.head = 0;
5651 } 5593 }
5652 if (track->freq.filter) { 5594 if (track->freq.filter) {
5653 track->freq.srcbuf.used = 0; 5595 track->freq.srcbuf.used = 0;
5654 track->freq.srcbuf.head = 0; 5596 track->freq.srcbuf.head = 0;
5655 if (track->freq_step < 65536) 5597 if (track->freq_step < 65536)
5656 track->freq_current = 65536; 5598 track->freq_current = 65536;
5657 else 5599 else
5658 track->freq_current = 0; 5600 track->freq_current = 0;
5659 memset(track->freq_prev, 0, sizeof(track->freq_prev)); 5601 memset(track->freq_prev, 0, sizeof(track->freq_prev));
5660 memset(track->freq_curr, 0, sizeof(track->freq_curr)); 5602 memset(track->freq_curr, 0, sizeof(track->freq_curr));
5661 } 5603 }
5662 /* Clear buffer, then operation halts naturally. */ 5604 /* Clear buffer, then operation halts naturally. */
5663 track->outbuf.used = 0; 5605 track->outbuf.used = 0;
5664 5606
5665 /* Clear counters. */ 5607 /* Clear counters. */
5666 track->dropframes = 0; 5608 track->dropframes = 0;
5667 5609
5668 audio_track_lock_exit(track); 5610 audio_track_lock_exit(track);
5669} 5611}
5670 5612
5671/* 5613/*
5672 * Drain the track. 5614 * Drain the track.
5673 * track must be present and for playback. 5615 * track must be present and for playback.
5674 * If successful, it returns 0. Otherwise returns errno. 5616 * If successful, it returns 0. Otherwise returns errno.
5675 * Must be called with sc_lock held. 5617 * Must be called with sc_lock held.
5676 */ 5618 */
5677static int 5619static int
5678audio_track_drain(struct audio_softc *sc, audio_track_t *track) 5620audio_track_drain(struct audio_softc *sc, audio_track_t *track)
5679{ 5621{
5680 audio_trackmixer_t *mixer; 5622 audio_trackmixer_t *mixer;
5681 int done; 5623 int done;
5682 int error; 5624 int error;
5683 5625
5684 KASSERT(track); 5626 KASSERT(track);
5685 TRACET(3, track, "start"); 5627 TRACET(3, track, "start");
5686 mixer = track->mixer; 5628 mixer = track->mixer;
5687 KASSERT(mutex_owned(sc->sc_lock)); 5629 KASSERT(mutex_owned(sc->sc_lock));
5688 5630
5689 /* Ignore them if pause. */ 5631 /* Ignore them if pause. */
5690 if (track->is_pause) { 5632 if (track->is_pause) {
5691 TRACET(3, track, "pause -> clear"); 5633 TRACET(3, track, "pause -> clear");
5692 track->pstate = AUDIO_STATE_CLEAR; 5634 track->pstate = AUDIO_STATE_CLEAR;
5693 } 5635 }
5694 /* Terminate early here if there is no data in the track. */ 5636 /* Terminate early here if there is no data in the track. */
5695 if (track->pstate == AUDIO_STATE_CLEAR) { 5637 if (track->pstate == AUDIO_STATE_CLEAR) {
5696 TRACET(3, track, "no need to drain"); 5638 TRACET(3, track, "no need to drain");
5697 return 0; 5639 return 0;
5698 } 5640 }
5699 track->pstate = AUDIO_STATE_DRAINING; 5641 track->pstate = AUDIO_STATE_DRAINING;
5700 5642
5701 for (;;) { 5643 for (;;) {
5702 /* I want to display it before condition evaluation. */ 5644 /* I want to display it before condition evaluation. */
5703 TRACET(3, track, "pid=%d.%d trkseq=%d hwseq=%d out=%d/%d/%d", 5645 TRACET(3, track, "pid=%d.%d trkseq=%d hwseq=%d out=%d/%d/%d",
5704 (int)curproc->p_pid, (int)curlwp->l_lid, 5646 (int)curproc->p_pid, (int)curlwp->l_lid,
5705 (int)track->seq, (int)mixer->hwseq, 5647 (int)track->seq, (int)mixer->hwseq,
5706 track->outbuf.head, track->outbuf.used, 5648 track->outbuf.head, track->outbuf.used,
5707 track->outbuf.capacity); 5649 track->outbuf.capacity);
5708 5650
5709 /* Condition to terminate */ 5651 /* Condition to terminate */
5710 audio_track_lock_enter(track); 5652 audio_track_lock_enter(track);
5711 done = (track->usrbuf.used < frametobyte(&track->inputfmt, 1) && 5653 done = (track->usrbuf.used < frametobyte(&track->inputfmt, 1) &&
5712 track->outbuf.used == 0 && 5654 track->outbuf.used == 0 &&
5713 track->seq <= mixer->hwseq); 5655 track->seq <= mixer->hwseq);
5714 audio_track_lock_exit(track); 5656 audio_track_lock_exit(track);
5715 if (done) 5657 if (done)
5716 break; 5658 break;
5717 5659
5718 TRACET(3, track, "sleep"); 5660 TRACET(3, track, "sleep");
5719 error = audio_track_waitio(sc, track); 5661 error = audio_track_waitio(sc, track);
5720 if (error) 5662 if (error)
5721 return error; 5663 return error;
5722 5664
5723 /* XXX call audio_track_play here ? */ 5665 /* XXX call audio_track_play here ? */
5724 } 5666 }
5725 5667
5726 track->pstate = AUDIO_STATE_CLEAR; 5668 track->pstate = AUDIO_STATE_CLEAR;
5727 TRACET(3, track, "done trk_inp=%d trk_out=%d", 5669 TRACET(3, track, "done trk_inp=%d trk_out=%d",
5728 (int)track->inputcounter, (int)track->outputcounter); 5670 (int)track->inputcounter, (int)track->outputcounter);
5729 return 0; 5671 return 0;
5730} 5672}
5731 5673
5732/* 5674/*
5733 * Send signal to process. 5675 * Send signal to process.
5734 * This is intended to be called only from audio_softintr_{rd,wr}. 5676 * This is intended to be called only from audio_softintr_{rd,wr}.
5735 * Must be called with sc_lock && sc_intr_lock held. 5677 * Must be called with sc_lock && sc_intr_lock held.
5736 */ 5678 */