diff options
Diffstat (limited to 'usr.bin/aucat/wav.c')
-rw-r--r-- | usr.bin/aucat/wav.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/usr.bin/aucat/wav.c b/usr.bin/aucat/wav.c new file mode 100644 index 00000000000..ae85e809f13 --- /dev/null +++ b/usr.bin/aucat/wav.c @@ -0,0 +1,116 @@ +#include <sys/types.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "conf.h" +#include "wav.h" + +/* + * max data of a .wav file. The total file size must be smaller than + * 2^31, and we also have to leave some space for the headers (around 40 + * bytes) + */ +#define WAV_DATAMAX (0x7fff0000) + +struct fileops wav_ops = { + "wav", + sizeof(struct wav), + wav_close, + wav_read, + wav_write, + NULL, /* start */ + NULL, /* stop */ + pipe_nfds, + pipe_pollfd, + pipe_revents +}; + +struct wav * +wav_new_in(struct fileops *ops, int fd, char *name, + struct aparams *par, unsigned hdr) +{ + struct wav *f; + + f = (struct wav *)pipe_new(ops, fd, name); + if (hdr == HDR_WAV) { + if (!wav_readhdr(f->pipe.fd, par, &f->rbytes)) + exit(1); + f->hpar = *par; + } else + f->rbytes = -1; + f->hdr = 0; + return f; +} + +struct wav * +wav_new_out(struct fileops *ops, int fd, char *name, + struct aparams *par, unsigned hdr) +{ + struct wav *f; + + f = (struct wav *)pipe_new(ops, fd, name); + if (hdr == HDR_WAV) { + if (!wav_writehdr(f->pipe.fd, par)) + exit(1); + f->hpar = *par; + f->wbytes = WAV_DATAMAX; + } else + f->wbytes = -1; + f->hdr = hdr; + return f; +} + +unsigned +wav_read(struct file *file, unsigned char *data, unsigned count) +{ + struct wav *f = (struct wav *)file; + unsigned n; + + if (f->rbytes >= 0 && count > f->rbytes) { + count = f->rbytes; /* file->rbytes fits in count */ + if (count == 0) { + DPRINTFN(2, "wav_read: %s: complete\n", f->pipe.file.name); + file_eof(&f->pipe.file); + return 0; + } + } + n = pipe_read(file, data, count); + if (f->rbytes >= 0) + f->rbytes -= n; + return n; +} + + +unsigned +wav_write(struct file *file, unsigned char *data, unsigned count) +{ + struct wav *f = (struct wav *)file; + unsigned n; + + if (f->wbytes >= 0 && count > f->wbytes) { + count = f->wbytes; /* wbytes fits in count */ + if (count == 0) { + DPRINTFN(2, "wav_write: %s: complete\n", + f->pipe.file.name); + file_hup(&f->pipe.file); + return 0; + } + } + n = pipe_write(file, data, count); + if (f->wbytes >= 0) + f->wbytes -= n; + return n; +} + +void +wav_close(struct file *file) +{ + struct wav *f = (struct wav *)file; + + if (f->hdr == HDR_WAV) + wav_writehdr(f->pipe.fd, &f->hpar); + pipe_close(file); +} |