File libmikmod-alsadrv.patch of Package libmikmod
drv_alsa: Fix stuttering sound and hang on exit
This patch addresses the following 2 issues:
1) With some apps using mikmod's alsa output would lead to stutering sound,
this is caused by setting incorrect swparams from the set_swparams function,
specifically by setting the start threshold to 0.
Since drv_alsa uses alsa_pcm_set_params which already sets sane defaults for
the swparams this patch simply drops the custom set_swparams function.
2) Apps using mikmod's alsa output would hang on exit in snd_pcm_drain because
ALSA_PlayStop would call snd_pcm_pause causing the snd_pcm_drain on exit to
never complete. This patch modifies ALSA_PlayStop to use snd_pcm_drop instead.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
--- libmikmod-3.2.0/drivers/drv_alsa.c 2012-06-01 15:05:53.000000000 +0200
+++ libmikmod-3.2.0.new/drivers/drv_alsa.c 2013-04-06 12:23:24.260062259 +0200
@@ -108,7 +108,7 @@
#ifdef OLD_ALSA
static int(*alsa_pcm_flush_playback)(snd_pcm_t*);
#else
-static int(*alsa_pcm_pause)(snd_pcm_t*, int);
+static int(*alsa_pcm_drop)(snd_pcm_t*);
#endif
#ifdef OLD_ALSA
static int(*alsa_pcm_open)(snd_pcm_t**,int,int,int);
@@ -169,7 +169,7 @@
#ifdef OLD_ALSA
#define alsa_pcm_flush_playback snd_pcm_flush_playback
#else
-#define alsa_pcm_pause snd_pcm_pause
+#define alsa_pcm_drop snd_pcm_drop
#endif
#define alsa_pcm_open snd_pcm_open
#ifdef OLD_ALSA
@@ -199,7 +199,6 @@
static int cardmin=0,cardmax=SND_CARDS;
#else
static snd_pcm_sframes_t period_size;
-static snd_pcm_sframes_t buffer_size_in_frames;
static int bytes_written = 0, bytes_played = 0;
#endif
static int global_frame_size;
@@ -252,7 +251,7 @@
#ifdef OLD_ALSA
if(!(alsa_pcm_flush_playback =dlsym(libasound,"snd_pcm_flush_playback"))) return 1;
#else
- if(!(alsa_pcm_pause =dlsym(libasound,"snd_pcm_pause"))) return 1;
+ if (!(alsa_pcm_drop = dlsym(libasound, "snd_pcm_drop"))) return 1;
#endif
if(!(alsa_pcm_open =dlsym(libasound,"snd_pcm_open"))) return 1;
#ifdef OLD_ALSA
@@ -311,7 +310,7 @@
#ifdef OLD_ALSA
alsa_pcm_flush_playback =NULL;
#else
- alsa_pcm_pause =NULL;
+ alsa_pcm_drop = NULL;
#endif
alsa_pcm_open =NULL;
#ifdef OLD_ALSA
@@ -392,41 +391,6 @@
return retval;
}
-#ifndef OLD_ALSA
-static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
-{
- int err;
-
- /* get the current swparams */
- err = alsa_pcm_sw_params_current(handle, swparams);
- if (err < 0) {
- printf("Unable to determine current swparams for playback: %s\n", alsa_strerror(err));
- return err;
- }
- /* start the transfer when the buffer is almost full: */
- /* (buffer_size / avail_min) * avail_min */
- err = alsa_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size_in_frames / period_size) * period_size);
- if (err < 0) {
- printf("Unable to set start threshold mode for playback: %s\n", alsa_strerror(err));
- return err;
- }
- /* allow the transfer when at least period_size samples can be processed */
- /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
- err = alsa_pcm_sw_params_set_avail_min(handle, swparams, period_size);
- if (err < 0) {
- printf("Unable to set avail min for playback: %s\n", alsa_strerror(err));
- return err;
- }
- /* write the parameters to the playback device */
- err = alsa_pcm_sw_params(handle, swparams);
- if (err < 0) {
- printf("Unable to set sw params for playback: %s\n", alsa_strerror(err));
- return err;
- }
- return 0;
-}
-#endif
-
static BOOL ALSA_Init_internal(void)
{
snd_pcm_format_t pformat;
@@ -648,23 +612,15 @@
printf("Unable to get buffer size for playback: %s\n", alsa_strerror(err));
goto END;
}
- buffer_size_in_frames = 1200;
period_size = temp_u_period_size;
}
-
- /* The set_swparams function was taken from test/pcm.c
- * in the alsa-lib distribution*/
- if ((err = set_swparams(pcm_h, swparams)) < 0) {
- printf("Setting of swparams failed: %s\n", snd_strerror(err));
- goto END;
- }
#endif
if (!(audiobuffer=(SBYTE*)MikMod_malloc(
#ifdef OLD_ALSA
fragmentsize
#else
- buffer_size_in_frames * global_frame_size
+ period_size * global_frame_size
#endif
))) {
#ifdef OLD_ALSA
@@ -796,7 +752,8 @@
{
if (bytes_written == 0 || bytes_played == bytes_written)
{
- bytes_written = VC_WriteBytes(audiobuffer,buffer_size_in_frames * global_frame_size);
+ bytes_written = VC_WriteBytes(audiobuffer,
+ period_size * global_frame_size);
bytes_played = 0;
}
@@ -827,7 +784,7 @@
#ifdef OLD_ALSA
alsa_pcm_flush_playback(pcm_h);
#else
- alsa_pcm_pause(pcm_h, 1);
+ alsa_pcm_drop(pcm_h);
#endif
}