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;
}