Subject: some gross audio tools
To: None <current-users@NetBSD.ORG>
From: John Kohl <jtk@atria.com>
List: current-users
Date: 02/23/1995 08:39:31
I've used these tools for testing recording and playback of sounds on
the new i386 SBPro driver. They might be useful to you as examples.
I used them almost exclusively with /dev/sound (for linear
recording/playback). The "stereo" argument is really a rate: positive
for one channel, negative for two channels.
==John
[1 audioplay.c (text/plain)]
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <fcntl.h>
#include <stdio.h>
#include "/sys/sys/audioio.h"
struct audio_info ainfo;
audio_device_t audevinfo;
#define SNDBUFSIZ 16384
unsigned char buf[SNDBUFSIZ];
main(int argc, char *argv[])
{
int fd, mixfd;
int cc;
int rate;
int totcount;
int i;
if (argc > 3) {
close(0);
if (open(argv[3], O_RDONLY) != 0)
errx(1, "wrong FD on opening file!\n");
}
if (argc < 2 || isatty(0))
errx(1, "usage: %s <dev> [stereo/rate] < filename", argv[0]);
fd = open(argv[1], O_WRONLY);
if (fd == -1)
err(1, "%s", argv[1]);
if (ioctl(fd, AUDIO_GETINFO, &ainfo)) err(1, "getinfo %s", argv[1]);
AUDIO_INITINFO(&ainfo);
ainfo.play.gain = AUDIO_MAX_GAIN;
ainfo.record.gain = AUDIO_MAX_GAIN;
ainfo.play.sample_rate = ainfo.record.sample_rate = 43478;
ainfo.record.pause = ~0; /* leave record alone */
ainfo.play.pause = 0; /* start up playback */
ainfo.record.channels = ainfo.play.channels = 1;
if (argc > 2) {
rate = atoi(argv[2]);
if (rate > 0) {
ainfo.record.sample_rate = ainfo.play.sample_rate = rate;
} else if (rate < 0) {
ainfo.record.sample_rate = ainfo.play.sample_rate = -rate;
ainfo.record.channels = ainfo.play.channels = 2;
}
}
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
#if 0
if (ainfo.play.sample_rate > 8000)
ainfo.blocksize = NBPG/4; /* XXX */
#endif
ainfo.blocksize = NBPG/2; /* take default */
ainfo.mode = 1 << AUMODE_PLAY;
if (ioctl(fd, AUDIO_GETDEV, &audevinfo)) err(1, "getdevinfo %s", argv[1]);
printf("device `%s' version %s config %s: play chans %d, freq %d\n",
audevinfo.name, audevinfo.version, audevinfo.config,
ainfo.play.channels,
ainfo.play.sample_rate);
mixfd = open("/dev/mixer", O_RDWR);
if (mixfd == -1)
warn("can't open mixer");
else {
mixer_ctrl_t mixinfo;
mixer_devinfo_t mixdevinfo;
for (mixdevinfo.index = 0;
ioctl(mixfd, AUDIO_MIXER_DEVINFO, &mixdevinfo) == 0;
mixdevinfo.index = mixdevinfo.next) {
printf("device index %d is `%s'\n", mixdevinfo.index,
mixdevinfo.label.name);
if (mixdevinfo.type == AUDIO_MIXER_VALUE)
mixinfo.un.value.num_channels = mixdevinfo.un.v.num_channels;
mixinfo.type = mixdevinfo.type;
mixinfo.dev = mixdevinfo.index;
if (ioctl(mixfd, AUDIO_MIXER_READ, &mixinfo)) {
warn("getmixinfo /dev/mixer");
continue;
}
switch (mixdevinfo.type) {
case AUDIO_MIXER_ENUM:
printf("enum ordinal %d\n", mixinfo.un.ord);
break;
case AUDIO_MIXER_SET:
printf("set mask %x\n", mixinfo.un.mask);
break;
case AUDIO_MIXER_VALUE:
printf("nchans %d: ", mixinfo.un.value.num_channels);
for (i = 0; i < mixinfo.un.value.num_channels; i++)
printf("%d ", mixinfo.un.value.level[i]);
putchar('\n');
break;
default:
printf("type %x\n", mixinfo.type);
}
if (strcmp(mixdevinfo.label.name, AudioNdac) == 0) {
mixinfo.un.value.level[0] =
mixinfo.un.value.level[1] = AUDIO_MAX_GAIN;
ioctl(mixfd, AUDIO_MIXER_WRITE, &mixinfo);
}
if (mixdevinfo.next == AUDIO_MIXER_LAST)
mixdevinfo.next = mixdevinfo.index + 1;
}
close(mixfd);
}
if (ioctl(fd, AUDIO_SETINFO, &ainfo)) err(1, "setinfo %s", argv[1]);
if (ioctl(fd, AUDIO_GETINFO, &ainfo)) err(1, "getinfo %s", argv[1]);
ioctl(fd, AUDIO_FLUSH, 0);
totcount = 0;
while ((cc = read(0, buf, SNDBUFSIZ)) > 0) {
totcount += write(fd, buf, cc);
fprintf(stderr, "%d\r", totcount);
}
exit(0);
}
[2 audiorecord.c (text/plain)]
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <fcntl.h>
#include "/sys/sys/audioio.h"
struct audio_info ainfo;
#define SNDBUFSIZ 16384
char buf[SNDBUFSIZ];
main(int argc, char *argv[])
{
int fd, mixfd;
int cc;
int dev = -1;
int rate;
int totcnt;
int maxcnt = 0;
if (argc > 4) {
close(1);
if (open(argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0644) != 1)
errx(1, "wrong FD on opening file!\n");
}
if (argc < 2 || isatty(1))
errx(1, "usage: %s <dev> [source] [stereo] > filename", argv[0]);
if (argc > 2) {
mixer_ctrl_t mixinfo;
mixer_devinfo_t mixdevinfo;
mixfd = open("/dev/mixer", O_RDWR);
if (mixfd == -1)
err("can't open /dev/mixer to select source");
for (mixdevinfo.index = 0;
ioctl(mixfd, AUDIO_MIXER_DEVINFO, &mixdevinfo) == 0;
mixdevinfo.index = mixdevinfo.next) {
if (mixdevinfo.type == AUDIO_MIXER_VALUE)
mixinfo.un.value.num_channels = mixdevinfo.un.v.num_channels;
if (strcmp(mixdevinfo.label.name, argv[2]) == 0) {
mixinfo.un.value.level[0] =
mixinfo.un.value.level[1] = AUDIO_MAX_GAIN;
mixinfo.type = mixdevinfo.type;
mixinfo.dev = mixdevinfo.index;
ioctl(mixfd, AUDIO_MIXER_WRITE, &mixinfo);
dev = mixinfo.dev;
}
if (strcmp(mixdevinfo.label.name, AudioNvolume) == 0) {
mixinfo.un.value.level[0] =
mixinfo.un.value.level[1] = AUDIO_MAX_GAIN;
mixinfo.type = mixdevinfo.type;
mixinfo.dev = mixdevinfo.index;
ioctl(mixfd, AUDIO_MIXER_WRITE, &mixinfo);
}
if (mixdevinfo.next == AUDIO_MIXER_LAST)
mixdevinfo.next = mixdevinfo.index + 1;
}
close(mixfd);
if (dev < 0)
errx(1, "can't find requested source device `%s'", argv[2]);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1)
err(1, "%s", argv[1]);
AUDIO_INITINFO(&ainfo);
ainfo.play.gain = AUDIO_MAX_GAIN;
ainfo.record.gain = AUDIO_MAX_GAIN;
ainfo.play.pause = ~0; /* leave pause alone */
ainfo.record.pause = 0; /* start recording */
if (dev >= 0)
ainfo.record.port = dev;
if (argc > 3) {
rate = atoi(argv[3]);
if (rate < 0) {
/* stereo */
ainfo.record.sample_rate = ainfo.play.sample_rate = -rate;
ainfo.record.channels = ainfo.play.channels = 2;
} else if (rate > 0) {
ainfo.record.sample_rate = ainfo.play.sample_rate = rate;
ainfo.record.channels = ainfo.play.channels = 1;
} else {
ainfo.record.channels = ainfo.play.channels = 2;
ainfo.record.sample_rate = ainfo.play.sample_rate = 22222;
}
} else {
ainfo.record.channels = ainfo.play.channels = 1;
ainfo.record.sample_rate = ainfo.play.sample_rate = 43478;
}
#if 0
if (ainfo.record.sample_rate > 8000)
ainfo.blocksize = NBPG/4; /* XXX */
#endif
ainfo.blocksize = NBPG/2;
ainfo.record.encoding = AUDIO_ENCODING_LINEAR;
/* ainfo.monitor_gain = AUDIO_MAX_GAIN;*/
ainfo.mode = 1 << AUMODE_RECORD;
if (ioctl(fd, AUDIO_SETINFO, &ainfo)) err(1, "setinfo %s", argv[1]);
if (ioctl(fd, AUDIO_GETINFO, &ainfo)) err(1, "getinfo %s", argv[1]);
fprintf(stderr, "record freq %d, chans %d\n", ainfo.record.sample_rate,
ainfo.record.channels);
if (argc > 5) {
maxcnt = atoi(argv[5]);
maxcnt *= ainfo.record.channels;
maxcnt *= ainfo.record.sample_rate;
maxcnt *= ainfo.record.precision / NBBY;
}
totcnt = 0;
ioctl(fd, AUDIO_FLUSH, 0);
while ((cc = read(fd, buf, SNDBUFSIZ)) > 0) {
totcnt += write(1, buf, cc);
fprintf(stderr, "%d\r", totcnt);
if (maxcnt && totcnt >= maxcnt)
exit(0);
}
exit(0);
}