comparison src/audio/alsa/SDL_alsa_audio.c @ 4347:38f22ed3a433 SDL-1.2

Option to fix bug #851 For some people setting the period size works better (and is what SDL 1.2.13 did), but for most people it's the same or worse. You can use an environment variable to pick which one you want.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 17 Oct 2009 06:55:17 +0000
parents 819270e2f893
children b312352d8c8d
comparison
equal deleted inserted replaced
4346:5fe9b267cf55 4347:38f22ed3a433
41 41
42 42
43 /* The tag name used by ALSA audio */ 43 /* The tag name used by ALSA audio */
44 #define DRIVER_NAME "alsa" 44 #define DRIVER_NAME "alsa"
45 45
46 /* Whether we should set the buffer size or the period size */
47 /*#define SET_PERIOD_SIZE*/
48 /*#define DEBUG_PERIOD_SIZE*/ 46 /*#define DEBUG_PERIOD_SIZE*/
49 47
50 /* Audio driver functions */ 48 /* Audio driver functions */
51 static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec); 49 static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec);
52 static void ALSA_WaitAudio(_THIS); 50 static void ALSA_WaitAudio(_THIS);
375 snd_pcm_hw_params_t *hwparams; 373 snd_pcm_hw_params_t *hwparams;
376 snd_pcm_sw_params_t *swparams; 374 snd_pcm_sw_params_t *swparams;
377 snd_pcm_format_t format; 375 snd_pcm_format_t format;
378 snd_pcm_uframes_t frames; 376 snd_pcm_uframes_t frames;
379 unsigned int rate; 377 unsigned int rate;
380 #ifdef SET_PERIOD_SIZE
381 unsigned int periods; 378 unsigned int periods;
382 #endif
383 unsigned int channels; 379 unsigned int channels;
384 Uint16 test_format; 380 Uint16 test_format;
385 381
386 /* Open the audio device */ 382 /* Open the audio device */
387 /* Name of device should depend on # channels in spec */ 383 /* Name of device should depend on # channels in spec */
473 return(-1); 469 return(-1);
474 } 470 }
475 spec->freq = rate; 471 spec->freq = rate;
476 472
477 /* Set the buffer size, in samples */ 473 /* Set the buffer size, in samples */
478 #ifdef SET_PERIOD_SIZE 474 if (getenv("SDL_AUDIO_ALSA_SET_PERIOD_SIZE")) {
479 frames = spec->samples; 475 frames = spec->samples;
480 status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL); 476 status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL);
481 if ( status < 0 ) { 477 if ( status < 0 ) {
482 SDL_SetError("Couldn't set period size: %s", SDL_NAME(snd_strerror)(status)); 478 SDL_SetError("Couldn't set period size: %s", SDL_NAME(snd_strerror)(status));
483 ALSA_CloseAudio(this); 479 ALSA_CloseAudio(this);
484 return(-1); 480 return(-1);
485 } 481 }
486 482
487 spec->samples = frames; 483 spec->samples = frames;
488 484
489 periods = 2; 485 periods = 2;
490 status = SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL); 486 status = SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL);
491 if ( status < 0 ) { 487 if ( status < 0 ) {
492 SDL_SetError("Couldn't set period count: %s", SDL_NAME(snd_strerror)(status)); 488 SDL_SetError("Couldn't set period count: %s", SDL_NAME(snd_strerror)(status));
493 ALSA_CloseAudio(this); 489 ALSA_CloseAudio(this);
494 return(-1); 490 return(-1);
495 } 491 }
496 #else 492 } else {
497 frames = spec->samples * 2; 493 frames = spec->samples * 2;
498 status = SDL_NAME(snd_pcm_hw_params_set_buffer_size_near)(pcm_handle, hwparams, &frames); 494 status = SDL_NAME(snd_pcm_hw_params_set_buffer_size_near)(pcm_handle, hwparams, &frames);
499 #endif 495 if ( status < 0 ) {
496 SDL_SetError("Couldn't set buffer size: %s", SDL_NAME(snd_strerror)(status));
497 ALSA_CloseAudio(this);
498 return(-1);
499 }
500 }
500 501
501 /* "set" the hardware with the desired parameters */ 502 /* "set" the hardware with the desired parameters */
502 status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams); 503 status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams);
503 if ( status < 0 ) { 504 if ( status < 0 ) {
504 SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status)); 505 SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status));