1 /* $NetBSD: audio.c,v 1.249 2009/12/06 22:42:48 dyoung Exp $ */
4 * Copyright (c) 1991-1993 Regents of the University of California.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the Computer Systems
18 * Engineering Group at Lawrence Berkeley Laboratory.
19 * 4. Neither the name of the University nor of the Laboratory may be used
20 * to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
39 * This code tries to do something half-way sensible with
40 * half-duplex hardware, such as with the SoundBlaster hardware. With
41 * half-duplex hardware allowing O_RDWR access doesn't really make
42 * sense. However, closing and opening the device to "turn around the
43 * line" is relatively expensive and costs a card reset (which can
44 * take some time, at least for the SoundBlaster hardware). Instead
45 * we allow O_RDWR access, and provide an ioctl to set the "mode",
46 * i.e. playing or recording.
48 * If you write to a half-duplex device in record mode, the data is
49 * tossed. If you read from the device in play mode, you get silence
50 * filled buffers at the rate at which samples are naturally
53 * If you try to set both play and record mode on a half-duplex
54 * device, playing takes precedence.
59 * - Add softaudio() isr processing for wakeup, poll, signals,
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.249 2009/12/06 22:42:48 dyoung Exp $");
69 #include <sys/param.h>
70 #include <sys/ioctl.h>
71 #include <sys/fcntl.h>
72 #include <sys/vnode.h>
73 #include <sys/select.h>
75 #include <sys/malloc.h>
77 #include <sys/systm.h>
78 #include <sys/syslog.h>
79 #include <sys/kernel.h>
80 #include <sys/signalvar.h>
82 #include <sys/audioio.h>
83 #include <sys/device.h>
86 #include <dev/audio_if.h>
87 #include <dev/audiovar.h>
89 #include <machine/endian.h>
91 /* #define AUDIO_DEBUG 1 */
93 #define DPRINTF(x) if (audiodebug) printf x
94 #define DPRINTFN(n,x) if (audiodebug>(n)) printf x
95 int audiodebug
= AUDIO_DEBUG
;
101 #define ROUNDSIZE(x) x &= -16 /* round to nice boundary */
102 #define SPECIFIED(x) (x != ~0)
103 #define SPECIFIED_CH(x) (x != (u_char)~0)
105 /* #define AUDIO_PM_IDLE */
107 int audio_idle_timeout
= 30;
110 int audio_blk_ms
= AUDIO_BLK_MS
;
112 int audiosetinfo(struct audio_softc
*, struct audio_info
*);
113 int audiogetinfo(struct audio_softc
*, struct audio_info
*, int);
115 int audio_open(dev_t
, struct audio_softc
*, int, int, struct lwp
*);
116 int audio_close(struct audio_softc
*, int, int, struct lwp
*);
117 int audio_read(struct audio_softc
*, struct uio
*, int);
118 int audio_write(struct audio_softc
*, struct uio
*, int);
119 int audio_ioctl(struct audio_softc
*, u_long
, void *, int, struct lwp
*);
120 int audio_poll(struct audio_softc
*, int, struct lwp
*);
121 int audio_kqfilter(struct audio_softc
*, struct knote
*);
122 paddr_t
audio_mmap(struct audio_softc
*, off_t
, int);
124 int mixer_open(dev_t
, struct audio_softc
*, int, int, struct lwp
*);
125 int mixer_close(struct audio_softc
*, int, int, struct lwp
*);
126 int mixer_ioctl(struct audio_softc
*, u_long
, void *, int, struct lwp
*);
127 static void mixer_remove(struct audio_softc
*, struct lwp
*);
128 static void mixer_signal(struct audio_softc
*);
130 void audio_init_record(struct audio_softc
*);
131 void audio_init_play(struct audio_softc
*);
132 int audiostartr(struct audio_softc
*);
133 int audiostartp(struct audio_softc
*);
134 void audio_rint(void *);
135 void audio_pint(void *);
136 int audio_check_params(struct audio_params
*);
138 void audio_calc_blksize(struct audio_softc
*, int);
139 void audio_fill_silence(struct audio_params
*, uint8_t *, int);
140 int audio_silence_copyout(struct audio_softc
*, int, struct uio
*);
142 void audio_init_ringbuffer(struct audio_softc
*,
143 struct audio_ringbuffer
*, int);
144 int audio_initbufs(struct audio_softc
*);
145 void audio_calcwater(struct audio_softc
*);
146 static inline int audio_sleep_timo(int *, const char *, int);
147 static inline int audio_sleep(int *, const char *);
148 static inline void audio_wakeup(int *);
149 int audio_drain(struct audio_softc
*);
150 void audio_clear(struct audio_softc
*);
151 static inline void audio_pint_silence
152 (struct audio_softc
*, struct audio_ringbuffer
*, uint8_t *, int);
155 (struct audio_softc
*, struct audio_ringbuffer
*, int, size_t);
156 void audio_free_ring(struct audio_softc
*, struct audio_ringbuffer
*);
157 static int audio_setup_pfilters(struct audio_softc
*, const audio_params_t
*,
158 stream_filter_list_t
*);
159 static int audio_setup_rfilters(struct audio_softc
*, const audio_params_t
*,
160 stream_filter_list_t
*);
161 static void audio_destruct_pfilters(struct audio_softc
*);
162 static void audio_destruct_rfilters(struct audio_softc
*);
163 static void audio_stream_dtor(audio_stream_t
*);
164 static int audio_stream_ctor(audio_stream_t
*, const audio_params_t
*, int);
165 static void stream_filter_list_append
166 (stream_filter_list_t
*, stream_filter_factory_t
,
167 const audio_params_t
*);
168 static void stream_filter_list_prepend
169 (stream_filter_list_t
*, stream_filter_factory_t
,
170 const audio_params_t
*);
171 static void stream_filter_list_set
172 (stream_filter_list_t
*, int, stream_filter_factory_t
,
173 const audio_params_t
*);
174 int audio_set_defaults(struct audio_softc
*, u_int
);
176 int audioprobe(device_t
, cfdata_t
, void *);
177 void audioattach(device_t
, device_t
, void *);
178 int audiodetach(device_t
, int);
179 int audioactivate(device_t
, enum devact
);
182 static void audio_idle(void *);
183 static void audio_activity(device_t
, devactive_t
);
186 static bool audio_suspend(device_t dv
, pmf_qual_t
);
187 static bool audio_resume(device_t dv
, pmf_qual_t
);
188 static void audio_volume_down(device_t
);
189 static void audio_volume_up(device_t
);
190 static void audio_volume_toggle(device_t
);
192 static void audio_mixer_capture(struct audio_softc
*);
193 static void audio_mixer_restore(struct audio_softc
*);
195 static int audio_get_props(struct audio_softc
*);
196 static bool audio_can_playback(struct audio_softc
*);
197 static bool audio_can_capture(struct audio_softc
*);
199 static void audio_softintr_rd(void *);
200 static void audio_softintr_wr(void *);
206 static const struct portname itable
[] = {
207 { AudioNmicrophone
, AUDIO_MICROPHONE
},
208 { AudioNline
, AUDIO_LINE_IN
},
209 { AudioNcd
, AUDIO_CD
},
212 static const struct portname otable
[] = {
213 { AudioNspeaker
, AUDIO_SPEAKER
},
214 { AudioNheadphone
, AUDIO_HEADPHONE
},
215 { AudioNline
, AUDIO_LINE_OUT
},
218 void au_setup_ports(struct audio_softc
*, struct au_mixer_ports
*,
219 mixer_devinfo_t
*, const struct portname
*);
220 int au_set_gain(struct audio_softc
*, struct au_mixer_ports
*,
222 void au_get_gain(struct audio_softc
*, struct au_mixer_ports
*,
224 int au_set_port(struct audio_softc
*, struct au_mixer_ports
*,
226 int au_get_port(struct audio_softc
*, struct au_mixer_ports
*);
227 int au_get_lr_value(struct audio_softc
*, mixer_ctrl_t
*,
229 int au_set_lr_value(struct audio_softc
*, mixer_ctrl_t
*,
231 int au_portof(struct audio_softc
*, char *, int);
233 typedef struct uio_fetcher
{
234 stream_fetcher_t base
;
240 static void uio_fetcher_ctor(uio_fetcher_t
*, struct uio
*, int);
241 static int uio_fetcher_fetch_to(stream_fetcher_t
*,
242 audio_stream_t
*, int);
243 static int null_fetcher_fetch_to(stream_fetcher_t
*,
244 audio_stream_t
*, int);
246 dev_type_open(audioopen
);
247 dev_type_close(audioclose
);
248 dev_type_read(audioread
);
249 dev_type_write(audiowrite
);
250 dev_type_ioctl(audioioctl
);
251 dev_type_poll(audiopoll
);
252 dev_type_mmap(audiommap
);
253 dev_type_kqfilter(audiokqfilter
);
255 const struct cdevsw audio_cdevsw
= {
256 audioopen
, audioclose
, audioread
, audiowrite
, audioioctl
,
257 nostop
, notty
, audiopoll
, audiommap
, audiokqfilter
, D_OTHER
260 /* The default audio mode: 8 kHz mono mu-law */
261 const struct audio_params audio_default
= {
263 .encoding
= AUDIO_ENCODING_ULAW
,
269 CFATTACH_DECL3_NEW(audio
, sizeof(struct audio_softc
),
270 audioprobe
, audioattach
, audiodetach
, audioactivate
, NULL
, NULL
,
271 DVF_DETACH_SHUTDOWN
);
273 extern struct cfdriver audio_cd
;
276 audioprobe(device_t parent
, cfdata_t match
, void *aux
)
278 struct audio_attach_args
*sa
;
281 DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n",
282 sa
->type
, sa
, sa
->hwif
));
283 return (sa
->type
== AUDIODEV_TYPE_AUDIO
) ? 1 : 0;
287 audioattach(device_t parent
, device_t self
, void *aux
)
289 struct audio_softc
*sc
;
290 struct audio_attach_args
*sa
;
291 const struct audio_hw_if
*hwp
;
295 int iclass
, mclass
, oclass
, rclass
, props
;
296 int record_master_found
, record_source_found
;
298 sc
= device_private(self
);
305 hwp
->query_encoding
== 0 ||
306 hwp
->set_params
== 0 ||
307 (hwp
->start_output
== 0 && hwp
->trigger_output
== 0) ||
308 (hwp
->start_input
== 0 && hwp
->trigger_input
== 0) ||
309 hwp
->halt_output
== 0 ||
310 hwp
->halt_input
== 0 ||
312 hwp
->set_port
== 0 ||
313 hwp
->get_port
== 0 ||
314 hwp
->query_devinfo
== 0 ||
315 hwp
->get_props
== 0) {
316 printf(": missing method\n");
326 sc
->sc_writing
= sc
->sc_waitcomp
= 0;
327 sc
->sc_lastinfovalid
= false;
329 props
= audio_get_props(sc
);
331 if (props
& AUDIO_PROP_FULLDUPLEX
)
332 aprint_normal(": full duplex");
334 aprint_normal(": half duplex");
336 if (props
& AUDIO_PROP_PLAYBACK
)
337 aprint_normal(", playback");
338 if (props
& AUDIO_PROP_CAPTURE
)
339 aprint_normal(", capture");
340 if (props
& AUDIO_PROP_MMAP
)
341 aprint_normal(", mmap");
342 if (props
& AUDIO_PROP_INDEPENDENT
)
343 aprint_normal(", independent");
348 if (audio_can_playback(sc
)) {
349 error
= audio_alloc_ring(sc
, &sc
->sc_pr
,
350 AUMODE_PLAY
, AU_RING_SIZE
);
353 aprint_error("audio: could not allocate play buffer\n");
357 if (audio_can_capture(sc
)) {
358 error
= audio_alloc_ring(sc
, &sc
->sc_rr
,
359 AUMODE_RECORD
, AU_RING_SIZE
);
361 if (sc
->sc_pr
.s
.start
!= 0)
362 audio_free_ring(sc
, &sc
->sc_pr
);
364 aprint_error("audio: could not allocate record buffer\n");
369 sc
->sc_lastgain
= 128;
371 if ((error
= audio_set_defaults(sc
, 0))) {
372 aprint_error("audioattach: audio_set_defaults() failed\n");
377 sc
->sc_sih_rd
= softint_establish(SOFTINT_SERIAL
,
378 audio_softintr_rd
, sc
);
379 sc
->sc_sih_wr
= softint_establish(SOFTINT_SERIAL
,
380 audio_softintr_wr
, sc
);
382 iclass
= mclass
= oclass
= rclass
= -1;
383 sc
->sc_inports
.index
= -1;
384 sc
->sc_inports
.master
= -1;
385 sc
->sc_inports
.nports
= 0;
386 sc
->sc_inports
.isenum
= false;
387 sc
->sc_inports
.allports
= 0;
388 sc
->sc_inports
.isdual
= false;
389 sc
->sc_inports
.mixerout
= -1;
390 sc
->sc_inports
.cur_port
= -1;
391 sc
->sc_outports
.index
= -1;
392 sc
->sc_outports
.master
= -1;
393 sc
->sc_outports
.nports
= 0;
394 sc
->sc_outports
.isenum
= false;
395 sc
->sc_outports
.allports
= 0;
396 sc
->sc_outports
.isdual
= false;
397 sc
->sc_outports
.mixerout
= -1;
398 sc
->sc_outports
.cur_port
= -1;
399 sc
->sc_monitor_port
= -1;
401 * Read through the underlying driver's list, picking out the class
402 * names from the mixer descriptions. We'll need them to decode the
403 * mixer descriptions on the next pass through the loop.
405 for(mi
.index
= 0; ; mi
.index
++) {
406 if (hwp
->query_devinfo(hdlp
, &mi
) != 0)
409 * The type of AUDIO_MIXER_CLASS merely introduces a class.
410 * All the other types describe an actual mixer.
412 if (mi
.type
== AUDIO_MIXER_CLASS
) {
413 if (strcmp(mi
.label
.name
, AudioCinputs
) == 0)
414 iclass
= mi
.mixer_class
;
415 if (strcmp(mi
.label
.name
, AudioCmonitor
) == 0)
416 mclass
= mi
.mixer_class
;
417 if (strcmp(mi
.label
.name
, AudioCoutputs
) == 0)
418 oclass
= mi
.mixer_class
;
419 if (strcmp(mi
.label
.name
, AudioCrecord
) == 0)
420 rclass
= mi
.mixer_class
;
424 * This is where we assign each control in the "audio" model, to the
425 * underlying "mixer" control. We walk through the whole list once,
426 * assigning likely candidates as we come across them.
428 record_master_found
= 0;
429 record_source_found
= 0;
430 for(mi
.index
= 0; ; mi
.index
++) {
431 if (hwp
->query_devinfo(hdlp
, &mi
) != 0)
433 if (mi
.type
== AUDIO_MIXER_CLASS
)
435 if (mi
.mixer_class
== iclass
) {
437 * AudioCinputs is only a fallback, when we don't
438 * find what we're looking for in AudioCrecord, so
439 * check the flags before accepting one of these.
441 if (strcmp(mi
.label
.name
, AudioNmaster
) == 0
442 && record_master_found
== 0)
443 sc
->sc_inports
.master
= mi
.index
;
444 if (strcmp(mi
.label
.name
, AudioNsource
) == 0
445 && record_source_found
== 0) {
446 if (mi
.type
== AUDIO_MIXER_ENUM
) {
448 for(i
= 0; i
< mi
.un
.e
.num_mem
; i
++)
449 if (strcmp(mi
.un
.e
.member
[i
].label
.name
,
450 AudioNmixerout
) == 0)
451 sc
->sc_inports
.mixerout
=
452 mi
.un
.e
.member
[i
].ord
;
454 au_setup_ports(sc
, &sc
->sc_inports
, &mi
,
457 if (strcmp(mi
.label
.name
, AudioNdac
) == 0 &&
458 sc
->sc_outports
.master
== -1)
459 sc
->sc_outports
.master
= mi
.index
;
460 } else if (mi
.mixer_class
== mclass
) {
461 if (strcmp(mi
.label
.name
, AudioNmonitor
) == 0)
462 sc
->sc_monitor_port
= mi
.index
;
463 } else if (mi
.mixer_class
== oclass
) {
464 if (strcmp(mi
.label
.name
, AudioNmaster
) == 0)
465 sc
->sc_outports
.master
= mi
.index
;
466 if (strcmp(mi
.label
.name
, AudioNselect
) == 0)
467 au_setup_ports(sc
, &sc
->sc_outports
, &mi
,
469 } else if (mi
.mixer_class
== rclass
) {
471 * These are the preferred mixers for the audio record
472 * controls, so set the flags here, but don't check.
474 if (strcmp(mi
.label
.name
, AudioNmaster
) == 0) {
475 sc
->sc_inports
.master
= mi
.index
;
476 record_master_found
= 1;
478 #if 1 /* Deprecated. Use AudioNmaster. */
479 if (strcmp(mi
.label
.name
, AudioNrecord
) == 0) {
480 sc
->sc_inports
.master
= mi
.index
;
481 record_master_found
= 1;
483 if (strcmp(mi
.label
.name
, AudioNvolume
) == 0) {
484 sc
->sc_inports
.master
= mi
.index
;
485 record_master_found
= 1;
488 if (strcmp(mi
.label
.name
, AudioNsource
) == 0) {
489 if (mi
.type
== AUDIO_MIXER_ENUM
) {
491 for(i
= 0; i
< mi
.un
.e
.num_mem
; i
++)
492 if (strcmp(mi
.un
.e
.member
[i
].label
.name
,
493 AudioNmixerout
) == 0)
494 sc
->sc_inports
.mixerout
=
495 mi
.un
.e
.member
[i
].ord
;
497 au_setup_ports(sc
, &sc
->sc_inports
, &mi
,
499 record_source_found
= 1;
503 DPRINTF(("audio_attach: inputs ports=0x%x, input master=%d, "
504 "output ports=0x%x, output master=%d\n",
505 sc
->sc_inports
.allports
, sc
->sc_inports
.master
,
506 sc
->sc_outports
.allports
, sc
->sc_outports
.master
));
508 selinit(&sc
->sc_rsel
);
509 selinit(&sc
->sc_wsel
);
512 callout_init(&sc
->sc_idle_counter
, 0);
513 callout_setfunc(&sc
->sc_idle_counter
, audio_idle
, self
);
516 if (!pmf_device_register(self
, audio_suspend
, audio_resume
))
517 aprint_error_dev(self
, "couldn't establish power handler\n");
519 if (!device_active_register(self
, audio_activity
))
520 aprint_error_dev(self
, "couldn't register activity handler\n");
523 if (!pmf_event_register(self
, PMFE_AUDIO_VOLUME_DOWN
,
524 audio_volume_down
, true))
525 aprint_error_dev(self
, "couldn't add volume down handler\n");
526 if (!pmf_event_register(self
, PMFE_AUDIO_VOLUME_UP
,
527 audio_volume_up
, true))
528 aprint_error_dev(self
, "couldn't add volume up handler\n");
529 if (!pmf_event_register(self
, PMFE_AUDIO_VOLUME_TOGGLE
,
530 audio_volume_toggle
, true))
531 aprint_error_dev(self
, "couldn't add volume toggle handler\n");
534 callout_schedule(&sc
->sc_idle_counter
, audio_idle_timeout
* hz
);
539 audioactivate(device_t self
, enum devact act
)
541 struct audio_softc
*sc
= device_private(self
);
544 case DVACT_DEACTIVATE
:
553 audiodetach(device_t self
, int flags
)
555 struct audio_softc
*sc
;
559 sc
= device_private(self
);
560 DPRINTF(("audio_detach: sc=%p flags=%d\n", sc
, flags
));
564 pmf_event_deregister(self
, PMFE_AUDIO_VOLUME_DOWN
,
565 audio_volume_down
, true);
566 pmf_event_deregister(self
, PMFE_AUDIO_VOLUME_UP
,
567 audio_volume_up
, true);
568 pmf_event_deregister(self
, PMFE_AUDIO_VOLUME_TOGGLE
,
569 audio_volume_toggle
, true);
572 callout_stop(&sc
->sc_idle_counter
);
574 device_active_deregister(self
, audio_activity
);
577 pmf_device_deregister(self
);
579 wakeup(&sc
->sc_wchan
);
580 wakeup(&sc
->sc_rchan
);
582 if (--sc
->sc_refcnt
>= 0) {
583 if (tsleep(&sc
->sc_refcnt
, PZERO
, "auddet", hz
* 120))
584 printf("audiodetach: %s didn't detach\n",
585 device_xname(sc
->dev
));
590 audio_free_ring(sc
, &sc
->sc_pr
);
591 audio_free_ring(sc
, &sc
->sc_rr
);
592 audio_destruct_pfilters(sc
);
593 audio_destruct_rfilters(sc
);
595 /* locate the major number */
596 maj
= cdevsw_lookup_major(&audio_cdevsw
);
598 /* Nuke the vnodes for any open instances (calls close). */
599 mn
= device_unit(self
);
600 vdevgone(maj
, mn
| SOUND_DEVICE
, mn
| SOUND_DEVICE
, VCHR
);
601 vdevgone(maj
, mn
| AUDIO_DEVICE
, mn
| AUDIO_DEVICE
, VCHR
);
602 vdevgone(maj
, mn
| AUDIOCTL_DEVICE
, mn
| AUDIOCTL_DEVICE
, VCHR
);
603 vdevgone(maj
, mn
| MIXER_DEVICE
, mn
| MIXER_DEVICE
, VCHR
);
606 softint_disestablish(sc
->sc_sih_rd
);
607 sc
->sc_sih_rd
= NULL
;
610 softint_disestablish(sc
->sc_sih_wr
);
611 sc
->sc_sih_wr
= NULL
;
615 callout_destroy(&sc
->sc_idle_counter
);
617 seldestroy(&sc
->sc_rsel
);
618 seldestroy(&sc
->sc_wsel
);
624 au_portof(struct audio_softc
*sc
, char *name
, int class)
629 sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) == 0;
631 if (mi
.mixer_class
== class && strcmp(mi
.label
.name
, name
) == 0)
637 au_setup_ports(struct audio_softc
*sc
, struct au_mixer_ports
*ports
,
638 mixer_devinfo_t
*mi
, const struct portname
*tbl
)
642 ports
->index
= mi
->index
;
643 if (mi
->type
== AUDIO_MIXER_ENUM
) {
644 ports
->isenum
= true;
645 for(i
= 0; tbl
[i
].name
; i
++)
646 for(j
= 0; j
< mi
->un
.e
.num_mem
; j
++)
647 if (strcmp(mi
->un
.e
.member
[j
].label
.name
,
649 ports
->allports
|= tbl
[i
].mask
;
650 ports
->aumask
[ports
->nports
] = tbl
[i
].mask
;
651 ports
->misel
[ports
->nports
] =
652 mi
->un
.e
.member
[j
].ord
;
653 ports
->miport
[ports
->nports
] =
654 au_portof(sc
, mi
->un
.e
.member
[j
].label
.name
,
656 if (ports
->mixerout
!= -1 &&
657 ports
->miport
[ports
->nports
] != -1)
658 ports
->isdual
= true;
661 } else if (mi
->type
== AUDIO_MIXER_SET
) {
662 for(i
= 0; tbl
[i
].name
; i
++)
663 for(j
= 0; j
< mi
->un
.s
.num_mem
; j
++)
664 if (strcmp(mi
->un
.s
.member
[j
].label
.name
,
666 ports
->allports
|= tbl
[i
].mask
;
667 ports
->aumask
[ports
->nports
] = tbl
[i
].mask
;
668 ports
->misel
[ports
->nports
] =
669 mi
->un
.s
.member
[j
].mask
;
670 ports
->miport
[ports
->nports
] =
671 au_portof(sc
, mi
->un
.s
.member
[j
].label
.name
,
679 * Called from hardware driver. This is where the MI audio driver gets
680 * probed/attached to the hardware driver.
683 audio_attach_mi(const struct audio_hw_if
*ahwp
, void *hdlp
, device_t dev
)
685 struct audio_attach_args arg
;
689 aprint_error("audio_attach_mi: NULL\n");
693 arg
.type
= AUDIODEV_TYPE_AUDIO
;
696 return config_found(dev
, &arg
, audioprint
);
700 void audio_printsc(struct audio_softc
*);
701 void audio_print_params(const char *, struct audio_params
*);
704 audio_printsc(struct audio_softc
*sc
)
706 printf("hwhandle %p hw_if %p ", sc
->hw_hdl
, sc
->hw_if
);
707 printf("open 0x%x mode 0x%x\n", sc
->sc_open
, sc
->sc_mode
);
708 printf("rchan 0x%x wchan 0x%x ", sc
->sc_rchan
, sc
->sc_wchan
);
709 printf("rring used 0x%x pring used=%d\n",
710 audio_stream_get_used(&sc
->sc_rr
.s
),
711 audio_stream_get_used(&sc
->sc_pr
.s
));
712 printf("rbus 0x%x pbus 0x%x ", sc
->sc_rbus
, sc
->sc_pbus
);
713 printf("blksize %d", sc
->sc_pr
.blksize
);
714 printf("hiwat %d lowat %d\n", sc
->sc_pr
.usedhigh
, sc
->sc_pr
.usedlow
);
718 audio_print_params(const char *s
, struct audio_params
*p
)
720 printf("%s enc=%u %uch %u/%ubit %uHz\n", s
, p
->encoding
, p
->channels
,
721 p
->validbits
, p
->precision
, p
->sample_rate
);
726 audio_alloc_ring(struct audio_softc
*sc
, struct audio_ringbuffer
*r
,
727 int direction
, size_t bufsize
)
729 const struct audio_hw_if
*hw
;
735 * Alloc DMA play and record buffers
737 if (bufsize
< AUMINBUF
)
740 if (hw
->round_buffersize
)
741 bufsize
= hw
->round_buffersize(hdl
, direction
, bufsize
);
743 r
->s
.start
= hw
->allocm(hdl
, direction
, bufsize
,
746 r
->s
.start
= malloc(bufsize
, M_DEVBUF
, M_WAITOK
);
749 r
->s
.bufsize
= bufsize
;
754 audio_free_ring(struct audio_softc
*sc
, struct audio_ringbuffer
*r
)
759 if (sc
->hw_if
->freem
)
760 sc
->hw_if
->freem(sc
->hw_hdl
, r
->s
.start
, M_DEVBUF
);
762 free(r
->s
.start
, M_DEVBUF
);
767 audio_setup_pfilters(struct audio_softc
*sc
, const audio_params_t
*pp
,
768 stream_filter_list_t
*pfilters
)
770 stream_filter_t
*pf
[AUDIO_MAX_FILTERS
];
771 audio_stream_t ps
[AUDIO_MAX_FILTERS
];
772 const audio_params_t
*from_param
;
773 audio_params_t
*to_param
;
776 while (sc
->sc_writing
) {
778 (void)tsleep(sc
, 0, "audioch", 10*hz
);
781 memset(pf
, 0, sizeof(pf
));
782 memset(ps
, 0, sizeof(ps
));
784 for (i
= 0; i
< pfilters
->req_size
; i
++) {
785 n
= pfilters
->req_size
- i
- 1;
786 to_param
= &pfilters
->filters
[n
].param
;
787 audio_check_params(to_param
);
788 pf
[i
] = pfilters
->filters
[n
].factory(sc
, from_param
, to_param
);
791 if (audio_stream_ctor(&ps
[i
], from_param
, AU_RING_SIZE
))
794 pf
[i
]->set_fetcher(pf
[i
], &pf
[i
- 1]->base
);
795 from_param
= to_param
;
797 if (i
< pfilters
->req_size
) { /* failure */
798 DPRINTF(("%s: pfilters failure\n", __func__
));
799 for (; i
>= 0; i
--) {
802 audio_stream_dtor(&ps
[i
]);
808 audio_destruct_pfilters(sc
);
809 memcpy(sc
->sc_pfilters
, pf
, sizeof(pf
));
810 memcpy(sc
->sc_pstreams
, ps
, sizeof(ps
));
811 sc
->sc_npfilters
= pfilters
->req_size
;
812 for (i
= 0; i
< pfilters
->req_size
; i
++) {
813 pf
[i
]->set_inputbuffer(pf
[i
], &sc
->sc_pstreams
[i
]);
816 /* hardware format and the buffer near to userland */
817 if (pfilters
->req_size
<= 0) {
818 sc
->sc_pr
.s
.param
= *pp
;
819 sc
->sc_pustream
= &sc
->sc_pr
.s
;
821 sc
->sc_pr
.s
.param
= pfilters
->filters
[0].param
;
822 sc
->sc_pustream
= &sc
->sc_pstreams
[0];
825 printf("%s: HW-buffer=%p pustream=%p\n",
826 __func__
, &sc
->sc_pr
.s
, sc
->sc_pustream
);
827 for (i
= 0; i
< pfilters
->req_size
; i
++) {
829 snprintf(num
, 100, "[%d]", i
);
830 audio_print_params(num
, &sc
->sc_pstreams
[i
].param
);
832 audio_print_params("[HW]", &sc
->sc_pr
.s
.param
);
833 #endif /* AUDIO_DEBUG */
840 audio_setup_rfilters(struct audio_softc
*sc
, const audio_params_t
*rp
,
841 stream_filter_list_t
*rfilters
)
843 stream_filter_t
*rf
[AUDIO_MAX_FILTERS
];
844 audio_stream_t rs
[AUDIO_MAX_FILTERS
];
845 const audio_params_t
*to_param
;
846 audio_params_t
*from_param
;
849 memset(rf
, 0, sizeof(rf
));
850 memset(rs
, 0, sizeof(rs
));
851 for (i
= 0; i
< rfilters
->req_size
; i
++) {
852 from_param
= &rfilters
->filters
[i
].param
;
853 audio_check_params(from_param
);
854 to_param
= i
+ 1 < rfilters
->req_size
855 ? &rfilters
->filters
[i
+ 1].param
: rp
;
856 rf
[i
] = rfilters
->filters
[i
].factory(sc
, from_param
, to_param
);
859 if (audio_stream_ctor(&rs
[i
], to_param
, AU_RING_SIZE
))
862 rf
[i
]->set_fetcher(rf
[i
], &rf
[i
- 1]->base
);
864 /* rf[0] has no previous fetcher because
865 * the audio hardware fills data to the
867 rf
[0]->set_inputbuffer(rf
[0], &sc
->sc_rr
.s
);
870 if (i
< rfilters
->req_size
) { /* failure */
871 DPRINTF(("%s: rfilters failure\n", __func__
));
872 for (; i
>= 0; i
--) {
875 audio_stream_dtor(&rs
[i
]);
880 audio_destruct_rfilters(sc
);
881 memcpy(sc
->sc_rfilters
, rf
, sizeof(rf
));
882 memcpy(sc
->sc_rstreams
, rs
, sizeof(rs
));
883 sc
->sc_nrfilters
= rfilters
->req_size
;
884 for (i
= 1; i
< rfilters
->req_size
; i
++) {
885 rf
[i
]->set_inputbuffer(rf
[i
], &sc
->sc_rstreams
[i
- 1]);
888 /* hardware format and the buffer near to userland */
889 if (rfilters
->req_size
<= 0) {
890 sc
->sc_rr
.s
.param
= *rp
;
891 sc
->sc_rustream
= &sc
->sc_rr
.s
;
893 sc
->sc_rr
.s
.param
= rfilters
->filters
[0].param
;
894 sc
->sc_rustream
= &sc
->sc_rstreams
[rfilters
->req_size
- 1];
897 printf("%s: HW-buffer=%p pustream=%p\n",
898 __func__
, &sc
->sc_rr
.s
, sc
->sc_rustream
);
899 audio_print_params("[HW]", &sc
->sc_rr
.s
.param
);
900 for (i
= 0; i
< rfilters
->req_size
; i
++) {
902 snprintf(num
, 100, "[%d]", i
);
903 audio_print_params(num
, &sc
->sc_rstreams
[i
].param
);
905 #endif /* AUDIO_DEBUG */
910 audio_destruct_pfilters(struct audio_softc
*sc
)
914 for (i
= 0; i
< sc
->sc_npfilters
; i
++) {
915 sc
->sc_pfilters
[i
]->dtor(sc
->sc_pfilters
[i
]);
916 sc
->sc_pfilters
[i
] = NULL
;
917 audio_stream_dtor(&sc
->sc_pstreams
[i
]);
919 sc
->sc_npfilters
= 0;
923 audio_destruct_rfilters(struct audio_softc
*sc
)
927 for (i
= 0; i
< sc
->sc_nrfilters
; i
++) {
928 sc
->sc_rfilters
[i
]->dtor(sc
->sc_rfilters
[i
]);
929 sc
->sc_rfilters
[i
] = NULL
;
930 audio_stream_dtor(&sc
->sc_rstreams
[i
]);
932 sc
->sc_nrfilters
= 0;
936 audio_stream_dtor(audio_stream_t
*stream
)
939 if (stream
->start
!= NULL
)
940 free(stream
->start
, M_DEVBUF
);
941 memset(stream
, 0, sizeof(audio_stream_t
));
945 audio_stream_ctor(audio_stream_t
*stream
, const audio_params_t
*param
, int size
)
949 size
= min(size
, AU_RING_SIZE
);
950 stream
->bufsize
= size
;
951 stream
->start
= malloc(size
, M_DEVBUF
, M_NOWAIT
);
952 if (stream
->start
== NULL
)
954 frame_size
= (param
->precision
+ 7) / 8 * param
->channels
;
955 size
= (size
/ frame_size
) * frame_size
;
956 stream
->end
= stream
->start
+ size
;
957 stream
->inp
= stream
->start
;
958 stream
->outp
= stream
->start
;
960 stream
->param
= *param
;
961 stream
->loop
= false;
966 stream_filter_list_append(stream_filter_list_t
*list
,
967 stream_filter_factory_t factory
,
968 const audio_params_t
*param
)
971 if (list
->req_size
>= AUDIO_MAX_FILTERS
) {
972 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
976 list
->filters
[list
->req_size
].factory
= factory
;
977 list
->filters
[list
->req_size
].param
= *param
;
982 stream_filter_list_set(stream_filter_list_t
*list
, int i
,
983 stream_filter_factory_t factory
,
984 const audio_params_t
*param
)
987 if (i
< 0 || i
>= AUDIO_MAX_FILTERS
) {
988 printf("%s: invalid index: %d\n", __func__
, i
);
992 list
->filters
[i
].factory
= factory
;
993 list
->filters
[i
].param
= *param
;
994 if (list
->req_size
<= i
)
995 list
->req_size
= i
+ 1;
999 stream_filter_list_prepend(stream_filter_list_t
*list
,
1000 stream_filter_factory_t factory
,
1001 const audio_params_t
*param
)
1004 if (list
->req_size
>= AUDIO_MAX_FILTERS
) {
1005 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
1009 memmove(&list
->filters
[1], &list
->filters
[0],
1010 sizeof(struct stream_filter_req
) * list
->req_size
);
1011 list
->filters
[0].factory
= factory
;
1012 list
->filters
[0].param
= *param
;
1017 audioopen(dev_t dev
, int flags
, int ifmt
, struct lwp
*l
)
1019 struct audio_softc
*sc
;
1022 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1029 device_active(sc
->dev
, DVA_SYSTEM
);
1034 switch (AUDIODEV(dev
)) {
1037 error
= audio_open(dev
, sc
, flags
, ifmt
, l
);
1039 case AUDIOCTL_DEVICE
:
1043 error
= mixer_open(dev
, sc
, flags
, ifmt
, l
);
1049 if (--sc
->sc_refcnt
< 0)
1050 wakeup(&sc
->sc_refcnt
);
1055 audioclose(dev_t dev
, int flags
, int ifmt
, struct lwp
*l
)
1057 struct audio_softc
*sc
;
1060 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1062 device_active(sc
->dev
, DVA_SYSTEM
);
1064 switch (AUDIODEV(dev
)) {
1067 error
= audio_close(sc
, flags
, ifmt
, l
);
1070 error
= mixer_close(sc
, flags
, ifmt
, l
);
1072 case AUDIOCTL_DEVICE
:
1086 audioread(dev_t dev
, struct uio
*uio
, int ioflag
)
1088 struct audio_softc
*sc
;
1091 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1099 switch (AUDIODEV(dev
)) {
1102 error
= audio_read(sc
, uio
, ioflag
);
1104 case AUDIOCTL_DEVICE
:
1112 if (--sc
->sc_refcnt
< 0)
1113 wakeup(&sc
->sc_refcnt
);
1118 audiowrite(dev_t dev
, struct uio
*uio
, int ioflag
)
1120 struct audio_softc
*sc
;
1123 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1131 switch (AUDIODEV(dev
)) {
1134 error
= audio_write(sc
, uio
, ioflag
);
1136 case AUDIOCTL_DEVICE
:
1144 if (--sc
->sc_refcnt
< 0)
1145 wakeup(&sc
->sc_refcnt
);
1150 audioioctl(dev_t dev
, u_long cmd
, void *addr
, int flag
, struct lwp
*l
)
1152 struct audio_softc
*sc
;
1155 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1160 switch (AUDIODEV(dev
)) {
1163 case AUDIOCTL_DEVICE
:
1164 device_active(sc
->dev
, DVA_SYSTEM
);
1165 if (IOCGROUP(cmd
) == IOCGROUP(AUDIO_MIXER_READ
))
1166 error
= mixer_ioctl(sc
, cmd
, addr
, flag
, l
);
1168 error
= audio_ioctl(sc
, cmd
, addr
, flag
, l
);
1171 error
= mixer_ioctl(sc
, cmd
, addr
, flag
, l
);
1177 if (--sc
->sc_refcnt
< 0)
1178 wakeup(&sc
->sc_refcnt
);
1183 audiopoll(dev_t dev
, int events
, struct lwp
*l
)
1185 struct audio_softc
*sc
;
1188 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1193 switch (AUDIODEV(dev
)) {
1196 revents
= audio_poll(sc
, events
, l
);
1198 case AUDIOCTL_DEVICE
:
1206 if (--sc
->sc_refcnt
< 0)
1207 wakeup(&sc
->sc_refcnt
);
1212 audiokqfilter(dev_t dev
, struct knote
*kn
)
1214 struct audio_softc
*sc
;
1217 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1222 switch (AUDIODEV(dev
)) {
1225 rv
= audio_kqfilter(sc
, kn
);
1227 case AUDIOCTL_DEVICE
:
1234 if (--sc
->sc_refcnt
< 0)
1235 wakeup(&sc
->sc_refcnt
);
1240 audiommap(dev_t dev
, off_t off
, int prot
)
1242 struct audio_softc
*sc
;
1245 sc
= device_lookup_private(&audio_cd
, AUDIOUNIT(dev
));
1249 device_active(sc
->dev
, DVA_SYSTEM
); /* XXXJDM */
1252 switch (AUDIODEV(dev
)) {
1255 error
= audio_mmap(sc
, off
, prot
);
1257 case AUDIOCTL_DEVICE
:
1265 if (--sc
->sc_refcnt
< 0)
1266 wakeup(&sc
->sc_refcnt
);
1274 audio_init_ringbuffer(struct audio_softc
*sc
, struct audio_ringbuffer
*rp
,
1280 blksize
= rp
->blksize
;
1281 if (blksize
< AUMINBLK
)
1283 if (blksize
> rp
->s
.bufsize
/ AUMINNOBLK
)
1284 blksize
= rp
->s
.bufsize
/ AUMINNOBLK
;
1286 DPRINTF(("audio_init_ringbuffer: MI blksize=%d\n", blksize
));
1287 if (sc
->hw_if
->round_blocksize
)
1288 blksize
= sc
->hw_if
->round_blocksize(sc
->hw_hdl
, blksize
,
1289 mode
, &rp
->s
.param
);
1291 panic("audio_init_ringbuffer: blksize");
1292 nblks
= rp
->s
.bufsize
/ blksize
;
1294 DPRINTF(("audio_init_ringbuffer: final blksize=%d\n", blksize
));
1295 rp
->blksize
= blksize
;
1296 rp
->maxblks
= nblks
;
1297 rp
->s
.end
= rp
->s
.start
+ nblks
* blksize
;
1298 rp
->s
.outp
= rp
->s
.inp
= rp
->s
.start
;
1304 rp
->copying
= false;
1305 rp
->needfill
= false;
1306 rp
->mmapped
= false;
1310 audio_initbufs(struct audio_softc
*sc
)
1312 const struct audio_hw_if
*hw
;
1315 DPRINTF(("audio_initbufs: mode=0x%x\n", sc
->sc_mode
));
1317 if (audio_can_capture(sc
)) {
1318 audio_init_ringbuffer(sc
, &sc
->sc_rr
, AUMODE_RECORD
);
1319 if (hw
->init_input
&& (sc
->sc_mode
& AUMODE_RECORD
)) {
1320 error
= hw
->init_input(sc
->hw_hdl
, sc
->sc_rr
.s
.start
,
1321 sc
->sc_rr
.s
.end
- sc
->sc_rr
.s
.start
);
1327 if (audio_can_playback(sc
)) {
1328 audio_init_ringbuffer(sc
, &sc
->sc_pr
, AUMODE_PLAY
);
1329 sc
->sc_sil_count
= 0;
1330 if (hw
->init_output
&& (sc
->sc_mode
& AUMODE_PLAY
)) {
1331 error
= hw
->init_output(sc
->hw_hdl
, sc
->sc_pr
.s
.start
,
1332 sc
->sc_pr
.s
.end
- sc
->sc_pr
.s
.start
);
1338 #ifdef AUDIO_INTR_TIME
1339 #define double u_long
1340 if (audio_can_playback(sc
)) {
1342 sc
->sc_pblktime
= (u_long
)(
1343 (double)sc
->sc_pr
.blksize
* 100000 /
1344 (double)(sc
->sc_pparams
.precision
/ NBBY
*
1345 sc
->sc_pparams
.channels
*
1346 sc
->sc_pparams
.sample_rate
)) * 10;
1347 DPRINTF(("audio: play blktime = %lu for %d\n",
1348 sc
->sc_pblktime
, sc
->sc_pr
.blksize
));
1350 if (audio_can_capture(sc
)) {
1352 sc
->sc_rblktime
= (u_long
)(
1353 (double)sc
->sc_rr
.blksize
* 100000 /
1354 (double)(sc
->sc_rparams
.precision
/ NBBY
*
1355 sc
->sc_rparams
.channels
*
1356 sc
->sc_rparams
.sample_rate
)) * 10;
1357 DPRINTF(("audio: record blktime = %lu for %d\n",
1358 sc
->sc_rblktime
, sc
->sc_rr
.blksize
));
1367 audio_calcwater(struct audio_softc
*sc
)
1370 /* set high at 100% */
1371 if (audio_can_playback(sc
)) {
1372 sc
->sc_pr
.usedhigh
=
1373 sc
->sc_pustream
->end
- sc
->sc_pustream
->start
;
1374 /* set low at 75% of usedhigh */
1375 sc
->sc_pr
.usedlow
= sc
->sc_pr
.usedhigh
* 3 / 4;
1376 if (sc
->sc_pr
.usedlow
== sc
->sc_pr
.usedhigh
)
1377 sc
->sc_pr
.usedlow
-= sc
->sc_pr
.blksize
;
1380 if (audio_can_capture(sc
)) {
1381 sc
->sc_rr
.usedhigh
=
1382 sc
->sc_rustream
->end
- sc
->sc_rustream
->start
-
1384 sc
->sc_rr
.usedlow
= 0;
1385 DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__
,
1386 sc
->sc_pr
.usedlow
, sc
->sc_pr
.usedhigh
,
1387 sc
->sc_rr
.usedlow
, sc
->sc_rr
.usedhigh
));
1392 audio_sleep_timo(int *chan
, const char *label
, int timo
)
1399 DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
1400 chan
, label
, timo
));
1402 st
= tsleep(chan
, PWAIT
| PCATCH
, label
, timo
);
1405 if (st
!= 0 && st
!= EINTR
)
1406 DPRINTF(("audio_sleep: woke up st=%d\n", st
));
1412 audio_sleep(int *chan
, const char *label
)
1415 return audio_sleep_timo(chan
, label
, 0);
1418 /* call at splaudio() */
1420 audio_wakeup(int *chan
)
1423 DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan
, *chan
));
1431 audio_open(dev_t dev
, struct audio_softc
*sc
, int flags
, int ifmt
,
1436 const struct audio_hw_if
*hw
;
1442 DPRINTF(("audio_open: flags=0x%x sc=%p hdl=%p\n",
1443 flags
, sc
, sc
->hw_hdl
));
1445 if (((flags
& FREAD
) && (sc
->sc_open
& AUOPEN_READ
)) ||
1446 ((flags
& FWRITE
) && (sc
->sc_open
& AUOPEN_WRITE
)))
1449 if (hw
->open
!= NULL
) {
1450 error
= hw
->open(sc
->hw_hdl
, flags
);
1455 sc
->sc_async_audio
= 0;
1458 sc
->sc_sil_count
= 0;
1459 sc
->sc_rbus
= false;
1460 sc
->sc_pbus
= false;
1462 sc
->sc_playdrop
= 0;
1464 sc
->sc_full_duplex
=
1465 (flags
& (FWRITE
|FREAD
)) == (FWRITE
|FREAD
) &&
1466 (audio_get_props(sc
) & AUDIO_PROP_FULLDUPLEX
);
1469 if (flags
& FREAD
) {
1470 sc
->sc_open
|= AUOPEN_READ
;
1471 mode
|= AUMODE_RECORD
;
1473 if (flags
& FWRITE
) {
1474 sc
->sc_open
|= AUOPEN_WRITE
;
1475 mode
|= AUMODE_PLAY
| AUMODE_PLAY_ALL
;
1479 * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
1480 * The /dev/audio is always (re)set to 8-bit MU-Law mono
1481 * For the other devices, you get what they were last set to.
1483 if (ISDEVAUDIO(dev
)) {
1484 error
= audio_set_defaults(sc
, mode
);
1486 struct audio_info ai
;
1488 AUDIO_INITINFO(&ai
);
1490 error
= audiosetinfo(sc
, &ai
);
1497 * Sample rate and precision are supposed to be set to proper
1498 * default values by the hardware driver, so that it may give
1501 if (sc
->sc_rparams
.precision
== 0 || sc
->sc_pparams
.precision
== 0) {
1502 printf("audio_open: 0 precision\n");
1507 /* audio_close() decreases sc_pr.usedlow, recalculate here */
1508 audio_calcwater(sc
);
1510 DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc
->sc_mode
));
1515 if (hw
->close
!= NULL
)
1516 hw
->close(sc
->hw_hdl
);
1519 sc
->sc_full_duplex
= 0;
1524 * Must be called from task context.
1527 audio_init_record(struct audio_softc
*sc
)
1532 if (sc
->hw_if
->speaker_ctl
&&
1533 (!sc
->sc_full_duplex
|| (sc
->sc_mode
& AUMODE_PLAY
) == 0))
1534 sc
->hw_if
->speaker_ctl(sc
->hw_hdl
, SPKR_OFF
);
1539 * Must be called from task context.
1542 audio_init_play(struct audio_softc
*sc
)
1547 sc
->sc_wstamp
= sc
->sc_pr
.stamp
;
1548 if (sc
->hw_if
->speaker_ctl
)
1549 sc
->hw_if
->speaker_ctl(sc
->hw_hdl
, SPKR_ON
);
1554 audio_drain(struct audio_softc
*sc
)
1556 struct audio_ringbuffer
*cb
;
1561 DPRINTF(("audio_drain: enter busy=%d\n", sc
->sc_pbus
));
1566 used
= audio_stream_get_used(&sc
->sc_pr
.s
);
1568 for (i
= 0; i
< sc
->sc_npfilters
; i
++)
1569 used
+= audio_stream_get_used(&sc
->sc_pstreams
[i
]);
1575 /* We've never started playing, probably because the
1576 * block was too short. Pad it and start now.
1579 uint8_t *inp
= cb
->s
.inp
;
1581 cc
= cb
->blksize
- (inp
- cb
->s
.start
) % cb
->blksize
;
1582 audio_fill_silence(&cb
->s
.param
, inp
, cc
);
1584 cb
->s
.inp
= audio_stream_add_inp(&cb
->s
, inp
, cc
);
1585 error
= audiostartp(sc
);
1591 * Play until a silence block has been played, then we
1592 * know all has been drained.
1593 * XXX This should be done some other way to avoid
1598 printf("audio_drain: copying in progress!?!\n");
1599 cb
->copying
= false;
1605 while (cb
->drops
== drops
&& !error
) {
1606 DPRINTF(("audio_drain: used=%d, drops=%ld\n",
1607 audio_stream_get_used(&sc
->sc_pr
.s
), cb
->drops
));
1609 * When the process is exiting, it ignores all signals and
1610 * we can't interrupt this sleep, so we set a timeout
1613 error
= audio_sleep_timo(&sc
->sc_wchan
, "aud_dr", 30*hz
);
1622 * Close an audio chip.
1626 audio_close(struct audio_softc
*sc
, int flags
, int ifmt
,
1629 const struct audio_hw_if
*hw
;
1632 DPRINTF(("audio_close: sc=%p\n", sc
));
1635 /* Stop recording. */
1636 if ((flags
& FREAD
) && sc
->sc_rbus
) {
1638 * XXX Some drivers (e.g. SB) use the same routine
1639 * to halt input and output so don't halt input if
1640 * in full duplex mode. These drivers should be fixed.
1642 if (!sc
->sc_full_duplex
|| hw
->halt_input
!= hw
->halt_output
)
1643 hw
->halt_input(sc
->hw_hdl
);
1644 sc
->sc_rbus
= false;
1647 * Block until output drains, but allow ^C interrupt.
1649 sc
->sc_pr
.usedlow
= sc
->sc_pr
.blksize
; /* avoid excessive wakeups */
1651 * If there is pending output, let it drain (unless
1652 * the output is paused).
1654 if ((flags
& FWRITE
) && sc
->sc_pbus
) {
1655 if (!sc
->sc_pr
.pause
&& !audio_drain(sc
) && hw
->drain
)
1656 (void)hw
->drain(sc
->hw_hdl
);
1657 hw
->halt_output(sc
->hw_hdl
);
1658 sc
->sc_pbus
= false;
1661 if (hw
->close
!= NULL
)
1662 hw
->close(sc
->hw_hdl
);
1666 sc
->sc_async_audio
= 0;
1667 sc
->sc_full_duplex
= 0;
1669 DPRINTF(("audio_close: done\n"));
1675 audio_read(struct audio_softc
*sc
, struct uio
*uio
, int ioflag
)
1677 struct audio_ringbuffer
*cb
;
1678 const uint8_t *outp
;
1680 int error
, s
, used
, cc
, n
;
1686 DPRINTFN(1,("audio_read: cc=%zu mode=%d\n",
1687 uio
->uio_resid
, sc
->sc_mode
));
1689 #ifdef AUDIO_PM_IDLE
1690 if (device_is_active(&sc
->dev
) || sc
->sc_idle
)
1691 device_active(&sc
->dev
, DVA_SYSTEM
);
1696 * If hardware is half-duplex and currently playing, return
1697 * silence blocks based on the number of blocks we have output.
1699 if (!sc
->sc_full_duplex
&& (sc
->sc_mode
& AUMODE_PLAY
)) {
1700 while (uio
->uio_resid
> 0 && !error
) {
1703 cc
= sc
->sc_pr
.stamp
- sc
->sc_wstamp
;
1706 DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
1707 sc
->sc_pr
.stamp
, sc
->sc_wstamp
));
1708 if (ioflag
& IO_NDELAY
) {
1712 error
= audio_sleep(&sc
->sc_rchan
, "aud_hr");
1722 if (uio
->uio_resid
< cc
)
1723 cc
= uio
->uio_resid
;
1724 DPRINTFN(1,("audio_read: reading in write mode, "
1726 error
= audio_silence_copyout(sc
, cc
, uio
);
1727 sc
->sc_wstamp
+= cc
;
1732 while (uio
->uio_resid
> 0 && !error
) {
1734 while ((used
= audio_stream_get_used(sc
->sc_rustream
)) <= 0) {
1735 if (!sc
->sc_rbus
&& !sc
->sc_rr
.pause
) {
1736 error
= audiostartr(sc
);
1742 if (ioflag
& IO_NDELAY
) {
1746 DPRINTFN(2, ("audio_read: sleep used=%d\n", used
));
1747 error
= audio_sleep(&sc
->sc_rchan
, "aud_rd");
1756 outp
= sc
->sc_rustream
->outp
;
1757 inp
= sc
->sc_rustream
->inp
;
1762 * cc is the amount of data in the sc_rustream excluding
1763 * wrapped data. Note the tricky case of inp == outp, which
1764 * must mean the buffer is full, not empty, because used > 0.
1766 cc
= outp
< inp
? inp
- outp
:sc
->sc_rustream
->end
- outp
;
1767 DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp
, cc
));
1770 error
= uiomove(__UNCONST(outp
), cc
, uio
);
1771 n
-= uio
->uio_resid
; /* number of bytes actually moved */
1774 sc
->sc_rustream
->outp
= audio_stream_add_outp
1775 (sc
->sc_rustream
, outp
, n
);
1776 cb
->copying
= false;
1783 audio_clear(struct audio_softc
*sc
)
1789 audio_wakeup(&sc
->sc_rchan
);
1790 sc
->hw_if
->halt_input(sc
->hw_hdl
);
1791 sc
->sc_rbus
= false;
1792 sc
->sc_rr
.pause
= false;
1795 audio_wakeup(&sc
->sc_wchan
);
1796 sc
->hw_if
->halt_output(sc
->hw_hdl
);
1797 sc
->sc_pbus
= false;
1798 sc
->sc_pr
.pause
= false;
1804 audio_calc_blksize(struct audio_softc
*sc
, int mode
)
1806 const audio_params_t
*parm
;
1807 struct audio_ringbuffer
*rb
;
1812 if (mode
== AUMODE_PLAY
) {
1814 parm
= &rb
->s
.param
;
1817 parm
= &rb
->s
.param
;
1820 rb
->blksize
= parm
->sample_rate
* audio_blk_ms
/ 1000 *
1821 parm
->channels
* parm
->precision
/ NBBY
;
1823 DPRINTF(("audio_calc_blksize: %s blksize=%d\n",
1824 mode
== AUMODE_PLAY
? "play" : "record", rb
->blksize
));
1828 audio_fill_silence(struct audio_params
*params
, uint8_t *p
, int n
)
1830 uint8_t auzero0
, auzero1
;
1833 auzero1
= 0; /* initialize to please gcc */
1835 switch (params
->encoding
) {
1836 case AUDIO_ENCODING_ULAW
:
1839 case AUDIO_ENCODING_ALAW
:
1842 case AUDIO_ENCODING_MPEG_L1_STREAM
:
1843 case AUDIO_ENCODING_MPEG_L1_PACKETS
:
1844 case AUDIO_ENCODING_MPEG_L1_SYSTEM
:
1845 case AUDIO_ENCODING_MPEG_L2_STREAM
:
1846 case AUDIO_ENCODING_MPEG_L2_PACKETS
:
1847 case AUDIO_ENCODING_MPEG_L2_SYSTEM
:
1848 case AUDIO_ENCODING_ADPCM
: /* is this right XXX */
1849 case AUDIO_ENCODING_SLINEAR_LE
:
1850 case AUDIO_ENCODING_SLINEAR_BE
:
1851 auzero0
= 0;/* fortunately this works for any number of bits */
1853 case AUDIO_ENCODING_ULINEAR_LE
:
1854 case AUDIO_ENCODING_ULINEAR_BE
:
1855 if (params
->precision
> 8) {
1856 nfill
= (params
->precision
+ NBBY
- 1)/ NBBY
;
1863 DPRINTF(("audio: bad encoding %d\n", params
->encoding
));
1869 *p
++ = auzero0
; /* XXX memset */
1870 } else /* nfill must no longer be 2 */ {
1871 if (params
->encoding
== AUDIO_ENCODING_ULINEAR_LE
) {
1877 while (n
>= nfill
) {
1885 if (n
-- > 0) /* XXX must be 1 - DIAGNOSTIC check? */
1891 audio_silence_copyout(struct audio_softc
*sc
, int n
, struct uio
*uio
)
1893 uint8_t zerobuf
[128];
1897 audio_fill_silence(&sc
->sc_rparams
, zerobuf
, sizeof zerobuf
);
1900 while (n
> 0 && uio
->uio_resid
> 0 && !error
) {
1901 k
= min(n
, min(uio
->uio_resid
, sizeof zerobuf
));
1902 error
= uiomove(zerobuf
, k
, uio
);
1909 uio_fetcher_fetch_to(stream_fetcher_t
*self
, audio_stream_t
*p
,
1912 uio_fetcher_t
*this;
1917 this = (uio_fetcher_t
*)self
;
1918 this->last_used
= audio_stream_get_used(p
);
1919 if (this->last_used
>= this->usedhigh
)
1922 * uio_fetcher ignores max_used and move the data as
1923 * much as possible in order to return the correct value
1924 * for audio_prinfo::seek and kfilters.
1926 stream_space
= audio_stream_get_space(p
);
1927 size
= min(this->uio
->uio_resid
, stream_space
);
1929 /* the first fragment of the space */
1930 stream_space
= p
->end
- p
->inp
;
1931 if (stream_space
>= size
) {
1932 error
= uiomove(p
->inp
, size
, this->uio
);
1935 p
->inp
= audio_stream_add_inp(p
, p
->inp
, size
);
1937 error
= uiomove(p
->inp
, stream_space
, this->uio
);
1940 p
->inp
= audio_stream_add_inp(p
, p
->inp
, stream_space
);
1941 error
= uiomove(p
->start
, size
- stream_space
, this->uio
);
1944 p
->inp
= audio_stream_add_inp(p
, p
->inp
, size
- stream_space
);
1946 this->last_used
= audio_stream_get_used(p
);
1951 null_fetcher_fetch_to(stream_fetcher_t
*self
,
1952 audio_stream_t
*p
, int max_used
)
1959 uio_fetcher_ctor(uio_fetcher_t
*this, struct uio
*u
, int h
)
1962 this->base
.fetch_to
= uio_fetcher_fetch_to
;
1968 audio_write(struct audio_softc
*sc
, struct uio
*uio
, int ioflag
)
1970 uio_fetcher_t ufetcher
;
1971 audio_stream_t stream
;
1972 struct audio_ringbuffer
*cb
;
1973 stream_fetcher_t
*fetcher
;
1974 stream_filter_t
*filter
;
1975 uint8_t *inp
, *einp
;
1976 int saveerror
, error
, s
, n
, cc
, used
;
1978 DPRINTFN(2,("audio_write: sc=%p count=%zu used=%d(hi=%d)\n",
1979 sc
, uio
->uio_resid
, audio_stream_get_used(sc
->sc_pustream
),
1980 sc
->sc_pr
.usedhigh
));
1985 if (uio
->uio_resid
== 0) {
1990 #ifdef AUDIO_PM_IDLE
1991 if (device_is_active(&sc
->dev
) || sc
->sc_idle
)
1992 device_active(&sc
->dev
, DVA_SYSTEM
);
1996 * If half-duplex and currently recording, throw away data.
1998 if (!sc
->sc_full_duplex
&&
1999 (sc
->sc_mode
& AUMODE_RECORD
)) {
2000 uio
->uio_offset
+= uio
->uio_resid
;
2002 DPRINTF(("audio_write: half-dpx read busy\n"));
2006 if (!(sc
->sc_mode
& AUMODE_PLAY_ALL
) && sc
->sc_playdrop
> 0) {
2007 n
= min(sc
->sc_playdrop
, uio
->uio_resid
);
2008 DPRINTF(("audio_write: playdrop %d\n", n
));
2009 uio
->uio_offset
+= n
;
2010 uio
->uio_resid
-= n
;
2011 sc
->sc_playdrop
-= n
;
2012 if (uio
->uio_resid
== 0)
2017 * setup filter pipeline
2019 uio_fetcher_ctor(&ufetcher
, uio
, cb
->usedhigh
);
2020 if (sc
->sc_npfilters
> 0) {
2021 fetcher
= &sc
->sc_pfilters
[sc
->sc_npfilters
- 1]->base
;
2023 fetcher
= &ufetcher
.base
;
2027 while (uio
->uio_resid
> 0 && !error
) {
2029 /* wait if the first buffer is occupied */
2030 while ((used
= audio_stream_get_used(sc
->sc_pustream
))
2032 DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d "
2034 cb
->usedlow
, cb
->usedhigh
));
2035 if (ioflag
& IO_NDELAY
) {
2039 error
= audio_sleep(&sc
->sc_wchan
, "aud_wr");
2054 * write to the sc_pustream as much as possible
2056 * work with a temporary audio_stream_t to narrow
2057 * splaudio() enclosure
2062 if (sc
->sc_npfilters
> 0) {
2063 filter
= sc
->sc_pfilters
[0];
2064 filter
->set_fetcher(filter
, &ufetcher
.base
);
2065 fetcher
= &sc
->sc_pfilters
[sc
->sc_npfilters
- 1]->base
;
2066 cc
= cb
->blksize
* 2;
2067 error
= fetcher
->fetch_to(fetcher
, &stream
, cc
);
2069 fetcher
= &ufetcher
.base
;
2070 cc
= sc
->sc_pustream
->end
- sc
->sc_pustream
->start
;
2071 error
= fetcher
->fetch_to(fetcher
, sc
->sc_pustream
, cc
);
2074 fetcher
= &ufetcher
.base
;
2075 cc
= stream
.end
- stream
.start
;
2076 error
= fetcher
->fetch_to(fetcher
, &stream
, cc
);
2079 if (sc
->sc_waitcomp
)
2083 if (sc
->sc_npfilters
> 0) {
2084 cb
->fstamp
+= ufetcher
.last_used
2085 - audio_stream_get_used(sc
->sc_pustream
);
2087 cb
->s
.used
+= stream
.used
- used
;
2088 cb
->s
.inp
= stream
.inp
;
2092 * This is a very suboptimal way of keeping track of
2093 * silence in the buffer, but it is simple.
2095 sc
->sc_sil_count
= 0;
2098 * If the interrupt routine wants the last block filled AND
2099 * the copy did not fill the last block completely it needs to
2102 if (cb
->needfill
&& inp
< einp
&&
2103 (inp
- cb
->s
.start
) / cb
->blksize
==
2104 (einp
- cb
->s
.start
) / cb
->blksize
) {
2105 /* Figure out how many bytes to a block boundary. */
2106 cc
= cb
->blksize
- (einp
- cb
->s
.start
) % cb
->blksize
;
2107 DPRINTF(("audio_write: partial fill %d\n", cc
));
2110 cb
->needfill
= false;
2111 cb
->copying
= false;
2112 if (!sc
->sc_pbus
&& !cb
->pause
) {
2114 error
= audiostartp(sc
);
2115 if (saveerror
!= 0) {
2116 /* Report the first error that occurred. */
2122 DPRINTFN(1, ("audio_write: fill %d\n", cc
));
2123 audio_fill_silence(&cb
->s
.param
, einp
, cc
);
2131 audio_ioctl(struct audio_softc
*sc
, u_long cmd
, void *addr
, int flag
,
2134 const struct audio_hw_if
*hw
;
2135 struct audio_offset
*ao
;
2137 int error
, s
, offs
, fd
;
2140 DPRINTF(("audio_ioctl(%lu,'%c',%lu)\n",
2141 IOCPARM_LEN(cmd
), (char)IOCGROUP(cmd
), cmd
&0xff));
2146 /* All handled in the upper FS layer. */
2150 *(int *)addr
= audio_stream_get_used(sc
->sc_rustream
);
2155 if (sc
->sc_async_audio
)
2157 sc
->sc_async_audio
= l
->l_proc
;
2158 DPRINTF(("audio_ioctl: FIOASYNC %p\n", l
->l_proc
));
2160 sc
->sc_async_audio
= 0;
2164 DPRINTF(("AUDIO_FLUSH\n"));
2169 error
= audio_initbufs(sc
);
2174 if ((sc
->sc_mode
& AUMODE_PLAY
) && !sc
->sc_pbus
&& pbus
)
2175 error
= audiostartp(sc
);
2177 (sc
->sc_mode
& AUMODE_RECORD
) && !sc
->sc_rbus
&& rbus
)
2178 error
= audiostartr(sc
);
2183 * Number of read (write) samples dropped. We don't know where or
2184 * when they were dropped.
2187 *(int *)addr
= sc
->sc_rr
.drops
;
2191 *(int *)addr
= sc
->sc_pr
.drops
;
2195 * Offsets into buffer.
2197 case AUDIO_GETIOFFS
:
2198 ao
= (struct audio_offset
*)addr
;
2200 /* figure out where next DMA will start */
2201 stamp
= sc
->sc_rustream
== &sc
->sc_rr
.s
2202 ? sc
->sc_rr
.stamp
: sc
->sc_rr
.fstamp
;
2203 offs
= sc
->sc_rustream
->inp
- sc
->sc_rustream
->start
;
2205 ao
->samples
= stamp
;
2207 (stamp
/ sc
->sc_rr
.blksize
) -
2208 (sc
->sc_rr
.stamp_last
/ sc
->sc_rr
.blksize
);
2209 sc
->sc_rr
.stamp_last
= stamp
;
2213 case AUDIO_GETOOFFS
:
2214 ao
= (struct audio_offset
*)addr
;
2216 /* figure out where next DMA will start */
2217 stamp
= sc
->sc_pustream
== &sc
->sc_pr
.s
2218 ? sc
->sc_pr
.stamp
: sc
->sc_pr
.fstamp
;
2219 offs
= sc
->sc_pustream
->outp
- sc
->sc_pustream
->start
2220 + sc
->sc_pr
.blksize
;
2222 ao
->samples
= stamp
;
2224 (stamp
/ sc
->sc_pr
.blksize
) -
2225 (sc
->sc_pr
.stamp_last
/ sc
->sc_pr
.blksize
);
2226 sc
->sc_pr
.stamp_last
= stamp
;
2227 if (sc
->sc_pustream
->start
+ offs
>= sc
->sc_pustream
->end
)
2233 * How many bytes will elapse until mike hears the first
2234 * sample of what we write next?
2237 *(u_long
*)addr
= audio_stream_get_used(sc
->sc_pustream
);
2241 DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc
->sc_mode
));
2242 error
= audiosetinfo(sc
, (struct audio_info
*)addr
);
2246 DPRINTF(("AUDIO_GETINFO\n"));
2247 error
= audiogetinfo(sc
, (struct audio_info
*)addr
, 0);
2250 case AUDIO_GETBUFINFO
:
2251 DPRINTF(("AUDIO_GETBUFINFO\n"));
2252 error
= audiogetinfo(sc
, (struct audio_info
*)addr
, 1);
2256 DPRINTF(("AUDIO_DRAIN\n"));
2257 error
= audio_drain(sc
);
2258 if (!error
&& hw
->drain
)
2259 error
= hw
->drain(sc
->hw_hdl
);
2263 DPRINTF(("AUDIO_GETDEV\n"));
2264 error
= hw
->getdev(sc
->hw_hdl
, (audio_device_t
*)addr
);
2268 DPRINTF(("AUDIO_GETENC\n"));
2269 error
= hw
->query_encoding(sc
->hw_hdl
,
2270 (struct audio_encoding
*)addr
);
2274 DPRINTF(("AUDIO_GETFD\n"));
2275 *(int *)addr
= sc
->sc_full_duplex
;
2279 DPRINTF(("AUDIO_SETFD\n"));
2281 if (audio_get_props(sc
) & AUDIO_PROP_FULLDUPLEX
) {
2283 error
= hw
->setfd(sc
->hw_hdl
, fd
);
2287 sc
->sc_full_duplex
= fd
;
2296 case AUDIO_GETPROPS
:
2297 DPRINTF(("AUDIO_GETPROPS\n"));
2298 *(int *)addr
= audio_get_props(sc
);
2302 if (hw
->dev_ioctl
) {
2303 error
= hw
->dev_ioctl(sc
->hw_hdl
, cmd
, addr
, flag
, l
);
2305 DPRINTF(("audio_ioctl: unknown ioctl\n"));
2310 DPRINTF(("audio_ioctl(%lu,'%c',%lu) result %d\n",
2311 IOCPARM_LEN(cmd
), (char)IOCGROUP(cmd
), cmd
&0xff, error
));
2316 audio_poll(struct audio_softc
*sc
, int events
, struct lwp
*l
)
2322 DPRINTF(("audio_poll: events=0x%x mode=%d\n", events
, sc
->sc_mode
));
2326 if (events
& (POLLIN
| POLLRDNORM
)) {
2327 used
= audio_stream_get_used(sc
->sc_rustream
);
2329 * If half duplex and playing, audio_read() will generate
2330 * silence at the play rate; poll for silence being
2331 * available. Otherwise, poll for recorded sound.
2333 if ((!sc
->sc_full_duplex
&& (sc
->sc_mode
& AUMODE_PLAY
)) ?
2334 sc
->sc_pr
.stamp
> sc
->sc_wstamp
:
2335 used
> sc
->sc_rr
.usedlow
)
2336 revents
|= events
& (POLLIN
| POLLRDNORM
);
2339 if (events
& (POLLOUT
| POLLWRNORM
)) {
2340 used
= audio_stream_get_used(sc
->sc_pustream
);
2342 * If half duplex and recording, audio_write() will throw
2343 * away play data, which means we are always ready to write.
2344 * Otherwise, poll for play buffer being below its low water
2347 if ((!sc
->sc_full_duplex
&& (sc
->sc_mode
& AUMODE_RECORD
)) ||
2348 (!(sc
->sc_mode
& AUMODE_PLAY_ALL
) && sc
->sc_playdrop
> 0) ||
2349 (used
<= sc
->sc_pr
.usedlow
))
2350 revents
|= events
& (POLLOUT
| POLLWRNORM
);
2354 if (events
& (POLLIN
| POLLRDNORM
))
2355 selrecord(l
, &sc
->sc_rsel
);
2357 if (events
& (POLLOUT
| POLLWRNORM
))
2358 selrecord(l
, &sc
->sc_wsel
);
2366 filt_audiordetach(struct knote
*kn
)
2368 struct audio_softc
*sc
;
2373 SLIST_REMOVE(&sc
->sc_rsel
.sel_klist
, kn
, knote
, kn_selnext
);
2378 filt_audioread(struct knote
*kn
, long hint
)
2380 struct audio_softc
*sc
;
2385 if (!sc
->sc_full_duplex
&& (sc
->sc_mode
& AUMODE_PLAY
))
2386 kn
->kn_data
= sc
->sc_pr
.stamp
- sc
->sc_wstamp
;
2388 kn
->kn_data
= audio_stream_get_used(sc
->sc_rustream
)
2389 - sc
->sc_rr
.usedlow
;
2392 return kn
->kn_data
> 0;
2395 static const struct filterops audioread_filtops
=
2396 { 1, NULL
, filt_audiordetach
, filt_audioread
};
2399 filt_audiowdetach(struct knote
*kn
)
2401 struct audio_softc
*sc
;
2406 SLIST_REMOVE(&sc
->sc_wsel
.sel_klist
, kn
, knote
, kn_selnext
);
2411 filt_audiowrite(struct knote
*kn
, long hint
)
2413 struct audio_softc
*sc
;
2414 audio_stream_t
*stream
;
2419 stream
= sc
->sc_pustream
;
2420 kn
->kn_data
= (stream
->end
- stream
->start
)
2421 - audio_stream_get_used(stream
);
2424 return kn
->kn_data
> 0;
2427 static const struct filterops audiowrite_filtops
=
2428 { 1, NULL
, filt_audiowdetach
, filt_audiowrite
};
2431 audio_kqfilter(struct audio_softc
*sc
, struct knote
*kn
)
2433 struct klist
*klist
;
2436 switch (kn
->kn_filter
) {
2438 klist
= &sc
->sc_rsel
.sel_klist
;
2439 kn
->kn_fop
= &audioread_filtops
;
2443 klist
= &sc
->sc_wsel
.sel_klist
;
2444 kn
->kn_fop
= &audiowrite_filtops
;
2454 SLIST_INSERT_HEAD(klist
, kn
, kn_selnext
);
2461 audio_mmap(struct audio_softc
*sc
, off_t off
, int prot
)
2463 const struct audio_hw_if
*hw
;
2464 struct audio_ringbuffer
*cb
;
2467 DPRINTF(("audio_mmap: off=%lld, prot=%d\n", (long long)off
, prot
));
2469 if (!(audio_get_props(sc
) & AUDIO_PROP_MMAP
) || !hw
->mappage
)
2473 * The idea here was to use the protection to determine if
2474 * we are mapping the read or write buffer, but it fails.
2475 * The VM system is broken in (at least) two ways.
2476 * 1) If you map memory VM_PROT_WRITE you SIGSEGV
2477 * when writing to it, so VM_PROT_READ|VM_PROT_WRITE
2478 * has to be used for mmapping the play buffer.
2479 * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
2480 * audio_mmap will get called at some point with VM_PROT_READ
2482 * So, alas, we always map the play buffer for now.
2484 if (prot
== (VM_PROT_READ
|VM_PROT_WRITE
) ||
2485 prot
== VM_PROT_WRITE
)
2487 else if (prot
== VM_PROT_READ
)
2495 if ((u_int
)off
>= cb
->s
.bufsize
)
2499 if (cb
== &sc
->sc_pr
) {
2500 audio_fill_silence(&cb
->s
.param
, cb
->s
.start
,
2503 sc
->sc_pustream
= &cb
->s
;
2504 if (!sc
->sc_pbus
&& !sc
->sc_pr
.pause
)
2505 (void)audiostartp(sc
);
2509 sc
->sc_rustream
= &cb
->s
;
2510 if (!sc
->sc_rbus
&& !sc
->sc_rr
.pause
)
2511 (void)audiostartr(sc
);
2516 return hw
->mappage(sc
->hw_hdl
, cb
->s
.start
, off
, prot
);
2520 audiostartr(struct audio_softc
*sc
)
2524 DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
2525 sc
->sc_rr
.s
.start
, audio_stream_get_used(&sc
->sc_rr
.s
),
2526 sc
->sc_rr
.usedhigh
, sc
->sc_rr
.mmapped
));
2528 if (!audio_can_capture(sc
))
2531 if (sc
->hw_if
->trigger_input
)
2532 error
= sc
->hw_if
->trigger_input(sc
->hw_hdl
, sc
->sc_rr
.s
.start
,
2533 sc
->sc_rr
.s
.end
, sc
->sc_rr
.blksize
,
2534 audio_rint
, (void *)sc
, &sc
->sc_rr
.s
.param
);
2536 error
= sc
->hw_if
->start_input(sc
->hw_hdl
, sc
->sc_rr
.s
.start
,
2537 sc
->sc_rr
.blksize
, audio_rint
, (void *)sc
);
2539 DPRINTF(("audiostartr failed: %d\n", error
));
2547 audiostartp(struct audio_softc
*sc
)
2552 used
= audio_stream_get_used(&sc
->sc_pr
.s
);
2553 DPRINTF(("audiostartp: start=%p used=%d(hi=%d blk=%d) mmapped=%d\n",
2554 sc
->sc_pr
.s
.start
, used
, sc
->sc_pr
.usedhigh
,
2555 sc
->sc_pr
.blksize
, sc
->sc_pr
.mmapped
));
2557 if (!audio_can_playback(sc
))
2560 if (!sc
->sc_pr
.mmapped
&& used
< sc
->sc_pr
.blksize
) {
2561 wakeup(&sc
->sc_wchan
);
2562 DPRINTF(("%s: wakeup and return\n", __func__
));
2566 if (sc
->hw_if
->trigger_output
) {
2567 DPRINTF(("%s: call trigger_output\n", __func__
));
2568 error
= sc
->hw_if
->trigger_output(sc
->hw_hdl
, sc
->sc_pr
.s
.start
,
2569 sc
->sc_pr
.s
.end
, sc
->sc_pr
.blksize
,
2570 audio_pint
, (void *)sc
, &sc
->sc_pr
.s
.param
);
2572 DPRINTF(("%s: call start_output\n", __func__
));
2573 error
= sc
->hw_if
->start_output(sc
->hw_hdl
,
2574 __UNCONST(sc
->sc_pr
.s
.outp
), sc
->sc_pr
.blksize
,
2575 audio_pint
, (void *)sc
);
2578 DPRINTF(("audiostartp failed: %d\n", error
));
2586 * When the play interrupt routine finds that the write isn't keeping
2587 * the buffer filled it will insert silence in the buffer to make up
2588 * for this. The part of the buffer that is filled with silence
2589 * is kept track of in a very approximate way: it starts at sc_sil_start
2590 * and extends sc_sil_count bytes. If there is already silence in
2591 * the requested area nothing is done; so when the whole buffer is
2592 * silent nothing happens. When the writer starts again sc_sil_count
2596 * Putting silence into the output buffer should not really be done
2597 * at splaudio, but there is no softaudio level to do it at yet.
2600 audio_pint_silence(struct audio_softc
*sc
, struct audio_ringbuffer
*cb
,
2601 uint8_t *inp
, int cc
)
2603 uint8_t *s
, *e
, *p
, *q
;
2605 if (sc
->sc_sil_count
> 0) {
2606 s
= sc
->sc_sil_start
; /* start of silence */
2607 e
= s
+ sc
->sc_sil_count
; /* end of sil., may be beyond end */
2608 p
= inp
; /* adjusted pointer to area to fill */
2610 p
+= cb
->s
.end
- cb
->s
.start
;
2612 /* Check if there is already silence. */
2613 if (!(s
<= p
&& p
< e
&&
2614 s
<= q
&& q
<= e
)) {
2616 sc
->sc_sil_count
= max(sc
->sc_sil_count
, q
-s
);
2617 DPRINTFN(5,("audio_pint_silence: fill cc=%d inp=%p, "
2618 "count=%d size=%d\n",
2619 cc
, inp
, sc
->sc_sil_count
,
2620 (int)(cb
->s
.end
- cb
->s
.start
)));
2621 audio_fill_silence(&cb
->s
.param
, inp
, cc
);
2623 DPRINTFN(5,("audio_pint_silence: already silent "
2624 "cc=%d inp=%p\n", cc
, inp
));
2628 sc
->sc_sil_start
= inp
;
2629 sc
->sc_sil_count
= cc
;
2630 DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n",
2632 audio_fill_silence(&cb
->s
.param
, inp
, cc
);
2637 audio_softintr_rd(void *cookie
)
2639 struct audio_softc
*sc
= cookie
;
2642 audio_wakeup(&sc
->sc_rchan
);
2643 selnotify(&sc
->sc_rsel
, 0, 0);
2644 if (sc
->sc_async_audio
!= NULL
) {
2645 DPRINTFN(3, ("audio_softintr_rd: sending SIGIO %p\n",
2646 sc
->sc_async_audio
));
2647 mutex_enter(proc_lock
);
2648 if ((p
= sc
->sc_async_audio
) != NULL
)
2650 mutex_exit(proc_lock
);
2655 audio_softintr_wr(void *cookie
)
2657 struct audio_softc
*sc
= cookie
;
2660 audio_wakeup(&sc
->sc_wchan
);
2661 selnotify(&sc
->sc_wsel
, 0, 0);
2662 if (sc
->sc_async_audio
!= NULL
) {
2663 DPRINTFN(3, ("audio_softintr_wr: sending SIGIO %p\n",
2664 sc
->sc_async_audio
));
2665 mutex_enter(proc_lock
);
2666 if ((p
= sc
->sc_async_audio
) != NULL
)
2668 mutex_exit(proc_lock
);
2673 * Called from HW driver module on completion of DMA output.
2674 * Start output of new block, wrap in ring buffer if needed.
2675 * If no more buffers to play, output zero instead.
2676 * Do a wakeup if necessary.
2681 stream_fetcher_t null_fetcher
;
2682 struct audio_softc
*sc
;
2683 const struct audio_hw_if
*hw
;
2684 struct audio_ringbuffer
*cb
;
2685 stream_fetcher_t
*fetcher
;
2693 return; /* ignore interrupt if not open */
2697 blksize
= cb
->blksize
;
2698 cb
->s
.outp
= audio_stream_add_outp(&cb
->s
, cb
->s
.outp
, blksize
);
2699 cb
->stamp
+= blksize
;
2701 DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
2702 cb
->s
.outp
, blksize
, cb
->s
.inp
));
2703 if (hw
->trigger_output
== NULL
)
2704 (void)hw
->start_output(sc
->hw_hdl
, __UNCONST(cb
->s
.outp
),
2705 blksize
, audio_pint
, (void *)sc
);
2709 #ifdef AUDIO_INTR_TIME
2714 t
= tv
.tv_usec
+ 1000000 * tv
.tv_sec
;
2715 if (sc
->sc_pnintr
) {
2716 long lastdelta
, totdelta
;
2717 lastdelta
= t
- sc
->sc_plastintr
- sc
->sc_pblktime
;
2718 if (lastdelta
> sc
->sc_pblktime
/ 3) {
2719 printf("audio: play interrupt(%d) off "
2720 "relative by %ld us (%lu)\n",
2721 sc
->sc_pnintr
, lastdelta
,
2724 totdelta
= t
- sc
->sc_pfirstintr
-
2725 sc
->sc_pblktime
* sc
->sc_pnintr
;
2726 if (totdelta
> sc
->sc_pblktime
) {
2727 printf("audio: play interrupt(%d) off "
2728 "absolute by %ld us (%lu) (LOST)\n",
2729 sc
->sc_pnintr
, totdelta
,
2731 sc
->sc_pnintr
++; /* avoid repeated messages */
2734 sc
->sc_pfirstintr
= t
;
2735 sc
->sc_plastintr
= t
;
2740 used
= audio_stream_get_used(&cb
->s
);
2742 * "used <= cb->usedlow" should be "used < blksize" ideally.
2743 * Some HW drivers such as uaudio(4) does not call audio_pint()
2744 * at accurate timing. If used < blksize, uaudio(4) already
2745 * request transfer of garbage data.
2747 if (used
<= cb
->usedlow
&& !cb
->copying
&& sc
->sc_npfilters
> 0) {
2748 /* we might have data in filter pipeline */
2749 null_fetcher
.fetch_to
= null_fetcher_fetch_to
;
2750 fetcher
= &sc
->sc_pfilters
[sc
->sc_npfilters
- 1]->base
;
2751 sc
->sc_pfilters
[0]->set_fetcher(sc
->sc_pfilters
[0],
2753 used
= audio_stream_get_used(sc
->sc_pustream
);
2754 cc
= cb
->s
.end
- cb
->s
.start
;
2755 if (blksize
* 2 < cc
)
2757 fetcher
->fetch_to(fetcher
, &cb
->s
, cc
);
2758 cb
->fstamp
+= used
- audio_stream_get_used(sc
->sc_pustream
);
2759 used
= audio_stream_get_used(&cb
->s
);
2761 if (used
< blksize
) {
2762 /* we don't have a full block to use */
2764 /* writer is in progress, don't disturb */
2765 cb
->needfill
= true;
2766 DPRINTFN(1, ("audio_pint: copying in progress\n"));
2769 cc
= blksize
- (inp
- cb
->s
.start
) % blksize
;
2774 sc
->sc_playdrop
+= cc
;
2776 audio_pint_silence(sc
, cb
, inp
, cc
);
2777 cb
->s
.inp
= audio_stream_add_inp(&cb
->s
, inp
, cc
);
2779 /* Clear next block so we keep ahead of the DMA. */
2780 used
= audio_stream_get_used(&cb
->s
);
2781 if (used
+ cc
< cb
->s
.end
- cb
->s
.start
)
2782 audio_pint_silence(sc
, cb
, inp
, blksize
);
2786 DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb
->s
.outp
, blksize
));
2787 if (hw
->trigger_output
== NULL
) {
2788 error
= hw
->start_output(sc
->hw_hdl
, __UNCONST(cb
->s
.outp
),
2789 blksize
, audio_pint
, (void *)sc
);
2791 /* XXX does this really help? */
2792 DPRINTF(("audio_pint restart failed: %d\n", error
));
2797 DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n",
2798 sc
->sc_mode
, cb
->pause
,
2799 audio_stream_get_used(sc
->sc_pustream
), cb
->usedlow
));
2800 if ((sc
->sc_mode
& AUMODE_PLAY
) && !cb
->pause
) {
2801 if (audio_stream_get_used(sc
->sc_pustream
) <= cb
->usedlow
)
2802 softint_schedule(sc
->sc_sih_wr
);
2805 /* Possible to return one or more "phantom blocks" now. */
2806 if (!sc
->sc_full_duplex
&& sc
->sc_rchan
)
2807 softint_schedule(sc
->sc_sih_rd
);
2811 * Called from HW driver module on completion of DMA input.
2812 * Mark it as input in the ring buffer (fiddle pointers).
2813 * Do a wakeup if necessary.
2818 stream_fetcher_t null_fetcher
;
2819 struct audio_softc
*sc
;
2820 const struct audio_hw_if
*hw
;
2821 struct audio_ringbuffer
*cb
;
2822 stream_fetcher_t
*last_fetcher
;
2831 return; /* ignore interrupt if not open */
2834 blksize
= cb
->blksize
;
2835 cb
->s
.inp
= audio_stream_add_inp(&cb
->s
, cb
->s
.inp
, blksize
);
2836 cb
->stamp
+= blksize
;
2838 DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n",
2839 cb
->s
.inp
, blksize
));
2840 if (hw
->trigger_input
== NULL
)
2841 (void)hw
->start_input(sc
->hw_hdl
, cb
->s
.inp
, blksize
,
2842 audio_rint
, (void *)sc
);
2846 #ifdef AUDIO_INTR_TIME
2851 t
= tv
.tv_usec
+ 1000000 * tv
.tv_sec
;
2852 if (sc
->sc_rnintr
) {
2853 long lastdelta
, totdelta
;
2854 lastdelta
= t
- sc
->sc_rlastintr
- sc
->sc_rblktime
;
2855 if (lastdelta
> sc
->sc_rblktime
/ 5) {
2856 printf("audio: record interrupt(%d) off "
2857 "relative by %ld us (%lu)\n",
2858 sc
->sc_rnintr
, lastdelta
,
2861 totdelta
= t
- sc
->sc_rfirstintr
-
2862 sc
->sc_rblktime
* sc
->sc_rnintr
;
2863 if (totdelta
> sc
->sc_rblktime
/ 2) {
2865 printf("audio: record interrupt(%d) off "
2866 "absolute by %ld us (%lu)\n",
2867 sc
->sc_rnintr
, totdelta
,
2869 sc
->sc_rnintr
++; /* avoid repeated messages */
2872 sc
->sc_rfirstintr
= t
;
2873 sc
->sc_rlastintr
= t
;
2878 if (!cb
->pause
&& sc
->sc_nrfilters
> 0) {
2879 null_fetcher
.fetch_to
= null_fetcher_fetch_to
;
2880 last_fetcher
= &sc
->sc_rfilters
[sc
->sc_nrfilters
- 1]->base
;
2881 sc
->sc_rfilters
[0]->set_fetcher(sc
->sc_rfilters
[0],
2883 used
= audio_stream_get_used(sc
->sc_rustream
);
2884 cc
= sc
->sc_rustream
->end
- sc
->sc_rustream
->start
;
2885 error
= last_fetcher
->fetch_to
2886 (last_fetcher
, sc
->sc_rustream
, cc
);
2887 cb
->fstamp
+= audio_stream_get_used(sc
->sc_rustream
) - used
;
2888 /* XXX what should do for error? */
2890 used
= audio_stream_get_used(&sc
->sc_rr
.s
);
2892 DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb
->pdrops
));
2893 cb
->pdrops
+= blksize
;
2894 cb
->s
.outp
= audio_stream_add_outp(&cb
->s
, cb
->s
.outp
, blksize
);
2895 } else if (used
+ blksize
> cb
->s
.end
- cb
->s
.start
&& !cb
->copying
) {
2896 DPRINTFN(1, ("audio_rint: drops %lu\n", cb
->drops
));
2897 cb
->drops
+= blksize
;
2898 cb
->s
.outp
= audio_stream_add_outp(&cb
->s
, cb
->s
.outp
, blksize
);
2901 DPRINTFN(2, ("audio_rint: inp=%p cc=%d\n", cb
->s
.inp
, blksize
));
2902 if (hw
->trigger_input
== NULL
) {
2903 error
= hw
->start_input(sc
->hw_hdl
, cb
->s
.inp
, blksize
,
2904 audio_rint
, (void *)sc
);
2906 /* XXX does this really help? */
2907 DPRINTF(("audio_rint: restart failed: %d\n", error
));
2912 softint_schedule(sc
->sc_sih_rd
);
2916 audio_check_params(struct audio_params
*p
)
2919 if (p
->encoding
== AUDIO_ENCODING_PCM16
) {
2920 if (p
->precision
== 8)
2921 p
->encoding
= AUDIO_ENCODING_ULINEAR
;
2923 p
->encoding
= AUDIO_ENCODING_SLINEAR
;
2924 } else if (p
->encoding
== AUDIO_ENCODING_PCM8
) {
2925 if (p
->precision
== 8)
2926 p
->encoding
= AUDIO_ENCODING_ULINEAR
;
2931 if (p
->encoding
== AUDIO_ENCODING_SLINEAR
)
2932 #if BYTE_ORDER == LITTLE_ENDIAN
2933 p
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
2935 p
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
2937 if (p
->encoding
== AUDIO_ENCODING_ULINEAR
)
2938 #if BYTE_ORDER == LITTLE_ENDIAN
2939 p
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
2941 p
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
2944 switch (p
->encoding
) {
2945 case AUDIO_ENCODING_ULAW
:
2946 case AUDIO_ENCODING_ALAW
:
2947 if (p
->precision
!= 8)
2950 case AUDIO_ENCODING_ADPCM
:
2951 if (p
->precision
!= 4 && p
->precision
!= 8)
2954 case AUDIO_ENCODING_SLINEAR_LE
:
2955 case AUDIO_ENCODING_SLINEAR_BE
:
2956 case AUDIO_ENCODING_ULINEAR_LE
:
2957 case AUDIO_ENCODING_ULINEAR_BE
:
2958 /* XXX is: our zero-fill can handle any multiple of 8 */
2959 if (p
->precision
!= 8 && p
->precision
!= 16 &&
2960 p
->precision
!= 24 && p
->precision
!= 32)
2962 if (p
->precision
== 8 && p
->encoding
== AUDIO_ENCODING_SLINEAR_BE
)
2963 p
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
2964 if (p
->precision
== 8 && p
->encoding
== AUDIO_ENCODING_ULINEAR_BE
)
2965 p
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
2966 if (p
->validbits
> p
->precision
)
2969 case AUDIO_ENCODING_MPEG_L1_STREAM
:
2970 case AUDIO_ENCODING_MPEG_L1_PACKETS
:
2971 case AUDIO_ENCODING_MPEG_L1_SYSTEM
:
2972 case AUDIO_ENCODING_MPEG_L2_STREAM
:
2973 case AUDIO_ENCODING_MPEG_L2_PACKETS
:
2974 case AUDIO_ENCODING_MPEG_L2_SYSTEM
:
2980 /* sanity check # of channels*/
2981 if (p
->channels
< 1 || p
->channels
> AUDIO_MAX_CHANNELS
)
2988 audio_set_defaults(struct audio_softc
*sc
, u_int mode
)
2990 struct audio_info ai
;
2992 /* default parameters */
2993 sc
->sc_rparams
= audio_default
;
2994 sc
->sc_pparams
= audio_default
;
2995 sc
->sc_blkset
= false;
2997 AUDIO_INITINFO(&ai
);
2998 ai
.record
.sample_rate
= sc
->sc_rparams
.sample_rate
;
2999 ai
.record
.encoding
= sc
->sc_rparams
.encoding
;
3000 ai
.record
.channels
= sc
->sc_rparams
.channels
;
3001 ai
.record
.precision
= sc
->sc_rparams
.precision
;
3002 ai
.record
.pause
= false;
3003 ai
.play
.sample_rate
= sc
->sc_pparams
.sample_rate
;
3004 ai
.play
.encoding
= sc
->sc_pparams
.encoding
;
3005 ai
.play
.channels
= sc
->sc_pparams
.channels
;
3006 ai
.play
.precision
= sc
->sc_pparams
.precision
;
3007 ai
.play
.pause
= false;
3010 return audiosetinfo(sc
, &ai
);
3014 au_set_lr_value(struct audio_softc
*sc
, mixer_ctrl_t
*ct
, int l
, int r
)
3017 ct
->type
= AUDIO_MIXER_VALUE
;
3018 ct
->un
.value
.num_channels
= 2;
3019 ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] = l
;
3020 ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] = r
;
3021 if (sc
->hw_if
->set_port(sc
->hw_hdl
, ct
) == 0)
3023 ct
->un
.value
.num_channels
= 1;
3024 ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] = (l
+r
)/2;
3025 return sc
->hw_if
->set_port(sc
->hw_hdl
, ct
);
3029 au_set_gain(struct audio_softc
*sc
, struct au_mixer_ports
*ports
,
3030 int gain
, int balance
)
3038 if (balance
== AUDIO_MID_BALANCE
) {
3040 } else if (balance
< AUDIO_MID_BALANCE
) {
3042 r
= (balance
* gain
) / AUDIO_MID_BALANCE
;
3045 l
= ((AUDIO_RIGHT_BALANCE
- balance
) * gain
)
3046 / AUDIO_MID_BALANCE
;
3048 DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n",
3049 gain
, balance
, l
, r
));
3051 if (ports
->index
== -1) {
3053 if (ports
->master
== -1)
3054 return 0; /* just ignore it silently */
3055 ct
.dev
= ports
->master
;
3056 error
= au_set_lr_value(sc
, &ct
, l
, r
);
3058 ct
.dev
= ports
->index
;
3059 if (ports
->isenum
) {
3060 ct
.type
= AUDIO_MIXER_ENUM
;
3061 error
= sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
);
3064 if (ports
->isdual
) {
3065 if (ports
->cur_port
== -1)
3066 ct
.dev
= ports
->master
;
3068 ct
.dev
= ports
->miport
[ports
->cur_port
];
3069 error
= au_set_lr_value(sc
, &ct
, l
, r
);
3071 for(i
= 0; i
< ports
->nports
; i
++)
3072 if (ports
->misel
[i
] == ct
.un
.ord
) {
3073 ct
.dev
= ports
->miport
[i
];
3075 au_set_lr_value(sc
, &ct
, l
, r
))
3082 ct
.type
= AUDIO_MIXER_SET
;
3083 error
= sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
);
3088 for(i
= 0; i
< ports
->nports
; i
++) {
3089 if (ports
->misel
[i
] & mask
) {
3090 ct
.dev
= ports
->miport
[i
];
3092 au_set_lr_value(sc
, &ct
, l
, r
) == 0)
3106 au_get_lr_value(struct audio_softc
*sc
, mixer_ctrl_t
*ct
, int *l
, int *r
)
3110 ct
->un
.value
.num_channels
= 2;
3111 if (sc
->hw_if
->get_port(sc
->hw_hdl
, ct
) == 0) {
3112 *l
= ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
];
3113 *r
= ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
];
3115 ct
->un
.value
.num_channels
= 1;
3116 error
= sc
->hw_if
->get_port(sc
->hw_hdl
, ct
);
3119 *r
= *l
= ct
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
3125 au_get_gain(struct audio_softc
*sc
, struct au_mixer_ports
*ports
,
3126 u_int
*pgain
, u_char
*pbalance
)
3132 lgain
= AUDIO_MAX_GAIN
/ 2;
3133 rgain
= AUDIO_MAX_GAIN
/ 2;
3134 if (ports
->index
== -1) {
3136 if (ports
->master
== -1)
3138 ct
.dev
= ports
->master
;
3139 ct
.type
= AUDIO_MIXER_VALUE
;
3140 if (au_get_lr_value(sc
, &ct
, &lgain
, &rgain
))
3143 ct
.dev
= ports
->index
;
3144 if (ports
->isenum
) {
3145 ct
.type
= AUDIO_MIXER_ENUM
;
3146 if (sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
))
3148 ct
.type
= AUDIO_MIXER_VALUE
;
3149 if (ports
->isdual
) {
3150 if (ports
->cur_port
== -1)
3151 ct
.dev
= ports
->master
;
3153 ct
.dev
= ports
->miport
[ports
->cur_port
];
3154 au_get_lr_value(sc
, &ct
, &lgain
, &rgain
);
3156 for(i
= 0; i
< ports
->nports
; i
++)
3157 if (ports
->misel
[i
] == ct
.un
.ord
) {
3158 ct
.dev
= ports
->miport
[i
];
3160 au_get_lr_value(sc
, &ct
,
3168 ct
.type
= AUDIO_MIXER_SET
;
3169 if (sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
))
3171 ct
.type
= AUDIO_MIXER_VALUE
;
3172 lgain
= rgain
= n
= 0;
3173 for(i
= 0; i
< ports
->nports
; i
++) {
3174 if (ports
->misel
[i
] & ct
.un
.mask
) {
3175 ct
.dev
= ports
->miport
[i
];
3177 au_get_lr_value(sc
, &ct
, &l
, &r
))
3193 if (lgain
== rgain
) { /* handles lgain==rgain==0 */
3195 *pbalance
= AUDIO_MID_BALANCE
;
3196 } else if (lgain
< rgain
) {
3198 /* balance should be > AUDIO_MID_BALANCE */
3199 *pbalance
= AUDIO_RIGHT_BALANCE
-
3200 (AUDIO_MID_BALANCE
* lgain
) / rgain
;
3201 } else /* lgain > rgain */ {
3203 /* balance should be < AUDIO_MID_BALANCE */
3204 *pbalance
= (AUDIO_MID_BALANCE
* rgain
) / lgain
;
3209 au_set_port(struct audio_softc
*sc
, struct au_mixer_ports
*ports
, u_int port
)
3212 int i
, error
, use_mixerout
;
3216 if (ports
->allports
== 0)
3217 return 0; /* Allow this special case. */
3218 else if (ports
->isdual
) {
3219 if (ports
->cur_port
== -1) {
3222 port
= ports
->aumask
[ports
->cur_port
];
3223 ports
->cur_port
= -1;
3228 if (ports
->index
== -1)
3230 ct
.dev
= ports
->index
;
3231 if (ports
->isenum
) {
3232 if (port
& (port
-1))
3233 return EINVAL
; /* Only one port allowed */
3234 ct
.type
= AUDIO_MIXER_ENUM
;
3236 for(i
= 0; i
< ports
->nports
; i
++)
3237 if (ports
->aumask
[i
] == port
) {
3238 if (ports
->isdual
&& use_mixerout
) {
3239 ct
.un
.ord
= ports
->mixerout
;
3240 ports
->cur_port
= i
;
3242 ct
.un
.ord
= ports
->misel
[i
];
3244 error
= sc
->hw_if
->set_port(sc
->hw_hdl
, &ct
);
3248 ct
.type
= AUDIO_MIXER_SET
;
3250 for(i
= 0; i
< ports
->nports
; i
++)
3251 if (ports
->aumask
[i
] & port
)
3252 ct
.un
.mask
|= ports
->misel
[i
];
3253 if (port
!= 0 && ct
.un
.mask
== 0)
3256 error
= sc
->hw_if
->set_port(sc
->hw_hdl
, &ct
);
3264 au_get_port(struct audio_softc
*sc
, struct au_mixer_ports
*ports
)
3269 if (ports
->index
== -1)
3271 ct
.dev
= ports
->index
;
3272 ct
.type
= ports
->isenum
? AUDIO_MIXER_ENUM
: AUDIO_MIXER_SET
;
3273 if (sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
))
3276 if (ports
->isenum
) {
3277 if (ports
->isdual
&& ports
->cur_port
!= -1) {
3278 if (ports
->mixerout
== ct
.un
.ord
)
3279 aumask
= ports
->aumask
[ports
->cur_port
];
3281 ports
->cur_port
= -1;
3284 for(i
= 0; i
< ports
->nports
; i
++)
3285 if (ports
->misel
[i
] == ct
.un
.ord
)
3286 aumask
= ports
->aumask
[i
];
3288 for(i
= 0; i
< ports
->nports
; i
++)
3289 if (ct
.un
.mask
& ports
->misel
[i
])
3290 aumask
|= ports
->aumask
[i
];
3296 audiosetinfo(struct audio_softc
*sc
, struct audio_info
*ai
)
3298 stream_filter_list_t pfilters
, rfilters
;
3299 audio_params_t pp
, rp
;
3300 struct audio_prinfo
*r
, *p
;
3301 const struct audio_hw_if
*hw
;
3302 audio_stream_t
*oldpus
, *oldrus
;
3307 int oldpblksize
, oldrblksize
;
3310 bool cleared
, modechange
, pausechange
;
3314 if (hw
== NULL
) /* HW has not attached */
3317 DPRINTF(("%s sc=%p ai=%p\n", __func__
, sc
, ai
));
3325 pausechange
= false;
3327 pp
= sc
->sc_pparams
; /* Temporary encoding storage in */
3328 rp
= sc
->sc_rparams
; /* case setting the modes fails. */
3331 if (SPECIFIED(p
->sample_rate
)) {
3332 pp
.sample_rate
= p
->sample_rate
;
3335 if (SPECIFIED(r
->sample_rate
)) {
3336 rp
.sample_rate
= r
->sample_rate
;
3339 if (SPECIFIED(p
->encoding
)) {
3340 pp
.encoding
= p
->encoding
;
3343 if (SPECIFIED(r
->encoding
)) {
3344 rp
.encoding
= r
->encoding
;
3347 if (SPECIFIED(p
->precision
)) {
3348 pp
.precision
= p
->precision
;
3349 /* we don't have API to specify validbits */
3350 pp
.validbits
= p
->precision
;
3353 if (SPECIFIED(r
->precision
)) {
3354 rp
.precision
= r
->precision
;
3355 /* we don't have API to specify validbits */
3356 rp
.validbits
= r
->precision
;
3359 if (SPECIFIED(p
->channels
)) {
3360 pp
.channels
= p
->channels
;
3363 if (SPECIFIED(r
->channels
)) {
3364 rp
.channels
= r
->channels
;
3368 if (!audio_can_capture(sc
))
3370 if (!audio_can_playback(sc
))
3374 if (audiodebug
&& nr
> 0)
3375 audio_print_params("audiosetinfo() Setting record params:", &rp
);
3376 if (audiodebug
&& np
> 0)
3377 audio_print_params("audiosetinfo() Setting play params:", &pp
);
3379 if (nr
> 0 && (error
= audio_check_params(&rp
)))
3381 if (np
> 0 && (error
= audio_check_params(&pp
)))
3384 oldpblksize
= sc
->sc_pr
.blksize
;
3385 oldrblksize
= sc
->sc_rr
.blksize
;
3394 setmode
|= AUMODE_RECORD
;
3402 setmode
|= AUMODE_PLAY
;
3405 if (SPECIFIED(ai
->mode
)) {
3411 sc
->sc_mode
= ai
->mode
;
3412 if (sc
->sc_mode
& AUMODE_PLAY_ALL
)
3413 sc
->sc_mode
|= AUMODE_PLAY
;
3414 if ((sc
->sc_mode
& AUMODE_PLAY
) && !sc
->sc_full_duplex
)
3415 /* Play takes precedence */
3416 sc
->sc_mode
&= ~AUMODE_RECORD
;
3419 oldpus
= sc
->sc_pustream
;
3420 oldrus
= sc
->sc_rustream
;
3424 indep
= audio_get_props(sc
) & AUDIO_PROP_INDEPENDENT
;
3426 if (setmode
== AUMODE_RECORD
)
3428 else if (setmode
== AUMODE_PLAY
)
3431 memset(&pfilters
, 0, sizeof(pfilters
));
3432 memset(&rfilters
, 0, sizeof(rfilters
));
3433 pfilters
.append
= stream_filter_list_append
;
3434 pfilters
.prepend
= stream_filter_list_prepend
;
3435 pfilters
.set
= stream_filter_list_set
;
3436 rfilters
.append
= stream_filter_list_append
;
3437 rfilters
.prepend
= stream_filter_list_prepend
;
3438 rfilters
.set
= stream_filter_list_set
;
3439 /* Some device drivers change channels/sample_rate and change
3440 * no channels/sample_rate. */
3441 error
= hw
->set_params(sc
->hw_hdl
, setmode
,
3442 sc
->sc_mode
& (AUMODE_PLAY
| AUMODE_RECORD
), &pp
, &rp
,
3443 &pfilters
, &rfilters
);
3445 DPRINTF(("%s: hw->set_params() failed with %d\n",
3450 audio_check_params(&pp
);
3451 audio_check_params(&rp
);
3453 /* XXX for !indep device, we have to use the same
3454 * parameters for the hardware, not userland */
3455 if (setmode
== AUMODE_RECORD
) {
3457 } else if (setmode
== AUMODE_PLAY
) {
3462 if (sc
->sc_pr
.mmapped
&& pfilters
.req_size
> 0) {
3463 DPRINTF(("%s: mmapped, and filters are requested.\n",
3469 /* construct new filter chain */
3470 if (setmode
& AUMODE_PLAY
) {
3471 error
= audio_setup_pfilters(sc
, &pp
, &pfilters
);
3475 if (setmode
& AUMODE_RECORD
) {
3476 error
= audio_setup_rfilters(sc
, &rp
, &rfilters
);
3480 DPRINTF(("%s: filter setup is completed.\n", __func__
));
3482 /* userland formats */
3483 sc
->sc_pparams
= pp
;
3484 sc
->sc_rparams
= rp
;
3487 /* Play params can affect the record params, so recalculate blksize. */
3488 if (nr
> 0 || np
> 0) {
3489 audio_calc_blksize(sc
, AUMODE_RECORD
);
3490 audio_calc_blksize(sc
, AUMODE_PLAY
);
3493 if (audiodebug
> 1 && nr
> 0)
3494 audio_print_params("audiosetinfo() After setting record params:", &sc
->sc_rparams
);
3495 if (audiodebug
> 1 && np
> 0)
3496 audio_print_params("audiosetinfo() After setting play params:", &sc
->sc_pparams
);
3499 if (SPECIFIED(p
->port
)) {
3504 error
= au_set_port(sc
, &sc
->sc_outports
, p
->port
);
3508 if (SPECIFIED(r
->port
)) {
3513 error
= au_set_port(sc
, &sc
->sc_inports
, r
->port
);
3517 if (SPECIFIED(p
->gain
)) {
3518 au_get_gain(sc
, &sc
->sc_outports
, &gain
, &balance
);
3519 error
= au_set_gain(sc
, &sc
->sc_outports
, p
->gain
, balance
);
3523 if (SPECIFIED(r
->gain
)) {
3524 au_get_gain(sc
, &sc
->sc_inports
, &gain
, &balance
);
3525 error
= au_set_gain(sc
, &sc
->sc_inports
, r
->gain
, balance
);
3530 if (SPECIFIED_CH(p
->balance
)) {
3531 au_get_gain(sc
, &sc
->sc_outports
, &gain
, &balance
);
3532 error
= au_set_gain(sc
, &sc
->sc_outports
, gain
, p
->balance
);
3536 if (SPECIFIED_CH(r
->balance
)) {
3537 au_get_gain(sc
, &sc
->sc_inports
, &gain
, &balance
);
3538 error
= au_set_gain(sc
, &sc
->sc_inports
, gain
, r
->balance
);
3543 if (SPECIFIED(ai
->monitor_gain
) && sc
->sc_monitor_port
!= -1) {
3546 ct
.dev
= sc
->sc_monitor_port
;
3547 ct
.type
= AUDIO_MIXER_VALUE
;
3548 ct
.un
.value
.num_channels
= 1;
3549 ct
.un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] = ai
->monitor_gain
;
3550 error
= sc
->hw_if
->set_port(sc
->hw_hdl
, &ct
);
3555 if (SPECIFIED_CH(p
->pause
)) {
3556 sc
->sc_pr
.pause
= p
->pause
;
3560 if (SPECIFIED_CH(r
->pause
)) {
3561 sc
->sc_rr
.pause
= r
->pause
;
3566 if (SPECIFIED(ai
->blocksize
)) {
3567 int pblksize
, rblksize
;
3569 /* Block size specified explicitly. */
3570 if (ai
->blocksize
== 0) {
3575 sc
->sc_blkset
= false;
3576 audio_calc_blksize(sc
, AUMODE_RECORD
);
3577 audio_calc_blksize(sc
, AUMODE_PLAY
);
3579 sc
->sc_blkset
= true;
3580 /* check whether new blocksize changes actually */
3581 if (hw
->round_blocksize
== NULL
) {
3586 sc
->sc_pr
.blksize
= ai
->blocksize
;
3587 sc
->sc_rr
.blksize
= ai
->blocksize
;
3589 pblksize
= hw
->round_blocksize(sc
->hw_hdl
,
3590 ai
->blocksize
, AUMODE_PLAY
, &sc
->sc_pr
.s
.param
);
3591 rblksize
= hw
->round_blocksize(sc
->hw_hdl
,
3592 ai
->blocksize
, AUMODE_RECORD
, &sc
->sc_rr
.s
.param
);
3593 if (pblksize
!= sc
->sc_pr
.blksize
||
3594 rblksize
!= sc
->sc_rr
.blksize
) {
3599 sc
->sc_pr
.blksize
= ai
->blocksize
;
3600 sc
->sc_rr
.blksize
= ai
->blocksize
;
3606 if (SPECIFIED(ai
->mode
)) {
3607 if (sc
->sc_mode
& AUMODE_PLAY
)
3608 audio_init_play(sc
);
3609 if (sc
->sc_mode
& AUMODE_RECORD
)
3610 audio_init_record(sc
);
3613 if (hw
->commit_settings
) {
3614 error
= hw
->commit_settings(sc
->hw_hdl
);
3619 sc
->sc_lastinfo
= *ai
;
3620 sc
->sc_lastinfovalid
= true;
3623 if (cleared
|| pausechange
) {
3627 init_error
= audio_initbufs(sc
);
3628 if (init_error
) goto err
;
3629 if (sc
->sc_pr
.blksize
!= oldpblksize
||
3630 sc
->sc_rr
.blksize
!= oldrblksize
||
3631 sc
->sc_pustream
!= oldpus
||
3632 sc
->sc_rustream
!= oldrus
)
3633 audio_calcwater(sc
);
3634 if ((sc
->sc_mode
& AUMODE_PLAY
) &&
3635 pbus
&& !sc
->sc_pbus
)
3636 init_error
= audiostartp(sc
);
3638 (sc
->sc_mode
& AUMODE_RECORD
) &&
3639 rbus
&& !sc
->sc_rbus
)
3640 init_error
= audiostartr(sc
);
3647 /* Change water marks after initializing the buffers. */
3648 if (SPECIFIED(ai
->hiwat
)) {
3650 if (blks
> sc
->sc_pr
.maxblks
)
3651 blks
= sc
->sc_pr
.maxblks
;
3654 sc
->sc_pr
.usedhigh
= blks
* sc
->sc_pr
.blksize
;
3656 if (SPECIFIED(ai
->lowat
)) {
3658 if (blks
> sc
->sc_pr
.maxblks
- 1)
3659 blks
= sc
->sc_pr
.maxblks
- 1;
3660 sc
->sc_pr
.usedlow
= blks
* sc
->sc_pr
.blksize
;
3662 if (SPECIFIED(ai
->hiwat
) || SPECIFIED(ai
->lowat
)) {
3663 if (sc
->sc_pr
.usedlow
> sc
->sc_pr
.usedhigh
- sc
->sc_pr
.blksize
)
3665 sc
->sc_pr
.usedhigh
- sc
->sc_pr
.blksize
;
3672 audiogetinfo(struct audio_softc
*sc
, struct audio_info
*ai
, int buf_only_mode
)
3674 struct audio_prinfo
*r
, *p
;
3675 const struct audio_hw_if
*hw
;
3680 if (hw
== NULL
) /* HW has not attached */
3683 p
->sample_rate
= sc
->sc_pparams
.sample_rate
;
3684 r
->sample_rate
= sc
->sc_rparams
.sample_rate
;
3685 p
->channels
= sc
->sc_pparams
.channels
;
3686 r
->channels
= sc
->sc_rparams
.channels
;
3687 p
->precision
= sc
->sc_pparams
.precision
;
3688 r
->precision
= sc
->sc_rparams
.precision
;
3689 p
->encoding
= sc
->sc_pparams
.encoding
;
3690 r
->encoding
= sc
->sc_rparams
.encoding
;
3692 if (buf_only_mode
) {
3705 r
->port
= au_get_port(sc
, &sc
->sc_inports
);
3706 p
->port
= au_get_port(sc
, &sc
->sc_outports
);
3708 r
->avail_ports
= sc
->sc_inports
.allports
;
3709 p
->avail_ports
= sc
->sc_outports
.allports
;
3711 au_get_gain(sc
, &sc
->sc_inports
, &r
->gain
, &r
->balance
);
3712 au_get_gain(sc
, &sc
->sc_outports
, &p
->gain
, &p
->balance
);
3715 if (sc
->sc_monitor_port
!= -1 && buf_only_mode
== 0) {
3718 ct
.dev
= sc
->sc_monitor_port
;
3719 ct
.type
= AUDIO_MIXER_VALUE
;
3720 ct
.un
.value
.num_channels
= 1;
3721 if (sc
->hw_if
->get_port(sc
->hw_hdl
, &ct
))
3722 ai
->monitor_gain
= 0;
3725 ct
.un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
3727 ai
->monitor_gain
= 0;
3729 p
->seek
= audio_stream_get_used(sc
->sc_pustream
);
3730 r
->seek
= audio_stream_get_used(sc
->sc_rustream
);
3733 * XXX samples should be a value for userland data.
3734 * But drops is a value for HW data.
3736 p
->samples
= (sc
->sc_pustream
== &sc
->sc_pr
.s
3737 ? sc
->sc_pr
.stamp
: sc
->sc_pr
.fstamp
) - sc
->sc_pr
.drops
;
3738 r
->samples
= (sc
->sc_rustream
== &sc
->sc_rr
.s
3739 ? sc
->sc_rr
.stamp
: sc
->sc_rr
.fstamp
) - sc
->sc_rr
.drops
;
3741 p
->eof
= sc
->sc_eof
;
3744 p
->pause
= sc
->sc_pr
.pause
;
3745 r
->pause
= sc
->sc_rr
.pause
;
3747 p
->error
= sc
->sc_pr
.drops
!= 0;
3748 r
->error
= sc
->sc_rr
.drops
!= 0;
3750 p
->waiting
= r
->waiting
= 0; /* open never hangs */
3752 p
->open
= (sc
->sc_open
& AUOPEN_WRITE
) != 0;
3753 r
->open
= (sc
->sc_open
& AUOPEN_READ
) != 0;
3755 p
->active
= sc
->sc_pbus
;
3756 r
->active
= sc
->sc_rbus
;
3758 p
->buffer_size
= sc
->sc_pustream
? sc
->sc_pustream
->bufsize
: 0;
3759 r
->buffer_size
= sc
->sc_rustream
? sc
->sc_rustream
->bufsize
: 0;
3761 ai
->blocksize
= sc
->sc_pr
.blksize
;
3762 if (sc
->sc_pr
.blksize
> 0) {
3763 ai
->hiwat
= sc
->sc_pr
.usedhigh
/ sc
->sc_pr
.blksize
;
3764 ai
->lowat
= sc
->sc_pr
.usedlow
/ sc
->sc_pr
.blksize
;
3766 ai
->hiwat
= ai
->lowat
= 0;
3767 ai
->mode
= sc
->sc_mode
;
3776 mixer_open(dev_t dev
, struct audio_softc
*sc
, int flags
,
3777 int ifmt
, struct lwp
*l
)
3779 if (sc
->hw_if
== NULL
)
3782 DPRINTF(("mixer_open: flags=0x%x sc=%p\n", flags
, sc
));
3788 * Remove a process from those to be signalled on mixer activity.
3791 mixer_remove(struct audio_softc
*sc
, struct lwp
*l
)
3793 struct mixer_asyncs
**pm
, *m
;
3801 for (pm
= &sc
->sc_async_mixer
; *pm
; pm
= &(*pm
)->next
) {
3802 if ((*pm
)->proc
== p
) {
3812 * Signal all processes waiting for the mixer.
3815 mixer_signal(struct audio_softc
*sc
)
3817 struct mixer_asyncs
*m
;
3819 for (m
= sc
->sc_async_mixer
; m
; m
= m
->next
) {
3820 mutex_enter(proc_lock
);
3821 psignal(m
->proc
, SIGIO
);
3822 mutex_exit(proc_lock
);
3827 * Close a mixer device
3831 mixer_close(struct audio_softc
*sc
, int flags
, int ifmt
,
3835 DPRINTF(("mixer_close: sc %p\n", sc
));
3836 mixer_remove(sc
, l
);
3841 mixer_ioctl(struct audio_softc
*sc
, u_long cmd
, void *addr
, int flag
,
3844 const struct audio_hw_if
*hw
;
3848 DPRINTF(("mixer_ioctl(%lu,'%c',%lu)\n",
3849 IOCPARM_LEN(cmd
), (char)IOCGROUP(cmd
), cmd
&0xff));
3853 /* we can return cached values if we are sleeping */
3854 if (cmd
!= AUDIO_MIXER_READ
)
3855 device_active(sc
->dev
, DVA_SYSTEM
);
3859 mixer_remove(sc
, l
); /* remove old entry */
3861 struct mixer_asyncs
*ma
;
3862 ma
= malloc(sizeof (struct mixer_asyncs
),
3863 M_DEVBUF
, M_WAITOK
);
3864 ma
->next
= sc
->sc_async_mixer
;
3865 ma
->proc
= l
->l_proc
;
3866 sc
->sc_async_mixer
= ma
;
3872 DPRINTF(("AUDIO_GETDEV\n"));
3873 error
= hw
->getdev(sc
->hw_hdl
, (audio_device_t
*)addr
);
3876 case AUDIO_MIXER_DEVINFO
:
3877 DPRINTF(("AUDIO_MIXER_DEVINFO\n"));
3878 ((mixer_devinfo_t
*)addr
)->un
.v
.delta
= 0; /* default */
3879 error
= hw
->query_devinfo(sc
->hw_hdl
, (mixer_devinfo_t
*)addr
);
3882 case AUDIO_MIXER_READ
:
3883 DPRINTF(("AUDIO_MIXER_READ\n"));
3884 mc
= (mixer_ctrl_t
*)addr
;
3886 if (device_is_active(sc
->sc_dev
) ||
3887 sc
->sc_mixer_state
== NULL
)
3888 error
= hw
->get_port(sc
->hw_hdl
, mc
);
3889 else if (mc
->dev
>= sc
->sc_nmixer_states
)
3893 memcpy(mc
, &sc
->sc_mixer_state
[dev
],
3894 sizeof(mixer_ctrl_t
));
3899 case AUDIO_MIXER_WRITE
:
3900 DPRINTF(("AUDIO_MIXER_WRITE\n"));
3901 error
= hw
->set_port(sc
->hw_hdl
, (mixer_ctrl_t
*)addr
);
3902 if (!error
&& hw
->commit_settings
)
3903 error
= hw
->commit_settings(sc
->hw_hdl
);
3910 error
= hw
->dev_ioctl(sc
->hw_hdl
, cmd
, addr
, flag
, l
);
3915 DPRINTF(("mixer_ioctl(%lu,'%c',%lu) result %d\n",
3916 IOCPARM_LEN(cmd
), (char)IOCGROUP(cmd
), cmd
&0xff, error
));
3919 #endif /* NAUDIO > 0 */
3923 #if NAUDIO == 0 && (NMIDI > 0 || NMIDIBUS > 0)
3924 #include <sys/param.h>
3925 #include <sys/systm.h>
3926 #include <sys/device.h>
3927 #include <sys/audioio.h>
3928 #include <dev/audio_if.h>
3931 #if NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0)
3933 audioprint(void *aux
, const char *pnp
)
3935 struct audio_attach_args
*arg
;
3940 switch (arg
->type
) {
3941 case AUDIODEV_TYPE_AUDIO
:
3944 case AUDIODEV_TYPE_MIDI
:
3947 case AUDIODEV_TYPE_OPL
:
3950 case AUDIODEV_TYPE_MPU
:
3954 panic("audioprint: unknown type %d", arg
->type
);
3956 aprint_normal("%s at %s", type
, pnp
);
3961 #endif /* NAUDIO > 0 || (NMIDI > 0 || NMIDIBUS > 0) */
3965 audio_mixer_capture(struct audio_softc
*sc
)
3970 for (mi
.index
= 0; ; mi
.index
++)
3971 if (sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) != 0)
3975 if (sc
->sc_mixer_state
!= NULL
&& sc
->sc_nmixer_states
!= mi
.index
) {
3976 free(sc
->sc_mixer_state
, M_DEVBUF
);
3977 sc
->sc_mixer_state
= NULL
;
3981 sc
->sc_nmixer_states
= mi
.index
;
3982 if (sc
->sc_mixer_state
== NULL
)
3983 sc
->sc_mixer_state
= malloc(
3984 sizeof(mixer_ctrl_t
) * sc
->sc_nmixer_states
,
3985 M_DEVBUF
, M_NOWAIT
);
3986 if (sc
->sc_mixer_state
== NULL
) {
3987 aprint_error("%s: couldn't allocate memory for mixer state\n",
3988 device_xname(sc
->dev
));
3992 for (mi
.index
= 0; ; mi
.index
++) {
3993 if (sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) != 0)
3995 if (mi
.type
== AUDIO_MIXER_CLASS
)
3997 mc
= &sc
->sc_mixer_state
[mi
.index
];
4000 mc
->un
.value
.num_channels
= mi
.un
.v
.num_channels
;
4001 (void)sc
->hw_if
->get_port(sc
->hw_hdl
, mc
);
4008 audio_mixer_restore(struct audio_softc
*sc
)
4013 if (sc
->sc_mixer_state
== NULL
)
4016 for (mi
.index
= 0; ; mi
.index
++) {
4017 if (sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) != 0)
4019 if (mi
.type
== AUDIO_MIXER_CLASS
)
4021 mc
= &sc
->sc_mixer_state
[mi
.index
];
4022 (void)sc
->hw_if
->set_port(sc
->hw_hdl
, mc
);
4024 if (sc
->hw_if
->commit_settings
)
4025 sc
->hw_if
->commit_settings(sc
->hw_hdl
);
4030 #ifdef AUDIO_PM_IDLE
4032 audio_idle(void *arg
)
4035 struct audio_softc
*sc
= device_private(dv
);
4038 extern int pnp_debug_idle
;
4040 printf("%s: idle handler called\n", device_xname(dv
));
4045 /* XXX joerg Make pmf_device_suspend handle children? */
4046 if (!pmf_device_suspend(dv
, PMF_Q_SELF
))
4049 if (!pmf_device_suspend(sc
->sc_dev
, PMF_Q_SELF
))
4050 pmf_device_resume(dv
, PMF_Q_SELF
);
4054 audio_activity(device_t dv
, devactive_t type
)
4056 struct audio_softc
*sc
= device_private(dv
);
4058 if (type
!= DVA_SYSTEM
)
4061 callout_schedule(&sc
->sc_idle_counter
, audio_idle_timeout
* hz
);
4063 sc
->sc_idle
= false;
4064 if (!device_is_active(dv
)) {
4065 /* XXX joerg How to deal with a failing resume... */
4066 pmf_device_resume(sc
->sc_dev
, PMF_Q_SELF
);
4067 pmf_device_resume(dv
, PMF_Q_SELF
);
4073 audio_suspend(device_t dv
, pmf_qual_t qual
)
4075 struct audio_softc
*sc
= device_private(dv
);
4076 const struct audio_hw_if
*hwp
= sc
->hw_if
;
4080 audio_mixer_capture(sc
);
4081 if (sc
->sc_pbus
== true)
4082 hwp
->halt_output(sc
->hw_hdl
);
4083 if (sc
->sc_rbus
== true)
4084 hwp
->halt_input(sc
->hw_hdl
);
4085 #ifdef AUDIO_PM_IDLE
4086 callout_stop(&sc
->sc_idle_counter
);
4094 audio_resume(device_t dv
, pmf_qual_t qual
)
4096 struct audio_softc
*sc
= device_private(dv
);
4100 if (sc
->sc_lastinfovalid
)
4101 audiosetinfo(sc
, &sc
->sc_lastinfo
);
4102 audio_mixer_restore(sc
);
4103 if ((sc
->sc_pbus
== true) && !sc
->sc_pr
.pause
)
4105 if ((sc
->sc_rbus
== true) && !sc
->sc_rr
.pause
)
4113 audio_volume_down(device_t dv
)
4115 struct audio_softc
*sc
= device_private(dv
);
4122 if (sc
->sc_outports
.index
== -1 && sc
->sc_outports
.master
!= -1) {
4123 mi
.index
= sc
->sc_outports
.master
;
4125 if (sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) != 0)
4129 au_get_gain(sc
, &sc
->sc_outports
, &gain
, &balance
);
4130 newgain
= gain
- mi
.un
.v
.delta
;
4131 if (newgain
< AUDIO_MIN_GAIN
)
4132 newgain
= AUDIO_MIN_GAIN
;
4133 au_set_gain(sc
, &sc
->sc_outports
, newgain
, balance
);
4139 audio_volume_up(device_t dv
)
4141 struct audio_softc
*sc
= device_private(dv
);
4143 u_int gain
, newgain
;
4147 if (sc
->sc_outports
.index
== -1 && sc
->sc_outports
.master
!= -1) {
4148 mi
.index
= sc
->sc_outports
.master
;
4150 if (sc
->hw_if
->query_devinfo(sc
->hw_hdl
, &mi
) != 0)
4154 au_get_gain(sc
, &sc
->sc_outports
, &gain
, &balance
);
4155 newgain
= gain
+ mi
.un
.v
.delta
;
4156 if (newgain
> AUDIO_MAX_GAIN
)
4157 newgain
= AUDIO_MAX_GAIN
;
4158 au_set_gain(sc
, &sc
->sc_outports
, newgain
, balance
);
4164 audio_volume_toggle(device_t dv
)
4166 struct audio_softc
*sc
= device_private(dv
);
4167 u_int gain
, newgain
;
4172 au_get_gain(sc
, &sc
->sc_outports
, &gain
, &balance
);
4174 sc
->sc_lastgain
= gain
;
4177 newgain
= sc
->sc_lastgain
;
4178 au_set_gain(sc
, &sc
->sc_outports
, newgain
, balance
);
4183 audio_get_props(struct audio_softc
*sc
)
4185 const struct audio_hw_if
*hw
;
4189 props
= hw
->get_props(sc
->hw_hdl
);
4192 * if neither playback nor capture properties are reported,
4193 * assume both are supported by the device driver
4195 if ((props
& (AUDIO_PROP_PLAYBACK
|AUDIO_PROP_CAPTURE
)) == 0)
4196 props
|= (AUDIO_PROP_PLAYBACK
| AUDIO_PROP_CAPTURE
);
4202 audio_can_playback(struct audio_softc
*sc
)
4204 return audio_get_props(sc
) & AUDIO_PROP_PLAYBACK
? true : false;
4208 audio_can_capture(struct audio_softc
*sc
)
4210 return audio_get_props(sc
) & AUDIO_PROP_CAPTURE
? true : false;
4213 #endif /* NAUDIO > 0 */