Home | History | Annotate | Line # | Download | only in dev
aucc.c revision 1.26
      1 /*	$NetBSD: aucc.c,v 1.26 2000/09/03 02:04:53 mhitch Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1999 Bernardo Innocenti
      5  * All rights reserved.
      6  *
      7  * Copyright (c) 1997 Stephan Thesing
      8  * All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *      This product includes software developed by Stephan Thesing.
     21  * 4. The name of the author may not be used to endorse or promote products
     22  *    derived from this software without specific prior written permission
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     33  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 /* TODO:
     37  *
     38  * - ulaw -> 14bit conversion
     39  * - channel allocation is wrong for 14bit mono
     40  * - convert the... err... conversion routines to 68k asm for best performance
     41  * 	XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont
     42  *	want to make life difficult for amigappc work.
     43  *		-is
     44  *
     45  * - rely on auconv.c routines for ulaw/alaw conversions
     46  * - perhaps use a calibration table for better 14bit output
     47  * - set 31KHz AGA video mode to allow 44.1KHz even if grfcc is missing
     48  *	in the kernel
     49  * - 14bit output requires maximum volume
     50  */
     51 
     52 #include "aucc.h"
     53 #if NAUCC > 0
     54 
     55 #include <sys/param.h>
     56 #include <sys/systm.h>
     57 #include <sys/errno.h>
     58 #include <sys/ioctl.h>
     59 #include <sys/device.h>
     60 #include <sys/proc.h>
     61 #include <machine/cpu.h>
     62 
     63 #include <sys/audioio.h>
     64 #include <dev/audio_if.h>
     65 #include <amiga/amiga/cc.h>
     66 #include <amiga/amiga/custom.h>
     67 #include <amiga/amiga/device.h>
     68 #include <amiga/dev/auccvar.h>
     69 
     70 
     71 #ifdef LEV6_DEFER
     72 #define AUCC_MAXINT 3
     73 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
     74 #else
     75 #define AUCC_MAXINT 4
     76 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
     77 #endif
     78 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
     79 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
     80 
     81 #ifdef AUDIO_DEBUG
     82 /*extern printf __P((const char *,...));*/
     83 int     auccdebug = 1;
     84 #define DPRINTF(x)      if (auccdebug) printf x
     85 #else
     86 #define DPRINTF(x)
     87 #endif
     88 
     89 #ifdef splaudio
     90 #undef splaudio
     91 #endif
     92 
     93 #define splaudio() spl4();
     94 
     95 /* clock frequency.. */
     96 extern int eclockfreq;
     97 
     98 
     99 /* hw audio ch */
    100 extern struct audio_channel channel[4];
    101 
    102 
    103 /*
    104  * Software state.
    105  */
    106 struct aucc_softc {
    107 	struct	device sc_dev;		/* base device */
    108 
    109 	int	sc_open;		/* single use device */
    110 	aucc_data_t sc_channel[4];	/* per channel freq, ... */
    111 	u_int	sc_encoding;		/* encoding AUDIO_ENCODING_.*/
    112 	int	sc_channels;		/* # of channels used */
    113 	int	sc_precision;		/* 8 or 16 bits */
    114 	int	sc_14bit;		/* 14bit output enabled */
    115 
    116 	int	sc_intrcnt;		/* interrupt count */
    117 	int	sc_channelmask;  	/* which channels are used ? */
    118 	void (*sc_decodefunc) __P((u_char **, u_char *, int));
    119 				/* pointer to format conversion routine */
    120 };
    121 
    122 /* interrupt interfaces */
    123 void aucc_inthdl __P((int));
    124 
    125 /* forward declarations */
    126 static int init_aucc __P((struct aucc_softc *));
    127 static u_int freqtoper  __P((u_int));
    128 static u_int pertofreq  __P((u_int));
    129 
    130 /* autoconfiguration driver */
    131 void	auccattach __P((struct device *, struct device *, void *));
    132 int	auccmatch __P((struct device *, struct cfdata *, void *));
    133 
    134 struct cfattach aucc_ca = {
    135 	sizeof(struct aucc_softc),
    136 	auccmatch,
    137 	auccattach
    138 };
    139 
    140 struct audio_device aucc_device = {
    141 	"Amiga-audio",
    142 	"2.0",
    143 	"aucc"
    144 };
    145 
    146 
    147 struct aucc_softc *aucc=NULL;
    148 
    149 
    150 unsigned char ulaw_to_lin[] = {
    151 	0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
    152 	0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
    153 	0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
    154 	0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
    155 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
    156 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
    157 	0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
    158 	0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
    159 	0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
    160 	0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
    161 	0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
    162 	0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
    163 	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
    164 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    165 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    166 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    167 	0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
    168 	0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
    169 	0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
    170 	0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
    171 	0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
    172 	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
    173 	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
    174 	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
    175 	0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
    176 	0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
    177 	0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
    178 	0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
    179 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    180 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    181 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    182 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    183 };
    184 
    185 /*
    186  * Define our interface to the higher level audio driver.
    187  */
    188 int	aucc_open __P((void *, int));
    189 void	aucc_close __P((void *));
    190 int	aucc_set_out_sr __P((void *, u_long));
    191 int	aucc_query_encoding __P((void *, struct audio_encoding *));
    192 int	aucc_round_blocksize __P((void *, int));
    193 int	aucc_commit_settings __P((void *));
    194 int	aucc_start_output __P((void *, void *, int, void (*)(void *),
    195 				  void *));
    196 int	aucc_start_input __P((void *, void *, int, void (*)(void *),
    197 				 void *));
    198 int	aucc_halt_output __P((void *));
    199 int	aucc_halt_input __P((void *));
    200 int	aucc_getdev __P((void *, struct audio_device *));
    201 int	aucc_set_port __P((void *, mixer_ctrl_t *));
    202 int	aucc_get_port __P((void *, mixer_ctrl_t *));
    203 int	aucc_query_devinfo __P((void *, mixer_devinfo_t *));
    204 void	aucc_encode __P((int, int, int, int, u_char *, u_short **));
    205 int	aucc_set_params __P((void *, int, int,
    206 	    struct audio_params *, struct audio_params *));
    207 int	aucc_get_props __P((void *));
    208 
    209 
    210 static void aucc_decode_slinear8_1ch __P((u_char **, u_char *, int));
    211 static void aucc_decode_slinear8_2ch __P((u_char **, u_char *, int));
    212 static void aucc_decode_slinear8_3ch __P((u_char **, u_char *, int));
    213 static void aucc_decode_slinear8_4ch __P((u_char **, u_char *, int));
    214 
    215 static void aucc_decode_ulinear8_1ch __P((u_char **, u_char *, int));
    216 static void aucc_decode_ulinear8_2ch __P((u_char **, u_char *, int));
    217 static void aucc_decode_ulinear8_3ch __P((u_char **, u_char *, int));
    218 static void aucc_decode_ulinear8_4ch __P((u_char **, u_char *, int));
    219 
    220 static void aucc_decode_ulaw_1ch __P((u_char **, u_char *, int));
    221 static void aucc_decode_ulaw_2ch __P((u_char **, u_char *, int));
    222 static void aucc_decode_ulaw_3ch __P((u_char **, u_char *, int));
    223 static void aucc_decode_ulaw_4ch __P((u_char **, u_char *, int));
    224 
    225 static void aucc_decode_slinear16_1ch __P((u_char **, u_char *, int));
    226 static void aucc_decode_slinear16_2ch __P((u_char **, u_char *, int));
    227 static void aucc_decode_slinear16_3ch __P((u_char **, u_char *, int));
    228 static void aucc_decode_slinear16_4ch __P((u_char **, u_char *, int));
    229 
    230 static void aucc_decode_slinear16sw_1ch __P((u_char **, u_char *, int));
    231 static void aucc_decode_slinear16sw_2ch __P((u_char **, u_char *, int));
    232 static void aucc_decode_slinear16sw_3ch __P((u_char **, u_char *, int));
    233 static void aucc_decode_slinear16sw_4ch __P((u_char **, u_char *, int));
    234 
    235 
    236 
    237 struct audio_hw_if sa_hw_if = {
    238 	aucc_open,
    239 	aucc_close,
    240 	NULL,
    241 	aucc_query_encoding,
    242 	aucc_set_params,
    243 	aucc_round_blocksize,
    244 	aucc_commit_settings,
    245 	NULL,
    246 	NULL,
    247 	aucc_start_output,
    248 	aucc_start_input,
    249 	aucc_halt_output,
    250 	aucc_halt_input,
    251 	NULL,
    252 	aucc_getdev,
    253 	NULL,
    254 	aucc_set_port,
    255 	aucc_get_port,
    256 	aucc_query_devinfo,
    257 	NULL,
    258 	NULL,
    259 	NULL,
    260 	NULL,
    261 	aucc_get_props,
    262 };
    263 
    264 /* autoconfig routines */
    265 
    266 int
    267 auccmatch(pdp, cfp, aux)
    268 	struct device *pdp;
    269 	struct cfdata *cfp;
    270 	void *aux;
    271 {
    272 	static int aucc_matched = 0;
    273 
    274 	if (!matchname((char *)aux, "aucc") ||
    275 #ifdef DRACO
    276 	    is_draco() ||
    277 #endif
    278 	    aucc_matched)
    279 		return 0;
    280 
    281 	aucc_matched = 1;
    282 	return 1;
    283 }
    284 
    285 /*
    286  * Audio chip found.
    287  */
    288 void
    289 auccattach(parent, self, args)
    290 	struct device *parent, *self;
    291 	void *args;
    292 {
    293 	register struct aucc_softc *sc = (struct aucc_softc *)self;
    294 	register int i;
    295 
    296 	printf("\n");
    297 
    298 	if((i=init_aucc(sc))) {
    299 		printf("audio: no chipmem\n");
    300 		return;
    301 	}
    302 
    303 	audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
    304 }
    305 
    306 
    307 static int
    308 init_aucc(sc)
    309 	struct aucc_softc *sc;
    310 {
    311 	register int i, err=0;
    312 
    313 	/* init values per channel */
    314  	for (i=0;i<4;i++) {
    315 		sc->sc_channel[i].nd_freq=8000;
    316 		sc->sc_channel[i].nd_per=freqtoper(8000);
    317 		sc->sc_channel[i].nd_busy=0;
    318 		sc->sc_channel[i].nd_dma=alloc_chipmem(AUDIO_BUF_SIZE*2);
    319 		if (sc->sc_channel[i].nd_dma==NULL)
    320 			err=1;
    321 	 	sc->sc_channel[i].nd_dmalength=0;
    322 		sc->sc_channel[i].nd_volume=64;
    323 		sc->sc_channel[i].nd_intr=NULL;
    324 		sc->sc_channel[i].nd_intrdata=NULL;
    325 		sc->sc_channel[i].nd_doublebuf=0;
    326 		DPRINTF(("dma buffer for channel %d is %p\n", i,
    327 		    sc->sc_channel[i].nd_dma));
    328 	}
    329 
    330 	if (err) {
    331 		for(i=0;i<4;i++)
    332 			if (sc->sc_channel[i].nd_dma)
    333 				free_chipmem(sc->sc_channel[i].nd_dma);
    334 	}
    335 
    336 	sc->sc_channels=1;
    337 	sc->sc_channelmask=0xf;
    338 	sc->sc_precision=8;
    339 	sc->sc_14bit = 0;
    340 	sc->sc_encoding=AUDIO_ENCODING_ULAW;
    341 	sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    342 
    343 	/* clear interrupts and dma: */
    344 	custom.intena = AUCC_ALLINTF;
    345 	custom.dmacon = AUCC_ALLDMAF;
    346 
    347 	return err;
    348 }
    349 
    350 int
    351 aucc_open(addr, flags)
    352 	void *addr;
    353 	int flags;
    354 {
    355 	struct aucc_softc *sc = addr;
    356 	int i;
    357 
    358 	DPRINTF(("sa_open: unit %p\n",sc));
    359 
    360 	if (sc->sc_open)
    361 		return (EBUSY);
    362 	sc->sc_open = 1;
    363 	for (i=0;i<AUCC_MAXINT;i++) {
    364 		sc->sc_channel[i].nd_intr=NULL;
    365 		sc->sc_channel[i].nd_intrdata=NULL;
    366 	}
    367 	aucc=sc;
    368 	sc->sc_channelmask=0xf;
    369 
    370 	DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
    371 
    372 	return (0);
    373 }
    374 
    375 void
    376 aucc_close(addr)
    377 	void *addr;
    378 {
    379 	register struct aucc_softc *sc = addr;
    380 
    381 	DPRINTF(("sa_close: sc=0x%p\n", sc));
    382 	/*
    383 	 * halt i/o, clear open flag, and done.
    384 	 */
    385 	aucc_halt_output(sc);
    386 	sc->sc_open = 0;
    387 
    388 	DPRINTF(("sa_close: closed.\n"));
    389 }
    390 
    391 int
    392 aucc_set_out_sr(addr, sr)
    393 	void *addr;
    394 	u_long sr;
    395 {
    396 	struct aucc_softc *sc=addr;
    397 	u_long per;
    398 	register int i;
    399 
    400 	per=freqtoper(sr);
    401 	if (per>0xffff)
    402 		return EINVAL;
    403 	sr=pertofreq(per);
    404 
    405 	for (i=0;i<4;i++) {
    406 		sc->sc_channel[i].nd_freq=sr;
    407 		sc->sc_channel[i].nd_per=per;
    408 	}
    409 
    410 	return(0);
    411 }
    412 
    413 int
    414 aucc_query_encoding(addr, fp)
    415 	void *addr;
    416 	struct audio_encoding *fp;
    417 {
    418 	switch (fp->index) {
    419 		case 0:
    420 			strcpy(fp->name, AudioEslinear);
    421 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    422 			fp->precision = 8;
    423 			fp->flags = 0;
    424 			break;
    425 		case 1:
    426 			strcpy(fp->name, AudioEmulaw);
    427 			fp->encoding = AUDIO_ENCODING_ULAW;
    428 			fp->precision = 8;
    429 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    430 			break;
    431 
    432 		case 2:
    433 			strcpy(fp->name, AudioEulinear);
    434 			fp->encoding = AUDIO_ENCODING_ULINEAR;
    435 			fp->precision = 8;
    436 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    437 			break;
    438 
    439 		case 3:
    440 			strcpy(fp->name, AudioEslinear);
    441 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    442 			fp->precision = 16;
    443 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    444 			break;
    445 
    446 		case 4:
    447 			strcpy(fp->name, AudioEslinear_be);
    448 			fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    449 			fp->precision = 16;
    450 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    451 			break;
    452 
    453 		case 5:
    454 			strcpy(fp->name, AudioEslinear_le);
    455 			fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    456 			fp->precision = 16;
    457 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    458 			break;
    459 
    460 		default:
    461 			return(EINVAL);
    462 			/*NOTREACHED*/
    463 	}
    464 	return(0);
    465 }
    466 
    467 int
    468 aucc_set_params(addr, setmode, usemode, p, r)
    469 	void *addr;
    470 	int setmode, usemode;
    471 	struct  audio_params *p, *r;
    472 {
    473 	struct aucc_softc *sc = addr;
    474 
    475 	/* if (setmode & AUMODE_RECORD)
    476 		return 0 ENXIO*/;
    477 
    478 #ifdef AUCCDEBUG
    479 	printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
    480 		"enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode,
    481 		p->encoding, p->precision, p->channels, p->sample_rate);
    482 #endif
    483 
    484 	switch (p->precision) {
    485 	case 8:
    486 		switch (p->encoding) {
    487 		case AUDIO_ENCODING_ULAW:
    488 			switch (p->channels) {
    489 			case 1:
    490 				sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    491 				break;
    492 			case 2:
    493 				sc->sc_decodefunc = aucc_decode_ulaw_2ch;
    494 				break;
    495 			case 3:
    496 				sc->sc_decodefunc = aucc_decode_ulaw_3ch;
    497 				break;
    498 			case 4:
    499 				sc->sc_decodefunc = aucc_decode_ulaw_4ch;
    500 				break;
    501 			default:
    502 				return EINVAL;
    503 			}
    504 			break;
    505 
    506 		case AUDIO_ENCODING_SLINEAR:
    507 		case AUDIO_ENCODING_SLINEAR_BE:
    508 		case AUDIO_ENCODING_SLINEAR_LE:
    509 			switch (p->channels) {
    510 			case 1:
    511 				sc->sc_decodefunc = aucc_decode_slinear8_1ch;
    512 				break;
    513 			case 2:
    514 				sc->sc_decodefunc = aucc_decode_slinear8_2ch;
    515 				break;
    516 			case 3:
    517 				sc->sc_decodefunc = aucc_decode_slinear8_3ch;
    518 				break;
    519 			case 4:
    520 				sc->sc_decodefunc = aucc_decode_slinear8_4ch;
    521 				break;
    522 			default:
    523 				return EINVAL;
    524 			}
    525 			break;
    526 
    527 		case AUDIO_ENCODING_ULINEAR:
    528 		case AUDIO_ENCODING_ULINEAR_BE:
    529 		case AUDIO_ENCODING_ULINEAR_LE:
    530 			switch (p->channels) {
    531 			case 1:
    532 				sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
    533 				break;
    534 			case 2:
    535 				sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
    536 				break;
    537 			case 3:
    538 				sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
    539 				break;
    540 			case 4:
    541 				sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
    542 				break;
    543 			default:
    544 				return EINVAL;
    545 			}
    546 			break;
    547 
    548 		default:
    549 			return EINVAL;
    550 		}
    551 		break;
    552 
    553 	case 16:
    554 		switch (p->encoding) {
    555 #if BYTE_ORDER == BIG_ENDIAN
    556 		case AUDIO_ENCODING_SLINEAR:
    557 #endif
    558 		case AUDIO_ENCODING_SLINEAR_BE:
    559 			switch (p->channels) {
    560 			case 1:
    561 				sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    562 				break;
    563 
    564 			case 2:
    565 				sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    566 				break;
    567 			case 3:
    568 				sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    569 				break;
    570 			case 4:
    571 				sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    572 				break;
    573 			default:
    574 				return EINVAL;
    575 			}
    576 			break;
    577 
    578 #if BYTE_ORDER == LITTLE_ENDIAN
    579 		case AUDIO_ENCODING_SLINEAR:
    580 #endif
    581 		case AUDIO_ENCODING_SLINEAR_LE:
    582 			switch (p->channels) {
    583 			case 1:
    584 				sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
    585 				break;
    586 			case 2:
    587 				sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
    588 				break;
    589 			case 3:
    590 				sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
    591 				break;
    592 			case 4:
    593 				sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
    594 				break;
    595 			default:
    596 				return EINVAL;
    597 			}
    598 			break;
    599 
    600 		default:
    601 			return EINVAL;
    602 		}
    603 		break;
    604 
    605 	default:
    606 		return EINVAL;
    607 	}
    608 
    609 	sc->sc_encoding = p->encoding;
    610 	sc->sc_precision = p->precision;
    611 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    612 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    613 
    614 	return aucc_set_out_sr(addr, p->sample_rate);
    615 }
    616 
    617 int
    618 aucc_round_blocksize(addr, blk)
    619 	void *addr;
    620 	int blk;
    621 {
    622 	/* round up to even size */
    623 	return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
    624 }
    625 
    626 int
    627 aucc_commit_settings(addr)
    628 	void *addr;
    629 {
    630 	register struct aucc_softc *sc = addr;
    631 	register int i;
    632 
    633 	DPRINTF(("sa_commit.\n"));
    634 
    635 	for (i=0;i<4;i++) {
    636 		custom.aud[i].vol=sc->sc_channel[i].nd_volume;
    637 		custom.aud[i].per=sc->sc_channel[i].nd_per;
    638 	}
    639 
    640 	DPRINTF(("commit done\n"));
    641 
    642 	return(0);
    643 }
    644 
    645 static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    646 static int masks2[4] = {1,2,4,8};
    647 
    648 int
    649 aucc_start_output(addr, p, cc, intr, arg)
    650 	void *addr;
    651 	void *p;
    652 	int cc;
    653 	void (*intr) __P((void *));
    654 	void *arg;
    655 {
    656 	struct aucc_softc *sc;
    657 	int mask;
    658 	int i, j, k, len;
    659 	u_char *dmap[4];
    660 
    661 
    662 	sc = addr;
    663 	mask = sc->sc_channelmask;
    664 
    665 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    666 
    667 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    668 
    669 	if (sc->sc_channels > 1)
    670 		mask &= masks[sc->sc_channels - 1];
    671 		/* we use first sc_channels channels */
    672 	if (mask == 0) /* active and used channels are disjoint */
    673 		return EINVAL;
    674 
    675 	for (i=0;i<4;i++) {
    676 		/* channels available ? */
    677 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    678 			return EBUSY; /* channel is busy */
    679 		if (channel[i].isaudio == -1)
    680 			return EBUSY; /* system uses them */
    681 	}
    682 
    683 	/* enable interrupt on 1st channel */
    684 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    685 		if (masks2[i] & mask) {
    686 			DPRINTF(("first channel is %d\n",i));
    687 			j=i;
    688 			sc->sc_channel[i].nd_intr=intr;
    689 			sc->sc_channel[i].nd_intrdata=arg;
    690 			break;
    691 		}
    692 	}
    693 
    694 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    695 		dmap[2], dmap[3], mask));
    696 
    697 	/* disable ints, dma for channels, until all parameters set */
    698 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    699 	custom.intreq = mask << INTB_AUD0;
    700 	custom.intena = mask << INTB_AUD0;
    701 
    702 	/* copy data to dma buffer */
    703 
    704 	if (sc->sc_channels == 1) {
    705 		dmap[0] =
    706 		dmap[1] =
    707 		dmap[2] =
    708 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    709 	}
    710 	else {
    711 		for (k=0; k<4; k++) {
    712 			if (masks2[k+j] & mask)
    713 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    714 		}
    715 	}
    716 
    717 	sc->sc_channel[j].nd_doublebuf ^= 1;
    718 	if (sc->sc_channel[j].nd_doublebuf) {
    719 		dmap[0] += AUDIO_BUF_SIZE;
    720 		dmap[1] += AUDIO_BUF_SIZE;
    721 		dmap[2] += AUDIO_BUF_SIZE;
    722 		dmap[3] += AUDIO_BUF_SIZE;
    723 	}
    724 
    725 	/* compute output length in bytes per channel.
    726 	 * divide by two only for 16bit->8bit conversion.
    727 	 */
    728 	len = cc / sc->sc_channels;
    729 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    730 		len /= 2;
    731 
    732 	/* call audio decoding routine */
    733 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    734 
    735 	/* dma buffers: we use same buffer 4 all channels
    736 	 * write dma location and length
    737 	 */
    738 	for (i = k = 0; i < 4; i++) {
    739 		if (masks2[i] & mask) {
    740 			DPRINTF(("turning channel %d on\n",i));
    741 			/* sc->sc_channel[i].nd_busy=1; */
    742 			channel[i].isaudio = 1;
    743 			channel[i].play_count = 1;
    744 			channel[i].handler = NULL;
    745 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    746 			if (sc->sc_14bit && (i > 1))
    747 				custom.aud[i].vol = 1;
    748 			else
    749 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    750 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    751 			custom.aud[i].len = len / 2;
    752 			sc->sc_channel[i].nd_mask = mask;
    753 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    754 			    sc->sc_channel[i].nd_per,
    755 			    sc->sc_channel[i].nd_volume, len));
    756 		}
    757 	}
    758 
    759 	channel[j].handler=aucc_inthdl;
    760 
    761 	/* enable ints */
    762 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    763 
    764 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    765 
    766 	/* enable dma */
    767 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    768 
    769 	DPRINTF(("enabled dma, mask=0x%x\n",mask));
    770 
    771 	return(0);
    772 }
    773 
    774 /* ARGSUSED */
    775 int
    776 aucc_start_input(addr, p, cc, intr, arg)
    777 	void *addr;
    778 	void *p;
    779 	int cc;
    780 	void (*intr) __P((void *));
    781 	void *arg;
    782 {
    783 
    784 	return ENXIO; /* no input */
    785 }
    786 
    787 int
    788 aucc_halt_output(addr)
    789 	void *addr;
    790 {
    791 	register struct aucc_softc *sc = addr;
    792 	register int i;
    793 
    794 	/* XXX only halt, if input is also halted ?? */
    795 	/* stop dma, etc */
    796 	custom.intena = AUCC_ALLINTF;
    797 	custom.dmacon = AUCC_ALLDMAF;
    798 	/* mark every busy unit idle */
    799 	for (i=0;i<4;i++) {
    800 		sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
    801 		channel[i].isaudio=0;
    802 		channel[i].play_count=0;
    803 	}
    804 
    805 	return(0);
    806 }
    807 
    808 int
    809 aucc_halt_input(addr)
    810 	void *addr;
    811 {
    812 	/* no input */
    813 
    814 	return ENXIO;
    815 }
    816 
    817 int
    818 aucc_getdev(addr, retp)
    819         void *addr;
    820         struct audio_device *retp;
    821 {
    822         *retp = aucc_device;
    823         return 0;
    824 }
    825 
    826 int
    827 aucc_set_port(addr, cp)
    828 	void *addr;
    829 	mixer_ctrl_t *cp;
    830 {
    831 	register struct aucc_softc *sc = addr;
    832 	register int i,j;
    833 
    834 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    835 
    836 	switch (cp->type) {
    837 	case AUDIO_MIXER_SET:
    838 		if (cp->dev!=AUCC_CHANNELS)
    839 			return EINVAL;
    840 		i=cp->un.mask;
    841 		if ((i<1) || (i>15))
    842 			return EINVAL;
    843 
    844 		sc->sc_channelmask=i;
    845 		break;
    846 
    847 	case AUDIO_MIXER_VALUE:
    848 		i=cp->un.value.num_channels;
    849 		if ((i<1) || (i>4))
    850 			return EINVAL;
    851 
    852 #ifdef __XXXwhatsthat
    853 		if (cp->dev!=AUCC_VOLUME)
    854 			return EINVAL;
    855 #endif
    856 
    857 		/* set volume for channel 0..i-1 */
    858 
    859 		/* evil workaround for xanim bug, IMO */
    860 		if ((sc->sc_channels == 1) && (i == 2)) {
    861 			sc->sc_channel[0].nd_volume =
    862 			    sc->sc_channel[3].nd_volume =
    863 			    cp->un.value.level[0]>>2;
    864 			sc->sc_channel[1].nd_volume =
    865 			    sc->sc_channel[2].nd_volume =
    866 			    cp->un.value.level[1]>>2;
    867 		} else if (i>1) {
    868 			for (j=0;j<i;j++)
    869 	 			sc->sc_channel[j].nd_volume =
    870 				    cp->un.value.level[j]>>2;
    871 		} else if (sc->sc_channels > 1)
    872 			for (j=0; j<sc->sc_channels; j++)
    873 	 			sc->sc_channel[j].nd_volume =
    874 				    cp->un.value.level[0]>>2;
    875 		else
    876 			for (j=0; j<4; j++)
    877 	 			sc->sc_channel[j].nd_volume =
    878 				    cp->un.value.level[0]>>2;
    879 		break;
    880 
    881 	default:
    882 		return EINVAL;
    883 		break;
    884 	}
    885 	return 0;
    886 }
    887 
    888 
    889 int
    890 aucc_get_port(addr, cp)
    891 	void *addr;
    892 	mixer_ctrl_t *cp;
    893 {
    894 	register struct aucc_softc *sc = addr;
    895 	register int i,j;
    896 
    897 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    898 
    899 	switch (cp->type) {
    900 	case AUDIO_MIXER_SET:
    901 		if (cp->dev!=AUCC_CHANNELS)
    902 			return EINVAL;
    903 		cp->un.mask=sc->sc_channelmask;
    904 		break;
    905 
    906 	case AUDIO_MIXER_VALUE:
    907 		i = cp->un.value.num_channels;
    908 		if ((i<1)||(i>4))
    909 			return EINVAL;
    910 
    911 		for (j=0;j<i;j++)
    912 			cp->un.value.level[j] =
    913 			    (sc->sc_channel[j].nd_volume<<2) +
    914 			    (sc->sc_channel[j].nd_volume>>4);
    915 		break;
    916 
    917 	default:
    918 		return EINVAL;
    919 	}
    920 	return 0;
    921 }
    922 
    923 
    924 int
    925 aucc_get_props(addr)
    926 	void *addr;
    927 {
    928 	return 0;
    929 }
    930 
    931 int
    932 aucc_query_devinfo(addr, dip)
    933 	void *addr;
    934 	register mixer_devinfo_t *dip;
    935 {
    936 	register int i;
    937 
    938 	switch(dip->index) {
    939 	case AUCC_CHANNELS:
    940 		dip->type = AUDIO_MIXER_SET;
    941 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    942 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    943                 strcpy(dip->label.name, AudioNspeaker);
    944 		for (i=0;i<16;i++) {
    945 			sprintf(dip->un.s.member[i].label.name,
    946 			    "channelmask%d", i);
    947 			dip->un.s.member[i].mask = i;
    948 		}
    949 		dip->un.s.num_mem = 16;
    950 		break;
    951 
    952 	case AUCC_VOLUME:
    953 		dip->type = AUDIO_MIXER_VALUE;
    954 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    955 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    956 		strcpy(dip->label.name, AudioNmaster);
    957 		dip->un.v.num_channels = 4;
    958 		strcpy(dip->un.v.units.name, AudioNvolume);
    959 		break;
    960 
    961 	case AUCC_OUTPUT_CLASS:
    962 		dip->type = AUDIO_MIXER_CLASS;
    963 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    964 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    965 		strcpy(dip->label.name, AudioCoutputs);
    966 		break;
    967 
    968 	default:
    969 		return ENXIO;
    970 	}
    971 
    972 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    973 
    974 	return(0);
    975 }
    976 
    977 
    978 /* audio int handler */
    979 void
    980 aucc_inthdl(int ch)
    981 {
    982 	register int i;
    983 	register int mask=aucc->sc_channel[ch].nd_mask;
    984 
    985 	/* for all channels in this maskgroup:
    986 	   disable dma, int
    987 	   mark idle */
    988 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
    989 
    990 	custom.intreq=mask<<INTB_AUD0; /* clear request */
    991 	/*
    992 	 * XXX: maybe we can leave ints and/or DMA on,
    993 	 * if another sample has to be played?
    994 	 */
    995 	custom.intena=mask<<INTB_AUD0;
    996 	/*
    997 	 * XXX custom.dmacon=mask; NO!!!
    998 	 */
    999 	for (i=0; i<4; i++) {
   1000 		if (masks2[i]&&mask) {
   1001 			DPRINTF(("marking channel %d idle\n",i));
   1002 			aucc->sc_channel[i].nd_busy=0;
   1003 			aucc->sc_channel[i].nd_mask=0;
   1004 			channel[i].isaudio=channel[i].play_count=0;
   1005 		}
   1006 	}
   1007 
   1008 	/* call handler */
   1009 	if (aucc->sc_channel[ch].nd_intr) {
   1010 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
   1011 		(*(aucc->sc_channel[ch].nd_intr))
   1012 		    (aucc->sc_channel[ch].nd_intrdata);
   1013 	}
   1014 	else
   1015 		DPRINTF(("zero int handler\n"));
   1016 	DPRINTF(("ints done\n"));
   1017 }
   1018 
   1019 
   1020 
   1021 
   1022 /* transform frequency to period, adjust bounds */
   1023 static u_int
   1024 freqtoper(u_int freq) {
   1025 	u_int per=eclockfreq*5/freq;
   1026 
   1027 	if (per<124)
   1028 		per=124; /* must have at least 124 ticks between samples */
   1029 
   1030 	return per;
   1031 }
   1032 
   1033 /* transform period to frequency */
   1034 static u_int
   1035 pertofreq(u_int per) {
   1036 	u_int freq=eclockfreq*5/per;
   1037 
   1038 	return freq;
   1039 }
   1040 
   1041 static void aucc_decode_slinear8_1ch (u_char **dmap, u_char *p, int i) {
   1042 	memcpy (dmap[0], p, i);
   1043 }
   1044 
   1045 static void aucc_decode_slinear8_2ch (u_char **dmap, u_char *p, int i) {
   1046 	u_char *ch0 = dmap[0];
   1047 	u_char *ch1 = dmap[1];
   1048 
   1049 	while (i--) {
   1050 		*ch0++ = *p++;
   1051 		*ch1++ = *p++;
   1052 	}
   1053 }
   1054 
   1055 static void aucc_decode_slinear8_3ch (u_char **dmap, u_char *p, int i) {
   1056 	u_char *ch0 = dmap[0];
   1057 	u_char *ch1 = dmap[1];
   1058 	u_char *ch2 = dmap[2];
   1059 
   1060 	while (i--) {
   1061 		*ch0++ = *p++;
   1062 		*ch1++ = *p++;
   1063 		*ch2++ = *p++;
   1064 	}
   1065 }
   1066 
   1067 static void aucc_decode_slinear8_4ch (u_char **dmap, u_char *p, int i) {
   1068 	u_char *ch0 = dmap[0];
   1069 	u_char *ch1 = dmap[1];
   1070 	u_char *ch2 = dmap[2];
   1071 	u_char *ch3 = dmap[3];
   1072 
   1073 	while (i--) {
   1074 		*ch0++ = *p++;
   1075 		*ch1++ = *p++;
   1076 		*ch2++ = *p++;
   1077 		*ch3++ = *p++;
   1078 	}
   1079 }
   1080 
   1081 static void
   1082 aucc_decode_ulinear8_1ch (dmap, p, i)
   1083 	u_char **dmap;
   1084 	u_char *p;
   1085 	int i;
   1086 {
   1087 	u_char *ch0 = dmap[0];
   1088 
   1089 	while (i--)
   1090 		*ch0++ = *p++ - 128;
   1091 }
   1092 
   1093 static void
   1094 aucc_decode_ulinear8_2ch(dmap, p, i)
   1095 	u_char **dmap;
   1096 	u_char *p;
   1097 	int i;
   1098 {
   1099 	u_char *ch0 = dmap[0];
   1100 	u_char *ch1 = dmap[1];
   1101 
   1102 	while (i--) {
   1103 		*ch0++ = *p++ - 128;
   1104 		*ch1++ = *p++ - 128;
   1105 	}
   1106 }
   1107 
   1108 static void
   1109 aucc_decode_ulinear8_3ch(dmap, p, i)
   1110 	u_char **dmap;
   1111 	u_char *p;
   1112 	int i;
   1113 {
   1114 	u_char *ch0 = dmap[0];
   1115 	u_char *ch1 = dmap[1];
   1116 	u_char *ch2 = dmap[2];
   1117 
   1118 	while (i--) {
   1119 		*ch0++ = *p++ - 128;
   1120 		*ch1++ = *p++ - 128;
   1121 		*ch2++ = *p++ - 128;
   1122 	}
   1123 }
   1124 
   1125 static void
   1126 aucc_decode_ulinear8_4ch(dmap, p, i)
   1127 	u_char **dmap;
   1128 	u_char *p;
   1129 	int i;
   1130 {
   1131 	u_char *ch0 = dmap[0];
   1132 	u_char *ch1 = dmap[1];
   1133 	u_char *ch2 = dmap[2];
   1134 	u_char *ch3 = dmap[3];
   1135 
   1136 	while (i--) {
   1137 		*ch0++ = *p++ - 128;
   1138 		*ch1++ = *p++ - 128;
   1139 		*ch2++ = *p++ - 128;
   1140 		*ch3++ = *p++ - 128;
   1141 	}
   1142 }
   1143 
   1144 
   1145 static void
   1146 aucc_decode_ulaw_1ch (dmap, p, i)
   1147 	u_char **dmap;
   1148 	u_char *p;
   1149 	int i;
   1150 {
   1151 	u_char *ch0 = dmap[0];
   1152 
   1153 	while (i--)
   1154 		*ch0++ = ulaw_to_lin[*p++];
   1155 }
   1156 
   1157 static void
   1158 aucc_decode_ulaw_2ch(dmap, p, i)
   1159 	u_char **dmap;
   1160 	u_char *p;
   1161 	int i;
   1162 {
   1163 	u_char *ch0 = dmap[0];
   1164 	u_char *ch1 = dmap[1];
   1165 
   1166 	while (i--) {
   1167 		*ch0++ = ulaw_to_lin[*p++];
   1168 		*ch1++ = ulaw_to_lin[*p++];
   1169 	}
   1170 }
   1171 
   1172 static void
   1173 aucc_decode_ulaw_3ch(dmap, p, i)
   1174 	u_char **dmap;
   1175 	u_char *p;
   1176 	int i;
   1177 {
   1178 	u_char *ch0 = dmap[0];
   1179 	u_char *ch1 = dmap[1];
   1180 	u_char *ch2 = dmap[2];
   1181 
   1182 	while (i--) {
   1183 		*ch0++ = ulaw_to_lin[*p++];
   1184 		*ch1++ = ulaw_to_lin[*p++];
   1185 		*ch2++ = ulaw_to_lin[*p++];
   1186 	}
   1187 }
   1188 
   1189 static void
   1190 aucc_decode_ulaw_4ch(dmap, p, i)
   1191 	u_char **dmap;
   1192 	u_char *p;
   1193 	int i;
   1194 {
   1195 	u_char *ch0 = dmap[0];
   1196 	u_char *ch1 = dmap[1];
   1197 	u_char *ch2 = dmap[2];
   1198 	u_char *ch3 = dmap[3];
   1199 
   1200 	while (i--) {
   1201 		*ch0++ = ulaw_to_lin[*p++];
   1202 		*ch1++ = ulaw_to_lin[*p++];
   1203 		*ch2++ = ulaw_to_lin[*p++];
   1204 		*ch3++ = ulaw_to_lin[*p++];
   1205 	}
   1206 }
   1207 
   1208 
   1209 /* 14bit output */
   1210 static void
   1211 aucc_decode_slinear16_1ch(dmap, p, i)
   1212 	u_char **dmap;
   1213 	u_char *p;
   1214 	int i;
   1215 {
   1216 	u_char *ch0 = dmap[0];
   1217 	u_char *ch3 = dmap[1]; /* XXX should be 3 */
   1218 
   1219 	while (i--) {
   1220 		*ch0++ = *p++;
   1221 		*ch3++ = *p++ >> 2;
   1222 	}
   1223 }
   1224 
   1225 /* 14bit stereo output */
   1226 static void
   1227 aucc_decode_slinear16_2ch(dmap, p, i)
   1228 	u_char **dmap;
   1229 	u_char *p;
   1230 	int i;
   1231 {
   1232 	u_char *ch0 = dmap[0];
   1233 	u_char *ch1 = dmap[1];
   1234 	u_char *ch2 = dmap[2];
   1235 	u_char *ch3 = dmap[3];
   1236 
   1237 	while (i--) {
   1238 		*ch0++ = *p++;
   1239 		*ch3++ = *p++ >> 2;
   1240 		*ch1++ = *p++;
   1241 		*ch2++ = *p++ >> 2;
   1242 	}
   1243 }
   1244 
   1245 static void
   1246 aucc_decode_slinear16_3ch(dmap, p, i)
   1247 	u_char **dmap;
   1248 	u_char *p;
   1249 	int i;
   1250 {
   1251 	u_char *ch0 = dmap[0];
   1252 	u_char *ch1 = dmap[1];
   1253 	u_char *ch2 = dmap[2];
   1254 
   1255 	while (i--) {
   1256 		*ch0++ = *p++; p++;
   1257 		*ch1++ = *p++; p++;
   1258 		*ch2++ = *p++; p++;
   1259 	}
   1260 }
   1261 
   1262 static void
   1263 aucc_decode_slinear16_4ch (dmap, p, i)
   1264 	u_char **dmap;
   1265 	u_char *p;
   1266 	int i;
   1267 {
   1268 	u_char *ch0 = dmap[0];
   1269 	u_char *ch1 = dmap[1];
   1270 	u_char *ch2 = dmap[2];
   1271 	u_char *ch3 = dmap[3];
   1272 
   1273 	while (i--) {
   1274 		*ch0++ = *p++; p++;
   1275 		*ch1++ = *p++; p++;
   1276 		*ch2++ = *p++; p++;
   1277 		*ch3++ = *p++; p++;
   1278 	}
   1279 }
   1280 
   1281 /* 14bit output, swap bytes */
   1282 static void
   1283 aucc_decode_slinear16sw_1ch(dmap, p, i)
   1284 	u_char **dmap;
   1285 	u_char *p;
   1286 	int i;
   1287 {
   1288 	u_char *ch0 = dmap[0];
   1289 	u_char *ch3 = dmap[1];	/* XXX should be 3 */
   1290 
   1291 	while (i--) {
   1292 		*ch3++ = *p++ >> 2;
   1293 		*ch0++ = *p++;
   1294 	}
   1295 }
   1296 
   1297 static void
   1298 aucc_decode_slinear16sw_2ch(dmap, p, i)
   1299 	u_char **dmap;
   1300 	u_char *p;
   1301 	int i;
   1302 {
   1303 	u_char *ch0 = dmap[0];
   1304 	u_char *ch1 = dmap[1];
   1305 	u_char *ch2 = dmap[2];
   1306 	u_char *ch3 = dmap[3];
   1307 
   1308 	while (i--) {
   1309 		*ch3++ = *p++ >> 2;
   1310 		*ch0++ = *p++;
   1311 		*ch2++ = *p++ >> 2;
   1312 		*ch1++ = *p++;
   1313 	}
   1314 }
   1315 
   1316 static void
   1317 aucc_decode_slinear16sw_3ch(dmap, p, i)
   1318 	u_char **dmap;
   1319 	u_char *p;
   1320 	int i;
   1321 {
   1322 	u_char *ch0 = dmap[0];
   1323 	u_char *ch1 = dmap[1];
   1324 	u_char *ch2 = dmap[2];
   1325 
   1326 	while (i--) {
   1327 		p++; *ch0++ = *p++;
   1328 		p++; *ch1++ = *p++;
   1329 		p++; *ch2++ = *p++;
   1330 	}
   1331 }
   1332 
   1333 static void
   1334 aucc_decode_slinear16sw_4ch(dmap, p, i)
   1335 	u_char **dmap;
   1336 	u_char *p;
   1337 	int i;
   1338 {
   1339 	u_char *ch0 = dmap[0];
   1340 	u_char *ch1 = dmap[1];
   1341 	u_char *ch2 = dmap[2];
   1342 	u_char *ch3 = dmap[3];
   1343 
   1344 	while (i--) {
   1345 		p++; *ch0++ = *p++;
   1346 		p++; *ch1++ = *p++;
   1347 		p++; *ch2++ = *p++;
   1348 		p++; *ch3++ = *p++;
   1349 	}
   1350 }
   1351 
   1352 
   1353 #endif /* NAUCC > 0 */
   1354