diff options
Diffstat (limited to 'appl/cmd/wav2iaf.b')
| -rw-r--r-- | appl/cmd/wav2iaf.b | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/appl/cmd/wav2iaf.b b/appl/cmd/wav2iaf.b new file mode 100644 index 00000000..d00dc69e --- /dev/null +++ b/appl/cmd/wav2iaf.b @@ -0,0 +1,171 @@ +implement Wav2Iaf; + +include "sys.m"; +include "draw.m"; +include "bufio.m"; + +sys: Sys; +FD: import sys; +bufio: Bufio; +Iobuf: import bufio; + +stderr: ref FD; +inf: ref Iobuf; +prog: string; +buff4: array of byte; + +pad := array[] of { " ", " ", "", " " }; + +Wav2Iaf: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +ioerror() +{ + sys->fprint(stderr, "%s: read error: %r\n", prog); + exit; +} + +shortfile(diag: string) +{ + sys->fprint(stderr, "%s: short read: %s\n", prog, diag); + exit; +} + +error(s: string) +{ + sys->fprint(stderr, "%s: bad wave file: %s\n", prog, s); + exit; +} + +get(c: int, s: string) +{ + n := inf.read(buff4, c); + if (n < 0) + ioerror(); + if (n != c) + shortfile("expected " + s); +} + +gets(c: int, s: string) : string +{ + get(c, s); + return string buff4[0:c]; +} + +need(s: string) +{ + get(4, s); + if (string buff4 != s) { + sys->fprint(stderr, "%s: not a wave file\n", prog); + exit; + } +} + +getl(s: string) : int +{ + get(4, s); + return int buff4[0] + (int buff4[1] << 8) + (int buff4[2] << 16) + (int buff4[3] << 24); +} + +getw(s: string) : int +{ + get(2, s); + return int buff4[0] + (int buff4[1] << 8); +} + +skip(n: int) +{ + while (n > 0) { + inf.getc(); + n--; + } +} + +bufcp(s, d: ref Iobuf, n: int) +{ + while (n > 0) { + b := s.getb(); + if (b < 0) { + if (b == Bufio->EOF) + sys->fprint(stderr, "%s: short input file\n", prog); + else + sys->fprint(stderr, "%s: read error: %r\n", prog); + exit; + } + d.putb(byte b); + n--; + } +} + +init(nil: ref Draw->Context, argv: list of string) +{ + l: int; + a: string; + + sys = load Sys Sys->PATH; + stderr = sys->fildes(2); + prog = hd argv; + argv = tl argv; + bufio = load Bufio Bufio->PATH; + if (bufio == nil) + sys->fprint(stderr, "%s: could not load %s: %r\n", prog, Bufio->PATH); + if (argv == nil) { + inf = bufio->fopen(sys->fildes(0), Bufio->OREAD); + if (inf == nil) { + sys->fprint(stderr, "%s: could not fopen stdin: %r\n", prog); + exit; + } + } + else if (tl argv != nil) { + sys->fprint(stderr, "usage: %s [infile]\n", prog); + exit; + } + else { + inf = bufio->open(hd argv, Sys->OREAD); + if (inf == nil) { + sys->fprint(stderr, "%s: could not open %s: %r\n", prog, hd argv); + exit; + } + } + buff4 = array[4] of byte; + need("RIFF"); + getl("length"); + need("WAVE"); + for (;;) { + a = gets(4, "tag"); + l = getl("length"); + if (a == "fmt ") + break; + skip(l); + } + if (getw("format") != 1) + error("not PCM"); + chans := getw("channels"); + rate := getl("rate"); + getl("AvgBytesPerSec"); + getw("BlockAlign"); + bits := getw("bits"); + l -= 16; + do { + skip(l); + a = gets(4, "tag"); + l = getl("length"); + } + while (a != "data"); + outf := bufio->fopen(sys->fildes(1), Sys->OWRITE); + if (outf == nil) { + sys->fprint(stderr, "%s: could not fopen stdout: %r\n", prog); + exit; + } + s := "rate\t" + string rate + "\n" + + "chans\t" + string chans + "\n" + + "bits\t" + string bits + "\n" + + "enc\tpcm"; + outf.puts(s); + outf.puts(pad[len s % 4]); + outf.puts("\n\n"); + bufcp(inf, outf, l); + outf.flush(); +} |
