squeezelite: Import new package
authorTed Hess <redacted>
Fri, 17 Jul 2015 16:12:18 +0000 (12:12 -0400)
committerTed Hess <redacted>
Fri, 17 Jul 2015 16:12:18 +0000 (12:12 -0400)
Signed-off-by: Ted Hess <redacted>
sound/squeezelite/Makefile [new file with mode: 0644]
sound/squeezelite/files/squeezelite.conf [new file with mode: 0644]
sound/squeezelite/files/squeezelite.init [new file with mode: 0644]
sound/squeezelite/patches/005-respect_LDFLAGS.patch [new file with mode: 0644]
sound/squeezelite/patches/010-wait_for_nonzero_mac.patch [new file with mode: 0644]
sound/squeezelite/patches/020-no_mpg123.patch [new file with mode: 0644]
sound/squeezelite/patches/030-fix_musl_compatibilty.patch [new file with mode: 0644]
sound/squeezelite/patches/040-clear_dynlink_errors.patch [new file with mode: 0644]

diff --git a/sound/squeezelite/Makefile b/sound/squeezelite/Makefile
new file mode 100644 (file)
index 0000000..8a1274c
--- /dev/null
@@ -0,0 +1,146 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=squeezelite
+PKG_VERSION:=1.8
+PKG_RELEASE=1
+
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_MAINTAINER:= Ted Hess <thess@kitschensync.net>
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://code.google.com/p/squeezelite/
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=8b8dfe6918ebe45ade5f3d9b68d453d7b8128d99
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_BUILD_DEPENDS:=libflac libvorbis libmad libfaad2 SQUEEZELITE_WMA:libffmpeg-audio-dec
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/squeezelite/default
+    SECTION:=sound
+    CATEGORY:=Sound
+    TITLE:=Headless squeezebox emulator
+    PROVIDES:=squeezelite
+    URL:=https://code.google.com/p/squeezelite/
+    DEPENDS:= +alsa-lib +SQUEEZELITE_RESAMPLE:libsoxr
+    MENU:=1
+endef
+
+define Package/squeezelite-full
+    $(call Package/squeezelite/default)
+    TITLE+= (full)
+    DEPENDS+= +libflac +libvorbis +libmad +libfaad2 \
+              +SQUEEZELITE_WMA:libffmpeg-audio-dec
+    VARIANT:=full
+endef
+
+define Package/squeezelite-mini
+    $(call Package/squeezelite/default)
+    TITLE+= (minimal)
+    VARIANT:=mini
+endef
+
+define Package/squeezelite/config/default
+
+       config SQUEEZELITE_WMA
+           bool "WMA/ALAC decode support"
+           help
+               Include WMA and ALAC decoding using ffmpeg
+           default n
+
+       config SQUEEZELITE_RESAMPLE
+           bool "Resample support"
+           help
+               Include support for resampling using libsoxr
+           default n
+
+       config SQUEEZELITE_DSD
+           bool "DSD playback over PCM (DoP)"
+           help
+               Include support for DSD over PCM for compatible DAC"
+           default n
+endef
+
+define Package/squeezelite-full/config
+    if PACKAGE_squeezelite-full
+       $(call Package/squeezelite/config/default)
+    endif
+endef
+
+define Package/squeezelite-mini/config
+    if PACKAGE_squeezelite-mini
+       $(call Package/squeezelite/config/default)
+    endif
+endef
+
+define Package/squeezelite/description/default
+    Squeezelite is a small headless squeezebox emulator for linux using alsa audio output 
+    It is aimed at supporting high quality audio at multiple sample rates including 
+    44.1/48/88.2/96/176.4/192k/352.8/384kHz 
+    Supported codecs: mp3, flac, ogg, aac, (wma and alac via ffmpeg) 
+    Native support for PCM builtin
+    Optional support of DSD playback via PCM for DoP capable DAC
+    Optional resampling to match sound device
+endef
+
+define Package/squeezelite/description
+    $(call Package/squeezelite/description/default)
+    .
+    This package has all the audio codecs compiled in.
+endef
+
+define Package/squeezelite-mini/description
+    $(call Package/squeezelite/description/default)
+    .
+    This package will dynamically load installed codecs.
+endef
+
+#ifeq ($(CONFIG_SQUEEZELITE_WMA),y)
+#    PKG_BUILD_DEPENDS+= libffmpeg-audio-dec
+#endif
+
+TARGET_CFLAGS+= -Wall -fPIC -O2 -DSELFPIPE
+
+ifeq ($(CONFIG_SQUEEZELITE_WMA),y)
+    TARGET_CFLAGS+= -DFFMPEG
+endif
+
+ifeq ($(CONFIG_SQUEEZELITE_DSD),y)
+    TARGET_CFLAGS+= -DDSD
+endif
+
+ifeq ($(CONFIG_SQUEEZELITE_RESAMPLE),y)
+    TARGET_CFLAGS+= -DRESAMPLE
+endif
+
+TARGET_LDFLAGS+= -lasound -lpthread -lm -lrt
+
+ifeq ($(BUILD_VARIANT),full)
+    TARGET_CFLAGS+= -DLINKALL
+endif
+
+define Package/squeezelite/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/squeezelite $(1)/usr/bin
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/squeezelite.init $(1)/etc/init.d/squeezelite
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_CONF) ./files/squeezelite.conf $(1)/etc/config/squeezelite
+endef
+
+Package/squeezelite-mini/install=$(Package/squeezelite/install)
+Package/squeezelite-full/install=$(Package/squeezelite/install)
+
+$(eval $(call BuildPackage,squeezelite-mini))
+$(eval $(call BuildPackage,squeezelite-full))
diff --git a/sound/squeezelite/files/squeezelite.conf b/sound/squeezelite/files/squeezelite.conf
new file mode 100644 (file)
index 0000000..57d1b73
--- /dev/null
@@ -0,0 +1,12 @@
+
+config options 'options'
+       option name 'SqueezeWrt'
+       option model_name 'SqueezeLite'
+       option close_delay '0'
+       option priority '0'
+       option max_sr '0'
+       option device 'hw:0,0'
+       option decoder_auto_conf '1'
+       option dsd_over_pcm '0'
+       option ircontrol '0'
+       option enabled '1'
diff --git a/sound/squeezelite/files/squeezelite.init b/sound/squeezelite/files/squeezelite.init
new file mode 100644 (file)
index 0000000..3fa008f
--- /dev/null
@@ -0,0 +1,134 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=99
+STOP=1
+
+USE_PROCD=1
+PROG=/usr/bin/squeezelite
+
+#
+# Auto config checks for existing codec installations if not specified in config
+# Explicit disable (override) by setting appropriate "decode_xxx" in config
+#
+checkcodec() {
+       config_get_bool auto_conf options "decoder_auto_conf" 1
+       config_get_bool codec options "$1" $auto_conf
+       
+       if [ $codec -ne 0 ] ; then 
+               if [ $auto_conf -eq 0 ] ; then
+                       #force use requested
+                       echo "$4"
+               else
+                       if [ -e "/usr/lib/${2}" ] ; then
+                               # Use codec (it exists)
+                               echo "$4"
+                       else
+                               #exclude non-existant
+                               if [ -z "$4" ] ; then
+                                       echo "-e $3"
+                               else
+                                       echo "$4,$3"
+                               fi
+                       fi
+               fi
+       else
+               # explicitly excluded
+               if [ -z "$4" ] ; then
+                       echo "-e $3"
+               else
+                       echo "$4,$3"
+               fi
+       fi
+}
+
+make_cmdline() {
+       cmdline=""
+
+       config_get name options name "SqueezeWrt"
+       cmdline="$cmdline -n $name"
+
+       config_get model_name options model_name "SqueezeLite"
+       cmdline="$cmdline -M $model_name"
+
+       config_get device options device ""
+       [ -n $device ] && cmdline="$cmdline -o $device"
+
+       config_get alsa_buffer options alsa_buffer 200
+       [ $alsa_buffer -eq 0 ] && alsa_buffer="200"
+    
+       config_get alsa_period options alsa_period 4
+       [ $alsa_period -eq 0 ] && alsa_period="4"
+    
+       config_get alsa_format options alsa_format 16
+       [ $alsa_format = "0" ] && alsa_format="16"
+
+       config_get alsa_mmap options alsa_mmap 0
+       cmdline="$cmdline -a $alsa_buffer:$alsa_period:$alsa_format:$alsa_mmap"
+
+       config_get stream_bufsiz options stream_bufsiz 2048
+       config_get out_bufsiz options out_bufsiz 3763
+       cmdline="$cmdline -b $stream_bufsiz:$out_bufsiz"
+
+       config_get max_sr options max_sr 0
+       if [ $max_sr -ne 0 ] ; then
+               max_sr="-r $max_sr"
+
+               config_get sr_delay options sr_delay 0
+               [ $sr_delay -ne 0 ] &&  max_sr="$max_sr:$sr_delay"
+               cmdline="$cmdline $max_sr"
+       fi
+
+
+       config_get close_delay options close_delay 0
+       [ $close_delay -ne 0 ] && cmdline="$cmdline -C $close_delay"
+
+       config_get server_addr options server_addr ""
+       if [ -n "$server_addr" ] ; then
+               config_get server_port options server_port 3483
+               cmdline="$cmdline -s $server_addr:$server_port"
+       fi
+
+       config_get priority options priority 0
+       [ $priority -ne 0 ] && cmdline="$cmdline -p $priority"
+
+       #
+       # ***NOTE: codec lib names are in squeezelite.h (set decode_auto_conf to 0 to ignore)
+       #
+       local excl_codecs=""
+       excl_codecs=`checkcodec decode_flac "libFLAC.so.8" flac "$excl_codecs"`
+       excl_codecs=`checkcodec decode_mp3 "libmad.so.0" mp3 "$excl_codecs"`
+       excl_codecs=`checkcodec decode_aac "libfaad.so.2" aac "$excl_codecs"`
+       excl_codecs=`checkcodec decode_ogg "libvorbisfile.so.3" ogg "$excl_codecs"`
+       excl_codecs=`checkcodec decode_wma_alac "libavcodec.so.56" wma,alac "$excl_codecs"`
+       cmdline="$cmdline $excl_codecs"
+
+       config_get dop options dsd_over_pcm 0
+       [ $dop -eq 1 ] && cmdline="$cmdline -D"
+}
+
+start_service() {
+       config_load squeezelite
+
+       config_get_bool enabled options 'enabled' 0
+       [ $enabled -eq 0 ] && return
+
+       # Build command params
+       make_cmdline
+
+       procd_open_instance
+       logger -t 'squeezelite' "$cmdline"
+       procd_set_param command "$PROG" $cmdline
+       procd_close_instance
+}
+
+# Wait for service to exit and release sockets
+reload_service() {
+       stop
+       sleep 2
+       start
+}
+
+restart() {
+       reload_service
+}
diff --git a/sound/squeezelite/patches/005-respect_LDFLAGS.patch b/sound/squeezelite/patches/005-respect_LDFLAGS.patch
new file mode 100644 (file)
index 0000000..d8df7ca
--- /dev/null
@@ -0,0 +1,56 @@
+From 1c53ed7db5b49ebf347efe65dbf9b740f9d54557 Mon Sep 17 00:00:00 2001
+From: Carlo Landmeter <clandmeter@gmail.com>
+Date: Tue, 31 Mar 2015 09:52:53 +0000
+Subject: [PATCH] respect LDFLAGS
+
+---
+ Makefile | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,7 @@
+ # Cross compile support - create a Makefile which defines these three variables and then includes this Makefile...
+-CFLAGS  ?= -Wall -fPIC -O2 $(OPTS)
+-LDFLAGS ?= -lasound -lpthread -lm -lrt
++CFLAGS  ?= -Wall -O2
++CFLAGS  += -fPIC $(OPTS)
++LIBS ?= -lasound -lpthread -lm -lrt
+ EXECUTABLE ?= squeezelite
+ # passing one or more of these in $(OPTS) enables optional feature inclusion
+@@ -52,20 +53,20 @@ endif
+ # add optional link options
+ ifneq (,$(findstring $(OPT_LINKALL), $(CFLAGS)))
+-      LDFLAGS += $(LINKALL)
++      LIBS += $(LINKALL)
+ ifneq (,$(findstring $(OPT_FF), $(CFLAGS)))
+-      LDFLAGS += $(LINKALL_FF)
++      LIBS += $(LINKALL_FF)
+ endif
+ ifneq (,$(findstring $(OPT_RESAMPLE), $(CFLAGS)))
+-      LDFLAGS += $(LINKALL_RESAMPLE)
++      LIBS += $(LINKALL_RESAMPLE)
+ endif
+ ifneq (,$(findstring $(OPT_IR), $(CFLAGS)))
+-      LDFLAGS += $(LINKALL_IR)
++      LIBS += $(LINKALL_IR)
+ endif
+ else
+ # if not LINKALL and linux add LINK_LINUX
+ ifeq ($(UNAME), Linux)
+-      LDFLAGS += $(LINK_LINUX)
++      LIBS += $(LINK_LINUX)
+ endif
+ endif
+@@ -74,7 +75,7 @@ OBJECTS = $(SOURCES:.c=.o)
+ all: $(EXECUTABLE)
+ $(EXECUTABLE): $(OBJECTS)
+-      $(CC) $(OBJECTS) $(LDFLAGS) -o $@
++      $(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -o $@
+ $(OBJECTS): $(DEPS)
diff --git a/sound/squeezelite/patches/010-wait_for_nonzero_mac.patch b/sound/squeezelite/patches/010-wait_for_nonzero_mac.patch
new file mode 100644 (file)
index 0000000..69d4f34
--- /dev/null
@@ -0,0 +1,30 @@
+--- a/main.c
++++ b/main.c
+@@ -187,6 +187,17 @@ static void sighandler(int signum) {
+       signal(signum, SIG_DFL);
+ }
++// Waits for nonzero MAC
++static void get_nonzero_mac(u8_t mac[], u32_t timeout_ms) {
++      u32_t wait_timeout = gettime_ms() + timeout_ms;
++      do{
++              get_mac(mac);
++              if ((mac[0]+mac[1]+mac[2]+mac[3]+mac[4]+mac[5]) != 0) {
++                      break;
++              }
++      }while(wait_timeout > gettime_ms());
++}
++
+ int main(int argc, char **argv) {
+       char *server = NULL;
+       char *output_device = "default";
+@@ -240,7 +251,8 @@ int main(int argc, char **argv) {
+ #define MAXCMDLINE 512
+       char cmdline[MAXCMDLINE] = "";
+-      get_mac(mac);
++      // Waits for nonzero MAC
++      get_nonzero_mac(mac,10000);
+       for (i = 0; i < argc && (strlen(argv[i]) + strlen(cmdline) + 2 < MAXCMDLINE); i++) {
+               strcat(cmdline, argv[i]);
diff --git a/sound/squeezelite/patches/020-no_mpg123.patch b/sound/squeezelite/patches/020-no_mpg123.patch
new file mode 100644 (file)
index 0000000..c3eb5d0
--- /dev/null
@@ -0,0 +1,83 @@
+--- a/Makefile
++++ b/Makefile
+@@ -15,7 +15,7 @@ OPT_IR      = -DIR
+ SOURCES = \
+       main.c slimproto.c buffer.c stream.c utils.c \
+       output.c output_alsa.c output_pa.c output_stdout.c output_pack.c decode.c \
+-      flac.c pcm.c mad.c vorbis.c faad.c mpg.c
++      flac.c pcm.c mad.c vorbis.c faad.c
+ SOURCES_DSD      = dsd.c dop.c dsd2pcm/dsd2pcm.c
+ SOURCES_FF       = ffmpeg.c
+@@ -25,7 +25,7 @@ SOURCES_IR       = ir.c
+ LINK_LINUX       = -ldl
+-LINKALL          = -lFLAC -lmad -lvorbisfile -lfaad -lmpg123
++LINKALL          = -lFLAC -lmad -lvorbisfile -lfaad
+ LINKALL_FF       = -lavcodec -lavformat -lavutil
+ LINKALL_RESAMPLE = -lsoxr
+ LINKALL_IR       = -llirc_client
+--- a/decode.c
++++ b/decode.c
+@@ -146,8 +146,8 @@ void decode_init(log_level level, const
+       // try mad then mpg for mp3 unless command line option passed
+       if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mad")) &&
+               (!include_codecs || strstr(include_codecs, "mp3") || strstr(include_codecs, "mad")))    codecs[i] = register_mad();
+-      if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mpg")) && !codecs[i] &&
+-              (!include_codecs || strstr(include_codecs, "mp3") || strstr(include_codecs, "mpg")))    codecs[i] = register_mpg();
++//    if (!(strstr(exclude_codecs, "mp3") || strstr(exclude_codecs, "mpg")) && !codecs[i] &&
++//            (!include_codecs || strstr(include_codecs, "mp3") || strstr(include_codecs, "mpg")))    codecs[i] = register_mpg();
+       mutex_create(decode.mutex);
+--- a/main.c
++++ b/main.c
+@@ -35,7 +35,8 @@
+ #else
+ #define CODECS_DSD  ""
+ #endif
+-#define CODECS_MP3  " (mad,mpg for specific mp3 codec)"
++//#define CODECS_MP3  " (mad,mpg for specific mp3 codec)"
++#define CODECS_MP3  " (mad for specific mp3 codec)"
+ #define CODECS CODECS_BASE CODECS_FF CODECS_DSD CODECS_MP3
+--- a/squeezelite.h
++++ b/squeezelite.h
+@@ -140,7 +140,7 @@
+ #if LINUX
+ #define LIBFLAC "libFLAC.so.8"
+ #define LIBMAD  "libmad.so.0"
+-#define LIBMPG "libmpg123.so.0"
++//#define LIBMPG "libmpg123.so.0"
+ #define LIBVORBIS "libvorbisfile.so.3"
+ #define LIBTREMOR "libvorbisidec.so.1"
+ #define LIBFAAD "libfaad.so.2"
+@@ -154,7 +154,7 @@
+ #if OSX
+ #define LIBFLAC "libFLAC.8.dylib"
+ #define LIBMAD  "libmad.0.dylib"
+-#define LIBMPG "libmpg123.0.dylib"
++//#define LIBMPG "libmpg123.0.dylib"
+ #define LIBVORBIS "libvorbisfile.3.dylib"
+ #define LIBTREMOR "libvorbisidec.1.dylib"
+ #define LIBFAAD "libfaad.2.dylib"
+@@ -167,7 +167,7 @@
+ #if WIN
+ #define LIBFLAC "libFLAC.dll"
+ #define LIBMAD  "libmad-0.dll"
+-#define LIBMPG "libmpg123-0.dll"
++//#define LIBMPG "libmpg123-0.dll"
+ #define LIBVORBIS "libvorbisfile.dll"
+ #define LIBTREMOR "libvorbisidec.dll"
+ #define LIBFAAD "libfaad2.dll"
+@@ -180,7 +180,7 @@
+ #if FREEBSD
+ #define LIBFLAC "libFLAC.so.11"
+ #define LIBMAD  "libmad.so.2"
+-#define LIBMPG "libmpg123.so.0"
++//#define LIBMPG "libmpg123.so.0"
+ #define LIBVORBIS "libvorbisfile.so.6"
+ #define LIBTREMOR "libvorbisidec.so.1"
+ #define LIBFAAD "libfaad.so.2"
diff --git a/sound/squeezelite/patches/030-fix_musl_compatibilty.patch b/sound/squeezelite/patches/030-fix_musl_compatibilty.patch
new file mode 100644 (file)
index 0000000..86e5260
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/output_alsa.c
++++ b/output_alsa.c
+@@ -862,8 +862,11 @@ void output_init_alsa(log_level level, c
+               LOG_INFO("memory locked");
+       }
++#ifdef M_TRIM_THRESHOLD
++      // mallopt is not defined in musl libc
+       mallopt(M_TRIM_THRESHOLD, -1);
+       mallopt(M_MMAP_MAX, 0);
++#endif
+       touch_memory(silencebuf, MAX_SILENCE_FRAMES * BYTES_PER_FRAME);
+       touch_memory(outputbuf->buf, outputbuf->size);
diff --git a/sound/squeezelite/patches/040-clear_dynlink_errors.patch b/sound/squeezelite/patches/040-clear_dynlink_errors.patch
new file mode 100644 (file)
index 0000000..1571572
--- /dev/null
@@ -0,0 +1,105 @@
+--- a/faad.c
++++ b/faad.c
+@@ -593,6 +593,8 @@ static bool load_faad() {
+               return false;
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       a->NeAACDecGetCurrentConfiguration = dlsym(handle, "NeAACDecGetCurrentConfiguration");
+       a->NeAACDecSetConfiguration = dlsym(handle, "NeAACDecSetConfiguration");
+       a->NeAACDecOpen = dlsym(handle, "NeAACDecOpen");
+--- a/ffmpeg.c
++++ b/ffmpeg.c
+@@ -590,6 +590,8 @@ static bool load_ff() {
+               return false;
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       sprintf(name, LIBAVFORMAT, LIBAVFORMAT_VERSION_MAJOR);
+       handle_format = dlopen(name, RTLD_NOW);
+       if (!handle_format) {
+--- a/flac.c
++++ b/flac.c
+@@ -241,6 +241,8 @@ static bool load_flac() {
+               return false;
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       f->FLAC__StreamDecoderErrorStatusString = dlsym(handle, "FLAC__StreamDecoderErrorStatusString");
+       f->FLAC__StreamDecoderStateString = dlsym(handle, "FLAC__StreamDecoderStateString");
+       f->FLAC__stream_decoder_new = dlsym(handle, "FLAC__stream_decoder_new");
+--- a/ir.c
++++ b/ir.c
+@@ -167,10 +167,10 @@ static void *ir_thread() {
+                       UNLOCK_I;
+                       wake_controller();
+               }
+-              
++
+               free(code);
+       }
+-      
++
+       return 0;
+ }
+@@ -184,6 +184,8 @@ static bool load_lirc() {
+               return false;
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       i->lirc_init = dlsym(handle, "lirc_init");
+       i->lirc_deinit = dlsym(handle, "lirc_deinit");
+       i->lirc_readconfig = dlsym(handle, "lirc_readconfig");
+--- a/mad.c
++++ b/mad.c
+@@ -364,7 +364,9 @@ static bool load_mad() {
+               LOG_INFO("dlerror: %s", dlerror());
+               return false;
+       }
+-      
++
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       m->mad_stream_init = dlsym(handle, "mad_stream_init");
+       m->mad_frame_init = dlsym(handle, "mad_frame_init");
+       m->mad_synth_init = dlsym(handle, "mad_synth_init");
+--- a/mpg.c
++++ b/mpg.c
+@@ -221,7 +221,9 @@ static bool load_mpg() {
+               LOG_INFO("dlerror: %s", dlerror());
+               return false;
+       }
+-      
++
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       m->mpg123_init = dlsym(handle, "mpg123_init");
+       m->mpg123_feature = dlsym(handle, "mpg123_feature");
+       m->mpg123_rates = dlsym(handle, "mpg123_rates");
+--- a/resample.c
++++ b/resample.c
+@@ -250,6 +250,8 @@ static bool load_soxr(void) {
+               return false;
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       r->soxr_io_spec = dlsym(handle, "soxr_io_spec");
+       r->soxr_quality_spec = dlsym(handle, "soxr_quality_spec");
+       r->soxr_create = dlsym(handle, "soxr_create");
+--- a/vorbis.c
++++ b/vorbis.c
+@@ -286,6 +286,8 @@ static bool load_vorbis() {
+               }
+       }
++      err = dlerror();        // Reset previous dynamic linking error string (if there was)
++
+       v->ov_read = tremor ? NULL : dlsym(handle, "ov_read");
+       v->ov_read_tremor = tremor ? dlsym(handle, "ov_read") : NULL;
+       v->ov_info = dlsym(handle, "ov_info");
git clone https://git.99rst.org/PROJECT