comparison src/audio/dsp/SDL_dspaudio.c @ 3826:5b483ce86357 SDL-ryan-multiple-audio-device

Minor fixes in dsp driver.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 07 Oct 2006 07:53:26 +0000
parents 1f156fd874fa
children 66fb40445587
comparison
equal deleted inserted replaced
3825:76c5a414b996 3826:5b483ce86357
187 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 187 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
188 188
189 /* Open the audio device */ 189 /* Open the audio device */
190 this->hidden->audio_fd = open(devname, flags, 0); 190 this->hidden->audio_fd = open(devname, flags, 0);
191 if (this->hidden->audio_fd < 0) { 191 if (this->hidden->audio_fd < 0) {
192 DSP_CloseDevice(this);
192 SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); 193 SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
193 return 0; 194 return 0;
194 } 195 }
195 this->hidden->mixbuf = NULL; 196 this->hidden->mixbuf = NULL;
196 197
197 /* Make the file descriptor use blocking writes with fcntl() */ 198 /* Make the file descriptor use blocking writes with fcntl() */
198 { 199 {
199 long flags; 200 long ctlflags;
200 flags = fcntl(this->hidden->audio_fd, F_GETFL); 201 ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
201 flags &= ~O_NONBLOCK; 202 ctlflags &= ~O_NONBLOCK;
202 if (fcntl(this->hidden->audio_fd, F_SETFL, flags) < 0) { 203 if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
204 DSP_CloseDevice(this);
203 SDL_SetError("Couldn't set audio blocking mode"); 205 SDL_SetError("Couldn't set audio blocking mode");
204 DSP_CloseDevice(this);
205 return 0; 206 return 0;
206 } 207 }
207 } 208 }
208 209
209 /* Get a list of supported hardware formats */ 210 /* Get a list of supported hardware formats */
210 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { 211 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
211 perror("SNDCTL_DSP_GETFMTS"); 212 perror("SNDCTL_DSP_GETFMTS");
213 DSP_CloseDevice(this);
212 SDL_SetError("Couldn't get audio format list"); 214 SDL_SetError("Couldn't get audio format list");
213 DSP_CloseDevice(this);
214 return 0; 215 return 0;
215 } 216 }
216 217
217 /* Try for a closest match on audio format */ 218 /* Try for a closest match on audio format */
218 format = 0; 219 format = 0;
265 if (!format) { 266 if (!format) {
266 test_format = SDL_NextAudioFormat(); 267 test_format = SDL_NextAudioFormat();
267 } 268 }
268 } 269 }
269 if (format == 0) { 270 if (format == 0) {
271 DSP_CloseDevice(this);
270 SDL_SetError("Couldn't find any hardware audio formats"); 272 SDL_SetError("Couldn't find any hardware audio formats");
271 DSP_CloseDevice(this);
272 return 0; 273 return 0;
273 } 274 }
274 this->spec.format = test_format; 275 this->spec.format = test_format;
275 276
276 /* Set the audio format */ 277 /* Set the audio format */
277 value = format; 278 value = format;
278 if ( (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || 279 if ( (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
279 (value != format) ) { 280 (value != format) ) {
280 perror("SNDCTL_DSP_SETFMT"); 281 perror("SNDCTL_DSP_SETFMT");
282 DSP_CloseDevice(this);
281 SDL_SetError("Couldn't set audio format"); 283 SDL_SetError("Couldn't set audio format");
282 DSP_CloseDevice(this);
283 return 0; 284 return 0;
284 } 285 }
285 286
286 /* Set the number of channels of output */ 287 /* Set the number of channels of output */
287 value = this->spec.channels; 288 value = this->spec.channels;
288 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { 289 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
289 perror("SNDCTL_DSP_CHANNELS"); 290 perror("SNDCTL_DSP_CHANNELS");
291 DSP_CloseDevice(this);
290 SDL_SetError("Cannot set the number of channels"); 292 SDL_SetError("Cannot set the number of channels");
291 DSP_CloseDevice(this);
292 return 0; 293 return 0;
293 } 294 }
294 this->spec.channels = value; 295 this->spec.channels = value;
295 296
296 /* Set the DSP frequency */ 297 /* Set the DSP frequency */
297 value = this->spec.freq; 298 value = this->spec.freq;
298 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { 299 if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
299 perror("SNDCTL_DSP_SPEED"); 300 perror("SNDCTL_DSP_SPEED");
301 DSP_CloseDevice(this);
300 SDL_SetError("Couldn't set audio frequency"); 302 SDL_SetError("Couldn't set audio frequency");
301 DSP_CloseDevice(this);
302 return 0; 303 return 0;
303 } 304 }
304 this->spec.freq = value; 305 this->spec.freq = value;
305 306
306 /* Calculate the final parameters for this audio specification */ 307 /* Calculate the final parameters for this audio specification */
307 SDL_CalculateAudioSpec(&this->spec); 308 SDL_CalculateAudioSpec(&this->spec);
308 309
309 /* Determine the power of two of the fragment size */ 310 /* Determine the power of two of the fragment size */
310 for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec); 311 for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
311 if ((0x01U << frag_spec) != this->spec.size) { 312 if ((0x01U << frag_spec) != this->spec.size) {
313 DSP_CloseDevice(this);
312 SDL_SetError("Fragment size must be a power of two"); 314 SDL_SetError("Fragment size must be a power of two");
313 DSP_CloseDevice(this);
314 return 0; 315 return 0;
315 } 316 }
316 frag_spec |= 0x00020000; /* two fragments, for low latency */ 317 frag_spec |= 0x00020000; /* two fragments, for low latency */
317 318
318 /* Set the audio buffering parameters */ 319 /* Set the audio buffering parameters */
337 /* Allocate mixing buffer */ 338 /* Allocate mixing buffer */
338 this->hidden->mixlen = this->spec.size; 339 this->hidden->mixlen = this->spec.size;
339 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); 340 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
340 if (this->hidden->mixbuf == NULL) { 341 if (this->hidden->mixbuf == NULL) {
341 DSP_CloseDevice(this); 342 DSP_CloseDevice(this);
343 SDL_OutOfMemory();
342 return 0; 344 return 0;
343 } 345 }
344 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); 346 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
345 347
346 /* We're ready to rock and roll. :-) */ 348 /* We're ready to rock and roll. :-) */