shithub: riscv

Download patch

ref: 577de86669fcd9ed19db4d7561651e6b9641f44e
parent: 70c6dab003afbdf48fec6fc6012ccdd3aa277ac2
author: cinap_lenrek <[email protected]>
date: Sun Feb 26 14:30:48 EST 2017

midi: ignore bends, allow piping from stdin and to stdout, write in chunks from within sample loop (thanks qu7uux)

--- a/sys/src/games/midi.c
+++ b/sys/src/games/midi.c
@@ -16,6 +16,7 @@
 int fd, ofd, div, tempo = 500000, ntrack;
 uvlong T;
 int freq[128];
+uchar out[8192], *outp = out;
 
 void *
 emallocz(int size)
@@ -110,8 +111,7 @@
 void
 run(uvlong n)
 {
-	int samp, j, k, l, no[128];
-	uchar *s;
+	int samp, j, k, no[128];
 	int t, f;
 	short u;
 	Tracker *x;
@@ -127,8 +127,7 @@
 			for(k = 0; k < 128; k++)
 				no[k] += x->notes[j][k];
 	}
-	s = emallocz(samp * 4);
-	for(l = 0; l < samp; l++){
+	while(samp--){
 		t = 0;
 		for(k = 0; k < 128; k++){
 			f = (T % freq[k]) >= freq[k]/2 ? 1 : 0;
@@ -135,12 +134,15 @@
 			t += f * no[k];
 		}
 		u = t*10;
-		s[4 * l] = s[4 * l + 2] = u;
-		s[4 * l + 1] = s[4 * l + 3] = u >> 8;
+		outp[0] = outp[2] = u;
+		outp[1] = outp[3] = u >> 8;
+		outp += 4;
+		if(outp == out + sizeof out){
+			write(ofd, out, sizeof out);
+			outp = out;
+		}
 		T++;
 	}
-	write(ofd, s, samp * 4);
-	free(s);
 }
 
 void
@@ -175,6 +177,9 @@
 	case 0xC:
 		get8(src);
 		break;
+	case 0xE:
+		get16(src);
+		break;
 	case 0xF:
 		t = get8(src);
 		n = get8(src);
@@ -187,11 +192,11 @@
 			tempo |= get8(src);
 			break;
 		case 5:
-			write(1, src->data, n);
+			write(2, src->data, n);
 			skip(src, n);
 			break;
 		default:
-			print("unknown meta event type %.2x\n", t);
+			fprint(2, "unknown meta event type %.2x\n", t);
 		case 3: case 1: case 2: case 0x58: case 0x59: case 0x21:
 			skip(src, n);
 		}
@@ -208,14 +213,17 @@
 	uvlong t, mint;
 	Tracker *x, *minx;
 
-	if(argc != 2)
-		sysfatal("invalid arguments");
-	fd = open(argv[1], OREAD);
-	if(fd < 0)
+	ARGBEGIN{
+	case 'c':
+		ofd = 1;
+		break;
+	}ARGEND;
+	if(*argv != nil)
+		fd = open(*argv, OREAD);
+	if(ofd == 0)
+		ofd = open("/dev/audio", OWRITE);
+	if(fd < 0 || ofd < 0)
 		sysfatal("open: %r");
-	ofd = open("/dev/audio", OWRITE);
-	if(ofd < 0)
-		sysfatal("ofd: %r");
 	if(get32(nil) != 0x4D546864 || get32(nil) != 6)
 		sysfatal("invalid file header");
 	get16(nil);
@@ -227,7 +235,7 @@
 			sysfatal("invalid track header");
 		size = get32(nil);
 		tr[i].data = emallocz(size);
-		read(fd, tr[i].data, size);
+		readn(fd, tr[i].data, size);
 	}
 	for(i = 0; i < 128; i++)
 		freq[i] = SAMPLE / (440 * pow(1.05946, i - 69));
@@ -243,8 +251,10 @@
 				minx = x;
 			}
 		}
-		if(minx == nil)
+		if(minx == nil){
+			write(ofd, out, outp - out);
 			exits(nil);
+		}
 		readevent(minx);
 	}
 }