shithub: pplay

Download patch

ref: 8cac775c460cd32ffa82a756e6c7e6dc6d7fda51
parent: c7d5348ddbb3bdb6358c153795bb4c0e18af1375
author: qwx <qwx@sciops.net>
date: Wed Nov 30 00:52:00 EST 2022

add zooming into a range

--- a/dat.h
+++ b/dat.h
@@ -28,7 +28,6 @@
 extern usize totalsz;
 
 extern int stereo;
-extern int zoom;
 extern int debug;
 
 #define MIN(x,y)	((x) < (y) ? (x) : (y))
--- a/draw.c
+++ b/draw.c
@@ -26,6 +26,7 @@
 static uchar *sbuf;
 static usize sbufsz;
 static int sampwidth = 1;
+static double zoom = 1.0;
 
 static Image *
 eallocimage(Rectangle r, int repl, ulong col)
@@ -220,22 +221,46 @@
 }
 
 void
-setzoom(int Δz, int pow)
+setzoom(int Δz, int mul)
 {
-	int z;
+	double z;
 
-	if(!pow)
+	if(!mul)
 		z = zoom + Δz;
 	else if(Δz < 0)
-		z = zoom >> -Δz;
+		z = zoom / pow(2, -Δz);
 	else
-		z = zoom << Δz;
-	if(z < 1 || z > (totalsz / 4) / Dx(screen->r))
+		z = zoom * pow(2, Δz);
+	if(z < 1.0 || z > (totalsz / Sampsz) / Dx(screen->r))
 		return;
 	zoom = z;
 	redraw(0);
 }
 
+int
+zoominto(vlong from, vlong to)
+{
+	if(dot.from.pos == 0 && dot.to.pos == totalsz){
+		fprint(2, "not a range\n");
+		return -1;
+	}
+	if(from < 0)
+		from = 0;
+	from &= ~3;
+	if(to >= totalsz)
+		to = totalsz;
+	to &= ~3;
+	if((to - from) / Sampsz < Dx(screen->r)){
+		werrstr("range too small");
+		return -1;
+	}
+	views = from;
+	viewe = to;
+	zoom = (double)totalsz / (to - from);
+	redraw(0);
+	return 0;
+}
+
 void
 setpan(int Δx)
 {
@@ -326,7 +351,7 @@
 	usize span;
 
 	lockdisplay(display);
-	T = totalsz / zoom / Dx(screen->r) & ~3;
+	T = (vlong)(totalsz / zoom / Dx(screen->r)) & ~3;
 	if(T == 0)
 		T = 4;
 	span = Dx(screen->r) * T;
--- a/fns.h
+++ b/fns.h
@@ -2,6 +2,7 @@
 void	initcmd(void);
 void	update(void);
 void	setzoom(int, int);
+int	zoominto(vlong, vlong);
 void	setpan(int);
 void	setloop(vlong);
 void	setofs(usize);
--- a/pplay.c
+++ b/pplay.c
@@ -9,7 +9,7 @@
 
 extern QLock lsync;
 
-int stereo, zoom = 1;
+int stereo;
 int debug;
 
 static Keyboardctl *kc;
@@ -140,12 +140,13 @@
 			break;
 		case 2:
 			switch(r){
+			case Kdel:
+			case 'q': threadexitsall(nil);
 			case ' ': toggleplay(); break;
 			case 'b': setjump(dot.from.pos); break;
 			case Kesc: setrange(0, totalsz); update(); break;
-			case Kdel:
-			case 'q': threadexitsall(nil);
-			case 'z': setzoom(-zoom + 1, 0); break;
+			case '\n': zoominto(dot.from.pos, dot.to.pos); break;
+			case 'z': zoominto(0, totalsz); break;
 			case '-': setzoom(-1, 0); break;
 			case '=': setzoom(1, 0); break;
 			case '_': setzoom(-1, 1); break;