ref: b1dc12bf2d11aa0ab8becc35d185cd586bb4b279
parent: 56d78c5f36adc9dd6dd6f5fa9063f795888e5de6
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Feb 24 20:32:31 EST 2016
more stuff
--- a/zuke.c
+++ b/zuke.c
@@ -17,12 +17,17 @@
Cforward,
Cbackward,
- Relbufsz = 32768,
+ Everror = 1,
+ Evready,
Bps = 44100*2*2, /* 44100KHz, stereo, u16 for a sample */
Seekbytes = Bps*10, /* 10 seconds */
Scrollwidth = 12,
+
+ Maxfailures = 16,
+
+ Relbufsz = Bps/5, /* 0.2 second */
};
static Meta *pl;
@@ -33,6 +38,8 @@
struct Player
{
Channel *ctl;
+ Channel *ev;
+ Channel *img;
int pcur;
};
@@ -175,7 +182,7 @@
if(cover != nil){
r = screen->r;
r.min.x = r.max.x - cover->r.max.x - 8;
- r.min.y = r.max.y - cover->r.max.y - 8;
+ r.min.y = r.max.y - cover->r.max.y - 8 - f->height - 4;
draw(screen, r, display->black, nil, ZP);
r.min.x += 4;
r.min.y += 4;
@@ -199,68 +206,54 @@
}
static void
-coverload(void *m_)
+coverload(void *player_)
{
- int p[2], p2[2], fd, pid, pid2;
+ int p[2], pid, fd;
char *prog;
Meta *m;
- Ioproc *io;
+ Channel *ch;
+ Player *player;
+ Image *newcover;
threadsetname("cover");
- m = m_;
- freeimage(cover);
- cover = nil;
- redraw(screen, 1);
+ player = player_;
+ m = &pl[player->pcur];
+ pid = -1;
+ ch = player->img;
+
if(m->imagefmt == nil || m->imagereader != 0)
- return;
+ goto done;
if(strcmp(m->imagefmt, "image/png") == 0)
- prog = "/bin/png";
+ prog = "png -9t | resize -x128";
else if(strcmp(m->imagefmt, "image/jpeg") == 0)
- prog = "/bin/jpg";
+ prog = "jpg -9t | resize -x128";
else
- return;
+ goto done;
- io = ioproc();
- if((fd = ioopen(io, m->path, OREAD)) < 0){
- closeioproc(io);
- return;
- }
- if(seek(fd, m->imageoffset, 0) != m->imageoffset){
- ioclose(io, fd);
- closeioproc(io);
- return;
- }
-
pipe(p);
if((pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
+ fd = open(m->path, OREAD);
+ seek(fd, m->imageoffset, 0);
dup(fd, 0); close(fd);
- dup(p[0], 1); close(p[0]);
- close(p[1]);
- execl(prog, prog, "-9t", nil);
+ dup(p[1], 1); close(p[1]);
+ close(2);
+ execl("/bin/rc", "rc", "-c", prog, nil);
sysfatal("execl: %r");
}
- ioclose(io, fd);
- close(p[0]);
-
- pipe(p2);
- if((pid2 = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
- dup(p[1], 0); close(p[1]);
- dup(p2[0], 1); close(p2[0]);
- close(p2[1]);
- execl("/bin/resize", "/bin/resize", "-x128", nil);
- sysfatal("execl: %r");
- }
close(p[1]);
- close(p2[0]);
- if(pid > 0 && pid2 > 0){
- cover = readimage(display, p2[1], 0);
- redraw(screen, 1);
+ if(pid > 0){
+ newcover = readimage(display, p[0], 0);
+ sendp(ch, newcover);
}
- postnote(PNGROUP, pid, "interrupt");
- postnote(PNGROUP, pid2, "interrupt");
- close(p2[1]);
- closeioproc(io);
+ close(p[0]);
+done:
+ if(pid < 0)
+ sendp(ch, nil);
+ chanfree(ch);
+ if(pid >= 0)
+ postnote(PNGROUP, pid, "interrupt");
+ threadexits(nil);
}
static void
@@ -269,54 +262,69 @@
char *buf;
Player *player;
Ioproc *io;
+ Image *thiscover;
ulong c;
- int p[2], fd, pid, n, noinit;
+ int p[2], fd, pid, n, got, noinit, trycoverload;
u64int bytesfrom;
+ threadsetname("player");
player = player_;
noinit = 0;
bytesfrom = 0;
c = 0;
buf = nil;
+ trycoverload = 1;
+ io = nil;
+ pid = -1;
restart:
+ if((fd = open(pl[player->pcur].path, OREAD)) < 0){
+ fprint(2, "%r\n");
+ nbsendul(player->ev, Everror);
+ goto freeplayer;
+ }
+
pipe(p);
if((pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
- dup(p[0], 1);
- if((fd = open(pl[player->pcur].path, OREAD)) < 0){
- fprint(2, "%r\n");
- exits(nil);
- }
- dup(fd, 0);
- close(fd);
- close(p[0]);
+ dup(p[0], 1); close(p[0]);
+ dup(fd, 0); close(fd);
close(p[1]);
close(2);
- execl("/bin/play", "/bin/play", "-o", "/fd/1", nil);
+ execl("/bin/rc", "rc", "-c", "play -o /fd/1", nil);
sysfatal("execl: %r");
}
if(pid < 0)
sysfatal("rfork: %r");
+ close(fd);
close(p[0]);
+ byteswritten = 0;
if(!noinit){
- threadsetname("player");
- c = recvul(player->ctl);
- if(c != Cstart)
- return;
+ nbsendul(player->ev, Evready);
buf = malloc(Relbufsz);
+ io = ioproc();
+ for(c = 0, got = 0; got < Relbufsz; got += n){
+ if((c = nbrecvul(player->ctl)) != 0)
+ break;
+ n = ioread(io, p[1], buf+got, Relbufsz-got);
+ if(n < 1)
+ break;
+ }
+ if(c == 0)
+ c = recvul(player->ctl);
+ if(c != Cstart)
+ goto freeplayer;
+ write(audio, buf, got);
+ byteswritten = got;
bytesfrom = 0;
c = 0;
noinit = 1;
}
- byteswritten = 0;
pcurplaying = player->pcur;
if(c != Cbackward)
- redraw(screen, 1);
- /*proccreate(coverload, &pl[pcurplaying], 4096);*/
+ redraw(screen, 0);
- io = ioproc();
while(1){
n = Relbufsz;
if(bytesfrom > byteswritten && n > bytesfrom-byteswritten)
@@ -325,6 +333,12 @@
if(n < 1)
break;
+ if(player->img != nil && nbrecv(player->img, &thiscover) > 0){
+ freeimage(cover);
+ cover = thiscover;
+ redraw(screen, 0);
+ player->img = nil;
+ }
c = nbrecvul(player->ctl);
if(c == Cstop)
goto stop;
@@ -342,22 +356,26 @@
c = 0;
if(bytesfrom <= byteswritten){
- if(iowrite(io, audio, buf, n) != n){
+ if(write(audio, buf, n) != n){
fprint(2, "failed to write %d bytes: %r\n", n);
break;
}
+ if(trycoverload && byteswritten >= Bps){
+ freeimage(cover);
+ cover = nil;
+ player->img = chancreate(sizeof(Image*), 0);
+ proccreate(coverload, player, 4096);
+ trycoverload = 0;
+ redraw(screen, 0);
+ }
}
byteswritten += n;
- if(bytesfrom == byteswritten || (bytesfrom < byteswritten && byteswritten/Bps > (byteswritten-n)/Bps))
+ if(bytesfrom == byteswritten || (byteswritten/Bps > (byteswritten-n)/Bps))
redraw(screen, 0);
}
- closeioproc(io);
- io = nil;
if(n == 0){ /* seeking backwards or end of the song */
close(p[1]);
- postnote(PNGROUP, pid, "interrupt");
- waitpid();
if(c != Cbackward){
bytesfrom = 0;
player->pcur++;
@@ -366,27 +384,28 @@
}
stop:
- closeioproc(io);
+ if(player->img != nil)
+ freeimage(recvp(player->img));
+freeplayer:
close(p[1]);
- postnote(PNGROUP, pid, "interrupt");
- waitpid();
+ closeioproc(io);
free(buf);
+ chanfree(player->ctl);
+ chanfree(player->ev);
+ free(player);
+ if(pid >= 0)
+ postnote(PNGROUP, pid, "interrupt");
+ threadexits(nil);
}
-static Player *
-newplayer(int pcur)
+static int
+playerret(Player *player)
{
- Player *player;
-
- player = malloc(sizeof(*player));
- player->ctl = chancreate(sizeof(ulong), 0);
- player->pcur = pcur;
-
- threadcreate(playerthread, player, mainstacksize);
-
- return player;
+ return recvul(player->ev) == Everror ? -1 : 0;
}
+static Player *playernext;
+
static void
stop(Player *player)
{
@@ -393,16 +412,48 @@
if(player == nil)
return;
+ if(player == playernext)
+ playernext = nil;
sendul(player->ctl, Cstop);
- chanfree(player->ctl);
- free(player);
}
-static void
+static Player *
+newplayer(int pcur, int loadnext)
+{
+ Player *player;
+
+ if(playernext != nil && loadnext){
+ if(pcur == playernext->pcur){
+ player = playernext;
+ playernext = nil;
+ goto done;
+ }
+ stop(playernext);
+ playernext = nil;
+ }
+
+ player = mallocz(sizeof(*player), 1);
+ player->ctl = chancreate(sizeof(ulong), 0);
+ player->ev = chancreate(sizeof(ulong), 0);
+ player->pcur = pcur;
+
+ threadcreate(playerthread, player, mainstacksize);
+ if(playerret(player) < 0)
+ return nil;
+
+done:
+ if(pcur < plnum-1 && playernext == nil && loadnext)
+ playernext = newplayer(pcur+1, 0);
+
+ return player;
+}
+
+static int
start(Player *player)
{
if(player != nil)
sendul(player->ctl, Cstart);
+ return -1;
}
static void
@@ -559,9 +610,9 @@
void
threadmain(int argc, char **argv)
{
- int inv, fd, scrolling, oldscroll, oldpcur, oldscrolling, usingscrollbar;
- Point lastclick;
+ char tmp[256];
Player *player;
+ Point lastclick;
Rune key;
Mouse m;
Alt a[] =
@@ -571,7 +622,7 @@
{ nil, &key, CHANRCV },
{ nil, nil, CHANEND },
};
- char tmp[256];
+ int inv, fd, scrolling, oldscroll, oldpcur, oldscrolling, usingscrollbar;
inv = 0;
ARGBEGIN{
@@ -652,12 +703,12 @@
pcur = scroll + (m.xy.y - screen->r.min.y)/f->height;
if(m.buttons == 4){
stop(player);
- player = newplayer(pcur);
+ player = newplayer(pcur, 1);
start(player);
}
}
break;
- case 1:
+ case 1: /* resize */
redraw(screen, 1);
break;
case 2:
@@ -688,7 +739,7 @@
break;
case 10:
stop(player);
- player = newplayer(pcur);
+ player = newplayer(pcur, 1);
start(player);
break;
case 'q': case Kdel:
@@ -704,7 +755,7 @@
if(++pcur >= plnum)
pcur = 0;
stop(player);
- player = newplayer(pcur);
+ player = newplayer(pcur, 1);
start(player);
break;
case '<':
@@ -714,7 +765,7 @@
if(--pcur < 0)
pcur = plnum-1;
stop(player);
- player = newplayer(pcur);
+ player = newplayer(pcur, 1);
start(player);
break;
case 's':