Subject: new au.c
To: None <port-mac68k@NetBSD.ORG>
From: SUNAGAWA Keiki <kei_sun@ba2.so-net.ne.jp>
List: port-mac68k
Date: 05/10/1998 01:54:16
Hi all,

I've got ASC working finally.  It plays sound files very
well without cough.  Many thanks to Colin Wood for his
helpful comments and suggestions.

How to play with it:

1. Cut the code and save it to au.c and compile it by typing
'cc -o au au.c'.

2. Get some sound file with raw format.

3. Type './au <file1> <file2> <mode>'.  '/dev/null' can be
used for file1 or file2 specifies no input. mode must be one
of 0 (monaural) or 2 (stereo).  Only left channel generates
sound in monaural mode.

Note that file1 is for left channel and file2 is for right
channel, so all machine except SE/30 needs the headphone
connected to audio jack.

Please let me know anything you notice.

Have fun!

--
SUNAGAWA Keiki <kei_sun@ba2.so-net.ne.jp>
Happy Hacking!

/* $Id: au.c,v 1.9 1998/05/09 16:50:40 kei Exp kei $ */

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
/* include <machine/obio/ascreg.h> */ /* not yet */

/* from ascreg.h */
#define ASC_ASC_BUF_LEN 370	/* buffer length */
#define ASC_BUF_LEFT 0x000	/* offset to left buffer */
#define ASC_BUF_RIGHT 0x400	/* offset to right buffer */

int
play(ad, fd1, fd2, mode)
	caddr_t ad;
	int fd1;
	int fd2;
	int mode;
{
	int volume = 3; /* 0 - 7 */
	int c1;
	int c2;
	int i;
	int q1;
	int q2;
	char *bp1;
	char *bp2;

	if ((bp1 = (char *)malloc(ASC_ASC_BUF_LEN)) == NULL) exit (1);
	if ((bp2 = (char *)malloc(ASC_ASC_BUF_LEN)) == NULL) exit (1);

	*(ad + 0x806) = volume << 5;
	*(ad + 0x807) = 0; /* unknown,  but needed */
	*(ad + 0x802) = mode; /* 0: monaural, 2: stereo */

	/* clear ASC buffer */
	for (i = 0; i < 0x800; i++) *(ad + i) = 0x80;

	q1 = q2 = 1;

	while (q1 || q2) {
		if (q1 && (c1 = read(fd1, bp1, ASC_ASC_BUF_LEN)) == 0)
			q1 = 0;
		if (q2 && (c2 = read(fd2, bp2, ASC_ASC_BUF_LEN)) == 0)
			q2 = 0;
		for (i = 0; i < ASC_ASC_BUF_LEN; i++) {
			*(ad + ASC_BUF_LEFT + i) =
				(c1 < ASC_ASC_BUF_LEN) ? 0x80 : *(bp1 + i);
			*(ad + ASC_BUF_RIGHT + i) =
				(c2 < ASC_ASC_BUF_LEN) ? 0x80 : *(bp2 + i);
		}
		*(ad + 0x801) = 1; /* 1: sampled mode, 2: wave-table mode */
		usleep(16666);
	}
	*(ad + 0x801) = 0; /* disable scanning buffer */
	return (0);
}

int
main(argc, argv)
	int argc;
	char *argv[];
{
	caddr_t ad;
	int afd;
	int fd1;
	int fd2;
	int mode;

	if (argc != 4) {
		fprintf(stderr, "usage: %s: <left> <right> <mode>\n");
		exit (1);
	}
	if ((fd1 = open(argv[1], O_RDONLY)) == (-1)) {
		fprintf(stderr, "can't open %s\n", argv[1]);
		exit (1);
	}
	if ((fd2 = open(argv[2], O_RDONLY)) == (-1)) {
		fprintf(stderr, "can't open %s\n", argv[2]);
		exit (1);
	}
	if (!isdigit(*argv[3]) || ((mode = atoi(argv[3])) != 2 && mode != 0)) {
		fprintf(stderr, "mode must be 0 (monaural) or 2 (stereo)\n");
		exit (1);
	}
	if ((afd = open("/dev/audio", O_RDWR)) == (-1)) {
		fprintf(stderr, "can't open /dev/audio\n");
		exit (1);
	}
	ad = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_FILE, afd, 0);
	if (ad == (caddr_t) (-1)) {
		printf("can't mmap fd %d\n", afd);
		exit (1);
	}
	close(afd);
	play(ad, fd1, fd2, mode);
	munmap(ad, 0x1000);
	exit (0);
}