$NetBSD: patch-ai,v 1.1 2002/06/27 15:52:19 agc Exp $ --- obuffer.cc 2002/06/27 15:41:04 1.1 +++ obuffer.cc 2002/06/27 15:41:40 @@ -217,10 +217,10 @@ int SparcObuffer::audio_fd = -1; #ifdef ULAW -SparcObuffer::SparcObuffer (Header *header, bool use_speaker, bool use_headphone, bool use_line_out) +SparcObuffer::SparcObuffer (Header *header, boolean use_speaker, boolean use_headphone, boolean use_line_out) #else SparcObuffer::SparcObuffer (uint32 number_of_channels, Header *header, - bool use_speaker, bool use_headphone, bool use_line_out) + boolean use_speaker, boolean use_headphone, boolean use_line_out) #endif { #ifndef ULAW @@ -406,9 +406,9 @@ #ifdef ULAW -bool SparcObuffer::class_suitable (uint32 number_of_channels, bool force_amd) +boolean SparcObuffer::class_suitable (uint32 number_of_channels, boolean force_amd) #else -bool SparcObuffer::class_suitable (void) +boolean SparcObuffer::class_suitable (void) #endif { #ifdef ULAW @@ -537,6 +537,7 @@ } // turn NDELAY mode off: +#ifndef __FreeBSD__ /* Our /dev/audio doesn't like non-blocking I/O */ int flags; if ((flags = fcntl (fd, F_GETFL, 0)) < 0) { @@ -549,6 +550,7 @@ perror ("fcntl F_SETFL on /dev/audio failed"); exit (1); } +#endif return fd; } @@ -629,7 +631,7 @@ } -bool LinuxObuffer::class_suitable (uint32 number_of_channels) +boolean LinuxObuffer::class_suitable (uint32 number_of_channels) { // open the dsp audio device: audio_fd = open_audio_device (); @@ -637,3 +639,122 @@ } #endif /* LINUX */ + +#ifdef NETBSD +int NetBSDObuffer::audio_fd = -1; + +int NetBSDObuffer::open_audio_device (void) +{ + int fd; + + if ((fd = open ("/dev/audio", O_WRONLY | O_NDELAY, 0)) < 0) + if (errno == EBUSY) + { + cerr << "Sorry, the audio device is busy!\n"; + exit (1); + } + else + { + perror ("can't open /dev/audio for writing"); + exit (1); + } + + int flags; + if ((flags = fcntl (fd, F_GETFL, 0)) < 0) + { + perror ("fcntl F_GETFL on /dev/audio failed"); + exit (1); + } + flags &= ~O_NDELAY; + if (fcntl (fd, F_SETFL, flags) < 0) + { + perror ("fcntl F_SETFL on /dev/audio failed"); + exit (1); + } + return fd; +} + + +NetBSDObuffer::NetBSDObuffer (uint32 number_of_channels, Header *header) +{ +#ifdef DEBUG + if (!number_of_channels || number_of_channels > MAXCHANNELS) + { + cerr << "NetBSDObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n"; + exit (1); + } +#endif + channels = number_of_channels; + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = buffer + i; + + if (audio_fd < 0) + { + cerr << "Internal error, NetBSDObuffer::audio_fd has to be initialized\n" + "by NetBSDObuffer::class_suitable()!\n"; + exit (1); + } + + audio_info info; + AUDIO_INITINFO(&info); + + // configure the device: + info.play.encoding = AUDIO_ENCODING_SLINEAR; + info.play.precision = 16; + info.play.channels = channels; + info.play.sample_rate = header->frequency (); + + if (ioctl (audio_fd, AUDIO_SETINFO, &info)) + { + perror ("configuration of /dev/audio failed"); + exit (1); + } +} + + +NetBSDObuffer::~NetBSDObuffer (void) +{ + close (audio_fd); +} + + +void NetBSDObuffer::append (uint32 channel, int16 value) +{ +#ifdef DEBUG + if (channel >= channels) + { + cerr << "illegal channelnumber in NetBSDObuffer::append()!\n"; + exit (1); + } + if (bufferp[channel] - buffer >= OBUFFERSIZE) + { + cerr << "buffer overflow!\n"; + exit (1); + } +#endif + *bufferp[channel] = value; + bufferp[channel] += channels; +} + + +void NetBSDObuffer::write_buffer (int) +{ + int length = (int)((char *)bufferp[0] - (char *)buffer); + if (write (audio_fd, buffer, length) != length) + { + perror ("write to /dev/audio failed"); + exit (1); + } + for (int i = 0; i < channels; ++i) + bufferp[i] = buffer + i; +} + + +boolean NetBSDObuffer::class_suitable (uint32 number_of_channels) +{ + // open the dsp audio device: + audio_fd = open_audio_device (); + return True; +} + +#endif /* NETBSD */