comparison src/audio/dmedia/SDL_irixaudio.c @ 2049:5f6550e5184f

Merged SDL-ryan-multiple-audio-device branch r2803:2871 into the trunk.
author Ryan C. Gordon <icculus@icculus.org>
date Tue, 17 Oct 2006 09:15:21 +0000
parents adf732f1f016
children 866052b01ee5
comparison
equal deleted inserted replaced
2048:6067c7f9a672 2049:5f6550e5184f
43 #define alSetQueueSize(x,y) ALsetqueuesize(x,y) 43 #define alSetQueueSize(x,y) ALsetqueuesize(x,y)
44 #define alSetSampFmt(x,y) ALsetsampfmt(x,y) 44 #define alSetSampFmt(x,y) ALsetsampfmt(x,y)
45 #define alSetWidth(x,y) ALsetwidth(x,y) 45 #define alSetWidth(x,y) ALsetwidth(x,y)
46 #endif 46 #endif
47 47
48 /* Audio driver functions */
49 static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec);
50 static void AL_WaitAudio(_THIS);
51 static void AL_PlayAudio(_THIS);
52 static Uint8 *AL_GetAudioBuf(_THIS);
53 static void AL_CloseAudio(_THIS);
54
55 /* Audio driver bootstrap functions */
56
57 static int
58 Audio_Available(void)
59 {
60 return 1;
61 }
62
63 static void
64 Audio_DeleteDevice(SDL_AudioDevice * device)
65 {
66 SDL_free(device->hidden);
67 SDL_free(device);
68 }
69
70 static SDL_AudioDevice *
71 Audio_CreateDevice(int devindex)
72 {
73 SDL_AudioDevice *this;
74
75 /* Initialize all variables that we clean on shutdown */
76 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
77 if (this) {
78 SDL_memset(this, 0, (sizeof *this));
79 this->hidden = (struct SDL_PrivateAudioData *)
80 SDL_malloc((sizeof *this->hidden));
81 }
82 if ((this == NULL) || (this->hidden == NULL)) {
83 SDL_OutOfMemory();
84 if (this) {
85 SDL_free(this);
86 }
87 return (0);
88 }
89 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
90
91 /* Set the function pointers */
92 this->OpenAudio = AL_OpenAudio;
93 this->WaitAudio = AL_WaitAudio;
94 this->PlayAudio = AL_PlayAudio;
95 this->GetAudioBuf = AL_GetAudioBuf;
96 this->CloseAudio = AL_CloseAudio;
97
98 this->free = Audio_DeleteDevice;
99
100 return this;
101 }
102
103 AudioBootStrap DMEDIA_bootstrap = {
104 "AL", "IRIX DMedia audio",
105 Audio_Available, Audio_CreateDevice
106 };
107
108
109 void static 48 void static
110 AL_WaitAudio(_THIS) 49 IRIXAUDIO_WaitDevice(_THIS)
111 { 50 {
112 Sint32 timeleft; 51 Sint32 timeleft;
113 52
114 timeleft = this->spec.samples - alGetFillable(audio_port); 53 timeleft = this->spec.samples - alGetFillable(this->hidden->audio_port);
115 if (timeleft > 0) { 54 if (timeleft > 0) {
116 timeleft /= (this->spec.freq / 1000); 55 timeleft /= (this->spec.freq / 1000);
117 SDL_Delay((Uint32) timeleft); 56 SDL_Delay((Uint32) timeleft);
118 } 57 }
119 } 58 }
120 59
121 static void 60 static void
122 AL_PlayAudio(_THIS) 61 IRIXAUDIO_PlayDevice(_THIS)
123 { 62 {
124 /* Write the audio data out */ 63 /* Write the audio data out */
125 if (alWriteFrames(audio_port, mixbuf, this->spec.samples) < 0) { 64 ALport port = this->hidden->audio_port;
65 Uint8 *mixbuf = this->hidden->mixbuf;
66 if (alWriteFrames(port, mixbuf, this->spec.samples) < 0) {
126 /* Assume fatal error, for now */ 67 /* Assume fatal error, for now */
127 this->enabled = 0; 68 this->enabled = 0;
128 } 69 }
129 } 70 }
130 71
131 static Uint8 * 72 static Uint8 *
132 AL_GetAudioBuf(_THIS) 73 IRIXAUDIO_GetDeviceBuf(_THIS)
133 { 74 {
134 return (mixbuf); 75 return (this->hidden->mixbuf);
135 } 76 }
136 77
137 static void 78 static void
138 AL_CloseAudio(_THIS) 79 IRIXAUDIO_CloseDevice(_THIS)
139 { 80 {
140 if (mixbuf != NULL) { 81 if (this->hidden != NULL) {
141 SDL_FreeAudioMem(mixbuf); 82 if (this->hidden->mixbuf != NULL) {
142 mixbuf = NULL; 83 SDL_FreeAudioMem(this->hidden->mixbuf);
143 } 84 this->hidden->mixbuf = NULL;
144 if (audio_port != NULL) { 85 }
145 alClosePort(audio_port); 86 if (this->hidden->audio_port != NULL) {
146 audio_port = NULL; 87 alClosePort(this->hidden->audio_port);
88 this->hidden->audio_port = NULL;
89 }
90 SDL_free(this->hidden);
91 this->hidden = NULL;
147 } 92 }
148 } 93 }
149 94
150 static int 95 static int
151 AL_OpenAudio(_THIS, SDL_AudioSpec * spec) 96 IRIXAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
152 { 97 {
153 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); 98 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
154 long width = 0; 99 long width = 0;
155 long fmt = 0; 100 long fmt = 0;
156 int valid = 0; 101 int valid = 0;
102
103 /* !!! FIXME: Handle multiple devices and capture? */
104
105 /* Initialize all variables that we clean on shutdown */
106 this->hidden = (struct SDL_PrivateAudioData *)
107 SDL_malloc((sizeof *this->hidden));
108 if (this->hidden == NULL) {
109 SDL_OutOfMemory();
110 return 0;
111 }
112 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
157 113
158 #ifdef OLD_IRIX_AUDIO 114 #ifdef OLD_IRIX_AUDIO
159 { 115 {
160 long audio_param[2]; 116 long audio_param[2];
161 audio_param[0] = AL_OUTPUT_RATE; 117 audio_param[0] = AL_OUTPUT_RATE;
162 audio_param[1] = spec->freq; 118 audio_param[1] = this->spec.freq;
163 valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0); 119 valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
164 } 120 }
165 #else 121 #else
166 { 122 {
167 ALpv audio_param; 123 ALpv audio_param;
168 audio_param.param = AL_RATE; 124 audio_param.param = AL_RATE;
169 audio_param.value.i = spec->freq; 125 audio_param.value.i = this->spec.freq;
170 valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0); 126 valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
171 } 127 }
172 #endif 128 #endif
173 129
174 while ((!valid) && (test_format)) { 130 while ((!valid) && (test_format)) {
175 valid = 1; 131 valid = 1;
176 spec->format = test_format; 132 this->spec.format = test_format;
177 133
178 switch (test_format) { 134 switch (test_format) {
179 case AUDIO_S8: 135 case AUDIO_S8:
180 width = AL_SAMPLE_8; 136 width = AL_SAMPLE_8;
181 fmt = AL_SAMPFMT_TWOSCOMP; 137 fmt = AL_SAMPFMT_TWOSCOMP;
201 157
202 if (valid) { 158 if (valid) {
203 ALconfig audio_config = alNewConfig(); 159 ALconfig audio_config = alNewConfig();
204 valid = 0; 160 valid = 0;
205 if (audio_config) { 161 if (audio_config) {
206 if (alSetChannels(audio_config, spec->channels) < 0) { 162 if (alSetChannels(audio_config, this->spec.channels) < 0) {
207 if (spec->channels > 2) { /* can't handle > stereo? */ 163 if (this->spec.channels > 2) { /* can't handle > stereo? */
208 spec->channels = 2; /* try again below. */ 164 this->spec.channels = 2; /* try again below. */
209 } 165 }
210 } 166 }
211 167
212 if ((alSetSampFmt(audio_config, fmt) >= 0) && 168 if ((alSetSampFmt(audio_config, fmt) >= 0) &&
213 ((!width) || (alSetWidth(audio_config, width) >= 0)) && 169 ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
214 (alSetQueueSize(audio_config, spec->samples * 2) >= 0) && 170 (alSetQueueSize(audio_config,this->spec.samples*2) >= 0) &&
215 (alSetChannels(audio_config, spec->channels) >= 0)) { 171 (alSetChannels(audio_config, this->spec.channels) >= 0)) {
216 172
217 audio_port = alOpenPort("SDL audio", "w", audio_config); 173 this->hidden->audio_port = alOpenPort("SDL audio", "w",
218 if (audio_port == NULL) { 174 audio_config);
175 if (this->hidden->audio_port == NULL) {
219 /* docs say AL_BAD_CHANNELS happens here, too. */ 176 /* docs say AL_BAD_CHANNELS happens here, too. */
220 int err = oserror(); 177 int err = oserror();
221 if (err == AL_BAD_CHANNELS) { 178 if (err == AL_BAD_CHANNELS) {
222 spec->channels = 2; 179 this->spec.channels = 2;
223 alSetChannels(audio_config, spec->channels); 180 alSetChannels(audio_config, this->spec.channels);
224 audio_port = alOpenPort("SDL audio", "w", 181 this->hidden->audio_port = alOpenPort("SDL audio", "w",
225 audio_config); 182 audio_config);
226 } 183 }
227 } 184 }
228 185
229 if (audio_port != NULL) { 186 if (this->hidden->audio_port != NULL) {
230 valid = 1; 187 valid = 1;
231 } 188 }
232 } 189 }
233 190
234 alFreeConfig(audio_config); 191 alFreeConfig(audio_config);
235 } 192 }
236 } 193 }
237 } 194 }
238 195
239 if (!valid) { 196 if (!valid) {
197 IRIXAUDIO_CloseDevice(this);
240 SDL_SetError("Unsupported audio format"); 198 SDL_SetError("Unsupported audio format");
241 return (-1); 199 return 0;
242 } 200 }
243 201
244 /* Update the fragment size as size in bytes */ 202 /* Update the fragment size as size in bytes */
245 SDL_CalculateAudioSpec(spec); 203 SDL_CalculateAudioSpec(&this->spec);
246 204
247 /* Allocate mixing buffer */ 205 /* Allocate mixing buffer */
248 mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); 206 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
249 if (mixbuf == NULL) { 207 if (this->hidden->mixbuf == NULL) {
208 IRIXAUDIO_CloseDevice(this);
250 SDL_OutOfMemory(); 209 SDL_OutOfMemory();
251 return (-1); 210 return 0;
252 } 211 }
253 SDL_memset(mixbuf, spec->silence, spec->size); 212 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
254 213
255 /* We're ready to rock and roll. :-) */ 214 /* We're ready to rock and roll. :-) */
256 return (0); 215 return 1;
257 } 216 }
217
218 static int
219 IRIXAUDIO_Init(SDL_AudioDriverImpl *impl)
220 {
221 /* Set the function pointers */
222 impl->OpenDevice = DSP_OpenDevice;
223 impl->PlayDevice = DSP_PlayDevice;
224 impl->WaitDevice = DSP_WaitDevice;
225 impl->GetDeviceBuf = DSP_GetDeviceBuf;
226 impl->CloseDevice = DSP_CloseDevice;
227 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: not true, I think. */
228
229 return 1;
230 }
231
232 AudioBootStrap IRIXAUDIO_bootstrap = {
233 "AL", "IRIX DMedia audio", IRIXAUDIO_Init, 0
234 };
258 235
259 /* vi: set ts=4 sw=4 expandtab: */ 236 /* vi: set ts=4 sw=4 expandtab: */