use unistd.h use fcntl.h use sys/types.h use sys/ioctl.h use stdlib.h use stdio.h use linux/soundcard.h use io use error use m use alloc int BUF_LENGTH=1 # 1 second int RATE=44100 int BITS_PER_SAMPLE=16 int CHANNELS=1 char *outfile = "/dev/dsp" int use_dsp = 1 int main(int argc, char **argv) int fd int arg int status if argc < 4 || argc > 5 error("syntax: %s freq amp duration [outfile]", argv[0]) float freq = atof(argv[1]) float amp = atof(argv[2]) float duration = atof(argv[3]) if argc == 5 use_dsp = 0 outfile = argv[4] fd = Open(outfile, O_WRONLY|O_CREAT|O_APPEND) if use_dsp arg = BITS_PER_SAMPLE status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg) if status == -1 error("SOUND_PCM_WRITE_BITS ioctl failed") if (arg != BITS_PER_SAMPLE) error("unable to set sample size") arg = CHANNELS status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg) if (status == -1) error("SOUND_PCM_WRITE_CHANNELS ioctl failed") if (arg != CHANNELS) error("unable to set number of channels") arg = RATE status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg) if (status == -1) error("SOUND_PCM_WRITE_RATE ioctl failed") if arg != RATE #warning("sample rate set to %d\n", arg) RATE = arg int buf_samples = BUF_LENGTH*RATE int buf_size = buf_samples * 2 # == buf_samples*BITS_PER_SAMPLE/8*CHANNELS char *buf = Malloc(buf_size) # create a sine wave... # assuming 16-bit mono... int duration_samples = duration * RATE float t = 0.0 float dt = 1.0/RATE float v int d while duration_samples > 0 int samples = min(buf_samples, duration_samples) int size = samples * 2 char *end = buf + size char *p for p=buf; p!=end; v = amp*sin(t*freq*2*pi) d = 0x8000 * v if d >= 0x8000 d = 0x7fff eif d < -0x8000 d = -0x8000 *p = d & 0xff ; ++p *p = (d>>8) & 0xff ; ++p t += dt status = write(fd, buf, size) if (status != size) error("wrote wrong number of bytes") duration_samples -= samples if use_dsp status = ioctl(fd, SOUND_PCM_SYNC, 0) if (status == -1) error("SOUND_PCM_SYNC ioctl failed") Free(buf) return 0