opus support using opusfile library (bug #4200)
authorOzkan Sezer <sezeroz@gmail.com>
Fri, 15 Jun 2018 08:32:56 +0300
changeset 855a7dee77dd60f
parent 854 ce5fdb8f1c55
child 856 2515d1444557
opus support using opusfile library (bug #4200)
SDL_mixer.h
configure
configure.in
mixer.c
music.c
music.h
music_opus.c
music_opus.h
     1.1 --- a/SDL_mixer.h	Tue Jun 12 13:45:37 2018 +0300
     1.2 +++ b/SDL_mixer.h	Fri Jun 15 08:32:56 2018 +0300
     1.3 @@ -80,7 +80,8 @@
     1.4      MIX_INIT_MOD    = 0x00000002,
     1.5      MIX_INIT_MP3    = 0x00000008,
     1.6      MIX_INIT_OGG    = 0x00000010,
     1.7 -    MIX_INIT_MID    = 0x00000020
     1.8 +    MIX_INIT_MID    = 0x00000020,
     1.9 +    MIX_INIT_OPUS   = 0x00000040
    1.10  } MIX_InitFlags;
    1.11  
    1.12  /* Loads dynamic libraries and prepares them for use.  Flags should be
    1.13 @@ -134,7 +135,8 @@
    1.14      MUS_MP3,
    1.15      MUS_MP3_MAD_UNUSED,
    1.16      MUS_FLAC,
    1.17 -    MUS_MODPLUG_UNUSED
    1.18 +    MUS_MODPLUG_UNUSED,
    1.19 +    MUS_OPUS
    1.20  } Mix_MusicType;
    1.21  
    1.22  /* The internal format for a music chunk interpreted via mikmod */
     2.1 --- a/configure	Tue Jun 12 13:45:37 2018 +0300
     2.2 +++ b/configure	Fri Jun 15 08:32:56 2018 +0300
     2.3 @@ -781,6 +781,8 @@
     2.4  VERSION_OBJECTS
     2.5  OBJECTS
     2.6  ac_aux_dir
     2.7 +OPUSFILE_LIBS
     2.8 +OPUSFILE_CFLAGS
     2.9  SMPEG_LIBS
    2.10  SMPEG_CFLAGS
    2.11  SMPEG_CONFIG
    2.12 @@ -922,6 +924,8 @@
    2.13  enable_music_mp3_mad_gpl_dithering
    2.14  enable_music_mp3_mpg123
    2.15  enable_music_mp3_mpg123_shared
    2.16 +enable_music_opus
    2.17 +enable_music_opus_shared
    2.18  '
    2.19        ac_precious_vars='build_alias
    2.20  host_alias
    2.21 @@ -936,7 +940,9 @@
    2.22  SDL_CFLAGS
    2.23  SDL_LIBS
    2.24  MODPLUG_CFLAGS
    2.25 -MODPLUG_LIBS'
    2.26 +MODPLUG_LIBS
    2.27 +OPUSFILE_CFLAGS
    2.28 +OPUSFILE_LIBS'
    2.29  
    2.30  
    2.31  # Initialize some variables set by options.
    2.32 @@ -1598,6 +1604,9 @@
    2.33                            enable MP3 music via libmpg123 [[default=yes]]
    2.34    --enable-music-mp3-mpg123-shared
    2.35                            dynamically load libmpg123 library [[default=yes]]
    2.36 +  --enable-music-opus     enable Opus music [[default=yes]]
    2.37 +  --enable-music-opus-shared
    2.38 +                          dynamically load opusfile library [[default=yes]]
    2.39  
    2.40  Optional Packages:
    2.41    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
    2.42 @@ -1627,6 +1636,10 @@
    2.43                C compiler flags for MODPLUG, overriding pkg-config
    2.44    MODPLUG_LIBS
    2.45                linker flags for MODPLUG, overriding pkg-config
    2.46 +  OPUSFILE_CFLAGS
    2.47 +              C compiler flags for OPUSFILE, overriding pkg-config
    2.48 +  OPUSFILE_LIBS
    2.49 +              linker flags for OPUSFILE, overriding pkg-config
    2.50  
    2.51  Use these variables to override the choices made by `configure' or to help
    2.52  it to find libraries and programs with nonstandard names/locations.
    2.53 @@ -3930,13 +3943,13 @@
    2.54  else
    2.55    lt_cv_nm_interface="BSD nm"
    2.56    echo "int some_variable = 0;" > conftest.$ac_ext
    2.57 -  (eval echo "\"\$as_me:3933: $ac_compile\"" >&5)
    2.58 +  (eval echo "\"\$as_me:3946: $ac_compile\"" >&5)
    2.59    (eval "$ac_compile" 2>conftest.err)
    2.60    cat conftest.err >&5
    2.61 -  (eval echo "\"\$as_me:3936: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
    2.62 +  (eval echo "\"\$as_me:3949: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
    2.63    (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
    2.64    cat conftest.err >&5
    2.65 -  (eval echo "\"\$as_me:3939: output\"" >&5)
    2.66 +  (eval echo "\"\$as_me:3952: output\"" >&5)
    2.67    cat conftest.out >&5
    2.68    if $GREP 'External.*some_variable' conftest.out > /dev/null; then
    2.69      lt_cv_nm_interface="MS dumpbin"
    2.70 @@ -5147,7 +5160,7 @@
    2.71    ;;
    2.72  *-*-irix6*)
    2.73    # Find out which ABI we are using.
    2.74 -  echo '#line 5150 "configure"' > conftest.$ac_ext
    2.75 +  echo '#line 5163 "configure"' > conftest.$ac_ext
    2.76    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
    2.77    (eval $ac_compile) 2>&5
    2.78    ac_status=$?
    2.79 @@ -6977,11 +6990,11 @@
    2.80     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.81     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.82     -e 's:$: $lt_compiler_flag:'`
    2.83 -   (eval echo "\"\$as_me:6980: $lt_compile\"" >&5)
    2.84 +   (eval echo "\"\$as_me:6993: $lt_compile\"" >&5)
    2.85     (eval "$lt_compile" 2>conftest.err)
    2.86     ac_status=$?
    2.87     cat conftest.err >&5
    2.88 -   echo "$as_me:6984: \$? = $ac_status" >&5
    2.89 +   echo "$as_me:6997: \$? = $ac_status" >&5
    2.90     if (exit $ac_status) && test -s "$ac_outfile"; then
    2.91       # The compiler can only warn and ignore the option if not recognized
    2.92       # So say no if there are warnings other than the usual output.
    2.93 @@ -7316,11 +7329,11 @@
    2.94     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.95     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.96     -e 's:$: $lt_compiler_flag:'`
    2.97 -   (eval echo "\"\$as_me:7319: $lt_compile\"" >&5)
    2.98 +   (eval echo "\"\$as_me:7332: $lt_compile\"" >&5)
    2.99     (eval "$lt_compile" 2>conftest.err)
   2.100     ac_status=$?
   2.101     cat conftest.err >&5
   2.102 -   echo "$as_me:7323: \$? = $ac_status" >&5
   2.103 +   echo "$as_me:7336: \$? = $ac_status" >&5
   2.104     if (exit $ac_status) && test -s "$ac_outfile"; then
   2.105       # The compiler can only warn and ignore the option if not recognized
   2.106       # So say no if there are warnings other than the usual output.
   2.107 @@ -7421,11 +7434,11 @@
   2.108     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   2.109     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   2.110     -e 's:$: $lt_compiler_flag:'`
   2.111 -   (eval echo "\"\$as_me:7424: $lt_compile\"" >&5)
   2.112 +   (eval echo "\"\$as_me:7437: $lt_compile\"" >&5)
   2.113     (eval "$lt_compile" 2>out/conftest.err)
   2.114     ac_status=$?
   2.115     cat out/conftest.err >&5
   2.116 -   echo "$as_me:7428: \$? = $ac_status" >&5
   2.117 +   echo "$as_me:7441: \$? = $ac_status" >&5
   2.118     if (exit $ac_status) && test -s out/conftest2.$ac_objext
   2.119     then
   2.120       # The compiler can only warn and ignore the option if not recognized
   2.121 @@ -7476,11 +7489,11 @@
   2.122     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   2.123     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   2.124     -e 's:$: $lt_compiler_flag:'`
   2.125 -   (eval echo "\"\$as_me:7479: $lt_compile\"" >&5)
   2.126 +   (eval echo "\"\$as_me:7492: $lt_compile\"" >&5)
   2.127     (eval "$lt_compile" 2>out/conftest.err)
   2.128     ac_status=$?
   2.129     cat out/conftest.err >&5
   2.130 -   echo "$as_me:7483: \$? = $ac_status" >&5
   2.131 +   echo "$as_me:7496: \$? = $ac_status" >&5
   2.132     if (exit $ac_status) && test -s out/conftest2.$ac_objext
   2.133     then
   2.134       # The compiler can only warn and ignore the option if not recognized
   2.135 @@ -9845,7 +9858,7 @@
   2.136    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   2.137    lt_status=$lt_dlunknown
   2.138    cat > conftest.$ac_ext <<_LT_EOF
   2.139 -#line 9848 "configure"
   2.140 +#line 9861 "configure"
   2.141  #include "confdefs.h"
   2.142  
   2.143  #if HAVE_DLFCN_H
   2.144 @@ -9941,7 +9954,7 @@
   2.145    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   2.146    lt_status=$lt_dlunknown
   2.147    cat > conftest.$ac_ext <<_LT_EOF
   2.148 -#line 9944 "configure"
   2.149 +#line 9957 "configure"
   2.150  #include "confdefs.h"
   2.151  
   2.152  #if HAVE_DLFCN_H
   2.153 @@ -12997,6 +13010,217 @@
   2.154  $as_echo "$as_me: WARNING: MP3 support disabled" >&2;}
   2.155  fi
   2.156  
   2.157 +# Check whether --enable-music-opus was given.
   2.158 +if test "${enable_music_opus+set}" = set; then :
   2.159 +  enableval=$enable_music_opus;
   2.160 +else
   2.161 +  enable_music_opus=yes
   2.162 +fi
   2.163 +
   2.164 +
   2.165 +# Check whether --enable-music-opus-shared was given.
   2.166 +if test "${enable_music_opus_shared+set}" = set; then :
   2.167 +  enableval=$enable_music_opus_shared;
   2.168 +else
   2.169 +  enable_music_opus_shared=yes
   2.170 +fi
   2.171 +
   2.172 +if test x$enable_music_opus = xyes; then
   2.173 +
   2.174 +pkg_failed=no
   2.175 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPUSFILE" >&5
   2.176 +$as_echo_n "checking for OPUSFILE... " >&6; }
   2.177 +
   2.178 +if test -n "$PKG_CONFIG"; then
   2.179 +    if test -n "$OPUSFILE_CFLAGS"; then
   2.180 +        pkg_cv_OPUSFILE_CFLAGS="$OPUSFILE_CFLAGS"
   2.181 +    else
   2.182 +        if test -n "$PKG_CONFIG" && \
   2.183 +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"opusfile >= 0.2\""; } >&5
   2.184 +  ($PKG_CONFIG --exists --print-errors "opusfile >= 0.2") 2>&5
   2.185 +  ac_status=$?
   2.186 +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   2.187 +  test $ac_status = 0; }; then
   2.188 +  pkg_cv_OPUSFILE_CFLAGS=`$PKG_CONFIG --cflags "opusfile >= 0.2" 2>/dev/null`
   2.189 +else
   2.190 +  pkg_failed=yes
   2.191 +fi
   2.192 +    fi
   2.193 +else
   2.194 +	pkg_failed=untried
   2.195 +fi
   2.196 +if test -n "$PKG_CONFIG"; then
   2.197 +    if test -n "$OPUSFILE_LIBS"; then
   2.198 +        pkg_cv_OPUSFILE_LIBS="$OPUSFILE_LIBS"
   2.199 +    else
   2.200 +        if test -n "$PKG_CONFIG" && \
   2.201 +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"opusfile >= 0.2\""; } >&5
   2.202 +  ($PKG_CONFIG --exists --print-errors "opusfile >= 0.2") 2>&5
   2.203 +  ac_status=$?
   2.204 +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   2.205 +  test $ac_status = 0; }; then
   2.206 +  pkg_cv_OPUSFILE_LIBS=`$PKG_CONFIG --libs "opusfile >= 0.2" 2>/dev/null`
   2.207 +else
   2.208 +  pkg_failed=yes
   2.209 +fi
   2.210 +    fi
   2.211 +else
   2.212 +	pkg_failed=untried
   2.213 +fi
   2.214 +
   2.215 +
   2.216 +
   2.217 +if test $pkg_failed = yes; then
   2.218 +
   2.219 +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
   2.220 +        _pkg_short_errors_supported=yes
   2.221 +else
   2.222 +        _pkg_short_errors_supported=no
   2.223 +fi
   2.224 +        if test $_pkg_short_errors_supported = yes; then
   2.225 +	        OPUSFILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "opusfile >= 0.2"`
   2.226 +        else
   2.227 +	        OPUSFILE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "opusfile >= 0.2"`
   2.228 +        fi
   2.229 +	# Put the nasty error message in config.log where it belongs
   2.230 +	echo "$OPUSFILE_PKG_ERRORS" >&5
   2.231 +
   2.232 +	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
   2.233 +$as_echo "no" >&6; }
   2.234 +                            ac_fn_c_check_header_mongrel "$LINENO" "opus/opusfile.h" "ac_cv_header_opus_opusfile_h" "$ac_includes_default"
   2.235 +if test "x$ac_cv_header_opus_opusfile_h" = xyes; then :
   2.236 +  have_opusfile_hdr=yes
   2.237 +fi
   2.238 +
   2.239 +
   2.240 +            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for op_open_callbacks in -lopusfile" >&5
   2.241 +$as_echo_n "checking for op_open_callbacks in -lopusfile... " >&6; }
   2.242 +if ${ac_cv_lib_opusfile_op_open_callbacks+:} false; then :
   2.243 +  $as_echo_n "(cached) " >&6
   2.244 +else
   2.245 +  ac_check_lib_save_LIBS=$LIBS
   2.246 +LIBS="-lopusfile  $LIBS"
   2.247 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
   2.248 +/* end confdefs.h.  */
   2.249 +
   2.250 +/* Override any GCC internal prototype to avoid an error.
   2.251 +   Use char because int might match the return type of a GCC
   2.252 +   builtin and then its argument prototype would still apply.  */
   2.253 +#ifdef __cplusplus
   2.254 +extern "C"
   2.255 +#endif
   2.256 +char op_open_callbacks ();
   2.257 +int
   2.258 +main ()
   2.259 +{
   2.260 +return op_open_callbacks ();
   2.261 +  ;
   2.262 +  return 0;
   2.263 +}
   2.264 +_ACEOF
   2.265 +if ac_fn_c_try_link "$LINENO"; then :
   2.266 +  ac_cv_lib_opusfile_op_open_callbacks=yes
   2.267 +else
   2.268 +  ac_cv_lib_opusfile_op_open_callbacks=no
   2.269 +fi
   2.270 +rm -f core conftest.err conftest.$ac_objext \
   2.271 +    conftest$ac_exeext conftest.$ac_ext
   2.272 +LIBS=$ac_check_lib_save_LIBS
   2.273 +fi
   2.274 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opusfile_op_open_callbacks" >&5
   2.275 +$as_echo "$ac_cv_lib_opusfile_op_open_callbacks" >&6; }
   2.276 +if test "x$ac_cv_lib_opusfile_op_open_callbacks" = xyes; then :
   2.277 +  have_opusfile_lib=yes
   2.278 +fi
   2.279 +
   2.280 +
   2.281 +elif test $pkg_failed = untried; then
   2.282 +	            ac_fn_c_check_header_mongrel "$LINENO" "opus/opusfile.h" "ac_cv_header_opus_opusfile_h" "$ac_includes_default"
   2.283 +if test "x$ac_cv_header_opus_opusfile_h" = xyes; then :
   2.284 +  have_opusfile_hdr=yes
   2.285 +fi
   2.286 +
   2.287 +
   2.288 +            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for op_open_callbacks in -lopusfile" >&5
   2.289 +$as_echo_n "checking for op_open_callbacks in -lopusfile... " >&6; }
   2.290 +if ${ac_cv_lib_opusfile_op_open_callbacks+:} false; then :
   2.291 +  $as_echo_n "(cached) " >&6
   2.292 +else
   2.293 +  ac_check_lib_save_LIBS=$LIBS
   2.294 +LIBS="-lopusfile  $LIBS"
   2.295 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
   2.296 +/* end confdefs.h.  */
   2.297 +
   2.298 +/* Override any GCC internal prototype to avoid an error.
   2.299 +   Use char because int might match the return type of a GCC
   2.300 +   builtin and then its argument prototype would still apply.  */
   2.301 +#ifdef __cplusplus
   2.302 +extern "C"
   2.303 +#endif
   2.304 +char op_open_callbacks ();
   2.305 +int
   2.306 +main ()
   2.307 +{
   2.308 +return op_open_callbacks ();
   2.309 +  ;
   2.310 +  return 0;
   2.311 +}
   2.312 +_ACEOF
   2.313 +if ac_fn_c_try_link "$LINENO"; then :
   2.314 +  ac_cv_lib_opusfile_op_open_callbacks=yes
   2.315 +else
   2.316 +  ac_cv_lib_opusfile_op_open_callbacks=no
   2.317 +fi
   2.318 +rm -f core conftest.err conftest.$ac_objext \
   2.319 +    conftest$ac_exeext conftest.$ac_ext
   2.320 +LIBS=$ac_check_lib_save_LIBS
   2.321 +fi
   2.322 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opusfile_op_open_callbacks" >&5
   2.323 +$as_echo "$ac_cv_lib_opusfile_op_open_callbacks" >&6; }
   2.324 +if test "x$ac_cv_lib_opusfile_op_open_callbacks" = xyes; then :
   2.325 +  have_opusfile_lib=yes
   2.326 +fi
   2.327 +
   2.328 +
   2.329 +else
   2.330 +	OPUSFILE_CFLAGS=$pkg_cv_OPUSFILE_CFLAGS
   2.331 +	OPUSFILE_LIBS=$pkg_cv_OPUSFILE_LIBS
   2.332 +        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
   2.333 +$as_echo "yes" >&6; }
   2.334 +	            have_opusfile_hdr=yes
   2.335 +            have_opusfile_lib=yes
   2.336 +
   2.337 +fi
   2.338 +
   2.339 +    if test x$have_opusfile_hdr = xyes -a x$have_opusfile_lib = xyes; then
   2.340 +        have_opusfile=yes
   2.341 +        case "$host" in
   2.342 +            *-*-darwin*)
   2.343 +                opusfile_lib=`find_lib libopusfile.dylib`
   2.344 +                ;;
   2.345 +            *-*-cygwin* | *-*-mingw32*)
   2.346 +                opusfile_lib=`find_lib "libopusfile*.dll"`
   2.347 +                ;;
   2.348 +            *)
   2.349 +                opusfile_lib=`find_lib "libopusfile[0-9]*.so.*"`
   2.350 +                if test x$opusfile_lib = x; then
   2.351 +                    opusfile_lib=`find_lib "libopusfile.so.*"`
   2.352 +                fi
   2.353 +                ;;
   2.354 +        esac
   2.355 +        EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OPUS $OPUSFILE_CFLAGS"
   2.356 +        if test x$enable_music_opus_shared = xyes && test x$opusfile_lib != x; then
   2.357 +            echo "-- dynamic opusfile -> $opusfile_lib"
   2.358 +            EXTRA_CFLAGS="$EXTRA_CFLAGS -DOPUS_DYNAMIC=\\\"$opusfile_lib\\\""
   2.359 +        else
   2.360 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS $OPUSFILE_LIBS"
   2.361 +        fi
   2.362 +    else
   2.363 +        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Unable to find opusfile library (http://opus-codec.org/)" >&5
   2.364 +$as_echo "$as_me: WARNING: *** Unable to find opusfile library (http://opus-codec.org/)" >&2;}
   2.365 +    fi
   2.366 +fi
   2.367 +
   2.368  EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBM"
   2.369  
   2.370  OBJECTS=`echo $SOURCES`
     3.1 --- a/configure.in	Tue Jun 12 13:45:37 2018 +0300
     3.2 +++ b/configure.in	Fri Jun 15 08:32:56 2018 +0300
     3.3 @@ -674,6 +674,50 @@
     3.4      AC_MSG_WARN([MP3 support disabled])
     3.5  fi
     3.6  
     3.7 +AC_ARG_ENABLE([music-opus],
     3.8 +AC_HELP_STRING([--enable-music-opus], [enable Opus music [[default=yes]]]),
     3.9 +              [], [enable_music_opus=yes])
    3.10 +
    3.11 +AC_ARG_ENABLE([music-opus-shared],
    3.12 +AC_HELP_STRING([--enable-music-opus-shared], [dynamically load opusfile library [[default=yes]]]),
    3.13 +              [], [enable_music_opus_shared=yes])
    3.14 +if test x$enable_music_opus = xyes; then
    3.15 +    PKG_CHECK_MODULES([OPUSFILE], [opusfile >= 0.2], [dnl
    3.16 +            have_opusfile_hdr=yes
    3.17 +            have_opusfile_lib=yes
    3.18 +        ], [dnl
    3.19 +            AC_CHECK_HEADER([opus/opusfile.h], [have_opusfile_hdr=yes])
    3.20 +            AC_CHECK_LIB([opusfile], [op_open_callbacks], [have_opusfile_lib=yes])
    3.21 +        ])
    3.22 +
    3.23 +    if test x$have_opusfile_hdr = xyes -a x$have_opusfile_lib = xyes; then
    3.24 +        have_opusfile=yes
    3.25 +        case "$host" in
    3.26 +            *-*-darwin*)
    3.27 +                opusfile_lib=[`find_lib libopusfile.dylib`]
    3.28 +                ;;
    3.29 +            *-*-cygwin* | *-*-mingw32*)
    3.30 +                opusfile_lib=[`find_lib "libopusfile*.dll"`]
    3.31 +                ;;
    3.32 +            *)
    3.33 +                opusfile_lib=[`find_lib "libopusfile[0-9]*.so.*"`]
    3.34 +                if test x$opusfile_lib = x; then
    3.35 +                    opusfile_lib=[`find_lib "libopusfile.so.*"`]
    3.36 +                fi
    3.37 +                ;;
    3.38 +        esac
    3.39 +        EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_OPUS $OPUSFILE_CFLAGS"
    3.40 +        if test x$enable_music_opus_shared = xyes && test x$opusfile_lib != x; then
    3.41 +            echo "-- dynamic opusfile -> $opusfile_lib"
    3.42 +            EXTRA_CFLAGS="$EXTRA_CFLAGS -DOPUS_DYNAMIC=\\\"$opusfile_lib\\\""
    3.43 +        else
    3.44 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS $OPUSFILE_LIBS"
    3.45 +        fi
    3.46 +    else
    3.47 +        AC_MSG_WARN([*** Unable to find opusfile library (http://opus-codec.org/)])
    3.48 +    fi
    3.49 +fi
    3.50 +
    3.51  EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBM"
    3.52  
    3.53  OBJECTS=`echo $SOURCES`
     4.1 --- a/mixer.c	Tue Jun 12 13:45:37 2018 +0300
     4.2 +++ b/mixer.c	Fri Jun 15 08:32:56 2018 +0300
     4.3 @@ -182,6 +182,14 @@
     4.4              Mix_SetError("OGG support not available");
     4.5          }
     4.6      }
     4.7 +    if (flags & MIX_INIT_OPUS) {
     4.8 +        if (load_music_type(MUS_OPUS)) {
     4.9 +            open_music_type(MUS_OPUS);
    4.10 +            result |= MIX_INIT_OPUS;
    4.11 +        } else {
    4.12 +            Mix_SetError("OPUS support not available");
    4.13 +        }
    4.14 +    }
    4.15      if (flags & MIX_INIT_MID) {
    4.16          if (load_music_type(MUS_MID)) {
    4.17              open_music_type(MUS_MID);
     5.1 --- a/music.c	Tue Jun 12 13:45:37 2018 +0300
     5.2 +++ b/music.c	Fri Jun 15 08:32:56 2018 +0300
     5.3 @@ -36,6 +36,7 @@
     5.4  #include "music_fluidsynth.h"
     5.5  #include "music_timidity.h"
     5.6  #include "music_ogg.h"
     5.7 +#include "music_opus.h"
     5.8  #include "music_mpg123.h"
     5.9  #include "music_mad.h"
    5.10  #include "music_smpeg.h"
    5.11 @@ -92,6 +93,9 @@
    5.12  #ifdef MUSIC_OGG
    5.13      &Mix_MusicInterface_OGG,
    5.14  #endif
    5.15 +#ifdef MUSIC_OPUS
    5.16 +    &Mix_MusicInterface_Opus,
    5.17 +#endif
    5.18  #ifdef MUSIC_MP3_MPG123
    5.19      &Mix_MusicInterface_MPG123,
    5.20  #endif
    5.21 @@ -354,6 +358,10 @@
    5.22          add_music_decoder("OGG");
    5.23          add_chunk_decoder("OGG");
    5.24      }
    5.25 +    if (has_music(MUS_OPUS)) {
    5.26 +        add_music_decoder("OPUS");
    5.27 +        add_chunk_decoder("OPUS");
    5.28 +    }
    5.29      if (has_music(MUS_MP3)) {
    5.30          add_music_decoder("MP3");
    5.31          add_chunk_decoder("MP3");
    5.32 @@ -438,6 +446,7 @@
    5.33  static Mix_MusicType detect_music_type(SDL_RWops *src)
    5.34  {
    5.35      Uint8 magic[12];
    5.36 +    Mix_MusicType t;
    5.37  
    5.38      if (SDL_RWread(src, magic, 1, 12) != 12) {
    5.39          Mix_SetError("Couldn't read first 12 bytes of audio data");
    5.40 @@ -451,8 +460,17 @@
    5.41          (SDL_memcmp(magic, "FORM", 4) == 0)) {
    5.42          return MUS_WAV;
    5.43      }
    5.44 -
    5.45 -    return detect_music_type_from_magic(magic);
    5.46 +    t = detect_music_type_from_magic(magic);
    5.47 +    if (t == MUS_OGG) {
    5.48 +        Sint64 pos = SDL_RWtell(src);
    5.49 +        SDL_RWseek(src, 28, RW_SEEK_CUR);
    5.50 +        SDL_RWread(src, magic, 1, 8);
    5.51 +        SDL_RWseek(src, pos, RW_SEEK_SET);
    5.52 +        if (SDL_memcmp(magic, "OpusHead", 8) == 0) {
    5.53 +            return MUS_OPUS;
    5.54 +        }
    5.55 +    }
    5.56 +    return t;
    5.57  }
    5.58  
    5.59  /* Load a music file */
    5.60 @@ -503,6 +521,8 @@
    5.61              type = MUS_MID;
    5.62          } else if (SDL_strcasecmp(ext, "OGG") == 0) {
    5.63              type = MUS_OGG;
    5.64 +        } else if (SDL_strcasecmp(ext, "OPUS") == 0) {
    5.65 +            type = MUS_OPUS;
    5.66          } else if (SDL_strcasecmp(ext, "FLAC") == 0) {
    5.67              type = MUS_FLAC;
    5.68          } else  if (SDL_strcasecmp(ext, "MPG") == 0 ||
     6.1 --- a/music.h	Tue Jun 12 13:45:37 2018 +0300
     6.2 +++ b/music.h	Fri Jun 15 08:32:56 2018 +0300
     6.3 @@ -39,6 +39,7 @@
     6.4      MIX_MUSIC_MAD,
     6.5      MIX_MUSIC_SMPEG,
     6.6      MIX_MUSIC_FLAC,
     6.7 +    MIX_MUSIC_OPUS,
     6.8      MIX_MUSIC_LAST
     6.9  } Mix_MusicAPI;
    6.10  
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/music_opus.c	Fri Jun 15 08:32:56 2018 +0300
     7.3 @@ -0,0 +1,369 @@
     7.4 +/*
     7.5 +  SDL_mixer:  An audio mixer library based on the SDL library
     7.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
     7.7 +
     7.8 +  This software is provided 'as-is', without any express or implied
     7.9 +  warranty.  In no event will the authors be held liable for any damages
    7.10 +  arising from the use of this software.
    7.11 +
    7.12 +  Permission is granted to anyone to use this software for any purpose,
    7.13 +  including commercial applications, and to alter it and redistribute it
    7.14 +  freely, subject to the following restrictions:
    7.15 +
    7.16 +  1. The origin of this software must not be misrepresented; you must not
    7.17 +     claim that you wrote the original software. If you use this software
    7.18 +     in a product, an acknowledgment in the product documentation would be
    7.19 +     appreciated but is not required.
    7.20 +  2. Altered source versions must be plainly marked as such, and must not be
    7.21 +     misrepresented as being the original software.
    7.22 +  3. This notice may not be removed or altered from any source distribution.
    7.23 +*/
    7.24 +
    7.25 +#ifdef MUSIC_OPUS
    7.26 +
    7.27 +/* This file supports Ogg Opus music streams */
    7.28 +
    7.29 +#include "SDL_loadso.h"
    7.30 +
    7.31 +#include "music_opus.h"
    7.32 +
    7.33 +#include <opusfile.h>
    7.34 +
    7.35 +typedef struct {
    7.36 +    int loaded;
    7.37 +    void *handle;
    7.38 +    OggOpusFile *(*op_open_callbacks)(void *,const OpusFileCallbacks *,const unsigned char *,size_t,int *);
    7.39 +    void (*op_free)(OggOpusFile *);
    7.40 +    const OpusHead *(*op_head)(const OggOpusFile *,int);
    7.41 +    int (*op_seekable)(const OggOpusFile *);
    7.42 +    int (*op_read)(OggOpusFile *, opus_int16 *,int,int *);
    7.43 +    int (*op_pcm_seek)(OggOpusFile *,ogg_int64_t);
    7.44 +} opus_loader;
    7.45 +
    7.46 +static opus_loader opus = {
    7.47 +    0, NULL
    7.48 +};
    7.49 +
    7.50 +#ifdef OPUS_DYNAMIC
    7.51 +#define FUNCTION_LOADER(FUNC, SIG) \
    7.52 +    opus.FUNC = (SIG) SDL_LoadFunction(opus.handle, #FUNC); \
    7.53 +    if (opus.FUNC == NULL) { SDL_UnloadObject(opus.handle); return -1; }
    7.54 +#else
    7.55 +#define FUNCTION_LOADER(FUNC, SIG) \
    7.56 +    opus.FUNC = FUNC;
    7.57 +#endif
    7.58 +
    7.59 +static int OPUS_Load(void)
    7.60 +{
    7.61 +    if (opus.loaded == 0) {
    7.62 +#ifdef OPUS_DYNAMIC
    7.63 +        opus.handle = SDL_LoadObject(OPUS_DYNAMIC);
    7.64 +        if (opus.handle == NULL) {
    7.65 +            return -1;
    7.66 +        }
    7.67 +#elif defined(__MACOSX__)
    7.68 +        extern OggOpusFile *op_open_callbacks(void *,const OpusFileCallbacks *,const unsigned char *,size_t,int *) __attribute__((weak_import));
    7.69 +        if (op_open_callbacks == NULL) {
    7.70 +            /* Missing weakly linked framework */
    7.71 +            Mix_SetError("Missing Opus.framework");
    7.72 +            return -1;
    7.73 +        }
    7.74 +#endif
    7.75 +        FUNCTION_LOADER(op_open_callbacks, OggOpusFile *(*)(void *,const OpusFileCallbacks *,const unsigned char *,size_t,int *))
    7.76 +        FUNCTION_LOADER(op_free, void (*)(OggOpusFile *))
    7.77 +        FUNCTION_LOADER(op_head, const OpusHead *(*)(const OggOpusFile *,int))
    7.78 +        FUNCTION_LOADER(op_seekable, int (*)(const OggOpusFile *))
    7.79 +        FUNCTION_LOADER(op_read, int (*)(OggOpusFile *, opus_int16 *,int,int *))
    7.80 +        FUNCTION_LOADER(op_pcm_seek, int (*)(OggOpusFile *,ogg_int64_t))
    7.81 +    }
    7.82 +    ++opus.loaded;
    7.83 +
    7.84 +    return 0;
    7.85 +}
    7.86 +
    7.87 +static void OPUS_Unload(void)
    7.88 +{
    7.89 +    if (opus.loaded == 0) {
    7.90 +        return;
    7.91 +    }
    7.92 +    if (opus.loaded == 1) {
    7.93 +#ifdef OPUS_DYNAMIC
    7.94 +        SDL_UnloadObject(opus.handle);
    7.95 +#endif
    7.96 +    }
    7.97 +    --opus.loaded;
    7.98 +}
    7.99 +
   7.100 +
   7.101 +typedef struct {
   7.102 +    SDL_RWops *src;
   7.103 +    int freesrc;
   7.104 +    int play_count;
   7.105 +    int volume;
   7.106 +    OggOpusFile *of;
   7.107 +    const OpusHead *op_info;
   7.108 +    int section;
   7.109 +    SDL_AudioStream *stream;
   7.110 +    char *buffer;
   7.111 +    int buffer_size;
   7.112 +} OPUS_music;
   7.113 +
   7.114 +
   7.115 +static int set_op_error(const char *function, int error)
   7.116 +{
   7.117 +#define HANDLE_ERROR_CASE(X)    case X: Mix_SetError("%s: %s", function, #X); break;
   7.118 +    switch (error) {
   7.119 +    HANDLE_ERROR_CASE(OP_FALSE);
   7.120 +    HANDLE_ERROR_CASE(OP_EOF);
   7.121 +    HANDLE_ERROR_CASE(OP_HOLE);
   7.122 +    HANDLE_ERROR_CASE(OP_EREAD);
   7.123 +    HANDLE_ERROR_CASE(OP_EFAULT);
   7.124 +    HANDLE_ERROR_CASE(OP_EIMPL);
   7.125 +    HANDLE_ERROR_CASE(OP_EINVAL);
   7.126 +    HANDLE_ERROR_CASE(OP_ENOTFORMAT);
   7.127 +    HANDLE_ERROR_CASE(OP_EBADHEADER);
   7.128 +    HANDLE_ERROR_CASE(OP_EVERSION);
   7.129 +    HANDLE_ERROR_CASE(OP_ENOTAUDIO);
   7.130 +    HANDLE_ERROR_CASE(OP_EBADPACKET);
   7.131 +    HANDLE_ERROR_CASE(OP_EBADLINK);
   7.132 +    HANDLE_ERROR_CASE(OP_ENOSEEK);
   7.133 +    HANDLE_ERROR_CASE(OP_EBADTIMESTAMP);
   7.134 +    default:
   7.135 +        Mix_SetError("%s: unknown error %d\n", function, error);
   7.136 +        break;
   7.137 +    }
   7.138 +    return -1;
   7.139 +}
   7.140 +
   7.141 +static int sdl_read_func(void *datasource, unsigned char *ptr, int size)
   7.142 +{
   7.143 +    return (int)SDL_RWread((SDL_RWops*)datasource, ptr, 1, size);
   7.144 +}
   7.145 +
   7.146 +static int sdl_seek_func(void *datasource, ogg_int64_t offset, int whence)
   7.147 +{
   7.148 +    return (SDL_RWseek((SDL_RWops*)datasource, offset, whence) < 0)? -1 : 0;
   7.149 +}
   7.150 +
   7.151 +static opus_int64 sdl_tell_func(void *datasource)
   7.152 +{
   7.153 +    return SDL_RWtell((SDL_RWops*)datasource);
   7.154 +}
   7.155 +
   7.156 +static int OPUS_Seek(void*, double);
   7.157 +static void OPUS_Delete(void*);
   7.158 +
   7.159 +static int OPUS_UpdateSection(OPUS_music *music)
   7.160 +{
   7.161 +    const OpusHead *op_info;
   7.162 +
   7.163 +    op_info = opus.op_head(music->of, -1);
   7.164 +    if (!op_info) {
   7.165 +        Mix_SetError("op_head returned NULL");
   7.166 +        return -1;
   7.167 +    }
   7.168 +
   7.169 +    if (music->op_info && op_info->channel_count == music->op_info->channel_count) {
   7.170 +        return 0;
   7.171 +    }
   7.172 +    music->op_info = op_info;
   7.173 +
   7.174 +    if (music->buffer) {
   7.175 +        SDL_free(music->buffer);
   7.176 +        music->buffer = NULL;
   7.177 +    }
   7.178 +
   7.179 +    if (music->stream) {
   7.180 +        SDL_FreeAudioStream(music->stream);
   7.181 +        music->stream = NULL;
   7.182 +    }
   7.183 +
   7.184 +    music->stream = SDL_NewAudioStream(AUDIO_S16, op_info->channel_count, 48000,
   7.185 +                                       music_spec.format, music_spec.channels, music_spec.freq);
   7.186 +    if (!music->stream) {
   7.187 +        return -1;
   7.188 +    }
   7.189 +
   7.190 +    music->buffer_size = music_spec.samples * sizeof(opus_int16) * op_info->channel_count;
   7.191 +    music->buffer = (char *)SDL_malloc(music->buffer_size);
   7.192 +    if (!music->buffer) {
   7.193 +        return -1;
   7.194 +    }
   7.195 +    return 0;
   7.196 +}
   7.197 +
   7.198 +/* Load an Opus stream from an SDL_RWops object */
   7.199 +static void *OPUS_CreateFromRW(SDL_RWops *src, int freesrc)
   7.200 +{
   7.201 +    OPUS_music *music;
   7.202 +    OpusFileCallbacks callbacks;
   7.203 +    int err = 0;
   7.204 +
   7.205 +    music = (OPUS_music *)SDL_calloc(1, sizeof *music);
   7.206 +    if (!music) {
   7.207 +        SDL_OutOfMemory();
   7.208 +        return NULL;
   7.209 +    }
   7.210 +    music->src = src;
   7.211 +    music->volume = MIX_MAX_VOLUME;
   7.212 +    music->section = -1;
   7.213 +
   7.214 +    SDL_zero(callbacks);
   7.215 +    callbacks.read = sdl_read_func;
   7.216 +    callbacks.seek = sdl_seek_func;
   7.217 +    callbacks.tell = sdl_tell_func;
   7.218 +
   7.219 +    music->of = opus.op_open_callbacks(src, &callbacks, NULL, 0, &err);
   7.220 +    if (music->of == NULL) {
   7.221 +    /*  set_op_error("op_open_callbacks", err);*/
   7.222 +        SDL_SetError("Not an Opus audio stream");
   7.223 +        SDL_free(music);
   7.224 +        return NULL;
   7.225 +    }
   7.226 +
   7.227 +    if (!opus.op_seekable(music->of)) {
   7.228 +        OPUS_Delete(music);
   7.229 +        Mix_SetError("Opus stream not seekable");
   7.230 +        return NULL;
   7.231 +    }
   7.232 +
   7.233 +    if (OPUS_UpdateSection(music) < 0) {
   7.234 +        OPUS_Delete(music);
   7.235 +        return NULL;
   7.236 +    }
   7.237 +
   7.238 +    music->freesrc = freesrc;
   7.239 +    return music;
   7.240 +}
   7.241 +
   7.242 +/* Set the volume for an Opus stream */
   7.243 +static void OPUS_SetVolume(void *context, int volume)
   7.244 +{
   7.245 +    OPUS_music *music = (OPUS_music *)context;
   7.246 +    music->volume = volume;
   7.247 +}
   7.248 +
   7.249 +/* Start playback of a given Opus stream */
   7.250 +static int OPUS_Play(void *context, int play_count)
   7.251 +{
   7.252 +    OPUS_music *music = (OPUS_music *)context;
   7.253 +    music->play_count = play_count;
   7.254 +    return OPUS_Seek(music, 0.0);
   7.255 +}
   7.256 +
   7.257 +/* Play some of a stream previously started with OPUS_Play() */
   7.258 +static int OPUS_GetSome(void *context, void *data, int bytes, SDL_bool *done)
   7.259 +{
   7.260 +    OPUS_music *music = (OPUS_music *)context;
   7.261 +    int filled, samples, section;
   7.262 +
   7.263 +    filled = SDL_AudioStreamGet(music->stream, data, bytes);
   7.264 +    if (filled != 0) {
   7.265 +        return filled;
   7.266 +    }
   7.267 +
   7.268 +    if (!music->play_count) {
   7.269 +        /* All done */
   7.270 +        *done = SDL_TRUE;
   7.271 +        return 0;
   7.272 +    }
   7.273 +
   7.274 +    section = music->section;
   7.275 +    samples = opus.op_read(music->of, (opus_int16 *)music->buffer, music->buffer_size / sizeof(opus_int16), &section);
   7.276 +    if (samples < 0) {
   7.277 +        set_op_error("op_read", samples);
   7.278 +        return -1;
   7.279 +    }
   7.280 +
   7.281 +    if (section != music->section) {
   7.282 +        music->section = section;
   7.283 +        if (OPUS_UpdateSection(music) < 0) {
   7.284 +            return -1;
   7.285 +        }
   7.286 +    }
   7.287 +
   7.288 +    if (samples > 0) {
   7.289 +        filled = samples * music->op_info->channel_count * 2;
   7.290 +        if (SDL_AudioStreamPut(music->stream, music->buffer, filled) < 0) {
   7.291 +            return -1;
   7.292 +        }
   7.293 +    } else {
   7.294 +        if (music->play_count == 1) {
   7.295 +            music->play_count = 0;
   7.296 +            SDL_AudioStreamFlush(music->stream);
   7.297 +        } else {
   7.298 +            int play_count = -1;
   7.299 +            if (music->play_count > 0) {
   7.300 +                play_count = (music->play_count - 1);
   7.301 +            }
   7.302 +            if (OPUS_Play(music, play_count) < 0) {
   7.303 +                return -1;
   7.304 +            }
   7.305 +        }
   7.306 +    }
   7.307 +    return 0;
   7.308 +}
   7.309 +
   7.310 +static int OPUS_GetAudio(void *context, void *data, int bytes)
   7.311 +{
   7.312 +    OPUS_music *music = (OPUS_music *)context;
   7.313 +    return music_pcm_getaudio(context, data, bytes, music->volume, OPUS_GetSome);
   7.314 +}
   7.315 +
   7.316 +/* Jump (seek) to a given position (time is in seconds) */
   7.317 +static int OPUS_Seek(void *context, double time)
   7.318 +{
   7.319 +    OPUS_music *music = (OPUS_music *)context;
   7.320 +    int result;
   7.321 +    result = opus.op_pcm_seek(music->of, (ogg_int64_t)(time * 48000));
   7.322 +    if (result < 0) {
   7.323 +        return set_op_error("op_pcm_seek", result);
   7.324 +    }
   7.325 +    return 0;
   7.326 +}
   7.327 +
   7.328 +/* Close the given Opus stream */
   7.329 +static void OPUS_Delete(void *context)
   7.330 +{
   7.331 +    OPUS_music *music = (OPUS_music *)context;
   7.332 +    opus.op_free(music->of);
   7.333 +    if (music->stream) {
   7.334 +        SDL_FreeAudioStream(music->stream);
   7.335 +    }
   7.336 +    if (music->buffer) {
   7.337 +        SDL_free(music->buffer);
   7.338 +    }
   7.339 +    if (music->freesrc) {
   7.340 +        SDL_RWclose(music->src);
   7.341 +    }
   7.342 +    SDL_free(music);
   7.343 +}
   7.344 +
   7.345 +Mix_MusicInterface Mix_MusicInterface_Opus =
   7.346 +{
   7.347 +    "OPUS",
   7.348 +    MIX_MUSIC_OPUS,
   7.349 +    MUS_OPUS,
   7.350 +    SDL_FALSE,
   7.351 +    SDL_FALSE,
   7.352 +
   7.353 +    OPUS_Load,
   7.354 +    NULL,   /* Open */
   7.355 +    OPUS_CreateFromRW,
   7.356 +    NULL,   /* CreateFromFile */
   7.357 +    OPUS_SetVolume,
   7.358 +    OPUS_Play,
   7.359 +    NULL,   /* IsPlaying */
   7.360 +    OPUS_GetAudio,
   7.361 +    OPUS_Seek,
   7.362 +    NULL,   /* Pause */
   7.363 +    NULL,   /* Resume */
   7.364 +    NULL,   /* Stop */
   7.365 +    OPUS_Delete,
   7.366 +    NULL,   /* Close */
   7.367 +    OPUS_Unload,
   7.368 +};
   7.369 +
   7.370 +#endif /* MUSIC_OPUS */
   7.371 +
   7.372 +/* vi: set ts=4 sw=4 expandtab: */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/music_opus.h	Fri Jun 15 08:32:56 2018 +0300
     8.3 @@ -0,0 +1,28 @@
     8.4 +/*
     8.5 +  SDL_mixer:  An audio mixer library based on the SDL library
     8.6 +  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
     8.7 +
     8.8 +  This software is provided 'as-is', without any express or implied
     8.9 +  warranty.  In no event will the authors be held liable for any damages
    8.10 +  arising from the use of this software.
    8.11 +
    8.12 +  Permission is granted to anyone to use this software for any purpose,
    8.13 +  including commercial applications, and to alter it and redistribute it
    8.14 +  freely, subject to the following restrictions:
    8.15 +
    8.16 +  1. The origin of this software must not be misrepresented; you must not
    8.17 +     claim that you wrote the original software. If you use this software
    8.18 +     in a product, an acknowledgment in the product documentation would be
    8.19 +     appreciated but is not required.
    8.20 +  2. Altered source versions must be plainly marked as such, and must not be
    8.21 +     misrepresented as being the original software.
    8.22 +  3. This notice may not be removed or altered from any source distribution.
    8.23 +*/
    8.24 +
    8.25 +/* This file supports Ogg Opus music streams */
    8.26 +
    8.27 +#include "music.h"
    8.28 +
    8.29 +extern Mix_MusicInterface Mix_MusicInterface_Opus;
    8.30 +
    8.31 +/* vi: set ts=4 sw=4 expandtab: */