Home | History | Annotate | Line # | Download | only in dev
aucc.c revision 1.29
      1 /*	$NetBSD: aucc.c,v 1.29 2002/01/26 13:40:53 aymeric 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 #include "opt_lev6_defer.h"
     71 
     72 
     73 #ifdef LEV6_DEFER
     74 #define AUCC_MAXINT 3
     75 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
     76 #else
     77 #define AUCC_MAXINT 4
     78 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
     79 #endif
     80 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
     81 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
     82 
     83 #ifdef AUDIO_DEBUG
     84 /*extern printf(const char *,...);*/
     85 int     auccdebug = 1;
     86 #define DPRINTF(x)      if (auccdebug) printf x
     87 #else
     88 #define DPRINTF(x)
     89 #endif
     90 
     91 #ifdef splaudio
     92 #undef splaudio
     93 #endif
     94 
     95 #define splaudio() spl4();
     96 
     97 /* clock frequency.. */
     98 extern int eclockfreq;
     99 
    100 
    101 /* hw audio ch */
    102 extern struct audio_channel channel[4];
    103 
    104 
    105 /*
    106  * Software state.
    107  */
    108 struct aucc_softc {
    109 	struct	device sc_dev;		/* base device */
    110 
    111 	int	sc_open;		/* single use device */
    112 	aucc_data_t sc_channel[4];	/* per channel freq, ... */
    113 	u_int	sc_encoding;		/* encoding AUDIO_ENCODING_.*/
    114 	int	sc_channels;		/* # of channels used */
    115 	int	sc_precision;		/* 8 or 16 bits */
    116 	int	sc_14bit;		/* 14bit output enabled */
    117 
    118 	int	sc_intrcnt;		/* interrupt count */
    119 	int	sc_channelmask;  	/* which channels are used ? */
    120 	void (*sc_decodefunc)(u_char **, u_char *, int);
    121 				/* pointer to format conversion routine */
    122 };
    123 
    124 /* interrupt interfaces */
    125 void aucc_inthdl(int);
    126 
    127 /* forward declarations */
    128 static int init_aucc(struct aucc_softc *);
    129 static u_int freqtoper(u_int);
    130 static u_int pertofreq(u_int);
    131 
    132 /* autoconfiguration driver */
    133 void	auccattach(struct device *, struct device *, void *);
    134 int	auccmatch(struct device *, struct cfdata *, void *);
    135 
    136 struct cfattach aucc_ca = {
    137 	sizeof(struct aucc_softc),
    138 	auccmatch,
    139 	auccattach
    140 };
    141 
    142 struct audio_device aucc_device = {
    143 	"Amiga-audio",
    144 	"2.0",
    145 	"aucc"
    146 };
    147 
    148 
    149 struct aucc_softc *aucc=NULL;
    150 
    151 
    152 unsigned char ulaw_to_lin[] = {
    153 	0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
    154 	0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
    155 	0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
    156 	0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
    157 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
    158 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
    159 	0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
    160 	0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
    161 	0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
    162 	0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
    163 	0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
    164 	0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
    165 	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
    166 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    167 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    168 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    169 	0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
    170 	0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
    171 	0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
    172 	0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
    173 	0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
    174 	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
    175 	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
    176 	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
    177 	0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
    178 	0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
    179 	0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
    180 	0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
    181 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    182 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    183 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    184 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    185 };
    186 
    187 /*
    188  * Define our interface to the higher level audio driver.
    189  */
    190 int	aucc_open(void *, int);
    191 void	aucc_close(void *);
    192 int	aucc_set_out_sr(void *, u_long);
    193 int	aucc_query_encoding(void *, struct audio_encoding *);
    194 int	aucc_round_blocksize(void *, int);
    195 int	aucc_commit_settings(void *);
    196 int	aucc_start_output(void *, void *, int, void (*)(void *), void *);
    197 int	aucc_start_input(void *, void *, int, void (*)(void *), void *);
    198 int	aucc_halt_output(void *);
    199 int	aucc_halt_input(void *);
    200 int	aucc_getdev(void *, struct audio_device *);
    201 int	aucc_set_port(void *, mixer_ctrl_t *);
    202 int	aucc_get_port(void *, mixer_ctrl_t *);
    203 int	aucc_query_devinfo(void *, mixer_devinfo_t *);
    204 void	aucc_encode(int, int, int, int, u_char *, u_short **);
    205 int	aucc_set_params(void *, int, int, struct audio_params *,
    206 			struct audio_params *);
    207 int	aucc_get_props(void *);
    208 
    209 
    210 static void aucc_decode_slinear8_1ch(u_char **, u_char *, int);
    211 static void aucc_decode_slinear8_2ch(u_char **, u_char *, int);
    212 static void aucc_decode_slinear8_3ch(u_char **, u_char *, int);
    213 static void aucc_decode_slinear8_4ch(u_char **, u_char *, int);
    214 
    215 static void aucc_decode_ulinear8_1ch(u_char **, u_char *, int);
    216 static void aucc_decode_ulinear8_2ch(u_char **, u_char *, int);
    217 static void aucc_decode_ulinear8_3ch(u_char **, u_char *, int);
    218 static void aucc_decode_ulinear8_4ch(u_char **, u_char *, int);
    219 
    220 static void aucc_decode_ulaw_1ch(u_char **, u_char *, int);
    221 static void aucc_decode_ulaw_2ch(u_char **, u_char *, int);
    222 static void aucc_decode_ulaw_3ch(u_char **, u_char *, int);
    223 static void aucc_decode_ulaw_4ch(u_char **, u_char *, int);
    224 
    225 static void aucc_decode_slinear16_1ch(u_char **, u_char *, int);
    226 static void aucc_decode_slinear16_2ch(u_char **, u_char *, int);
    227 static void aucc_decode_slinear16_3ch(u_char **, u_char *, int);
    228 static void aucc_decode_slinear16_4ch(u_char **, u_char *, int);
    229 
    230 static void aucc_decode_slinear16sw_1ch(u_char **, u_char *, int);
    231 static void aucc_decode_slinear16sw_2ch(u_char **, u_char *, int);
    232 static void aucc_decode_slinear16sw_3ch(u_char **, u_char *, int);
    233 static void aucc_decode_slinear16sw_4ch(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 	NULL,
    263 	NULL,
    264 	NULL,
    265 };
    266 
    267 /* autoconfig routines */
    268 
    269 int
    270 auccmatch(struct device *pdp, struct cfdata *cfp, 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(struct device *parent, struct device *self, void *args)
    290 {
    291 	register struct aucc_softc *sc = (struct aucc_softc *)self;
    292 	register int i;
    293 
    294 	printf("\n");
    295 
    296 	if((i=init_aucc(sc))) {
    297 		printf("audio: no chipmem\n");
    298 		return;
    299 	}
    300 
    301 	audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
    302 }
    303 
    304 
    305 static int
    306 init_aucc(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(void *addr, int flags)
    349 {
    350 	struct aucc_softc *sc = addr;
    351 	int i;
    352 
    353 	DPRINTF(("sa_open: unit %p\n",sc));
    354 
    355 	if (sc->sc_open)
    356 		return (EBUSY);
    357 	sc->sc_open = 1;
    358 	for (i=0;i<AUCC_MAXINT;i++) {
    359 		sc->sc_channel[i].nd_intr=NULL;
    360 		sc->sc_channel[i].nd_intrdata=NULL;
    361 	}
    362 	aucc=sc;
    363 	sc->sc_channelmask=0xf;
    364 
    365 	DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
    366 
    367 	return (0);
    368 }
    369 
    370 void
    371 aucc_close(void *addr)
    372 {
    373 	register struct aucc_softc *sc = addr;
    374 
    375 	DPRINTF(("sa_close: sc=0x%p\n", sc));
    376 	/*
    377 	 * halt i/o, clear open flag, and done.
    378 	 */
    379 	aucc_halt_output(sc);
    380 	sc->sc_open = 0;
    381 
    382 	DPRINTF(("sa_close: closed.\n"));
    383 }
    384 
    385 int
    386 aucc_set_out_sr(void *addr, u_long sr)
    387 {
    388 	struct aucc_softc *sc=addr;
    389 	u_long per;
    390 	register int i;
    391 
    392 	per=freqtoper(sr);
    393 	if (per>0xffff)
    394 		return EINVAL;
    395 	sr=pertofreq(per);
    396 
    397 	for (i=0;i<4;i++) {
    398 		sc->sc_channel[i].nd_freq=sr;
    399 		sc->sc_channel[i].nd_per=per;
    400 	}
    401 
    402 	return(0);
    403 }
    404 
    405 int
    406 aucc_query_encoding(void *addr, struct audio_encoding *fp)
    407 {
    408 	switch (fp->index) {
    409 		case 0:
    410 			strcpy(fp->name, AudioEslinear);
    411 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    412 			fp->precision = 8;
    413 			fp->flags = 0;
    414 			break;
    415 		case 1:
    416 			strcpy(fp->name, AudioEmulaw);
    417 			fp->encoding = AUDIO_ENCODING_ULAW;
    418 			fp->precision = 8;
    419 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    420 			break;
    421 
    422 		case 2:
    423 			strcpy(fp->name, AudioEulinear);
    424 			fp->encoding = AUDIO_ENCODING_ULINEAR;
    425 			fp->precision = 8;
    426 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    427 			break;
    428 
    429 		case 3:
    430 			strcpy(fp->name, AudioEslinear);
    431 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    432 			fp->precision = 16;
    433 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    434 			break;
    435 
    436 		case 4:
    437 			strcpy(fp->name, AudioEslinear_be);
    438 			fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    439 			fp->precision = 16;
    440 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    441 			break;
    442 
    443 		case 5:
    444 			strcpy(fp->name, AudioEslinear_le);
    445 			fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    446 			fp->precision = 16;
    447 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    448 			break;
    449 
    450 		default:
    451 			return(EINVAL);
    452 			/*NOTREACHED*/
    453 	}
    454 	return(0);
    455 }
    456 
    457 int
    458 aucc_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
    459                 struct audio_params *r)
    460 {
    461 	struct aucc_softc *sc = addr;
    462 
    463 	/* if (setmode & AUMODE_RECORD)
    464 		return 0 ENXIO*/;
    465 
    466 #ifdef AUCCDEBUG
    467 	printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
    468 		"enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode,
    469 		p->encoding, p->precision, p->channels, p->sample_rate);
    470 #endif
    471 
    472 	switch (p->precision) {
    473 	case 8:
    474 		switch (p->encoding) {
    475 		case AUDIO_ENCODING_ULAW:
    476 			switch (p->channels) {
    477 			case 1:
    478 				sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    479 				break;
    480 			case 2:
    481 				sc->sc_decodefunc = aucc_decode_ulaw_2ch;
    482 				break;
    483 			case 3:
    484 				sc->sc_decodefunc = aucc_decode_ulaw_3ch;
    485 				break;
    486 			case 4:
    487 				sc->sc_decodefunc = aucc_decode_ulaw_4ch;
    488 				break;
    489 			default:
    490 				return EINVAL;
    491 			}
    492 			break;
    493 
    494 		case AUDIO_ENCODING_SLINEAR:
    495 		case AUDIO_ENCODING_SLINEAR_BE:
    496 		case AUDIO_ENCODING_SLINEAR_LE:
    497 			switch (p->channels) {
    498 			case 1:
    499 				sc->sc_decodefunc = aucc_decode_slinear8_1ch;
    500 				break;
    501 			case 2:
    502 				sc->sc_decodefunc = aucc_decode_slinear8_2ch;
    503 				break;
    504 			case 3:
    505 				sc->sc_decodefunc = aucc_decode_slinear8_3ch;
    506 				break;
    507 			case 4:
    508 				sc->sc_decodefunc = aucc_decode_slinear8_4ch;
    509 				break;
    510 			default:
    511 				return EINVAL;
    512 			}
    513 			break;
    514 
    515 		case AUDIO_ENCODING_ULINEAR:
    516 		case AUDIO_ENCODING_ULINEAR_BE:
    517 		case AUDIO_ENCODING_ULINEAR_LE:
    518 			switch (p->channels) {
    519 			case 1:
    520 				sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
    521 				break;
    522 			case 2:
    523 				sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
    524 				break;
    525 			case 3:
    526 				sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
    527 				break;
    528 			case 4:
    529 				sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
    530 				break;
    531 			default:
    532 				return EINVAL;
    533 			}
    534 			break;
    535 
    536 		default:
    537 			return EINVAL;
    538 		}
    539 		break;
    540 
    541 	case 16:
    542 		switch (p->encoding) {
    543 #if BYTE_ORDER == BIG_ENDIAN
    544 		case AUDIO_ENCODING_SLINEAR:
    545 #endif
    546 		case AUDIO_ENCODING_SLINEAR_BE:
    547 			switch (p->channels) {
    548 			case 1:
    549 				sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    550 				break;
    551 
    552 			case 2:
    553 				sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    554 				break;
    555 			case 3:
    556 				sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    557 				break;
    558 			case 4:
    559 				sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    560 				break;
    561 			default:
    562 				return EINVAL;
    563 			}
    564 			break;
    565 
    566 #if BYTE_ORDER == LITTLE_ENDIAN
    567 		case AUDIO_ENCODING_SLINEAR:
    568 #endif
    569 		case AUDIO_ENCODING_SLINEAR_LE:
    570 			switch (p->channels) {
    571 			case 1:
    572 				sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
    573 				break;
    574 			case 2:
    575 				sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
    576 				break;
    577 			case 3:
    578 				sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
    579 				break;
    580 			case 4:
    581 				sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
    582 				break;
    583 			default:
    584 				return EINVAL;
    585 			}
    586 			break;
    587 
    588 		default:
    589 			return EINVAL;
    590 		}
    591 		break;
    592 
    593 	default:
    594 		return EINVAL;
    595 	}
    596 
    597 	sc->sc_encoding = p->encoding;
    598 	sc->sc_precision = p->precision;
    599 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    600 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    601 
    602 	return aucc_set_out_sr(addr, p->sample_rate);
    603 }
    604 
    605 int
    606 aucc_round_blocksize(void *addr, int blk)
    607 {
    608 	/* round up to even size */
    609 	return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
    610 }
    611 
    612 int
    613 aucc_commit_settings(void *addr)
    614 {
    615 	register struct aucc_softc *sc = addr;
    616 	register int i;
    617 
    618 	DPRINTF(("sa_commit.\n"));
    619 
    620 	for (i=0;i<4;i++) {
    621 		custom.aud[i].vol=sc->sc_channel[i].nd_volume;
    622 		custom.aud[i].per=sc->sc_channel[i].nd_per;
    623 	}
    624 
    625 	DPRINTF(("commit done\n"));
    626 
    627 	return(0);
    628 }
    629 
    630 static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    631 static int masks2[4] = {1,2,4,8};
    632 
    633 int
    634 aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    635 {
    636 	struct aucc_softc *sc;
    637 	int mask;
    638 	int i, j, k, len;
    639 	u_char *dmap[4];
    640 
    641 
    642 	sc = addr;
    643 	mask = sc->sc_channelmask;
    644 
    645 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    646 
    647 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    648 
    649 	if (sc->sc_channels > 1)
    650 		mask &= masks[sc->sc_channels - 1];
    651 		/* we use first sc_channels channels */
    652 	if (mask == 0) /* active and used channels are disjoint */
    653 		return EINVAL;
    654 
    655 	for (i=0;i<4;i++) {
    656 		/* channels available ? */
    657 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    658 			return EBUSY; /* channel is busy */
    659 		if (channel[i].isaudio == -1)
    660 			return EBUSY; /* system uses them */
    661 	}
    662 
    663 	/* enable interrupt on 1st channel */
    664 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    665 		if (masks2[i] & mask) {
    666 			DPRINTF(("first channel is %d\n",i));
    667 			j=i;
    668 			sc->sc_channel[i].nd_intr=intr;
    669 			sc->sc_channel[i].nd_intrdata=arg;
    670 			break;
    671 		}
    672 	}
    673 
    674 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    675 		dmap[2], dmap[3], mask));
    676 
    677 	/* disable ints, dma for channels, until all parameters set */
    678 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    679 	custom.intreq = mask << INTB_AUD0;
    680 	custom.intena = mask << INTB_AUD0;
    681 
    682 	/* copy data to dma buffer */
    683 
    684 	if (sc->sc_channels == 1) {
    685 		dmap[0] =
    686 		dmap[1] =
    687 		dmap[2] =
    688 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    689 	}
    690 	else {
    691 		for (k=0; k<4; k++) {
    692 			if (masks2[k+j] & mask)
    693 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    694 		}
    695 	}
    696 
    697 	sc->sc_channel[j].nd_doublebuf ^= 1;
    698 	if (sc->sc_channel[j].nd_doublebuf) {
    699 		dmap[0] += AUDIO_BUF_SIZE;
    700 		dmap[1] += AUDIO_BUF_SIZE;
    701 		dmap[2] += AUDIO_BUF_SIZE;
    702 		dmap[3] += AUDIO_BUF_SIZE;
    703 	}
    704 
    705 	/* compute output length in bytes per channel.
    706 	 * divide by two only for 16bit->8bit conversion.
    707 	 */
    708 	len = cc / sc->sc_channels;
    709 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    710 		len /= 2;
    711 
    712 	/* call audio decoding routine */
    713 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    714 
    715 	/* dma buffers: we use same buffer 4 all channels
    716 	 * write dma location and length
    717 	 */
    718 	for (i = k = 0; i < 4; i++) {
    719 		if (masks2[i] & mask) {
    720 			DPRINTF(("turning channel %d on\n",i));
    721 			/* sc->sc_channel[i].nd_busy=1; */
    722 			channel[i].isaudio = 1;
    723 			channel[i].play_count = 1;
    724 			channel[i].handler = NULL;
    725 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    726 			if (sc->sc_14bit && (i > 1))
    727 				custom.aud[i].vol = 1;
    728 			else
    729 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    730 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    731 			custom.aud[i].len = len / 2;
    732 			sc->sc_channel[i].nd_mask = mask;
    733 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    734 			    sc->sc_channel[i].nd_per,
    735 			    sc->sc_channel[i].nd_volume, len));
    736 		}
    737 	}
    738 
    739 	channel[j].handler=aucc_inthdl;
    740 
    741 	/* enable ints */
    742 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    743 
    744 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    745 
    746 	/* enable dma */
    747 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    748 
    749 	DPRINTF(("enabled dma, mask=0x%x\n",mask));
    750 
    751 	return(0);
    752 }
    753 
    754 /* ARGSUSED */
    755 int
    756 aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    757 {
    758 
    759 	return ENXIO; /* no input */
    760 }
    761 
    762 int
    763 aucc_halt_output(void *addr)
    764 {
    765 	register struct aucc_softc *sc = addr;
    766 	register int i;
    767 
    768 	/* XXX only halt, if input is also halted ?? */
    769 	/* stop dma, etc */
    770 	custom.intena = AUCC_ALLINTF;
    771 	custom.dmacon = AUCC_ALLDMAF;
    772 	/* mark every busy unit idle */
    773 	for (i=0;i<4;i++) {
    774 		sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
    775 		channel[i].isaudio=0;
    776 		channel[i].play_count=0;
    777 	}
    778 
    779 	return(0);
    780 }
    781 
    782 int
    783 aucc_halt_input(void *addr)
    784 {
    785 	/* no input */
    786 
    787 	return ENXIO;
    788 }
    789 
    790 int
    791 aucc_getdev(void *addr, struct audio_device *retp)
    792 {
    793         *retp = aucc_device;
    794         return 0;
    795 }
    796 
    797 int
    798 aucc_set_port(void *addr, mixer_ctrl_t *cp)
    799 {
    800 	register struct aucc_softc *sc = addr;
    801 	register int i,j;
    802 
    803 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    804 
    805 	switch (cp->type) {
    806 	case AUDIO_MIXER_SET:
    807 		if (cp->dev!=AUCC_CHANNELS)
    808 			return EINVAL;
    809 		i=cp->un.mask;
    810 		if ((i<1) || (i>15))
    811 			return EINVAL;
    812 
    813 		sc->sc_channelmask=i;
    814 		break;
    815 
    816 	case AUDIO_MIXER_VALUE:
    817 		i=cp->un.value.num_channels;
    818 		if ((i<1) || (i>4))
    819 			return EINVAL;
    820 
    821 #ifdef __XXXwhatsthat
    822 		if (cp->dev!=AUCC_VOLUME)
    823 			return EINVAL;
    824 #endif
    825 
    826 		/* set volume for channel 0..i-1 */
    827 
    828 		/* evil workaround for xanim bug, IMO */
    829 		if ((sc->sc_channels == 1) && (i == 2)) {
    830 			sc->sc_channel[0].nd_volume =
    831 			    sc->sc_channel[3].nd_volume =
    832 			    cp->un.value.level[0]>>2;
    833 			sc->sc_channel[1].nd_volume =
    834 			    sc->sc_channel[2].nd_volume =
    835 			    cp->un.value.level[1]>>2;
    836 		} else if (i>1) {
    837 			for (j=0;j<i;j++)
    838 	 			sc->sc_channel[j].nd_volume =
    839 				    cp->un.value.level[j]>>2;
    840 		} else if (sc->sc_channels > 1)
    841 			for (j=0; j<sc->sc_channels; j++)
    842 	 			sc->sc_channel[j].nd_volume =
    843 				    cp->un.value.level[0]>>2;
    844 		else
    845 			for (j=0; j<4; j++)
    846 	 			sc->sc_channel[j].nd_volume =
    847 				    cp->un.value.level[0]>>2;
    848 		break;
    849 
    850 	default:
    851 		return EINVAL;
    852 		break;
    853 	}
    854 	return 0;
    855 }
    856 
    857 
    858 int
    859 aucc_get_port(void *addr, mixer_ctrl_t *cp)
    860 {
    861 	register struct aucc_softc *sc = addr;
    862 	register int i,j;
    863 
    864 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    865 
    866 	switch (cp->type) {
    867 	case AUDIO_MIXER_SET:
    868 		if (cp->dev!=AUCC_CHANNELS)
    869 			return EINVAL;
    870 		cp->un.mask=sc->sc_channelmask;
    871 		break;
    872 
    873 	case AUDIO_MIXER_VALUE:
    874 		i = cp->un.value.num_channels;
    875 		if ((i<1)||(i>4))
    876 			return EINVAL;
    877 
    878 		for (j=0;j<i;j++)
    879 			cp->un.value.level[j] =
    880 			    (sc->sc_channel[j].nd_volume<<2) +
    881 			    (sc->sc_channel[j].nd_volume>>4);
    882 		break;
    883 
    884 	default:
    885 		return EINVAL;
    886 	}
    887 	return 0;
    888 }
    889 
    890 
    891 int
    892 aucc_get_props(void *addr)
    893 {
    894 	return 0;
    895 }
    896 
    897 int
    898 aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
    899 {
    900 	register int i;
    901 
    902 	switch(dip->index) {
    903 	case AUCC_CHANNELS:
    904 		dip->type = AUDIO_MIXER_SET;
    905 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    906 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    907                 strcpy(dip->label.name, AudioNspeaker);
    908 		for (i=0;i<16;i++) {
    909 			sprintf(dip->un.s.member[i].label.name,
    910 			    "channelmask%d", i);
    911 			dip->un.s.member[i].mask = i;
    912 		}
    913 		dip->un.s.num_mem = 16;
    914 		break;
    915 
    916 	case AUCC_VOLUME:
    917 		dip->type = AUDIO_MIXER_VALUE;
    918 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    919 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    920 		strcpy(dip->label.name, AudioNmaster);
    921 		dip->un.v.num_channels = 4;
    922 		strcpy(dip->un.v.units.name, AudioNvolume);
    923 		break;
    924 
    925 	case AUCC_OUTPUT_CLASS:
    926 		dip->type = AUDIO_MIXER_CLASS;
    927 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    928 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    929 		strcpy(dip->label.name, AudioCoutputs);
    930 		break;
    931 
    932 	default:
    933 		return ENXIO;
    934 	}
    935 
    936 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    937 
    938 	return(0);
    939 }
    940 
    941 
    942 /* audio int handler */
    943 void
    944 aucc_inthdl(int ch)
    945 {
    946 	register int i;
    947 	register int mask=aucc->sc_channel[ch].nd_mask;
    948 
    949 	/* for all channels in this maskgroup:
    950 	   disable dma, int
    951 	   mark idle */
    952 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
    953 
    954 	custom.intreq=mask<<INTB_AUD0; /* clear request */
    955 	/*
    956 	 * XXX: maybe we can leave ints and/or DMA on,
    957 	 * if another sample has to be played?
    958 	 */
    959 	custom.intena=mask<<INTB_AUD0;
    960 	/*
    961 	 * XXX custom.dmacon=mask; NO!!!
    962 	 */
    963 	for (i=0; i<4; i++) {
    964 		if (masks2[i]&&mask) {
    965 			DPRINTF(("marking channel %d idle\n",i));
    966 			aucc->sc_channel[i].nd_busy=0;
    967 			aucc->sc_channel[i].nd_mask=0;
    968 			channel[i].isaudio=channel[i].play_count=0;
    969 		}
    970 	}
    971 
    972 	/* call handler */
    973 	if (aucc->sc_channel[ch].nd_intr) {
    974 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
    975 		(*(aucc->sc_channel[ch].nd_intr))
    976 		    (aucc->sc_channel[ch].nd_intrdata);
    977 	}
    978 	else
    979 		DPRINTF(("zero int handler\n"));
    980 	DPRINTF(("ints done\n"));
    981 }
    982 
    983 
    984 
    985 
    986 /* transform frequency to period, adjust bounds */
    987 static u_int
    988 freqtoper(u_int freq)
    989 {
    990 	u_int per=eclockfreq*5/freq;
    991 
    992 	if (per<124)
    993 		per=124; /* must have at least 124 ticks between samples */
    994 
    995 	return per;
    996 }
    997 
    998 /* transform period to frequency */
    999 static u_int
   1000 pertofreq(u_int per)
   1001 {
   1002 	u_int freq=eclockfreq*5/per;
   1003 
   1004 	return freq;
   1005 }
   1006 
   1007 static void
   1008 aucc_decode_slinear8_1ch(u_char **dmap, u_char *p, int i)
   1009 {
   1010 	memcpy (dmap[0], p, i);
   1011 }
   1012 
   1013 static void
   1014 aucc_decode_slinear8_2ch(u_char **dmap, u_char *p, int i)
   1015 {
   1016 	u_char *ch0 = dmap[0];
   1017 	u_char *ch1 = dmap[1];
   1018 
   1019 	while (i--) {
   1020 		*ch0++ = *p++;
   1021 		*ch1++ = *p++;
   1022 	}
   1023 }
   1024 
   1025 static void
   1026 aucc_decode_slinear8_3ch(u_char **dmap, u_char *p, int i)
   1027 {
   1028 	u_char *ch0 = dmap[0];
   1029 	u_char *ch1 = dmap[1];
   1030 	u_char *ch2 = dmap[2];
   1031 
   1032 	while (i--) {
   1033 		*ch0++ = *p++;
   1034 		*ch1++ = *p++;
   1035 		*ch2++ = *p++;
   1036 	}
   1037 }
   1038 
   1039 static void
   1040 aucc_decode_slinear8_4ch(u_char **dmap, u_char *p, int i)
   1041 {
   1042 	u_char *ch0 = dmap[0];
   1043 	u_char *ch1 = dmap[1];
   1044 	u_char *ch2 = dmap[2];
   1045 	u_char *ch3 = dmap[3];
   1046 
   1047 	while (i--) {
   1048 		*ch0++ = *p++;
   1049 		*ch1++ = *p++;
   1050 		*ch2++ = *p++;
   1051 		*ch3++ = *p++;
   1052 	}
   1053 }
   1054 
   1055 static void
   1056 aucc_decode_ulinear8_1ch(u_char **dmap, u_char *p, int i)
   1057 {
   1058 	u_char *ch0 = dmap[0];
   1059 
   1060 	while (i--)
   1061 		*ch0++ = *p++ - 128;
   1062 }
   1063 
   1064 static void
   1065 aucc_decode_ulinear8_2ch(u_char **dmap, u_char *p, int i)
   1066 {
   1067 	u_char *ch0 = dmap[0];
   1068 	u_char *ch1 = dmap[1];
   1069 
   1070 	while (i--) {
   1071 		*ch0++ = *p++ - 128;
   1072 		*ch1++ = *p++ - 128;
   1073 	}
   1074 }
   1075 
   1076 static void
   1077 aucc_decode_ulinear8_3ch(u_char **dmap, u_char *p, int i)
   1078 {
   1079 	u_char *ch0 = dmap[0];
   1080 	u_char *ch1 = dmap[1];
   1081 	u_char *ch2 = dmap[2];
   1082 
   1083 	while (i--) {
   1084 		*ch0++ = *p++ - 128;
   1085 		*ch1++ = *p++ - 128;
   1086 		*ch2++ = *p++ - 128;
   1087 	}
   1088 }
   1089 
   1090 static void
   1091 aucc_decode_ulinear8_4ch(u_char **dmap, u_char *p, int i)
   1092 {
   1093 	u_char *ch0 = dmap[0];
   1094 	u_char *ch1 = dmap[1];
   1095 	u_char *ch2 = dmap[2];
   1096 	u_char *ch3 = dmap[3];
   1097 
   1098 	while (i--) {
   1099 		*ch0++ = *p++ - 128;
   1100 		*ch1++ = *p++ - 128;
   1101 		*ch2++ = *p++ - 128;
   1102 		*ch3++ = *p++ - 128;
   1103 	}
   1104 }
   1105 
   1106 
   1107 static void
   1108 aucc_decode_ulaw_1ch(u_char **dmap, u_char *p, int i)
   1109 {
   1110 	u_char *ch0 = dmap[0];
   1111 
   1112 	while (i--)
   1113 		*ch0++ = ulaw_to_lin[*p++];
   1114 }
   1115 
   1116 static void
   1117 aucc_decode_ulaw_2ch(u_char **dmap, u_char *p, int i)
   1118 {
   1119 	u_char *ch0 = dmap[0];
   1120 	u_char *ch1 = dmap[1];
   1121 
   1122 	while (i--) {
   1123 		*ch0++ = ulaw_to_lin[*p++];
   1124 		*ch1++ = ulaw_to_lin[*p++];
   1125 	}
   1126 }
   1127 
   1128 static void
   1129 aucc_decode_ulaw_3ch(u_char **dmap, u_char *p, int i)
   1130 {
   1131 	u_char *ch0 = dmap[0];
   1132 	u_char *ch1 = dmap[1];
   1133 	u_char *ch2 = dmap[2];
   1134 
   1135 	while (i--) {
   1136 		*ch0++ = ulaw_to_lin[*p++];
   1137 		*ch1++ = ulaw_to_lin[*p++];
   1138 		*ch2++ = ulaw_to_lin[*p++];
   1139 	}
   1140 }
   1141 
   1142 static void
   1143 aucc_decode_ulaw_4ch(u_char **dmap, u_char *p, int i)
   1144 {
   1145 	u_char *ch0 = dmap[0];
   1146 	u_char *ch1 = dmap[1];
   1147 	u_char *ch2 = dmap[2];
   1148 	u_char *ch3 = dmap[3];
   1149 
   1150 	while (i--) {
   1151 		*ch0++ = ulaw_to_lin[*p++];
   1152 		*ch1++ = ulaw_to_lin[*p++];
   1153 		*ch2++ = ulaw_to_lin[*p++];
   1154 		*ch3++ = ulaw_to_lin[*p++];
   1155 	}
   1156 }
   1157 
   1158 
   1159 /* 14bit output */
   1160 static void
   1161 aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
   1162 {
   1163 	u_char *ch0 = dmap[0];
   1164 	u_char *ch3 = dmap[1]; /* XXX should be 3 */
   1165 
   1166 	while (i--) {
   1167 		*ch0++ = *p++;
   1168 		*ch3++ = *p++ >> 2;
   1169 	}
   1170 }
   1171 
   1172 /* 14bit stereo output */
   1173 static void
   1174 aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
   1175 {
   1176 	u_char *ch0 = dmap[0];
   1177 	u_char *ch1 = dmap[1];
   1178 	u_char *ch2 = dmap[2];
   1179 	u_char *ch3 = dmap[3];
   1180 
   1181 	while (i--) {
   1182 		*ch0++ = *p++;
   1183 		*ch3++ = *p++ >> 2;
   1184 		*ch1++ = *p++;
   1185 		*ch2++ = *p++ >> 2;
   1186 	}
   1187 }
   1188 
   1189 static void
   1190 aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
   1191 {
   1192 	u_char *ch0 = dmap[0];
   1193 	u_char *ch1 = dmap[1];
   1194 	u_char *ch2 = dmap[2];
   1195 
   1196 	while (i--) {
   1197 		*ch0++ = *p++; p++;
   1198 		*ch1++ = *p++; p++;
   1199 		*ch2++ = *p++; p++;
   1200 	}
   1201 }
   1202 
   1203 static void
   1204 aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
   1205 {
   1206 	u_char *ch0 = dmap[0];
   1207 	u_char *ch1 = dmap[1];
   1208 	u_char *ch2 = dmap[2];
   1209 	u_char *ch3 = dmap[3];
   1210 
   1211 	while (i--) {
   1212 		*ch0++ = *p++; p++;
   1213 		*ch1++ = *p++; p++;
   1214 		*ch2++ = *p++; p++;
   1215 		*ch3++ = *p++; p++;
   1216 	}
   1217 }
   1218 
   1219 /* 14bit output, swap bytes */
   1220 static void
   1221 aucc_decode_slinear16sw_1ch(u_char **dmap, u_char *p, int i)
   1222 {
   1223 	u_char *ch0 = dmap[0];
   1224 	u_char *ch3 = dmap[1];	/* XXX should be 3 */
   1225 
   1226 	while (i--) {
   1227 		*ch3++ = *p++ >> 2;
   1228 		*ch0++ = *p++;
   1229 	}
   1230 }
   1231 
   1232 static void
   1233 aucc_decode_slinear16sw_2ch(u_char **dmap, u_char *p, int i)
   1234 {
   1235 	u_char *ch0 = dmap[0];
   1236 	u_char *ch1 = dmap[1];
   1237 	u_char *ch2 = dmap[2];
   1238 	u_char *ch3 = dmap[3];
   1239 
   1240 	while (i--) {
   1241 		*ch3++ = *p++ >> 2;
   1242 		*ch0++ = *p++;
   1243 		*ch2++ = *p++ >> 2;
   1244 		*ch1++ = *p++;
   1245 	}
   1246 }
   1247 
   1248 static void
   1249 aucc_decode_slinear16sw_3ch(u_char **dmap, u_char *p, 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 		p++; *ch0++ = *p++;
   1257 		p++; *ch1++ = *p++;
   1258 		p++; *ch2++ = *p++;
   1259 	}
   1260 }
   1261 
   1262 static void
   1263 aucc_decode_slinear16sw_4ch(u_char **dmap, u_char *p, 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 		p++; *ch0++ = *p++;
   1272 		p++; *ch1++ = *p++;
   1273 		p++; *ch2++ = *p++;
   1274 		p++; *ch3++ = *p++;
   1275 	}
   1276 }
   1277 
   1278 
   1279 #endif /* NAUCC > 0 */
   1280