2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 /* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */
25 /* patch for IRIX 5 by Georg Schwarz 18/07/2004 */
27 #include "SDL_timer.h"
28 #include "SDL_audio.h"
29 #include "../SDL_audiomem.h"
30 #include "../SDL_audio_c.h"
31 #include "SDL_irixaudio.h"
34 #ifndef AL_RESOURCE /* as a test whether we use the old IRIX audio libraries */
35 #define OLD_IRIX_AUDIO
36 #define alClosePort(x) ALcloseport(x)
37 #define alFreeConfig(x) ALfreeconfig(x)
38 #define alGetFillable(x) ALgetfillable(x)
39 #define alNewConfig() ALnewconfig()
40 #define alOpenPort(x,y,z) ALopenport(x,y,z)
41 #define alSetChannels(x,y) ALsetchannels(x,y)
42 #define alSetQueueSize(x,y) ALsetqueuesize(x,y)
43 #define alSetSampFmt(x,y) ALsetsampfmt(x,y)
44 #define alSetWidth(x,y) ALsetwidth(x,y)
47 /* Audio driver functions */
48 static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec);
49 static void AL_WaitAudio(_THIS);
50 static void AL_PlayAudio(_THIS);
51 static Uint8 *AL_GetAudioBuf(_THIS);
52 static void AL_CloseAudio(_THIS);
54 /* Audio driver bootstrap functions */
56 static int Audio_Available(void)
61 static void Audio_DeleteDevice(SDL_AudioDevice *device)
63 SDL_free(device->hidden);
67 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
69 SDL_AudioDevice *this;
71 /* Initialize all variables that we clean on shutdown */
72 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
74 SDL_memset(this, 0, (sizeof *this));
75 this->hidden = (struct SDL_PrivateAudioData *)
76 SDL_malloc((sizeof *this->hidden));
78 if ( (this == NULL) || (this->hidden == NULL) ) {
85 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
87 /* Set the function pointers */
88 this->OpenAudio = AL_OpenAudio;
89 this->WaitAudio = AL_WaitAudio;
90 this->PlayAudio = AL_PlayAudio;
91 this->GetAudioBuf = AL_GetAudioBuf;
92 this->CloseAudio = AL_CloseAudio;
94 this->free = Audio_DeleteDevice;
99 AudioBootStrap DMEDIA_bootstrap = {
100 "AL", "IRIX DMedia audio",
101 Audio_Available, Audio_CreateDevice
105 void static AL_WaitAudio(_THIS)
109 timeleft = this->spec.samples - alGetFillable(audio_port);
110 if ( timeleft > 0 ) {
111 timeleft /= (this->spec.freq/1000);
112 SDL_Delay((Uint32)timeleft);
116 static void AL_PlayAudio(_THIS)
118 /* Write the audio data out */
119 if ( alWriteFrames(audio_port, mixbuf, this->spec.samples) < 0 ) {
120 /* Assume fatal error, for now */
125 static Uint8 *AL_GetAudioBuf(_THIS)
130 static void AL_CloseAudio(_THIS)
132 if ( mixbuf != NULL ) {
133 SDL_FreeAudioMem(mixbuf);
136 if ( audio_port != NULL ) {
137 alClosePort(audio_port);
142 static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec)
144 Uint16 test_format = SDL_FirstAudioFormat(spec->format);
149 #ifdef OLD_IRIX_AUDIO
152 audio_param[0] = AL_OUTPUT_RATE;
153 audio_param[1] = spec->freq;
154 valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
159 audio_param.param = AL_RATE;
160 audio_param.value.i = spec->freq;
161 valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
165 while ((!valid) && (test_format)) {
167 spec->format = test_format;
169 switch (test_format) {
172 fmt = AL_SAMPFMT_TWOSCOMP;
176 width = AL_SAMPLE_16;
177 fmt = AL_SAMPFMT_TWOSCOMP;
182 test_format = SDL_NextAudioFormat();
187 ALconfig audio_config = alNewConfig();
190 if (alSetChannels(audio_config, spec->channels) < 0) {
191 if (spec->channels > 2) { /* can't handle > stereo? */
192 spec->channels = 2; /* try again below. */
196 if ((alSetSampFmt(audio_config, fmt) >= 0) &&
197 ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
198 (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
199 (alSetChannels(audio_config, spec->channels) >= 0)) {
201 audio_port = alOpenPort("SDL audio", "w", audio_config);
202 if (audio_port == NULL) {
203 /* docs say AL_BAD_CHANNELS happens here, too. */
205 if (err == AL_BAD_CHANNELS) {
207 alSetChannels(audio_config, spec->channels);
208 audio_port = alOpenPort("SDL audio", "w",
213 if (audio_port != NULL) {
218 alFreeConfig(audio_config);
224 SDL_SetError("Unsupported audio format");
228 /* Update the fragment size as size in bytes */
229 SDL_CalculateAudioSpec(spec);
231 /* Allocate mixing buffer */
232 mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
233 if (mixbuf == NULL) {
237 SDL_memset(mixbuf, spec->silence, spec->size);
239 /* We're ready to rock and roll. :-) */