ref: 7fb266c8b5f73defd884c57ec1742d28ef5f6404
parent: 1645178866a8901a120769199de27bb6f458b82e
author: qwx <[email protected]>
date: Sat Oct 29 17:59:51 EDT 2022
decouple sample drawing from playback
--- a/draw.c
+++ b/draw.c
@@ -1,5 +1,6 @@
#include <u.h>
#include <libc.h>
+#include <thread.h>
#include <draw.h>
#include "dat.h"
#include "fns.h"
@@ -14,12 +15,10 @@
static Image *viewbg, *view;
static Rectangle liner;
static Point statp;
-static vlong views, viewe, viewmax, bgofs;
+static vlong views, viewe, viewmax;
static int bgscalyl, bgscalyr, bgscalf;
-static uchar bgbuf[Nchunk * 200];
+static Channel *drawc;
-static void (*drawbg)(void);
-
static Image *
eallocimage(Rectangle r, int repl, ulong col)
{
@@ -31,7 +30,7 @@
}
static void
-drawsamps(void)
+drawsamps(void*)
{
int x, n, lmin, lmax, rmin, rmax;
s16int s;
@@ -38,54 +37,56 @@
uchar *p, *e, *et;
Rectangle l, r;
- if(bgofs >= viewe)
- return;
- n = viewe - bgofs;
- if(n > sizeof bgbuf)
- n = sizeof bgbuf;
- if(n > T)
- n -= n % T;
- if(!file)
- p = pcmbuf + bgofs;
- else{
- seek(ifd, bgofs, 0);
- n = read(ifd, bgbuf, n);
- seek(ifd, seekp, 0);
- p = bgbuf;
- }
- e = p + n;
- x = (bgofs - views) / T;
- while(p < e){
- n = T;
- if(n > e - p)
- n -= n - (e - p);
- bgofs += n;
- et = p + n;
- lmin = lmax = 0;
- rmin = rmax = 0;
- while(p < et){
- s = (s16int)(p[1] << 8 | p[0]);
- if(s < lmin)
- lmin = s;
- else if(s > lmax)
- lmax = s;
- if(stereo){
- s = (s16int)(p[3] << 8 | p[2]);
- if(s < rmin)
- rmin = s;
- else if(s > rmax)
- rmax = s;
+ for(;;){
+ recvul(drawc);
+ lockdisplay(display);
+again:
+ draw(viewbg, viewbg->r, display->black, nil, ZP);
+ n = viewe - views;
+ if(!file)
+ p = pcmbuf + views;
+ else{
+ seek(ifd, bgofs, 0);
+ n = read(ifd, bgbuf, n);
+ seek(ifd, seekp, 0);
+ p = bgbuf;
+ }
+ e = p + n;
+ x = 0;
+ while(p < e){
+ if(nbrecvul(drawc) == 1)
+ goto again;
+ n = T;
+ if(n > e - p)
+ n -= n - (e - p);
+ et = p + n;
+ lmin = lmax = 0;
+ rmin = rmax = 0;
+ while(p < et){
+ s = (s16int)(p[1] << 8 | p[0]);
+ if(s < lmin)
+ lmin = s;
+ else if(s > lmax)
+ lmax = s;
+ if(stereo){
+ s = (s16int)(p[3] << 8 | p[2]);
+ if(s < rmin)
+ rmin = s;
+ else if(s > rmax)
+ rmax = s;
+ }
+ p += 4;
}
- p += 4;
+ l = Rect(x, bgscalyl - lmax / bgscalf,
+ x+1, bgscalyl - lmin / bgscalf);
+ r = Rect(x, bgscalyr - rmax / bgscalf,
+ x+1, bgscalyr - rmin / bgscalf);
+ draw(viewbg, l, col[Csamp], nil, ZP);
+ if(stereo)
+ draw(viewbg, r, col[Csamp], nil, ZP);
+ x++;
}
- l = Rect(x, bgscalyl - lmax / bgscalf,
- x+1, bgscalyl - lmin / bgscalf);
- r = Rect(x, bgscalyr - rmax / bgscalf,
- x+1, bgscalyr - rmin / bgscalf);
- draw(viewbg, l, col[Csamp], nil, ZP);
- if(stereo)
- draw(viewbg, r, col[Csamp], nil, ZP);
- x++;
+ unlockdisplay(display);
}
}
@@ -160,7 +161,7 @@
{
int x;
- drawbg();
+ lockdisplay(display);
drawview();
x = screen->r.min.x + (seekp - views) / T;
//if(liner.min.x == x || seekp < views && x > liner.min.x)
@@ -172,6 +173,7 @@
draw(screen, liner, col[Cline], nil, ZP);
drawstat();
flushimage(display, 1);
+ unlockdisplay(display);
}
void
@@ -266,6 +268,7 @@
{
vlong span;
+ lockdisplay(display);
T = filesz / zoom / Dx(screen->r) & ~3;
if(T == 0)
T = 4;
@@ -276,10 +279,10 @@
else if(views > viewmax)
views = viewmax;
viewe = views + span;
- bgofs = views;
if(all)
resetdraw();
- draw(viewbg, viewbg->r, display->black, nil, ZP);
+ unlockdisplay(display);
+ nbsendul(drawc, 1);
update();
}
@@ -288,10 +291,15 @@
{
if(initdraw(nil, nil, "pplay") < 0)
sysfatal("initdraw: %r");
+ display->locking = 1;
+ unlockdisplay(display);
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);
- drawbg = drawsamps;
loope = filesz;
+ if((drawc = chancreate(sizeof(ulong), 0)) == nil)
+ sysfatal("chancreate: %r");
+ if(proccreate(drawsamps, nil, mainstacksize) < 0)
+ sysfatal("proccreate: %r");
redraw(1);
}