Home | History | Annotate | Line # | Download | only in dev
aucc.c revision 1.24
      1 /*	$NetBSD: aucc.c,v 1.24 1999/03/04 20:45:01 is 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 	if (matchname((char *)aux, "aucc") &&
    273 #ifdef DRACO
    274 	    !is_draco() &&
    275 #endif
    276 	    (cfp->cf_unit == 0))
    277 		return 1;
    278 
    279 	return 0;
    280 }
    281 
    282 /*
    283  * Audio chip found.
    284  */
    285 void
    286 auccattach(parent, self, args)
    287 	struct device *parent, *self;
    288 	void *args;
    289 {
    290 	register struct aucc_softc *sc = (struct aucc_softc *)self;
    291 	register int i;
    292 
    293 	printf("\n");
    294 
    295 	if((i=init_aucc(sc))) {
    296 		printf("audio: no chipmem\n");
    297 		return;
    298 	}
    299 
    300 	audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
    301 }
    302 
    303 
    304 static int
    305 init_aucc(sc)
    306 	struct aucc_softc *sc;
    307 {
    308 	register int i, err=0;
    309 
    310 	/* init values per channel */
    311  	for (i=0;i<4;i++) {
    312 		sc->sc_channel[i].nd_freq=8000;
    313 		sc->sc_channel[i].nd_per=freqtoper(8000);
    314 		sc->sc_channel[i].nd_busy=0;
    315 		sc->sc_channel[i].nd_dma=alloc_chipmem(AUDIO_BUF_SIZE*2);
    316 		if (sc->sc_channel[i].nd_dma==NULL)
    317 			err=1;
    318 	 	sc->sc_channel[i].nd_dmalength=0;
    319 		sc->sc_channel[i].nd_volume=64;
    320 		sc->sc_channel[i].nd_intr=NULL;
    321 		sc->sc_channel[i].nd_intrdata=NULL;
    322 		sc->sc_channel[i].nd_doublebuf=0;
    323 		DPRINTF(("dma buffer for channel %d is %p\n", i,
    324 		    sc->sc_channel[i].nd_dma));
    325 	}
    326 
    327 	if (err) {
    328 		for(i=0;i<4;i++)
    329 			if (sc->sc_channel[i].nd_dma)
    330 				free_chipmem(sc->sc_channel[i].nd_dma);
    331 	}
    332 
    333 	sc->sc_channels=1;
    334 	sc->sc_channelmask=0xf;
    335 	sc->sc_precision=8;
    336 	sc->sc_14bit = 0;
    337 	sc->sc_encoding=AUDIO_ENCODING_ULAW;
    338 	sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    339 
    340 	/* clear interrupts and dma: */
    341 	custom.intena = AUCC_ALLINTF;
    342 	custom.dmacon = AUCC_ALLDMAF;
    343 
    344 	return err;
    345 }
    346 
    347 int
    348 aucc_open(addr, flags)
    349 	void *addr;
    350 	int flags;
    351 {
    352 	struct aucc_softc *sc = addr;
    353 	int i;
    354 
    355 	DPRINTF(("sa_open: unit %p\n",sc));
    356 
    357 	if (sc->sc_open)
    358 		return (EBUSY);
    359 	sc->sc_open = 1;
    360 	for (i=0;i<AUCC_MAXINT;i++) {
    361 		sc->sc_channel[i].nd_intr=NULL;
    362 		sc->sc_channel[i].nd_intrdata=NULL;
    363 	}
    364 	aucc=sc;
    365 	sc->sc_channelmask=0xf;
    366 
    367 	DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
    368 
    369 	return (0);
    370 }
    371 
    372 void
    373 aucc_close(addr)
    374 	void *addr;
    375 {
    376 	register struct aucc_softc *sc = addr;
    377 
    378 	DPRINTF(("sa_close: sc=0x%p\n", sc));
    379 	/*
    380 	 * halt i/o, clear open flag, and done.
    381 	 */
    382 	aucc_halt_output(sc);
    383 	sc->sc_open = 0;
    384 
    385 	DPRINTF(("sa_close: closed.\n"));
    386 }
    387 
    388 int
    389 aucc_set_out_sr(addr, sr)
    390 	void *addr;
    391 	u_long sr;
    392 {
    393 	struct aucc_softc *sc=addr;
    394 	u_long per;
    395 	register int i;
    396 
    397 	per=freqtoper(sr);
    398 	if (per>0xffff)
    399 		return EINVAL;
    400 	sr=pertofreq(per);
    401 
    402 	for (i=0;i<4;i++) {
    403 		sc->sc_channel[i].nd_freq=sr;
    404 		sc->sc_channel[i].nd_per=per;
    405 	}
    406 
    407 	return(0);
    408 }
    409 
    410 int
    411 aucc_query_encoding(addr, fp)
    412 	void *addr;
    413 	struct audio_encoding *fp;
    414 {
    415 	switch (fp->index) {
    416 		case 0:
    417 			strcpy(fp->name, AudioEslinear);
    418 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    419 			fp->precision = 8;
    420 			fp->flags = 0;
    421 			break;
    422 		case 1:
    423 			strcpy(fp->name, AudioEmulaw);
    424 			fp->encoding = AUDIO_ENCODING_ULAW;
    425 			fp->precision = 8;
    426 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    427 			break;
    428 
    429 		case 2:
    430 			strcpy(fp->name, AudioEulinear);
    431 			fp->encoding = AUDIO_ENCODING_ULINEAR;
    432 			fp->precision = 8;
    433 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    434 			break;
    435 
    436 		case 3:
    437 			strcpy(fp->name, AudioEslinear);
    438 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    439 			fp->precision = 16;
    440 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    441 			break;
    442 
    443 		case 4:
    444 			strcpy(fp->name, AudioEslinear_be);
    445 			fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    446 			fp->precision = 16;
    447 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    448 			break;
    449 
    450 		case 5:
    451 			strcpy(fp->name, AudioEslinear_le);
    452 			fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    453 			fp->precision = 16;
    454 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    455 			break;
    456 
    457 		default:
    458 			return(EINVAL);
    459 			/*NOTREACHED*/
    460 	}
    461 	return(0);
    462 }
    463 
    464 int
    465 aucc_set_params(addr, setmode, usemode, p, r)
    466 	void *addr;
    467 	int setmode, usemode;
    468 	struct  audio_params *p, *r;
    469 {
    470 	struct aucc_softc *sc = addr;
    471 
    472 	/* if (setmode & AUMODE_RECORD)
    473 		return 0 ENXIO*/;
    474 
    475 #ifdef AUCCDEBUG
    476 	printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
    477 		"enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode,
    478 		p->encoding, p->precision, p->channels, p->sample_rate);
    479 #endif
    480 
    481 	switch (p->precision) {
    482 	case 8:
    483 		switch (p->encoding) {
    484 		case AUDIO_ENCODING_ULAW:
    485 			switch (p->channels) {
    486 			case 1:
    487 				sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    488 				break;
    489 			case 2:
    490 				sc->sc_decodefunc = aucc_decode_ulaw_2ch;
    491 				break;
    492 			case 3:
    493 				sc->sc_decodefunc = aucc_decode_ulaw_3ch;
    494 				break;
    495 			case 4:
    496 				sc->sc_decodefunc = aucc_decode_ulaw_4ch;
    497 				break;
    498 			default:
    499 				return EINVAL;
    500 			}
    501 			break;
    502 
    503 		case AUDIO_ENCODING_SLINEAR:
    504 		case AUDIO_ENCODING_SLINEAR_BE:
    505 		case AUDIO_ENCODING_SLINEAR_LE:
    506 			switch (p->channels) {
    507 			case 1:
    508 				sc->sc_decodefunc = aucc_decode_slinear8_1ch;
    509 				break;
    510 			case 2:
    511 				sc->sc_decodefunc = aucc_decode_slinear8_2ch;
    512 				break;
    513 			case 3:
    514 				sc->sc_decodefunc = aucc_decode_slinear8_3ch;
    515 				break;
    516 			case 4:
    517 				sc->sc_decodefunc = aucc_decode_slinear8_4ch;
    518 				break;
    519 			default:
    520 				return EINVAL;
    521 			}
    522 			break;
    523 
    524 		case AUDIO_ENCODING_ULINEAR:
    525 		case AUDIO_ENCODING_ULINEAR_BE:
    526 		case AUDIO_ENCODING_ULINEAR_LE:
    527 			switch (p->channels) {
    528 			case 1:
    529 				sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
    530 				break;
    531 			case 2:
    532 				sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
    533 				break;
    534 			case 3:
    535 				sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
    536 				break;
    537 			case 4:
    538 				sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
    539 				break;
    540 			default:
    541 				return EINVAL;
    542 			}
    543 			break;
    544 
    545 		default:
    546 			return EINVAL;
    547 		}
    548 		break;
    549 
    550 	case 16:
    551 		switch (p->encoding) {
    552 #if BYTE_ORDER == BIG_ENDIAN
    553 		case AUDIO_ENCODING_SLINEAR:
    554 #endif
    555 		case AUDIO_ENCODING_SLINEAR_BE:
    556 			switch (p->channels) {
    557 			case 1:
    558 				sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    559 				break;
    560 
    561 			case 2:
    562 				sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    563 				break;
    564 			case 3:
    565 				sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    566 				break;
    567 			case 4:
    568 				sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    569 				break;
    570 			default:
    571 				return EINVAL;
    572 			}
    573 			break;
    574 
    575 #if BYTE_ORDER == LITTLE_ENDIAN
    576 		case AUDIO_ENCODING_SLINEAR:
    577 #endif
    578 		case AUDIO_ENCODING_SLINEAR_LE:
    579 			switch (p->channels) {
    580 			case 1:
    581 				sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
    582 				break;
    583 			case 2:
    584 				sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
    585 				break;
    586 			case 3:
    587 				sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
    588 				break;
    589 			case 4:
    590 				sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
    591 				break;
    592 			default:
    593 				return EINVAL;
    594 			}
    595 			break;
    596 
    597 		default:
    598 			return EINVAL;
    599 		}
    600 		break;
    601 
    602 	default:
    603 		return EINVAL;
    604 	}
    605 
    606 	sc->sc_encoding = p->encoding;
    607 	sc->sc_precision = p->precision;
    608 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    609 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    610 
    611 	return aucc_set_out_sr(addr, p->sample_rate);
    612 }
    613 
    614 int
    615 aucc_round_blocksize(addr, blk)
    616 	void *addr;
    617 	int blk;
    618 {
    619 	/* round up to even size */
    620 	return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
    621 }
    622 
    623 int
    624 aucc_commit_settings(addr)
    625 	void *addr;
    626 {
    627 	register struct aucc_softc *sc = addr;
    628 	register int i;
    629 
    630 	DPRINTF(("sa_commit.\n"));
    631 
    632 	for (i=0;i<4;i++) {
    633 		custom.aud[i].vol=sc->sc_channel[i].nd_volume;
    634 		custom.aud[i].per=sc->sc_channel[i].nd_per;
    635 	}
    636 
    637 	DPRINTF(("commit done\n"));
    638 
    639 	return(0);
    640 }
    641 
    642 static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    643 static int masks2[4] = {1,2,4,8};
    644 
    645 int
    646 aucc_start_output(addr, p, cc, intr, arg)
    647 	void *addr;
    648 	void *p;
    649 	int cc;
    650 	void (*intr) __P((void *));
    651 	void *arg;
    652 {
    653 	struct aucc_softc *sc;
    654 	int mask;
    655 	int i, j, k, len;
    656 	u_char *dmap[4];
    657 
    658 
    659 	sc = addr;
    660 	mask = sc->sc_channelmask;
    661 
    662 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    663 
    664 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    665 
    666 	if (sc->sc_channels > 1)
    667 		mask &= masks[sc->sc_channels - 1];
    668 		/* we use first sc_channels channels */
    669 	if (mask == 0) /* active and used channels are disjoint */
    670 		return EINVAL;
    671 
    672 	for (i=0;i<4;i++) {
    673 		/* channels available ? */
    674 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    675 			return EBUSY; /* channel is busy */
    676 		if (channel[i].isaudio == -1)
    677 			return EBUSY; /* system uses them */
    678 	}
    679 
    680 	/* enable interrupt on 1st channel */
    681 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    682 		if (masks2[i] & mask) {
    683 			DPRINTF(("first channel is %d\n",i));
    684 			j=i;
    685 			sc->sc_channel[i].nd_intr=intr;
    686 			sc->sc_channel[i].nd_intrdata=arg;
    687 			break;
    688 		}
    689 	}
    690 
    691 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    692 		dmap[2], dmap[3], mask));
    693 
    694 	/* disable ints, dma for channels, until all parameters set */
    695 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    696 	custom.intreq = mask << INTB_AUD0;
    697 	custom.intena = mask << INTB_AUD0;
    698 
    699 	/* copy data to dma buffer */
    700 
    701 	if (sc->sc_channels == 1) {
    702 		dmap[0] =
    703 		dmap[1] =
    704 		dmap[2] =
    705 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    706 	}
    707 	else {
    708 		for (k=0; k<4; k++) {
    709 			if (masks2[k+j] & mask)
    710 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    711 		}
    712 	}
    713 
    714 	sc->sc_channel[j].nd_doublebuf ^= 1;
    715 	if (sc->sc_channel[j].nd_doublebuf) {
    716 		dmap[0] += AUDIO_BUF_SIZE;
    717 		dmap[1] += AUDIO_BUF_SIZE;
    718 		dmap[2] += AUDIO_BUF_SIZE;
    719 		dmap[3] += AUDIO_BUF_SIZE;
    720 	}
    721 
    722 	/* compute output length in bytes per channel.
    723 	 * divide by two only for 16bit->8bit conversion.
    724 	 */
    725 	len = cc / sc->sc_channels;
    726 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    727 		len /= 2;
    728 
    729 	/* call audio decoding routine */
    730 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    731 
    732 	/* dma buffers: we use same buffer 4 all channels
    733 	 * write dma location and length
    734 	 */
    735 	for (i = k = 0; i < 4; i++) {
    736 		if (masks2[i] & mask) {
    737 			DPRINTF(("turning channel %d on\n",i));
    738 			/* sc->sc_channel[i].nd_busy=1; */
    739 			channel[i].isaudio = 1;
    740 			channel[i].play_count = 1;
    741 			channel[i].handler = NULL;
    742 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    743 			if (sc->sc_14bit && (i > 1))
    744 				custom.aud[i].vol = 1;
    745 			else
    746 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    747 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    748 			custom.aud[i].len = len / 2;
    749 			sc->sc_channel[i].nd_mask = mask;
    750 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    751 			    sc->sc_channel[i].nd_per,
    752 			    sc->sc_channel[i].nd_volume, len));
    753 		}
    754 	}
    755 
    756 	channel[j].handler=aucc_inthdl;
    757 
    758 	/* enable ints */
    759 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    760 
    761 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    762 
    763 	/* enable dma */
    764 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    765 
    766 	DPRINTF(("enabled dma, mask=0x%x\n",mask));
    767 
    768 	return(0);
    769 }
    770 
    771 /* ARGSUSED */
    772 int
    773 aucc_start_input(addr, p, cc, intr, arg)
    774 	void *addr;
    775 	void *p;
    776 	int cc;
    777 	void (*intr) __P((void *));
    778 	void *arg;
    779 {
    780 
    781 	return ENXIO; /* no input */
    782 }
    783 
    784 int
    785 aucc_halt_output(addr)
    786 	void *addr;
    787 {
    788 	register struct aucc_softc *sc = addr;
    789 	register int i;
    790 
    791 	/* XXX only halt, if input is also halted ?? */
    792 	/* stop dma, etc */
    793 	custom.intena = AUCC_ALLINTF;
    794 	custom.dmacon = AUCC_ALLDMAF;
    795 	/* mark every busy unit idle */
    796 	for (i=0;i<4;i++) {
    797 		sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
    798 		channel[i].isaudio=0;
    799 		channel[i].play_count=0;
    800 	}
    801 
    802 	return(0);
    803 }
    804 
    805 int
    806 aucc_halt_input(addr)
    807 	void *addr;
    808 {
    809 	/* no input */
    810 
    811 	return ENXIO;
    812 }
    813 
    814 int
    815 aucc_getdev(addr, retp)
    816         void *addr;
    817         struct audio_device *retp;
    818 {
    819         *retp = aucc_device;
    820         return 0;
    821 }
    822 
    823 int
    824 aucc_set_port(addr, cp)
    825 	void *addr;
    826 	mixer_ctrl_t *cp;
    827 {
    828 	register struct aucc_softc *sc = addr;
    829 	register int i,j;
    830 
    831 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    832 
    833 	switch (cp->type) {
    834 	case AUDIO_MIXER_SET:
    835 		if (cp->dev!=AUCC_CHANNELS)
    836 			return EINVAL;
    837 		i=cp->un.mask;
    838 		if ((i<1) || (i>15))
    839 			return EINVAL;
    840 
    841 		sc->sc_channelmask=i;
    842 		break;
    843 
    844 	case AUDIO_MIXER_VALUE:
    845 		i=cp->un.value.num_channels;
    846 		if ((i<1) || (i>4))
    847 			return EINVAL;
    848 
    849 #ifdef __XXXwhatsthat
    850 		if (cp->dev!=AUCC_VOLUME)
    851 			return EINVAL;
    852 #endif
    853 
    854 		/* set volume for channel 0..i-1 */
    855 
    856 		/* evil workaround for xanim bug, IMO */
    857 		if ((sc->sc_channels == 1) && (i == 2)) {
    858 			sc->sc_channel[0].nd_volume =
    859 			    sc->sc_channel[3].nd_volume =
    860 			    cp->un.value.level[0]>>2;
    861 			sc->sc_channel[1].nd_volume =
    862 			    sc->sc_channel[2].nd_volume =
    863 			    cp->un.value.level[1]>>2;
    864 		} else if (i>1) {
    865 			for (j=0;j<i;j++)
    866 	 			sc->sc_channel[j].nd_volume =
    867 				    cp->un.value.level[j]>>2;
    868 		} else if (sc->sc_channels > 1)
    869 			for (j=0; j<sc->sc_channels; j++)
    870 	 			sc->sc_channel[j].nd_volume =
    871 				    cp->un.value.level[0]>>2;
    872 		else
    873 			for (j=0; j<4; j++)
    874 	 			sc->sc_channel[j].nd_volume =
    875 				    cp->un.value.level[0]>>2;
    876 		break;
    877 
    878 	default:
    879 		return EINVAL;
    880 		break;
    881 	}
    882 	return 0;
    883 }
    884 
    885 
    886 int
    887 aucc_get_port(addr, cp)
    888 	void *addr;
    889 	mixer_ctrl_t *cp;
    890 {
    891 	register struct aucc_softc *sc = addr;
    892 	register int i,j;
    893 
    894 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    895 
    896 	switch (cp->type) {
    897 	case AUDIO_MIXER_SET:
    898 		if (cp->dev!=AUCC_CHANNELS)
    899 			return EINVAL;
    900 		cp->un.mask=sc->sc_channelmask;
    901 		break;
    902 
    903 	case AUDIO_MIXER_VALUE:
    904 		i = cp->un.value.num_channels;
    905 		if ((i<1)||(i>4))
    906 			return EINVAL;
    907 
    908 		for (j=0;j<i;j++)
    909 			cp->un.value.level[j] =
    910 			    (sc->sc_channel[j].nd_volume<<2) +
    911 			    (sc->sc_channel[j].nd_volume>>4);
    912 		break;
    913 
    914 	default:
    915 		return EINVAL;
    916 	}
    917 	return 0;
    918 }
    919 
    920 
    921 int
    922 aucc_get_props(addr)
    923 	void *addr;
    924 {
    925 	return 0;
    926 }
    927 
    928 int
    929 aucc_query_devinfo(addr, dip)
    930 	void *addr;
    931 	register mixer_devinfo_t *dip;
    932 {
    933 	register int i;
    934 
    935 	switch(dip->index) {
    936 	case AUCC_CHANNELS:
    937 		dip->type = AUDIO_MIXER_SET;
    938 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    939 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    940                 strcpy(dip->label.name, AudioNspeaker);
    941 		for (i=0;i<16;i++) {
    942 			sprintf(dip->un.s.member[i].label.name,
    943 			    "channelmask%d", i);
    944 			dip->un.s.member[i].mask = i;
    945 		}
    946 		dip->un.s.num_mem = 16;
    947 		break;
    948 
    949 	case AUCC_VOLUME:
    950 		dip->type = AUDIO_MIXER_VALUE;
    951 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    952 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    953 		strcpy(dip->label.name, AudioNmaster);
    954 		dip->un.v.num_channels = 4;
    955 		strcpy(dip->un.v.units.name, AudioNvolume);
    956 		break;
    957 
    958 	case AUCC_OUTPUT_CLASS:
    959 		dip->type = AUDIO_MIXER_CLASS;
    960 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    961 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    962 		strcpy(dip->label.name, AudioCoutputs);
    963 		break;
    964 
    965 	default:
    966 		return ENXIO;
    967 	}
    968 
    969 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    970 
    971 	return(0);
    972 }
    973 
    974 
    975 /* audio int handler */
    976 void
    977 aucc_inthdl(int ch)
    978 {
    979 	register int i;
    980 	register int mask=aucc->sc_channel[ch].nd_mask;
    981 
    982 	/* for all channels in this maskgroup:
    983 	   disable dma, int
    984 	   mark idle */
    985 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
    986 
    987 	custom.intreq=mask<<INTB_AUD0; /* clear request */
    988 	/*
    989 	 * XXX: maybe we can leave ints and/or DMA on,
    990 	 * if another sample has to be played?
    991 	 */
    992 	custom.intena=mask<<INTB_AUD0;
    993 	/*
    994 	 * XXX custom.dmacon=mask; NO!!!
    995 	 */
    996 	for (i=0; i<4; i++) {
    997 		if (masks2[i]&&mask) {
    998 			DPRINTF(("marking channel %d idle\n",i));
    999 			aucc->sc_channel[i].nd_busy=0;
   1000 			aucc->sc_channel[i].nd_mask=0;
   1001 			channel[i].isaudio=channel[i].play_count=0;
   1002 		}
   1003 	}
   1004 
   1005 	/* call handler */
   1006 	if (aucc->sc_channel[ch].nd_intr) {
   1007 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
   1008 		(*(aucc->sc_channel[ch].nd_intr))
   1009 		    (aucc->sc_channel[ch].nd_intrdata);
   1010 	}
   1011 	else
   1012 		DPRINTF(("zero int handler\n"));
   1013 	DPRINTF(("ints done\n"));
   1014 }
   1015 
   1016 
   1017 
   1018 
   1019 /* transform frequency to period, adjust bounds */
   1020 static u_int
   1021 freqtoper(u_int freq) {
   1022 	u_int per=eclockfreq*5/freq;
   1023 
   1024 	if (per<124)
   1025 		per=124; /* must have at least 124 ticks between samples */
   1026 
   1027 	return per;
   1028 }
   1029 
   1030 /* transform period to frequency */
   1031 static u_int
   1032 pertofreq(u_int per) {
   1033 	u_int freq=eclockfreq*5/per;
   1034 
   1035 	return freq;
   1036 }
   1037 
   1038 static void aucc_decode_slinear8_1ch (u_char **dmap, u_char *p, int i) {
   1039 	memcpy (dmap[0], p, i);
   1040 }
   1041 
   1042 static void aucc_decode_slinear8_2ch (u_char **dmap, u_char *p, int i) {
   1043 	u_char *ch0 = dmap[0];
   1044 	u_char *ch1 = dmap[1];
   1045 
   1046 	while (i--) {
   1047 		*ch0++ = *p++;
   1048 		*ch1++ = *p++;
   1049 	}
   1050 }
   1051 
   1052 static void aucc_decode_slinear8_3ch (u_char **dmap, u_char *p, int i) {
   1053 	u_char *ch0 = dmap[0];
   1054 	u_char *ch1 = dmap[1];
   1055 	u_char *ch2 = dmap[2];
   1056 
   1057 	while (i--) {
   1058 		*ch0++ = *p++;
   1059 		*ch1++ = *p++;
   1060 		*ch2++ = *p++;
   1061 	}
   1062 }
   1063 
   1064 static void aucc_decode_slinear8_4ch (u_char **dmap, u_char *p, int i) {
   1065 	u_char *ch0 = dmap[0];
   1066 	u_char *ch1 = dmap[1];
   1067 	u_char *ch2 = dmap[2];
   1068 	u_char *ch3 = dmap[3];
   1069 
   1070 	while (i--) {
   1071 		*ch0++ = *p++;
   1072 		*ch1++ = *p++;
   1073 		*ch2++ = *p++;
   1074 		*ch3++ = *p++;
   1075 	}
   1076 }
   1077 
   1078 static void
   1079 aucc_decode_ulinear8_1ch (dmap, p, i)
   1080 	u_char **dmap;
   1081 	u_char *p;
   1082 	int i;
   1083 {
   1084 	u_char *ch0 = dmap[0];
   1085 
   1086 	while (i--)
   1087 		*ch0++ = *p++ - 128;
   1088 }
   1089 
   1090 static void
   1091 aucc_decode_ulinear8_2ch(dmap, p, i)
   1092 	u_char **dmap;
   1093 	u_char *p;
   1094 	int i;
   1095 {
   1096 	u_char *ch0 = dmap[0];
   1097 	u_char *ch1 = dmap[1];
   1098 
   1099 	while (i--) {
   1100 		*ch0++ = *p++ - 128;
   1101 		*ch1++ = *p++ - 128;
   1102 	}
   1103 }
   1104 
   1105 static void
   1106 aucc_decode_ulinear8_3ch(dmap, p, i)
   1107 	u_char **dmap;
   1108 	u_char *p;
   1109 	int i;
   1110 {
   1111 	u_char *ch0 = dmap[0];
   1112 	u_char *ch1 = dmap[1];
   1113 	u_char *ch2 = dmap[2];
   1114 
   1115 	while (i--) {
   1116 		*ch0++ = *p++ - 128;
   1117 		*ch1++ = *p++ - 128;
   1118 		*ch2++ = *p++ - 128;
   1119 	}
   1120 }
   1121 
   1122 static void
   1123 aucc_decode_ulinear8_4ch(dmap, p, i)
   1124 	u_char **dmap;
   1125 	u_char *p;
   1126 	int i;
   1127 {
   1128 	u_char *ch0 = dmap[0];
   1129 	u_char *ch1 = dmap[1];
   1130 	u_char *ch2 = dmap[2];
   1131 	u_char *ch3 = dmap[3];
   1132 
   1133 	while (i--) {
   1134 		*ch0++ = *p++ - 128;
   1135 		*ch1++ = *p++ - 128;
   1136 		*ch2++ = *p++ - 128;
   1137 		*ch3++ = *p++ - 128;
   1138 	}
   1139 }
   1140 
   1141 
   1142 static void
   1143 aucc_decode_ulaw_1ch (dmap, p, i)
   1144 	u_char **dmap;
   1145 	u_char *p;
   1146 	int i;
   1147 {
   1148 	u_char *ch0 = dmap[0];
   1149 
   1150 	while (i--)
   1151 		*ch0++ = ulaw_to_lin[*p++];
   1152 }
   1153 
   1154 static void
   1155 aucc_decode_ulaw_2ch(dmap, p, i)
   1156 	u_char **dmap;
   1157 	u_char *p;
   1158 	int i;
   1159 {
   1160 	u_char *ch0 = dmap[0];
   1161 	u_char *ch1 = dmap[1];
   1162 
   1163 	while (i--) {
   1164 		*ch0++ = ulaw_to_lin[*p++];
   1165 		*ch1++ = ulaw_to_lin[*p++];
   1166 	}
   1167 }
   1168 
   1169 static void
   1170 aucc_decode_ulaw_3ch(dmap, p, i)
   1171 	u_char **dmap;
   1172 	u_char *p;
   1173 	int i;
   1174 {
   1175 	u_char *ch0 = dmap[0];
   1176 	u_char *ch1 = dmap[1];
   1177 	u_char *ch2 = dmap[2];
   1178 
   1179 	while (i--) {
   1180 		*ch0++ = ulaw_to_lin[*p++];
   1181 		*ch1++ = ulaw_to_lin[*p++];
   1182 		*ch2++ = ulaw_to_lin[*p++];
   1183 	}
   1184 }
   1185 
   1186 static void
   1187 aucc_decode_ulaw_4ch(dmap, p, i)
   1188 	u_char **dmap;
   1189 	u_char *p;
   1190 	int i;
   1191 {
   1192 	u_char *ch0 = dmap[0];
   1193 	u_char *ch1 = dmap[1];
   1194 	u_char *ch2 = dmap[2];
   1195 	u_char *ch3 = dmap[3];
   1196 
   1197 	while (i--) {
   1198 		*ch0++ = ulaw_to_lin[*p++];
   1199 		*ch1++ = ulaw_to_lin[*p++];
   1200 		*ch2++ = ulaw_to_lin[*p++];
   1201 		*ch3++ = ulaw_to_lin[*p++];
   1202 	}
   1203 }
   1204 
   1205 
   1206 /* 14bit output */
   1207 static void
   1208 aucc_decode_slinear16_1ch(dmap, p, i)
   1209 	u_char **dmap;
   1210 	u_char *p;
   1211 	int i;
   1212 {
   1213 	u_char *ch0 = dmap[0];
   1214 	u_char *ch3 = dmap[1]; /* XXX should be 3 */
   1215 
   1216 	while (i--) {
   1217 		*ch0++ = *p++;
   1218 		*ch3++ = *p++ >> 2;
   1219 	}
   1220 }
   1221 
   1222 /* 14bit stereo output */
   1223 static void
   1224 aucc_decode_slinear16_2ch(dmap, p, i)
   1225 	u_char **dmap;
   1226 	u_char *p;
   1227 	int i;
   1228 {
   1229 	u_char *ch0 = dmap[0];
   1230 	u_char *ch1 = dmap[1];
   1231 	u_char *ch2 = dmap[2];
   1232 	u_char *ch3 = dmap[3];
   1233 
   1234 	while (i--) {
   1235 		*ch0++ = *p++;
   1236 		*ch3++ = *p++ >> 2;
   1237 		*ch1++ = *p++;
   1238 		*ch2++ = *p++ >> 2;
   1239 	}
   1240 }
   1241 
   1242 static void
   1243 aucc_decode_slinear16_3ch(dmap, p, i)
   1244 	u_char **dmap;
   1245 	u_char *p;
   1246 	int i;
   1247 {
   1248 	u_char *ch0 = dmap[0];
   1249 	u_char *ch1 = dmap[1];
   1250 	u_char *ch2 = dmap[2];
   1251 
   1252 	while (i--) {
   1253 		*ch0++ = *p++; p++;
   1254 		*ch1++ = *p++; p++;
   1255 		*ch2++ = *p++; p++;
   1256 	}
   1257 }
   1258 
   1259 static void
   1260 aucc_decode_slinear16_4ch (dmap, p, i)
   1261 	u_char **dmap;
   1262 	u_char *p;
   1263 	int i;
   1264 {
   1265 	u_char *ch0 = dmap[0];
   1266 	u_char *ch1 = dmap[1];
   1267 	u_char *ch2 = dmap[2];
   1268 	u_char *ch3 = dmap[3];
   1269 
   1270 	while (i--) {
   1271 		*ch0++ = *p++; p++;
   1272 		*ch1++ = *p++; p++;
   1273 		*ch2++ = *p++; p++;
   1274 		*ch3++ = *p++; p++;
   1275 	}
   1276 }
   1277 
   1278 /* 14bit output, swap bytes */
   1279 static void
   1280 aucc_decode_slinear16sw_1ch(dmap, p, i)
   1281 	u_char **dmap;
   1282 	u_char *p;
   1283 	int i;
   1284 {
   1285 	u_char *ch0 = dmap[0];
   1286 	u_char *ch3 = dmap[3];
   1287 
   1288 	while (i--) {
   1289 		*ch3++ = *p++ >> 2;
   1290 		*ch0++ = *p++;
   1291 	}
   1292 }
   1293 
   1294 static void
   1295 aucc_decode_slinear16sw_2ch(dmap, p, i)
   1296 	u_char **dmap;
   1297 	u_char *p;
   1298 	int i;
   1299 {
   1300 	u_char *ch0 = dmap[0];
   1301 	u_char *ch1 = dmap[1];
   1302 	u_char *ch2 = dmap[2];
   1303 	u_char *ch3 = dmap[3];
   1304 
   1305 	while (i--) {
   1306 		*ch3++ = *p++ >> 2;
   1307 		*ch0++ = *p++;
   1308 		*ch2++ = *p++ >> 2;
   1309 		*ch1++ = *p++;
   1310 	}
   1311 }
   1312 
   1313 static void
   1314 aucc_decode_slinear16sw_3ch(dmap, p, i)
   1315 	u_char **dmap;
   1316 	u_char *p;
   1317 	int i;
   1318 {
   1319 	u_char *ch0 = dmap[0];
   1320 	u_char *ch1 = dmap[1];
   1321 	u_char *ch2 = dmap[2];
   1322 
   1323 	while (i--) {
   1324 		p++; *ch0++ = *p++;
   1325 		p++; *ch1++ = *p++;
   1326 		p++; *ch2++ = *p++;
   1327 	}
   1328 }
   1329 
   1330 static void
   1331 aucc_decode_slinear16sw_4ch(dmap, p, i)
   1332 	u_char **dmap;
   1333 	u_char *p;
   1334 	int i;
   1335 {
   1336 	u_char *ch0 = dmap[0];
   1337 	u_char *ch1 = dmap[1];
   1338 	u_char *ch2 = dmap[2];
   1339 	u_char *ch3 = dmap[3];
   1340 
   1341 	while (i--) {
   1342 		p++; *ch0++ = *p++;
   1343 		p++; *ch1++ = *p++;
   1344 		p++; *ch2++ = *p++;
   1345 		p++; *ch3++ = *p++;
   1346 	}
   1347 }
   1348 
   1349 
   1350 #endif /* NAUCC > 0 */
   1351