Home | History | Annotate | Line # | Download | only in dev
aucc.c revision 1.35.2.1
      1 /*	$NetBSD: aucc.c,v 1.35.2.1 2005/01/03 16:42:02 kent 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  * - mu-law -> 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 mu-law/A-law 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/cdefs.h>
     56 __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.35.2.1 2005/01/03 16:42:02 kent Exp $");
     57 
     58 #include <sys/param.h>
     59 #include <sys/systm.h>
     60 #include <sys/errno.h>
     61 #include <sys/ioctl.h>
     62 #include <sys/device.h>
     63 #include <sys/proc.h>
     64 #include <machine/cpu.h>
     65 
     66 #include <sys/audioio.h>
     67 #include <dev/audio_if.h>
     68 #include <amiga/amiga/cc.h>
     69 #include <amiga/amiga/custom.h>
     70 #include <amiga/amiga/device.h>
     71 #include <amiga/dev/auccvar.h>
     72 
     73 #include "opt_lev6_defer.h"
     74 
     75 
     76 #ifdef LEV6_DEFER
     77 #define AUCC_MAXINT 3
     78 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
     79 #else
     80 #define AUCC_MAXINT 4
     81 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
     82 #endif
     83 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
     84 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
     85 
     86 #ifdef AUDIO_DEBUG
     87 /*extern printf(const char *,...);*/
     88 int     auccdebug = 1;
     89 #define DPRINTF(x)      if (auccdebug) printf x
     90 #else
     91 #define DPRINTF(x)
     92 #endif
     93 
     94 #ifdef splaudio
     95 #undef splaudio
     96 #endif
     97 
     98 #define splaudio() spl4();
     99 
    100 /* clock frequency.. */
    101 extern int eclockfreq;
    102 
    103 
    104 /* hw audio ch */
    105 extern struct audio_channel channel[4];
    106 
    107 
    108 /*
    109  * Software state.
    110  */
    111 struct aucc_softc {
    112 	struct	device sc_dev;		/* base device */
    113 
    114 	int	sc_open;		/* single use device */
    115 	aucc_data_t sc_channel[4];	/* per channel freq, ... */
    116 	u_int	sc_encoding;		/* encoding AUDIO_ENCODING_.*/
    117 	int	sc_channels;		/* # of channels used */
    118 	int	sc_precision;		/* 8 or 16 bits */
    119 	int	sc_14bit;		/* 14bit output enabled */
    120 
    121 	int	sc_intrcnt;		/* interrupt count */
    122 	int	sc_channelmask;  	/* which channels are used ? */
    123 	void (*sc_decodefunc)(u_char **, u_char *, int);
    124 				/* pointer to format conversion routine */
    125 };
    126 
    127 /* interrupt interfaces */
    128 void aucc_inthdl(int);
    129 
    130 /* forward declarations */
    131 static int init_aucc(struct aucc_softc *);
    132 static u_int freqtoper(u_int);
    133 static u_int pertofreq(u_int);
    134 
    135 /* autoconfiguration driver */
    136 void	auccattach(struct device *, struct device *, void *);
    137 int	auccmatch(struct device *, struct cfdata *, void *);
    138 
    139 CFATTACH_DECL(aucc, sizeof(struct aucc_softc),
    140     auccmatch, auccattach, NULL, NULL);
    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 mulaw_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_int);
    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, audio_params_t *, audio_params_t *,
    206 			stream_filter_list_t *, stream_filter_list_t *);
    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_mulaw_1ch(u_char **, u_char *, int);
    221 static void aucc_decode_mulaw_2ch(u_char **, u_char *, int);
    222 static void aucc_decode_mulaw_3ch(u_char **, u_char *, int);
    223 static void aucc_decode_mulaw_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 const 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_mulaw_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_int 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,
    459 		audio_params_t *p, audio_params_t *r,
    460 		stream_filter_list_t *pfil, stream_filter_list_t *rfil)
    461 {
    462 	struct aucc_softc *sc = addr;
    463 
    464 	/* if (setmode & AUMODE_RECORD)
    465 		return 0 ENXIO*/;
    466 
    467 #ifdef AUCCDEBUG
    468 	printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
    469 		"enc %u, bits %u, chn %u, sr %u)\n", setmode, usemode,
    470 		p->encoding, p->precision, p->channels, p->sample_rate);
    471 #endif
    472 
    473 	switch (p->precision) {
    474 	case 8:
    475 		switch (p->encoding) {
    476 		case AUDIO_ENCODING_ULAW:
    477 			switch (p->channels) {
    478 			case 1:
    479 				sc->sc_decodefunc = aucc_decode_mulaw_1ch;
    480 				break;
    481 			case 2:
    482 				sc->sc_decodefunc = aucc_decode_mulaw_2ch;
    483 				break;
    484 			case 3:
    485 				sc->sc_decodefunc = aucc_decode_mulaw_3ch;
    486 				break;
    487 			case 4:
    488 				sc->sc_decodefunc = aucc_decode_mulaw_4ch;
    489 				break;
    490 			default:
    491 				return EINVAL;
    492 			}
    493 			break;
    494 
    495 		case AUDIO_ENCODING_SLINEAR:
    496 		case AUDIO_ENCODING_SLINEAR_BE:
    497 		case AUDIO_ENCODING_SLINEAR_LE:
    498 			switch (p->channels) {
    499 			case 1:
    500 				sc->sc_decodefunc = aucc_decode_slinear8_1ch;
    501 				break;
    502 			case 2:
    503 				sc->sc_decodefunc = aucc_decode_slinear8_2ch;
    504 				break;
    505 			case 3:
    506 				sc->sc_decodefunc = aucc_decode_slinear8_3ch;
    507 				break;
    508 			case 4:
    509 				sc->sc_decodefunc = aucc_decode_slinear8_4ch;
    510 				break;
    511 			default:
    512 				return EINVAL;
    513 			}
    514 			break;
    515 
    516 		case AUDIO_ENCODING_ULINEAR:
    517 		case AUDIO_ENCODING_ULINEAR_BE:
    518 		case AUDIO_ENCODING_ULINEAR_LE:
    519 			switch (p->channels) {
    520 			case 1:
    521 				sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
    522 				break;
    523 			case 2:
    524 				sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
    525 				break;
    526 			case 3:
    527 				sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
    528 				break;
    529 			case 4:
    530 				sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
    531 				break;
    532 			default:
    533 				return EINVAL;
    534 			}
    535 			break;
    536 
    537 		default:
    538 			return EINVAL;
    539 		}
    540 		break;
    541 
    542 	case 16:
    543 		switch (p->encoding) {
    544 #if BYTE_ORDER == BIG_ENDIAN
    545 		case AUDIO_ENCODING_SLINEAR:
    546 #endif
    547 		case AUDIO_ENCODING_SLINEAR_BE:
    548 			switch (p->channels) {
    549 			case 1:
    550 				sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    551 				break;
    552 
    553 			case 2:
    554 				sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    555 				break;
    556 			case 3:
    557 				sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    558 				break;
    559 			case 4:
    560 				sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    561 				break;
    562 			default:
    563 				return EINVAL;
    564 			}
    565 			break;
    566 
    567 #if BYTE_ORDER == LITTLE_ENDIAN
    568 		case AUDIO_ENCODING_SLINEAR:
    569 #endif
    570 		case AUDIO_ENCODING_SLINEAR_LE:
    571 			switch (p->channels) {
    572 			case 1:
    573 				sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
    574 				break;
    575 			case 2:
    576 				sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
    577 				break;
    578 			case 3:
    579 				sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
    580 				break;
    581 			case 4:
    582 				sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
    583 				break;
    584 			default:
    585 				return EINVAL;
    586 			}
    587 			break;
    588 
    589 		default:
    590 			return EINVAL;
    591 		}
    592 		break;
    593 
    594 	default:
    595 		return EINVAL;
    596 	}
    597 
    598 	sc->sc_encoding = p->encoding;
    599 	sc->sc_precision = p->precision;
    600 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    601 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    602 
    603 	return aucc_set_out_sr(addr, p->sample_rate);
    604 }
    605 
    606 int
    607 aucc_round_blocksize(void *addr, int blk)
    608 {
    609 	/* round up to even size */
    610 	return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
    611 }
    612 
    613 int
    614 aucc_commit_settings(void *addr)
    615 {
    616 	register struct aucc_softc *sc = addr;
    617 	register int i;
    618 
    619 	DPRINTF(("sa_commit.\n"));
    620 
    621 	for (i=0;i<4;i++) {
    622 		custom.aud[i].vol=sc->sc_channel[i].nd_volume;
    623 		custom.aud[i].per=sc->sc_channel[i].nd_per;
    624 	}
    625 
    626 	DPRINTF(("commit done\n"));
    627 
    628 	return(0);
    629 }
    630 
    631 static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    632 static int masks2[4] = {1,2,4,8};
    633 
    634 int
    635 aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    636 {
    637 	struct aucc_softc *sc;
    638 	int mask;
    639 	int i, j, k, len;
    640 	u_char *dmap[4];
    641 
    642 
    643 	sc = addr;
    644 	mask = sc->sc_channelmask;
    645 
    646 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    647 
    648 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    649 
    650 	if (sc->sc_channels > 1)
    651 		mask &= masks[sc->sc_channels - 1];
    652 		/* we use first sc_channels channels */
    653 	if (mask == 0) /* active and used channels are disjoint */
    654 		return EINVAL;
    655 
    656 	for (i=0;i<4;i++) {
    657 		/* channels available ? */
    658 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    659 			return EBUSY; /* channel is busy */
    660 		if (channel[i].isaudio == -1)
    661 			return EBUSY; /* system uses them */
    662 	}
    663 
    664 	/* enable interrupt on 1st channel */
    665 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    666 		if (masks2[i] & mask) {
    667 			DPRINTF(("first channel is %d\n",i));
    668 			j=i;
    669 			sc->sc_channel[i].nd_intr=intr;
    670 			sc->sc_channel[i].nd_intrdata=arg;
    671 			break;
    672 		}
    673 	}
    674 
    675 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    676 		dmap[2], dmap[3], mask));
    677 
    678 	/* disable ints, DMA for channels, until all parameters set */
    679 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    680 	custom.intreq = mask << INTB_AUD0;
    681 	custom.intena = mask << INTB_AUD0;
    682 
    683 	/* copy data to DMA buffer */
    684 
    685 	if (sc->sc_channels == 1) {
    686 		dmap[0] =
    687 		dmap[1] =
    688 		dmap[2] =
    689 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    690 	}
    691 	else {
    692 		for (k=0; k<4; k++) {
    693 			if (masks2[k+j] & mask)
    694 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    695 		}
    696 	}
    697 
    698 	sc->sc_channel[j].nd_doublebuf ^= 1;
    699 	if (sc->sc_channel[j].nd_doublebuf) {
    700 		dmap[0] += AUDIO_BUF_SIZE;
    701 		dmap[1] += AUDIO_BUF_SIZE;
    702 		dmap[2] += AUDIO_BUF_SIZE;
    703 		dmap[3] += AUDIO_BUF_SIZE;
    704 	}
    705 
    706 	/* compute output length in bytes per channel.
    707 	 * divide by two only for 16bit->8bit conversion.
    708 	 */
    709 	len = cc / sc->sc_channels;
    710 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    711 		len /= 2;
    712 
    713 	/* call audio decoding routine */
    714 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    715 
    716 	/* DMA buffers: we use same buffer 4 all channels
    717 	 * write DMA location and length
    718 	 */
    719 	for (i = k = 0; i < 4; i++) {
    720 		if (masks2[i] & mask) {
    721 			DPRINTF(("turning channel %d on\n",i));
    722 			/* sc->sc_channel[i].nd_busy=1; */
    723 			channel[i].isaudio = 1;
    724 			channel[i].play_count = 1;
    725 			channel[i].handler = NULL;
    726 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    727 			if (sc->sc_14bit && (i > 1))
    728 				custom.aud[i].vol = 1;
    729 			else
    730 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    731 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    732 			custom.aud[i].len = len / 2;
    733 			sc->sc_channel[i].nd_mask = mask;
    734 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    735 			    sc->sc_channel[i].nd_per,
    736 			    sc->sc_channel[i].nd_volume, len));
    737 		}
    738 	}
    739 
    740 	channel[j].handler=aucc_inthdl;
    741 
    742 	/* enable ints */
    743 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    744 
    745 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    746 
    747 	/* enable DMA */
    748 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    749 
    750 	DPRINTF(("enabled DMA, mask=0x%x\n",mask));
    751 
    752 	return(0);
    753 }
    754 
    755 /* ARGSUSED */
    756 int
    757 aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    758 {
    759 
    760 	return ENXIO; /* no input */
    761 }
    762 
    763 int
    764 aucc_halt_output(void *addr)
    765 {
    766 	register struct aucc_softc *sc = addr;
    767 	register int i;
    768 
    769 	/* XXX only halt, if input is also halted ?? */
    770 	/* stop DMA, etc */
    771 	custom.intena = AUCC_ALLINTF;
    772 	custom.dmacon = AUCC_ALLDMAF;
    773 	/* mark every busy unit idle */
    774 	for (i=0;i<4;i++) {
    775 		sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
    776 		channel[i].isaudio=0;
    777 		channel[i].play_count=0;
    778 	}
    779 
    780 	return(0);
    781 }
    782 
    783 int
    784 aucc_halt_input(void *addr)
    785 {
    786 	/* no input */
    787 
    788 	return ENXIO;
    789 }
    790 
    791 int
    792 aucc_getdev(void *addr, struct audio_device *retp)
    793 {
    794         *retp = aucc_device;
    795         return 0;
    796 }
    797 
    798 int
    799 aucc_set_port(void *addr, mixer_ctrl_t *cp)
    800 {
    801 	register struct aucc_softc *sc = addr;
    802 	register int i,j;
    803 
    804 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    805 
    806 	switch (cp->type) {
    807 	case AUDIO_MIXER_SET:
    808 		if (cp->dev!=AUCC_CHANNELS)
    809 			return EINVAL;
    810 		i=cp->un.mask;
    811 		if ((i<1) || (i>15))
    812 			return EINVAL;
    813 
    814 		sc->sc_channelmask=i;
    815 		break;
    816 
    817 	case AUDIO_MIXER_VALUE:
    818 		i=cp->un.value.num_channels;
    819 		if ((i<1) || (i>4))
    820 			return EINVAL;
    821 
    822 #ifdef __XXXwhatsthat
    823 		if (cp->dev!=AUCC_VOLUME)
    824 			return EINVAL;
    825 #endif
    826 
    827 		/* set volume for channel 0..i-1 */
    828 
    829 		/* evil workaround for xanim bug, IMO */
    830 		if ((sc->sc_channels == 1) && (i == 2)) {
    831 			sc->sc_channel[0].nd_volume =
    832 			    sc->sc_channel[3].nd_volume =
    833 			    cp->un.value.level[0]>>2;
    834 			sc->sc_channel[1].nd_volume =
    835 			    sc->sc_channel[2].nd_volume =
    836 			    cp->un.value.level[1]>>2;
    837 		} else if (i>1) {
    838 			for (j=0;j<i;j++)
    839 	 			sc->sc_channel[j].nd_volume =
    840 				    cp->un.value.level[j]>>2;
    841 		} else if (sc->sc_channels > 1)
    842 			for (j=0; j<sc->sc_channels; j++)
    843 	 			sc->sc_channel[j].nd_volume =
    844 				    cp->un.value.level[0]>>2;
    845 		else
    846 			for (j=0; j<4; j++)
    847 	 			sc->sc_channel[j].nd_volume =
    848 				    cp->un.value.level[0]>>2;
    849 		break;
    850 
    851 	default:
    852 		return EINVAL;
    853 		break;
    854 	}
    855 	return 0;
    856 }
    857 
    858 
    859 int
    860 aucc_get_port(void *addr, mixer_ctrl_t *cp)
    861 {
    862 	register struct aucc_softc *sc = addr;
    863 	register int i,j;
    864 
    865 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    866 
    867 	switch (cp->type) {
    868 	case AUDIO_MIXER_SET:
    869 		if (cp->dev!=AUCC_CHANNELS)
    870 			return EINVAL;
    871 		cp->un.mask=sc->sc_channelmask;
    872 		break;
    873 
    874 	case AUDIO_MIXER_VALUE:
    875 		i = cp->un.value.num_channels;
    876 		if ((i<1)||(i>4))
    877 			return EINVAL;
    878 
    879 		for (j=0;j<i;j++)
    880 			cp->un.value.level[j] =
    881 			    (sc->sc_channel[j].nd_volume<<2) +
    882 			    (sc->sc_channel[j].nd_volume>>4);
    883 		break;
    884 
    885 	default:
    886 		return EINVAL;
    887 	}
    888 	return 0;
    889 }
    890 
    891 
    892 int
    893 aucc_get_props(void *addr)
    894 {
    895 	return 0;
    896 }
    897 
    898 int
    899 aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
    900 {
    901 	register int i;
    902 
    903 	switch(dip->index) {
    904 	case AUCC_CHANNELS:
    905 		dip->type = AUDIO_MIXER_SET;
    906 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    907 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    908                 strcpy(dip->label.name, AudioNspeaker);
    909 		for (i=0;i<16;i++) {
    910 			sprintf(dip->un.s.member[i].label.name,
    911 			    "channelmask%d", i);
    912 			dip->un.s.member[i].mask = i;
    913 		}
    914 		dip->un.s.num_mem = 16;
    915 		break;
    916 
    917 	case AUCC_VOLUME:
    918 		dip->type = AUDIO_MIXER_VALUE;
    919 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    920 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    921 		strcpy(dip->label.name, AudioNmaster);
    922 		dip->un.v.num_channels = 4;
    923 		strcpy(dip->un.v.units.name, AudioNvolume);
    924 		break;
    925 
    926 	case AUCC_OUTPUT_CLASS:
    927 		dip->type = AUDIO_MIXER_CLASS;
    928 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    929 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    930 		strcpy(dip->label.name, AudioCoutputs);
    931 		break;
    932 
    933 	default:
    934 		return ENXIO;
    935 	}
    936 
    937 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    938 
    939 	return(0);
    940 }
    941 
    942 
    943 /* audio int handler */
    944 void
    945 aucc_inthdl(int ch)
    946 {
    947 	register int i;
    948 	register int mask=aucc->sc_channel[ch].nd_mask;
    949 
    950 	/* for all channels in this maskgroup:
    951 	   disable DMA, int
    952 	   mark idle */
    953 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
    954 
    955 	custom.intreq=mask<<INTB_AUD0; /* clear request */
    956 	/*
    957 	 * XXX: maybe we can leave ints and/or DMA on,
    958 	 * if another sample has to be played?
    959 	 */
    960 	custom.intena=mask<<INTB_AUD0;
    961 	/*
    962 	 * XXX custom.dmacon=mask; NO!!!
    963 	 */
    964 	for (i=0; i<4; i++) {
    965 		if (masks2[i]&&mask) {
    966 			DPRINTF(("marking channel %d idle\n",i));
    967 			aucc->sc_channel[i].nd_busy=0;
    968 			aucc->sc_channel[i].nd_mask=0;
    969 			channel[i].isaudio=channel[i].play_count=0;
    970 		}
    971 	}
    972 
    973 	/* call handler */
    974 	if (aucc->sc_channel[ch].nd_intr) {
    975 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
    976 		(*(aucc->sc_channel[ch].nd_intr))
    977 		    (aucc->sc_channel[ch].nd_intrdata);
    978 	}
    979 	else
    980 		DPRINTF(("zero int handler\n"));
    981 	DPRINTF(("ints done\n"));
    982 }
    983 
    984 
    985 
    986 
    987 /* transform frequency to period, adjust bounds */
    988 static u_int
    989 freqtoper(u_int freq)
    990 {
    991 	u_int per=eclockfreq*5/freq;
    992 
    993 	if (per<124)
    994 		per=124; /* must have at least 124 ticks between samples */
    995 
    996 	return per;
    997 }
    998 
    999 /* transform period to frequency */
   1000 static u_int
   1001 pertofreq(u_int per)
   1002 {
   1003 	u_int freq=eclockfreq*5/per;
   1004 
   1005 	return freq;
   1006 }
   1007 
   1008 static void
   1009 aucc_decode_slinear8_1ch(u_char **dmap, u_char *p, int i)
   1010 {
   1011 	memcpy (dmap[0], p, i);
   1012 }
   1013 
   1014 static void
   1015 aucc_decode_slinear8_2ch(u_char **dmap, u_char *p, int i)
   1016 {
   1017 	u_char *ch0 = dmap[0];
   1018 	u_char *ch1 = dmap[1];
   1019 
   1020 	while (i--) {
   1021 		*ch0++ = *p++;
   1022 		*ch1++ = *p++;
   1023 	}
   1024 }
   1025 
   1026 static void
   1027 aucc_decode_slinear8_3ch(u_char **dmap, u_char *p, int i)
   1028 {
   1029 	u_char *ch0 = dmap[0];
   1030 	u_char *ch1 = dmap[1];
   1031 	u_char *ch2 = dmap[2];
   1032 
   1033 	while (i--) {
   1034 		*ch0++ = *p++;
   1035 		*ch1++ = *p++;
   1036 		*ch2++ = *p++;
   1037 	}
   1038 }
   1039 
   1040 static void
   1041 aucc_decode_slinear8_4ch(u_char **dmap, u_char *p, int i)
   1042 {
   1043 	u_char *ch0 = dmap[0];
   1044 	u_char *ch1 = dmap[1];
   1045 	u_char *ch2 = dmap[2];
   1046 	u_char *ch3 = dmap[3];
   1047 
   1048 	while (i--) {
   1049 		*ch0++ = *p++;
   1050 		*ch1++ = *p++;
   1051 		*ch2++ = *p++;
   1052 		*ch3++ = *p++;
   1053 	}
   1054 }
   1055 
   1056 static void
   1057 aucc_decode_ulinear8_1ch(u_char **dmap, u_char *p, int i)
   1058 {
   1059 	u_char *ch0 = dmap[0];
   1060 
   1061 	while (i--)
   1062 		*ch0++ = *p++ - 128;
   1063 }
   1064 
   1065 static void
   1066 aucc_decode_ulinear8_2ch(u_char **dmap, u_char *p, int i)
   1067 {
   1068 	u_char *ch0 = dmap[0];
   1069 	u_char *ch1 = dmap[1];
   1070 
   1071 	while (i--) {
   1072 		*ch0++ = *p++ - 128;
   1073 		*ch1++ = *p++ - 128;
   1074 	}
   1075 }
   1076 
   1077 static void
   1078 aucc_decode_ulinear8_3ch(u_char **dmap, u_char *p, int i)
   1079 {
   1080 	u_char *ch0 = dmap[0];
   1081 	u_char *ch1 = dmap[1];
   1082 	u_char *ch2 = dmap[2];
   1083 
   1084 	while (i--) {
   1085 		*ch0++ = *p++ - 128;
   1086 		*ch1++ = *p++ - 128;
   1087 		*ch2++ = *p++ - 128;
   1088 	}
   1089 }
   1090 
   1091 static void
   1092 aucc_decode_ulinear8_4ch(u_char **dmap, u_char *p, int i)
   1093 {
   1094 	u_char *ch0 = dmap[0];
   1095 	u_char *ch1 = dmap[1];
   1096 	u_char *ch2 = dmap[2];
   1097 	u_char *ch3 = dmap[3];
   1098 
   1099 	while (i--) {
   1100 		*ch0++ = *p++ - 128;
   1101 		*ch1++ = *p++ - 128;
   1102 		*ch2++ = *p++ - 128;
   1103 		*ch3++ = *p++ - 128;
   1104 	}
   1105 }
   1106 
   1107 
   1108 static void
   1109 aucc_decode_mulaw_1ch(u_char **dmap, u_char *p, int i)
   1110 {
   1111 	u_char *ch0 = dmap[0];
   1112 
   1113 	while (i--)
   1114 		*ch0++ = mulaw_to_lin[*p++];
   1115 }
   1116 
   1117 static void
   1118 aucc_decode_mulaw_2ch(u_char **dmap, u_char *p, int i)
   1119 {
   1120 	u_char *ch0 = dmap[0];
   1121 	u_char *ch1 = dmap[1];
   1122 
   1123 	while (i--) {
   1124 		*ch0++ = mulaw_to_lin[*p++];
   1125 		*ch1++ = mulaw_to_lin[*p++];
   1126 	}
   1127 }
   1128 
   1129 static void
   1130 aucc_decode_mulaw_3ch(u_char **dmap, u_char *p, int i)
   1131 {
   1132 	u_char *ch0 = dmap[0];
   1133 	u_char *ch1 = dmap[1];
   1134 	u_char *ch2 = dmap[2];
   1135 
   1136 	while (i--) {
   1137 		*ch0++ = mulaw_to_lin[*p++];
   1138 		*ch1++ = mulaw_to_lin[*p++];
   1139 		*ch2++ = mulaw_to_lin[*p++];
   1140 	}
   1141 }
   1142 
   1143 static void
   1144 aucc_decode_mulaw_4ch(u_char **dmap, u_char *p, int i)
   1145 {
   1146 	u_char *ch0 = dmap[0];
   1147 	u_char *ch1 = dmap[1];
   1148 	u_char *ch2 = dmap[2];
   1149 	u_char *ch3 = dmap[3];
   1150 
   1151 	while (i--) {
   1152 		*ch0++ = mulaw_to_lin[*p++];
   1153 		*ch1++ = mulaw_to_lin[*p++];
   1154 		*ch2++ = mulaw_to_lin[*p++];
   1155 		*ch3++ = mulaw_to_lin[*p++];
   1156 	}
   1157 }
   1158 
   1159 
   1160 /* 14bit output */
   1161 static void
   1162 aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
   1163 {
   1164 	u_char *ch0 = dmap[0];
   1165 	u_char *ch3 = dmap[1]; /* XXX should be 3 */
   1166 
   1167 	while (i--) {
   1168 		*ch0++ = *p++;
   1169 		*ch3++ = *p++ >> 2;
   1170 	}
   1171 }
   1172 
   1173 /* 14bit stereo output */
   1174 static void
   1175 aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
   1176 {
   1177 	u_char *ch0 = dmap[0];
   1178 	u_char *ch1 = dmap[1];
   1179 	u_char *ch2 = dmap[2];
   1180 	u_char *ch3 = dmap[3];
   1181 
   1182 	while (i--) {
   1183 		*ch0++ = *p++;
   1184 		*ch3++ = *p++ >> 2;
   1185 		*ch1++ = *p++;
   1186 		*ch2++ = *p++ >> 2;
   1187 	}
   1188 }
   1189 
   1190 static void
   1191 aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
   1192 {
   1193 	u_char *ch0 = dmap[0];
   1194 	u_char *ch1 = dmap[1];
   1195 	u_char *ch2 = dmap[2];
   1196 
   1197 	while (i--) {
   1198 		*ch0++ = *p++; p++;
   1199 		*ch1++ = *p++; p++;
   1200 		*ch2++ = *p++; p++;
   1201 	}
   1202 }
   1203 
   1204 static void
   1205 aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
   1206 {
   1207 	u_char *ch0 = dmap[0];
   1208 	u_char *ch1 = dmap[1];
   1209 	u_char *ch2 = dmap[2];
   1210 	u_char *ch3 = dmap[3];
   1211 
   1212 	while (i--) {
   1213 		*ch0++ = *p++; p++;
   1214 		*ch1++ = *p++; p++;
   1215 		*ch2++ = *p++; p++;
   1216 		*ch3++ = *p++; p++;
   1217 	}
   1218 }
   1219 
   1220 /* 14bit output, swap bytes */
   1221 static void
   1222 aucc_decode_slinear16sw_1ch(u_char **dmap, u_char *p, int i)
   1223 {
   1224 	u_char *ch0 = dmap[0];
   1225 	u_char *ch3 = dmap[1];	/* XXX should be 3 */
   1226 
   1227 	while (i--) {
   1228 		*ch3++ = *p++ >> 2;
   1229 		*ch0++ = *p++;
   1230 	}
   1231 }
   1232 
   1233 static void
   1234 aucc_decode_slinear16sw_2ch(u_char **dmap, u_char *p, int i)
   1235 {
   1236 	u_char *ch0 = dmap[0];
   1237 	u_char *ch1 = dmap[1];
   1238 	u_char *ch2 = dmap[2];
   1239 	u_char *ch3 = dmap[3];
   1240 
   1241 	while (i--) {
   1242 		*ch3++ = *p++ >> 2;
   1243 		*ch0++ = *p++;
   1244 		*ch2++ = *p++ >> 2;
   1245 		*ch1++ = *p++;
   1246 	}
   1247 }
   1248 
   1249 static void
   1250 aucc_decode_slinear16sw_3ch(u_char **dmap, u_char *p, int i)
   1251 {
   1252 	u_char *ch0 = dmap[0];
   1253 	u_char *ch1 = dmap[1];
   1254 	u_char *ch2 = dmap[2];
   1255 
   1256 	while (i--) {
   1257 		p++; *ch0++ = *p++;
   1258 		p++; *ch1++ = *p++;
   1259 		p++; *ch2++ = *p++;
   1260 	}
   1261 }
   1262 
   1263 static void
   1264 aucc_decode_slinear16sw_4ch(u_char **dmap, u_char *p, int i)
   1265 {
   1266 	u_char *ch0 = dmap[0];
   1267 	u_char *ch1 = dmap[1];
   1268 	u_char *ch2 = dmap[2];
   1269 	u_char *ch3 = dmap[3];
   1270 
   1271 	while (i--) {
   1272 		p++; *ch0++ = *p++;
   1273 		p++; *ch1++ = *p++;
   1274 		p++; *ch2++ = *p++;
   1275 		p++; *ch3++ = *p++;
   1276 	}
   1277 }
   1278 
   1279 
   1280 #endif /* NAUCC > 0 */
   1281