code: plan9front

Download patch

ref: af2f7ea2364f50458b46262aa7027470983c13b6
parent: 51ead1072b1c4b55ec898a083ed2bba878c33927
author: qwx <devnull@localhost>
date: Tue Apr 27 05:48:14 EDT 2021

games/opl3: don't buffer output and simplify (thanks umbraticus)

this fixes real-time applications.

-n previously specified a rate divisor rather than the rate itself,
which was used for specific applications outside of 9front.  instead,
just set the rate directly, more useful and straightforward.

--- a/sys/man/1/opl3
+++ b/sys/man/1/opl3
@@ -4,7 +4,7 @@
 .SH SYNOPSIS
 .B opl3
 [
-.B -n
+.B -r
 .I rate
 ] [
 .I file
@@ -44,7 +44,7 @@
 chip may be sampled before processing the next command.
 The period itself is the inverse of the command rate, 44100 Hz by default.
 This rate can be set using the
-.B -n
+.B -r
 parameter.
 .SH SOURCE
 .B /sys/src/games/opl3
--- a/sys/src/games/opl3/opl3m.c
+++ b/sys/src/games/opl3/opl3m.c
@@ -6,14 +6,10 @@
 void	opl3wr(int, int);
 void	opl3init(int);
 
-enum{
-	Rate = 44100,
-};
-
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-n nsamp] [file]\n", argv0);
+	fprint(2, "usage: %s [-r rate] [file]\n", argv0);
 	exits("usage");
 }
 
@@ -20,15 +16,15 @@
 void
 main(int argc, char **argv)
 {
-	int r, v, dt, nsamp, fd;
-	uchar *sb, u[5];
-	Biobuf *bi, *bo;
+	int rate, r, v, dt, fd;
+	uchar sb[65536 * 4], u[5];
+	Biobuf *bi;
 
 	fd = 0;
-	nsamp = 1;
+	rate = 44100;
 	ARGBEGIN{
-	case 'n':
-		nsamp = Rate / atoi(EARGF(usage()));
+	case 'r':
+		rate = atoi(EARGF(usage()));
 		break;
 	default:
 		usage();
@@ -37,21 +33,16 @@
 		if((fd = open(*argv, OREAD)) < 0)
 			sysfatal("open: %r");
 	bi = Bfdopen(fd, OREAD);
-	bo = Bfdopen(1, OWRITE);
-	if(bi == nil || bo == nil)
+	if(bi == nil)
 		sysfatal("Bfdopen: %r");
-	nsamp *= 4;
-	if((sb = malloc(nsamp)) == nil)
-		sysfatal("malloc: %r");
-	opl3init(Rate);
+	opl3init(rate);
 	while(Bread(bi, u, sizeof u) > 0){
 		r = u[1] << 8 | u[0];
 		v = u[2];
-		dt = u[4] << 8 | u[3];
 		opl3wr(r, v);
-		while(dt-- > 0){
-			opl3out(sb, nsamp);
-			Bwrite(bo, sb, nsamp);
+		if(dt = (u[4] << 8 | u[3]) * 4){	/* 16-bit stereo */
+			opl3out(sb, dt);
+			write(1, sb, dt);
 		}
 	}
 }