ref: f87b680a865536dafad94ed9e08e62970519450b
parent: c923daa68daae862ccdd638cbb9e255c609b09de
author: qwx <qwx@sciops.net>
date: Wed Jul 26 00:24:26 EDT 2023
pcmmix: truncate to shortest buffer; heuristic for stdin bleh necessary for easy single track editing in pplay
--- a/pcmmix.c
+++ b/pcmmix.c
@@ -1,17 +1,22 @@
#include <u.h>
#include <libc.h>
+enum{
+ Bufsz = 8192,
+};
+
typedef struct File File;
struct File{
int fd;
char *path;
int n;
- uchar buf[8192];
+ int Δ;
+ uchar buf[Bufsz];
};
void
usage(void)
{
- fprint(2, "usage: %s [-f factor] [FILE..]\n", argv0);
+ fprint(2, "usage: %s [-t] [-f factor] [FILE..]\n", argv0);
exits("usage");
}
@@ -18,17 +23,19 @@
void
main(int argc, char **argv)
{
- int n;
+ int n, m, notrunc, gotem;
double f;
- uchar u[8192], *p, *q;
+ File *ftab, *fp;
+ uchar u[Bufsz], *p, *q;
s32int v;
int nf;
- File *ftab, *fp;
Dir *d;
+ notrunc = 0;
f = 1.0;
ARGBEGIN{
case 'f': f = strtod(EARGF(usage()), nil); break;
+ case 't': notrunc = 1; break;
default: usage();
}ARGEND
nf = argc + 1;
@@ -35,34 +42,56 @@
if((ftab = mallocz(nf * sizeof *ftab, 1)) == nil)
sysfatal("mallocz: %r");
fp = ftab;
- fp->path = "stdin";
- if(nf > 1){
- if((d = dirfstat(0)) == nil)
- sysfatal("dirfstat: %r");
- fp->fd = d->length > 0 ? 0 : -1;
- free(d);
- }
- fp++;
+ (fp++)->path = "stdin";
while(*argv != nil){
if((fp->fd = open(*argv, OREAD)) < 0)
sysfatal("open: %r");
- fp->path = *argv++;
- fp++;
+ (fp++)->path = *argv++;
}
+ gotem = 0;
for(;;){
n = 0;
for(fp=ftab; fp<ftab+nf; fp++){
if(fp->fd < 0)
continue;
- if((fp->n = read(fp->fd, fp->buf, sizeof fp->buf)) > 0)
+ if(fp == ftab){
+ if((d = dirfstat(0)) == nil)
+ sysfatal("dirfstat: %r");
+ m = d->length;
+ free(d);
+ if(m > 0)
+ gotem = 1;
+ else if(gotem){
+ if(!notrunc)
+ exits(nil);
+ fp->fd = -1;
+ continue;
+ }
+ }
+ m = sizeof fp->buf - fp->Δ;
+ if(m < 0)
+ m = sizeof fp->buf;
+ if(n > 0 && n < m)
+ m = n;
+ fp->n = read(fp->fd, fp->buf+fp->Δ, m);
+ if(n == 0 || notrunc && n < fp->n || !notrunc && n > fp->n)
+ n = fp->n;
+ fprint(2, "%zd n %d fp->n %d Δ %d\n", fp-ftab, n, fp->n, fp->Δ);
+ if(fp->n > 0)
continue;
fp->fd = -1;
+ if(!notrunc)
+ exits(nil);
if(fp->n < 0)
fprint(2, "file %s: read: %r\n", fp->path);
}
- memset(u, 0, sizeof u);
+ if(n <= 0)
+ break;
+ memset(u, 0, n);
for(fp=ftab; fp<ftab+nf; fp++){
- for(p=u, q=fp->buf; q<fp->buf+fp->n; p+=2, q+=2){
+ if(fp->fd < 0)
+ continue;
+ for(p=u, q=fp->buf; q<fp->buf+n; p+=2, q+=2){
v = (s16int)(q[1] << 8 | q[0]);
v *= f;
v += (s16int)(p[1] << 8 | p[0]);
@@ -73,11 +102,8 @@
p[0] = v;
p[1] = v >> 8;
}
- if(fp->n > n)
- n = fp->n;
+ fp->Δ = n < fp->n ? fp->n - n : 0;
}
- if(n == 0)
- break;
write(1, u, n);
}
exits(nil);