code: plan9front

Download patch

ref: 4ba285fb7dc477013ce1fca68adf59244fc42bd4
parent: 43a3a80be3cd9fe7e0f31efe5c24c3e321e07b08
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Sep 20 12:54:36 EDT 2022

audio/zuke: fix/enable playlist loading via plumber "audio" port

--- a/sys/lib/plumb/basic
+++ b/sys/lib/plumb/basic
@@ -36,7 +36,7 @@
 # audio
 type is text
 data matches '[a-zA-Z¡-￿0-9_\-.,/]+'
-data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS)'
+data matches '([a-zA-Z¡-￿0-9_\-.,/]+)\.(mp3|MP3|ogg|OGG|flac|FLAC|wav|WAV|au|AU|mid|MID|mus|MUS|m3u|M3U|pls|PLS|plist|PLIST)'
 arg isfile	$0
 plumb to audio
 plumb start window -scroll play $file
--- a/sys/man/1/zuke
+++ b/sys/man/1/zuke
@@ -83,6 +83,12 @@
 bar, current position, track duration and volume are displayed.  ``∫''
 is shown if shuffle mode is enabled.
 .PP
+Plumbing a file with
+.B .plist
+extension loads the playlist in
+.IR zuke .
+This is useful with a collection of playlists displayed aside.
+.PP
 .I Zuke
 provides a number of keyboard controls:
 .RS
--- a/sys/src/cmd/audio/zuke/zuke.c
+++ b/sys/src/cmd/audio/zuke/zuke.c
@@ -42,6 +42,8 @@
 	Dblow,
 	Dbinv,
 	Numcolors,
+
+	Ncol = 10,
 };
 
 struct Color {
@@ -85,8 +87,8 @@
 static Mousectl *mctl;
 static Keyboardctl kctl;
 static int shiftdown;
-static int colwidth[10];
-static int mincolwidth[10];
+static int colwidth[Ncol];
+static int mincolwidth[Ncol];
 static char *cols = "AatD";
 static int colspath;
 static int *shuffle;
@@ -826,15 +828,6 @@
 }
 
 static void
-writeplist(void)
-{
-	int i;
-
-	for(i = 0; i < pl->n; i++)
-		printmeta(&out, pl->m+i);
-}
-
-static void
 freeplist(Playlist *pl)
 {
 	if(pl != nil){
@@ -872,7 +865,7 @@
 }
 
 static Playlist *
-readplist(int fd)
+readplist(int fd, int mincolwidth[Ncol])
 {
 	char *raw, *s, *e, *a[5], *b;
 	int plsz, i, x;
@@ -1077,9 +1070,36 @@
 }
 
 static void
+adjustcolumns(void)
+{
+	int i, n, total, width;
+
+	total = 0;
+	n = 0;
+	width = Dx(screen->r);
+	for(i = 0; cols[i] != 0; i++){
+		if(cols[i] == Pduration || cols[i] == Pdate || cols[i] == Ptrack)
+			width -= mincolwidth[i] + 8;
+		else{
+			total += mincolwidth[i];
+			n++;
+		}
+	}
+	colspath = 0;
+	for(i = 0; cols[i] != 0; i++){
+		if(cols[i] == Ppath || cols[i] == Pbasename)
+			colspath = 1;
+		if(cols[i] == Pduration || cols[i] == Pdate || cols[i] == Ptrack)
+			colwidth[i] = mincolwidth[i];
+		else
+			colwidth[i] = (width - Scrollwidth - n*8) * mincolwidth[i] / total;
+	}
+}
+
+static void
 plumbaudio(void *kbd)
 {
-	int i, f, pf;
+	int i, f, pf, mcw[Ncol], wasplaying;
 	Playlist *p;
 	Plumbmsg *m;
 	char *s, *e;
@@ -1099,15 +1119,23 @@
 				s = smprint("%s/%.*s", m->wdir, m->ndata, m->data);
 
 			if((e = strrchr(s, '.')) != nil && strcmp(e, ".plist") == 0 && (pf = open(s, OREAD)) >= 0){
-				p = readplist(pf);
+				p = readplist(pf, mcw);
 				close(pf);
 				if(p == nil)
 					continue;
-
+				wasplaying = pcurplaying;
+				/* make sure nothing is playing */
+				while(pcurplaying >= 0){
+					sendul(kbd, 'v');
+					sleep(100);
+				}
 				freeplist(pl);
 				pl = p;
-				memset(mincolwidth, 0, sizeof(mincolwidth)); /* readjust columns */
-				sendul(playc, 0);
+				memmove(mincolwidth, mcw, sizeof(mincolwidth));
+				adjustcolumns();
+				pcur = 0;
+				if(wasplaying >= 0)
+					sendul(kbd, '\n');
 			}else{
 				for(i = 0; i < pl->n; i++){
 					if(strcmp(pl->m[i].path, s) == 0){
@@ -1127,33 +1155,6 @@
 }
 
 static void
-adjustcolumns(void)
-{
-	int i, n, total, width;
-
-	total = 0;
-	n = 0;
-	width = Dx(screen->r);
-	for(i = 0; cols[i] != 0; i++){
-		if(cols[i] == Pduration || cols[i] == Pdate || cols[i] == Ptrack)
-			width -= mincolwidth[i] + 8;
-		else{
-			total += mincolwidth[i];
-			n++;
-		}
-	}
-	colspath = 0;
-	for(i = 0; cols[i] != 0; i++){
-		if(cols[i] == Ppath || cols[i] == Pbasename)
-			colspath = 1;
-		if(cols[i] == Pduration || cols[i] == Pdate || cols[i] == Ptrack)
-			colwidth[i] = mincolwidth[i];
-		else
-			colwidth[i] = (width - Scrollwidth - n*8) * mincolwidth[i] / total;
-	}
-}
-
-static void
 kbproc(void *cchan)
 {
 	char *s, buf[128], buf2[128];
@@ -1297,7 +1298,7 @@
 	fmtinstall('P', positionfmt);
 	threadsetname("zuke");
 
-	if((pl = readplist(0)) == nil){
+	if((pl = readplist(0, mincolwidth)) == nil){
 		fprint(2, "playlist: %r\n");
 		sysfatal("playlist error");
 	}
@@ -1487,7 +1488,9 @@
 				continue;
 			case 'v':
 				stop(playercurr);
+				stop(playernext);
 				playercurr = nil;
+				playernext = nil;
 				pcurplaying = -1;
 				freeimage(cover);
 				cover = nil;