2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <sys/param.h>
23 #include <sys/audioio.h>
25 # include <sys/endian.h>
27 #include <sys/ioctl.h>
38 static int audio_fd = -1;
45 Create "snd_renderbuffer" with the proper sound format if the call is successful
46 May return a suggested format if the requested format isn't available
49 qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
55 // Open the audio device
59 snddev = "/dev/audio";
61 snddev = "/dev/sound";
63 audio_fd = open (snddev, O_WRONLY | O_NDELAY | O_NONBLOCK);
66 Con_Printf("Can't open the sound device (%s)\n", snddev);
70 AUDIO_INITINFO (&info);
71 #ifdef AUMODE_PLAY // NetBSD / OpenBSD
72 info.mode = AUMODE_PLAY;
74 info.play.sample_rate = requested->speed;
75 info.play.channels = requested->channels;
76 info.play.precision = requested->width * 8;
77 if (requested->width == 1)
79 info.play.encoding = AUDIO_ENCODING_LINEAR8;
81 info.play.encoding = AUDIO_ENCODING_ULINEAR;
85 info.play.encoding = AUDIO_ENCODING_LINEAR;
87 # if BYTE_ORDER == BIG_ENDIAN
88 info.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
90 info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
94 if (ioctl (audio_fd, AUDIO_SETINFO, &info) != 0)
96 Con_Printf("Can't set up the sound device (%s)\n", snddev);
100 // TODO: check the parameters with AUDIO_GETINFO
101 // TODO: check AUDIO_ENCODINGFLAG_EMULATED with AUDIO_GETENC
103 snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL);
112 Stop the sound card, delete "snd_renderbuffer" and free its other resources
115 void SndSys_Shutdown (void)
123 if (snd_renderbuffer != NULL)
125 Mem_Free(snd_renderbuffer->ring);
126 Mem_Free(snd_renderbuffer);
127 snd_renderbuffer = NULL;
136 Submit the contents of "snd_renderbuffer" to the sound card
139 void SndSys_Submit (void)
141 unsigned int startoffset, factor, limit, nbframes;
145 snd_renderbuffer->startframe == snd_renderbuffer->endframe)
148 startoffset = snd_renderbuffer->startframe % snd_renderbuffer->maxframes;
149 factor = snd_renderbuffer->format.width * snd_renderbuffer->format.channels;
150 limit = snd_renderbuffer->maxframes - startoffset;
151 nbframes = snd_renderbuffer->endframe - snd_renderbuffer->startframe;
152 if (nbframes > limit)
154 written = write (audio_fd, &snd_renderbuffer->ring[startoffset * factor], limit * factor);
157 Con_Printf("SndSys_Submit: audio write returned %d!\n", written);
161 if (written % factor != 0)
162 Sys_Error("SndSys_Submit: nb of bytes written (%d) isn't aligned to a frame sample!\n", written);
164 snd_renderbuffer->startframe += written / factor;
166 if ((unsigned int)written < limit * factor)
168 Con_Printf("SndSys_Submit: audio can't keep up! (%u < %u)\n", written, limit * factor);
176 written = write (audio_fd, &snd_renderbuffer->ring[startoffset * factor], nbframes * factor);
179 Con_Printf("SndSys_Submit: audio write returned %d!\n", written);
182 snd_renderbuffer->startframe += written / factor;
190 Returns the number of sample frames consumed since the sound started
193 unsigned int SndSys_GetSoundTime (void)
197 if (ioctl (audio_fd, AUDIO_GETINFO, &info) < 0)
199 Con_Print("Error: can't get audio info\n");
204 return info.play.samples;
210 SndSys_LockRenderBuffer
212 Get the exclusive lock on "snd_renderbuffer"
215 qboolean SndSys_LockRenderBuffer (void)
224 SndSys_UnlockRenderBuffer
226 Release the exclusive lock on "snd_renderbuffer"
229 void SndSys_UnlockRenderBuffer (void)
238 Send keyboard events originating from the sound system (e.g. MIDI)
241 void SndSys_SendKeyEvents(void)