static int oss_open(struct voss_backend *pbe, const char *devname, int samplerate, int bufsize, int *pchannels, int *pformat, int attr, int fionbio) { int temp; int err; pbe->fd = open(devname, attr); if (pbe->fd < 0) { warn("Could not open DSP device '%s'", devname); return (-1); } err = ioctl(pbe->fd, FIONBIO, &fionbio); if (err < 0) { warn("Could not set blocking mode on DSP"); goto error; } err = oss_set_format(pbe->fd, pformat); if (err < 0) { warn("Could not set sample format 0x%08x", *pformat); goto error; } temp = *pchannels; bufsize /= temp; /* get buffer size per channel */ do { err = ioctl(pbe->fd, SOUND_PCM_WRITE_CHANNELS, &temp); } while (err < 0 && --temp > 0); err = ioctl(pbe->fd, SOUND_PCM_READ_CHANNELS, &temp); if (err < 0 || temp <= 0 || temp > *pchannels) { warn("Could not set DSP channels: %d / %d", temp, *pchannels); goto error; } *pchannels = temp; temp = samplerate; err = ioctl(pbe->fd, SNDCTL_DSP_SPEED, &temp); if (err < 0 || temp != samplerate) { warn("Could not set sample rate to %d / %d Hz", temp, samplerate); goto error; } temp = bufsize * (*pchannels); err = ioctl(pbe->fd, SNDCTL_DSP_SETBLKSIZE, &temp); if (err < 0) { warn("Could not set block size to %d", temp); goto error; } return (0); error: close(pbe->fd); pbe->fd = -1; return (-1); }
static void oss_restore_format() { RD_WAVEFORMATEX wfx; memset(&wfx, 0, sizeof(RD_WAVEFORMATEX)); switch (format) { case AFMT_U8: wfx.wBitsPerSample = 8; break; case AFMT_S16_LE: wfx.wBitsPerSample = 16; break; default: wfx.wBitsPerSample = 0; } wfx.nChannels = stereo ? 2 : 1; wfx.nSamplesPerSec = snd_rate; oss_set_format(&wfx); }