NetBSD Problem Report #6787

Received: (qmail 28674 invoked from network); 11 Jan 1999 10:47:26 -0000
Message-Id: <199901111041.LAA12494@cyberlap.informatik.uni-karlsruhe.de>
Date: Mon, 11 Jan 1999 11:41:19 +0100 (MET)
From: frueauf@ira.uka.de
Reply-To: frueauf@ira.uka.de, bernardo.innocenti@usa.net
To: gnats-bugs@gnats.netbsd.org
Subject: Modifications to aucc.c for more input formats and 14bit stereo output
X-Send-Pr-Version: 3.95

>Number:         6787
>Category:       port-amiga
>Synopsis:       Modifications to aucc.c for more input formats and 14bit stereo output
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-amiga-maintainer
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 11 02:50:01 +0000 1999
>Closed-Date:    Thu Mar 04 20:59:51 +0000 1999
>Last-Modified:  Thu Mar 04 21:02:41 +0000 1999
>Originator:     Thorsten Frueauf
>Release:        <NetBSD-current source date> NetBSD current 10.01.1999
>Organization:
private

>Environment:

Any amiga with "Paula" :-)

>Description:

I send this pr for Bernardo Innocenti <bernardo.innocenti@usa.net>
because he can't send the pr himself. So for further feedback/information
I suggest getting in touch with him. I had no chance to actually test
his modifications, as I am out of reach of my amiga for several weeks.

To cite Bernardos mail to port-amiga@netbsd.org:

"I finally managed to improve Paula's /dev/audio driver to handle
some more input formats (supports 8/16bit, signed/unsigned,
big/little endian, linear/alaw). The device can also do 14bit
stereo output.

 Perhaps the driver needs some more testing with all possible
input combination and it's still not possible to replay at
more than 28KHz if the AGA video mode is not set at 31KHz.
This is a problem for people like me who own a gfx board and
do not want to compile the Amiga custom chips support into
the kernel."

>How-To-Repeat:

Use the current amiga audio driver and come to the conclusion one can
improve it :)

>Fix:

Here is the diff of Bernardos aucc.c against the current in tree aucc.c. If
its more convineint to get his whole aucc.c, then get either in touch
with him or me.

--- /src/sys/arch/amiga/dev/aucc.c	Wed Aug 19 10:28:29 1998
+++ aucc.c-new	Mon Jan 11 11:02:34 1999
@@ -1,6 +1,9 @@
 /*	$NetBSD: aucc.c,v 1.23 1998/08/17 21:16:09 augustss Exp $	*/

 /*
+ * Copyright (c) 1999 Bernardo Innocenti
+ * All rights reserved.
+ *
  * Copyright (c) 1997 Stephan Thesing
  * All rights reserved.
  *
@@ -30,6 +33,17 @@
  * 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
+ * - 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 +105,13 @@
 	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)		/* pointer to format conversion routine */
+		(u_char **, u_char *, int);
 };

 /* interrupt interfaces */
@@ -116,7 +134,7 @@

 struct audio_device aucc_device = {
 	"Amiga-audio",
-	"x",
+	"2.0",
 	"aucc"
 };

@@ -178,11 +196,39 @@
 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,
@@ -257,7 +303,8 @@
 	register int i, err=0;

 	/* init values per channel */
- 	for (i=0;i<4;i++) {
+ 	for (i=0;i<4;i++)
+	{
 		sc->sc_channel[i].nd_freq=8000;
 		sc->sc_channel[i].nd_per=freqtoper(8000);
 		sc->sc_channel[i].nd_busy=0;
@@ -271,10 +318,10 @@
 		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) {
+	if (err)
+	{
 		for(i=0;i<4;i++)
 			if (sc->sc_channel[i].nd_dma)
 				free_chipmem(sc->sc_channel[i].nd_dma);
@@ -282,15 +329,16 @@

 	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 +409,52 @@
 	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);
 }
@@ -405,28 +475,108 @@
 	    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;
-		/* NOTREADCHED */
-	}
+				default:
+					return EINVAL;
+			}
+			break;

-	if (p->precision != 8)
-		return EINVAL;
+		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;

-	if ((p->channels<1) || (p->channels>4))
-		return(EINVAL);
+		default:
+			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 +586,8 @@
 	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 +622,8 @@
 {
 	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 +634,25 @@
 	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;i<AUCC_MAXINT;i++) {
-		if (masks2[i]&mask) {
+	for (i = j = 0; i < AUCC_MAXINT; i++)
+	{
+		if (masks2[i] & mask)
+		{
 			DPRINTF(("first channel is %d\n",i));
 			j=i;
 			sc->sc_channel[i].nd_intr=intr;
@@ -514,66 +666,80 @@

 	/* disable ints, dma for channels, until all parameters set */
 	/* XXX dont disable DMA! custom.dmacon=mask;*/
-	custom.intreq=mask<<INTB_AUD0;
-	custom.intena=mask<<INTB_AUD0;
+	custom.intreq = mask << INTB_AUD0;
+	custom.intena = mask << INTB_AUD0;

 	/* copy data to dma buffer */

- 
-	pp=(u_char *)p;
-
-	if (sc->sc_channels == 1) {
+	if (sc->sc_channels == 1)
+	{
 		dmap[0] =
 		dmap[1] =
 		dmap[2] =
-		dmap[3] = 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;
+		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
+	}
+	else
+	{
+		for (k=0; k<4; k++)
+		{
+			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);
-
-	/* 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) {
+	/* 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;
+
+	/* 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]<<INTB_AUD0);
+	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);

-	DPRINTF(("enabled ints: 0x%x\n",(masks2[j]<<INTB_AUD0)));
+	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));

 	/* enable dma */
-	custom.dmacon=DMAF_SETCLR|DMAF_MASTER|mask;
+	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;

 	DPRINTF(("enabled dma, mask=0x%x\n",mask));

@@ -844,72 +1010,325 @@
 	return freq;
 }

+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];

-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;
+	while (i--)
+	{
+		*ch0++ = *p++;
+		*ch1++ = *p++;
+	}
+}

-#ifdef AUCCDEBUG
-	static int debctl = 6;
-#endif
+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++;
+	}
+}

-	off = 0;
-	tab = NULL;
+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++;
+	}
+}

-#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;
+
+static void aucc_decode_ulinear8_1ch (u_char **dmap, u_char *p, int i)
+{
+	u_char *ch0 = dmap[0];
+
+	while (i--)
+		*ch0++ = *p++ - 128;
+}
+
+static void aucc_decode_ulinear8_2ch (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;
 	}
+}

-	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;
+static void aucc_decode_ulinear8_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++ - 128;
+		*ch1++ = *p++ - 128;
+		*ch2++ = *p++ - 128;
+	}
+}
+
+static void aucc_decode_ulinear8_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++ - 128;
+		*ch1++ = *p++ - 128;
+		*ch2++ = *p++ - 128;
+		*ch3++ = *p++ - 128;
+	}
+}
+
+
+static void aucc_decode_ulaw_1ch (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 (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 (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 (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 (u_char **dmap, u_char *p, int i)
+{
+	u_char *ch0 = dmap[0];
+	u_char *ch3 = dmap[1]; /* XXX should be 3 */
+
+	while (i--)
+	{
+		if (*p & 0x80) /* negative ? */
+		{
+			*ch0++ = *p++;
+			*ch3++ = -(((u_char)(-(*p++))) >> 2);
 		}
-	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;
+		else
+		{
+			*ch0++ = *p++;
+			*ch3++ = *p++ >> 2;
 		}
-	
+	}
+}
+
+/* 14bit stereo output */
+static void aucc_decode_slinear16_2ch (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--)
+	{
+		if (*p & 0x80) /* negative ? */
+		{
+			*ch0++ = *p++;
+			*ch3++ = -(((u_char)(-(*p++))) >> 2);
+		}
+		else
+		{
+			*ch0++ = *p++;
+			*ch3++ = *p++ >> 2;
+		}
+
+		if (*p & 0x80) /* negative ? */
+		{
+			*ch1++ = *p++;
+			*ch2++ = -(((u_char)(-(*p++))) >> 2);
+		}
+		else
+		{
+			*ch1++ = *p++;
+			*ch2++ = *p++ >> 2;
+		}
+	}
+}
+
+static void aucc_decode_slinear16_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++; p++;
+		*ch1++ = *p++; p++;
+		*ch2++ = *p++; p++;
+	}
+}
+
+static void aucc_decode_slinear16_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++; p++;
+		*ch1++ = *p++; p++;
+		*ch2++ = *p++; p++;
+		*ch3++ = *p++; p++;
+	}
+}
+
+/* 14bit output, swap bytes */
+static void aucc_decode_slinear16sw_1ch (u_char **dmap, u_char *p, int i)
+{
+	u_char *ch0 = dmap[0];
+	u_char *ch3 = dmap[3];
+
+	while (i--)
+	{	
+		if (*(p+1) & 0x80) /* negative ? */
+		{
+			*ch3++ = -(((u_char)(-(*p++))) >> 2);
+			*ch0++ = *p++;
+		}
+		else
+		{
+			*ch3++ = *p++ >> 2;
+			*ch0++ = *p++;
+		}
+	}
 }
+
+static void aucc_decode_slinear16sw_2ch (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--)
+	{
+		if (*(p+1) & 0x80) /* negative ? */
+		{
+			*ch3++ = -(((u_char)(-(*p++))) >> 2);
+			*ch0++ = *p++;
+		}
+		else
+		{
+			*ch3++ = *p++ >> 2;
+			*ch0++ = *p++;
+		}
+
+		if (*(p+1) & 0x80) /* negative ? */
+		{
+			*ch2++ = -(((u_char)(-(*p++))) >> 2);
+			*ch1++ = *p++;
+		}
+		else
+		{
+			*ch2++ = *p++ >> 2;
+			*ch1++ = *p++;
+		}
+	}
+}
+
+static void aucc_decode_slinear16sw_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--)
+	{
+		p++; *ch0++ = *p++;
+		p++; *ch1++ = *p++;
+		p++; *ch2++ = *p++;
+	}
+}
+
+static void aucc_decode_slinear16sw_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--)
+	{
+		p++; *ch0++ = *p++;
+		p++; *ch1++ = *p++;
+		p++; *ch2++ = *p++;
+		p++; *ch3++ = *p++;
+	}
+}
+

 #endif /* NAUCC > 0 */
>Release-Note:
>Audit-Trail:

From: christos@zoulas.com (Christos Zoulas)
To: frueauf@ira.uka.de, bernardo.innocenti@usa.net,
        gnats-bugs@gnats.netbsd.org
Cc:  Subject: Re: port-amiga/6787: Modifications to aucc.c for more input formats and 14bit stereo output
Date: Mon, 11 Jan 1999 06:40:27 -0500

 On Jan 11, 11:41am, frueauf@ira.uka.de (frueauf@ira.uka.de) wrote:
 -- Subject: port-amiga/6787: Modifications to aucc.c for more input formats a

 | 
 |  /*
 | + * Copyright (c) 1999 Bernardo Innocenti
 | + * All rights reserved.
 | + *

 Please get him to assign copyright to TNF if possible.

 christos

From: Thorsten Frueauf <frueauf@ira.uka.de>
To: christos@zoulas.com (Christos Zoulas)
Cc: frueauf@ira.uka.de, bernardo.innocenti@usa.net, gnats-bugs@gnats.netbsd.org
Subject: Re: port-amiga/6787: Modifications to aucc.c for more input formats
Date: Mon, 11 Jan 1999 15:04:09 +0100 (MET)

 Hello!

 > |  /*
 > | + * Copyright (c) 1999 Bernardo Innocenti
 > | + * All rights reserved.
 > | + *
 > 
 > Please get him to assign copyright to TNF if possible.

 Ok, he is on the cc: anyway, so what would be the appropriate change?
 Any template that he can use? I am sure he can speak up himself whether
 assigning the code to TNF is a problem or not :)

 Greets
       Thorsten

From: christos@zoulas.com (Christos Zoulas)
To: Thorsten Frueauf <frueauf@ira.uka.de>
Cc: bernardo.innocenti@usa.net, gnats-bugs@gnats.netbsd.org
Subject: Re: port-amiga/6787: Modifications to aucc.c for more input formats
Date: Mon, 11 Jan 1999 09:30:40 -0500

 On Jan 11,  3:04pm, frueauf@ira.uka.de (Thorsten Frueauf) wrote:
 -- Subject: Re: port-amiga/6787: Modifications to aucc.c for more input forma

 | Hello!
 | 
 | > |  /*
 | > | + * Copyright (c) 1999 Bernardo Innocenti
 | > | + * All rights reserved.
 | > | + *
 | > 
 | > Please get him to assign copyright to TNF if possible.
 | 
 | Ok, he is on the cc: anyway, so what would be the appropriate change?
 | Any template that he can use? I am sure he can speak up himself whether
 | assigning the code to TNF is a problem or not :)

 I'll send him a copyright form agreement if he decides to do it.

 christos

 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Billy Bob.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *        This product includes software developed by the NetBSD
  *        Foundation, Inc. and its contributors.
  * 4. Neither the name of The NetBSD Foundation nor the names of its
  *    contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
State-Changed-From-To: open->closed 
State-Changed-By: is 
State-Changed-When: Thu Mar 4 12:59:51 PST 1999 
State-Changed-Why:  
Added code, after reformatting it to fit our coding standard. 
-is 
>Unformatted:
 Modifications to aucc.c for more input formats and 14bit stereo output

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.49 2026/05/14 01:52:41 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.