[libmikmod] Fix stuttering sound and hang on exit for apps using libmikmod's alsa driver
Hans de Goede
jwrdegoede at fedoraproject.org
Sat Apr 6 12:02:23 UTC 2013
commit 479d52a35e65a839d41a40807f7c3af9f31d8ab9
Author: Hans de Goede <hdegoede at redhat.com>
Date: Sat Apr 6 14:06:17 2013 +0200
Fix stuttering sound and hang on exit for apps using libmikmod's alsa driver
- Remove non standard options configure adds to CFLAGS
- Run autoreconf for aarch64 support (rhbz#925794)
libmikmod-alsadrv.patch | 148 +++++++++++++++++++++++++++++++++++++++++++++++
libmikmod-cflags.patch | 71 ++++++++++++++++++++++
libmikmod.spec | 14 ++++-
3 files changed, 231 insertions(+), 2 deletions(-)
---
diff --git a/libmikmod-alsadrv.patch b/libmikmod-alsadrv.patch
new file mode 100644
index 0000000..da3f4fa
--- /dev/null
+++ b/libmikmod-alsadrv.patch
@@ -0,0 +1,148 @@
+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 at 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
+ }
+
diff --git a/libmikmod-cflags.patch b/libmikmod-cflags.patch
new file mode 100644
index 0000000..fbe6349
--- /dev/null
+++ b/libmikmod-cflags.patch
@@ -0,0 +1,71 @@
+diff -up libmikmod-3.2.0/config.h.in~ libmikmod-3.2.0/config.h.in
+diff -up libmikmod-3.2.0/configure.in~ libmikmod-3.2.0/configure.in
+--- libmikmod-3.2.0/configure.in~ 2012-06-01 15:15:29.000000000 +0200
++++ libmikmod-3.2.0/configure.in 2013-04-06 12:43:30.200076725 +0200
+@@ -634,66 +634,6 @@ then
+ fi
+ fi
+
+-# If compiling with gcc, use adequate optimization flags
+-if test $ac_cv_prog_gcc = yes
+-then
+- # On at least x86 platforms, gcc 2.7.2.1 and earlier won't work if -O3 (or
+- # -finline-functions) are used. Versions 2.7.2.3, 2.8.x and egcs are ok
+- # (didn't test 2.7.2.2).
+- # Until there's an easy way to catch broken inlining, we choose flags known
+- # to work correctly depending of the compiler version.
+- AC_CACHE_CHECK([if inlining functions is safe],
+- libmikmod_cv_gcc_inline_safe,
+- AC_TRY_RUN([
+-int main()
+-{
+-#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ > 7)
+- exit(0);
+-#else
+- exit(1);
+-#endif
+-}],
+- libmikmod_cv_gcc_inline_safe=yes,
+- libmikmod_cv_gcc_inline_safe=no,
+- libmikmod_cv_gcc_inline_safe=no))
+- if test $libmikmod_cv_gcc_inline_safe = yes
+- then
+- CFLAGS="$CFLAGS -finline-functions"
+- else
+- CFLAGS="$CFLAGS -fno-strength-reduce"
+- fi
+- CFLAGS="$CFLAGS -funroll-loops -ffast-math"
+- if test $libmikmod_debug = yes
+- then
+- CFLAGS="$CFLAGS -Wall -Werror"
+- else
+- CFLAGS="$CFLAGS -Wall"
+- fi
+-
+- # pgcc 2.95.2 appears not to be able to compile libmikmod, although regular
+- # gcc works fine. Issue a warning if the compiler is pgcc, until a reliable
+- # way to detect flawed version (or, better, a reliable workaround) is
+- # found.
+-dnl do not cache this test - better rechecking every time
+- AC_MSG_CHECKING(if compiler is pgcc)
+- if ($CC -v 2>&1 | grep ^pgcc > /dev/null) 2>/dev/null
+- then
+- libmikmod_gcc_is_pgcc=yes
+- else
+- libmikmod_gcc_is_pgcc=no
+- fi
+- AC_MSG_RESULT($libmikmod_gcc_is_pgcc)
+- if test $libmikmod_gcc_is_pgcc = yes
+- then
+- echo "
+-*** Version 2.95.2 of this compiler, and perhaps others, are unable to
+-*** compile libmikmod. If compilation fails for playercode/virtch.c
+-*** around line 650, with the error ``internal error--insn does not
+-*** satisfy its constraints'', then you'll have to use another compiler.
+-" >&2
+- fi
+-fi
+-
+ if test x$libmikmod_threads != xno
+ then
+ AC_DEFINE(HAVE_PTHREAD)
diff --git a/libmikmod.spec b/libmikmod.spec
index 93d2692..d7f8235 100644
--- a/libmikmod.spec
+++ b/libmikmod.spec
@@ -1,7 +1,7 @@
Summary: A MOD music file player library
Name: libmikmod
Version: 3.2.0
-Release: 20%{?dist}
+Release: 21%{?dist}
License: GPLv2 and LGPLv2+
Group: Applications/Multimedia
URL: http://mikmod.shlomifish.org/
@@ -13,7 +13,9 @@ Patch3: libmikmod-CVE-2007-6720.patch
Patch4: libmikmod-CVE-2009-0179.patch
# Fix rhbz#855130
Patch5: libmikmod-malloc-fail.patch
-BuildRequires: alsa-lib-devel
+Patch6: libmikmod-alsadrv.patch
+Patch7: libmikmod-cflags.patch
+BuildRequires: alsa-lib-devel libtool
%description
libmikmod is a library used by the mikmod MOD music file player for
@@ -42,6 +44,9 @@ applications for mikmod.
%patch3 -p1
%patch4 -p1
%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+autoreconf -i -f
%build
@@ -83,6 +88,11 @@ fi
%changelog
+* Sat Apr 6 2013 Hans de Goede <hdegoede at redhat.com> - 3.2.0-21
+- Fix stuttering sound and hang on exit for apps using libmikmod's alsa driver
+- Remove non standard options configure adds to CFLAGS
+- Run autoreconf for aarch64 support (rhbz#925794)
+
* Thu Feb 14 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 3.2.0-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
More information about the scm-commits
mailing list