version 1.10, 2005/01/13 19:19:44 |
version 1.11, 2005/01/20 04:21:42 |
|
|
#include <unistd.h> |
#include <unistd.h> |
#include <err.h> |
#include <err.h> |
|
|
|
#define _PATH_AUDIO "/dev/audio" |
|
|
/* |
/* |
* aucat: concatenate and play Sun 8-bit .au files |
* aucat: concatenate and play Sun 8-bit .au files |
*/ |
*/ |
|
|
int playfile(int, char *); |
int playfile(int, char *); |
|
void usage(void) __attribute__((__noreturn__)); |
|
|
/* function playfile: given a file which is positioned at the beginning |
/* |
|
* function playfile: given a file which is positioned at the beginning |
* of what is assumed to be an .au data stream copy it out to the audio |
* of what is assumed to be an .au data stream copy it out to the audio |
* device. Return 0 on success, -1 on failure. |
* device. Return 0 on success, -1 on failure. |
*/ |
*/ |
|
|
playfile(int fd, char *dev) |
playfile(int fd, char *dev) |
{ |
{ |
static int afd = -1; |
static int afd = -1; |
int rd; |
ssize_t rd; |
char buf[5120]; |
char buf[5120]; |
|
|
if (afd == -1 && (afd = open(dev, O_WRONLY)) < 0) { |
if (afd == -1 && (afd = open(dev, O_WRONLY)) < 0) { |
warn("can't open %s", dev); |
warn("can't open %s", dev); |
return(-1); |
return(-1); |
} |
} |
while ((rd = read(fd, buf, sizeof(buf))) > 0) { |
while ((rd = read(fd, buf, sizeof(buf))) > 0) |
write(afd, buf, rd); |
if (write(afd, buf, rd) != rd) |
if (rd < sizeof(buf)) |
warn("write"); |
break; |
if (rd == -1) |
} |
warn("read"); |
|
|
return (0); |
return (0); |
} |
} |
|
|
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
{ |
{ |
int fd, ch; |
int fd, ch; |
unsigned long data; |
u_int32_t data; |
char magic[5]; |
char magic[4]; |
char *dev; |
char *dev; |
|
|
dev = getenv("AUDIODEVICE"); |
dev = getenv("AUDIODEVICE"); |
if (dev == 0) |
if (dev == NULL) |
dev = "/dev/audio"; |
dev = _PATH_AUDIO; |
|
|
while ((ch = getopt(argc, argv, "f:")) != -1) { |
while ((ch = getopt(argc, argv, "f:")) != -1) { |
switch(ch) { |
switch (ch) { |
case 'f': |
case 'f': |
dev = optarg; |
dev = optarg; |
break; |
break; |
|
default: |
|
usage(); |
|
/* NOTREACHED */ |
} |
} |
} |
} |
argc -= optind; |
argc -= optind; |
argv += optind; |
argv += optind; |
|
|
|
if (argc == 0) |
|
usage(); |
while (argc) { |
while (argc) { |
if ((fd = open(*argv, O_RDONLY)) < 0) |
if ((fd = open(*argv, O_RDONLY)) < 0) |
err(1, "cannot open %s", *argv); |
err(1, "cannot open %s", *argv); |
|
|
read(fd, magic, 4); |
if (read(fd, magic, sizeof(magic)) != sizeof(magic) || |
magic[4] = '\0'; |
strncmp(magic, ".snd", 4)) { |
if (strcmp(magic, ".snd")) { |
|
/* |
/* |
* not an .au file, bad header. |
* not an .au file, bad header. |
* Assume raw audio data since that's |
* Assume raw audio data since that's |
* what /dev/audio generates by default. |
* what /dev/audio generates by default. |
*/ |
*/ |
lseek(fd, 0, SEEK_SET); |
if (lseek(fd, 0, SEEK_SET) == -1) |
|
warn("lseek"); |
} else { |
} else { |
read(fd, &data, sizeof(data)); |
if (read(fd, &data, sizeof(data)) == sizeof(data)) { |
data = ntohl(data); |
data = ntohl(data); |
lseek(fd, (off_t)data, SEEK_SET); |
if (lseek(fd, (off_t)data, SEEK_SET) == -1) |
|
warn("lseek"); |
|
} |
} |
} |
if (playfile(fd, dev) < 0) |
if (playfile(fd, dev) < 0) |
exit(1); |
exit(1); |
|
|
argv++; |
argv++; |
} |
} |
exit(0); |
exit(0); |
|
} |
|
|
|
void |
|
usage(void) |
|
{ |
|
extern char *__progname; |
|
|
|
fprintf(stderr, "usage: %s [-f device] file ...\n", __progname); |
|
exit(1); |
} |
} |