Mercurial > sdl-ios-xcode
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: */ |