shithub: zuke

Download patch

ref: 4c5bf2f861bb45cb1c2fbce54217c06948c1c8ab
parent: 81916a6bba65225bf4ed83133ebb2081eb996dc5
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat Feb 20 12:59:03 EST 2016

use new playlist format in the player

--- a/tracklist.rc
+++ /dev/null
@@ -1,8 +1,0 @@
-#!/bin/rc
-
-ls -Q $"*/*/*/*.mp3 $"*/*/*/*.ogg $"*/*/*/*.flac >[2]/dev/null | while (track=`{read}) {
-	echo -n $track
-	echo -n '	'
-	tags=`{audio/readtags $"track |[2] audio/printtags}
-	echo $"tags
-}
--- a/zuke.c
+++ b/zuke.c
@@ -5,6 +5,8 @@
 #include <keyboard.h>
 #include <bio.h>
 #include <thread.h>
+#include <ctype.h>
+#include "plist.h"
 
 typedef struct Player Player;
 
@@ -15,12 +17,10 @@
 	Ctoggle,
 };
 
-static struct
-{
-	char *file;
-	char *name;
-}*plist;
-static int plen;
+static Meta *pl;
+static int plnum;
+static char *plraw;
+static int plrawsize;
 
 struct Player
 {
@@ -40,6 +40,7 @@
 static void
 redraw(Image *screen, int new)
 {
+	char tmp[256];
 	Point p, sp;
 	int i;
 
@@ -51,7 +52,7 @@
 	p.y = screen->r.min.y + 2;
 	scrollsz = Dy(screen->r) / f->height - 1;
 
-	for(i = scroll; i < plen; i++){
+	for(i = scroll; i < plnum; i++){
 		if(p.y > screen->r.max.y)
 			break;
 		if(pcurplaying == i){
@@ -63,6 +64,8 @@
 			left.y = right.y = p.y + f->height;
 			line(screen, left, right, 0, 0, 0, colb, sp);
 		}
+
+		snprint(tmp, sizeof(tmp), "%s - %s - %s", pl[i].artist[0], pl[i].album, pl[i].title);
 		if(pcur == i){
 			Rectangle sel;
 			sel = screen->r;
@@ -69,10 +72,10 @@
 			sel.min.y = p.y;
 			sel.max.y = p.y + f->height;
 			draw(screen, sel, colb, nil, ZP);
-			string(screen, p, cola, sp, f, plist[i].name);
+			string(screen, p, cola, sp, f, tmp);
 		}
 		else
-			string(screen, p, colb, sp, f, plist[i].name);
+			string(screen, p, colb, sp, f, tmp);
 		p.y += f->height;
 	}
 
@@ -101,7 +104,7 @@
 		close(p[1]);
 		close(0);
 		close(2);
-		execl("/bin/play", "/bin/play", "-o", "/fd/1", plist[player->pcur].file, nil);
+		execl("/bin/play", "/bin/play", "-o", "/fd/1", pl[player->pcur].path, nil);
 		sysfatal("execl: %r");
 	}
 	if(pid < 0)
@@ -195,26 +198,81 @@
 static void
 readplist(void)
 {
-	Biobuf b;
+	Meta *m;
+	char *s, *e, *endrec;
+	int i, n, sz, alloc, tagsz, intval;
 
-	Binit(&b, 0, OREAD);
-	for(plen = 0;; plen++){
-		char *s[2];
-		int n;
-
-		s[0] = Brdstr(&b, '\n', 1);
-		if(s[0] == nil)
+	s = nil;
+	for(alloc = sz = 0;;){
+		alloc += 65536;
+		if((s = realloc(s, alloc)) == nil)
+			sysfatal("no memory");
+		for(n = 0; sz < alloc; sz += n){
+			n = read(0, s+sz, alloc-sz);
+			if(n < 0)
+				sysfatal("%r");
+			if(n == 0)
+				break;
+		}
+		if(n == 0)
 			break;
-		plist = realloc(plist, sizeof(*plist)*(plen+1));
-		n = getfields(s[0], s, 2, 1, "\t");
-		if(n < 1)
-			break;
-		plist[plen].file = plist[plen].name = s[0];
-		if(n > 1)
-			plist[plen].name = s[1];
-		else if((plist[plen].name = strrchr(s[0], '/')) != nil)
-			plist[plen].name++; 
 	}
+
+	plraw = s;
+	plrawsize = sz;
+	plraw[plrawsize-1] = 0;
+	if(sz < 4 || s[0] != '#' || s[1] != ' ' || !isdigit(s[2]) || (s = memchr(plraw, '\n', sz)) == nil)
+		sysfatal("invalid playlist");
+	s++; /* at the start of the first record */
+
+	plnum = atoi(plraw+2);
+	pl = calloc(plnum, sizeof(Meta));
+	for(i = 0; i < plnum; i++, s = endrec){
+		if(plraw+plrawsize < s+10)
+			sysfatal("truncated playlist");
+		if(s[0] != '#' || s[1] != ' ' || !isdigit(s[2]) || strtol(s+2, &e, 10) != i)
+			sysfatal("invalid record");
+
+		sz = strtol(e, &s, 10);
+		s++; /* skip '\n' */
+		if(s+sz > plraw+plrawsize)
+			sysfatal("truncated playlist");
+		s[sz-1] = 0; /* '\n'→'\0' to mark the end of the record */
+		endrec = s+sz;
+		m = &pl[i];
+
+		for(;;){
+			if(s[0] == Pimage){
+				m->imageoffset = strtol(s+2, &e, 10);
+				m->imagesize = strtol(e+1, &s, 10);
+				m->imagereader = strtol(s+1, &e, 10);
+				s = e + 1;
+			}else if(s[0] == Pchannels || s[0] == Pduration || s[0] == Psamplerate){
+				intval = strtol(s+2, &e, 10);
+				if(s[0] == Pchannels) m->channels = intval;
+				else if(s[0] == Pduration) m->duration = intval;
+				else if(s[0] == Psamplerate) m->samplerate = intval;
+				s = e + 1;
+			}else if(s[0] == Ppath){
+				m->path = s+2;
+				break; /* always the last one */
+			}else{
+				tagsz = strtol(s+1, &e, 10);
+				if(e+tagsz >= plraw+plrawsize)
+					sysfatal("truncated playlist");
+				e++; /* point to tag value */
+				e[tagsz] = 0; /* '\n'→'\0' to mark the end of the tag value */
+				if(s[0] == Palbum) m->album = e;
+				else if(s[0] == Partist && m->numartist < Maxartist) m->artist[m->numartist++] = e;
+				else if(s[0] == Pdate) m->date = e;
+				else if(s[0] == Ptitle) m->title = e;
+				else if(s[0] == Pdate) m->date = e;
+				else if(s[0] == Ptrack) m->track = e;
+				else sysfatal("unknown tag type %c", s[0]);
+				s = e + tagsz+1;
+			}
+		}
+	}
 }
 
 static void
@@ -252,7 +310,7 @@
 		sysfatal("audio: %r");
 
 	readplist();
-	if(plen < 1){
+	if(plnum < 1){
 		fprint(2, "empty playlist\n");
 		sysfatal("empty");
 	}
@@ -298,7 +356,7 @@
 			}else if(e.kbdc == Kpgdown){
 				pcur += scrollsz;
 			}else if(e.kbdc == Kend){
-				pcur = plen-1;
+				pcur = plnum-1;
 			}else if(e.kbdc == Khome){
 				pcur = 0;
 			}else if(e.kbdc == 0x0a){
@@ -312,7 +370,7 @@
 				pcur = pcurplaying;
 			}else if(e.kbdc == '>' && pcurplaying >= 0){
 				pcur = pcurplaying;
-				if(++pcur >= plen)
+				if(++pcur >= plnum)
 					pcur = 0;
 				stop(player);
 				player = newplayer(pcur);
@@ -320,12 +378,11 @@
 			}else if(e.kbdc == '<' && pcurplaying >= 0){
 				pcur = pcurplaying;
 				if(--pcur < 0)
-					pcur = plen-1;
+					pcur = plnum-1;
 				stop(player);
 				player = newplayer(pcur);
 				start(player);
 			}else if(e.kbdc == 's' && player != nil){
-				pcur = -1;
 				stop(player);
 				player = nil;
 			}else if(e.kbdc == 'p'){
@@ -336,8 +393,8 @@
 		if(pcur != oldpcur){
 			if(pcur < 0)
 				pcur = 0;
-			else if(pcur >= plen)
-				pcur = plen - 1;
+			else if(pcur >= plnum)
+				pcur = plnum - 1;
 
 			if(pcur < scroll)
 				scroll = pcur;
@@ -344,8 +401,8 @@
 			else if(pcur > scroll + scrollsz)
 				scroll = pcur - scrollsz;
 
-			if(scroll > plen - scrollsz)
-				scroll = plen - scrollsz;
+			if(scroll > plnum - scrollsz)
+				scroll = plnum - scrollsz;
 			else if(scroll < 0)
 				scroll = 0;