diff --git a/sys/arch/amiga/dev/aucc.c b/sys/arch/amiga/dev/aucc.c index 17f5367e98d7..dfaea25cf9d3 100644 --- a/sys/arch/amiga/dev/aucc.c +++ b/sys/arch/amiga/dev/aucc.c @@ -1,6 +1,9 @@ -/* $NetBSD: aucc.c,v 1.23 1998/08/17 21:16:09 augustss Exp $ */ +/* $NetBSD: aucc.c,v 1.24 1999/03/04 20:45:01 is Exp $ */ /* + * Copyright (c) 1999 Bernardo Innocenti + * All rights reserved. + * * Copyright (c) 1997 Stephan Thesing * All rights reserved. * @@ -30,6 +33,22 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* TODO: + * + * - ulaw -> 14bit conversion + * - channel allocation is wrong for 14bit mono + * - convert the... err... conversion routines to 68k asm for best performance + * XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont + * want to make life difficult for amigappc work. + * -is + * + * - rely on auconv.c routines for ulaw/alaw conversions + * - perhaps use a calibration table for better 14bit output + * - set 31KHz AGA video mode to allow 44.1KHz even if grfcc is missing + * in the kernel + * - 14bit output requires maximum volume + */ + #include "aucc.h" #if NAUCC > 0 @@ -91,9 +110,13 @@ struct aucc_softc { aucc_data_t sc_channel[4]; /* per channel freq, ... */ u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/ int sc_channels; /* # of channels used */ + int sc_precision; /* 8 or 16 bits */ + int sc_14bit; /* 14bit output enabled */ int sc_intrcnt; /* interrupt count */ int sc_channelmask; /* which channels are used ? */ + void (*sc_decodefunc) __P((u_char **, u_char *, int)); + /* pointer to format conversion routine */ }; /* interrupt interfaces */ @@ -116,7 +139,7 @@ struct cfattach aucc_ca = { struct audio_device aucc_device = { "Amiga-audio", - "x", + "2.0", "aucc" }; @@ -178,11 +201,39 @@ int aucc_getdev __P((void *, struct audio_device *)); int aucc_set_port __P((void *, mixer_ctrl_t *)); int aucc_get_port __P((void *, mixer_ctrl_t *)); int aucc_query_devinfo __P((void *, mixer_devinfo_t *)); -void aucc_encode __P((int, int, int, u_char *, u_short **)); +void aucc_encode __P((int, int, int, int, u_char *, u_short **)); int aucc_set_params __P((void *, int, int, struct audio_params *, struct audio_params *)); int aucc_get_props __P((void *)); + +static void aucc_decode_slinear8_1ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear8_2ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear8_3ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear8_4ch __P((u_char **, u_char *, int)); + +static void aucc_decode_ulinear8_1ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulinear8_2ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulinear8_3ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulinear8_4ch __P((u_char **, u_char *, int)); + +static void aucc_decode_ulaw_1ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulaw_2ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulaw_3ch __P((u_char **, u_char *, int)); +static void aucc_decode_ulaw_4ch __P((u_char **, u_char *, int)); + +static void aucc_decode_slinear16_1ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16_2ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16_3ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16_4ch __P((u_char **, u_char *, int)); + +static void aucc_decode_slinear16sw_1ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16sw_2ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16sw_3ch __P((u_char **, u_char *, int)); +static void aucc_decode_slinear16sw_4ch __P((u_char **, u_char *, int)); + + + struct audio_hw_if sa_hw_if = { aucc_open, aucc_close, @@ -271,7 +322,6 @@ init_aucc(sc) sc->sc_channel[i].nd_doublebuf=0; DPRINTF(("dma buffer for channel %d is %p\n", i, sc->sc_channel[i].nd_dma)); - } if (err) { @@ -282,15 +332,16 @@ init_aucc(sc) sc->sc_channels=1; sc->sc_channelmask=0xf; + sc->sc_precision=8; + sc->sc_14bit = 0; + sc->sc_encoding=AUDIO_ENCODING_ULAW; + sc->sc_decodefunc = aucc_decode_ulaw_1ch; /* clear interrupts and dma: */ custom.intena = AUCC_ALLINTF; - custom.dmacon = AUCC_ALLDMAF;; - - sc->sc_encoding=AUDIO_ENCODING_ULAW; + custom.dmacon = AUCC_ALLDMAF; return err; - } int @@ -361,30 +412,51 @@ aucc_query_encoding(addr, fp) void *addr; struct audio_encoding *fp; { - switch (fp->index) { - case 0: - strcpy(fp->name, AudioEslinear); - fp->encoding = AUDIO_ENCODING_SLINEAR; - fp->precision = 8; - fp->flags = 0; - break; - case 1: - strcpy(fp->name, AudioEmulaw); - fp->encoding = AUDIO_ENCODING_ULAW; - fp->precision = 8; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - break; + switch (fp->index) { + case 0: + strcpy(fp->name, AudioEslinear); + fp->encoding = AUDIO_ENCODING_SLINEAR; + fp->precision = 8; + fp->flags = 0; + break; + case 1: + strcpy(fp->name, AudioEmulaw); + fp->encoding = AUDIO_ENCODING_ULAW; + fp->precision = 8; + fp->flags = AUDIO_ENCODINGFLAG_EMULATED; + break; - case 2: - strcpy(fp->name, AudioEulinear); - fp->encoding = AUDIO_ENCODING_ULINEAR; - fp->precision = 8; - fp->flags = AUDIO_ENCODINGFLAG_EMULATED; - break; + case 2: + strcpy(fp->name, AudioEulinear); + fp->encoding = AUDIO_ENCODING_ULINEAR; + fp->precision = 8; + fp->flags = AUDIO_ENCODINGFLAG_EMULATED; + break; - default: - return(EINVAL); - /*NOTREACHED*/ + case 3: + strcpy(fp->name, AudioEslinear); + fp->encoding = AUDIO_ENCODING_SLINEAR; + fp->precision = 16; + fp->flags = AUDIO_ENCODINGFLAG_EMULATED; + break; + + case 4: + strcpy(fp->name, AudioEslinear_be); + fp->encoding = AUDIO_ENCODING_SLINEAR_BE; + fp->precision = 16; + fp->flags = AUDIO_ENCODINGFLAG_EMULATED; + break; + + case 5: + strcpy(fp->name, AudioEslinear_le); + fp->encoding = AUDIO_ENCODING_SLINEAR_LE; + fp->precision = 16; + fp->flags = AUDIO_ENCODINGFLAG_EMULATED; + break; + + default: + return(EINVAL); + /*NOTREACHED*/ } return(0); } @@ -401,32 +473,140 @@ aucc_set_params(addr, setmode, usemode, p, r) return 0 ENXIO*/; #ifdef AUCCDEBUG - printf("aucc_set_params(setmode 0x%x, usemode 0x%x, enc %d, bits %d, chn %d, sr %ld)\n", - setmode, usemode, p->encoding, p->precision, p->channels, p->sample_rate); + printf("aucc_set_params(setmode 0x%x, usemode 0x%x, " + "enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode, + p->encoding, p->precision, p->channels, p->sample_rate); #endif - switch (p->encoding) { - case AUDIO_ENCODING_ULAW: - case AUDIO_ENCODING_SLINEAR: - case AUDIO_ENCODING_SLINEAR_BE: - case AUDIO_ENCODING_SLINEAR_LE: - case AUDIO_ENCODING_ULINEAR_BE: - case AUDIO_ENCODING_ULINEAR_LE: - break; + switch (p->precision) { + case 8: + switch (p->encoding) { + case AUDIO_ENCODING_ULAW: + switch (p->channels) { + case 1: + sc->sc_decodefunc = aucc_decode_ulaw_1ch; + break; + case 2: + sc->sc_decodefunc = aucc_decode_ulaw_2ch; + break; + case 3: + sc->sc_decodefunc = aucc_decode_ulaw_3ch; + break; + case 4: + sc->sc_decodefunc = aucc_decode_ulaw_4ch; + break; + default: + return EINVAL; + } + break; + + case AUDIO_ENCODING_SLINEAR: + case AUDIO_ENCODING_SLINEAR_BE: + case AUDIO_ENCODING_SLINEAR_LE: + switch (p->channels) { + case 1: + sc->sc_decodefunc = aucc_decode_slinear8_1ch; + break; + case 2: + sc->sc_decodefunc = aucc_decode_slinear8_2ch; + break; + case 3: + sc->sc_decodefunc = aucc_decode_slinear8_3ch; + break; + case 4: + sc->sc_decodefunc = aucc_decode_slinear8_4ch; + break; + default: + return EINVAL; + } + break; + + case AUDIO_ENCODING_ULINEAR: + case AUDIO_ENCODING_ULINEAR_BE: + case AUDIO_ENCODING_ULINEAR_LE: + switch (p->channels) { + case 1: + sc->sc_decodefunc = aucc_decode_ulinear8_1ch; + break; + case 2: + sc->sc_decodefunc = aucc_decode_ulinear8_2ch; + break; + case 3: + sc->sc_decodefunc = aucc_decode_ulinear8_3ch; + break; + case 4: + sc->sc_decodefunc = aucc_decode_ulinear8_4ch; + break; + default: + return EINVAL; + } + break; + + default: + return EINVAL; + } + break; + + case 16: + switch (p->encoding) { +#if BYTE_ORDER == BIG_ENDIAN + case AUDIO_ENCODING_SLINEAR: +#endif + case AUDIO_ENCODING_SLINEAR_BE: + switch (p->channels) { + case 1: + sc->sc_decodefunc = aucc_decode_slinear16_1ch; + break; + + case 2: + sc->sc_decodefunc = aucc_decode_slinear16_2ch; + break; + case 3: + sc->sc_decodefunc = aucc_decode_slinear16_3ch; + break; + case 4: + sc->sc_decodefunc = aucc_decode_slinear16_4ch; + break; + default: + return EINVAL; + } + break; + +#if BYTE_ORDER == LITTLE_ENDIAN + case AUDIO_ENCODING_SLINEAR: +#endif + case AUDIO_ENCODING_SLINEAR_LE: + switch (p->channels) { + case 1: + sc->sc_decodefunc = aucc_decode_slinear16sw_1ch; + break; + case 2: + sc->sc_decodefunc = aucc_decode_slinear16sw_2ch; + break; + case 3: + sc->sc_decodefunc = aucc_decode_slinear16sw_3ch; + break; + case 4: + sc->sc_decodefunc = aucc_decode_slinear16sw_4ch; + break; + default: + return EINVAL; + } + break; + + default: + return EINVAL; + } + break; default: return EINVAL; - /* NOTREADCHED */ } - if (p->precision != 8) - return EINVAL; - - if ((p->channels<1) || (p->channels>4)) - return(EINVAL); - - sc->sc_channels = p->channels; sc->sc_encoding = p->encoding; + sc->sc_precision = p->precision; + sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2)); + sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels; return aucc_set_out_sr(addr, p->sample_rate); } @@ -436,9 +616,8 @@ aucc_round_blocksize(addr, blk) void *addr; int blk; { - - - return blk>AUDIO_BUF_SIZE?AUDIO_BUF_SIZE:blk; /* round up to even size */ + /* round up to even size */ + return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk; } int @@ -473,9 +652,8 @@ aucc_start_output(addr, p, cc, intr, arg) { struct aucc_softc *sc; int mask; - int i,j,k; - u_short *dmap[4]; - u_char *pp; + int i, j, k, len; + u_char *dmap[4]; sc = addr; @@ -486,21 +664,22 @@ aucc_start_output(addr, p, cc, intr, arg) DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg)); if (sc->sc_channels > 1) - mask &=masks[sc->sc_channels-1]; + mask &= masks[sc->sc_channels - 1]; /* we use first sc_channels channels */ - if (mask==0) /* active and used channels are disjoint */ + if (mask == 0) /* active and used channels are disjoint */ return EINVAL; - for (i=0;i<4;i++) { /* channels available ? */ - if ((masks2[i]&mask)&&(sc->sc_channel[i].nd_busy)) + for (i=0;i<4;i++) { + /* channels available ? */ + if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy)) return EBUSY; /* channel is busy */ - if (channel[i].isaudio==-1) + if (channel[i].isaudio == -1) return EBUSY; /* system uses them */ } /* enable interrupt on 1st channel */ - for (i=j=0;isc_channel[i].nd_intr=intr; @@ -514,66 +693,75 @@ aucc_start_output(addr, p, cc, intr, arg) /* disable ints, dma for channels, until all parameters set */ /* XXX dont disable DMA! custom.dmacon=mask;*/ - custom.intreq=mask<sc_channels == 1) { dmap[0] = dmap[1] = dmap[2] = - dmap[3] = sc->sc_channel[j].nd_dma; - } else { + dmap[3] = (u_char *)sc->sc_channel[j].nd_dma; + } + else { for (k=0; k<4; k++) { - if (masks2[k+j]&mask) - dmap[k]=sc->sc_channel[k+j].nd_dma; + if (masks2[k+j] & mask) + dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma; } } sc->sc_channel[j].nd_doublebuf ^= 1; if (sc->sc_channel[j].nd_doublebuf) { - dmap[0] += AUDIO_BUF_SIZE/sizeof(u_short); - dmap[1] += AUDIO_BUF_SIZE/sizeof(u_short); - dmap[2] += AUDIO_BUF_SIZE/sizeof(u_short); - dmap[3] += AUDIO_BUF_SIZE/sizeof(u_short); + dmap[0] += AUDIO_BUF_SIZE; + dmap[1] += AUDIO_BUF_SIZE; + dmap[2] += AUDIO_BUF_SIZE; + dmap[3] += AUDIO_BUF_SIZE; } - aucc_encode(sc->sc_encoding, sc->sc_channels, cc, pp, dmap); + /* compute output length in bytes per channel. + * divide by two only for 16bit->8bit conversion. + */ + len = cc / sc->sc_channels; + if (!sc->sc_14bit && (sc->sc_precision == 16)) + len /= 2; - /* dma buffers: we use same buffer 4 all channels */ - /* write dma location and length */ - for (i=k=0; i<4; i++) { + /* call audio decoding routine */ + sc->sc_decodefunc (dmap, (u_char *)p, len); + + /* dma buffers: we use same buffer 4 all channels + * write dma location and length + */ + for (i = k = 0; i < 4; i++) { if (masks2[i] & mask) { DPRINTF(("turning channel %d on\n",i)); - /* sc->sc_channel[i].nd_busy=1;*/ - channel[i].isaudio=1; - channel[i].play_count=1; - channel[i].handler=NULL; - custom.aud[i].per=sc->sc_channel[i].nd_per; - custom.aud[i].vol=sc->sc_channel[i].nd_volume; + /* sc->sc_channel[i].nd_busy=1; */ + channel[i].isaudio = 1; + channel[i].play_count = 1; + channel[i].handler = NULL; + custom.aud[i].per = sc->sc_channel[i].nd_per; + if (sc->sc_14bit && (i > 1)) + custom.aud[i].vol = 1; + else + custom.aud[i].vol = sc->sc_channel[i].nd_volume; custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]); - custom.aud[i].len=cc/(sc->sc_channels*2); - sc->sc_channel[i].nd_mask=mask; + custom.aud[i].len = len / 2; + sc->sc_channel[i].nd_mask = mask; DPRINTF(("per is %d, vol is %d, len is %d\n",\ sc->sc_channel[i].nd_per, - sc->sc_channel[i].nd_volume, cc>>1)); - + sc->sc_channel[i].nd_volume, len)); } } channel[j].handler=aucc_inthdl; /* enable ints */ - custom.intena=INTF_SETCLR|INTF_INTEN| (masks2[j]<dev!=AUCC_CHANNELS) return EINVAL; i=cp->un.mask; - if ((i<1)||(i>15)) + if ((i<1) || (i>15)) return EINVAL; + sc->sc_channelmask=i; break; case AUDIO_MIXER_VALUE: i=cp->un.value.num_channels; - if ((i<1)||(i>4)) + if ((i<1) || (i>4)) return EINVAL; #ifdef __XXXwhatsthat @@ -796,12 +985,15 @@ aucc_inthdl(int ch) DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask)); custom.intreq=mask<sc_channel[i].nd_busy=0; @@ -813,9 +1005,11 @@ aucc_inthdl(int ch) /* call handler */ if (aucc->sc_channel[ch].nd_intr) { DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr)); - (*(aucc->sc_channel[ch].nd_intr))(aucc->sc_channel[ch].nd_intrdata); + (*(aucc->sc_channel[ch].nd_intr)) + (aucc->sc_channel[ch].nd_intrdata); } - else DPRINTF(("zero int handler\n")); + else + DPRINTF(("zero int handler\n")); DPRINTF(("ints done\n")); } @@ -824,8 +1018,7 @@ aucc_inthdl(int ch) /* transform frequency to period, adjust bounds */ static u_int -freqtoper(u_int freq) -{ +freqtoper(u_int freq) { u_int per=eclockfreq*5/freq; if (per<124) @@ -836,80 +1029,322 @@ freqtoper(u_int freq) /* transform period to frequency */ static u_int -pertofreq(u_int per) -{ +pertofreq(u_int per) { u_int freq=eclockfreq*5/per; - return freq; } - - -void -aucc_encode(enc, channels, i, p, dmap) - int enc, channels, i; - u_char *p; - u_short **dmap; -{ - char *q, *r, *s, *t; - int off; - u_char *tab; - -#ifdef AUCCDEBUG - static int debctl = 6; -#endif - - off = 0; - tab = NULL; - -#ifdef AUCCDEBUG - if (--debctl >= 0) - printf("Enc: enc %d, chan %d, dmap %p %p %p %p\n", - enc, channels, dmap[0], dmap[1], dmap[2], dmap[3]); -#endif - - switch (enc) { - case AUDIO_ENCODING_ULAW: - tab=ulaw_to_lin; - break; - case AUDIO_ENCODING_ULINEAR_BE: - case AUDIO_ENCODING_ULINEAR_LE: - off=-128; - break; - case AUDIO_ENCODING_SLINEAR_BE: - case AUDIO_ENCODING_SLINEAR_LE: - break; - default: - return; - } - - q = (char *)dmap[0]; - r = (char *)dmap[1]; - s = (char *)dmap[2]; - t = (char *)dmap[3]; - - if (tab) - while (i) { - switch (channels) { - case 4: *t++ = tab[*p++]; - case 3: *s++ = tab[*p++]; - case 2: *r++ = tab[*p++]; - case 1: *q++ = tab[*p++]; - } - i -= channels; - } - else - while (i) { - switch (channels) { - case 4: *t++ = *p++ + off; - case 3: *s++ = *p++ + off; - case 2: *r++ = *p++ + off; - case 1: *q++ = *p++ + off; - } - i -= channels; - } - +static void aucc_decode_slinear8_1ch (u_char **dmap, u_char *p, int i) { + memcpy (dmap[0], p, i); } +static void aucc_decode_slinear8_2ch (u_char **dmap, u_char *p, int i) { + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + + while (i--) { + *ch0++ = *p++; + *ch1++ = *p++; + } +} + +static void aucc_decode_slinear8_3ch (u_char **dmap, u_char *p, int i) { + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + + while (i--) { + *ch0++ = *p++; + *ch1++ = *p++; + *ch2++ = *p++; + } +} + +static void aucc_decode_slinear8_4ch (u_char **dmap, u_char *p, int i) { + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch0++ = *p++; + *ch1++ = *p++; + *ch2++ = *p++; + *ch3++ = *p++; + } +} + +static void +aucc_decode_ulinear8_1ch (dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + + while (i--) + *ch0++ = *p++ - 128; +} + +static void +aucc_decode_ulinear8_2ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + + while (i--) { + *ch0++ = *p++ - 128; + *ch1++ = *p++ - 128; + } +} + +static void +aucc_decode_ulinear8_3ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + + while (i--) { + *ch0++ = *p++ - 128; + *ch1++ = *p++ - 128; + *ch2++ = *p++ - 128; + } +} + +static void +aucc_decode_ulinear8_4ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch0++ = *p++ - 128; + *ch1++ = *p++ - 128; + *ch2++ = *p++ - 128; + *ch3++ = *p++ - 128; + } +} + + +static void +aucc_decode_ulaw_1ch (dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + + while (i--) + *ch0++ = ulaw_to_lin[*p++]; +} + +static void +aucc_decode_ulaw_2ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + + while (i--) { + *ch0++ = ulaw_to_lin[*p++]; + *ch1++ = ulaw_to_lin[*p++]; + } +} + +static void +aucc_decode_ulaw_3ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + + while (i--) { + *ch0++ = ulaw_to_lin[*p++]; + *ch1++ = ulaw_to_lin[*p++]; + *ch2++ = ulaw_to_lin[*p++]; + } +} + +static void +aucc_decode_ulaw_4ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch0++ = ulaw_to_lin[*p++]; + *ch1++ = ulaw_to_lin[*p++]; + *ch2++ = ulaw_to_lin[*p++]; + *ch3++ = ulaw_to_lin[*p++]; + } +} + + +/* 14bit output */ +static void +aucc_decode_slinear16_1ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch3 = dmap[1]; /* XXX should be 3 */ + + while (i--) { + *ch0++ = *p++; + *ch3++ = *p++ >> 2; + } +} + +/* 14bit stereo output */ +static void +aucc_decode_slinear16_2ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch0++ = *p++; + *ch3++ = *p++ >> 2; + *ch1++ = *p++; + *ch2++ = *p++ >> 2; + } +} + +static void +aucc_decode_slinear16_3ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + + while (i--) { + *ch0++ = *p++; p++; + *ch1++ = *p++; p++; + *ch2++ = *p++; p++; + } +} + +static void +aucc_decode_slinear16_4ch (dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch0++ = *p++; p++; + *ch1++ = *p++; p++; + *ch2++ = *p++; p++; + *ch3++ = *p++; p++; + } +} + +/* 14bit output, swap bytes */ +static void +aucc_decode_slinear16sw_1ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch3++ = *p++ >> 2; + *ch0++ = *p++; + } +} + +static void +aucc_decode_slinear16sw_2ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + *ch3++ = *p++ >> 2; + *ch0++ = *p++; + *ch2++ = *p++ >> 2; + *ch1++ = *p++; + } +} + +static void +aucc_decode_slinear16sw_3ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + + while (i--) { + p++; *ch0++ = *p++; + p++; *ch1++ = *p++; + p++; *ch2++ = *p++; + } +} + +static void +aucc_decode_slinear16sw_4ch(dmap, p, i) + u_char **dmap; + u_char *p; + int i; +{ + u_char *ch0 = dmap[0]; + u_char *ch1 = dmap[1]; + u_char *ch2 = dmap[2]; + u_char *ch3 = dmap[3]; + + while (i--) { + p++; *ch0++ = *p++; + p++; *ch1++ = *p++; + p++; *ch2++ = *p++; + p++; *ch3++ = *p++; + } +} + + #endif /* NAUCC > 0 */