shithub: pplay

Download patch

ref: fd7be1f5cae97cba175519e97fa5b0b60b93ea70
parent: 331ab02f38db96f0a90c8bd9b195f5db01545c5a
author: qwx <qwx@sciops.net>
date: Wed Jan 8 22:40:28 EST 2020

split source up to facilitate extension

--- /dev/null
+++ b/dat.h
@@ -1,0 +1,5 @@
+extern ulong nbuf;
+extern uchar *buf, *bufp, *bufe, *viewp, *viewe, *viewmax, *loops, *loope;
+extern int T;
+extern int stereo;
+extern int zoom;
--- /dev/null
+++ b/draw.c
@@ -1,0 +1,175 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+enum{
+	Cbg,
+	Csamp,
+	Cline,
+	Cloop,
+	Ncol,
+};
+static Image *col[Ncol];
+static Image *viewbg, *view;
+static Rectangle liner;
+static Point statp;
+
+static Image *
+eallocimage(Rectangle r, int repl, ulong col)
+{
+	Image *i;
+
+	if((i = allocimage(display, r, screen->chan, repl, col)) == nil)
+		sysfatal("allocimage: %r");
+	return i;
+}
+
+static void
+drawstat(void)
+{
+	char s[64];
+
+	snprint(s, sizeof s, "T %d p %zd", T, bufp-buf);
+	string(screen, statp, col[Cline], ZP, font, s);
+}
+
+static void
+drawsamps(void)
+{
+	int x, yl, yr, w, scal, lmin, lmax, rmin, rmax;
+	short s;
+	uchar *p, *e;
+	Rectangle l, r;
+
+	w = T * 4;
+	p = viewp;
+	x = 0;
+	yl = viewbg->r.max.y / (stereo ? 4 : 2);
+	yr = viewbg->r.max.y - yl;
+	scal = 32767 / yl;
+	while(p < viewe){
+		e = p + w;
+		if(e > viewe)
+			e = viewe;
+		lmin = lmax = 0;
+		rmin = rmax = 0;
+		while(p < e){
+			s = (short)(p[1] << 8 | p[0]);
+			if(s < lmin)
+				lmin = s;
+			else if(s > lmax)
+				lmax = s;
+			if(stereo){
+				s = (short)(p[3] << 8 | p[2]);
+				if(s < rmin)
+					rmin = s;
+				else if(s > rmax)
+					rmax = s;
+			}
+			p += 4;
+		}
+		l = Rect(x, yl - lmax / scal, x+1, yl - lmin / scal);
+		draw(viewbg, l, col[Csamp], nil, ZP);
+		if(stereo){
+			r = Rect(x, yr - rmax / scal, x+1, yr - rmin / scal);
+			draw(viewbg, r, col[Csamp], nil, ZP);
+		}
+		x++;
+	}
+}
+
+void
+update(void)
+{
+	int x;
+
+	x = screen->r.min.x + (bufp - viewp) / 4 / T;
+	if(liner.min.x == x || bufp < viewp && x > liner.min.x)
+		return;
+	draw(screen, screen->r, view, nil, ZP);
+	liner.min.x = x;
+	liner.max.x = x + 1;
+	if(bufp >= viewp)
+		draw(screen, liner, col[Cline], nil, ZP);
+	drawstat();
+	flushimage(display, 1);
+}
+
+void
+drawview(void)
+{
+	int x;
+	Rectangle r;
+
+	draw(view, view->r, viewbg, nil, ZP);
+	if(loops != buf && loops >= viewp){
+		x = (loops - viewp) / 4 / T;
+		r = view->r;
+		r.min.x += x;
+		r.max.x = r.min.x + 1;
+		draw(view, r, col[Cloop], nil, ZP);
+	}
+	if(loope != bufe && loope >= viewp){
+		x = (loope - viewp) / 4 / T;
+		r = view->r;
+		r.min.x += x;
+		r.max.x = r.min.x + 1;
+		draw(view, r, col[Cloop], nil, ZP);
+	}
+	draw(screen, screen->r, view, nil, ZP);
+	draw(screen, liner, col[Cline], nil, ZP);
+	drawstat();
+	flushimage(display, 1);
+}
+
+void
+redrawbg(void)
+{
+	int w, x;
+	Rectangle viewr, midr;
+
+	T = nbuf / zoom / Dx(screen->r);
+	if(T == 0)
+		T = 1;
+	w = Dx(screen->r) * T * 4;
+	viewmax = bufe - w;
+	if(viewp < buf)
+		viewp = buf;
+	else if(viewp > viewmax)
+		viewp = viewmax;
+	viewe = viewp + w;
+	x = screen->r.min.x + (bufp - viewp) / 4 / T;
+	liner = screen->r;
+	liner.min.x = x;
+	liner.max.x = x + 1;
+	viewr = rectsubpt(screen->r, screen->r.min);
+	freeimage(viewbg);
+	freeimage(view);
+	viewbg = eallocimage(viewr, 0, DBlack);
+	view = eallocimage(viewr, 0, DBlack);
+	if(stereo){
+		midr = viewr;
+		midr.min.y = midr.max.y / 2;
+		midr.max.y = midr.min.y + 1;
+		draw(viewbg, midr, col[Csamp], nil, ZP);
+		statp = Pt(screen->r.min.x,
+			screen->r.min.y + (Dy(screen->r) - font->height) / 2 + 1);
+	}else
+		statp = Pt(screen->r.min.x, screen->r.max.y - font->height);
+	drawsamps();
+	drawview();
+}
+
+void
+initview(void)
+{
+	if(initdraw(nil, nil, "pplay") < 0)
+		sysfatal("initdraw: %r");
+	col[Cbg] = display->black;
+	col[Csamp] = eallocimage(Rect(0,0,1,1), 1, 0x440000FF);
+	col[Cline] = eallocimage(Rect(0,0,1,1), 1, 0x884400FF);
+	col[Cloop] = eallocimage(Rect(0,0,1,1), 1, 0x777777FF);
+	redrawbg();
+}
--- /dev/null
+++ b/edit.c
@@ -1,0 +1,26 @@
+#include <u.h>
+#include <libc.h>
+#include "dat.h"
+#include "fns.h"
+
+void
+writepcm(char *path)
+{
+	int n, fd, sz;
+	uchar *p;
+
+	if((fd = create(path, OWRITE, 0664)) < 0){
+		fprint(2, "create: %r\n");
+		return;
+	}
+	if((sz = iounit(fd)) == 0)
+		sz = 8192;
+	for(p=loops; p<loope; p+=sz){
+		n = loope - p < sz ? loope - p : sz;
+		if(write(fd, p, n) != n){
+			fprint(2, "write: %r\n");
+			break;
+		}
+	}
+	close(fd);
+}
--- /dev/null
+++ b/fns.h
@@ -1,0 +1,5 @@
+void	writepcm(char*);
+void	update(void);
+void	drawview(void);
+void	redrawbg(void);
+void	initview(void);
--- a/mkfile
+++ b/mkfile
@@ -1,6 +1,10 @@
 </$objtype/mkfile
 BIN=$home/bin/$objtype
 TARG=pplay
-OFILES=pplay.$O
+OFILES=\
+	draw.$O\
+	edit.$O\
+	pplay.$O\
+
 HFILES=
 </sys/src/cmd/mkone
--- a/pplay.c
+++ b/pplay.c
@@ -4,66 +4,28 @@
 #include <draw.h>
 #include <mouse.h>
 #include <keyboard.h>
+#include "dat.h"
+#include "fns.h"
 
 enum{
 	Ndelay = 44100 / 25,
 	Nchunk = Ndelay * 4,
-
-	Cbg = 0,
-	Csamp,
-	Cline,
-	Cloop,
-	Ncol
+	Nreadsz = 4*1024*1024,
 };
 
-int cat;
-int T, stereo, zoom = 1;
-Rectangle liner;
-Point statp;
 ulong nbuf;
 uchar *buf, *bufp, *bufe, *viewp, *viewe, *viewmax, *loops, *loope;
-Image *viewbg, *view, *col[Ncol], *disp;
-Keyboardctl *kc;
-Mousectl *mc;
-QLock lck;
+int T;
+int stereo;
+int zoom = 1;
 
-Image *
-eallocimage(Rectangle r, int repl, ulong col)
-{
-	Image *i;
+static Keyboardctl *kc;
+static Mousectl *mc;
+static QLock lck;
+static int pause;
+static int cat;
 
-	if((i = allocimage(display, r, screen->chan, repl, col)) == nil)
-		sysfatal("allocimage: %r");
-	return i;
-}
-
-void
-drawstat(void)
-{
-	char s[64];
-
-	snprint(s, sizeof s, "T %d p %zd", T, bufp-buf);
-	string(screen, statp, col[Cline], ZP, font, s);
-}
-
-void
-update(void)
-{
-	int x;
-
-	x = screen->r.min.x + (bufp - viewp) / 4 / T;
-	if(liner.min.x == x || bufp < viewp && x > liner.min.x)
-		return;
-	draw(screen, screen->r, view, nil, ZP);
-	liner.min.x = x;
-	liner.max.x = x + 1;
-	if(bufp >= viewp)
-		draw(screen, liner, col[Cline], nil, ZP);
-	drawstat();
-	flushimage(display, 1);
-}
-
-void
+static void
 athread(void *)
 {
 	int n, fd;
@@ -85,149 +47,24 @@
 	close(fd);
 }
 
-void
-drawsamps(void)
+static char *
+prompt(void)
 {
-	int x, yl, yr, w, scal, lmin, lmax, rmin, rmax;
-	short s;
-	uchar *p, *e;
-	Rectangle l, r;
+	int n;
+	static char buf[256];
 
-	w = T * 4;
-	p = viewp;
-	x = 0;
-	yl = viewbg->r.max.y / (stereo ? 4 : 2);
-	yr = viewbg->r.max.y - yl;
-	scal = 32767 / yl;
-	while(p < viewe){
-		e = p + w;
-		if(e > viewe)
-			e = viewe;
-		lmin = lmax = 0;
-		rmin = rmax = 0;
-		while(p < e){
-			s = (short)(p[1] << 8 | p[0]);
-			if(s < lmin)
-				lmin = s;
-			else if(s > lmax)
-				lmax = s;
-			if(stereo){
-				s = (short)(p[3] << 8 | p[2]);
-				if(s < rmin)
-					rmin = s;
-				else if(s > rmax)
-					rmax = s;
-			}
-			p += 4;
-		}
-		l = Rect(x, yl - lmax / scal, x+1, yl - lmin / scal);
-		draw(viewbg, l, col[Csamp], nil, ZP);
-		if(stereo){
-			r = Rect(x, yr - rmax / scal, x+1, yr - rmin / scal);
-			draw(viewbg, r, col[Csamp], nil, ZP);
-		}
-		x++;
-	}
-}
-
-void
-drawview(void)
-{
-	int x;
-	Rectangle r;
-
-	draw(view, view->r, viewbg, nil, ZP);
-	if(loops != buf && loops >= viewp){
-		x = (loops - viewp) / 4 / T;
-		r = view->r;
-		r.min.x += x;
-		r.max.x = r.min.x + 1;
-		draw(view, r, col[Cloop], nil, ZP);
-	}
-	if(loope != bufe && loope >= viewp){
-		x = (loope - viewp) / 4 / T;
-		r = view->r;
-		r.min.x += x;
-		r.max.x = r.min.x + 1;
-		draw(view, r, col[Cloop], nil, ZP);
-	}
-	draw(screen, screen->r, view, nil, ZP);
-	draw(screen, liner, col[Cline], nil, ZP);
-	drawstat();
-	flushimage(display, 1);
-}
-
-void
-redrawbg(void)
-{
-	int w, x;
-	Rectangle viewr, midr;
-
-	T = nbuf / zoom / Dx(screen->r);
-	if(T == 0)
-		T = 1;
-	w = Dx(screen->r) * T * 4;
-	viewmax = bufe - w;
-	if(viewp < buf)
-		viewp = buf;
-	else if(viewp > viewmax)
-		viewp = viewmax;
-	viewe = viewp + w;
-	x = screen->r.min.x + (bufp - viewp) / 4 / T;
-	liner = screen->r;
-	liner.min.x = x;
-	liner.max.x = x + 1;
-	viewr = rectsubpt(screen->r, screen->r.min);
-	freeimage(viewbg);
-	freeimage(view);
-	viewbg = eallocimage(viewr, 0, DBlack);
-	view = eallocimage(viewr, 0, DBlack);
-	if(stereo){
-		midr = viewr;
-		midr.min.y = midr.max.y / 2;
-		midr.max.y = midr.min.y + 1;
-		draw(viewbg, midr, col[Csamp], nil, ZP);
-		statp = Pt(screen->r.min.x,
-			screen->r.min.y + (Dy(screen->r) - font->height) / 2 + 1);
-	}else
-		statp = Pt(screen->r.min.x, screen->r.max.y - font->height);
-	drawsamps();
-	drawview();
-}
-
-void
-writepcm(int pause)
-{
-	int fd, n, sz;
-	char path[256];
-	uchar *p;
-
-	memset(path, 0, sizeof path);
+	memset(buf, 0, sizeof buf);
 	if(!pause)
 		qlock(&lck);
-	n = enter("path:", path, sizeof(path)-UTFmax, mc, kc, nil);
+	n = enter("path:", buf, sizeof(buf)-UTFmax, mc, kc, nil);
 	if(!pause)
 		qunlock(&lck);
 	if(n < 0)
-		return;
-	if((fd = create(path, OWRITE, 0664)) < 0){
-		fprint(2, "create: %r\n");
-		return;
-	}
-	if((sz = iounit(fd)) == 0)
-		sz = 8192;
-	for(p=loops; p<loope; p+=sz){
-		n = loope - p < sz ? loope - p : sz;
-		if(write(fd, p, n) != n){
-			fprint(2, "write: %r\n");
-			goto end;
-		}
-	}
-end:
-	close(fd);
+		return nil;
+	return buf;
 }
 
-void
+static void
 setzoom(int n)
 {
 	int m;
@@ -240,7 +77,7 @@
 		redrawbg();
 }
 
-void
+static void
 setpan(int n)
 {
 	n *= T * 4 * 16;
@@ -250,7 +87,7 @@
 	redrawbg();
 }
 
-void
+static void
 setloop(void)
 {
 	int n;
@@ -267,7 +104,7 @@
 	drawview();
 }
 
-void
+static void
 setpos(void)
 {
 	int n;
@@ -281,7 +118,7 @@
 	update();
 }
 
-void
+static void
 bufrealloc(ulong n)
 {
 	int off;
@@ -293,7 +130,25 @@
 	bufp = buf + off;
 }
 
-void
+static void
+initbuf(int fd)
+{
+	int n, sz;
+
+	bufrealloc(nbuf += Nreadsz);
+	if((sz = iounit(fd)) == 0)
+		sz = 8192;
+	while((n = read(fd, bufp, sz)) > 0){
+		bufp += n;
+		if(bufp + sz >= bufe)
+			bufrealloc(nbuf += Nreadsz);
+	}
+	if(n < 0)
+		sysfatal("read: %r");
+	bufrealloc(nbuf = bufp - buf);
+}
+
+static void
 usage(void)
 {
 	fprint(2, "usage: %s [-cs] [pcm]\n", argv0);
@@ -303,7 +158,8 @@
 void
 threadmain(int argc, char **argv)
 {
-	int n, sz, fd, pause;
+	int fd;
+	char *p;
 	Mouse mo;
 	Rune r;
 
@@ -314,35 +170,18 @@
 	}ARGEND
 	if((fd = *argv != nil ? open(*argv, OREAD) : 0) < 0)
 		sysfatal("open: %r");
-	if(sz = iounit(fd), sz == 0)
-		sz = 8192;
-	bufrealloc(nbuf += 4*1024*1024);
-	while((n = read(fd, bufp, sz)) > 0){
-		bufp += n;
-		if(bufp + sz >= bufe)
-			bufrealloc(nbuf += 4*1024*1024);
-	}
-	if(n < 0)
-		sysfatal("read: %r");
+	initbuf(fd);
 	close(fd);
-	bufrealloc(nbuf = bufp - buf);
 	nbuf /= 4;
 	bufp = buf;
-	if(initdraw(nil, nil, "pplay") < 0)
-		sysfatal("initdraw: %r");
-	if(kc = initkeyboard(nil), kc == nil)
-		sysfatal("initkeyboard: %r");
-	if(mc = initmouse(nil, screen), mc == nil)
-		sysfatal("initmouse: %r");
-	col[Cbg] = display->black;
-	col[Csamp] = eallocimage(Rect(0,0,1,1), 1, 0x440000FF);
-	col[Cline] = eallocimage(Rect(0,0,1,1), 1, 0x884400FF);
-	col[Cloop] = eallocimage(Rect(0,0,1,1), 1, 0x777777FF);
 	viewp = buf;
 	loops = buf;
 	loope = bufe;
-	redrawbg();
-	pause = 0;
+	initview();
+	if((kc = initkeyboard(nil)) == nil)
+		sysfatal("initkeyboard: %r");
+	if((mc = initmouse(nil, screen)) == nil)
+		sysfatal("initmouse: %r");
 	Alt a[] = {
 		{mc->resizec, nil, CHANRCV},
 		{mc->c, &mc->Mouse, CHANRCV},
@@ -385,7 +224,10 @@
 			case '-': setzoom(-1); break;
 			case '=':
 			case '+': setzoom(1); break;
-			case 'w': writepcm(pause); break;
+			case 'w':
+				if((p = prompt()) != nil)
+					writepcm(p);
+				break;
 			}
 			break;
 		}