pkgsrc/audio/nspmod/patches/patch-bb
1998-08-07 10:35:47 +00:00

285 lines
5.8 KiB
Text

$NetBSD: patch-bb,v 1.2 1998/08/07 10:36:06 agc Exp $
*** /dev/null Fri Mar 6 05:54:22 1998
--- dacio-netbsd.c Fri Mar 6 06:51:04 1998
***************
*** 0 ****
--- 1,278 ----
+ #include <stdio.h> /*(perror)*/
+ #include <fcntl.h> /*O_WRONLY*/
+ #include <sys/ioctl.h> /*(ioctl)*/
+ #include <string.h> /*(memset)*/
+ #include <unistd.h> /*(write)*/
+ #include <sys/audioio.h> /*SNDCTL_XXX*/
+ #include <errno.h> /*EINTR*/
+ #include "defs.h" /*u8,u16*/
+ #include "dacio.h" /*(dacioXXX)*/
+ #include "mem.h" /*(memPerm)*/
+
+ #if 0
+ #define LIM_SIZE (32 * 256) /* 32ch * 8bit */
+
+ static u8 *lim;
+
+ static void
+ makeLim(void)
+ {
+ u8 *p;
+ i15x i;
+
+ lim = (u8 *)memPerm(LIM_SIZE) + LIM_SIZE/2;
+ p = lim-128;
+ for (i = 0; i < 256; i++, p++) *p = i;
+ for (; p < lim + LIM_SIZE/2; p++) *p = 255;
+ }
+ #endif
+
+ static int fd;
+
+ #ifndef DAC_DEV
+ #define DAC_DEV "/dev/audio"
+ #endif
+
+ void
+ dacioInit(void)
+ {
+ fd = open(DAC_DEV, O_WRONLY);
+ if (fd < 0) {
+ perror("dacioInit");
+ exit(1);
+ }
+ /*makeLim();*/
+ }
+
+ static struct {
+ union {
+ u8 *p8;
+ i15 *p16;
+ } p;
+ u8 *top;
+ u8 *bot;
+ int size;
+ int shift;
+ } buf;
+
+ #define bufRest() ((buf.bot - buf.p.p8) >> buf.shift)
+
+ static DacioConfInfo dci;
+
+ void
+ dacioConf(DacioConfInfo *dcp)
+ {
+ audio_info_t info;
+
+ #if 0
+ if (ioctl(fd, AUDIO_FLUSH, 0) < 0) {
+ perror("dacioConf");
+ exit(1);
+ }
+ #endif
+ AUDIO_INITINFO(&info);
+ info.play.encoding = AUDIO_ENCODING_LINEAR;
+ info.play.precision = dcp->bits;
+ info.play.channels = dcp->stereo ? 2 : 1;
+ info.play.sample_rate = dcp->speed;
+ if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
+ perror("dacioConf");
+ exit(1);
+ }
+ /*fprintf(stderr, "fmt = 0x%x\n", tmp);*/
+
+ if (ioctl(fd, AUDIO_GETINFO, &info) < 0) {
+ perror("dacioConf");
+ exit(1);
+ }
+ buf.size = info.play.buffer_size;
+ /*fprintf(stderr, "buffer size = 0x%x\n", buf.size);*/
+ dci = *dcp;
+ /*if (buf.top != NULL) free(buf.top);*/
+ buf.top = memPerm(buf.size);
+ buf.p.p8 = buf.top;
+ buf.bot = buf.top + buf.size;
+ buf.shift = dci.stereo + ffs(dci.bits / 8) - 1;
+ }
+
+ void
+ dacioSync(void)
+ {
+ if (ioctl(fd, AUDIO_DRAIN, 0) < 0) {
+ perror("dacioSync");
+ exit(1);
+ }
+ }
+
+ /* OS independent part (?) */
+
+ void
+ dacioFlush(void)
+ {
+ i15x n;
+ u8 *u8p;
+ i15 *i15p;
+ int s;
+
+ if (buf.p.p8 <= buf.top) return;
+
+ n = bufRest() << dci.stereo;
+ switch (dci.bits) {
+ case 8:
+ u8p = buf.p.p8;
+ for (; n > 0; n--)
+ *u8p++ = 128;
+ buf.p.p8 = u8p;
+ break;
+ case 16:
+ i15p = buf.p.p16;
+ for (; n > 0; n--)
+ *i15p++ = 0;
+ buf.p.p16 = i15p;
+ break;
+ }
+
+ RETRY:
+ s = write(fd, buf.top, buf.size);
+ if (s < buf.size) {
+ if (s < 0) {
+ if (errno == EINTR) goto RETRY;
+ perror("dacioFlush");
+ } else fprintf(stderr, "wrote only %d bytes\n", s);
+ exit(1);
+ }
+ buf.p.p8 = buf.top;
+ }
+
+ static struct {
+ const i31 *p0;
+ const i31 *p;
+ i15x len;
+ } inbuf;
+
+ void
+ dacioIncomingBuf(const i31 *bp)
+ {
+ inbuf.p0 = bp;
+ }
+
+ void
+ dacioIncomingBufLen(i15x len)
+ {
+ inbuf.len = len;
+ }
+
+ static i15x gv = 0x40*0x40; /* default g.v = m.v = 64 */
+
+ /* gv = 0(min)..64*128(max) */
+ void
+ dacioGlobalVol(i15x v)
+ {
+ gv = v;
+ }
+
+ #define VOL_MAX (64*64*128) /* vol max * g.v max * m.v max */
+ #define VOL_MAX_LOG ( 6+ 6+ 7) /* 1 << VOL_MAX_LOG == VOL_MAX */
+ #define LEV_MAX (128*VOL_MAX)
+
+ #if 0
+ #define to8bit(x, /*i31x*/tmpvar) \
+ ( tmpvar = (x) * gv, \
+ (tmpvar >= LEV_MAX) ? 255 : \
+ (tmpvar < -LEV_MAX) ? 0 : \
+ (u32x)tmpvar/VOL_MAX ^ 128 )
+ /* ^^^^^^ see asm output w/o this */
+ #define to8bit(x, /*i31x*/tmpvar) \
+ ( tmpvar = (x) * gv + LEV_MAX, \
+ (tmpvar & ~(LEV_MAX*2-1)) ? \
+ ((tmpvar < 0)? 0 : 255) : \
+ (u32x)tmpvar/VOL_MAX)
+ #define to8bit(x, /*i31x*/tmpvar) lim[(x) * gv >> VOL_MAX_LOG]
+ #else
+ /* almost the same CPU usage as lim[] table mathod */
+ #define to8bit(x, /*i31x*/tmpvar) \
+ ( tmpvar = ((x) * gv + LEV_MAX) >> VOL_MAX_LOG, \
+ (tmpvar & ~255)? ~tmpvar >> 16 : tmpvar ) /* 16 will be OK */
+ /* ~(tmpvar >> 16) makes longer asm */
+ #endif
+ #define to16bit(x) \
+ ( ((x) * gv) >> 12 )
+
+ /* stereo */
+ static void
+ dacioOutHirevS(i15x n)
+ {
+ const i31 *inbufp = inbuf.p;
+ u8 *u8p;
+ i15 *i15p;
+
+ switch (dci.bits) {
+ case 8:
+ u8p = buf.p.p8;
+ for (; n > 0; n--) {
+ i31x tmp;
+ *u8p++ = to8bit(*inbufp++, tmp); /* L */
+ *u8p++ = to8bit(*inbufp++, tmp); /* R */
+ }
+ buf.p.p8 = u8p;
+ break;
+ case 16:
+ i15p = buf.p.p16;
+ for (; n > 0; n--) {
+ *i15p++ = to16bit(*inbufp++); /* L */
+ *i15p++ = to16bit(*inbufp++); /* R */
+ }
+ buf.p.p16 = i15p;
+ break;
+ }
+ inbuf.p = inbufp;
+ }
+
+ /* mono */
+ static void
+ dacioOutHirevM(i15x n)
+ {
+ const i31 *inbufp = inbuf.p;
+ u8 *u8p;
+ i15 *i15p;
+
+ switch (dci.bits) {
+ case 8:
+ u8p = buf.p.p8;
+ for (; n > 0; n--) {
+ i31x tmp;
+ *u8p++ = to8bit(*inbufp, tmp);
+ inbufp += 2;
+ }
+ buf.p.p8 = u8p;
+ break;
+ case 16:
+ i15p = buf.p.p16;
+ for (; n > 0; n--) {
+ *i15p++ = to16bit(*inbufp);
+ inbufp += 2;
+ }
+ buf.p.p16 = i15p;
+ break;
+ }
+ inbuf.p = inbufp;
+ }
+
+ #define dacioOutHirev(x) \
+ if (dci.stereo) dacioOutHirevS(x); else dacioOutHirevM(x)
+
+ void
+ dacioOut(void)
+ {
+ i31x iLen;
+ i31x oLen;
+
+ inbuf.p = inbuf.p0;
+ iLen = inbuf.len;
+ while ((oLen = bufRest()) <= iLen) {
+ iLen -= oLen;
+ dacioOutHirev(oLen);
+ dacioFlush();
+ }
+ dacioOutHirev(iLen);
+ }