diff options
Diffstat (limited to 'appl/cmd/auplay.b')
| -rw-r--r-- | appl/cmd/auplay.b | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/appl/cmd/auplay.b b/appl/cmd/auplay.b new file mode 100644 index 00000000..0be6f556 --- /dev/null +++ b/appl/cmd/auplay.b @@ -0,0 +1,114 @@ +implement AuPlay; + +include "sys.m"; +include "draw.m"; + +sys: Sys; +FD: import sys; +stderr: ref FD; + +include "string.m"; + +str: String; + +prog: string; +play: int; +Magic: con "rate"; +data: con "/dev/audio"; +ctl: con "/dev/audioctl"; +buffz: con Sys->ATOMICIO; + +AuPlay: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +process(f: string) +{ + buff := array[buffz] of byte; + inf := sys->open(f, Sys->OREAD); + if (inf == nil) { + sys->fprint(stderr, "%s: could not open %s: %r\n", prog, f); + return; + } + n := sys->read(inf, buff, buffz); + if (n < 0) { + sys->fprint(stderr, "%s: could not read %s: %r\n", prog, f); + return; + } + if (n < 10 || string buff[0:4] != Magic) { + sys->fprint(stderr, "%s: %s: not an audio file\n", prog, f); + return; + } + i := 0; + for (;;) { + if (i == n) { + sys->fprint(stderr, "%s: %s: bad header\n", prog, f); + return; + } + if (buff[i] == byte '\n') { + i++; + if (i == n) { + sys->fprint(stderr, "%s: %s: bad header\n", prog, f); + return; + } + if (buff[i] == byte '\n') { + i++; + if ((i % 4) != 0) { + sys->fprint(stderr, "%s: %s: unpadded header\n", prog, f); + return; + } + break; + } + } + else + i++; + } + if (!play) { + sys->write(stderr, buff, i - 1); + return; + } + df := sys->open(data, Sys->OWRITE); + if (df == nil) { + sys->fprint(stderr, "%s: could not open %s: %r\n", prog, data); + return; + } + cf := sys->open(ctl, Sys->OWRITE); + if (cf == nil) { + sys->fprint(stderr, "%s: could not open %s: %r\n", prog, ctl); + return; + } + if (sys->write(cf, buff, i - 1) < 0) { + sys->fprint(stderr, "%s: could not write %s: %r\n", prog, ctl); + return; + } + if (n > i && sys->write(df, buff[i:n], n - i) < 0) { + sys->fprint(stderr, "%s: could not write %s: %r\n", prog, data); + return; + } + if (sys->stream(inf, df, Sys->ATOMICIO) < 0) { + sys->fprint(stderr, "%s: could not stream %s: %r\n", prog, data); + return; + } +} + +init(nil: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + str = load String String->PATH; + stderr = sys->fildes(2); + p := hd argv; + v := tl argv; + (nil, b) := str->splitr(p, "/"); + if (b != nil) + p = b; + (b, nil) = str->splitr(p, "."); + if (b != nil) + p = b[0:len b - 1]; + prog = p; + play = prog == "auplay"; + while (v != nil) { + process(hd v); + v = tl v; + } +} |
