Mercurial > sdl-ios-xcode
comparison src/audio/paudio/SDL_paudio.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | d910939febfa |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
53 /* Open the audio device for playback, and don't block if busy */ | 53 /* Open the audio device for playback, and don't block if busy */ |
54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ | 54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ |
55 #define OPEN_FLAGS O_WRONLY | 55 #define OPEN_FLAGS O_WRONLY |
56 | 56 |
57 /* Audio driver functions */ | 57 /* Audio driver functions */ |
58 static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec); | 58 static int Paud_OpenAudio (_THIS, SDL_AudioSpec * spec); |
59 static void Paud_WaitAudio(_THIS); | 59 static void Paud_WaitAudio (_THIS); |
60 static void Paud_PlayAudio(_THIS); | 60 static void Paud_PlayAudio (_THIS); |
61 static Uint8 *Paud_GetAudioBuf(_THIS); | 61 static Uint8 *Paud_GetAudioBuf (_THIS); |
62 static void Paud_CloseAudio(_THIS); | 62 static void Paud_CloseAudio (_THIS); |
63 | 63 |
64 /* Audio driver bootstrap functions */ | 64 /* Audio driver bootstrap functions */ |
65 | 65 |
66 static int Audio_Available(void) | 66 static int |
67 { | 67 Audio_Available (void) |
68 int fd; | 68 { |
69 int available; | 69 int fd; |
70 | 70 int available; |
71 available = 0; | 71 |
72 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | 72 available = 0; |
73 if ( fd >= 0 ) { | 73 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0); |
74 available = 1; | 74 if (fd >= 0) { |
75 close(fd); | 75 available = 1; |
76 } | 76 close (fd); |
77 return(available); | 77 } |
78 } | 78 return (available); |
79 | 79 } |
80 static void Audio_DeleteDevice(SDL_AudioDevice *device) | 80 |
81 { | 81 static void |
82 SDL_free(device->hidden); | 82 Audio_DeleteDevice (SDL_AudioDevice * device) |
83 SDL_free(device); | 83 { |
84 } | 84 SDL_free (device->hidden); |
85 | 85 SDL_free (device); |
86 static SDL_AudioDevice *Audio_CreateDevice(int devindex) | 86 } |
87 { | 87 |
88 SDL_AudioDevice *this; | 88 static SDL_AudioDevice * |
89 | 89 Audio_CreateDevice (int devindex) |
90 /* Initialize all variables that we clean on shutdown */ | 90 { |
91 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | 91 SDL_AudioDevice *this; |
92 if ( this ) { | 92 |
93 SDL_memset(this, 0, (sizeof *this)); | 93 /* Initialize all variables that we clean on shutdown */ |
94 this->hidden = (struct SDL_PrivateAudioData *) | 94 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); |
95 SDL_malloc((sizeof *this->hidden)); | 95 if (this) { |
96 } | 96 SDL_memset (this, 0, (sizeof *this)); |
97 if ( (this == NULL) || (this->hidden == NULL) ) { | 97 this->hidden = (struct SDL_PrivateAudioData *) |
98 SDL_OutOfMemory(); | 98 SDL_malloc ((sizeof *this->hidden)); |
99 if ( this ) { | 99 } |
100 SDL_free(this); | 100 if ((this == NULL) || (this->hidden == NULL)) { |
101 } | 101 SDL_OutOfMemory (); |
102 return(0); | 102 if (this) { |
103 } | 103 SDL_free (this); |
104 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | 104 } |
105 audio_fd = -1; | 105 return (0); |
106 | 106 } |
107 /* Set the function pointers */ | 107 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); |
108 this->OpenAudio = Paud_OpenAudio; | 108 audio_fd = -1; |
109 this->WaitAudio = Paud_WaitAudio; | 109 |
110 this->PlayAudio = Paud_PlayAudio; | 110 /* Set the function pointers */ |
111 this->GetAudioBuf = Paud_GetAudioBuf; | 111 this->OpenAudio = Paud_OpenAudio; |
112 this->CloseAudio = Paud_CloseAudio; | 112 this->WaitAudio = Paud_WaitAudio; |
113 | 113 this->PlayAudio = Paud_PlayAudio; |
114 this->free = Audio_DeleteDevice; | 114 this->GetAudioBuf = Paud_GetAudioBuf; |
115 | 115 this->CloseAudio = Paud_CloseAudio; |
116 return this; | 116 |
117 this->free = Audio_DeleteDevice; | |
118 | |
119 return this; | |
117 } | 120 } |
118 | 121 |
119 AudioBootStrap Paud_bootstrap = { | 122 AudioBootStrap Paud_bootstrap = { |
120 Paud_DRIVER_NAME, "AIX Paudio", | 123 Paud_DRIVER_NAME, "AIX Paudio", |
121 Audio_Available, Audio_CreateDevice | 124 Audio_Available, Audio_CreateDevice |
122 }; | 125 }; |
123 | 126 |
124 /* This function waits until it is possible to write a full sound buffer */ | 127 /* This function waits until it is possible to write a full sound buffer */ |
125 static void Paud_WaitAudio(_THIS) | 128 static void |
129 Paud_WaitAudio (_THIS) | |
126 { | 130 { |
127 fd_set fdset; | 131 fd_set fdset; |
128 | 132 |
129 /* See if we need to use timed audio synchronization */ | 133 /* See if we need to use timed audio synchronization */ |
130 if ( frame_ticks ) { | 134 if (frame_ticks) { |
131 /* Use timer for general audio synchronization */ | 135 /* Use timer for general audio synchronization */ |
132 Sint32 ticks; | 136 Sint32 ticks; |
133 | 137 |
134 ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | 138 ticks = ((Sint32) (next_frame - SDL_GetTicks ())) - FUDGE_TICKS; |
135 if ( ticks > 0 ) { | 139 if (ticks > 0) { |
136 SDL_Delay(ticks); | 140 SDL_Delay (ticks); |
137 } | 141 } |
138 } else { | 142 } else { |
139 audio_buffer paud_bufinfo; | 143 audio_buffer paud_bufinfo; |
140 | 144 |
141 /* Use select() for audio synchronization */ | 145 /* Use select() for audio synchronization */ |
142 struct timeval timeout; | 146 struct timeval timeout; |
143 FD_ZERO(&fdset); | 147 FD_ZERO (&fdset); |
144 FD_SET(audio_fd, &fdset); | 148 FD_SET (audio_fd, &fdset); |
145 | 149 |
146 if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | 150 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { |
147 #ifdef DEBUG_AUDIO | 151 #ifdef DEBUG_AUDIO |
148 fprintf(stderr, "Couldn't get audio buffer information\n"); | 152 fprintf (stderr, "Couldn't get audio buffer information\n"); |
149 #endif | 153 #endif |
150 timeout.tv_sec = 10; | 154 timeout.tv_sec = 10; |
151 timeout.tv_usec = 0; | 155 timeout.tv_usec = 0; |
152 } else { | 156 } else { |
153 long ms_in_buf = paud_bufinfo.write_buf_time; | 157 long ms_in_buf = paud_bufinfo.write_buf_time; |
154 timeout.tv_sec = ms_in_buf/1000; | 158 timeout.tv_sec = ms_in_buf / 1000; |
155 ms_in_buf = ms_in_buf - timeout.tv_sec*1000; | 159 ms_in_buf = ms_in_buf - timeout.tv_sec * 1000; |
156 timeout.tv_usec = ms_in_buf*1000; | 160 timeout.tv_usec = ms_in_buf * 1000; |
157 #ifdef DEBUG_AUDIO | 161 #ifdef DEBUG_AUDIO |
158 fprintf( stderr, | 162 fprintf (stderr, |
159 "Waiting for write_buf_time=%ld,%ld\n", | 163 "Waiting for write_buf_time=%ld,%ld\n", |
160 timeout.tv_sec, | 164 timeout.tv_sec, timeout.tv_usec); |
161 timeout.tv_usec ); | 165 #endif |
162 #endif | 166 } |
163 } | 167 |
164 | 168 #ifdef DEBUG_AUDIO |
165 #ifdef DEBUG_AUDIO | 169 fprintf (stderr, "Waiting for audio to get ready\n"); |
166 fprintf(stderr, "Waiting for audio to get ready\n"); | 170 #endif |
167 #endif | 171 if (select (audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { |
168 if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { | 172 const char *message = |
169 const char *message = "Audio timeout - buggy audio driver? (disabled)"; | 173 "Audio timeout - buggy audio driver? (disabled)"; |
170 /* | 174 /* |
171 * In general we should never print to the screen, | 175 * In general we should never print to the screen, |
172 * but in this case we have no other way of letting | 176 * but in this case we have no other way of letting |
173 * the user know what happened. | 177 * the user know what happened. |
174 */ | 178 */ |
175 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); | 179 fprintf (stderr, "SDL: %s - %s\n", strerror (errno), message); |
176 this->enabled = 0; | 180 this->enabled = 0; |
177 /* Don't try to close - may hang */ | 181 /* Don't try to close - may hang */ |
178 audio_fd = -1; | 182 audio_fd = -1; |
179 #ifdef DEBUG_AUDIO | 183 #ifdef DEBUG_AUDIO |
180 fprintf(stderr, "Done disabling audio\n"); | 184 fprintf (stderr, "Done disabling audio\n"); |
181 #endif | 185 #endif |
182 } | 186 } |
183 #ifdef DEBUG_AUDIO | 187 #ifdef DEBUG_AUDIO |
184 fprintf(stderr, "Ready!\n"); | 188 fprintf (stderr, "Ready!\n"); |
185 #endif | 189 #endif |
186 } | 190 } |
187 } | 191 } |
188 | 192 |
189 static void Paud_PlayAudio(_THIS) | 193 static void |
190 { | 194 Paud_PlayAudio (_THIS) |
191 int written; | 195 { |
192 | 196 int written; |
193 /* Write the audio data, checking for EAGAIN on broken audio drivers */ | 197 |
194 do { | 198 /* Write the audio data, checking for EAGAIN on broken audio drivers */ |
195 written = write(audio_fd, mixbuf, mixlen); | 199 do { |
196 if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) { | 200 written = write (audio_fd, mixbuf, mixlen); |
197 SDL_Delay(1); /* Let a little CPU time go by */ | 201 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { |
198 } | 202 SDL_Delay (1); /* Let a little CPU time go by */ |
199 } while ( (written < 0) && | 203 } |
200 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) ); | 204 } |
201 | 205 while ((written < 0) && |
202 /* If timer synchronization is enabled, set the next write frame */ | 206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); |
203 if ( frame_ticks ) { | 207 |
204 next_frame += frame_ticks; | 208 /* If timer synchronization is enabled, set the next write frame */ |
205 } | 209 if (frame_ticks) { |
206 | 210 next_frame += frame_ticks; |
207 /* If we couldn't write, assume fatal error for now */ | 211 } |
208 if ( written < 0 ) { | 212 |
209 this->enabled = 0; | 213 /* If we couldn't write, assume fatal error for now */ |
210 } | 214 if (written < 0) { |
211 #ifdef DEBUG_AUDIO | 215 this->enabled = 0; |
212 fprintf(stderr, "Wrote %d bytes of audio data\n", written); | 216 } |
213 #endif | 217 #ifdef DEBUG_AUDIO |
214 } | 218 fprintf (stderr, "Wrote %d bytes of audio data\n", written); |
215 | 219 #endif |
216 static Uint8 *Paud_GetAudioBuf(_THIS) | 220 } |
217 { | 221 |
218 return mixbuf; | 222 static Uint8 * |
219 } | 223 Paud_GetAudioBuf (_THIS) |
220 | 224 { |
221 static void Paud_CloseAudio(_THIS) | 225 return mixbuf; |
222 { | 226 } |
223 if ( mixbuf != NULL ) { | 227 |
224 SDL_FreeAudioMem(mixbuf); | 228 static void |
225 mixbuf = NULL; | 229 Paud_CloseAudio (_THIS) |
226 } | 230 { |
227 if ( audio_fd >= 0 ) { | 231 if (mixbuf != NULL) { |
228 close(audio_fd); | 232 SDL_FreeAudioMem (mixbuf); |
229 audio_fd = -1; | 233 mixbuf = NULL; |
230 } | 234 } |
231 } | 235 if (audio_fd >= 0) { |
232 | 236 close (audio_fd); |
233 static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec) | 237 audio_fd = -1; |
234 { | 238 } |
235 char audiodev[1024]; | 239 } |
236 int format; | 240 |
237 int bytes_per_sample; | 241 static int |
238 Uint16 test_format; | 242 Paud_OpenAudio (_THIS, SDL_AudioSpec * spec) |
239 audio_init paud_init; | 243 { |
240 audio_buffer paud_bufinfo; | 244 char audiodev[1024]; |
241 audio_status paud_status; | 245 int format; |
242 audio_control paud_control; | 246 int bytes_per_sample; |
243 audio_change paud_change; | 247 Uint16 test_format; |
244 | 248 audio_init paud_init; |
245 /* Reset the timer synchronization flag */ | 249 audio_buffer paud_bufinfo; |
246 frame_ticks = 0.0; | 250 audio_status paud_status; |
247 | 251 audio_control paud_control; |
248 /* Open the audio device */ | 252 audio_change paud_change; |
249 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | 253 |
250 if ( audio_fd < 0 ) { | 254 /* Reset the timer synchronization flag */ |
251 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | 255 frame_ticks = 0.0; |
252 return -1; | 256 |
253 } | 257 /* Open the audio device */ |
254 | 258 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0); |
255 /* | 259 if (audio_fd < 0) { |
256 * We can't set the buffer size - just ask the device for the maximum | 260 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno)); |
257 * that we can have. | 261 return -1; |
258 */ | 262 } |
259 if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | 263 |
260 SDL_SetError("Couldn't get audio buffer information"); | 264 /* |
261 return -1; | 265 * We can't set the buffer size - just ask the device for the maximum |
262 } | 266 * that we can have. |
263 | 267 */ |
264 mixbuf = NULL; | 268 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { |
265 | 269 SDL_SetError ("Couldn't get audio buffer information"); |
266 if ( spec->channels > 1 ) | 270 return -1; |
267 spec->channels = 2; | 271 } |
268 else | 272 |
269 spec->channels = 1; | 273 mixbuf = NULL; |
270 | 274 |
271 /* | 275 if (spec->channels > 1) |
272 * Fields in the audio_init structure: | 276 spec->channels = 2; |
273 * | 277 else |
274 * Ignored by us: | 278 spec->channels = 1; |
275 * | 279 |
276 * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? | 280 /* |
277 * paud.slot_number; * slot number of the adapter | 281 * Fields in the audio_init structure: |
278 * paud.device_id; * adapter identification number | 282 * |
279 * | 283 * Ignored by us: |
280 * Input: | 284 * |
281 * | 285 * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? |
282 * paud.srate; * the sampling rate in Hz | 286 * paud.slot_number; * slot number of the adapter |
283 * paud.bits_per_sample; * 8, 16, 32, ... | 287 * paud.device_id; * adapter identification number |
284 * paud.bsize; * block size for this rate | 288 * |
285 * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX | 289 * Input: |
286 * paud.channels; * 1=mono, 2=stereo | 290 * |
287 * paud.flags; * FIXED - fixed length data | 291 * paud.srate; * the sampling rate in Hz |
288 * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) | 292 * paud.bits_per_sample; * 8, 16, 32, ... |
289 * * TWOS_COMPLEMENT - 2's complement data | 293 * paud.bsize; * block size for this rate |
290 * * SIGNED - signed? comment seems wrong in sys/audio.h | 294 * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX |
291 * * BIG_ENDIAN | 295 * paud.channels; * 1=mono, 2=stereo |
292 * paud.operation; * PLAY, RECORD | 296 * paud.flags; * FIXED - fixed length data |
293 * | 297 * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) |
294 * Output: | 298 * * TWOS_COMPLEMENT - 2's complement data |
295 * | 299 * * SIGNED - signed? comment seems wrong in sys/audio.h |
296 * paud.flags; * PITCH - pitch is supported | 300 * * BIG_ENDIAN |
297 * * INPUT - input is supported | 301 * paud.operation; * PLAY, RECORD |
298 * * OUTPUT - output is supported | 302 * |
299 * * MONITOR - monitor is supported | 303 * Output: |
300 * * VOLUME - volume is supported | 304 * |
301 * * VOLUME_DELAY - volume delay is supported | 305 * paud.flags; * PITCH - pitch is supported |
302 * * BALANCE - balance is supported | 306 * * INPUT - input is supported |
303 * * BALANCE_DELAY - balance delay is supported | 307 * * OUTPUT - output is supported |
304 * * TREBLE - treble control is supported | 308 * * MONITOR - monitor is supported |
305 * * BASS - bass control is supported | 309 * * VOLUME - volume is supported |
306 * * BESTFIT_PROVIDED - best fit returned | 310 * * VOLUME_DELAY - volume delay is supported |
307 * * LOAD_CODE - DSP load needed | 311 * * BALANCE - balance is supported |
308 * paud.rc; * NO_PLAY - DSP code can't do play requests | 312 * * BALANCE_DELAY - balance delay is supported |
309 * * NO_RECORD - DSP code can't do record requests | 313 * * TREBLE - treble control is supported |
310 * * INVALID_REQUEST - request was invalid | 314 * * BASS - bass control is supported |
311 * * CONFLICT - conflict with open's flags | 315 * * BESTFIT_PROVIDED - best fit returned |
312 * * OVERLOADED - out of DSP MIPS or memory | 316 * * LOAD_CODE - DSP load needed |
313 * paud.position_resolution; * smallest increment for position | 317 * paud.rc; * NO_PLAY - DSP code can't do play requests |
314 */ | 318 * * NO_RECORD - DSP code can't do record requests |
315 | 319 * * INVALID_REQUEST - request was invalid |
316 paud_init.srate = spec->freq; | 320 * * CONFLICT - conflict with open's flags |
317 paud_init.mode = PCM; | 321 * * OVERLOADED - out of DSP MIPS or memory |
318 paud_init.operation = PLAY; | 322 * paud.position_resolution; * smallest increment for position |
319 paud_init.channels = spec->channels; | 323 */ |
320 | 324 |
321 /* Try for a closest match on audio format */ | 325 paud_init.srate = spec->freq; |
322 format = 0; | 326 paud_init.mode = PCM; |
323 for ( test_format = SDL_FirstAudioFormat(spec->format); | 327 paud_init.operation = PLAY; |
324 ! format && test_format; ) { | 328 paud_init.channels = spec->channels; |
325 #ifdef DEBUG_AUDIO | 329 |
326 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | 330 /* Try for a closest match on audio format */ |
327 #endif | 331 format = 0; |
328 switch ( test_format ) { | 332 for (test_format = SDL_FirstAudioFormat (spec->format); |
329 case AUDIO_U8: | 333 !format && test_format;) { |
330 bytes_per_sample = 1; | 334 #ifdef DEBUG_AUDIO |
331 paud_init.bits_per_sample = 8; | 335 fprintf (stderr, "Trying format 0x%4.4x\n", test_format); |
332 paud_init.flags = TWOS_COMPLEMENT | FIXED; | 336 #endif |
333 format = 1; | 337 switch (test_format) { |
334 break; | 338 case AUDIO_U8: |
335 case AUDIO_S8: | 339 bytes_per_sample = 1; |
336 bytes_per_sample = 1; | 340 paud_init.bits_per_sample = 8; |
337 paud_init.bits_per_sample = 8; | 341 paud_init.flags = TWOS_COMPLEMENT | FIXED; |
338 paud_init.flags = SIGNED | | 342 format = 1; |
339 TWOS_COMPLEMENT | FIXED; | 343 break; |
340 format = 1; | 344 case AUDIO_S8: |
341 break; | 345 bytes_per_sample = 1; |
342 case AUDIO_S16LSB: | 346 paud_init.bits_per_sample = 8; |
343 bytes_per_sample = 2; | 347 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; |
344 paud_init.bits_per_sample = 16; | 348 format = 1; |
345 paud_init.flags = SIGNED | | 349 break; |
346 TWOS_COMPLEMENT | FIXED; | 350 case AUDIO_S16LSB: |
347 format = 1; | 351 bytes_per_sample = 2; |
348 break; | 352 paud_init.bits_per_sample = 16; |
349 case AUDIO_S16MSB: | 353 paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; |
350 bytes_per_sample = 2; | 354 format = 1; |
351 paud_init.bits_per_sample = 16; | 355 break; |
352 paud_init.flags = BIG_ENDIAN | | 356 case AUDIO_S16MSB: |
353 SIGNED | | 357 bytes_per_sample = 2; |
354 TWOS_COMPLEMENT | FIXED; | 358 paud_init.bits_per_sample = 16; |
355 format = 1; | 359 paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED; |
356 break; | 360 format = 1; |
357 case AUDIO_U16LSB: | 361 break; |
358 bytes_per_sample = 2; | 362 case AUDIO_U16LSB: |
359 paud_init.bits_per_sample = 16; | 363 bytes_per_sample = 2; |
360 paud_init.flags = TWOS_COMPLEMENT | FIXED; | 364 paud_init.bits_per_sample = 16; |
361 format = 1; | 365 paud_init.flags = TWOS_COMPLEMENT | FIXED; |
362 break; | 366 format = 1; |
363 case AUDIO_U16MSB: | 367 break; |
364 bytes_per_sample = 2; | 368 case AUDIO_U16MSB: |
365 paud_init.bits_per_sample = 16; | 369 bytes_per_sample = 2; |
366 paud_init.flags = BIG_ENDIAN | | 370 paud_init.bits_per_sample = 16; |
367 TWOS_COMPLEMENT | FIXED; | 371 paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED; |
368 format = 1; | 372 format = 1; |
369 break; | 373 break; |
370 default: | 374 default: |
371 break; | 375 break; |
372 } | 376 } |
373 if ( ! format ) { | 377 if (!format) { |
374 test_format = SDL_NextAudioFormat(); | 378 test_format = SDL_NextAudioFormat (); |
375 } | 379 } |
376 } | 380 } |
377 if ( format == 0 ) { | 381 if (format == 0) { |
378 #ifdef DEBUG_AUDIO | 382 #ifdef DEBUG_AUDIO |
379 fprintf(stderr, "Couldn't find any hardware audio formats\n"); | 383 fprintf (stderr, "Couldn't find any hardware audio formats\n"); |
380 #endif | 384 #endif |
381 SDL_SetError("Couldn't find any hardware audio formats"); | 385 SDL_SetError ("Couldn't find any hardware audio formats"); |
382 return -1; | 386 return -1; |
383 } | 387 } |
384 spec->format = test_format; | 388 spec->format = test_format; |
385 | 389 |
386 /* | 390 /* |
387 * We know the buffer size and the max number of subsequent writes | 391 * We know the buffer size and the max number of subsequent writes |
388 * that can be pending. If more than one can pend, allow the application | 392 * that can be pending. If more than one can pend, allow the application |
389 * to do something like double buffering between our write buffer and | 393 * to do something like double buffering between our write buffer and |
390 * the device's own buffer that we are filling with write() anyway. | 394 * the device's own buffer that we are filling with write() anyway. |
391 * | 395 * |
392 * We calculate spec->samples like this because SDL_CalculateAudioSpec() | 396 * We calculate spec->samples like this because SDL_CalculateAudioSpec() |
393 * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) | 397 * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) |
394 * into spec->size in return. | 398 * into spec->size in return. |
395 */ | 399 */ |
396 if ( paud_bufinfo.request_buf_cap == 1 ) | 400 if (paud_bufinfo.request_buf_cap == 1) { |
397 { | 401 spec->samples = paud_bufinfo.write_buf_cap |
398 spec->samples = paud_bufinfo.write_buf_cap | 402 / bytes_per_sample / spec->channels; |
399 / bytes_per_sample | 403 } else { |
400 / spec->channels; | 404 spec->samples = paud_bufinfo.write_buf_cap |
401 } | 405 / bytes_per_sample / spec->channels / 2; |
402 else | 406 } |
403 { | 407 paud_init.bsize = bytes_per_sample * spec->channels; |
404 spec->samples = paud_bufinfo.write_buf_cap | 408 |
405 / bytes_per_sample | 409 SDL_CalculateAudioSpec (spec); |
406 / spec->channels | 410 |
407 / 2; | 411 /* |
408 } | 412 * The AIX paud device init can't modify the values of the audio_init |
409 paud_init.bsize = bytes_per_sample * spec->channels; | 413 * structure that we pass to it. So we don't need any recalculation |
410 | 414 * of this stuff and no reinit call as in linux dsp and dma code. |
411 SDL_CalculateAudioSpec(spec); | 415 * |
412 | 416 * /dev/paud supports all of the encoding formats, so we don't need |
413 /* | 417 * to do anything like reopening the device, either. |
414 * The AIX paud device init can't modify the values of the audio_init | 418 */ |
415 * structure that we pass to it. So we don't need any recalculation | 419 if (ioctl (audio_fd, AUDIO_INIT, &paud_init) < 0) { |
416 * of this stuff and no reinit call as in linux dsp and dma code. | 420 switch (paud_init.rc) { |
417 * | 421 case 1: |
418 * /dev/paud supports all of the encoding formats, so we don't need | 422 SDL_SetError |
419 * to do anything like reopening the device, either. | 423 ("Couldn't set audio format: DSP can't do play requests"); |
420 */ | 424 return -1; |
421 if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 ) { | 425 break; |
422 switch ( paud_init.rc ) | 426 case 2: |
423 { | 427 SDL_SetError |
424 case 1 : | 428 ("Couldn't set audio format: DSP can't do record requests"); |
425 SDL_SetError("Couldn't set audio format: DSP can't do play requests"); | 429 return -1; |
426 return -1; | 430 break; |
427 break; | 431 case 4: |
428 case 2 : | 432 SDL_SetError ("Couldn't set audio format: request was invalid"); |
429 SDL_SetError("Couldn't set audio format: DSP can't do record requests"); | 433 return -1; |
430 return -1; | 434 break; |
431 break; | 435 case 5: |
432 case 4 : | 436 SDL_SetError |
433 SDL_SetError("Couldn't set audio format: request was invalid"); | 437 ("Couldn't set audio format: conflict with open's flags"); |
434 return -1; | 438 return -1; |
435 break; | 439 break; |
436 case 5 : | 440 case 6: |
437 SDL_SetError("Couldn't set audio format: conflict with open's flags"); | 441 SDL_SetError |
438 return -1; | 442 ("Couldn't set audio format: out of DSP MIPS or memory"); |
439 break; | 443 return -1; |
440 case 6 : | 444 break; |
441 SDL_SetError("Couldn't set audio format: out of DSP MIPS or memory"); | 445 default: |
442 return -1; | 446 SDL_SetError |
443 break; | 447 ("Couldn't set audio format: not documented in sys/audio.h"); |
444 default : | 448 return -1; |
445 SDL_SetError("Couldn't set audio format: not documented in sys/audio.h"); | 449 break; |
446 return -1; | 450 } |
447 break; | 451 } |
448 } | 452 |
449 } | 453 /* Allocate mixing buffer */ |
450 | 454 mixlen = spec->size; |
451 /* Allocate mixing buffer */ | 455 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); |
452 mixlen = spec->size; | 456 if (mixbuf == NULL) { |
453 mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | 457 return -1; |
454 if ( mixbuf == NULL ) { | 458 } |
455 return -1; | 459 SDL_memset (mixbuf, spec->silence, spec->size); |
456 } | 460 |
457 SDL_memset(mixbuf, spec->silence, spec->size); | 461 /* |
458 | 462 * Set some paramters: full volume, first speaker that we can find. |
459 /* | 463 * Ignore the other settings for now. |
460 * Set some paramters: full volume, first speaker that we can find. | 464 */ |
461 * Ignore the other settings for now. | 465 paud_change.input = AUDIO_IGNORE; /* the new input source */ |
462 */ | 466 paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ |
463 paud_change.input = AUDIO_IGNORE; /* the new input source */ | 467 paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ |
464 paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ | 468 paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ |
465 paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ | 469 paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ |
466 paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ | 470 paud_change.balance = 0x3fffffff; /* the new balance */ |
467 paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ | 471 paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ |
468 paud_change.balance = 0x3fffffff; /* the new balance */ | 472 paud_change.treble = AUDIO_IGNORE; /* the new treble state */ |
469 paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ | 473 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ |
470 paud_change.treble = AUDIO_IGNORE; /* the new treble state */ | 474 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ |
471 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ | 475 |
472 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ | 476 paud_control.ioctl_request = AUDIO_CHANGE; |
473 | 477 paud_control.request_info = (char *) &paud_change; |
474 paud_control.ioctl_request = AUDIO_CHANGE; | 478 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { |
475 paud_control.request_info = (char*)&paud_change; | 479 #ifdef DEBUG_AUDIO |
476 if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | 480 fprintf (stderr, "Can't change audio display settings\n"); |
477 #ifdef DEBUG_AUDIO | 481 #endif |
478 fprintf(stderr, "Can't change audio display settings\n" ); | 482 } |
479 #endif | 483 |
480 } | 484 /* |
481 | 485 * Tell the device to expect data. Actual start will wait for |
482 /* | 486 * the first write() call. |
483 * Tell the device to expect data. Actual start will wait for | 487 */ |
484 * the first write() call. | 488 paud_control.ioctl_request = AUDIO_START; |
485 */ | 489 paud_control.position = 0; |
486 paud_control.ioctl_request = AUDIO_START; | 490 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { |
487 paud_control.position = 0; | 491 #ifdef DEBUG_AUDIO |
488 if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | 492 fprintf (stderr, "Can't start audio play\n"); |
489 #ifdef DEBUG_AUDIO | 493 #endif |
490 fprintf(stderr, "Can't start audio play\n" ); | 494 SDL_SetError ("Can't start audio play"); |
491 #endif | 495 return -1; |
492 SDL_SetError("Can't start audio play"); | 496 } |
493 return -1; | 497 |
494 } | 498 /* Check to see if we need to use select() workaround */ |
495 | 499 { |
496 /* Check to see if we need to use select() workaround */ | 500 char *workaround; |
497 { char *workaround; | 501 workaround = SDL_getenv ("SDL_DSP_NOSELECT"); |
498 workaround = SDL_getenv("SDL_DSP_NOSELECT"); | 502 if (workaround) { |
499 if ( workaround ) { | 503 frame_ticks = (float) (spec->samples * 1000) / spec->freq; |
500 frame_ticks = (float)(spec->samples*1000)/spec->freq; | 504 next_frame = SDL_GetTicks () + frame_ticks; |
501 next_frame = SDL_GetTicks()+frame_ticks; | 505 } |
502 } | 506 } |
503 } | 507 |
504 | 508 /* Get the parent process id (we're the parent of the audio thread) */ |
505 /* Get the parent process id (we're the parent of the audio thread) */ | 509 parent = getpid (); |
506 parent = getpid(); | 510 |
507 | 511 /* We're ready to rock and roll. :-) */ |
508 /* We're ready to rock and roll. :-) */ | 512 return 0; |
509 return 0; | 513 } |
510 } | 514 |
511 | 515 /* vi: set ts=4 sw=4 expandtab: */ |