mpg123: Import upstream release 1.30.2.

This commit is contained in:
Alexandre Julliard 2022-08-03 17:27:11 +02:00
parent ce0a985f1b
commit be227979b0
11 changed files with 200 additions and 36 deletions

View file

@ -83,6 +83,9 @@
/* Define to 1 if you have the <CoreServices/CoreServices.h> header file. */
/* #undef HAVE_CORESERVICES_CORESERVICES_H */
/* Define to 1 if you have the `ctermid' function. */
/* #undef HAVE_CTERMID */
/* Define to 1 if you have the <CUlib.h> header file. */
/* #undef HAVE_CULIB_H */
@ -101,6 +104,12 @@
/* Define to 1 if you have the `dlsym' function. */
/* #undef HAVE_DLSYM */
/* Define to 1 if you have the `execvp' function. */
/* #undef HAVE_EXECVP */
/* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
@ -182,6 +191,9 @@
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1
/* for Win/DOS system with setmode() */
#define HAVE_SETMODE 1
/* Define to 1 if you have the `setpriority' function. */
/* #undef HAVE_SETPRIORITY */
@ -296,6 +308,9 @@
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#define HAVE_WS2TCPIP_H 1
/* for Win/DOS system with _setmode() */
#define HAVE__SETMODE 1
/* Define to indicate that float storage follows IEEE754. */
#define IEEE_FLOAT 1
@ -321,6 +336,9 @@
/* Define to the shared archive member specification, say "(shr.o)". */
/* #undef LT_SHARED_LIB_MEMBER */
/* Define to for new net123 network stack. */
/* #undef NET123 */
/* Define if network support is enabled. */
/* #undef NETWORK */
@ -392,7 +410,7 @@
#define PACKAGE_NAME "mpg123"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "mpg123 1.29.1"
#define PACKAGE_STRING "mpg123 1.30.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mpg123"
@ -401,7 +419,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.29.1"
#define PACKAGE_VERSION "1.30.2"
/* Define if portaudio v18 API is wanted. */
/* #undef PORTAUDIO18 */
@ -443,7 +461,7 @@
/* #undef USE_YASM_FOR_AVX */
/* Version number of package */
#define VERSION "1.29.1"
#define VERSION "1.30.2"
/* Define to use Win32 named pipes */
#define WANT_WIN32_FIFO 1

View file

@ -155,6 +155,15 @@ int compat_fclose(FILE *stream)
return fclose(stream);
}
void compat_binmode(int fd, int enable)
{
#if defined(HAVE__SETMODE)
_setmode(fd, enable ? _O_BINARY : _O_TEXT);
#elif defined(HAVE_SETMODE)
setmode(fd, enable ? O_BINARY : O_TEXT);
#endif
}
#ifndef WINDOWS_UWP
/*
@ -441,7 +450,13 @@ size_t unintr_write(int fd, void const *buffer, size_t bytes)
{
bytes -= part;
written += part;
} else if(errno != EINTR)
} else if(errno != EINTR && errno != EAGAIN
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
// Not all platforms define it (or only in more modern POSIX modes).
// Standard says it is supposed to be a macro, so simple check here.
&& errno != EWOULDBLOCK
#endif
)
break;
}
return written;
@ -456,11 +471,15 @@ size_t unintr_read(int fd, void *buffer, size_t bytes)
{
errno = 0;
ssize_t part = read(fd, (char*)buffer+got, bytes);
if(part >= 0)
if(part > 0) // == 0 is end of file
{
bytes -= part;
got += part;
} else if(errno != EINTR)
} else if(errno != EINTR && errno != EAGAIN
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
&& errno != EWOULDBLOCK
#endif
)
break;
}
return got;

View file

@ -67,6 +67,19 @@
#define ULONG_MAX ((unsigned long)-1)
#endif
#ifndef OFF_MAX
#if SIZEOF_OFF_T == 4
#define OFF_MAX ((uint32_t)-1/2)
#elif SIZEOF_OFF_T == 8
#define OFF_MAX ((uint64_t)-1/2)
#else
#error "Unexpected width of off_t."
#endif
#endif
// Add two values (themselves assumed to be < limit), saturating to given limit.
#define SATURATE_ADD(inout, add, limit) inout = (limit-add >= inout) ? inout+add : limit;
#ifdef HAVE_STRING_H
#include <string.h>
#endif
@ -74,7 +87,7 @@
#include <strings.h>
#endif
#ifdef OS2
#ifdef __OS2__
#include <float.h>
#endif
@ -182,9 +195,17 @@ FILE* compat_fdopen(int fd, const char *mode);
int compat_close(int infd);
int compat_fclose(FILE* stream);
/**
* Setting binary mode on a descriptor, where necessary.
* We do not bother with errors. This has to work.
* You can enable or disable binary mode.
*/
void compat_binmode(int fd, int enable);
/* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
#ifdef WANT_WIN32_UNICODE
#if defined (_WIN32) || defined (__CYGWIN__)
/**
* win32_uni2mbc
* Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
@ -198,6 +219,19 @@ int compat_fclose(FILE* stream);
*/
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
/**
* win32_uni2mbc
* Converts a null terminated UCS-2 string to a multibyte (UTF-7) equivalent.
* Caller is supposed to free allocated buffer.
* @param[in] wptr Pointer to wide string.
* @param[out] mbptr Pointer to multibyte string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
*/
int win32_wide_utf7(const wchar_t * const wptr, char **mbptr, size_t * buflen);
/**
* win32_mbc2uni
* Converts a null terminated UTF-8 string to a UCS-2 equivalent.
@ -281,11 +315,6 @@ size_t unintr_write(int fd, void const *buffer, size_t bytes);
size_t unintr_read (int fd, void *buffer, size_t bytes);
size_t unintr_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
/* That one comes from Tellie on OS/2, needed in resolver. */
#ifdef __KLIBC__
typedef int socklen_t;
#endif
/* OSX SDK defines an enum with "normal" as value. That clashes with
optimize.h */
#ifdef __APPLE__

View file

@ -14,7 +14,7 @@
/* Win32 is only supported with unicode now. These headers also cover
module stuff. The WANT_WIN32_UNICODE macro is synonymous with
"want windows-specific API, and only the unicode variants of which". */
#ifdef WANT_WIN32_UNICODE
#if defined (_WIN32) || defined (__CYGWIN__)
#include <wchar.h>
#include <windows.h>
#include <winnls.h>
@ -63,20 +63,21 @@ char* compat_strdup(const char *src)
}
/* Windows Unicode stuff */
#ifdef WANT_WIN32_UNICODE
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
/* Provided unconditionally, since WASAPI needs it to configure the audio device */
#if defined (_WIN32) || defined (__CYGWIN__)
static
int win32_wide_common(const wchar_t * const wptr, char **mbptr, size_t * buflen, UINT cp)
{
size_t len;
char *buf;
int ret = 0;
len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
len = WideCharToMultiByte(cp, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
if(!buf) len = 0;
else {
if (len != 0) ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
if (len != 0) ret = WideCharToMultiByte(cp, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
buf[len] = '0'; /* Must terminate */
}
*mbptr = buf; /* Set string pointer to allocated buffer */
@ -84,6 +85,16 @@ int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
return ret;
}
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
{
return win32_wide_common(wptr, mbptr, buflen, CP_UTF8);
}
int win32_wide_utf7(const wchar_t * const wptr, char **mbptr, size_t * buflen)
{
return win32_wide_common(wptr, mbptr, buflen, CP_UTF7);
}
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
{
size_t len;

View file

@ -17,6 +17,7 @@
#define compat_close INT123_compat_close
#define compat_fclose INT123_compat_fclose
#define win32_wide_utf8 INT123_win32_wide_utf8
#define win32_wide_utf7 INT123_win32_wide_utf7
#define win32_utf8_wide INT123_win32_utf8_wide
#define compat_catpath INT123_compat_catpath
#define compat_isdir INT123_compat_isdir

View file

@ -984,6 +984,12 @@ int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change)
return mpg123_volume(mh, change + (double) mh->p.outscale);
}
int attribute_align_arg mpg123_volume_change_db(mpg123_handle *mh, double change)
{
if(mh == NULL) return MPG123_ERR;
return mpg123_volume(mh, dbchange(mh->p.outscale, change));
}
int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol)
{
if(mh == NULL) return MPG123_ERR;

View file

@ -222,10 +222,9 @@ static mpg123_text *add_id3_text( mpg123_text **list, size_t *size
return NULL; // no lone language intended
if(id || description)
{
size_t i;
// Look through list of existing texts and return an existing entry
// if it should be overwritten.
for(i=0; i<*size; ++i)
for(size_t i=0; i<*size; ++i)
{
mpg123_text *entry = *list+i;
if(description)
@ -255,13 +254,11 @@ static mpg123_text *add_id3_text( mpg123_text **list, size_t *size
static mpg123_picture *add_id3_picture(mpg123_picture **list, size_t *size, char type, mpg123_string *description)
{
size_t i;
if(!description)
return NULL;
// Return entry to overwrite, if appropriate.
for(i=0; i<*size; ++i)
for(size_t i=0; i<*size; ++i)
{
mpg123_picture *entry = *list+i;
if( type == entry->type

View file

@ -454,8 +454,8 @@ int attribute_align_arg mpg123_getstate2(mpg123_handle *mh, int key, long *val,
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
{
#ifndef NO_EQUALIZER
if(mh == NULL) return MPG123_BAD_HANDLE;
#ifndef NO_EQUALIZER
if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
switch(channel)
{
@ -478,9 +478,42 @@ int attribute_align_arg mpg123_eq2(mpg123_handle *mh, int channel, int band, dou
return mpg123_eq(mh, channel, band, val);
}
int attribute_align_arg mpg123_eq_bands(mpg123_handle *mh, int channel, int a, int b, double factor)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
#ifndef NO_EQUALIZER
int ret;
// Always count up.
if(a>b){ int s=a; a=b; b=s; }
for(int n=a; n<=b; ++n)
if( (ret=mpg123_eq(mh, channel, n, factor)) != MPG123_OK )
return ret;
#endif
return MPG123_OK;
}
int attribute_align_arg mpg123_eq_change(mpg123_handle *mh, int channel, int a, int b, double db)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
#ifndef NO_EQUALIZER
// Always count up.
if(a>b){ int s=a; a=b; b=s; }
for(int band=a; band<=b; ++band)
{
if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
if(channel & MPG123_LEFT)
mh->equalizer[0][band] = DOUBLE_TO_REAL(dbchange(REAL_TO_DOUBLE(mh->equalizer[0][band]), db));
if(channel & MPG123_RIGHT)
mh->equalizer[1][band] = DOUBLE_TO_REAL(dbchange(REAL_TO_DOUBLE(mh->equalizer[1][band]), db));;
mh->have_eq_settings = TRUE;
}
#endif
return MPG123_OK;
}
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
{
double ret = 0.;
double ret = 1.;
#ifndef NO_EQUALIZER
/* Handle this gracefully. When there is no band, it has no volume. */

View file

@ -1,5 +1,5 @@
/*
libmpg123: MPEG Audio Decoder library (version 1.29.1)
libmpg123: MPEG Audio Decoder library (version 1.30.2)
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
@ -18,7 +18,7 @@
* to the header.
*/
#ifndef MPG123_API_VERSION
#define MPG123_API_VERSION 46
#define MPG123_API_VERSION 47
#endif
#ifndef MPG123_EXPORT
@ -1093,6 +1093,28 @@ MPG123_EXPORT int mpg123_eq( mpg123_handle *mh
MPG123_EXPORT int mpg123_eq2( mpg123_handle *mh
, int channel, int band, double val );
/** Set a range of equalizer bands
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both.
* \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 factor The (linear) adjustment factor, 1 being neutral.
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_eq_bands( mpg123_handle *mh
, int channel, int a, int b, double factor );
/** Change a range of equalizer bands
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both.
* \param a The first equalizer band to change (from 0 to 31)
* \param b The last equalizer band to change (from 0 to 31)
* \param db The adjustment in dB (limited to +/- 60 dB).
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_eq_change( mpg123_handle *mh
, int channel, int a, int b, double db );
#ifdef MPG123_ENUM_API
/** Get the 32 Band Audio Equalizer settings.
*
@ -1141,6 +1163,13 @@ MPG123_EXPORT int mpg123_volume(mpg123_handle *mh, double vol);
*/
MPG123_EXPORT int mpg123_volume_change(mpg123_handle *mh, double change);
/** Adjust output volume including the RVA setting by chosen amount
* \param mh handle
* \param change volume adjustment in decibels (limited to +/- 60 dB)
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_volume_change_db(mpg123_handle *mh, double db);
/** Return current volume setting, the actual value due to RVA, and the RVA
* adjustment itself. It's all as double float value to abstract the sample
* format. The volume values are linear factors / amplitudes (not percent)
@ -1741,7 +1770,7 @@ MPG123_EXPORT int mpg123_id3( mpg123_handle *mh
, mpg123_id3v1 **v1, mpg123_id3v2 **v2 );
/** Return pointers to and size of stored raw ID3 data if storage has
* been configured with MPG123_RAW_ID3 and stream parsing passed the
* been configured with MPG123_STORE_RAW_ID3 and stream parsing passed the
* metadata already. Null value with zero size is a possibility!
* The storage can change at any next API call.
*

View file

@ -339,4 +339,16 @@ int open_fixed_post(mpg123_handle *mh, int channels, int encoding);
#define TIMEOUT_READ
#endif
// Change a given linear factor by the given dB value, bounded
// to +/- 60 dB.
static inline double dbchange(double base_factor, double db)
{
double nscale = base_factor * pow(10, db/20);
if(nscale < 0.001) // -60 dB
nscale = 0.001;
if(nscale > 1000)
nscale = 1000; // +60 dB
return nscale;
}
#endif

View file

@ -129,7 +129,8 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
return READER_ERROR;
}
if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
if(!(fr->rdat.flags & READER_BUFFERED))
SATURATE_ADD(fr->rdat.filepos, ret, OFF_MAX);
cnt += ret;
fr->icy.next -= ret;
if(fr->icy.next > 0)
@ -147,7 +148,8 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
if(ret == 0) break;
debug2("got meta-size byte: %u, at filepos %li", temp_buff, (long)fr->rdat.filepos );
if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret; /* 1... */
if(!(fr->rdat.flags & READER_BUFFERED))
SATURATE_ADD(fr->rdat.filepos, ret, OFF_MAX); /* 1... */
if((meta_size = ((size_t) temp_buff) * 16))
{
@ -166,7 +168,8 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
left -= ret;
}
meta_buff[meta_size] = 0; /* string paranoia */
if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
if(!(fr->rdat.flags & READER_BUFFERED))
SATURATE_ADD(fr->rdat.filepos, ret, OFF_MAX);
if(fr->icy.data) free(fr->icy.data);
fr->icy.data = meta_buff;
@ -218,7 +221,8 @@ static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t coun
ret = fr->rdat.fdread(fr,buf+cnt,count-cnt);
if(ret < 0) return READER_ERROR;
if(ret == 0) break;
if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
if(!(fr->rdat.flags & READER_BUFFERED))
SATURATE_ADD(fr->rdat.filepos, ret, OFF_MAX);
cnt += ret;
}
return cnt;
@ -396,7 +400,10 @@ static off_t generic_tell(mpg123_handle *fr)
{
#ifndef NO_FEEDER
if(fr->rdat.flags & READER_BUFFERED)
fr->rdat.filepos = fr->rdat.buffer.fileoff+fr->rdat.buffer.pos;
{
fr->rdat.filepos = fr->rdat.buffer.fileoff;
SATURATE_ADD(fr->rdat.filepos, fr->rdat.buffer.pos, OFF_MAX);
}
#endif
return fr->rdat.filepos;
@ -458,6 +465,7 @@ static off_t get_fileinfo(mpg123_handle *fr)
debug("cannot seek back");
return -1;
}
fr->rdat.filepos = 0; // un-do our seeking here
debug1("returning length: %"OFF_P, (off_p)len);
return len;
@ -816,7 +824,8 @@ static int feed_seek_frame(mpg123_handle *fr, off_t num){ return READER_ERROR; }
static void buffered_forget(mpg123_handle *fr)
{
bc_forget(&fr->rdat.buffer);
fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
fr->rdat.filepos = fr->rdat.buffer.fileoff;
SATURATE_ADD(fr->rdat.filepos, fr->rdat.buffer.pos, OFF_MAX);
}
off_t feed_set_pos(mpg123_handle *fr, off_t pos)
@ -1064,8 +1073,8 @@ static int default_init(mpg123_handle *fr)
if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
#endif
fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
fr->rdat.filepos = 0;
fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
if(fr->p.flags & MPG123_FORCE_SEEKABLE)
fr->rdat.flags |= READER_SEEKABLE;
/*