mpg123 1.33.0-dev+20250525022201

This commit is contained in:
Ozkan Sezer
2025-05-25 20:40:02 +03:00
parent 22dadfaa3c
commit bf2eba7bc0
28 changed files with 433 additions and 112 deletions

42
INSTALL
View File

@@ -32,6 +32,11 @@ You want:
1. Build 1. Build
Note: If you want the full range of output modules, you might
run into cirucular dependencies, as pulseaudio or SDL might also
want to use parts of the mpg123 distribution. You can split the
build avoid that circle.
There is one main supported way to get your mpg123 installation There is one main supported way to get your mpg123 installation
consisting of consisting of
@@ -51,6 +56,43 @@ This way is the usual GNU 3-step procedure:
make make
make install make install
If you want to separate components (for avoiding circular dependencies,
for example), you can split things at various points. Either you build
all libraries and programs first, then all output modules via
# Build programs and libs only.
./configure --disable-components --enable-programs \
--enable-libmpg123 --enable-libsyn123 --enable-libout123 \
--with-default-audio=$OUTPUT_MODULES
make && make install
# Build packges relying on mpg123 libraries.
# After that, build out123 modules with external dependencies
./configure --disable-components --enable-libout123-modules \
--with-audio=$OUTPUT_MODULES
make && make install
or you can build each component individually, or just separate out the
problematic modules by
# Build all components, but dummy output only.
./configure --with-audio=dummy,$SAFE_MODULES \
--with-default-audio=$OUTPUT_MODULES
make && install
# Build other packages, like SDL, pulse.
# After that, build output modules depending on those.
# Without --with-audio, auto-detection will build a list.
./configure --disable-components --enable-libout123-modules \
--with-audio=$UNSAFE_MODULES
make && make install
The variables OUTPUT_MODULES, SAFE_MOULES, and UNSAFE_MODULES are
supposed to contain comma-separated lists of output modules like
"oss,pulse,alsa,jack". You need to give a full list when building
libout123 without modules to setup the default search order. Without
this, it won't find modules automatically without specifying one with
mpg123 -o $module. There is no module registry, just a simple build-time
list and the option to specify a module at runtime.
Run Run
./configure --help ./configure --help

26
NEWS
View File

@@ -1,3 +1,29 @@
1.33.0
------
- mpg123
-- Fix printout of filenames at end (convert/limit text encoding).
-- Treat HTTP header encoding as unknown/ASCII and formally convert to UTF-8.
-- Make --continue mode work with --random.
-- Handle possible failure of __wgetmainargs on Windows (bug 375).
- mpg123-id3dump: Fix up command line arg handling for Windows.
- build:
-- Use CCASFLAGS for assembler tests, to enable builds that enable instruction
sets that way (bug 377).
- compat: Map strtok use to strtok_r or strtok_s (MS platforms), if possible.
users only in control_generic and libout123 so far. Out123 itself uses mytok.
Shall fix bug 376 (build with MSVC again).
- libout123
-- modules/win32: Align waveOutGetDevCapsA to WAVEOUTCAPSA, in anticipation
of some UNICODE change.
- libmpg123
-- API version 49 with added mpg123_open_handle64(), mpg123_open64(), and
mpg123_open_fixed64() that are not subject to largefile renaming. This
means you can still access internal I/O with MPG123_PORTABLE_API. The
code has been there before, anyway.
-- With MPG123_PORTABLE_API, mpg123_open_handle() is hidden now (use
mpg123_open_handle64() instead).
-- more silence on errors (sideband limit message)
1.32.10 1.32.10
------ ------
- scripts/tag_lyrics.py: fix for python3 (thanks to cclauss, - scripts/tag_lyrics.py: fix for python3 (thanks to cclauss,

View File

@@ -2,6 +2,16 @@ Changes in libmpg123 libtool interface versions. Next to the version
the mpg123 release where its changes first appeared to the public the mpg123 release where its changes first appeared to the public
is given. is given.
49.0.49 (mpg123 1.33)
- Added mpg123_open_handle64() as clearly portable match for
mpg123_reader64(). It is just mpg123_open_handle() without
code path for non-portable API.
- Remove mpg123_open_handle() and renamed variants from builds
with MPG123_PORTABLE_API. Code must switch to
mpg123_open_handle64() there if MPG123_API_VERSION >= 49!
- Added mpg123_open64() and mpg123_open_fixed64() as portable
variants of mpg123_open() and mpg123_open_fixed().
48.0.48 (mpg123 1.32) 48.0.48 (mpg123 1.32)
- Added mpg123_distversion() and mpg123_libversion(). - Added mpg123_distversion() and mpg123_libversion().
- Added mpg123_reader64() and the other int64_t-based functions: - Added mpg123_reader64() and the other int64_t-based functions:

53
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for mpg123 1.32.10. # Generated by GNU Autoconf 2.71 for mpg123 1.33.0-dev+20250525022201.
# #
# Report bugs to <maintainer@mpg123.org>. # Report bugs to <maintainer@mpg123.org>.
# #
@@ -621,8 +621,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='mpg123' PACKAGE_NAME='mpg123'
PACKAGE_TARNAME='mpg123' PACKAGE_TARNAME='mpg123'
PACKAGE_VERSION='1.32.10' PACKAGE_VERSION='1.33.0-dev+20250525022201'
PACKAGE_STRING='mpg123 1.32.10' PACKAGE_STRING='mpg123 1.33.0-dev+20250525022201'
PACKAGE_BUGREPORT='maintainer@mpg123.org' PACKAGE_BUGREPORT='maintainer@mpg123.org'
PACKAGE_URL='' PACKAGE_URL=''
@@ -1727,7 +1727,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures mpg123 1.32.10 to adapt to many kinds of systems. \`configure' configures mpg123 1.33.0-dev+20250525022201 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1798,7 +1798,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of mpg123 1.32.10:";; short | recursive ) echo "Configuration of mpg123 1.33.0-dev+20250525022201:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1877,7 +1877,8 @@ Optional Features:
--disable-layer1 no layer I decoding --disable-layer1 no layer I decoding
--disable-layer2 no layer II decoding --disable-layer2 no layer II decoding
--disable-layer3 no layer III decoding --disable-layer3 no layer III decoding
--enable-portable only build portable API (no off_t, no internal I/O) --enable-portable only build portable API (no off_t, no internal I/O
-- and no end-user programs)
--disable-largefile to not attempt to use 64 bit file offsets internally --disable-largefile to not attempt to use 64 bit file offsets internally
--disable-feature_report --disable-feature_report
Disable feature report function Disable feature report function
@@ -2076,7 +2077,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
mpg123 configure 1.32.10 mpg123 configure 1.33.0-dev+20250525022201
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2621,7 +2622,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by mpg123 $as_me 1.32.10, which was It was created by mpg123 $as_me 1.33.0-dev+20250525022201, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -3390,8 +3391,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
LIBMPG123_VERSION=48:3:48 LIBMPG123_VERSION=49:3:49
LIBOUT123_VERSION=5:1:5 LIBOUT123_VERSION=5:2:5
LIBSYN123_VERSION=2:3:2 LIBSYN123_VERSION=2:3:2
@@ -3991,7 +3992,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='mpg123' PACKAGE='mpg123'
VERSION='1.32.10' VERSION='1.33.0-dev+20250525022201'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -17131,7 +17132,7 @@ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if .balign is present" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if .balign is present" >&5
printf %s "checking if .balign is present... " >&6; } printf %s "checking if .balign is present... " >&6; }
echo '.balign 4' > conftest.s echo '.balign 4' > conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } printf "%s\n" "yes" >&6; }
@@ -17151,7 +17152,7 @@ if test x"$asmalign_exp" = xunknown; then
printf %s "checking if .align takes 2-exponent... " >&6; } printf %s "checking if .align takes 2-exponent... " >&6; }
asmalign_exp="no" asmalign_exp="no"
echo '.align 3' > conftest.s echo '.align 3' > conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
asmalign_exp="yes" asmalign_exp="yes"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } printf "%s\n" "yes" >&6; }
@@ -17198,7 +17199,7 @@ printf %s "checking if assembler supports AVX instructions... " >&6; }
avx_support="no" avx_support="no"
echo '.text' > conftest.s echo '.text' > conftest.s
echo 'vaddps %ymm0,%ymm0,%ymm0' >> conftest.s echo 'vaddps %ymm0,%ymm0,%ymm0' >> conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
avx_support="yes" avx_support="yes"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } printf "%s\n" "yes" >&6; }
@@ -17789,6 +17790,7 @@ then :
fi fi
# strtok_s for MSVCRT, not the C11 variant
ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
if test "x$ac_cv_func_strerror" = xyes if test "x$ac_cv_func_strerror" = xyes
then : then :
@@ -17807,6 +17809,18 @@ then :
printf "%s\n" "#define HAVE_USELOCALE 1" >>confdefs.h printf "%s\n" "#define HAVE_USELOCALE 1" >>confdefs.h
fi fi
ac_fn_c_check_func "$LINENO" "strtok_r" "ac_cv_func_strtok_r"
if test "x$ac_cv_func_strtok_r" = xyes
then :
printf "%s\n" "#define HAVE_STRTOK_R 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "strtok_s" "ac_cv_func_strtok_s"
if test "x$ac_cv_func_strtok_s" = xyes
then :
printf "%s\n" "#define HAVE_STRTOK_S 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale"
@@ -22453,7 +22467,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by mpg123 $as_me 1.32.10, which was This file was extended by mpg123 $as_me 1.33.0-dev+20250525022201, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -22521,7 +22535,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
mpg123 config.status 1.32.10 mpg123 config.status 1.33.0-dev+20250525022201
configured by $0, generated by GNU Autoconf 2.71, configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@@ -24222,11 +24236,18 @@ fi
default_offset_bits=`expr "$ac_cv_sizeof_off_t" "*" "8"` default_offset_bits=`expr "$ac_cv_sizeof_off_t" "*" "8"`
if test "x$build_programs" = xyes && ! test "x$portable_api" = xyes; then
build_mpg123_programs=yes
else
build_mpg123_programs=no
fi
echo " echo "
$PACKAGE_NAME $PACKAGE_VERSION $PACKAGE_NAME $PACKAGE_VERSION
Install path ............ $prefix Install path ............ $prefix
Components .............. $components Components .............. $components
Main mpg123 program(s)... $build_mpg123_programs
CPU Optimization ........ $cpu_type CPU Optimization ........ $cpu_type
Compiler Optimization ... $with_optimization" Compiler Optimization ... $with_optimization"
if test x"$use_yasm_for_avx" = xyes; then if test x"$use_yasm_for_avx" = xyes; then

View File

@@ -1209,7 +1209,7 @@ dnl ############## Assembler, compiler properties
# extended to use balign if present # extended to use balign if present
AC_MSG_CHECKING([if .balign is present]) AC_MSG_CHECKING([if .balign is present])
echo '.balign 4' > conftest.s echo '.balign 4' > conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
AC_DEFINE(ASMALIGN_BALIGN, 1, [ Define if .balign is present. ]) AC_DEFINE(ASMALIGN_BALIGN, 1, [ Define if .balign is present. ])
@@ -1224,7 +1224,7 @@ if test x"$asmalign_exp" = xunknown; then
AC_MSG_CHECKING([if .align takes 2-exponent]) AC_MSG_CHECKING([if .align takes 2-exponent])
asmalign_exp="no" asmalign_exp="no"
echo '.align 3' > conftest.s echo '.align 3' > conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
asmalign_exp="yes" asmalign_exp="yes"
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
else else
@@ -1263,7 +1263,7 @@ if test x"$avx_support" = xunknown; then
avx_support="no" avx_support="no"
echo '.text' > conftest.s echo '.text' > conftest.s
echo 'vaddps %ymm0,%ymm0,%ymm0' >> conftest.s echo 'vaddps %ymm0,%ymm0,%ymm0' >> conftest.s
if $CCAS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then if $CCAS $CCASFLAGS -c -o conftest.o conftest.s 1>/dev/null 2>&1; then
avx_support="yes" avx_support="yes"
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
else else
@@ -1331,7 +1331,7 @@ dnl ############## LFS stuff
portable_api=no portable_api=no
AC_ARG_ENABLE(portable, AC_ARG_ENABLE(portable,
[AS_HELP_STRING( [--enable-portable], [only build portable API (no off_t, no internal I/O)])], [AS_HELP_STRING( [--enable-portable], [only build portable API (no off_t, no internal I/O -- and no end-user programs)])],
[ [
if test "x$enableval" = xyes; then if test "x$enableval" = xyes; then
portable_api="yes" portable_api="yes"
@@ -1491,7 +1491,8 @@ AC_CHECK_FUNCS( sched_setscheduler setuid getuid)
# Check for setpriority # Check for setpriority
AC_CHECK_FUNCS( setpriority ) AC_CHECK_FUNCS( setpriority )
AC_CHECK_FUNCS( strerror strerror_l uselocale ) # strtok_s for MSVCRT, not the C11 variant
AC_CHECK_FUNCS( strerror strerror_l uselocale strtok_r strtok_s)
AC_CHECK_FUNCS( setlocale nl_langinfo mbstowcs wcstombs wcswidth iswprint ) AC_CHECK_FUNCS( setlocale nl_langinfo mbstowcs wcstombs wcswidth iswprint )
@@ -2953,11 +2954,18 @@ dnl ############## Display Message
default_offset_bits=`expr "$ac_cv_sizeof_off_t" "*" "8"` default_offset_bits=`expr "$ac_cv_sizeof_off_t" "*" "8"`
if test "x$build_programs" = xyes && ! test "x$portable_api" = xyes; then
build_mpg123_programs=yes
else
build_mpg123_programs=no
fi
echo " echo "
$PACKAGE_NAME $PACKAGE_VERSION $PACKAGE_NAME $PACKAGE_VERSION
Install path ............ $prefix Install path ............ $prefix
Components .............. $components Components .............. $components
Main mpg123 program(s)... $build_mpg123_programs
CPU Optimization ........ $cpu_type CPU Optimization ........ $cpu_type
Compiler Optimization ... $with_optimization" Compiler Optimization ... $with_optimization"
if test x"$use_yasm_for_avx" = xyes; then if test x"$use_yasm_for_avx" = xyes; then

View File

@@ -141,9 +141,10 @@ is the number of entry starting at 1. A value of 0 is the default and means play
Enable playlist continuation mode. This changes frame skipping to apply only to the first track and also continues to play following tracks in playlist after the selected one. Also, the option to play a number of frames only applies to the whole playlist. Basically, this tries to treat the playlist more like one big stream (like, an audio book). Enable playlist continuation mode. This changes frame skipping to apply only to the first track and also continues to play following tracks in playlist after the selected one. Also, the option to play a number of frames only applies to the whole playlist. Basically, this tries to treat the playlist more like one big stream (like, an audio book).
The current track number in list (1-based) and frame number (0-based) are printed at exit (useful if you interrupted playback and want to continue later). The current track number in list (1-based) and frame number (0-based) are printed at exit (useful if you interrupted playback and want to continue later).
Note that the continuation info is printed to standard output unless the switch for piping audio data to standard out is used. Also, it really makes sense to work with actual playlist files instead of lists of file names as arguments, to keep track positions consistent. Note that the continuation info is printed to standard output unless the switch for piping audio data to standard out is used. Also, it really makes sense to work with actual playlist files instead of lists of file names as arguments, to keep track positions consistent.
This interacts fine with \-\-random since version 1.33, but not \-\-shuffle, as that destroys the notion of a stable position in the playlist.
.TP .TP
\fB\-\-loop \fItimes\fR \fB\-\-loop \fItimes\fR
for looping track(s) a certain number of times, < 0 means infinite loop (not with \-\-random!). for playing track(s) a certain number of times in a loop, < 0 means infinite loop.
.TP .TP
.BR \-\-keep\-open .BR \-\-keep\-open
For remote control mode: Keep loaded file open after reaching end. For remote control mode: Keep loaded file open after reaching end.
@@ -228,7 +229,7 @@ as a CDR file. If \- is used as the filename, the CDR file is written
to stdout. to stdout.
.TP .TP
.BR \-\-reopen .BR \-\-reopen
Forces reopen of the audiodevice after ever song Forces reopen of the audiodevice after every track.
.TP .TP
.BR \-\-cpu\ \fIdecoder\-type .BR \-\-cpu\ \fIdecoder\-type
Selects a certain decoder (optimized for specific CPU), for example i586 or MMX. Selects a certain decoder (optimized for specific CPU), for example i586 or MMX.

View File

@@ -3,7 +3,7 @@
# - devel packages for alsa, sdl, etc... to build the respective output modules. # - devel packages for alsa, sdl, etc... to build the respective output modules.
Summary: The fast console mpeg audio decoder/player. Summary: The fast console mpeg audio decoder/player.
Name: mpg123 Name: mpg123
Version: 1.32.10 Version: 1.33.0-dev+20250525022201
Release: 1 Release: 1
URL: http://www.mpg123.org/ URL: http://www.mpg123.org/
License: GPL License: GPL

View File

@@ -67,6 +67,8 @@ check_function_exists(shmdt HAVE_SHMDT)
check_function_exists(shmctl HAVE_SHMCTL) check_function_exists(shmctl HAVE_SHMCTL)
check_function_exists(strerror HAVE_STRERROR) check_function_exists(strerror HAVE_STRERROR)
check_function_exists(strerror_l HAVE_STRERROR_L) check_function_exists(strerror_l HAVE_STRERROR_L)
check_function_exists(strtok_r HAVE_STRTOK_R)
check_function_exists(strtok_s HAVE_STRTOK_S)
check_function_exists(fork HAVE_FORK) check_function_exists(fork HAVE_FORK)
check_function_exists(execvp HAVE_EXECVP) check_function_exists(execvp HAVE_EXECVP)
check_function_exists(ctermid HAVE_CTERMID) check_function_exists(ctermid HAVE_CTERMID)

View File

@@ -43,6 +43,8 @@
#cmakedefine HAVE_SIGNAL_H 1 #cmakedefine HAVE_SIGNAL_H 1
#cmakedefine HAVE_STRERROR 1 #cmakedefine HAVE_STRERROR 1
#cmakedefine HAVE_STRERROR_L 1 #cmakedefine HAVE_STRERROR_L 1
#cmakedefine HAVE_STRTOK_R 1
#cmakedefine HAVE_STRTOK_S 1
#cmakedefine HAVE_FORK 1 #cmakedefine HAVE_FORK 1
#cmakedefine HAVE_EXECVP 1 #cmakedefine HAVE_EXECVP 1
#cmakedefine HAVE_CTERMID 1 #cmakedefine HAVE_CTERMID 1

View File

@@ -110,8 +110,17 @@
typedef unsigned char byte; typedef unsigned char byte;
// Annoying hackery to select a safe strtok variant. MS decided to call their strtok_r strtok_s, while
// C11 declares another strtok_s with different prototype. Thanks to you all.
#ifdef HAVE_STRTOK_R
#define INT123_compat_strtok(a, b, c) strtok_r((a), (b), (c))
#endif
#if (defined(_UCRT) || defined(_MSC_VER) || (defined(__MINGW32__) || defined(__MINGW64__)) || (defined(__WATCOMC__) && defined(__NT__))) && !defined(__CYGWIN__) #if (defined(_UCRT) || defined(_MSC_VER) || (defined(__MINGW32__) || defined(__MINGW64__)) || (defined(__WATCOMC__) && defined(__NT__))) && !defined(__CYGWIN__)
#define MPG123_COMPAT_MSVCRT_IO #define MPG123_COMPAT_MSVCRT_IO
#ifndef INT123_compat_strtok
#define INT123_compat_strtok(a, b, c) strtok_s((a), (b), (c))
#endif
#endif #endif
#if defined(MPG123_COMPAT_MSVCRT_IO) #if defined(MPG123_COMPAT_MSVCRT_IO)
@@ -150,6 +159,11 @@ typedef unsigned char byte;
#include <io.h> #include <io.h>
#endif #endif
#ifndef INT123_compat_strtok
#warning "no safe strtok found"
#define INT123_compat_strtok(a, b, c) strtok((a), (b))
#endif
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */ /* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *INT123_safe_realloc(void *ptr, size_t size); void *INT123_safe_realloc(void *ptr, size_t size);
// Also freeing ptr if result is NULL. You can do // Also freeing ptr if result is NULL. You can do

View File

@@ -49,9 +49,9 @@
#include "../common/debug.h" #include "../common/debug.h"
#include "wpathconv.h"
#ifdef USE_MODULES #ifdef USE_MODULES
#include "wpathconv.h"
/* /*
This is what I expected the platform-specific dance for dynamic module This is what I expected the platform-specific dance for dynamic module
support to be. Little did I know about the peculiarities of (long) support to be. Little did I know about the peculiarities of (long)

View File

@@ -244,6 +244,12 @@
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H #undef HAVE_STRING_H
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if you have the `strtok_s' function. */
#undef HAVE_STRTOK_S
/* Define to 1 if you have the <sun/audioio.h> header file. */ /* Define to 1 if you have the <sun/audioio.h> header file. */
#undef HAVE_SUN_AUDIOIO_H #undef HAVE_SUN_AUDIOIO_H

View File

@@ -780,8 +780,9 @@ int control_generic (mpg123_handle *fr)
/* commands with arguments */ /* commands with arguments */
cmd = NULL; cmd = NULL;
arg = NULL; arg = NULL;
cmd = strtok(comstr," \t"); /* get the main command */ char *toksave = NULL;
arg = strtok(NULL,""); /* get the args */ cmd = INT123_compat_strtok(comstr, " \t", &toksave); /* get the main command */
arg = INT123_compat_strtok(NULL, "", &toksave); /* get the args */
if (cmd && strlen(cmd) && arg && strlen(arg)) if (cmd && strlen(cmd) && arg && strlen(arg))
{ {

View File

@@ -13,11 +13,15 @@
/** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */ /** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */
/** \defgroup mpg123_h mpg123 header general settings and notes
* @{
*/
/** A macro to check at compile time which set of API functions to expect. /** A macro to check at compile time which set of API functions to expect.
* This must be incremented at least each time a new symbol is added * This must be incremented at least each time a new symbol is added
* to the header. * to the header.
*/ */
#define MPG123_API_VERSION 48 #define MPG123_API_VERSION 49
/** library patch level at client build time */ /** library patch level at client build time */
#define MPG123_PATCHLEVEL 3 #define MPG123_PATCHLEVEL 3
@@ -43,8 +47,10 @@
#endif #endif
#endif #endif
/** Earlier versions of libmpg123 put enums into public API calls, /** \page enumapi About enum API
* thich is not exactly safe. There are ABI rules, but you can use *
* Earlier versions of libmpg123 put enums into public API calls,
* which is not exactly safe. There are ABI rules, but you can use
* compiler switches to change the sizes of enums. It is safer not * compiler switches to change the sizes of enums. It is safer not
* to have them in API calls. Thus, the default is to remap calls and * to have them in API calls. Thus, the default is to remap calls and
* structs to variants that use plain ints. Define MPG123_ENUM_API to * structs to variants that use plain ints. Define MPG123_ENUM_API to
@@ -53,6 +59,21 @@
* You might want to define this to increase the chance of your binary * You might want to define this to increase the chance of your binary
* working with an older version of the library. But if that is your goal, * working with an older version of the library. But if that is your goal,
* you should better build with an older version to begin with. * you should better build with an older version to begin with.
*
* You can avoid renamed symbols by using the non-enum names directly:
*
* - mpg123_param2()
* - mpg123_getparam2()
* - mpg123_feature2()
* - mpg123_eq2()
* - mpg123_geteq2()
* - mpg123_frameinfo2()
* - mpg123_info2()
* - mpg123_getstate2()
* - mpg123_enc_from_id3_2()
* - mpg123_store_utf8_2()
* - mpg123_par2()
* - mpg123_getpar2()
*/ */
#ifndef MPG123_ENUM_API #ifndef MPG123_ENUM_API
@@ -76,7 +97,7 @@
#ifndef MPG123_PORTABLE_API #ifndef MPG123_PORTABLE_API
#include <sys/types.h> #include <sys/types.h>
/* A little hack to help MSVC not having ssize_t. */ /** A little hack to help MSVC not having ssize_t. */
#ifdef _MSC_VER #ifdef _MSC_VER
typedef ptrdiff_t mpg123_ssize_t; typedef ptrdiff_t mpg123_ssize_t;
#else #else
@@ -85,26 +106,61 @@ typedef ssize_t mpg123_ssize_t;
#endif #endif
/* Handling of large file offsets. /** \page lfs Handling of large file offsets
When client code defines _FILE_OFFSET_BITS, it wants non-default large file support, *
and thus functions with added suffix (mpg123_open_64). The default library build provides * When client code defines _FILE_OFFSET_BITS, it wants non-default large file
wrapper and alias functions to accomodate client code variations (dual-mode library like glibc). * support, and thus functions with added suffix (mpg123_open_64). The default
* library build provides wrapper and alias functions to accomodate client code
Client code can definie MPG123_NO_LARGENAME and MPG123_LARGESUFFIX, respectively, for disabling * variations (dual-mode library like glibc).
or enforcing the suffixes. If explicit usage of 64 bit offsets is desired, the int64_t API *
(functions with 64 suffix without underscore, notablly mpg123_reader64()) can be used since * Client code can definie MPG123_NO_LARGENAME and MPG123_LARGESUFFIX,
API version 48 (mpg123 1.32). * respectively, for disabling or enforcing the suffixes. You should *not* do
* this, though, unless you *really* want to deal with symbol ABI yourself.
When in doubt, use the explicit 64 bit functions and avoid off_t in the API. You can define * If explicit usage of 64 bit offsets is desired, the int64_t API
MPG123_PORTABLE_API to ensure that. That being said, if you and your compiler do not have * consisting of functions with 64 suffix without underscore, notably
problems with the concept of off_t, just use the normal API and be happy. Both 32 and 64 * mpg123_reader64(), can be used since API version 48 (mpg123 1.32). A matching
bit versions will be present where appropriate. * mpg123_open64(), stripped-down mpg123_open_handle_64() is present since API
* version 49 (mpg123 1.33).
*
* When in doubt, use the explicit 64 bit functions and avoid off_t in the API.
* You can define MPG123_PORTABLE_API to ensure that. That being said, if you
* and your compiler do not have problems with the concept of off_t, just use
* the normal AP like the I/O API of the standard C library. Both 32 and 64 bit
* versions of functions will be present where appropriate.
*
* If your toolchain enforces _FILE_OFFSET_BITS also during build of libmpg123,
* only that setting will be supported for client code.
*/ */
#ifndef MPG123_PORTABLE_API #ifndef MPG123_PORTABLE_API
/* /** \page lfs_names Renaming of functions for largefile support
Now, the renaming of large file aware functions. *
By default, it appends underscore _FILE_OFFSET_BITS (so, mpg123_seek_64 for mpg123_seek), if _FILE_OFFSET_BITS is defined. You can force a different suffix via MPG123_LARGESUFFIX (that must include the underscore), or you can just disable the whole mess by defining MPG123_NO_LARGENAME. * Now, the renaming of large file aware functions.
* By default, it appends underscore _FILE_OFFSET_BITS (so, mpg123_seek_64() for mpg123_seek()),
* if _FILE_OFFSET_BITS is defined. These are the affected API functions:
*
* - mpg123_open_fixed()
* - mpg123_open()
* - mpg123_open_fd()
* - mpg123_open_handle()
* - mpg123_framebyframe_decode()
* - mpg123_decode_frame()
* - mpg123_tell()
* - mpg123_tellframe()
* - mpg123_tell_stream()
* - mpg123_seek()
* - mpg123_feedseek()
* - mpg123_seek_frame()
* - mpg123_timeframe()
* - mpg123_index()
* - mpg123_set_index()
* - mpg123_position()
* - mpg123_length()
* - mpg123_framelength()
* - mpg123_set_filesize()
* - mpg123_replace_reader()
* - mpg123_replace_reader_handle()
* - mpg123_framepos()
*/ */
#if (!defined MPG123_NO_LARGENAME) && ((defined _FILE_OFFSET_BITS) || (defined MPG123_LARGESUFFIX)) #if (!defined MPG123_NO_LARGENAME) && ((defined _FILE_OFFSET_BITS) || (defined MPG123_LARGESUFFIX))
@@ -142,6 +198,8 @@ typedef ssize_t mpg123_ssize_t;
#endif /* largefile hackery */ #endif /* largefile hackery */
#endif #endif
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -774,7 +832,7 @@ MPG123_EXPORT int mpg123_open_fixed(mpg123_handle *mh, const char *path
* UTF-8, which also fits any sane modern install of Unix-like systems. * UTF-8, which also fits any sane modern install of Unix-like systems.
* *
* \param mh handle * \param mh handle
* \param path filesystem * \param path filesystem path
* \return MPG123_OK on success * \return MPG123_OK on success
*/ */
MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path); MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path);
@@ -786,17 +844,63 @@ MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path);
* \return MPG123_OK on success * \return MPG123_OK on success
*/ */
MPG123_EXPORT int mpg123_open_fd(mpg123_handle *mh, int fd); MPG123_EXPORT int mpg123_open_fd(mpg123_handle *mh, int fd);
#endif
/** Use an opaque handle as bitstream input. This works only with the /** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_replace_reader_handle() or mpg123_reader64()! * replaced I/O from mpg123_replace_reader_handle() or mpg123_reader64()!
* mpg123_close() will call the cleanup callback for your non-NULL * mpg123_close() will call the cleanup callback for your non-NULL
* handle (if you gave one). * handle (if you gave one).
* Note that this used to be usable with MPG123_PORTABLE_API defined in
* mpg123 1.32.x and was in fact the only entry point for handle I/O.
* Since mpg123 1.33.0 and API version 49, there is
* mpg123_open_handle64() for the portable case and has to be used
* instead of this function here, even if it _would_ work just fine,
* the inclusion of a largefile-renamed symbol in the portable set was wrong.
*
* \param mh handle * \param mh handle
* \param iohandle your handle * \param iohandle your handle
* \return MPG123_OK on success * \return MPG123_OK on success
*/ */
MPG123_EXPORT int mpg123_open_handle(mpg123_handle *mh, void *iohandle); MPG123_EXPORT int mpg123_open_handle(mpg123_handle *mh, void *iohandle);
#endif
/** Open and prepare to decode the specified file by filesystem path.
* This works exactly like mpg123_open() in modern libmpg123, see there
* for more description. This name is not subject to largefile symbol renaming.
* You can also use it with MPG123_PORTABLE_API.
*
* \param mh handle
* \param path filesystem path of your resource
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open64(mpg123_handle *mh, const char *path);
/** Open a simple MPEG file with fixed properties.
* This is the same as mpg123_open_fixed(), just with a stable
* symbol name for int64_t portable API.
*
* \param mh handle
* \param path filesystem path (see mpg123_open())
* \param channels allowed channel count, either 1 (MPG123_MONO) or
* 2 (MPG123_STEREO), or bitwise or of them, but then you're halfway back to
* calling mpg123_format() again;-)
* \param encoding a definite encoding from enum mpg123_enc_enum
* or a bitmask like for mpg123_format(), defeating the purpose somewhat
*/
MPG123_EXPORT int mpg123_open_fixed64(mpg123_handle *mh, const char *path
, int channels, int encoding);
/** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_reader64()!
* mpg123_close() will call the cleanup callback for your non-NULL
* handle (if you gave one).
* This is a simplified variant of mpg123_open_handle() that only
* supports the int64_t API, available with MPG123_PORTABLE_API.
*
* \param mh handle
* \param iohandle your handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_handle64(mpg123_handle *mh, void *iohandle);
/** Open a new bitstream and prepare for direct feeding /** Open a new bitstream and prepare for direct feeding
* This works together with mpg123_decode(); you are responsible for reading and feeding the input bitstream. * This works together with mpg123_decode(); you are responsible for reading and feeding the input bitstream.
@@ -1258,6 +1362,7 @@ MPG123_EXPORT int mpg123_eq2( mpg123_handle *mh
/** Set a range of equalizer bands /** Set a range of equalizer bands
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or * \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both. * #MPG123_LEFT|#MPG123_RIGHT for both.
* \param mh handle
* \param a The first equalizer band to set (from 0 to 31) * \param a The first equalizer band to set (from 0 to 31)
* \param b The last equalizer band to set (from 0 to 31) * \param b The last equalizer band to set (from 0 to 31)
* \param factor The (linear) adjustment factor, 1 being neutral. * \param factor The (linear) adjustment factor, 1 being neutral.
@@ -1267,6 +1372,7 @@ MPG123_EXPORT int mpg123_eq_bands( mpg123_handle *mh
, int channel, int a, int b, double factor ); , int channel, int a, int b, double factor );
/** Change a range of equalizer bands /** Change a range of equalizer bands
* \param mh handle
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or * \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both. * #MPG123_LEFT|#MPG123_RIGHT for both.
* \param a The first equalizer band to change (from 0 to 31) * \param a The first equalizer band to change (from 0 to 31)
@@ -2218,7 +2324,8 @@ MPG123_EXPORT int mpg123_replace_reader_handle( mpg123_handle *mh
/** Set up portable read functions on an opaque handle. /** Set up portable read functions on an opaque handle.
* The handle is a void pointer, so you can pass any data you want... * The handle is a void pointer, so you can pass any data you want...
* mpg123_open_handle() is the call you make to use the I/O defined here. * mpg123_open64() (since API 49) or mpg123_open_handle() is the call you make
* to use the I/O defined here.
* There is no fallback to internal read/seek here. * There is no fallback to internal read/seek here.
* Note: As it would be troublesome to mess with this while having a file open, * Note: As it would be troublesome to mess with this while having a file open,
* this mpg123_close() is implied here. * this mpg123_close() is implied here.

View File

@@ -20,7 +20,7 @@
*/ */
#define OUT123_API_VERSION 5 #define OUT123_API_VERSION 5
/** library patch level at client build time */ /** library patch level at client build time */
#define OUT123_PATCHLEVEL 1 #define OUT123_PATCHLEVEL 2
/* We only need size_t definition. */ /* We only need size_t definition. */
#include <stddef.h> #include <stddef.h>

View File

@@ -1112,7 +1112,7 @@ void syn123_be2host(void *buf, size_t samplesize, size_t samplecount);
// anywhere, also to avoid using non-standard types like ssize_t. // anywhere, also to avoid using non-standard types like ssize_t.
#if !defined(SYN123_PORTABLE_API) && !defined(SYN123_NO_LARGEFUNC) #if !defined(SYN123_PORTABLE_API) && !defined(SYN123_NO_LARGEFUNC)
/* A little hack to help MSVC not having ssize_t, duplicated in internal header. */ /** A little hack to help MSVC not having ssize_t, duplicated in internal header. */
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stddef.h> #include <stddef.h>
typedef ptrdiff_t syn123_ssize_t; typedef ptrdiff_t syn123_ssize_t;

View File

@@ -341,7 +341,8 @@ int INT123_do_layer2(mpg123_handle *fr)
if(fr->jsbound > fr->II_sblimit) if(fr->jsbound > fr->II_sblimit)
{ {
fprintf(stderr, "Truncating stereo boundary to sideband limit.\n"); if(NOQUIET)
error("Truncating stereo boundary to sideband limit.");
fr->jsbound=fr->II_sblimit; fr->jsbound=fr->II_sblimit;
} }

View File

@@ -15,9 +15,7 @@
#define FORCE_ACCURATE #define FORCE_ACCURATE
#include "../common/sample.h" #include "../common/sample.h"
#include "parse.h" #include "parse.h"
#ifndef PORTABLE_API
#include "lfs_wrap.h" #include "lfs_wrap.h"
#endif
#include "../common/debug.h" #include "../common/debug.h"
@@ -559,18 +557,9 @@ double attribute_align_arg mpg123_geteq2(mpg123_handle *mh, int channel, int ban
return mpg123_geteq(mh, channel, band); return mpg123_geteq(mh, channel, band);
} }
#ifndef PORTABLE_API // LFS wrapper code is so agnostic to it all now that internal I/O is portable
// as long as you do not mix in off_t API.
#ifdef FORCED_OFF_64 int attribute_align_arg mpg123_open64(mpg123_handle *mh, const char *path)
// Only _64 symbols for a system-wide enforced _FILE_OFFSET_BITS=64.
#define mpg123_open mpg123_open_64
#define mpg123_open_fixed mpg123_open_fixed_64
#define mpg123_open_fd mpg123_open_fd_64
#define mpg123_open_handle mpg123_open_handle_64
#endif
/* plain file access, no http! */
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
{ {
if(mh == NULL) return MPG123_BAD_HANDLE; if(mh == NULL) return MPG123_BAD_HANDLE;
@@ -585,6 +574,24 @@ int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
return ret; return ret;
} }
#ifndef PORTABLE_API
#ifdef FORCED_OFF_64
// Only _64 symbols for a system-wide enforced _FILE_OFFSET_BITS=64.
#define mpg123_open mpg123_open_64
#define mpg123_open_fixed mpg123_open_fixed_64
#define mpg123_open_fd mpg123_open_fd_64
#define mpg123_open_handle mpg123_open_handle_64
#endif
// This now is agnostic to off_t choice, but still subject to renaming
// for legacy reasons.
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
{
return mpg123_open64(mh, path);
}
#endif // PORTABLE_API
// The convenience function mpg123_open_fixed() wraps over acual mpg123_open // The convenience function mpg123_open_fixed() wraps over acual mpg123_open
// and hence needs to have the exact same code in lfs_wrap.c. The flesh is // and hence needs to have the exact same code in lfs_wrap.c. The flesh is
// in INT123_open_fixed_pre() and INT123_open_fixed_post(), wich are only defined here. // in INT123_open_fixed_pre() and INT123_open_fixed_post(), wich are only defined here.
@@ -624,17 +631,28 @@ static int INT123_open_fixed_post(mpg123_handle *mh, int channels, int encoding)
return err; return err;
} }
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path int attribute_align_arg mpg123_open_fixed64( mpg123_handle *mh, const char *path
, int channels, int encoding ) , int channels, int encoding )
{ {
int err = INT123_open_fixed_pre(mh, channels, encoding); int err = INT123_open_fixed_pre(mh, channels, encoding);
if(err == MPG123_OK) if(err == MPG123_OK)
err = mpg123_open(mh, path); err = mpg123_open64(mh, path);
if(err == MPG123_OK) if(err == MPG123_OK)
err = INT123_open_fixed_post(mh, channels, encoding); err = INT123_open_fixed_post(mh, channels, encoding);
return err; return err;
} }
#ifndef PORTABLE_API
// Only to have the modern offset-agnostic open under a fixed name.
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
return mpg123_open_fixed64(mh, path, channels, encoding);
}
// Won't define a 'portable' variant of this, as I cannot guess
// properties of the handed-in fd, which in theory, on specific platforms,
// could not support large files.
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd) int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
{ {
if(mh == NULL) return MPG123_BAD_HANDLE; if(mh == NULL) return MPG123_BAD_HANDLE;
@@ -650,21 +668,33 @@ int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
} }
#endif // PORTABLE_API #endif // PORTABLE_API
// Only works with int64 reader setup.
int attribute_align_arg mpg123_open_handle64(mpg123_handle *mh, void *iohandle)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
mpg123_close(mh);
return INT123_open_stream_handle(mh, iohandle);
}
#ifndef PORTABLE_API
// Change from 1.32: No largefile-renamed symbols in a library with strict
// portable API.
// I allow that breaking change since this is far from a standard libmpg123 build.
int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle) int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle)
{ {
if(mh == NULL) return MPG123_BAD_HANDLE; if(mh == NULL) return MPG123_BAD_HANDLE;
mpg123_close(mh); mpg123_close(mh);
int ret; int ret;
#ifndef PORTABLE_API
ret = INT123_wrap_open( mh, iohandle, NULL, -1 ret = INT123_wrap_open( mh, iohandle, NULL, -1
, mh->p.timeout, mh->p.flags & MPG123_QUIET ); , mh->p.timeout, mh->p.flags & MPG123_QUIET );
iohandle = ret == LFS_WRAP_NONE ? iohandle : mh->wrapperdata; iohandle = ret == LFS_WRAP_NONE ? iohandle : mh->wrapperdata;
if(ret >= 0) if(ret >= 0)
#endif
ret = INT123_open_stream_handle(mh, iohandle); ret = INT123_open_stream_handle(mh, iohandle);
return ret; return ret;
} }
#endif
int attribute_align_arg mpg123_open_feed(mpg123_handle *mh) int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
{ {

View File

@@ -456,11 +456,11 @@ out123_open(out123_handle *ao, const char* driver, const char* device)
/* Now loop over the list of possible modules to find one that works. */ /* Now loop over the list of possible modules to find one that works. */
char *toksave = NULL; char *toksave = NULL;
nextname = strtok_r(modnames, ",", &toksave); nextname = INT123_compat_strtok(modnames, ",", &toksave);
while(!ao->open && nextname) while(!ao->open && nextname)
{ {
char *curname = nextname; char *curname = nextname;
nextname = strtok_r(NULL, ",", &toksave); nextname = INT123_compat_strtok(NULL, ",", &toksave);
check_output_module(ao, curname, device, !nextname); check_output_module(ao, curname, device, !nextname);
if(ao->open) if(ao->open)
{ {

View File

@@ -172,7 +172,7 @@ static int get_formats_win32(out123_handle *ao)
int ret = 0; int ret = 0;
UINT dev_id = dev_select(ao); UINT dev_id = dev_select(ao);
MMRESULT mr = waveOutGetDevCaps(dev_id, &caps, sizeof(caps)); MMRESULT mr = waveOutGetDevCapsA(dev_id, &caps, sizeof(caps));
if(mr != MMSYSERR_NOERROR) if(mr != MMSYSERR_NOERROR)
return 0; /* no formats? */ return 0; /* no formats? */
@@ -367,7 +367,7 @@ static int enumerate_win32( out123_handle *ao, int (*store_device)(void *devlist
for(i = 0; i < devices; i++){ for(i = 0; i < devices; i++){
memset(id, 0, sizeof(id)); memset(id, 0, sizeof(id));
memset(&caps, 0, sizeof(caps)); memset(&caps, 0, sizeof(caps));
mr = waveOutGetDevCaps(i, &caps, sizeof(caps)); mr = waveOutGetDevCapsA(i, &caps, sizeof(caps));
if (mr != MMSYSERR_NOERROR) { if (mr != MMSYSERR_NOERROR) {
switch(mr) { switch(mr) {
case MMSYSERR_BADDEVICEID: case MMSYSERR_BADDEVICEID:

View File

@@ -59,6 +59,7 @@ size_t utf8outstr(char **dest, const char *source, int to_terminal);
// If count is >= 0, it is used instead of strlen(source), enabling // If count is >= 0, it is used instead of strlen(source), enabling
// processing of data without closing zero byte. // processing of data without closing zero byte.
// Returns 0 if all went well, as do the others following. // Returns 0 if all went well, as do the others following.
// On error, the dest memory is freed and the pointer nulled.
int unknown2utf8(char **dest, const char *source, int count); int unknown2utf8(char **dest, const char *source, int count);
// Wrapper around the above for printing the string to some stream. // Wrapper around the above for printing the string to some stream.
// Return value is directly from fprintf or also -1 if there was trouble // Return value is directly from fprintf or also -1 if there was trouble

View File

@@ -364,7 +364,11 @@ int main(int argc, char **argv)
int i, result; int i, result;
mpg123_handle* m; mpg123_handle* m;
#if defined(WANT_WIN32_UNICODE) #if defined(WANT_WIN32_UNICODE)
win32_cmdline_utf8(&argc,&argv); if(win32_cmdline_utf8(&argc,&argv) != 0)
{
error("Cannot convert command line to UTF8!");
return 1;
}
#endif #endif
progname = argv[0]; progname = argv[0];
@@ -428,9 +432,9 @@ int main(int argc, char **argv)
mpg123_delete(m); mpg123_delete(m);
mpg123_exit(); mpg123_exit();
if(errors) error1("Encountered %i errors along the way.", errors);
return errors != 0;
#if defined(WANT_WIN32_UNICODE) #if defined(WANT_WIN32_UNICODE)
win32_cmdline_free(argc,argv); win32_cmdline_free(argc,argv);
#endif #endif
if(errors) error1("Encountered %i errors along the way.", errors);
return errors != 0;
} }

View File

@@ -1431,9 +1431,17 @@ int main(int sys_argc, char ** sys_argv)
print_outstr(stderr, filename, 0, stderr_is_term); print_outstr(stderr, filename, 0, stderr_is_term);
fprintf(stderr, " ...\n"); fprintf(stderr, " ...\n");
if(filept->htd.icy_name.fill) if(filept->htd.icy_name.fill)
fprintf(stderr, "ICY-NAME: %s\n", filept->htd.icy_name.p); {
fprintf(stderr, "ICY-NAME: ");
print_outstr(stderr, filept->htd.icy_name.p, 1, stderr_is_term);
fprintf(stderr, "\n");
}
if(filept->htd.icy_url.fill) if(filept->htd.icy_url.fill)
fprintf(stderr, "ICY-URL: %s\n", filept->htd.icy_url.p); {
fprintf(stderr, "ICY-URL: ");
print_outstr(stderr, filept->htd.icy_url.p, 1, stderr_is_term);
fprintf(stderr, "\n");
}
} }
#if !defined(GENERIC) #if !defined(GENERIC)
{ {
@@ -1515,7 +1523,9 @@ int main(int sys_argc, char ** sys_argv)
fprintf(stderr, "This was a Frankenstein track.\n"); fprintf(stderr, "This was a Frankenstein track.\n");
position_info(mh, 0, ao, NULL, NULL, &secs, NULL, NULL, NULL); position_info(mh, 0, ao, NULL, NULL, &secs, NULL, NULL, NULL);
fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", (int)(secs / 60), ((int)secs) % 60, filename); fprintf(stderr,"[%d:%02d] Decoding of ", (int)(secs / 60), ((int)secs) % 60);
print_outstr(stderr, filename, 0, stderr_is_term);
fprintf(stderr," finished.\n");
} }
else if(param.verbose) fprintf(stderr, "\n"); else if(param.verbose) fprintf(stderr, "\n");

View File

@@ -34,6 +34,14 @@
enum playlist_type { UNKNOWN = 0, M3U, PLS, NO_LIST }; enum playlist_type { UNKNOWN = 0, M3U, PLS, NO_LIST };
enum playflag
{
PL_IS_UTF8 = 1 // if we really know the contents are UTF-8-encooded
, PL_HIT_END = 2
, PL_STDIN_USED = 4 // If the playlist itself or an input file was '-' (stdin not usable for terminal.).
, PL_NO_RANDOM = 8
};
typedef struct listitem typedef struct listitem
{ {
char* url; /* the filename */ char* url; /* the filename */
@@ -56,10 +64,7 @@ typedef struct playlist_struct
mpg123_string linebuf; mpg123_string linebuf;
mpg123_string dir; mpg123_string dir;
enum playlist_type type; enum playlist_type type;
int is_utf8; /* if we really know the contents are UTF-8-encooded */ unsigned int flags;
int hit_end;
// If the playlist itself or an input file was '-' (stdin not usable for terminal.).
int stdin_used;
} playlist_struct; } playlist_struct;
/* one global instance... add a pointer to this to every function definition and you have OO-style... */ /* one global instance... add a pointer to this to every function definition and you have OO-style... */
@@ -97,7 +102,7 @@ void prepare_playlist(int argc, char** argv, int args_utf8, int *is_utf8)
mpg123_free_string(&pl.linebuf); mpg123_free_string(&pl.linebuf);
mpg123_free_string(&pl.dir); mpg123_free_string(&pl.dir);
if(is_utf8) if(is_utf8)
*is_utf8 = pl.is_utf8; *is_utf8 = (pl.flags & PL_IS_UTF8) != 0;
} }
/* Return a random number >= 0 and < n */ /* Return a random number >= 0 and < n */
@@ -142,9 +147,9 @@ char *get_next_file(void)
} }
else else
{ {
/* Handle looping first, but only if there is a random track selection // Handle looping first, but only if there is a random track selection
presently active (see playlist_jump() for interaction). */ // Also applies to continue mode.
if(!(pl.num && ((pl.loop > 0 && --pl.loop) || pl.loop < 0))) if(!(pl.num && ((pl.loop > 0 && --pl.loop) || pl.loop < 0)) && !(pl.flags & PL_NO_RANDOM))
{ {
/* Randomly select the next track. */ /* Randomly select the next track. */
do /* limiting randomness: don't repeat too early */ do /* limiting randomness: don't repeat too early */
@@ -157,6 +162,7 @@ char *get_next_file(void)
newitem = &pl.list[pl.pos]; newitem = &pl.list[pl.pos];
pl.num = pl.pos+1; pl.num = pl.pos+1;
pl.flags &= ~PL_NO_RANDOM; // The random blocking works only once.
} }
/* "-" is STDIN, "" is dumb, NULL is nothing */ /* "-" is STDIN, "" is dumb, NULL is nothing */
@@ -168,7 +174,7 @@ char *get_next_file(void)
} }
else else
{ {
pl.hit_end = TRUE; pl.flags |= PL_HIT_END;
return NULL; return NULL;
} }
} }
@@ -179,7 +185,7 @@ size_t playlist_pos(size_t *total, long *loop)
*total = pl.fill; *total = pl.fill;
if(loop) if(loop)
*loop = pl.loop; *loop = pl.loop;
return pl.hit_end ? pl.fill+1 : pl.num; return pl.flags & PL_HIT_END ? pl.fill+1 : pl.num;
} }
void playlist_jump(mpg123_ssize_t incr) void playlist_jump(mpg123_ssize_t incr)
@@ -286,23 +292,23 @@ static void init_playlist(void)
pl.fill = 0; pl.fill = 0;
pl.pos = 0; pl.pos = 0;
pl.num = 0; pl.num = 0;
if(APPFLAG(MPG123APP_CONTINUE) && param.listentry > 0)
pl.pos = param.listentry - 1;
pl.list = NULL; pl.list = NULL;
pl.alloc_step = 10; pl.alloc_step = 10;
mpg123_init_string(&pl.dir); mpg123_init_string(&pl.dir);
mpg123_init_string(&pl.linebuf); mpg123_init_string(&pl.linebuf);
pl.type = UNKNOWN; pl.type = UNKNOWN;
pl.is_utf8 = FALSE; pl.flags = 0;
pl.hit_end = FALSE;
pl.loop = param.loop; pl.loop = param.loop;
pl.stdin_used = FALSE; if(APPFLAG(MPG123APP_CONTINUE) && param.listentry > 0)
{
pl.pos = param.listentry - 1;
pl.flags |= PL_NO_RANDOM; // Skip random selection for first track.
}
} }
int playlist_stdin(void) int playlist_stdin(void)
{ {
return pl.stdin_used; return (pl.flags & PL_STDIN_USED) != 0;
} }
/* /*
@@ -314,7 +320,10 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
{ {
int firstline = 0; int firstline = 0;
pl.is_utf8 = args_utf8; if(args_utf8)
pl.flags |= PL_IS_UTF8;
else
pl.flags &= ~PL_IS_UTF8;
/* hack for url that has been detected as track, not playlist */ /* hack for url that has been detected as track, not playlist */
if(pl.type == NO_LIST) return 0; if(pl.type == NO_LIST) return 0;
@@ -343,7 +352,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
if (param.listname || pl.file) if (param.listname || pl.file)
{ {
size_t line_offset = 0; size_t line_offset = 0;
pl.is_utf8 = 0; // Playlist files in env encoding (HTTP lists should be ASCII-clean). pl.flags &= ~PL_IS_UTF8; // Playlist files in env encoding (HTTP lists should be ASCII-clean).
if(!pl.file) if(!pl.file)
{ {
pl.file = stream_open(param.listname); pl.file = stream_open(param.listname);
@@ -352,7 +361,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
firstline = 1; /* just opened */ firstline = 1; /* just opened */
if(pl.file->fd == STDIN_FILENO) if(pl.file->fd == STDIN_FILENO)
{ {
pl.stdin_used = TRUE; pl.flags |= PL_STDIN_USED;
param.listname = NULL; param.listname = NULL;
} }
} }
@@ -393,7 +402,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
} }
} }
char *ptmp = NULL; char *ptmp = NULL;
outstr(&ptmp, pl.file->htd.content_type.p, 0, stderr_is_term); outstr(&ptmp, pl.file->htd.content_type.p, 1, stderr_is_term);
error1( "Unknown playlist MIME type %s; maybe "PACKAGE_NAME error1( "Unknown playlist MIME type %s; maybe "PACKAGE_NAME
" can support it in future if you report this to the maintainer." " can support it in future if you report this to the maintainer."
, PSTR(ptmp) ); , PSTR(ptmp) );
@@ -671,7 +680,7 @@ static int add_to_playlist(char* new_entry, char freeit)
if(pl.fill < pl.size) if(pl.fill < pl.size)
{ {
if(!strcmp(new_entry, "-") || !strcmp(new_entry, "/dev/stdin")) if(!strcmp(new_entry, "-") || !strcmp(new_entry, "/dev/stdin"))
pl.stdin_used = TRUE; pl.flags |= PL_STDIN_USED;
pl.list[pl.fill].freeit = freeit; pl.list[pl.fill].freeit = freeit;
pl.list[pl.fill].url = new_entry; pl.list[pl.fill].url = new_entry;
pl.list[pl.fill].playcount = 0; pl.list[pl.fill].playcount = 0;

View File

@@ -317,6 +317,17 @@ static int stream_parse_headers(struct stream *sd, mpg123_string *location)
{ {
break; // This is the content separator line. break; // This is the content separator line.
} }
{ // Convert from unknown/ASCII encoding to UTF-8. Play safe.
char *buf = NULL;
if(unknown2utf8(&buf, line.p, -1))
{
error("failed converting HTTP header line");
continue;
}
// Avoiding extra allocation here would be nice. mpg123_adopt_string()?
mpg123_set_string(&line, buf);
free(buf);
}
// React to HTTP error codes, but do not enforce an OK being sent as Shoutcast // React to HTTP error codes, but do not enforce an OK being sent as Shoutcast
// only produces very minimal headers, not even a HTTP response code. // only produces very minimal headers, not even a HTTP response code.
// Well, ICY 200 OK could be there, but then we got other headers to know // Well, ICY 200 OK could be there, but then we got other headers to know

View File

@@ -15,11 +15,11 @@
// only single spaces as separator to ease parsing by build scripts // only single spaces as separator to ease parsing by build scripts
#define MPG123_MAJOR 1 #define MPG123_MAJOR 1
#define MPG123_MINOR 32 #define MPG123_MINOR 33
#define MPG123_PATCH 10 #define MPG123_PATCH 0
// Don't get too wild with that to avoid confusing m4. No brackets. // Don't get too wild with that to avoid confusing m4. No brackets.
// Also, it should fit well into a sane file name for the tarball. // Also, it should fit well into a sane file name for the tarball.
#define MPG123_SUFFIX "" #define MPG123_SUFFIX "-dev+20250525022201"
#define MPG123_VERSION_CAT_REALLY(a, b, c) #a "." #b "." #c #define MPG123_VERSION_CAT_REALLY(a, b, c) #a "." #b "." #c
#define MPG123_VERSION_CAT(a, b, c) MPG123_VERSION_CAT_REALLY(a, b, c) #define MPG123_VERSION_CAT(a, b, c) MPG123_VERSION_CAT_REALLY(a, b, c)

View File

@@ -22,6 +22,7 @@ void __cdecl __declspec(dllimport) __wgetmainargs (
int win32_cmdline_utf8(int * argc, char *** argv) int win32_cmdline_utf8(int * argc, char *** argv)
{ {
int argcounter; int argcounter;
int nargc;
wchar_t **argv_wide; wchar_t **argv_wide;
wchar_t **env; wchar_t **env;
char *argvptr; char *argvptr;
@@ -31,9 +32,21 @@ int win32_cmdline_utf8(int * argc, char *** argv)
if(argv == NULL || argc == NULL) return -1; if(argv == NULL || argc == NULL) return -1;
startup.newmode = 0; startup.newmode = 0;
__wgetmainargs(argc, &argv_wide,&env,1, &startup); nargc = -1;
argv_wide = NULL;
env = NULL;
__wgetmainargs(&nargc, &argv_wide,&env,1, &startup);
if (nargc == -1 || argv_wide == NULL || env == NULL) {
error("Cannot allocate memory for wide command line.");
return -1;
}
*argc = nargc;
*argv = (char **)calloc(sizeof (char *), *argc); *argv = (char **)calloc(sizeof (char *), *argc);
if(*argv == NULL){ error("Cannot allocate memory for command line."); return -1; } if(*argv == NULL)
{
error("Cannot allocate memory for UTF-8 command line.");
return -1;
}
for(argcounter = 0; argcounter < *argc; argcounter++) for(argcounter = 0; argcounter < *argc; argcounter++)
{ {

View File

@@ -9,6 +9,7 @@ if test -z "$build_type"; then
echo "Please specify a build type as argument, one of:" echo "Please specify a build type as argument, one of:"
echo "x86, x86_64, x86-cross, x86_64-cross" echo "x86, x86_64, x86-cross, x86_64-cross"
echo "Optionally set a number of parallel make processes as second argument." echo "Optionally set a number of parallel make processes as second argument."
echo "A third argument might override the list of output modules to build."
exit 1 exit 1
fi fi
@@ -23,6 +24,8 @@ build_procs=$2
# -D__MINGW_USE_VC2005_COMPAT=1 use 64bit time internally for 32bit, so XP and earlier don't get into # -D__MINGW_USE_VC2005_COMPAT=1 use 64bit time internally for 32bit, so XP and earlier don't get into
# missing _time32 errors # missing _time32 errors
modules=${3:-win32_wasapi,win32}
echo "build type: $build_type" echo "build type: $build_type"
case $build_type in case $build_type in
x86) x86)
@@ -55,8 +58,7 @@ temp="$PWD/tmp"
final="$PWD/releases" final="$PWD/releases"
txt="README COPYING NEWS" txt="README COPYING NEWS"
# let's try with modules # let's try with modules
opts="LDFLAGS=-static-libgcc" opts="--with-audio=$modules LDFLAGS=-static-libgcc"
#opts="--with-audio=win32 --disable-modules"
# Get the version for the build from version.h. # Get the version for the build from version.h.
major=$(grep '#define MPG123_MAJOR' src/version.h | cut -f 3 -d ' ') major=$(grep '#define MPG123_MAJOR' src/version.h | cut -f 3 -d ' ')