code: plan9front

Download patch

ref: 14fe59e83905a5d84bbf257807976f25c0421c65
parent: 1d63115328e8ca2fe06159da5f18bde43adca3df
author: qwx <qwx@sciops.net>
date: Thu Jun 29 15:16:31 EDT 2023

games/opl3: fix choking on high tempo streams

also remove bullshit concurrency and locks, what was i thinking

--- a/sys/src/games/opl3/opl3m.c
+++ b/sys/src/games/opl3/opl3m.c
@@ -8,6 +8,8 @@
 
 enum{
 	OPLrate = 49716,	/* 14318180Hz master clock / 288 */
+	Devrate = 44100,
+	Srate = Devrate / 100,
 };
 
 void
@@ -22,10 +24,8 @@
 {
 	int rate, stream, n, r, v, fd, pfd[2];
 	uchar sb[64*1024], u[5];
-	double f;
-	vlong dt, T;
+	double s, f, dt, T;
 	Biobuf *bi;
-	QLock slock;
 
 	fd = 0;
 	stream = 0;
@@ -73,15 +73,13 @@
 			sysfatal("rfork: %r");
 		case 0:
 			for(;;){
-				qlock(&slock);
-				n = OPLrate / 1e3;
-				T += n * (1e9 / OPLrate);
+				n = Srate;
+				s = 1e9 * n / OPLrate;
+				T += s;
+				dt = floor((T - nsec()) / 1e6);
 				n *= 4;
 				opl3out(sb, n);
-				n = write(pfd[1], sb, n);
-				dt = (T - nsec()) / 1e6;
-				qunlock(&slock);
-				if(n <= 0)
+				if(write(pfd[1], sb, n) != n)
 					break;
 				if(dt > 0)
 					sleep(dt);
@@ -92,18 +90,18 @@
 		r = u[1] << 8 | u[0];
 		v = u[2];
 		opl3wr(r, v);
+		if(stream)
+			continue;
 		dt += (u[4] << 8 | u[3]) * f;
-		qlock(&slock);
 		while((n = dt) > 0){
 			if(n > sizeof sb / 4)
 				n = sizeof sb / 4;
 			dt -= n;
-			T += n * (1e9 / OPLrate);
+			T += n * 1e9 / OPLrate;
 			n *= 4;
 			opl3out(sb, n);
 			write(pfd[1], sb, n);
 		}
-		qunlock(&slock);
 	}
 	if(n < 0)
 		sysfatal("read: %r");