summaryrefslogtreecommitdiff
path: root/appl/cmd/wav2iaf.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/wav2iaf.b')
-rw-r--r--appl/cmd/wav2iaf.b171
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();
+}