[MPG123] Update to version 1.26.1. CORE-17098

This commit is contained in:
Thomas Faber 2020-05-30 21:43:44 +02:00
parent cab7e9ade8
commit aa811c00e3
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
27 changed files with 2163 additions and 710 deletions

View file

@ -64,7 +64,7 @@ Used Version: 0.1.9
Website: http://www.mega-nerd.com/SRC/download.html
Title: libmpg123 (used by winemp3.acm)
Used Version: 1.25.13
Used Version: 1.26.1
Website: http://www.mpg123.de/
Title: STLport

View file

@ -17,9 +17,8 @@
#include "config.h"
#include "intsym.h"
/* For --nagging compilation with -std=c89, we need
to disable the inline keyword. */
#ifdef PLAIN_C89
/* Disable inline for non-C99 compilers. */
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
#ifndef inline
#define inline
#endif
@ -66,6 +65,9 @@
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#ifndef SSIZE_MAX
#define SSIZE_MAX ((size_t)-1/2)
#endif
#ifndef ULONG_MAX
#define ULONG_MAX ((unsigned long)-1)
#endif
@ -122,7 +124,7 @@ char* compat_strdup(const char *s);
/* If we have the size checks enabled, try to derive some sane printfs.
Simple start: Use max integer type and format if long is not big enough.
I am hesitating to use %ll without making sure that it's there... */
#if !(defined PLAIN_C89) && (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
#if (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
# define OFF_P PRIiMAX
typedef intmax_t off_p;
#else
@ -130,7 +132,7 @@ typedef intmax_t off_p;
typedef long off_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
#if (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
# define SIZE_P PRIuMAX
typedef uintmax_t size_p;
#else
@ -138,7 +140,7 @@ typedef uintmax_t size_p;
typedef unsigned long size_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
#if (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
# define SSIZE_P PRIuMAX
typedef intmax_t ssize_p;
#else
@ -266,10 +268,11 @@ void compat_dlclose(void *handle);
#endif
/* Blocking write/read of data with signal resilience.
Both continue after being interrupted by signals and always return the
They continue after being interrupted by signals and always return the
amount of processed data (shortage indicating actual problem or EOF). */
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__

View file

@ -6,7 +6,7 @@
#define ABI_ALIGN_FUN 1
/* Define to use proper rounding. */
/* #undef ACCURATE_ROUNDING */
#define ACCURATE_ROUNDING 1
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
@ -77,6 +77,9 @@
/* Define to 1 if you have the <AudioUnit/AudioUnit.h> header file. */
/* #undef HAVE_AUDIOUNIT_AUDIOUNIT_H */
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the <CoreServices/CoreServices.h> header file. */
/* #undef HAVE_CORESERVICES_CORESERVICES_H */
@ -104,15 +107,15 @@
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the `getuid' function. */
/* #undef HAVE_GETUID */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `iswprint' function. */
#define HAVE_ISWPRINT 1
/* Define to 1 if you have the <langinfo.h> header file. */
/* #undef HAVE_LANGINFO_H */
@ -134,13 +137,16 @@
/* Define to 1 if you have the <machine/soundcard.h> header file. */
/* #undef HAVE_MACHINE_SOUNDCARD_H */
/* Define to 1 if you have the `mbstowcs' function. */
#define HAVE_MBSTOWCS 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkfifo' function. */
/* #undef HAVE_MKFIFO */
/* Define to 1 if you have a working `mmap' system call. */
/* Define to 1 if you have the `mmap' function. */
/* #undef HAVE_MMAP */
/* Define to 1 if you have the <netdb.h> header file. */
@ -185,6 +191,18 @@
/* Define to 1 if you have the `setuid' function. */
/* #undef HAVE_SETUID */
/* Define to 1 if you have the `shmat' function. */
/* #undef HAVE_SHMAT */
/* Define to 1 if you have the `shmctl' function. */
/* #undef HAVE_SHMCTL */
/* Define to 1 if you have the `shmdt' function. */
/* #undef HAVE_SHMDT */
/* Define to 1 if you have the `shmget' function. */
/* #undef HAVE_SHMGET */
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
@ -221,6 +239,9 @@
/* Define to 1 if you have the <sys/ioctl.h> header file. */
/* #undef HAVE_SYS_IOCTL_H */
/* Define to 1 if you have the <sys/ipc.h> header file. */
/* #undef HAVE_SYS_IPC_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
@ -230,6 +251,9 @@
/* Define to 1 if you have the <sys/select.h> header file. */
/* #undef HAVE_SYS_SELECT_H */
/* Define to 1 if you have the <sys/shm.h> header file. */
/* #undef HAVE_SYS_SHM_H */
/* Define to 1 if you have the <sys/signal.h> header file. */
/* #undef HAVE_SYS_SIGNAL_H */
@ -257,6 +281,18 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define to 1 if you have the `wcstombs' function. */
#define HAVE_WCSTOMBS 1
/* Define to 1 if you have the `wcswidth' function. */
/* #undef HAVE_WCSWIDTH */
/* Define to 1 if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1
@ -331,6 +367,9 @@
/* Define to disable layer III. */
/* #undef NO_LAYER3 */
/* Define to disable analyzer info. */
/* #undef NO_MOREINFO */
/* Define to disable ntom resampling. */
/* #undef NO_NTOM */
@ -356,7 +395,7 @@
#define PACKAGE_NAME "mpg123"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "mpg123 1.25.13"
#define PACKAGE_STRING "mpg123 1.26.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mpg123"
@ -365,7 +404,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.25.13"
#define PACKAGE_VERSION "1.26.1"
/* Define if portaudio v18 API is wanted. */
/* #undef PORTAUDIO18 */
@ -388,6 +427,9 @@
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to not duplicate some code for likely cases in libsyn123. */
/* #undef SYN123_NO_CASES */
/* Define if modules are enabled */
/* #undef USE_MODULES */
@ -398,7 +440,7 @@
/* #undef USE_YASM_FOR_AVX */
/* Version number of package */
#define VERSION "1.25.13"
#define VERSION "1.26.1"
/* Define to use Win32 named pipes */
#define WANT_WIN32_FIFO 1
@ -409,7 +451,7 @@
/* Define to use Unicode for Windows */
#define WANT_WIN32_UNICODE 1
/* WinXP and above for ipv6 */
/* Windows Vista and later APIs */
/* #undef WINVER */
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
@ -435,7 +477,7 @@
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* WinXP and above for ipv6 */
/* Windows Vista and later APIs */
/* #undef _WIN32_WINNT */
/* Define to empty if `const' does not conform to ANSI C. */

View file

@ -20,6 +20,8 @@
Variadic macros are a C99 feature...
Now just predefining stuff non-variadic for up to 15 arguments.
It's cumbersome to have them all with different names, though...
Update: Also adding variadic macros now. We star to use some C99.
*/
#ifdef ME
@ -31,6 +33,10 @@
#ifdef DEBUG
#include <stdio.h>
// The future (from about 20 years ago;-):
#define mdebug(s, ...) fprintf(stderr, DBGPRFX "[" __FILE__ ":%i] debug: " s "\n", __LINE__, __VA_ARGS__)
#define debug(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__)
#define debug1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a)
#define debug2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b)
@ -48,6 +54,9 @@
#define debug14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define debug15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define mdebug(s, ...)
#define debug(s)
#define debug1(s, a)
#define debug2(s, a, b)
@ -68,6 +77,9 @@
/* warning macros also here... */
#ifndef NO_WARNING
#define mwarning(s, ...) fprintf(stderr, DBGPRFX "[" __FILE__ ":%i] warning: " s "\n", __LINE__, __VA_ARGS__)
#define warning(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__)
#define warning1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a)
#define warning2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b)
@ -85,6 +97,7 @@
#define warning14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define warning15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define mwarning(s, ...)
#define warning(s)
#define warning1(s, a)
#define warning2(s, a, b)
@ -104,7 +117,10 @@
#endif
/* error macros also here... */
#ifndef NO_ERROR
#ifndef NO_ERRORMSG
#define merror(s, ...) fprintf(stderr, DBGPRFX "[" __FILE__ ":%i] error: " s "\n", __LINE__, __VA_ARGS__)
#define error(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__)
#define error1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
#define error2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)
@ -122,6 +138,7 @@
#define error14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define error15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define merror(s, ...)
#define error(s)
#define error1(s, a)
#define error2(s, a, b)
@ -142,6 +159,9 @@
/* ereturn macros also here... */
#ifndef NO_ERETURN
#define mereturn(rv, s, ...) do{ fprintf(stderr, DBGPRFX "[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, __VA_ARGS__); return rv; }while(0)
#define ereturn(rv, s) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__); return rv; }while(0)
#define ereturn1(rv, s, a) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a); return rv; }while(0)
#define ereturn2(rv, s, a, b) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b); return rv; }while(0)
@ -159,6 +179,7 @@
#define ereturn14(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n); return rv; }while(0)
#define ereturn15(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); return rv; }while(0)
#else
#define mereturn(rv, s, ...) return rv
#define ereturn(rv, s) return rv
#define ereturn1(rv, s, a) return rv
#define ereturn2(rv, s, a, b) return rv

View file

@ -4,7 +4,7 @@
separate header just for audio format definitions not tied to
library code
copyright 1995-2015 by the mpg123 project
copyright 1995-2020 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
@ -99,19 +99,43 @@ enum mpg123_enc_enum
* \return size of one sample in bytes
*/
#define MPG123_SAMPLESIZE(enc) ( \
(enc) & MPG123_ENC_8 \
? 1 \
: ( (enc) & MPG123_ENC_16 \
? 2 \
: ( (enc) & MPG123_ENC_24 \
? 3 \
: ( ( (enc) & MPG123_ENC_32 \
|| (enc) == MPG123_ENC_FLOAT_32 ) \
? 4 \
: ( (enc) == MPG123_ENC_FLOAT_64 \
? 8 \
: 0 \
) ) ) ) )
(enc) < 1 \
? 0 \
: ( (enc) & MPG123_ENC_8 \
? 1 \
: ( (enc) & MPG123_ENC_16 \
? 2 \
: ( (enc) & MPG123_ENC_24 \
? 3 \
: ( ( (enc) & MPG123_ENC_32 \
|| (enc) == MPG123_ENC_FLOAT_32 ) \
? 4 \
: ( (enc) == MPG123_ENC_FLOAT_64 \
? 8 \
: 0 \
) ) ) ) ) )
/** Representation of zero in differing encodings.
* This exists to define proper silence in various encodings without
* having to link to libsyn123 to do actual conversions at runtime.
* You have to handle big/little endian order yourself, though.
* This takes the shortcut that any signed encoding has a zero with
* all-zero bits. Unsigned linear encodings just have the highest bit set
* (2^(n-1) for n bits), while the nonlinear 8-bit ones are special.
* \param enc the encoding (mpg123_enc_enum value)
* \param siz bytes per sample (return value of MPG123_SAMPLESIZE(enc))
* \param off byte (octet) offset counted from LSB
* \return unsigned byte value for the designated octet
*/
#define MPG123_ZEROSAMPLE(enc, siz, off) ( \
(enc) == MPG123_ENC_ULAW_8 \
? (off == 0 ? 0xff : 0x00) \
: ( (enc) == MPG123_ENC_ALAW_8 \
? (off == 0 ? 0xd5 : 0x00) \
: ( (((enc) & (MPG123_ENC_SIGNED|MPG123_ENC_FLOAT)) || (siz) != ((off)+1)) \
? 0x00 \
: 0x80 \
) ) )
/** Structure defining an audio format.
* Providing the members as individual function arguments to define a certain

View file

@ -84,6 +84,7 @@ struct mpg123_pars_struct
long feedpool;
long feedbuffer;
#endif
long freeformat_framesize;
};
enum frame_state_flags
@ -224,6 +225,7 @@ struct mpg123_handle_struct
/* bitstream info; bsi */
int bitindex;
long bits_avail;
unsigned char *wordpointer;
/* temporary storage for getbits stuff */
unsigned long ultmp;
@ -248,7 +250,7 @@ struct mpg123_handle_struct
int fsizeold;
int ssize;
unsigned int bitreservoir;
unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
unsigned char bsspace[2][MAXFRAMESIZE+512+4]; /* MAXFRAMESIZE */
unsigned char *bsbuf;
unsigned char *bsbufold;
int bsnum;
@ -295,6 +297,8 @@ struct mpg123_handle_struct
#ifndef NO_ID3V2
mpg123_id3v2 id3v2;
#endif
unsigned char *id3v2_raw;
size_t id3v2_size;
#ifndef NO_ICY
struct icy_meta icy;
#endif
@ -333,6 +337,11 @@ struct mpg123_handle_struct
void *wrapperdata;
/* A callback used to properly destruct the wrapper data. */
void (*wrapperclean)(void*);
int enc_delay;
int enc_padding;
#ifndef NO_MOREINFO
struct mpg123_moreinfo *pinfo;
#endif
};
/* generic init, does not include dynamic buffers */
@ -376,9 +385,10 @@ MPEG 2.5
576
*/
#ifdef GAPLESS
/* well, I take that one for granted... at least layer3 */
// Well, I take that one for granted... at least layer3.
// The value is needed for mpg123_getstate() in any build.
#define GAPLESS_DELAY 529
#ifdef GAPLESS
void frame_gapless_init(mpg123_handle *fr, off_t framecount, off_t bskip, off_t eskip);
void frame_gapless_realinit(mpg123_handle *fr);
void frame_gapless_update(mpg123_handle *mh, off_t total_samples);

View file

@ -13,29 +13,21 @@
#define _MPG123_GETBITS_H_
#include "mpg123lib_intern.h"
#include "debug.h"
#define backbits(fr,nob) ((void)( \
fr->bits_avail += nob, \
fr->bitindex -= nob, \
fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 0x7 ))
#define getbitoffset(fr) ((-fr->bitindex)&0x7)
#define getbyte(fr) (*fr->wordpointer++)
/* There is something wrong with that macro... the function below works also for the layer1 test case. */
#define macro_getbits(fr, nob) ( \
fr->ultmp = fr->wordpointer[0],\
fr->ultmp <<= 8, \
fr->ultmp |= fr->wordpointer[1], \
fr->ultmp <<= 8, \
fr->ultmp |= fr->wordpointer[2], \
fr->ultmp <<= fr->bitindex, \
fr->ultmp &= 0xffffff, \
fr->bitindex += nob, \
fr->ultmp >>= (24-nob), \
fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7, \
fr->ultmp)
/* Precomputing the bytes to be read is error-prone, and some over-read
is even expected for Huffman. Just play safe and return zeros in case
of overflow. This assumes you made bitindex zero already! */
#define getbyte(fr) ( (fr)->bits_avail-=8, (fr)->bits_avail >= 0 \
? *((fr)->wordpointer++) \
: 0 )
static unsigned int getbits(mpg123_handle *fr, int number_of_bits)
{
@ -44,11 +36,16 @@ static unsigned int getbits(mpg123_handle *fr, int number_of_bits)
#ifdef DEBUG_GETBITS
fprintf(stderr,"g%d",number_of_bits);
#endif
fr->bits_avail -= number_of_bits;
/* Safety catch until we got the nasty code fully figured out. */
/* No, that catch stays here, even if we think we got it figured out! */
if( (long)(fr->wordpointer-fr->bsbuf)*8
+ fr->bitindex+number_of_bits > (long)fr->framesize*8 )
if(fr->bits_avail < 0)
{
if(NOQUIET)
error2( "Tried to read %i bits with %li available."
, number_of_bits, fr->bits_avail );
return 0;
}
/* This is actually slow: if(!number_of_bits)
return 0; */
@ -85,7 +82,7 @@ fprintf(stderr,":%lx\n",rval);
#define skipbits(fr, nob) fr->ultmp = ( \
fr->ultmp = fr->wordpointer[0], fr->ultmp <<= 8, fr->ultmp |= fr->wordpointer[1], \
fr->ultmp <<= 8, fr->ultmp |= fr->wordpointer[2], fr->ultmp <<= fr->bitindex, \
fr->ultmp &= 0xffffff, fr->bitindex += nob, \
fr->ultmp &= 0xffffff, fr->bitindex += nob, fr->bits_avail -= nob, \
fr->ultmp >>= (24-nob), fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7 )
@ -93,11 +90,13 @@ fprintf(stderr,":%lx\n",rval);
fr->ultmp = (unsigned char) (fr->wordpointer[0] << fr->bitindex), \
fr->ultmp |= ((unsigned long) fr->wordpointer[1]<<fr->bitindex)>>8, \
fr->ultmp <<= nob, fr->ultmp >>= 8, \
fr->bitindex += nob, fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex += nob, fr->bits_avail -= nob, \
fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7, fr->ultmp )
#define get1bit(fr) ( \
fr->uctmp = *fr->wordpointer << fr->bitindex, fr->bitindex++, \
fr->uctmp = *fr->wordpointer << fr->bitindex, \
++fr->bitindex, --fr->bits_avail, \
fr->wordpointer += (fr->bitindex>>3), fr->bitindex &= 7, fr->uctmp>>7 )

View file

@ -9,6 +9,7 @@
#define catchsignal INT123_catchsignal
#define safe_realloc INT123_safe_realloc
#define compat_strdup INT123_compat_strdup
#define compat_getenv INT123_compat_getenv
#define compat_open INT123_compat_open
#define compat_fopen INT123_compat_fopen
#define compat_fdopen INT123_compat_fdopen
@ -16,8 +17,18 @@
#define compat_fclose INT123_compat_fclose
#define win32_wide_utf8 INT123_win32_wide_utf8
#define win32_utf8_wide INT123_win32_utf8_wide
#define compat_catpath INT123_compat_catpath
#define compat_isdir INT123_compat_isdir
#define compat_diropen INT123_compat_diropen
#define compat_dirclose INT123_compat_dirclose
#define compat_nextfile INT123_compat_nextfile
#define compat_nextdir INT123_compat_nextdir
#define compat_dlopen INT123_compat_dlopen
#define compat_dlsym INT123_compat_dlsym
#define compat_dlclose INT123_compat_dlclose
#define unintr_write INT123_unintr_write
#define unintr_read INT123_unintr_read
#define unintr_fwrite INT123_unintr_fwrite
#define ntom_set_ntom INT123_ntom_set_ntom
#define synth_1to1 INT123_synth_1to1
#define synth_1to1_dither INT123_synth_1to1_dither
@ -192,7 +203,6 @@
#define frame_set_seek INT123_frame_set_seek
#define frame_tell_seek INT123_frame_tell_seek
#define frame_fill_toc INT123_frame_fill_toc
#define getbits INT123_getbits
#define getcpuflags INT123_getcpuflags
#define icy2utf8 INT123_icy2utf8
#define init_icy INT123_init_icy
@ -210,14 +220,14 @@
#define fi_add INT123_fi_add
#define fi_set INT123_fi_set
#define fi_reset INT123_fi_reset
#define double_to_long_rounded INT123_double_to_long_rounded
#define scale_rounded INT123_scale_rounded
#define decode_update INT123_decode_update
#define decoder_synth_bytes INT123_decoder_synth_bytes
#define samples_to_bytes INT123_samples_to_bytes
#define bytes_to_samples INT123_bytes_to_samples
#define outblock_bytes INT123_outblock_bytes
#define postprocess_buffer INT123_postprocess_buffer
#define open_fixed_pre INT123_open_fixed_pre
#define open_fixed_post INT123_open_fixed_post
#define frame_cpu_opt INT123_frame_cpu_opt
#define set_synth_functions INT123_set_synth_functions
#define dectype INT123_dectype

View file

@ -1,5 +1,5 @@
/*
libmpg123: MPEG Audio Decoder library (version 1.25.13)
libmpg123: MPEG Audio Decoder library (version 1.26.1)
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
@ -17,7 +17,7 @@
* This should be incremented at least each time a new symbol is added
* to the header.
*/
#define MPG123_API_VERSION 44
#define MPG123_API_VERSION 45
#ifndef MPG123_EXPORT
/** Defines needed for MS Visual Studio(tm) DLL builds.
@ -91,6 +91,7 @@ typedef long ssize_t;
#endif
#define MPG123_LARGENAME(func) MPG123_MACROCAT(func, MPG123_LARGESUFFIX)
#define mpg123_open_fixed MPG123_LARGENAME(mpg123_open_fixed)
#define mpg123_open MPG123_LARGENAME(mpg123_open)
#define mpg123_open_fd MPG123_LARGENAME(mpg123_open_fd)
#define mpg123_open_handle MPG123_LARGENAME(mpg123_open_handle)
@ -139,14 +140,19 @@ struct mpg123_handle_struct;
typedef struct mpg123_handle_struct mpg123_handle;
/** Function to initialise the mpg123 library.
* This function is not thread-safe. Call it exactly once per process, before any other (possibly threaded) work with the library.
* This should be called once in a non-parallel context. It is not explicitly
* thread-safe, but repeated/concurrent calls still _should_ be safe as static
* tables are filled with the same values anyway.
*
* \return MPG123_OK if successful, otherwise an error number.
*/
MPG123_EXPORT int mpg123_init(void);
/** Function to close down the mpg123 library.
* This function is not thread-safe. Call it exactly once per process, before any other (possibly threaded) work with the library. */
/** Superfluous Function to close down the mpg123 library.
* This was created with the thought that there sometime will be cleanup code
* to be run after library use. This never materialized. You can forget about
* this function and it is only here for old programs that do call it.
*/
MPG123_EXPORT void mpg123_exit(void);
/** Create a handle with optional choice of decoder (named by a string, see mpg123_decoders() or mpg123_supported_decoders()).
@ -164,6 +170,13 @@ MPG123_EXPORT mpg123_handle *mpg123_new(const char* decoder, int *error);
*/
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh);
/** Free plain memory allocated within libmpg123.
* This is for library users that are not sure to use the same underlying
* memory allocator as libmpg123. It is just a wrapper over free() in
* the underlying C library.
*/
MPG123_EXPORT void mpg123_free(void *ptr);
/** Enumeration of the parameters types that it is possible to set/get. */
enum mpg123_parms
{
@ -177,7 +190,8 @@ enum mpg123_parms
MPG123_UPSPEED, /**< play every Nth frame (integer) */
MPG123_START_FRAME, /**< start with this frame (skip frames before that, integer) */
MPG123_DECODE_FRAMES, /**< decode only this number of frames (integer) */
MPG123_ICY_INTERVAL, /**< stream contains ICY metadata with this interval (integer) */
MPG123_ICY_INTERVAL, /**< Stream contains ICY metadata with this interval (integer).
Make sure to set this _before_ opening a stream.*/
MPG123_OUTSCALE, /**< the scale for output samples (amplitude - integer or float according to mpg123 output format, normally integer) */
MPG123_TIMEOUT, /**< timeout for reading from a stream (not supported on win32, integer) */
MPG123_REMOVE_FLAGS, /**< remove some flags (inverse of MPG123_ADD_FLAGS, integer) */
@ -186,6 +200,11 @@ enum mpg123_parms
,MPG123_PREFRAMES /**< Decode/ignore that many frames in advance for layer 3. This is needed to fill bit reservoir after seeking, for example (but also at least one frame in advance is needed to have all "normal" data for layer 3). Give a positive integer value, please.*/
,MPG123_FEEDPOOL /**< For feeder mode, keep that many buffers in a pool to avoid frequent malloc/free. The pool is allocated on mpg123_open_feed(). If you change this parameter afterwards, you can trigger growth and shrinkage during decoding. The default value could change any time. If you care about this, then set it. (integer) */
,MPG123_FEEDBUFFER /**< Minimal size of one internal feeder buffer, again, the default value is subject to change. (integer) */
,MPG123_FREEFORMAT_SIZE /**< Tell the parser a free-format frame size to
* avoid read-ahead to get it. A value of -1 (default) means that the parser
* will determine it. The parameter value is applied during decoder setup
* for a freshly opened stream only.
*/
};
/** Flag bits for MPG123_FLAGS, use the usual binary or to combine. */
@ -216,6 +235,37 @@ enum mpg123_param_flags
* the stream is assumed as non-seekable unless overridden.
*/
,MPG123_FORCE_SEEKABLE = 0x40000 /**< 19th bit: Force the stream to be seekable. */
,MPG123_STORE_RAW_ID3 = 0x80000 /**< store raw ID3 data (even if skipping) */
,MPG123_FORCE_ENDIAN = 0x100000 /**< Enforce endianess of output samples.
* This is not reflected in the format codes. If this flag is set along with
* MPG123_BIG_ENDIAN, MPG123_ENC_SIGNED16 means s16be, without
* MPG123_BIG_ENDIAN, it means s16le. Normal operation without
* MPG123_FORCE_ENDIAN produces output in native byte order.
*/
,MPG123_BIG_ENDIAN = 0x200000 /**< Choose big endian instead of little. */
,MPG123_NO_READAHEAD = 0x400000 /**< Disable read-ahead in parser. If
* you know you provide full frames to the feeder API, this enables
* decoder output from the first one on, instead of having to wait for
* the next frame to confirm that the stream is healthy. It also disables
* free format support unless you provide a frame size using
* MPG123_FREEFORMAT_SIZE.
*/
,MPG123_FLOAT_FALLBACK = 0x800000 /**< Consider floating point output encoding only after
* trying other (possibly downsampled) rates and encodings first. This is to
* support efficient playback where floating point output is only configured for
* an external resampler, bypassing that resampler when the desired rate can
* be produced directly. This is enabled by default to be closer to older versions
* of libmpg123 which did not enable float automatically at all. If disabled,
* float is considered after the 16 bit default and higher-bit integer encodings
* for any rate. */
,MPG123_NO_FRANKENSTEIN = 0x1000000 /**< Disable support for Frankenstein streams
* (different MPEG streams stiched together). Do not accept serious change of MPEG
* header inside a single stream. With this flag, the audio output format cannot
* change during decoding unless you open a new stream. This also stops decoding
* after an announced end of stream (Info header contained a number of frames
* and this number has been reached). This makes your MP3 files behave more like
* ordinary media files with defined structure, rather than stream dumps with
* some sugar. */
};
/** choices for MPG123_RVA */
@ -267,6 +317,9 @@ enum mpg123_feature_set
,MPG123_FEATURE_PARSE_ICY /**< ICY support */
,MPG123_FEATURE_TIMEOUT_READ /**< Reader with timeout (network). */
,MPG123_FEATURE_EQUALIZER /**< tunable equalizer */
,MPG123_FEATURE_MOREINFO /**< more info extraction (for frame analyzer) */
,MPG123_FEATURE_OUTPUT_FLOAT32 /**< 32 bit float output */
,MPG123_FEATURE_OUTPUT_FLOAT64 /**< 64 bit float output (usually never) */
};
/** Query libmpg123 features.
@ -275,6 +328,17 @@ enum mpg123_feature_set
*/
MPG123_EXPORT int mpg123_feature(const enum mpg123_feature_set key);
/** Query libmpg123 features with better ABI compatibility
*
* This is the same as mpg123_feature(), but this time not using
* the enum as argument. Compilers don't have to agree on the size of
* enums and hence they are not safe in public API.
*
* \param key feature selection
* \return 1 for success, 0 for unimplemented functions
*/
MPG123_EXPORT int mpg123_feature2(int key);
/* @} */
@ -429,7 +493,12 @@ MPG123_EXPORT const char* mpg123_current_decoder(mpg123_handle *mh);
*
* Functions to get and select the format of the decoded audio.
*
* Before you dive in, please be warned that you might get confused by this. This seems to happen a lot, therefore I am trying to explain in advance.
* Before you dive in, please be warned that you might get confused by this.
* This seems to happen a lot, therefore I am trying to explain in advance.
* If you do feel confused and just want to decode your normal MPEG audio files that
* don't alter properties in the middle, just use mpg123_open_fixed() with a fixed encoding
* and channel count and forget about a matrix of audio formats. If you want to get funky,
* read ahead ...
*
* The mpg123 library decides what output format to use when encountering the first frame in a stream, or actually any frame that is still valid but differs from the frames before in the prompted output format. At such a deciding point, an internal table of allowed encodings, sampling rates and channel setups is consulted. According to this table, an output format is chosen and the decoding engine set up accordingly (including optimized routines for different output formats). This might seem unusual but it just follows from the non-existence of "MPEG audio files" with defined overall properties. There are streams, streams are concatenations of (semi) independent frames. We store streams on disk and call them "MPEG audio files", but that does not change their nature as the decoder is concerned (the LAME/Xing header for gapless decoding makes things interesting again).
*
@ -451,7 +520,9 @@ enum mpg123_channelcount
/** An array of supported standard sample rates
* These are possible native sample rates of MPEG audio files.
* You can still force mpg123 to resample to a different one, but by default you will only get audio in one of these samplings.
* You can still force mpg123 to resample to a different one, but by
* default you will only get audio in one of these samplings.
* This list is in ascending order.
* \param list Store a pointer to the sample rates array there.
* \param number Store the number of sample rates there. */
MPG123_EXPORT void mpg123_rates(const long **list, size_t *number);
@ -490,6 +561,19 @@ MPG123_EXPORT int mpg123_format_all(mpg123_handle *mh);
MPG123_EXPORT int mpg123_format( mpg123_handle *mh
, long rate, int channels, int encodings );
/** Set the audio format support of a mpg123_handle in detail:
* \param mh handle
* \param rate The sample rate value (in Hertz). Special value 0 means
* all rates (the reason for this variant of mpg123_format()).
* \param channels A combination of MPG123_STEREO and MPG123_MONO.
* \param encodings A combination of accepted encodings for rate and channels,
* p.ex MPG123_ENC_SIGNED16 | MPG123_ENC_ULAW_8 (or 0 for no support).
* Please note that some encodings may not be supported in the library build
* and thus will be ignored here.
* \return MPG123_OK on success, MPG123_ERR if there was an error. */
MPG123_EXPORT int mpg123_format2( mpg123_handle *mh
, long rate, int channels, int encodings );
/** Check to see if a specific format at a specific rate is supported
* by mpg123_handle.
* \param mh handle
@ -538,8 +622,51 @@ MPG123_EXPORT int mpg123_getformat2( mpg123_handle *mh
* @{
*/
/* reading samples / triggering decoding, possible return values: */
/** Enumeration of the error codes returned by libmpg123 functions. */
/** Open a simple MPEG file with fixed properties.
*
* This function shall simplify the common use case of a plain MPEG
* file on disk that you want to decode, with one fixed sample
* rate and channel count, and usually a length defined by a Lame/Info/Xing
* tag. It will:
*
* - set the MPG123_NO_FRANKENSTEIN flag
* - set up format support according to given parameters,
* - open the file,
* - query audio format,
* - fix the audio format support table to ensure the format stays the same,
* - call mpg123_scan() if there is no header frame to tell the track length.
*
* From that on, you can call mpg123_getformat() for querying the sample
* rate (and channel count in case you allowed both) and mpg123_length()
* to get a pretty safe number for the duration.
* Only the sample rate is left open as that indeed is a fixed property of
* MPEG files. You could set MPG123_FORCE_RATE beforehand, but that may trigger
* low-quality resampling in the decoder, only do so if in dire need.
* The library will convert mono files to stereo for you, and vice versa.
* If any constraint cannot be satisified (most likely because of a non-default
* build of libmpg123), you get MPG123_ERR returned and can query the detailed
* cause from the handle. Only on MPG123_OK there will an open file that you
* then close using mpg123_close(), or implicitly on mpg123_delete() or the next
* call to open another file.
*
* So, for your usual CD rip collection, you could use
*
* mpg123_open_fixed(mh, path, MPG123_STEREO, MPG123_ENC_SIGNED_16)
*
* and be happy calling mpg123_getformat() to verify 44100 Hz rate, then just
* playing away with mpg123_read(). The occasional mono file, or MP2 file,
* will also be decoded without you really noticing. Just the speed could be
* wrong if you do not care about sample rate at all.
* \param mh handle
* \param path filesystem path
* \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_fixed(mpg123_handle *mh, const char *path
, int channels, int encoding);
/** Open and prepare to decode the specified file by filesystem path.
* This does not open HTTP urls; libmpg123 contains no networking code.
@ -569,6 +696,8 @@ MPG123_EXPORT int mpg123_open_handle(mpg123_handle *mh, void *iohandle);
/** 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.
* Also, you are expected to handle ICY metadata extraction yourself. This
* input method does not handle MPG123_ICY_INTERVAL. It does parse ID3 frames, though.
* \param mh handle
* \return MPG123_OK on success
*/
@ -581,6 +710,10 @@ MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh);
MPG123_EXPORT int mpg123_close(mpg123_handle *mh);
/** Read from stream and decode up to outmemsize bytes.
*
* Note: The type of outmemory changed to a void pointer in mpg123 1.26.0
* (API version 45).
*
* \param mh handle
* \param outmemory address of output buffer to write to
* \param outmemsize maximum number of bytes to write
@ -588,7 +721,7 @@ MPG123_EXPORT int mpg123_close(mpg123_handle *mh);
* \return MPG123_OK or error/message code
*/
MPG123_EXPORT int mpg123_read(mpg123_handle *mh
, unsigned char *outmemory, size_t outmemsize, size_t *done );
, void *outmemory, size_t outmemsize, size_t *done );
/** Feed data for a stream that has been opened with mpg123_open_feed().
* It's give and take: You provide the bytestream, mpg123 gives you the decoded samples.
@ -607,6 +740,10 @@ MPG123_EXPORT int mpg123_feed( mpg123_handle *mh
* without taking decoded data.
* Think of this function being the union of mpg123_read() and mpg123_feed() (which it actually is, sort of;-).
* You can actually always decide if you want those specialized functions in separate steps or one call this one here.
*
* Note: The type of outmemory changed to a void pointer in mpg123 1.26.0
* (API version 45).
*
* \param mh handle
* \param inmemory input buffer
* \param inmemsize number of input bytes
@ -617,7 +754,7 @@ MPG123_EXPORT int mpg123_feed( mpg123_handle *mh
*/
MPG123_EXPORT int mpg123_decode( mpg123_handle *mh
, const unsigned char *inmemory, size_t inmemsize
, unsigned char *outmemory, size_t outmemsize, size_t *done );
, void *outmemory, size_t outmemsize, size_t *done );
/** Decode next MPEG frame to internal buffer
* or read a frame and return after setting a new format.
@ -913,6 +1050,30 @@ struct mpg123_frameinfo
enum mpg123_vbr vbr; /**< The VBR mode. */
};
/** Data structure for even more detailed information out of the decoder,
* for MPEG layer III only.
* This was added to support the frame analyzer by the Lame project and
* just follows what was used there before. You know what the fields mean
* if you want use this structure. */
struct mpg123_moreinfo
{
double xr[2][2][576];
double sfb[2][2][22]; /* [2][2][SBMAX_l] */
double sfb_s[2][2][3*13]; /* [2][2][3*SBMAX_s] */
int qss[2][2];
int big_values[2][2];
int sub_gain[2][2][3];
int scalefac_scale[2][2];
int preflag[2][2];
int blocktype[2][2];
int mixed[2][2];
int mainbits[2][2];
int sfbits[2][2];
int scfsi[2];
int maindata;
int padding;
};
/** Get frame information about the MPEG audio bitstream and store it in a mpg123_frameinfo structure.
* \param mh handle
* \param mi address of existing frameinfo structure to write to
@ -920,6 +1081,15 @@ struct mpg123_frameinfo
*/
MPG123_EXPORT int mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi);
/** Trigger collection of additional decoder information while decoding.
* \param mh handle
* \param mi pointer to data storage (NULL to disable collection)
* \return MPG123_OK if the collection was enabled/disabled as desired, MPG123_ERR
* otherwise (e.g. if the feature is disabled)
*/
MPG123_EXPORT int mpg123_set_moreinfo( mpg123_handle *mh
, struct mpg123_moreinfo *mi );
/** Get the safe output buffer size for all cases
* (when you want to replace the internal buffer)
* \return safe buffer size
@ -935,13 +1105,22 @@ MPG123_EXPORT size_t mpg123_safe_buffer(void);
*/
MPG123_EXPORT int mpg123_scan(mpg123_handle *mh);
/** Return, if possible, the full (expected) length of current track in frames.
/** Return, if possible, the full (expected) length of current track in
* MPEG frames.
* \param mh handle
* \return length >= 0 or MPG123_ERR if there is no length guess possible.
*/
MPG123_EXPORT off_t mpg123_framelength(mpg123_handle *mh);
/** Return, if possible, the full (expected) length of current track in samples.
/** Return, if possible, the full (expected) length of current
* track in samples (PCM frames).
*
* This relies either on an Info frame at the beginning or a previous
* call to mpg123_scan() to get the real number of MPEG frames in a
* file. It will guess based on file size if neither Info frame nor
* scan data are present. In any case, there is no guarantee that the
* decoder will not give you more data, for example in case the open
* file gets appended to during decoding.
* \param mh handle
* \return length >= 0 or MPG123_ERR if there is no length guess possible.
*/
@ -981,6 +1160,9 @@ enum mpg123_state
,MPG123_BUFFERFILL /**< Get fill of internal (feed) input buffer as integer byte count returned as long and as double. An error is returned on integer overflow while converting to (signed) long, but the returned floating point value shold still be fine. */
,MPG123_FRANKENSTEIN /**< Stream consists of carelessly stitched together files. Seeking may yield unexpected results (also with MPG123_ACCURATE, it may be confused). */
,MPG123_FRESH_DECODER /**< Decoder structure has been updated, possibly indicating changed stream (integer value, 0 if false, 1 if true). Flag is cleared after retrieval. */
,MPG123_ENC_DELAY /** Encoder delay read from Info tag (layer III, -1 if unknown). */
,MPG123_ENC_PADDING /** Encoder padding read from Info tag (layer III, -1 if unknown). */
,MPG123_DEC_DELAY /** Decoder delay (for layer III only, -1 otherwise). */
};
/** Get various current decoder/stream state information.
@ -1013,12 +1195,26 @@ typedef struct
size_t fill; /**< number of used bytes (including closing zero byte) */
} mpg123_string;
/** Create and allocate memory for a new mpg123_string
/** Allocate and intialize a new string.
* \param val optional initial string value (can be NULL)
*/
MPG123_EXPORT mpg123_string* mpg123_new_string(const char* val);
/** Free memory of contents and the string structure itself.
* \param sb string handle
*/
MPG123_EXPORT void mpg123_delete_string(mpg123_string* sb);
/** Initialize an existing mpg123_string structure to {NULL, 0, 0}.
* If you hand in a NULL pointer here, your program should crash. The other
* string functions are more forgiving, but this one here is too basic.
* \param sb string handle (address of existing structure on your side)
*/
MPG123_EXPORT void mpg123_init_string(mpg123_string* sb);
/** Free-up mempory for an existing mpg123_string
/** Free-up memory of the contents of an mpg123_string (not the struct itself).
* This also calls mpg123_init_string() and hence is safe to be called
* repeatedly.
* \param sb string handle
*/
MPG123_EXPORT void mpg123_free_string(mpg123_string* sb);
@ -1049,6 +1245,20 @@ MPG123_EXPORT int mpg123_grow_string(mpg123_string* sb, size_t news);
*/
MPG123_EXPORT int mpg123_copy_string(mpg123_string* from, mpg123_string* to);
/** Move the contents of one mpg123_string string to another.
* This frees any memory associated with the target and moves over the
* pointers from the source, leaving the source without content after
* that. The only possible error is that you hand in NULL pointers.
* If you handed in a valid source, its contents will be gone, even if
* there was no target to move to. If you hand in a valid target, its
* original contents will also always be gone, to be replaced with the
* source's contents if there was some.
* \param from source string handle
* \param to target string handle
* \return 0 on error, 1 on success
*/
MPG123_EXPORT int mpg123_move_string(mpg123_string* from, mpg123_string* to);
/** Append a C-String to an mpg123_string
* \param sb string handle
* \param stuff to append
@ -1083,8 +1293,10 @@ MPG123_EXPORT int mpg123_set_string(mpg123_string* sb, const char* stuff);
MPG123_EXPORT int mpg123_set_substring( mpg123_string *sb
, const char *stuff, size_t from, size_t count );
/** Count characters in a mpg123 string (non-null bytes or UTF-8 characters).
* Even with the fill property, the character count is not obvious as there could be multiple trailing null bytes.
/** Count characters in a mpg123 string (non-null bytes or Unicode points).
* This function is of limited use, as it does just count code points
* encoded in an UTF-8 string, only loosely related to the count of visible
* characters. Get your full Unicode handling support elsewhere.
* \param sb string handle
* \param utf8 a flag to tell if the string is in utf8 encoding
* \return character count
@ -1097,6 +1309,15 @@ MPG123_EXPORT size_t mpg123_strlen(mpg123_string *sb, int utf8);
*/
MPG123_EXPORT int mpg123_chomp_string(mpg123_string *sb);
/** Determine if two strings contain the same data.
* This only returns 1 if both given handles are non-NULL and
* if they are filled with the same bytes.
* \param a first string handle
* \param b second string handle
* \return 0 for different strings, 1 for identical
*/
MPG123_EXPORT int mpg123_same_string(mpg123_string *a, mpg123_string *b);
/** The mpg123 text encodings. This contains encodings we encounter in ID3 tags or ICY meta info. */
enum mpg123_text_encoding
{
@ -1147,8 +1368,10 @@ MPG123_EXPORT int mpg123_store_utf8(mpg123_string *sb, enum mpg123_text_encoding
/** Sub data structure for ID3v2, for storing various text fields (including comments).
* This is for ID3v2 COMM, TXXX and all the other text fields.
* Only COMM and TXXX have a description, only COMM and USLT have a language.
* You should consult the ID3v2 specification for the use of the various text fields ("frames" in ID3v2 documentation, I use "fields" here to separate from MPEG frames). */
* Only COMM, TXXX and USLT may have a description, only COMM and USLT
* have a language.
* You should consult the ID3v2 specification for the use of the various text fields
* ("frames" in ID3v2 documentation, I use "fields" here to separate from MPEG frames). */
typedef struct
{
char lang[3]; /**< Three-letter language code (not terminated). */
@ -1218,7 +1441,8 @@ typedef struct
size_t texts; /**< Numer of text fields. */
mpg123_text *extra; /**< The array of extra (TXXX) fields. */
size_t extras; /**< Number of extra text (TXXX) fields. */
mpg123_picture *picture; /**< Array of ID3v2 pictures fields (APIC). */
mpg123_picture *picture; /**< Array of ID3v2 pictures fields (APIC).
Only populated if MPG123_PICTURE flag is set! */
size_t pictures; /**< Number of picture (APIC) fields. */
} mpg123_id3v2;
@ -1260,6 +1484,21 @@ MPG123_EXPORT void mpg123_meta_free(mpg123_handle *mh);
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
* metadata already. Null value with zero size is a possibility!
* The storage can change at any next API call.
* \param v1 address to store pointer to v1 tag
* \param v1_size size of v1 data in bytes
* \param v2 address to store pointer to v2 tag
* \param v2_size size of v2 data in bytes
* \return MPG123_OK or MPG123_ERR. Only on MPG123_OK the output
* values are set.
*/
MPG123_EXPORT int mpg123_id3_raw( mpg123_handle *mh
, unsigned char **v1, size_t *v1_size
, unsigned char **v2, size_t *v2_size );
/** Point icy_meta to existing data structure wich may change on any next read/decode function call.
* \param mh handle
* \param icy_meta return address for ICY meta string (set to NULL if nothing there)
@ -1344,6 +1583,19 @@ MPG123_EXPORT int mpg123_fmt_all(mpg123_pars *mp);
MPG123_EXPORT int mpg123_fmt(mpg123_pars *mp
, long rate, int channels, int encodings);
/** Set the audio format support of a mpg123_pars in detail:
* \param mp parameter handle
* \param rate The sample rate value (in Hertz). Special value 0 means
* all rates (reason for this variant of mpg123_fmt).
* \param channels A combination of MPG123_STEREO and MPG123_MONO.
* \param encodings A combination of accepted encodings for rate and channels,
* p.ex MPG123_ENC_SIGNED16|MPG123_ENC_ULAW_8 (or 0 for no
* support).
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_fmt2(mpg123_pars *mp
, long rate, int channels, int encodings);
/** Check to see if a specific format at a specific rate is supported
* by mpg123_pars.
* \param mp parameter handle
@ -1388,13 +1640,17 @@ MPG123_EXPORT int mpg123_getpar( mpg123_pars *mp
* Note that the required buffer size could be bigger than expected from output
* encoding if libmpg123 has to convert from primary decoder output (p.ex. 32 bit
* storage for 24 bit output).
*
* Note: The type of data changed to a void pointer in mpg123 1.26.0
* (API version 45).
*
* \param mh handle
* \param data pointer to user buffer
* \param size of buffer in bytes
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_replace_buffer(mpg123_handle *mh
, unsigned char *data, size_t size);
, void *data, size_t size);
/** The max size of one frame's decoded output with current settings.
* Use that to determine an appropriate minimum buffer size for decoding one frame.

View file

@ -303,6 +303,9 @@ off_t outblock_bytes(mpg123_handle *fr, off_t s);
/* Postprocessing format conversion of freshly decoded buffer. */
void postprocess_buffer(mpg123_handle *fr);
int open_fixed_pre(mpg123_handle *mh, int channels, int encoding);
int open_fixed_post(mpg123_handle *mh, int channels, int encoding);
/* If networking is enabled and we really mean internal networking, the timeout_read function is available. */
#if defined (NETWORK) && !defined (WANT_WIN32_SOCKETS)
/* Does not work with win32 */

View file

@ -16,7 +16,7 @@ int frame_bitrate(mpg123_handle *fr);
long frame_freq(mpg123_handle *fr);
int read_frame_recover(mpg123_handle* fr); /* dead? */
int read_frame(mpg123_handle *fr);
void set_pointer(mpg123_handle *fr, long backstep);
void set_pointer(mpg123_handle *fr, int part2, long backstep);
int position_info(mpg123_handle* fr, unsigned long no, long buffsize, unsigned long* frames_left, double* current_seconds, double* seconds_left);
double compute_bpf(mpg123_handle *fr);
long time_to_frame(mpg123_handle *fr, double seconds);

View file

@ -151,4 +151,45 @@ static inline int16_t ftoi16(float x)
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
#endif
/* Finished 32 bit sample to unsigned 32 bit sample. */
#define CONV_SU32(s) \
( (s >= 0) \
? ((uint32_t)s + (uint32_t)2147483648UL) \
: (s == -2147483647-1 /* Work around to prevent a non-conformant MSVC warning/error */ \
? 0 /* Separate because negation would overflow. */ \
: (uint32_t)2147483648UL - (uint32_t)(-s) ) \
)
/* Finished 16 bit sample to unsigned 16 bit sample. */
#define CONV_SU16(s) (uint16_t)((int32_t)(s)+32768)
/* Same style for syn123 generic conversion. */
#define CONV_SU8(s) (uint8_t)((int16_t)s+128)
/* Unsigned 32 bit sample to signed 32 bit sample. */
#define CONV_US32(u) \
( (u >= 2147483648UL) \
? (int32_t)((uint32_t)u - (uint32_t)2147483648UL) \
: ((u == 0) \
? (int32_t)-2147483648UL \
: -(int32_t)((uint32_t)2147483648UL - u) ) \
)
/* Unsigned 16 bit sample to signed 16 bit sample. */
#define CONV_US16(s) (int16_t)((int32_t)s-32768)
/* Same style for syn123 generic conversion. */
#define CONV_US8(s) (int8_t)((int16_t)s-128)
/* 24 bit conversion: drop or add a least significant byte. */
#ifdef WORDS_BIGENDIAN
/* Highest byte first. Drop last. */
#define DROP4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2];}
#define ADD4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2]; (w)[3]=0;}
#else
/* Lowest byte first, drop that. */
#define DROP4BYTE(w,r) {(w)[0]=(r)[1]; (w)[1]=(r)[2]; (w)[2]=(r)[3];}
#define ADD4BYTE(w,r) {(w)[0]=0; (w)[1]=(r)[0]; (w)[2]=(r)[1]; (w)[3]=(r)[2];}
#endif
#endif

View file

@ -0,0 +1,103 @@
/*
swap_bytes: Swap byte order of samples in a buffer.
copyright 2018 by the mpg123 project
licensed under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
This is C source to include in your code to get the function named
swap_bytes. It is serves intentional duplication in libmpg123 and
libsyn123 to avoid introducing a dependency between them. This function
is too small for that.
*/
/* Other headers are already included! */
/* Optionally use platform-specific byteswap macros. */
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
/* Plain stupid swapping of elements in a byte array. */
/* This is the fallback when there is no native bswap macro. */
#define SWAP(a,b) tmp = p[a]; p[a] = p[b]; p[b] = tmp;
/* Convert samplecount elements of samplesize bytes each in buffer buf. */
static void swap_bytes(void *buf, size_t samplesize, size_t samplecount)
{
unsigned char *p = buf;
unsigned char *pend = (unsigned char*)buf+samplesize*samplecount;
unsigned char tmp;
if(samplesize < 2)
return;
switch(samplesize)
{
case 2: /* AB -> BA */
#ifdef HAVE_BYTESWAP_H
{
uint16_t* pp = (uint16_t*)p;
for(; pp<(uint16_t*)pend; ++pp)
*pp = bswap_16(*pp);
}
#else
for(; p<pend; p+=2)
{
SWAP(0,1)
}
#endif
break;
case 3: /* ABC -> CBA */
for(; p<pend; p+=3)
{
SWAP(0,2)
}
break;
case 4: /* ABCD -> DCBA */
#ifdef HAVE_BYTESWAP_H
{
uint32_t* pp = (uint32_t*)p;
for(; pp<(uint32_t*)pend; ++pp)
*pp = bswap_32(*pp);
}
#else
for(; p<pend; p+=4)
{
SWAP(0,3)
SWAP(1,2)
}
#endif
break;
case 8: /* ABCDEFGH -> HGFEDCBA */
#ifdef HAVE_BYTESWAP_H
{
uint64_t* pp = (uint64_t*)p;
for(; pp<(uint64_t*)pend; ++pp)
*pp = bswap_64(*pp);
}
#else
for(; p<pend; p+=8)
{
SWAP(0,7)
SWAP(1,6)
SWAP(2,5)
SWAP(3,4)
}
#endif
break;
/* All the weird choices with the full nested loop. */
default:
for(; p<pend; p+=samplesize)
{
size_t j;
for(j=0; j<samplesize/2; ++j)
{
SWAP(j, samplesize-j-1)
}
}
}
}
#undef SWAP

View file

@ -1,6 +1,11 @@
#include "mpg123lib_intern.h"
int mpg123_feature(const enum mpg123_feature_set key)
int attribute_align_arg mpg123_feature2(int key)
{
return mpg123_feature(key);
}
int attribute_align_arg mpg123_feature(const enum mpg123_feature_set key)
{
switch(key)
{
@ -32,6 +37,20 @@ int mpg123_feature(const enum mpg123_feature_set key)
return 1;
#endif /* mpg123_output_32bit */
case MPG123_FEATURE_OUTPUT_FLOAT32:
#if defined(NO_REAL) || defined(REAL_IS_DOUBLE)
return 0;
#else
return 1;
#endif
case MPG123_FEATURE_OUTPUT_FLOAT64:
#if defined(NO_REAL) || !defined(REAL_IS_DOUBLE)
return 0;
#else
return 1;
#endif
case MPG123_FEATURE_PARSE_ID3V2:
#ifdef NO_ID3V2
return 0;
@ -106,6 +125,12 @@ int mpg123_feature(const enum mpg123_feature_set key)
#else
return 0;
#endif
case MPG123_FEATURE_MOREINFO:
#ifndef NO_MOREINFO
return 1;
#else
return 0;
#endif
default: return 0;
}

View file

@ -1,7 +1,7 @@
/*
format:routines to deal with audio (output) format
format: routines to deal with audio (output) format
copyright 2008-14 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2008-20 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
@ -26,6 +26,7 @@
*/
#include "mpg123lib_intern.h"
#include "sample.h"
#include "debug.h"
/* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
@ -60,6 +61,10 @@ static const int my_encodings[MPG123_ENCODINGS] =
static const int enc_float_range[2] = { 6, 8 };
/* same for 8 bit encodings */
static const int enc_8bit_range[2] = { 8, 12 };
// for 24 bit quality (24 and 32 bit integers)
static const int enc_24bit_range[2] = { 2, 6 };
// for completeness, the 16 bits
static const int enc_16bit_range[2] = { 0, 2};
/*
Only one type of float is supported.
@ -150,14 +155,14 @@ static int enc2num(int encoding)
return -1;
}
static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
static int cap_fit(mpg123_pars *p, struct audioformat *nf, int f0, int f2)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, nf->rate);
int rn = rate2num(p, nf->rate);
if(rn >= 0) for(i=f0;i<f2;i++)
{
if(fr->p.audio_caps[c][rn][i])
if(p->audio_caps[c][rn][i])
{
nf->encoding = my_encodings[i];
return 1;
@ -166,48 +171,54 @@ static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
return 0;
}
static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
static int imin(int a, int b)
{
nf->rate = frame_freq(fr)>>fr->p.down_sample;
if(cap_fit(fr,nf,f0,f2)) return 1;
if(fr->p.flags & MPG123_AUTO_RESAMPLE)
{
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
}
#ifndef NO_NTOM
/* If nothing worked, try the other rates, only without constrains from user.
In case you didn't guess: We enable flexible resampling if we find a working rate. */
if( fr->p.flags & MPG123_AUTO_RESAMPLE &&
!fr->p.force_rate && fr->p.down_sample == 0)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, frame_freq(fr));
int rrn;
if(rn < 0) return 0;
/* Try higher rates first. */
for(i=f0;i<f2;i++) for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
}
#endif
return a < b ? a : b;
}
return 0;
static int imax(int a, int b)
{
return a > b ? a : b;
}
// Find a possible encoding with given rate and channel count,
// try differing channel count, too.
// This updates the given format and returns TRUE if an encoding
// was found.
static int enc_chan_fit( mpg123_pars *p, long rate, struct audioformat *nnf
, int f0, int f2, int try_float )
{
#define ENCRANGE(range) imax(f0, range[0]), imin(f2, range[1])
struct audioformat nf = *nnf;
nf.rate = rate;
if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
goto eend;
if(try_float &&
cap_fit(p, &nf, ENCRANGE(enc_float_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
goto eend;
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
goto eend;
if(try_float &&
cap_fit(p, &nf, ENCRANGE(enc_float_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
goto eend;
return FALSE;
eend:
*nnf = nf;
return TRUE;
#undef ENCRANGE
}
/* match constraints against supported audio formats, store possible setup in frame
@ -216,12 +227,17 @@ int frame_output_format(mpg123_handle *fr)
{
struct audioformat nf;
int f0=0;
int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */
int f2=MPG123_ENCODINGS+1; // Include all encodings by default.
mpg123_pars *p = &fr->p;
int try_float = (p->flags & MPG123_FLOAT_FALLBACK) ? 0 : 1;
/* initialize new format, encoding comes later */
nf.channels = fr->stereo;
/* All this forcing should be removed in favour of the capabilities table... */
// I intended the forcing stuff to be weaved into the format support table,
// but this probably will never happen, as this would change library behaviour.
// One could introduce an additional effective format table that takes for
// forcings into account, but that would have to be updated on any flag
// change. Tedious.
if(p->flags & MPG123_FORCE_8BIT)
{
f0 = enc_8bit_range[0];
@ -229,6 +245,7 @@ int frame_output_format(mpg123_handle *fr)
}
if(p->flags & MPG123_FORCE_FLOAT)
{
try_float = 1;
f0 = enc_float_range[0];
f2 = enc_float_range[1];
}
@ -237,52 +254,105 @@ int frame_output_format(mpg123_handle *fr)
if(p->flags & MPG123_FORCE_MONO) nf.channels = 1;
if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
// Strategy update: Avoid too early triggering of the NtoM decoder.
// Main target is the native rate, with any encoding.
// Then, native rate with any channel count and any encoding.
// Then, it's down_sample from native rate.
// As last resort: NtoM rate.
// So the priority is 1. rate 2. channels 3. encoding.
// As encodings go, 16 bit is tranditionally preferred as efficient choice.
// Next in line are wider float and integer encodings, then 8 bit as
// last resort.
#ifndef NO_NTOM
if(p->force_rate)
{
nf.rate = p->force_rate;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
if(enc_chan_fit(p, p->force_rate, &nf, f0, f2, try_float))
goto end;
// Keep the order consistent if float is considered fallback only.
if(!try_float &&
enc_chan_fit(p, p->force_rate, &nf, f0, f2, TRUE))
goto end;
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
if(NOQUIET)
error3( "Unable to set up output format! Constraints: %s%s%liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
p->force_rate );
merror( "Unable to set up output format! Constraints: %s%s%liHz."
, ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
, ( p->flags & MPG123_FORCE_FLOAT ? "float, " :
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
, p->force_rate );
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
}
#endif
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
// Native decoder rate first.
if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, try_float))
goto end;
// Then downsamplings.
if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
{
if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
, f0, f2, try_float ))
goto end;
if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
, f0, f2, try_float ))
goto end;
}
// And again the whole deal with float fallback.
if(!try_float)
{
if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, TRUE))
goto end;
// Then downsamplings.
if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
{
if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
, f0, f2, TRUE ))
goto end;
if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
, f0, f2, TRUE ))
goto end;
}
}
#ifndef NO_NTOM
// Try to find any rate that works and resample using NtoM hackery.
if( p->flags & MPG123_AUTO_RESAMPLE && fr->p.down_sample == 0)
{
int i;
int rn = rate2num(p, frame_freq(fr));
int rrn;
if(rn < 0) return 0;
/* Try higher rates first. */
for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
goto end;
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
goto end;
// And again for float fallback.
if(!try_float)
{
/* Try higher rates first. */
for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
goto end;
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
goto end;
}
}
#endif
/* Here is the _bad_ end. */
if(NOQUIET)
{
error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
}
merror( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz."
, ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
, ( p->flags & MPG123_FORCE_FLOAT ? "float, " :
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
, frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
@ -305,7 +375,7 @@ end: /* Here is the _good_ end. */
fr->af.encsize = mpg123_encsize(fr->af.encoding);
if(fr->af.encsize < 1)
{
if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding);
error1("Some unknown encoding??? (%i)", fr->af.encoding);
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
@ -391,6 +461,17 @@ int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
return MPG123_OK;
}
int attribute_align_arg mpg123_format2(mpg123_handle *mh, long rate, int channels, int encodings)
{
int r;
if(mh == NULL) return MPG123_BAD_HANDLE;
r = mpg123_fmt2(&mh->p, rate, channels, encodings);
if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
return r;
}
// Keep old behaviour.
int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
{
int r;
@ -401,9 +482,9 @@ int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels
return r;
}
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
int attribute_align_arg mpg123_fmt2(mpg123_pars *mp, long rate, int channels, int encodings)
{
int ie, ic, ratei;
int ie, ic, ratei, r1, r2;
int ch[2] = {0, 1};
if(mp == NULL) return MPG123_BAD_PARS;
if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
@ -412,10 +493,21 @@ int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int
if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */
else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
ratei = rate2num(mp, rate);
if(ratei < 0) return MPG123_BAD_RATE;
if(rate)
{
r1 = rate2num(mp, rate);
r2 = r1+1;
}
else
{
r1 = 0;
r2 = MPG123_RATES+1; /* including forced rate */
}
if(r1 < 0) return MPG123_BAD_RATE;
/* now match the encodings */
for(ratei = r1; ratei < r2; ++ratei)
for(ic = 0; ic < 2; ++ic)
{
for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
@ -428,6 +520,14 @@ int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int
return MPG123_OK;
}
// Keep old behaviour, error on rate=0.
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
{
return (rate == 0)
? MPG123_BAD_RATE
: mpg123_fmt2(mp, rate, channels, encodings);
}
int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
{
if(mh == NULL) return 0;
@ -484,37 +584,17 @@ off_t outblock_bytes(mpg123_handle *fr, off_t s)
}
#ifndef NO_32BIT
/* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers.
This has to be aware of endianness, of course. */
static void chop_fourth_byte(struct outbuffer *buf)
{
unsigned char *wpos = buf->data;
unsigned char *rpos = buf->data;
#ifdef WORDS_BIGENDIAN
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
rpos++; /* Skip the lowest byte (last). */
}
#else
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
rpos++; /* Skip the lowest byte (first). */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
}
#endif
size_t blocks = buf->fill/4;
size_t i;
for(i=0; i<blocks; ++i,wpos+=3,rpos+=4)
DROP4BYTE(wpos, rpos)
buf->fill = wpos-buf->data;
}
@ -526,18 +606,7 @@ static void conv_s32_to_u32(struct outbuffer *buf)
size_t count = buf->fill/sizeof(int32_t);
for(i=0; i<count; ++i)
{
/* Different strategy since we don't have a larger type at hand.
Also watch out for silly +-1 fun because integer constants are signed in C90! */
if(ssamples[i] >= 0)
usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
/* The smallest value goes zero. */
else if(ssamples[i] == ((int32_t)-2147483647-1))
usamples[i] = 0;
/* Now -value is in the positive range of signed int ... so it's a possible value at all. */
else
usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
}
usamples[i] = CONV_SU32(ssamples[i]);
}
#endif
@ -559,10 +628,7 @@ static void conv_s16_to_u16(struct outbuffer *buf)
size_t count = buf->fill/sizeof(int16_t);
for(i=0; i<count; ++i)
{
long tmp = (long)ssamples[i]+32768;
usamples[i] = (uint16_t)tmp;
}
usamples[i] = CONV_SU16(ssamples[i]);
}
#ifndef NO_REAL
@ -618,6 +684,18 @@ static void conv_s16_to_s32(struct outbuffer *buf)
#endif
#endif
#include "swap_bytes_impl.h"
void swap_endian(struct outbuffer *buf, int block)
{
size_t count;
if(block >= 2)
{
count = buf->fill/(unsigned int)block;
swap_bytes(buf->data, (size_t)block, count);
}
}
void postprocess_buffer(mpg123_handle *fr)
{
@ -680,4 +758,17 @@ void postprocess_buffer(mpg123_handle *fr)
break;
#endif
}
if(fr->p.flags & MPG123_FORCE_ENDIAN)
{
if(
#ifdef WORDS_BIGENDIAN
!(
#endif
fr->p.flags & MPG123_BIG_ENDIAN
#ifdef WORDS_BIGENDIAN
)
#endif
)
swap_endian(&fr->buffer, mpg123_encsize(fr->af.encoding));
}
}

View file

@ -1,7 +1,7 @@
/*
frame: Heap of routines dealing with the core mpg123 data structure.
copyright 2008-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2008-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
@ -40,7 +40,7 @@ static void frame_default_pars(mpg123_pars *mp)
#ifdef GAPLESS
mp->flags |= MPG123_GAPLESS;
#endif
mp->flags |= MPG123_AUTO_RESAMPLE;
mp->flags |= MPG123_AUTO_RESAMPLE|MPG123_FLOAT_FALLBACK;
#ifndef NO_NTOM
mp->force_rate = 0;
#endif
@ -64,6 +64,7 @@ static void frame_default_pars(mpg123_pars *mp)
mp->feedpool = 5;
mp->feedbuffer = 4096;
#endif
mp->freeformat_framesize = -1;
}
void frame_init(mpg123_handle *fr)
@ -124,6 +125,7 @@ void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
#endif
fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
fr->id3v2_raw = NULL;
frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
fr->synth = NULL;
fr->synth_mono = NULL;
@ -132,6 +134,9 @@ void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
fi_init(&fr->index);
frame_index_setup(fr); /* Apply the size setting. */
#endif
#ifndef NO_MOREINFO
fr->pinfo = NULL;
#endif
}
#ifdef OPT_DITHER
@ -183,8 +188,9 @@ int frame_outbuffer(mpg123_handle *fr)
if(fr->buffer.size < size)
{
fr->err = MPG123_BAD_BUFFER;
if(NOQUIET) error2("have external buffer of size %"SIZE_P", need %"SIZE_P, (size_p)fr->buffer.size, (size_p)size);
if(NOQUIET)
merror( "have external buffer of size %"SIZE_P", need %"SIZE_P
, (size_p)fr->buffer.size, (size_p)size );
return MPG123_ERR;
}
}
@ -210,7 +216,7 @@ int frame_outbuffer(mpg123_handle *fr)
return MPG123_OK;
}
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, void *data, size_t size)
{
debug2("replace buffer with %p size %"SIZE_P, data, (size_p)size);
if(mh == NULL) return MPG123_BAD_HANDLE;
@ -236,20 +242,19 @@ int frame_index_setup(mpg123_handle *fr)
if(fr->p.index_size >= 0)
{ /* Simple fixed index. */
fr->index.grow_size = 0;
debug1("resizing index to %li", fr->p.index_size);
ret = fi_resize(&fr->index, (size_t)fr->p.index_size);
debug2("index resized... %lu at %p", (unsigned long)fr->index.size, (void*)fr->index.data);
}
else
{ /* A growing index. We give it a start, though. */
fr->index.grow_size = (size_t)(- fr->p.index_size);
if(fr->index.size < fr->index.grow_size)
ret = fi_resize(&fr->index, fr->index.grow_size);
ret = fi_resize(&fr->index, fr->index.grow_size);
else
ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */
}
debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret);
if(ret && NOQUIET)
error("frame index setup (initial resize) failed");
return ret;
}
#endif
@ -560,7 +565,14 @@ static void frame_fixed_reset(mpg123_handle *fr)
#endif
fr->halfphase = 0; /* here or indeed only on first-time init? */
fr->error_protection = 0;
fr->freeformat_framesize = -1;
fr->freeformat_framesize = fr->p.freeformat_framesize;
fr->enc_delay = -1;
fr->enc_padding = -1;
memset(fr->id3buf, 0, sizeof(fr->id3buf));
if(fr->id3v2_raw)
free(fr->id3v2_raw);
fr->id3v2_raw = NULL;
fr->id3v2_size = 0;
}
static void frame_free_buffers(mpg123_handle *fr)
@ -623,6 +635,18 @@ int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *heade
return MPG123_OK;
}
int attribute_align_arg mpg123_set_moreinfo( mpg123_handle *mh
, struct mpg123_moreinfo *mi)
{
#ifndef NO_MOREINFO
mh->pinfo = mi;
return MPG123_OK;
#else
mh->err = MPG123_MISSING_FEATURE;
return MPG123_ERR;
#endif
}
/*
Fuzzy frame offset searching (guessing).
When we don't have an accurate position, we may use an inaccurate one.
@ -739,7 +763,9 @@ off_t frame_ins2outs(mpg123_handle *fr, off_t ins)
# ifndef NO_NTOM
case 3: outs = ntom_ins2outs(fr, ins); break;
# endif
default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
default: if(NOQUIET)
merror( "Bad down_sample (%i) ... should not be possible!!"
, fr->down_sample );
}
return outs;
}
@ -759,7 +785,9 @@ off_t frame_outs(mpg123_handle *fr, off_t num)
#ifndef NO_NTOM
case 3: outs = ntom_frmouts(fr, num); break;
#endif
default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
default: if(NOQUIET)
merror( "Bad down_sample (%i) ... should not be possible!!"
, fr->down_sample );
}
return outs;
}
@ -781,7 +809,9 @@ off_t frame_expect_outsamples(mpg123_handle *fr)
#ifndef NO_NTOM
case 3: outs = ntom_frame_outsamples(fr); break;
#endif
default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
default: if(NOQUIET)
merror( "Bad down_sample (%i) ... should not be possible!!"
, fr->down_sample );
}
return outs;
}
@ -801,7 +831,8 @@ off_t frame_offset(mpg123_handle *fr, off_t outs)
#ifndef NO_NTOM
case 3: num = ntom_frameoff(fr, outs); break;
#endif
default: error("Bad down_sample ... should not be possible!!");
default: if(NOQUIET)
error("Bad down_sample ... should not be possible!!");
}
return num;
}
@ -849,7 +880,10 @@ void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
if(gapless_samples > total_samples)
{
if(NOQUIET) error2("End sample count smaller than gapless end! (%"OFF_P" < %"OFF_P"). Disabling gapless mode from now on.", (off_p)total_samples, (off_p)fr->end_s);
if(NOQUIET)
merror( "End sample count smaller than gapless end! (%"OFF_P
" < %"OFF_P"). Disabling gapless mode from now on."
, (off_p)total_samples, (off_p)fr->end_s );
/* This invalidates the current position... but what should I do? */
frame_gapless_init(fr, -1, 0, 0);
frame_gapless_realinit(fr);
@ -912,7 +946,7 @@ void frame_set_frameseek(mpg123_handle *fr, off_t fe)
void frame_skip(mpg123_handle *fr)
{
#ifndef NO_LAYER3
if(fr->lay == 3) set_pointer(fr, 512);
if(fr->lay == 3) set_pointer(fr, 1, 512);
#endif
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*
index: frame index data structure and functions
copyright 2007-2015 by the mpg123 project
copyright 2007-2020 by the mpg123 project
-= free software under the terms of the LGPL 2.1 =-
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
@ -74,12 +74,8 @@ int fi_resize(struct frame_index *fi, size_t newsize)
fi->next = fi_next(fi);
debug2("new index of size %lu at %p", (unsigned long)fi->size, (void*)fi->data);
return 0;
}
else
{
error("failed to resize index!");
} else
return -1;
}
}
void fi_add(struct frame_index *fi, off_t pos)

View file

@ -34,6 +34,14 @@ static int check_balloc(mpg123_handle *fr, unsigned int *balloc, unsigned int *e
return 0;
}
#define NEED_BITS(fr, num) \
if((fr)->bits_avail < num) \
{ \
if(NOQUIET) \
error2("%u bits needed, %li available", num, (fr)->bits_avail); \
return -1; \
} \
static int I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
{
unsigned int *ba=balloc;
@ -43,42 +51,62 @@ static int I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT
{
int i;
int jsbound = fr->jsbound;
unsigned int needbits = jsbound*2*4 + (SBLIMIT-jsbound)*4;
NEED_BITS(fr, needbits);
needbits = 0;
for(i=0;i<jsbound;i++)
{
*ba++ = getbits(fr, 4);
*ba++ = getbits(fr, 4);
ba[0] = getbits_fast(fr, 4);
ba[1] = getbits_fast(fr, 4);
needbits += ((ba[0]?1:0)+(ba[1]?1:0))*6;
ba+=2;
}
for(i=jsbound;i<SBLIMIT;i++)
{
*ba = getbits_fast(fr, 4);
needbits += (*ba?1:0)*12;
++ba;
}
for(i=jsbound;i<SBLIMIT;i++) *ba++ = getbits(fr, 4);
if(check_balloc(fr, balloc, ba)) return -1;
ba = balloc;
NEED_BITS(fr, needbits)
for(i=0;i<jsbound;i++)
{
if ((*ba++))
*sca++ = getbits(fr, 6);
*sca++ = getbits_fast(fr, 6);
if ((*ba++))
*sca++ = getbits(fr, 6);
*sca++ = getbits_fast(fr, 6);
}
for (i=jsbound;i<SBLIMIT;i++)
if((*ba++))
for (i=jsbound;i<SBLIMIT;i++) if((*ba++))
{
*sca++ = getbits(fr, 6);
*sca++ = getbits(fr, 6);
*sca++ = getbits_fast(fr, 6);
*sca++ = getbits_fast(fr, 6);
}
}
else
{
int i;
for(i=0;i<SBLIMIT;i++) *ba++ = getbits(fr, 4);
unsigned int needbits = SBLIMIT*4;
NEED_BITS(fr, needbits)
needbits = 0;
for(i=0;i<SBLIMIT;i++)
{
*ba = getbits_fast(fr, 4);
needbits += (*ba?1:0)*6;
++ba;
}
if(check_balloc(fr, balloc, ba)) return -1;
ba = balloc;
NEED_BITS(fr, needbits)
for (i=0;i<SBLIMIT;i++)
if ((*ba++))
*sca++ = getbits(fr, 6);
if ((*ba++))
*sca++ = getbits_fast(fr, 6);
}
return 0;
@ -87,7 +115,7 @@ static int I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT
/* Something sane in place of undefined (-1)<<n. Well, not really. */
#define MINUS_SHIFT(n) ( (int)(((unsigned int)-1)<<(n)) )
static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
static int I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
{
int i,n;
int smpb[2*SBLIMIT]; /* values: 0-65535 */
@ -97,9 +125,24 @@ static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
if(fr->stereo == 2)
{
unsigned int needbits = 0;
int jsbound = fr->jsbound;
register real *f0 = fraction[0];
register real *f1 = fraction[1];
ba = balloc;
for(sample=smpb,i=0;i<jsbound;i++)
{
if((n=*ba++))
needbits += n+1;
if((n=*ba++))
needbits += n+1;
}
for(i=jsbound;i<SBLIMIT;i++)
if((n = *ba++))
needbits += n+1;
NEED_BITS(fr, needbits)
ba = balloc;
for(sample=smpb,i=0;i<jsbound;i++)
{
@ -137,12 +180,21 @@ static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
}
else
{
unsigned int needbits = 0;
register real *f0 = fraction[0];
ba = balloc;
for(sample=smpb,i=0;i<SBLIMIT;i++)
if((n = *ba++))
needbits += n+1;
NEED_BITS(fr, needbits);
ba = balloc;
for(sample=smpb,i=0;i<SBLIMIT;i++)
if ((n = *ba++))
*sample++ = getbits(fr, n+1);
ba = balloc;
for(sample=smpb,i=0;i<SBLIMIT;i++)
{
@ -153,6 +205,7 @@ static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
for(i=fr->down_sample_sblimit;i<32;i++)
fraction[0][i] = DOUBLE_TO_REAL(0.0);
}
return 0;
}
int do_layer1(mpg123_handle *fr)
@ -171,13 +224,19 @@ int do_layer1(mpg123_handle *fr)
if(I_step_one(balloc,scale_index,fr))
{
if(NOQUIET) error("Aborting layer I decoding after step one.\n");
if(NOQUIET)
error("Aborting layer I decoding after step one.");
return clip;
}
for(i=0;i<SCALE_BLOCK;i++)
{
I_step_two(fraction,balloc,scale_index,fr);
if(I_step_two(fraction,balloc,scale_index,fr))
{
if(NOQUIET)
error("Aborting layer I decoding after step two.");
return clip;
}
if(single != SINGLE_STEREO)
clip += (fr->synth_mono)(fraction[single], fr);

View file

@ -114,7 +114,7 @@ real* init_layer12_table_mmx(mpg123_handle *fr, real *table, int m)
#ifndef NO_LAYER2
static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
static int II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
{
int stereo = fr->stereo-1;
int sblimit = fr->II_sblimit;
@ -125,6 +125,9 @@ static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
unsigned int scfsi_buf[64];
unsigned int *scfsi,*bita;
int sc,step;
/* Count the bits needed for getbits_fast(). */
unsigned int needbits = 0;
unsigned int scale_bits[4] = { 18, 12, 6, 12 };
bita = bit_alloc;
if(stereo)
@ -132,19 +135,28 @@ static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
for(i=jsbound;i;i--,alloc1+=(1<<step))
{
step=alloc1->bits;
*bita++ = (char) getbits(fr, step);
*bita++ = (char) getbits(fr, step);
bita[0] = (char) getbits(fr, step);
bita[1] = (char) getbits(fr, step);
needbits += ((bita[0]?1:0)+(bita[1]?1:0))*2;
bita+=2;
}
for(i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
{
step=alloc1->bits;
bita[0] = (char) getbits(fr, step);
bita[1] = bita[0];
needbits += (bita[0]?1:0)*2*2;
bita+=2;
}
bita = bit_alloc;
scfsi=scfsi_buf;
if(fr->bits_avail < needbits)
{
if(NOQUIET)
error2("need %u bits, have %li", needbits, fr->bits_avail);
return -1;
}
for(i=sblimit2;i;i--)
if(*bita++) *scfsi++ = (char) getbits_fast(fr, 2);
}
@ -153,17 +165,39 @@ static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
for(i=sblimit;i;i--,alloc1+=(1<<step))
{
step=alloc1->bits;
*bita++ = (char) getbits(fr, step);
*bita = (char) getbits(fr, step);
if(*bita)
needbits += 2;
++bita;
}
bita = bit_alloc;
scfsi=scfsi_buf;
if(fr->bits_avail < needbits)
{
if(NOQUIET)
error2("need %u bits, have %li", needbits, fr->bits_avail);
return -1;
}
for(i=sblimit;i;i--)
if(*bita++) *scfsi++ = (char) getbits_fast(fr, 2);
}
needbits = 0;
bita = bit_alloc;
scfsi=scfsi_buf;
for(i=sblimit2;i;i--)
for(i=sblimit2;i;--i)
if(*bita++)
needbits += scale_bits[*scfsi++];
if(fr->bits_avail < needbits)
{
if(NOQUIET)
error2("need %u bits, have %li", needbits, fr->bits_avail);
return -1;
}
bita = bit_alloc;
scfsi=scfsi_buf;
for(i=sblimit2;i;--i)
if(*bita++)
switch(*scfsi++)
{
@ -188,6 +222,8 @@ static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
*scale++ = sc;
break;
}
return 0;
}
@ -230,6 +266,8 @@ static void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int
}
else
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = DOUBLE_TO_REAL(0.0);
if(fr->bits_avail < 0)
return; /* Caller checks that again. */
}
}
@ -267,6 +305,8 @@ static void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int
fraction[0][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m1]); fraction[1][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m2]);
}
scale+=6;
if(fr->bits_avail < 0)
return; /* Caller checks that again. */
}
else
{
@ -351,11 +391,22 @@ int do_layer2(mpg123_handle *fr)
if(stereo == 1 || single == SINGLE_MIX) /* also, mix not really handled */
single = SINGLE_LEFT;
II_step_one(bit_alloc, scale, fr);
if(II_step_one(bit_alloc, scale, fr))
{
if(NOQUIET)
error("first step of layer I decoding failed");
return clip;
}
for(i=0;i<SCALE_BLOCK;i++)
{
II_step_two(bit_alloc,fraction,scale,fr,i>>2);
if(fr->bits_avail < 0)
{
if(NOQUIET)
error("missing bits in layer II step two");
return clip;
}
for(j=0;j<3;j++)
{
if(single != SINGLE_STEREO)

View file

@ -410,6 +410,23 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
const int *tab = tabs[fr->lsf];
{ /* First ensure we got enough bits available. */
unsigned int needbits = 0;
needbits += tab[1]; /* main_data_begin */
needbits += stereo == 1 ? tab[2] : tab[3]; /* private */
if(!fr->lsf)
needbits += stereo*4; /* scfsi */
/* For each granule for each channel ... */
needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->lsf?1:0)+2);
if(fr->bits_avail < needbits) \
{
if(NOQUIET)
error2( "%u bits for side info needed, only %li available"
, needbits, fr->bits_avail );
return 1;
}
}
si->main_data_begin = getbits(fr, tab[1]);
if(si->main_data_begin > fr->bitreservoir)
@ -434,8 +451,9 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
}
/* Keep track of the available data bytes for the bit reservoir.
Think: Substract the 2 crc bytes in parser already? */
fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize - (fr->error_protection ? 2 : 0);
CRC is included in ssize already. */
fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize;
/* Limit the reservoir to the max for MPEG 1.0 or 2.x . */
if(fr->bitreservoir > (unsigned int) (fr->lsf == 0 ? 511 : 255))
fr->bitreservoir = (fr->lsf == 0 ? 511 : 255);
@ -443,21 +461,21 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
/* Now back into less commented territory. It's code. It works. */
if (stereo == 1)
si->private_bits = getbits_fast(fr, tab[2]);
si->private_bits = getbits(fr, tab[2]);
else
si->private_bits = getbits_fast(fr, tab[3]);
si->private_bits = getbits(fr, tab[3]);
if(!fr->lsf) for(ch=0; ch<stereo; ch++)
{
si->ch[ch].gr[0].scfsi = -1;
si->ch[ch].gr[1].scfsi = getbits_fast(fr, 4);
si->ch[ch].gr[1].scfsi = getbits(fr, 4);
}
for (gr=0; gr<tab[0]; gr++)
for (ch=0; ch<stereo; ch++)
{
register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
unsigned int qss;
gr_info->part2_3_length = getbits(fr, 12);
gr_info->big_values = getbits(fr, 9);
if(gr_info->big_values > 288)
@ -465,18 +483,25 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
if(NOQUIET) error("big_values too large!");
gr_info->big_values = 288;
}
gr_info->pow2gain = fr->gainpow2+256 - getbits_fast(fr, 8) + powdiff;
if(ms_stereo) gr_info->pow2gain += 2;
qss = getbits_fast(fr, 8);
gr_info->pow2gain = fr->gainpow2+256 - qss + powdiff;
if(ms_stereo)
gr_info->pow2gain += 2;
#ifndef NO_MOREINFO
if(fr->pinfo)
fr->pinfo->qss[gr][ch] = qss;
#endif
gr_info->scalefac_compress = getbits(fr, tab[4]);
if(gr_info->part2_3_length == 0)
{
if(gr_info->scalefac_compress > 0)
debug1( "scalefac_compress _should_ be zero instead of %i"
if(gr_info->scalefac_compress > 0 && VERBOSE2)
error1( "scalefac_compress should be zero instead of %i"
, gr_info->scalefac_compress );
gr_info->scalefac_compress = 0;
}
if(get1bit(fr))
/* 22 bits for if/else block */
if(getbits(fr,1))
{ /* window switch flag */
int i;
gr_info->block_type = getbits_fast(fr, 2);
@ -489,7 +514,14 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
*/
gr_info->table_select[2] = 0;
for(i=0;i<3;i++)
gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(fr, 3)<<3);
{
unsigned int sbg = (getbits_fast(fr, 3)<<3);
gr_info->full_gain[i] = gr_info->pow2gain + sbg;
#ifndef NO_MOREINFO
if(fr->pinfo)
fr->pinfo->sub_gain[gr][ch][i] = sbg / 8;
#endif
}
if(gr_info->block_type == 0)
{
@ -572,7 +604,10 @@ static int III_get_scale_factors_1(mpg123_handle *fr, int *scf,struct gr_info_s
if(gr_info->block_type == 2)
{
int i=18;
numbits = (num0 + num1) * 18;
numbits = (num0 + num1) * 18 /* num0 * (17+1?) + num1 * 18 */
- (gr_info->mixed_block_flag ? num0 : 0);
if(numbits > gr_info->part2_3_length)
return -1;
if(gr_info->mixed_block_flag)
{
@ -580,7 +615,6 @@ static int III_get_scale_factors_1(mpg123_handle *fr, int *scf,struct gr_info_s
*scf++ = getbits_fast(fr, num0);
i = 9;
numbits -= num0; /* num0 * 17 + num1 * 18 */
}
for(;i;i--) *scf++ = getbits_fast(fr, num0);
@ -596,51 +630,53 @@ static int III_get_scale_factors_1(mpg123_handle *fr, int *scf,struct gr_info_s
if(scfsi < 0)
{ /* scfsi < 0 => granule == 0 */
numbits = (num0 + num1) * 10 + num0;
if(numbits > gr_info->part2_3_length)
return -1;
for(i=11;i;i--) *scf++ = getbits_fast(fr, num0);
for(i=10;i;i--) *scf++ = getbits_fast(fr, num1);
numbits = (num0 + num1) * 10 + num0;
*scf++ = 0;
}
else
{
numbits = 0;
numbits = !(scfsi & 0x8) * num0 * 6
+ !(scfsi & 0x4) * num0 * 5
+ !(scfsi & 0x2) * num1 * 5
+ !(scfsi & 0x1) * num1 * 5;
if(numbits > gr_info->part2_3_length)
return -1;
if(!(scfsi & 0x8))
{
for (i=0;i<6;i++) *scf++ = getbits_fast(fr, num0);
numbits += num0 * 6;
}
else scf += 6;
if(!(scfsi & 0x4))
{
for (i=0;i<5;i++) *scf++ = getbits_fast(fr, num0);
numbits += num0 * 5;
}
else scf += 5;
if(!(scfsi & 0x2))
{
for(i=0;i<5;i++) *scf++ = getbits_fast(fr, num1);
numbits += num1 * 5;
}
else scf += 5;
if(!(scfsi & 0x1))
{
for (i=0;i<5;i++) *scf++ = getbits_fast(fr, num1);
numbits += num1 * 5;
}
else scf += 5;
*scf++ = 0; /* no l[21] in original sources */
}
}
return numbits;
}
@ -649,7 +685,7 @@ static int III_get_scale_factors_2(mpg123_handle *fr, int *scf,struct gr_info_s
{
const unsigned char *pnt;
int i,j,n=0,numbits=0;
unsigned int slen;
unsigned int slen, slen2;
const unsigned char stab[3][6][4] =
{
@ -685,12 +721,22 @@ static int III_get_scale_factors_2(mpg123_handle *fr, int *scf,struct gr_info_s
if(gr_info->part2_3_length == 0)
{
int i;
for(i=0;i<39;i++)
*scf++ = 0;
return 0;
}
slen2 = slen;
for(i=0;i<4;i++)
{
int num = slen2 & 0x7;
slen2 >>= 3;
if(num)
numbits += pnt[i] * num;
}
if(numbits > gr_info->part2_3_length)
return -1;
for(i=0;i<4;i++)
{
int num = slen & 0x7;
@ -698,8 +744,6 @@ static int III_get_scale_factors_2(mpg123_handle *fr, int *scf,struct gr_info_s
if(num)
{
for(j=0;j<(int)(pnt[i]);j++) *scf++ = getbits_fast(fr, num);
numbits += pnt[i] * num;
}
else
for(j=0;j<(int)(pnt[i]);j++) *scf++ = 0;
@ -773,6 +817,8 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
mask <<= 8-num;
part2remain -= num;
/* Bitindex is zero now, we are allowed to use getbyte(). */
{
int bv = gr_info->big_values;
int region1 = gr_info->region1start;
@ -843,6 +889,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
if( (!mc) )
{
mc = *m++;
//fprintf(stderr, "%i setting xrpnt = xr + %i (%ld)\n", __LINE__, *m, xrpnt-(real*)xr);
xrpnt = ((real *) xr) + (*m++);
lwin = *m++;
cb = *m++;
@ -972,6 +1019,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
if(!mc)
{
mc = *m++;
//fprintf(stderr, "%i setting xrpnt = xr + %i (%ld)\n", __LINE__, *m, xrpnt-(real*)xr);
xrpnt = ((real *) xr) + (*m++);
lwin = *m++;
cb = *m++;
@ -1226,6 +1274,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
part2remain += num;
backbits(fr, num);
num = 0;
}
else
{
@ -1249,7 +1298,8 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
if(part2remain > 0) skipbits(fr, part2remain);
else if(part2remain < 0)
{
debug1("Can't rewind stream by %d bits!",-part2remain);
if(VERBOSE2)
error1("Can't rewind stream by %d bits!",-part2remain);
return 1; /* -> error */
}
return 0;
@ -1977,6 +2027,73 @@ static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT], real tsOut[SSLIMIT][SBLIMIT]
}
}
#ifndef NO_MOREINFO
static void fill_pinfo_side(mpg123_handle *fr, struct III_sideinfo *si, int gr, int stereo1)
{
int i, sb;
float ifqstep; /* Why not double? */
int ch, ss;;
for(ch = 0; ch < stereo1; ++ch)
{
struct gr_info_s *gr_infos = &(si->ch[ch].gr[gr]);
fr->pinfo->big_values[gr][ch] = gr_infos->big_values;
fr->pinfo->scalefac_scale[gr][ch] = gr_infos->scalefac_scale;
fr->pinfo->mixed[gr][ch] = gr_infos->mixed_block_flag;
fr->pinfo->blocktype[gr][ch] = gr_infos->block_type;
fr->pinfo->mainbits[gr][ch] = gr_infos->part2_3_length;
fr->pinfo->preflag[gr][ch] = gr_infos->preflag;
if(gr == 1)
fr->pinfo->scfsi[ch] = gr_infos->scfsi;
}
for(ch = 0; ch < stereo1; ++ch)
{
struct gr_info_s *gr_infos = &(si->ch[ch].gr[gr]);
ifqstep = (fr->pinfo->scalefac_scale[gr][ch] == 0) ? .5 : 1.0;
if(2 == gr_infos->block_type)
{
for(i = 0; i < 3; ++i)
{
for(sb = 0; sb < 12; ++sb)
{
int j = 3 * sb + i;
/*
is_p = scalefac[sfb*3+lwin-gr_infos->mixed_block_flag];
*/
/* scalefac was copied into pinfo->sfb_s[] before */
fr->pinfo->sfb_s[gr][ch][j] = -ifqstep *
fr->pinfo->sfb_s[gr][ch][j - gr_infos->mixed_block_flag];
fr->pinfo->sfb_s[gr][ch][j] -= 2 *
(fr->pinfo->sub_gain[gr][ch][i]);
}
fr->pinfo->sfb_s[gr][ch][3 * sb + i] =
-2 * (fr->pinfo->sub_gain[gr][ch][i]);
}
} else
{
for(sb = 0; sb < 21; ++sb)
{
/* scalefac was copied into pinfo->sfb[] before */
fr->pinfo->sfb[gr][ch][sb] = fr->pinfo->sfb_s[gr][ch][sb];
if (gr_infos->preflag)
fr->pinfo->sfb[gr][ch][sb] += pretab_choice[1][sb];
fr->pinfo->sfb[gr][ch][sb] *= -ifqstep;
}
fr->pinfo->sfb[gr][ch][21] = 0;
}
}
for(ch = 0; ch < stereo1; ++ch)
{
int j = 0;
for(sb = 0; sb < SBLIMIT; ++sb)
for (ss = 0; ss < SSLIMIT; ++ss, ++j)
fr->pinfo->xr[gr][ch][j] = fr->layer3.hybrid_in[ch][sb][ss];
}
}
#endif
/* And at the end... the main layer3 handler */
int do_layer3(mpg123_handle *fr)
@ -2017,8 +2134,14 @@ int do_layer3(mpg123_handle *fr)
return clip;
}
set_pointer(fr,sideinfo.main_data_begin);
set_pointer(fr, 1, sideinfo.main_data_begin);
#ifndef NO_MOREINFO
if(fr->pinfo)
{
fr->pinfo->maindata = sideinfo.main_data_begin;
fr->pinfo->padding = fr->padding;
}
#endif
for(gr=0;gr<granules;gr++)
{
/* hybridIn[2][SBLIMIT][SSLIMIT] */
@ -2029,14 +2152,46 @@ int do_layer3(mpg123_handle *fr)
{
struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
long part2bits;
if(gr_info->part2_3_length > fr->bits_avail)
{
if(NOQUIET)
error2(
"part2_3_length (%u) too large for available bit count (%li)"
, gr_info->part2_3_length, fr->bits_avail );
return clip;
}
if(fr->lsf)
part2bits = III_get_scale_factors_2(fr, scalefacs[0],gr_info,0);
else
part2bits = III_get_scale_factors_1(fr, scalefacs[0],gr_info,0,gr);
if(part2bits < 0)
{
if(VERBOSE2)
error("not enough bits for scale factors");
return clip;
}
#ifndef NO_MOREINFO
if(fr->pinfo)
{
int i;
fr->pinfo->sfbits[gr][0] = part2bits;
for(i=0; i<39; ++i)
fr->pinfo->sfb_s[gr][0][i] = scalefacs[0][i];
}
#endif
if(III_dequantize_sample(fr, hybridIn[0], scalefacs[0],gr_info,sfreq,part2bits))
{
if(VERBOSE2) error("dequantization failed!");
if(NOQUIET)
error("dequantization failed!");
return clip;
}
if(fr->bits_avail < 0)
{
if(NOQUIET)
error("bit deficit after dequant");
return clip;
}
}
@ -2050,9 +2205,33 @@ int do_layer3(mpg123_handle *fr)
else
part2bits = III_get_scale_factors_1(fr, scalefacs[1],gr_info,1,gr);
if(part2bits < 0)
{
if(VERBOSE2)
error("not enough bits for scale factors");
return clip;
}
#ifndef NO_MOREINFO
if(fr->pinfo)
{
int i;
fr->pinfo->sfbits[gr][1] = part2bits;
for(i=0; i<39; ++i)
fr->pinfo->sfb_s[gr][1][i] = scalefacs[1][i];
}
#endif
if(III_dequantize_sample(fr, hybridIn[1],scalefacs[1],gr_info,sfreq,part2bits))
{
if(VERBOSE2) error("dequantization failed!");
if(NOQUIET)
error("dequantization failed!");
return clip;
}
if(fr->bits_avail < 0)
{
if(NOQUIET)
error("bit deficit after dequant");
return clip;
}
@ -2102,6 +2281,11 @@ int do_layer3(mpg123_handle *fr)
}
}
#ifndef NO_MOREINFO
if(fr->pinfo)
fill_pinfo_side(fr, &sideinfo, gr, stereo1);
#endif
for(ch=0;ch<stereo1;ch++)
{
struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);

View file

@ -1,7 +1,7 @@
/*
lfs_alias: Aliases to the small/native API functions with the size of long int as suffix.
copyright 2010-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2010-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
@ -100,6 +100,14 @@ EOT
}' < mpg123.h.in
*/
int NATIVE_NAME(mpg123_open_fixed)( mpg123_handle *mh, const char *path
, int channels, int encoding );
int attribute_align_arg ALIAS_NAME(mpg123_open_fixed)( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
return NATIVE_NAME(mpg123_open_fixed)(mh, path, channels, encoding);
}
int NATIVE_NAME(mpg123_open)(mpg123_handle *mh, const char *path);
int attribute_align_arg ALIAS_NAME(mpg123_open)(mpg123_handle *mh, const char *path)
{

View file

@ -1,7 +1,7 @@
/*
lfs_wrap: Crappy wrapper code for supporting crappy ambiguous large file support.
copyright 2010 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2010-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, thanks to Guido Draheim for consulting
@ -552,7 +552,6 @@ off_t wrap_lseek(void *handle, off_t offset, int whence)
case IO_FD: return ioh->r_lseek(ioh->fd, smalloff, whence);
case IO_HANDLE: return ioh->r_h_lseek(ioh->handle, smalloff, whence);
}
error("Serious breakage - bad IO type in LFS wrapper!");
return -1;
}
else
@ -571,6 +570,7 @@ off_t wrap_lseek(void *handle, off_t offset, int whence)
#undef mpg123_replace_reader
#undef mpg123_replace_reader_handle
#undef mpg123_open
#undef mpg123_open_fixed
#undef mpg123_open_fd
#undef mpg123_open_handle
@ -699,6 +699,19 @@ int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
else return MPG123_LARGENAME(mpg123_open)(mh, path);
}
// This one needs to follow the logic of the original, and wrap the actual
// mpg123_open() here.
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
int err = open_fixed_pre(mh, channels, encoding);
if(err == MPG123_OK)
err = mpg123_open(mh, path);
if(err == MPG123_OK)
err = open_fixed_post(mh, channels, encoding);
return err;
}
/*
This is in fact very similar to the above:
The open routines always need to watch out for a prepared wrapper handle to use replaced normal I/O.

View file

@ -1,7 +1,7 @@
/*
libmpg123: MPEG Audio Decoder library
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1995-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
@ -14,6 +14,7 @@
/* Want accurate rounding function regardless of decoder setup. */
#define FORCE_ACCURATE
#include "sample.h"
#include "parse.h"
#define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
@ -49,6 +50,7 @@ int attribute_align_arg mpg123_init(void)
void attribute_align_arg mpg123_exit(void)
{
/* nothing yet, but something later perhaps */
/* Nope. This is dead space. */
}
/* create a new handle with specified decoder, decoder can be "", "auto" or NULL for auto-detection */
@ -230,7 +232,8 @@ int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long
#ifdef FRAME_INDEX
mp->index_size = val;
#else
ret = MPG123_NO_INDEX;
if(val) // It is only an eror if you want to enable the index.
ret = MPG123_NO_INDEX;
#endif
break;
case MPG123_PREFRAMES:
@ -253,6 +256,9 @@ int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long
ret = MPG123_MISSING_FEATURE;
#endif
break;
case MPG123_FREEFORMAT_SIZE:
mp->freeformat_framesize = val;
break;
default:
ret = MPG123_BAD_PARAM;
}
@ -342,6 +348,9 @@ int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, lo
ret = MPG123_MISSING_FEATURE;
#endif
break;
case MPG123_FREEFORMAT_SIZE:
*val = mp->freeformat_framesize;
break;
default:
ret = MPG123_BAD_PARAM;
}
@ -384,6 +393,15 @@ int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key
theval = mh->state_flags & FRAME_FRESH_DECODER;
mh->state_flags &= ~FRAME_FRESH_DECODER;
break;
case MPG123_ENC_DELAY:
theval = mh->enc_delay;
break;
case MPG123_ENC_PADDING:
theval = mh->enc_padding;
break;
case MPG123_DEC_DELAY:
theval = mh->lay == 3 ? GAPLESS_DELAY : -1;
break;
default:
mh->err = MPG123_BAD_KEY;
ret = MPG123_ERR;
@ -394,6 +412,7 @@ int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key
return ret;
}
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
{
#ifndef NO_EQUALIZER
@ -444,6 +463,54 @@ int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
return open_stream(mh, path, -1);
}
// 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
// in open_fixed_pre() and open_fixed_post(), wich are only defined here.
int open_fixed_pre(mpg123_handle *mh, int channels, int encoding)
{
if(!mh)
return MPG123_BAD_HANDLE;
mh->p.flags |= MPG123_NO_FRANKENSTEIN;
int err = mpg123_format_none(mh);
if(err == MPG123_OK)
err = mpg123_format2(mh, 0, channels, encoding);
return err;
}
int open_fixed_post(mpg123_handle *mh, int channels, int encoding)
{
if(!mh)
return MPG123_BAD_HANDLE;
long rate;
int err = mpg123_getformat(mh, &rate, &channels, &encoding);
if(err == MPG123_OK)
err = mpg123_format_none(mh);
if(err == MPG123_OK)
err = mpg123_format(mh, rate, channels, encoding);
if(err == MPG123_OK)
{
if(mh->track_frames < 1 && (mh->rdat.flags & READER_SEEKABLE))
{
debug("open_fixed_post: scan because we can seek and do not know track_frames");
err = mpg123_scan(mh);
}
}
if(err != MPG123_OK)
mpg123_close(mh);
return err;
}
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
int err = open_fixed_pre(mh, channels, encoding);
if(err == MPG123_OK)
err = mpg123_open(mh, path);
if(err == MPG123_OK)
err = open_fixed_post(mh, channels, encoding);
return err;
}
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
@ -546,6 +613,8 @@ int decode_update(mpg123_handle *mh)
{
mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
mh->down_sample_sblimit /= frame_freq(mh);
if(mh->down_sample_sblimit < 1)
mh->down_sample_sblimit = 1;
}
else mh->down_sample_sblimit = SBLIMIT;
mh->outblock = outblock_bytes(mh,
@ -571,6 +640,7 @@ int decode_update(mpg123_handle *mh)
do_rva(mh);
debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);
mh->decoder_change = 0;
return 0;
}
@ -637,9 +707,9 @@ static int get_next_frame(mpg123_handle *mh)
else return MPG123_ERR; /* Some real error. */
}
/* Now, there should be new data to decode ... and also possibly new stream properties */
if(mh->header_change > 1)
if(mh->header_change > 1 || mh->decoder_change)
{
debug("big header change");
debug("big header or decoder change");
change = 1;
mh->header_change = 0;
/* Need to update decoder structure right away since frame might need to
@ -667,7 +737,6 @@ static int get_next_frame(mpg123_handle *mh)
All other situations resulted in returns from the loop. */
if(change)
{
mh->decoder_change = 0;
if(mh->fresh)
{
#ifdef GAPLESS
@ -832,20 +901,25 @@ int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsig
if(mh == NULL) return MPG123_BAD_HANDLE;
if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
mh->buffer.fill = 0; /* always start fresh */
/* Be nice: Set these also for sensible values in case of error. */
if(audio) *audio = NULL;
if(bytes) *bytes = 0;
while(TRUE)
{
/* decode if possible */
if(mh->to_decode)
{
if(num != NULL) *num = mh->num;
if(mh->new_format)
{
debug("notifiying new format");
mh->new_format = 0;
return MPG123_NEW_FORMAT;
}
if(num != NULL) *num = mh->num;
debug("decoding");
if(mh->decoder_change && decode_update(mh) < 0)
return MPG123_ERR;
decode_the_frame(mh);
mh->to_decode = mh->to_ignore = FALSE;
@ -865,7 +939,7 @@ int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsig
}
}
int attribute_align_arg mpg123_read(mpg123_handle *mh, unsigned char *out, size_t size, size_t *done)
int attribute_align_arg mpg123_read(mpg123_handle *mh, void *out, size_t size, size_t *done)
{
return mpg123_decode(mh, NULL, 0, out, size, done);
}
@ -915,14 +989,14 @@ int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in,
}
*/
int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, void *outmem, size_t outmemsize, size_t *done)
{
int ret = MPG123_OK;
size_t mdone = 0;
unsigned char *outmemory = outmem;
if(done != NULL) *done = 0;
if(mh == NULL) return MPG123_BAD_HANDLE;
#ifndef NO_FEEDER
if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK)
{
ret = MPG123_ERR;
@ -949,6 +1023,11 @@ int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *in
ret = MPG123_NO_SPACE;
goto decodeend;
}
if(mh->decoder_change && decode_update(mh) < 0)
{
ret = MPG123_ERR;
goto decodeend;
}
decode_the_frame(mh);
mh->to_decode = mh->to_ignore = FALSE;
mh->buffer.p = mh->buffer.data;
@ -977,10 +1056,6 @@ int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *in
decodeend:
if(done != NULL) *done = mdone;
return ret;
#else
mh->err = MPG123_MISSING_FEATURE;
return MPG123_ERR;
#endif
}
long attribute_align_arg mpg123_clip(mpg123_handle *mh)
@ -1031,7 +1106,7 @@ int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *
case 1: mi->mode = MPG123_M_JOINT; break;
case 2: mi->mode = MPG123_M_DUAL; break;
case 3: mi->mode = MPG123_M_MONO; break;
default: error("That mode cannot be!");
default: mi->mode = 0; // Nothing good to do here.
}
mi->mode_ext = mh->mode_ext;
mi->framesize = mh->framesize+4; /* Include header. */
@ -1462,6 +1537,23 @@ int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_
return MPG123_OK;
}
int attribute_align_arg mpg123_id3_raw( mpg123_handle *mh
, unsigned char **v1, size_t *v1_size
, unsigned char **v2, size_t *v2_size )
{
if(!mh)
return MPG123_ERR;
if(v1 != NULL)
*v1 = mh->id3buf[0] ? mh->id3buf : NULL;
if(v1_size != NULL)
*v1_size = mh->id3buf[0] ? 128 : 0;
if(v2 != NULL)
*v2 = mh->id3v2_raw;
if(v2_size != NULL)
*v2_size = mh->id3v2_size;
return MPG123_OK;
}
int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
@ -1627,6 +1719,11 @@ void attribute_align_arg mpg123_delete(mpg123_handle *mh)
}
}
void attribute_align_arg mpg123_free(void *ptr)
{
free(ptr);
}
static const char *mpg123_error[] =
{
"No error... (code 0)",

View file

@ -1,7 +1,7 @@
/*
parse: spawned from common; clustering around stream/frame parsing
copyright ?-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp & Thomas Orgis
*/
@ -11,13 +11,19 @@
#include <sys/stat.h>
#include <fcntl.h>
#ifndef __REACTOS__
#include "getbits.h"
#endif
#if defined (WANT_WIN32_SOCKETS)
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#ifdef __REACTOS__
#include "getbits.h"
#endif
/* a limit for number of frames in a track; beyond that unsigned long may not be enough to hold byte addresses */
#ifdef HAVE_LIMITS_H
#include <limits.h>
@ -408,6 +414,9 @@ static int check_lame_tag(mpg123_handle *fr)
lame_offset += 3; /* 24 in */
if(VERBOSE3) fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n"
, (int)pad_in, (int)pad_out);
/* Store even if libmpg123 does not do gapless decoding itself. */
fr->enc_delay = (int)pad_in;
fr->enc_padding = (int)pad_out;
#ifdef GAPLESS
if(fr->p.flags & MPG123_GAPLESS)
frame_gapless_init(fr, fr->track_frames, pad_in, pad_out);
@ -458,8 +467,7 @@ static int halfspeed_do(mpg123_handle *fr)
debug("repeat!");
fr->to_decode = fr->to_ignore = TRUE;
--fr->halfphase;
fr->bitindex = 0;
fr->wordpointer = (unsigned char *) fr->bsbuf;
set_pointer(fr, 0, 0);
if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize);
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
return 1;
@ -511,6 +519,20 @@ int read_frame(mpg123_handle *fr)
/* From now on, old frame data is tainted by parsing attempts. */
fr->to_decode = fr->to_ignore = FALSE;
if( fr->p.flags & MPG123_NO_FRANKENSTEIN &&
( (fr->track_frames > 0 && fr->num >= fr->track_frames-1)
#ifdef GAPLESS
|| (fr->gapless_frames > 0 && fr->num >= fr->gapless_frames-1)
#endif
) )
{
mdebug( "stopping parsing at %"OFF_P
" frames as indicated fixed track length"
, (off_p)fr->num+1 );
return 0;
}
read_again:
/* In case we are looping to find a valid frame, discard any buffered data before the current position.
This is essential to prevent endless looping, always going back to the beginning when feeder buffer is exhausted. */
@ -543,7 +565,9 @@ init_resync:
if(!fr->firsthead)
{
ret = do_readahead(fr, newhead);
ret = fr->p.flags & MPG123_NO_READAHEAD
? PARSE_GOOD
: do_readahead(fr, newhead);
/* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */
if(ret < 0) fr->rd->back_bytes(fr, 4);
JUMP_CONCLUSION(ret);
@ -551,16 +575,27 @@ init_resync:
/* Now we should have our valid header and proceed to reading the frame. */
if(fr->p.flags & MPG123_NO_FRANKENSTEIN)
{
if(fr->firsthead && !head_compatible(fr->firsthead, newhead))
{
mdebug( "stopping before reading frame %"OFF_P
" as its header indicates Frankenstein coming for you", (off_p)fr->num );
return 0;
}
}
/* if filepos is invalid, so is framepos */
framepos = fr->rd->tell(fr) - 4;
/* flip/init buffer for Layer 3 */
{
unsigned char *newbuf = fr->bsspace[fr->bsnum]+512;
/* read main data into memory */
debug2("read frame body of %i at %"OFF_P, fr->framesize, framepos+4);
if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0)
{
/* if failed: flip back */
debug("need more?");
debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error");
goto read_frame_bad;
}
fr->bsbufold = fr->bsbuf;
@ -593,8 +628,8 @@ init_resync:
debug2("fr->firsthead: %08lx, audio_start: %li", fr->firsthead, (long int)fr->audio_start);
}
fr->bitindex = 0;
fr->wordpointer = (unsigned char *) fr->bsbuf;
set_pointer(fr, 0, 0);
/* Question: How bad does the floating point value get with repeated recomputation?
Also, considering that we can play the file or parts of many times. */
if(++fr->mean_frames != 0)
@ -787,6 +822,12 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
if(fr->freeformat_framesize < 0)
{
int ret;
if(fr->p.flags & MPG123_NO_READAHEAD)
{
if(VERBOSE3)
error("Got no free-format frame size and am not allowed to read ahead.");
return PARSE_BAD;
}
*freeformat_count += 1;
if(*freeformat_count > 5)
{
@ -825,9 +866,10 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
fr->do_layer = do_layer1;
if(!fr->freeformat)
{
fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
fr->framesize /= freqs[fr->sampling_frequency];
fr->framesize = ((fr->framesize+fr->padding)<<2)-4;
long fs = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
fs /= freqs[fr->sampling_frequency];
fs = ((fs+fr->padding)<<2)-4;
fr->framesize = (int)fs;
}
break;
#endif
@ -838,9 +880,10 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
if(!fr->freeformat)
{
debug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] );
fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
fr->framesize /= freqs[fr->sampling_frequency];
fr->framesize += fr->padding - 4;
long fs = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
fs /= freqs[fr->sampling_frequency];
fs += fr->padding - 4;
fr->framesize = (int)fs;
}
break;
#endif
@ -858,9 +901,17 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
if(!fr->freeformat)
{
fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
fr->framesize = fr->framesize + fr->padding - 4;
long fs = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
fs /= freqs[fr->sampling_frequency]<<(fr->lsf);
fs += fr->padding - 4;
fr->framesize = fs;
}
if(fr->framesize < fr->ssize)
{
if(NOQUIET)
error2( "Frame smaller than mandatory side info (%i < %i)!"
, fr->framesize, fr->ssize );
return PARSE_BAD;
}
break;
#endif
@ -878,13 +929,38 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
return PARSE_GOOD;
}
void set_pointer(mpg123_handle *fr, long backstep)
{
fr->wordpointer = fr->bsbuf + fr->ssize - backstep;
if (backstep)
memcpy(fr->wordpointer,fr->bsbufold+fr->fsizeold-backstep,backstep);
/* Prepare for bit reading. Two stages:
0. Layers 1 and 2, side info for layer 3
1. Second call for possible bit reservoir for layer 3 part 2,3.
This overwrites side info needed for stage 0.
fr->bitindex = 0;
Continuing to read bits after layer 3 side info shall fail unless
set_pointer() is called to refresh things.
*/
void set_pointer(mpg123_handle *fr, int part2, long backstep)
{
fr->bitindex = 0;
if(fr->lay == 3)
{
if(part2)
{
fr->wordpointer = fr->bsbuf + fr->ssize - backstep;
if(backstep)
memcpy( fr->wordpointer, fr->bsbufold+fr->fsizeold-backstep
, backstep );
fr->bits_avail = (long)(fr->framesize - fr->ssize + backstep)*8;
}
else
{
fr->wordpointer = fr->bsbuf;
fr->bits_avail = fr->ssize*8;
}
}
else
{
fr->wordpointer = fr->bsbuf;
fr->bits_avail = fr->framesize*8;
}
}
/********************************/
@ -1204,7 +1280,8 @@ static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount
if(limit >= 0 && *headcount >= limit)
{
if(NOQUIET) error1("Giving up searching valid MPEG header after %li bytes of junk.", *headcount);
return PARSE_END;
fr->err = MPG123_RESYNC_FAIL;
return PARSE_ERR;
}
else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr));

View file

@ -1,9 +1,10 @@
/* TODO: Check all read calls (in loops, especially!) for return value 0 (EOF)! */
/* Check if get_fileinfo should read ID3 info or not, seems a bit out of place here. */
/* #define EXTRA_DEBUG */
/*
readers.c: reading input data
copyright ?-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2020 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
@ -383,18 +384,12 @@ static int stream_back_bytes(mpg123_handle *fr, off_t bytes)
}
/* returns size on success... */
/* returns size on success... otherwise an error code < 0 */
static int generic_read_frame_body(mpg123_handle *fr,unsigned char *buf, int size)
{
long l;
if((l=fr->rd->fullread(fr,buf,size)) != size)
{
long ll = l;
if(ll <= 0) ll = 0;
return READER_MORE;
}
return l;
l=fr->rd->fullread(fr,buf,size);
return (l >= 0 && l<size) ? READER_ERROR : l;
}
static off_t generic_tell(mpg123_handle *fr)
@ -436,18 +431,35 @@ static off_t get_fileinfo(mpg123_handle *fr)
{
off_t len;
if((len=io_seek(&fr->rdat,0,SEEK_END)) < 0) return -1;
if((len=io_seek(&fr->rdat,0,SEEK_END)) < 0)
{
debug("cannot seek to end");
return -1;
} else if(len >= 128)
{
if(io_seek(&fr->rdat,-128,SEEK_END) < 0)
{
debug("cannot seek to END-128");
return -1;
}
if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128)
{
debug("cannot read ID3v1?!");
return -1;
}
if(!strncmp((char*)fr->id3buf,"TAG",3)) len -= 128;
} else
{
debug("stream too short for ID3");
}
if(io_seek(&fr->rdat,-128,SEEK_END) < 0) return -1;
if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128) return -1;
if(!strncmp((char*)fr->id3buf,"TAG",3)) len -= 128;
if(io_seek(&fr->rdat,0,SEEK_SET) < 0) return -1;
if(len <= 0) return -1;
if(io_seek(&fr->rdat,0,SEEK_SET) < 0)
{
debug("cannot seek back");
return -1;
}
debug1("returning length: %"OFF_P, (off_p)len);
return len;
}
@ -831,6 +843,8 @@ static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t
{
struct bufferchain *bc = &fr->rdat.buffer;
ssize_t gotcount;
if(VERBOSE3)
mdebug("buffered_fullread: want %zd", count);
if(bc->size - bc->pos < count)
{ /* Add more stuff to buffer. If hitting end of file, adjust count. */
unsigned char readbuf[4096];
@ -863,9 +877,8 @@ static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t
count = bc->size - bc->pos; /* We want only what we got. */
}
gotcount = bc_give(bc, out, count);
if(VERBOSE3) debug2("wanted %li, got %li", (long)count, (long)gotcount);
if(VERBOSE3)
mdebug("buffered_fullread: got %zd", gotcount);
if(gotcount != count){ if(NOQUIET) error("gotcount != count"); return READER_ERROR; }
else return gotcount;
}
@ -1028,7 +1041,9 @@ static int default_init(mpg123_handle *fr)
int flags;
if(fr->rdat.r_read != NULL)
{
error("Timeout reading does not work with user-provided read function. Implement it yourself!");
if(NOQUIET)
error( "Timeout reading does not work with user-provided"
" read function. Implement it yourself!" );
return -1;
}
flags = fcntl(fr->rdat.filept, F_GETFL);
@ -1060,6 +1075,7 @@ static int default_init(mpg123_handle *fr)
*/
if(fr->rdat.filelen >= 0)
{
debug("seekable stream");
fr->rdat.flags |= READER_SEEKABLE;
if(!strncmp((char*)fr->id3buf,"TAG",3))
{
@ -1071,18 +1087,21 @@ static int default_init(mpg123_handle *fr)
else if(fr->p.flags & MPG123_SEEKBUFFER)
{
#ifdef NO_FEEDER
error("Buffered readers not supported in this build.");
if(NOQUIET)
error("Buffered readers not supported in this build.");
fr->err = MPG123_MISSING_FEATURE;
return -1;
#else
if (fr->rd == &readers[READER_STREAM])
{
debug("switching to buffered stream reader");
fr->rd = &readers[READER_BUF_STREAM];
fr->rdat.fullread = plain_fullread;
}
#ifndef NO_ICY
else if(fr->rd == &readers[READER_ICY_STREAM])
{
debug("switching to buffered ICY stream reader");
fr->rd = &readers[READER_BUF_ICY_STREAM];
fr->rdat.fullread = icy_fullread;
}
@ -1095,7 +1114,7 @@ static int default_init(mpg123_handle *fr)
bc_init(&fr->rdat.buffer);
fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
fr->rdat.flags |= READER_BUFFERED;
#endif /* NO_FEEDER */
#endif /* NO_ICY */
}
return 0;
}
@ -1119,7 +1138,8 @@ int open_feed(mpg123_handle *fr)
{
debug("feed reader");
#ifdef NO_FEEDER
error("Buffered readers not supported in this build.");
if(NOQUIET)
error("Buffered readers not supported in this build.");
fr->err = MPG123_MISSING_FEATURE;
return -1;
#else

View file

@ -1,7 +1,7 @@
/*
stringbuf: mimicking a bit of C++ to more safely handle strings
copyright 2006-17 by the mpg123 project
copyright 2006-20 by the mpg123 project
- free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
@ -14,6 +14,24 @@
#include <string.h>
#include "debug.h"
mpg123_string* attribute_align_arg mpg123_new_string(const char *val)
{
mpg123_string *sb = malloc(sizeof(mpg123_string));
if(!sb)
return NULL;
mpg123_init_string(sb);
mpg123_set_string(sb, val);
return sb;
}
void attribute_align_arg mpg123_delete_string(mpg123_string* sb)
{
if(!sb)
return;
mpg123_free_string(sb);
free(sb);
}
void attribute_align_arg mpg123_init_string(mpg123_string* sb)
{
/* Handing in NULL here is a fatal mistake and rightfully so. */
@ -59,6 +77,12 @@ int attribute_align_arg mpg123_resize_string(mpg123_string* sb, size_t new)
{
sb->p = t;
sb->size = new;
if(sb->size < sb->fill)
{
// Cut short the existing data, properly.
sb->fill = sb->size;
sb->p[sb->fill-1] = 0;
}
return 1;
}
else return 0;
@ -95,6 +119,19 @@ int attribute_align_arg mpg123_copy_string(mpg123_string* from, mpg123_string* t
else return 0;
}
int attribute_align_arg mpg123_move_string(mpg123_string *from, mpg123_string *to)
{
if(to)
mpg123_free_string(to);
else
mpg123_free_string(from);
if(from && to)
*to = *from;
if(from)
mpg123_init_string(from);
return (from && to) ? 1 : 0;
}
int attribute_align_arg mpg123_add_string(mpg123_string* sb, const char* stuff)
{
debug1("adding %s", stuff);
@ -200,3 +237,14 @@ int attribute_align_arg mpg123_chomp_string(mpg123_string *sb)
return 1;
}
int attribute_align_arg mpg123_same_string(mpg123_string *a, mpg123_string *b)
{
if(!a || !b)
return 0;
if(a->fill != b->fill)
return 0;
if(memcmp(a->p, b->p, a->fill))
return 0;
return 1;
}