/*
- mpg123lib_intern: Common non-public stuff for libmpg123
+ abi_align: An attempt to avoid breakage because of mixing
+ compilers with different alignment.
- copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
+ copyright 1995-2015 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
- derived from the old mpg123.h
+ There used to be code that checks alignment, but it did not really
+ work anyway. The only straw we have is putting that alignment
+ attribute to API functions.
*/
#ifndef MPG123_H_ABI_ALIGN
#include "config.h"
/* ABI conformance for other compilers.
- mpg123 needs 16byte-aligned stack for SSE and friends.
+ mpg123 needs 16byte-aligned (or more) stack for SSE and friends.
gcc provides that, but others don't necessarily. */
#ifdef ABI_ALIGN_FUN
+
#ifndef attribute_align_arg
+
#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
# define attribute_align_arg __attribute__((force_align_arg_pointer))
/* The gcc that can align the stack does not need the check... nor does it work with gcc 4.3+, anyway. */
#else
-
# define attribute_align_arg
-/* Other compilers get code to catch misaligned stack.
- Well, except Sun Studio, which accepts the aligned attribute but does not honor it. */
-#if !defined(__SUNPRO_C)
-# define NEED_ALIGNCHECK
#endif
-#endif
-#endif
-#else
+#endif /* attribute_align_arg */
+
+#else /* ABI_ALIGN_FUN */
+
#define attribute_align_arg
-/* We won't try the align check... */
-#endif
-#endif
+#endif /* ABI_ALIGN_FUN */
+
+#endif /* MPG123_H_ABI_ALIGN */
#define MPG123_COMPAT_H
#include "config.h"
-#include "intsym.h"
+
+/* Needed for strdup(), in strict mode ... */
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <errno.h>
#ifdef HAVE_STDLIB_H
/* realloc, size_t */
#ifdef HAVE_STRING_H
#include <string.h>
#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
#ifdef OS2
#include <float.h>
typedef unsigned char byte;
+#ifdef _MSC_VER
+typedef long ssize_t;
+#endif
+
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size);
#ifndef HAVE_STRERROR
* @return file descriptor (>=0) or error code.
*/
int compat_open(const char *filename, int flags);
+FILE* compat_fopen(const char *filename, const char *mode);
/**
* Closing a file handle can be platform specific.
* @return 0 if the file was successfully closed. A return value of -1 indicates an error.
*/
int compat_close(int infd);
+int compat_fclose(FILE* stream);
/* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
#endif
+/* Blocking write/read of data with signal resilience.
+ Both 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);
+
/* That one comes from Tellie on OS/2, needed in resolver. */
#ifdef __KLIBC__
typedef int socklen_t;
#include "true.h"
+#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
+void (*catchsignal(int signum, void(*handler)()))();
+#endif
+
#endif
/* Define to use proper rounding. */
/* #undef ACCURATE_ROUNDING */
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define if .balign is present. */
+#define ASMALIGN_BALIGN 1
+
+/* Define if .align just takes byte count. */
+/* #undef ASMALIGN_BYTE */
+
/* Define if .align takes 3 for alignment of 2^3=8 bytes instead of 8. */
/* #undef ASMALIGN_EXP */
functions. */
#define LFS_ALIAS_BITS 32
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
+/* The suffix for module files. */
+#define MODULE_FILE_SUFFIX ".la"
+
/* Define if network support is enabled. */
#define NETWORK 1
/* Define to disable downsampled decoding. */
/* #undef NO_DOWNSAMPLE */
+/* Define to disable equalizer. */
+/* #undef NO_EQUALIZER */
+
/* Define to disable error messages in combination with a return value (the
return is left intact). */
/* #undef NO_ERETURN */
#define PACKAGE "mpg123"
/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "mpg123-devel@lists.sourceforge.net"
+#define PACKAGE_BUGREPORT "maintainer@mpg123.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "mpg123"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "mpg123 1.22.1"
+#define PACKAGE_STRING "mpg123 1.23.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mpg123"
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.22.1"
+#define PACKAGE_VERSION "1.23.0"
/* Define if portaudio v18 API is wanted. */
/* #undef PORTAUDIO18 */
/* #undef USE_YASM_FOR_AVX */
/* Version number of package */
-#define VERSION "1.22.1"
+#define VERSION "1.23.0"
/* Define to use Win32 named pipes */
#define WANT_WIN32_FIFO 1
/* Define to use Unicode for Windows */
#define WANT_WIN32_UNICODE 1
+/* WinXP and above for ipv6 */
+/* #undef WINVER */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
+/* WinXP and above for ipv6 */
+/* #undef _WIN32_WINNT */
+
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef int32_t */
+/* Define to `long long' if <sys/types.h> does not define. */
+/* #undef int64_t */
+
+/* Define to the native offset type (long or actually off_t). */
+#define lfs_alias_t long
+
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* #undef size_t */
/* Define to `long' if <sys/types.h> does not define. */
-#define ssize_t long
+/* #undef ssize_t */
/* Define to `unsigned short' if <sys/types.h> does not define. */
/* #undef uint16_t */
It's cumbersome to have them all with different names, though...
*/
+#ifdef ME
+#define DBGPRFX ME": "
+#else
+#define DBGPRFX ""
+#endif
+
#ifdef DEBUG
+
#include <stdio.h>
-#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__)
-#define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a)
-#define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b)
-#define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c)
-#define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d)
-#define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e)
-#define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f)
-#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g)
-#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
-#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
-#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
-#define debug11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
-#define debug12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
-#define debug13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
-#define debug14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, "[" __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, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#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)
+#define debug3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c)
+#define debug4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d)
+#define debug5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e)
+#define debug6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f)
+#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g)
+#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
+#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
+#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
+#define debug11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
+#define debug12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
+#define debug13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#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 debug(s)
#define debug1(s, a)
/* warning macros also here... */
#ifndef NO_WARNING
-#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__)
-#define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a)
-#define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b)
-#define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c)
-#define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d)
-#define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e)
-#define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f)
-#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g)
-#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
-#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
-#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
-#define warning11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
-#define warning12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
-#define warning13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
-#define warning14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, "[" __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, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#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)
+#define warning3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c)
+#define warning4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d)
+#define warning5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e)
+#define warning6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f)
+#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g)
+#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
+#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
+#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
+#define warning11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
+#define warning12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
+#define warning13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#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 warning(s)
#define warning1(s, a)
#endif
/* error macros also here... */
-#ifndef NO_ERRORMSG
-#define error(s) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__)
-#define error1(s, a) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
-#define error2(s, a, b) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)
-#define error3(s, a, b, c) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c)
-#define error4(s, a, b, c, d) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d)
-#define error5(s, a, b, c, d, e) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e)
-#define error6(s, a, b, c, d, e, f) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f)
-#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g)
-#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
-#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
-#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
-#define error11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
-#define error12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
-#define error13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
-#define error14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, "\n[" __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, "\n[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
+#ifndef NO_ERROR
+#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)
+#define error3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c)
+#define error4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d)
+#define error5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e)
+#define error6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f)
+#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g)
+#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
+#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
+#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
+#define error11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
+#define error12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
+#define error13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
+#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 error(s)
#define error1(s, a)
/* ereturn macros also here... */
#ifndef NO_ERETURN
-#define ereturn(rv, s) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__); return rv; }while(0)
-#define ereturn1(rv, s, a) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a); return rv; }while(0)
-#define ereturn2(rv, s, a, b) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b); return rv; }while(0)
-#define ereturn3(rv, s, a, b, c) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c); return rv; }while(0)
-#define ereturn4(rv, s, a, b, c, d) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d); return rv; }while(0)
-#define ereturn5(rv, s, a, b, c, d, e) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e); return rv; }while(0)
-#define ereturn6(rv, s, a, b, c, d, e, f) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f); return rv; }while(0)
-#define ereturn7(rv, s, a, b, c, d, e, f, g) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g); return rv; }while(0)
-#define ereturn8(rv, s, a, b, c, d, e, f, g, h) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h); return rv; }while(0)
-#define ereturn9(rv, s, a, b, c, d, e, f, g, h, i) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); return rv; }while(0)
-#define ereturn10(rv, s, a, b, c, d, e, f, g, h, i, j) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); return rv; }while(0)
-#define ereturn11(rv, s, a, b, c, d, e, f, g, h, i, j, k) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k); return rv; }while(0)
-#define ereturn12(rv, s, a, b, c, d, e, f, g, h, i, j, k, l) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l); return rv; }while(0)
-#define ereturn13(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m) do{ fprintf(stderr, "\n[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m); return rv; }while(0)
-#define ereturn14(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) do{ fprintf(stderr, "\n[" __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, "\n[" __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)
+#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)
+#define ereturn3(rv, s, a, b, c) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c); return rv; }while(0)
+#define ereturn4(rv, s, a, b, c, d) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d); return rv; }while(0)
+#define ereturn5(rv, s, a, b, c, d, e) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e); return rv; }while(0)
+#define ereturn6(rv, s, a, b, c, d, e, f) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f); return rv; }while(0)
+#define ereturn7(rv, s, a, b, c, d, e, f, g) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g); return rv; }while(0)
+#define ereturn8(rv, s, a, b, c, d, e, f, g, h) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h); return rv; }while(0)
+#define ereturn9(rv, s, a, b, c, d, e, f, g, h, i) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); return rv; }while(0)
+#define ereturn10(rv, s, a, b, c, d, e, f, g, h, i, j) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); return rv; }while(0)
+#define ereturn11(rv, s, a, b, c, d, e, f, g, h, i, j, k) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k); return rv; }while(0)
+#define ereturn12(rv, s, a, b, c, d, e, f, g, h, i, j, k, l) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l); return rv; }while(0)
+#define ereturn13(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m); return rv; }while(0)
+#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 ereturn(rv, s) return rv
#define ereturn1(rv, s, a) return rv
int synth_1to1_real_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_real_avx (real*, int, mpg123_handle*, int);
-int synth_1to1_real_stereo_avx (real*, real*, mpg123_handle*);
+int synth_1to1_fltst_avx (real*, real*, mpg123_handle*);
int synth_1to1_real_altivec (real*, int, mpg123_handle*, int);
-int synth_1to1_real_stereo_altivec(real*, real*, mpg123_handle*);
+int synth_1to1_fltst_altivec(real*, real*, mpg123_handle*);
int synth_1to1_real_neon (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_real_neon64 (real*, int, mpg123_handle*, int);
-int synth_1to1_real_stereo_neon64(real*, real*, mpg123_handle*);
+int synth_1to1_fltst_neon64(real*, real*, mpg123_handle*);
int synth_1to1_real_mono (real*, mpg123_handle*);
int synth_1to1_real_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
int synth_1to1_s32_neon (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_s32_neon64 (real*, int, mpg123_handle*, int);
-int synth_1to1_s32_stereo_neon64(real*, real*, mpg123_handle*);
+int synth_1to1_s32st_neon64(real*, real*, mpg123_handle*);
int synth_1to1_s32_mono (real*, mpg123_handle*);
int synth_1to1_s32_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
--- /dev/null
+/*
+ dither: Generate shaped noise for dithering
+
+ copyright 2009 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 Taihei Monma
+*/
+
+#include "config.h"
+#include "compat.h"
+#include "dither.h"
+
+static const uint32_t init_seed = 2463534242UL;
+
+#define LAP 100
+
+/*
+ xorshift random number generator, with output scaling to [-0.5, 0.5]
+ This is the white noise...
+ See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
+*/
+static float rand_xorshift32(uint32_t *seed)
+{
+ union
+ {
+ uint32_t i;
+ float f;
+ } fi;
+
+ fi.i = *seed;
+ fi.i ^= (fi.i<<13);
+ fi.i ^= (fi.i>>17);
+ fi.i ^= (fi.i<<5);
+ *seed = fi.i;
+
+ /* scale the number to [-0.5, 0.5] */
+#ifdef IEEE_FLOAT
+ fi.i = (fi.i>>9)|0x3f800000;
+ fi.f -= 1.5f;
+#else
+ fi.f = (double)fi.i / 4294967295.0;
+ fi.f -= 0.5f;
+#endif
+ return fi.f;
+}
+
+static void white_noise(float *table, size_t count)
+{
+ size_t i;
+ uint32_t seed = init_seed;
+
+ for(i=0; i<count; ++i)
+ table[i] = rand_xorshift32(&seed);
+}
+
+static void tpdf_noise(float *table, size_t count)
+{
+ size_t i;
+ uint32_t seed = init_seed;
+
+ for(i=0; i<count; ++i)
+ table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
+}
+
+static void highpass_tpdf_noise(float *table, size_t count)
+{
+ size_t i;
+ uint32_t seed = init_seed;
+ /* Ensure some minimum lap for keeping the high-pass filter circular. */
+ size_t lap = count > 2*LAP ? LAP : count/2;
+
+ float input_noise;
+ float xv[9], yv[9];
+
+ for(i=0;i<9;i++)
+ {
+ xv[i] = yv[i] = 0.0f;
+ }
+
+ for(i=0;i<count+lap;i++)
+ {
+ if(i==count) seed=init_seed;
+
+ /* generate and add 2 random numbers, to make a TPDF noise distribution */
+ input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
+
+ /* apply 8th order Chebyshev high-pass IIR filter */
+ /* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
+ Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
+ xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8];
+ xv[8] = input_noise / 1.382814179e+07;
+ yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8];
+ yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
+ - 56 * (xv[3] + xv[5]) + 70 * xv[4]
+ + ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
+ + (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
+ + (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
+ + (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
+ if(i>=lap) table[i-lap] = yv[8] * 3.0f;
+ }
+}
+
+void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
+{
+ switch(noisetype)
+ {
+ case mpg123_white_noise: white_noise(table, count); break;
+ case mpg123_tpdf_noise: tpdf_noise(table, count); break;
+ case mpg123_highpass_tpdf_noise:
+ highpass_tpdf_noise(table, count);
+ break;
+ }
+}
+
+/* Generate white noise and shape it with a high pass filter. */
+void dither_table_init(float *dithertable)
+{
+ highpass_tpdf_noise(dithertable, DITHERSIZE);
+}
--- /dev/null
+/*
+ libmpg123: MPEG Audio Decoder library
+
+ separate header just for audio format definitions not tied to
+ library code
+
+ copyright 1995-2015 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
+*/
+
+#ifndef MPG123_ENC_H
+#define MPG123_ENC_H
+
+/** \file fmt123.h Audio format definitions. */
+
+/** \defgroup mpg123_enc mpg123 PCM sample encodings
+ * These are definitions for audio formats used by libmpg123 and
+ * libout123.
+ *
+ * @{
+ */
+
+/** An enum over all sample types possibly known to mpg123.
+ * The values are designed as bit flags to allow bitmasking for encoding
+ * families.
+ * This is also why the enum is not used as type for actual encoding variables,
+ * plain integers (at least 16 bit, 15 bit being used) cover the possible
+ * combinations of these flags.
+ *
+ * Note that (your build of) libmpg123 does not necessarily support all these.
+ * Usually, you can expect the 8bit encodings and signed 16 bit.
+ * Also 32bit float will be usual beginning with mpg123-1.7.0 .
+ * What you should bear in mind is that (SSE, etc) optimized routines may be
+ * absent for some formats. We do have SSE for 16, 32 bit and float, though.
+ * 24 bit integer is done via postprocessing of 32 bit output -- just cutting
+ * the last byte, no rounding, even. If you want better, do it yourself.
+ *
+ * All formats are in native byte order. If you need different endinaness, you
+ * can simply postprocess the output buffers (libmpg123 wouldn't do anything
+ * else). The macro MPG123_SAMPLESIZE() can be helpful there.
+ */
+enum mpg123_enc_enum
+{
+/* 0000 0000 0000 1111 Some 8 bit integer encoding. */
+ MPG123_ENC_8 = 0x00f
+/* 0000 0000 0100 0000 Some 16 bit integer encoding. */
+, MPG123_ENC_16 = 0x040
+/* 0100 0000 0000 0000 Some 24 bit integer encoding. */
+, MPG123_ENC_24 = 0x4000
+/* 0000 0001 0000 0000 Some 32 bit integer encoding. */
+, MPG123_ENC_32 = 0x100
+/* 0000 0000 1000 0000 Some signed integer encoding. */
+, MPG123_ENC_SIGNED = 0x080
+/* 0000 1110 0000 0000 Some float encoding. */
+, MPG123_ENC_FLOAT = 0xe00
+/* 0000 0000 1101 0000 signed 16 bit */
+, MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10)
+/* 0000 0000 0110 0000 unsigned 16 bit */
+, MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20)
+/* 0000 0000 0000 0001 unsigned 8 bit */
+, MPG123_ENC_UNSIGNED_8 = 0x01
+/* 0000 0000 1000 0010 signed 8 bit */
+, MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED|0x02)
+/* 0000 0000 0000 0100 ulaw 8 bit */
+, MPG123_ENC_ULAW_8 = 0x04
+/* 0000 0000 0000 1000 alaw 8 bit */
+, MPG123_ENC_ALAW_8 = 0x08
+/* 0001 0001 1000 0000 signed 32 bit */
+, MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000
+/* 0010 0001 0000 0000 unsigned 32 bit */
+, MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000
+/* 0101 0000 1000 0000 signed 24 bit */
+, MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000
+/* 0110 0000 0000 0000 unsigned 24 bit */
+, MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000
+/* 0000 0010 0000 0000 32bit float */
+, MPG123_ENC_FLOAT_32 = 0x200
+/* 0000 0100 0000 0000 64bit float */
+, MPG123_ENC_FLOAT_64 = 0x400
+/* Any possibly known encoding from the list above. */
+, MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16
+ | MPG123_ENC_UNSIGNED_8 | MPG123_ENC_SIGNED_8
+ | MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
+ | MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
+ | MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
+ | MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 )
+};
+
+/** Get size of one PCM sample with given encoding.
+ * This is included both in libmpg123 and libout123. Both offer
+ * an API function to provide the macro results from library
+ * compile-time, not that of you application. This most likely
+ * does not matter as I do not expect any fresh PCM sample
+ * encoding to appear. But who knows? Perhaps the encoding type
+ * will be abused for funny things in future, not even plain PCM.
+ * And, by the way: Thomas really likes the ?: operator.
+ * \param enc the encoding (mpg123_enc_enum value)
+ * \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 \
+) ) ) ) )
+
+/** Structure defining an audio format.
+ * Providing the members as individual function arguments to define a certain
+ * output format is easy enough. This struct makes is more comfortable to deal
+ * with a list of formats.
+ * Negative values for the members might be used to communicate use of default
+ * values.
+ */
+struct mpg123_fmt
+{
+ long rate; /**< sampling rate in Hz */
+ int channels; /**< channel count */
+ /** encoding code, can be single value or bitwise or of members of
+ * mpg123_enc_enum */
+ int encoding;
+};
+
+/* @} */
+
+#endif
+
float *decwin_mmx;
float *decwins;
#endif
+#ifndef NO_EQUALIZER
int have_eq_settings;
real equalizer[2][32];
-
+#endif
/* for halfspeed mode */
unsigned char ssave[34];
int halfphase;
-#ifndef MPG123_INTMAP_H
-#define MPG123_INTMAP_H
-/* Mapping of internal mpg123 symbols to something that is less likely to conflict in case of static linking. */
+#ifndef MPG123_INTSYM_H
+#define MPG123_INTSYM_H
+/* Mapping of internal mpg123 symbols to something that is less likely to
+ conflict in case of static linking. */
+#include "config.h"
#define COS9 INT123_COS9
#define tfcos36 INT123_tfcos36
#define pnts INT123_pnts
#define safe_realloc INT123_safe_realloc
#define compat_open INT123_compat_open
+#define compat_fopen INT123_compat_fopen
#define compat_close INT123_compat_close
+#define compat_fclose INT123_compat_fclose
#define win32_wide_utf8 INT123_win32_wide_utf8
#define win32_utf8_wide INT123_win32_utf8_wide
+#define unintr_write INT123_unintr_write
+#define unintr_read INT123_unintr_read
#define ntom_set_ntom INT123_ntom_set_ntom
#define synth_1to1 INT123_synth_1to1
#define synth_1to1_dither INT123_synth_1to1_dither
#define synth_1to1_arm INT123_synth_1to1_arm
#define synth_1to1_neon INT123_synth_1to1_neon
#define synth_1to1_stereo_neon INT123_synth_1to1_stereo_neon
+#define synth_1to1_neon64 INT123_synth_1to1_neon64
+#define synth_1to1_stereo_neon64 INT123_synth_1to1_stereo_neon64
#define absynth_1to1_i486 INT123_absynth_1to1_i486
#define synth_1to1_mono INT123_synth_1to1_mono
#define synth_1to1_m2s INT123_synth_1to1_m2s
#define synth_1to1_real_x86_64 INT123_synth_1to1_real_x86_64
#define synth_1to1_real_stereo_x86_64 INT123_synth_1to1_real_stereo_x86_64
#define synth_1to1_real_avx INT123_synth_1to1_real_avx
-#define synth_1to1_real_stereo_avx INT123_synth_1to1_real_stereo_avx
+#define synth_1to1_fltst_avx INT123_synth_1to1_fltst_avx
#define synth_1to1_real_altivec INT123_synth_1to1_real_altivec
-#define synth_1to1_real_stereo_altivec INT123_synth_1to1_real_stereo_altivec
+#define synth_1to1_fltst_altivec INT123_synth_1to1_fltst_altivec
#define synth_1to1_real_neon INT123_synth_1to1_real_neon
#define synth_1to1_real_stereo_neon INT123_synth_1to1_real_stereo_neon
+#define synth_1to1_real_neon64 INT123_synth_1to1_real_neon64
+#define synth_1to1_fltst_neon64 INT123_synth_1to1_fltst_neon64
#define synth_1to1_real_mono INT123_synth_1to1_real_mono
#define synth_1to1_real_m2s INT123_synth_1to1_real_m2s
#define synth_2to1_real INT123_synth_2to1_real
#define synth_1to1_s32_stereo_altivec INT123_synth_1to1_s32_stereo_altivec
#define synth_1to1_s32_neon INT123_synth_1to1_s32_neon
#define synth_1to1_s32_stereo_neon INT123_synth_1to1_s32_stereo_neon
+#define synth_1to1_s32_neon64 INT123_synth_1to1_s32_neon64
+#define synth_1to1_s32st_neon64 INT123_synth_1to1_s32st_neon64
#define synth_1to1_s32_mono INT123_synth_1to1_s32_mono
#define synth_1to1_s32_m2s INT123_synth_1to1_s32_m2s
#define synth_2to1_s32 INT123_synth_2to1_s32
#define dct36 INT123_dct36
#define dct36_3dnow INT123_dct36_3dnow
#define dct36_3dnowext INT123_dct36_3dnowext
-#define dct36_sse INT123_dct36_sse
#define dct36_x86_64 INT123_dct36_x86_64
+#define dct36_sse INT123_dct36_sse
#define dct36_avx INT123_dct36_avx
#define dct36_neon INT123_dct36_neon
#define dct36_neon64 INT123_dct36_neon64
#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 frame_cpu_opt INT123_frame_cpu_opt
#define set_synth_functions INT123_set_synth_functions
#define dectype INT123_dectype
#define compute_bpf INT123_compute_bpf
#define time_to_frame INT123_time_to_frame
#define get_songlen INT123_get_songlen
+#define bc_prepare INT123_bc_prepare
+#define bc_cleanup INT123_bc_cleanup
+#define bc_poolsize INT123_bc_poolsize
+#define bc_fill INT123_bc_fill
#define open_stream INT123_open_stream
#define open_stream_handle INT123_open_stream_handle
#define open_feed INT123_open_feed
#define feed_forget INT123_feed_forget
#define feed_set_pos INT123_feed_set_pos
#define open_bad INT123_open_bad
+#define check_neon INT123_check_neon
#define dct64_3dnow INT123_dct64_3dnow
#define dct64_3dnowext INT123_dct64_3dnowext
+#define dct64_avx INT123_dct64_avx
+#define dct64_real_avx INT123_dct64_real_avx
#define dct64_mmx INT123_dct64_mmx
#define dct64_MMX INT123_dct64_MMX
+#define dct64_neon INT123_dct64_neon
+#define dct64_neon64 INT123_dct64_neon64
+#define dct64_real_neon64 INT123_dct64_real_neon64
+#define dct64_real_neon INT123_dct64_real_neon
#define dct64_sse INT123_dct64_sse
#define dct64_real_sse INT123_dct64_real_sse
#define dct64_x86_64 INT123_dct64_x86_64
#define dct64_real_x86_64 INT123_dct64_real_x86_64
-#define dct64_avx INT123_dct64_avx
-#define dct64_real_avx INT123_dct64_real_avx
-#define dct64_neon INT123_dct64_neon
-#define dct64_real_neon INT123_dct64_real_neon
-#define dct64_neon64 INT123_dct64_neon64
-#define dct64_real_neon64 INT123_dct64_real_neon64
#define do_equalizer_3dnow INT123_do_equalizer_3dnow
#define synth_1to1_3dnow_asm INT123_synth_1to1_3dnow_asm
#define synth_1to1_arm_asm INT123_synth_1to1_arm_asm
#define synth_1to1_i586_asm INT123_synth_1to1_i586_asm
#define synth_1to1_i586_asm_dither INT123_synth_1to1_i586_asm_dither
#define synth_1to1_MMX INT123_synth_1to1_MMX
+#define synth_1to1_neon_asm INT123_synth_1to1_neon_asm
+#define synth_1to1_neon64_asm INT123_synth_1to1_neon64_asm
+#define synth_1to1_neon64_accurate_asm INT123_synth_1to1_neon64_accurate_asm
+#define synth_1to1_real_neon64_asm INT123_synth_1to1_real_neon64_asm
+#define synth_1to1_s32_neon64_asm INT123_synth_1to1_s32_neon64_asm
+#define synth_1to1_neon_accurate_asm INT123_synth_1to1_neon_accurate_asm
+#define synth_1to1_real_neon_asm INT123_synth_1to1_real_neon_asm
+#define synth_1to1_s32_neon_asm INT123_synth_1to1_s32_neon_asm
#define synth_1to1_sse_accurate_asm INT123_synth_1to1_sse_accurate_asm
#define synth_1to1_real_sse_asm INT123_synth_1to1_real_sse_asm
#define synth_1to1_s32_sse_asm INT123_synth_1to1_s32_sse_asm
+#define synth_1to1_s_avx_asm INT123_synth_1to1_s_avx_asm
+#define synth_1to1_s_avx_accurate_asm INT123_synth_1to1_s_avx_accurate_asm
+#define synth_1to1_real_s_avx_asm INT123_synth_1to1_real_s_avx_asm
+#define synth_1to1_s32_s_avx_asm INT123_synth_1to1_s32_s_avx_asm
+#define synth_1to1_s_neon_asm INT123_synth_1to1_s_neon_asm
+#define synth_1to1_s_neon64_asm INT123_synth_1to1_s_neon64_asm
+#define synth_1to1_s_neon64_accurate_asm INT123_synth_1to1_s_neon64_accurate_asm
+#define synth_1to1_real_s_neon64_asm INT123_synth_1to1_real_s_neon64_asm
+#define synth_1to1_s32_s_neon64_asm INT123_synth_1to1_s32_s_neon64_asm
+#define synth_1to1_s_neon_accurate_asm INT123_synth_1to1_s_neon_accurate_asm
+#define synth_1to1_real_s_neon_asm INT123_synth_1to1_real_s_neon_asm
+#define synth_1to1_s32_s_neon_asm INT123_synth_1to1_s32_s_neon_asm
#define synth_1to1_s_sse_accurate_asm INT123_synth_1to1_s_sse_accurate_asm
#define synth_1to1_real_s_sse_asm INT123_synth_1to1_real_s_sse_asm
#define synth_1to1_s32_s_sse_asm INT123_synth_1to1_s32_s_sse_asm
#define synth_1to1_x86_64_accurate_asm INT123_synth_1to1_x86_64_accurate_asm
#define synth_1to1_real_x86_64_asm INT123_synth_1to1_real_x86_64_asm
#define synth_1to1_s32_x86_64_asm INT123_synth_1to1_s32_x86_64_asm
-#define synth_1to1_s_avx_asm INT123_synth_1to1_s_avx_asm
-#define synth_1to1_s_avx_accurate_asm INT123_synth_1to1_s_avx_accurate_asm
-#define synth_1to1_real_s_avx_asm INT123_synth_1to1_real_s_avx_asm
-#define synth_1to1_s32_s_avx_asm INT123_synth_1to1_s32_s_avx_asm
-#define synth_1to1_neon_asm INT123_synth_1to1_neon_asm
-#define synth_1to1_neon_accurate_asm INT123_synth_1to1_neon_accurate_asm
-#define synth_1to1_real_neon_asm INT123_synth_1to1_real_neon_asm
-#define synth_1to1_s32_neon_asm INT123_synth_1to1_s32_neon_asm
-#define synth_1to1_s_neon_asm INT123_synth_1to1_s_neon_asm
-#define synth_1to1_s_neon_accurate_asm INT123_synth_1to1_s_neon_accurate_asm
-#define synth_1to1_real_s_neon_asm INT123_synth_1to1_real_s_neon_asm
-#define synth_1to1_s32_s_neon_asm INT123_synth_1to1_s32_s_neon_asm
-#define synth_1to1_neon64_asm INT123_synth_1to1_neon64_asm
-#define synth_1to1_neon64_accurate_asm INT123_synth_1to1_neon64_accurate_asm
-#define synth_1to1_real_neon64_asm INT123_synth_1to1_real_neon64_asm
-#define synth_1to1_s32_neon64_asm INT123_synth_1to1_s32_neon64_asm
-#define synth_1to1_s_neon64_asm INT123_synth_1to1_s_neon64_asm
-#define synth_1to1_s_neon64_accurate_asm INT123_synth_1to1_s_neon64_accurate_asm
-#define synth_1to1_real_s_neon64_asm INT123_synth_1to1_real_s_neon64_asm
-#define synth_1to1_s32_s_neon64_asm INT123_synth_1to1_s32_s_neon64_asm
#define costab_mmxsse INT123_costab_mmxsse
#define make_decode_tables_mmx_asm INT123_make_decode_tables_mmx_asm
-#define check_neon INT123_check_neon
+#ifndef HAVE_STRDUP
+#define strdup INT123_strdup
+#endif
+#ifndef HAVE_STRERROR
+#define strerror INT123_strerror
+#endif
#endif
/*
- libmpg123: MPEG Audio Decoder library (version 1.22.1)
+ libmpg123: MPEG Audio Decoder library (version 1.23.0)
- copyright 1995-2010 by the mpg123 project - free software under the terms of the LGPL 2.1
+ copyright 1995-2015 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
*/
#ifndef MPG123_LIB_H
#define MPG123_LIB_H
-/** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */
+#include <fmt123.h>
-/* A macro to check at compile time which set of API functions to expect.
- This should be incremented at least each time a new symbol is added to the header. */
-#define MPG123_API_VERSION 41
+/** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */
-/* These aren't actually in use... seems to work without using libtool. */
+/** A macro to check at compile time which set of API functions to expect.
+ * This should be incremented at least each time a new symbol is added
+ * to the header.
+ */
+#define MPG123_API_VERSION 42
+
+/** Defines needed for MS Visual Studio(tm) DLL builds.
+ * Every public function must be prefixed with MPG123_EXPORT. When building
+ * the DLL ensure to define BUILD_MPG123_DLL. This makes the function accessible
+ * for clients and includes it in the import library which is created together
+ * with the DLL. When consuming the DLL ensure to define LINK_MPG123_DLL which
+ * imports the functions from the DLL.
+ */
#ifdef BUILD_MPG123_DLL
/* The dll exports. */
#define MPG123_EXPORT __declspec(dllexport)
#define mpg123_set_index MPG123_LARGENAME(mpg123_set_index)
#define mpg123_position MPG123_LARGENAME(mpg123_position)
#define mpg123_length MPG123_LARGENAME(mpg123_length)
+#define mpg123_framelength MPG123_LARGENAME(mpg123_framelength)
#define mpg123_set_filesize MPG123_LARGENAME(mpg123_set_filesize)
#define mpg123_replace_reader MPG123_LARGENAME(mpg123_replace_reader)
#define mpg123_replace_reader_handle MPG123_LARGENAME(mpg123_replace_reader_handle)
*
* \return MPG123_OK if successful, otherwise an error number.
*/
-MPG123_EXPORT int mpg123_init(void);
+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. */
* and optional retrieval of an error code to feed to mpg123_plain_strerror().
* Optional means: Any of or both the parameters may be NULL.
*
- * \return Non-NULL pointer when successful.
+ * \param decoder optional choice of decoder variant (NULL for default)
+ * \param error optional address to store error codes
+ * \return Non-NULL pointer to fresh handle when successful.
*/
MPG123_EXPORT mpg123_handle *mpg123_new(const char* decoder, int *error);
-/** Delete handle, mh is either a valid mpg123 handle or NULL. */
+/** Delete handle, mh is either a valid mpg123 handle or NULL.
+ * \param mh handle
+ */
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh);
/** Enumeration of the parameters types that it is possible to set/get. */
,MPG123_RVA_MAX = MPG123_RVA_ALBUM /**< The maximum RVA code, may increase in future. */
};
-/* TODO: Assess the possibilities and troubles of changing parameters during playback. */
-
/** Set a specific parameter, for a specific mpg123_handle, using a parameter
* type key chosen from the mpg123_parms enumeration, to the specified value.
- * \return MPG123_OK on success
+ * \param mh handle
+ * \param type parameter choice
+ * \param value integer value
+ * \param fvalue floating point value
+ * \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_param(mpg123_handle *mh, enum mpg123_parms type, long value, double fvalue);
+MPG123_EXPORT int mpg123_param( mpg123_handle *mh
+, enum mpg123_parms type, long value, double fvalue );
/** Get a specific parameter, for a specific mpg123_handle.
* See the mpg123_parms enumeration for a list of available parameters.
+ * \param mh handle
+ * \param type parameter choice
+ * \param value integer value return address
+ * \param fvalue floating point value return address
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_getparam(mpg123_handle *mh, enum mpg123_parms type, long *val, double *fval);
+MPG123_EXPORT int mpg123_getparam( mpg123_handle *mh
+, enum mpg123_parms type, long *value, double *fvalue );
/** Feature set available for query with mpg123_feature. */
enum mpg123_feature_set
,MPG123_FEATURE_DECODE_NTOM /**< flexible rate decoding */
,MPG123_FEATURE_PARSE_ICY /**< ICY support */
,MPG123_FEATURE_TIMEOUT_READ /**< Reader with timeout (network). */
+ ,MPG123_FEATURE_EQUALIZER /**< tunable equalizer */
};
-/** Query libmpg123 feature, 1 for success, 0 for unimplemented functions. */
+/** Query libmpg123 features.
+ * \param key feature selection
+ * \return 1 for success, 0 for unimplemented functions
+ */
MPG123_EXPORT int mpg123_feature(const enum mpg123_feature_set key);
/* @} */
,MPG123_INT_OVERFLOW /**< Some integer overflow. */
};
-/** Return a string describing that error errcode means. */
+/** Look up error strings given integer code.
+ * \param errcode integer error code
+ * \return string describing what that error error code means
+ */
MPG123_EXPORT const char* mpg123_plain_strerror(int errcode);
/** Give string describing what error has occured in the context of handle mh.
* When a function operating on an mpg123 handle returns MPG123_ERR, you should check for the actual reason via
* char *errmsg = mpg123_strerror(mh)
- * This function will catch mh == NULL and return the message for MPG123_BAD_HANDLE. */
+ * This function will catch mh == NULL and return the message for MPG123_BAD_HANDLE.
+ * \param mh handle
+ * \return error message
+ */
MPG123_EXPORT const char* mpg123_strerror(mpg123_handle *mh);
/** Return the plain errcode intead of a string.
+ * \param mh handle
* \return error code recorded in handle or MPG123_BAD_HANDLE
*/
MPG123_EXPORT int mpg123_errcode(mpg123_handle *mh);
* @{
*/
-/** Return a NULL-terminated array of generally available decoder names (plain 8bit ASCII). */
+/** Get available decoder list.
+ * \return NULL-terminated array of generally available decoder names (plain 8bit ASCII)
+ */
MPG123_EXPORT const char **mpg123_decoders(void);
-/** Return a NULL-terminated array of the decoders supported by the CPU (plain 8bit ASCII). */
+/** Get supported decoder list.
+ * \return NULL-terminated array of the decoders supported by the CPU (plain 8bit ASCII)
+ */
MPG123_EXPORT const char **mpg123_supported_decoders(void);
-/** Set the chosen decoder to 'decoder_name'
- * \return MPG123_OK on success
+/** Set the active decoder.
+ * \param mh handle
+ * \param decoder_name name of decoder
+ * \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_decoder(mpg123_handle *mh, const char* decoder_name);
-/** Get the currently active decoder engine name.
- The active decoder engine can vary depening on output constraints,
- mostly non-resampling, integer output is accelerated via 3DNow & Co. but for other modes a fallback engine kicks in.
- Note that this can return a decoder that is ony active in the hidden and not available as decoder choice from the outside.
- \return The decoder name or NULL on error. */
+/** Get the currently active decoder name.
+ * The active decoder engine can vary depening on output constraints,
+ * mostly non-resampling, integer output is accelerated via 3DNow & Co. but for
+ * other modes a fallback engine kicks in.
+ * Note that this can return a decoder that is ony active in the hidden and not
+ * available as decoder choice from the outside.
+ * \param mh handle
+ * \return The decoder name or NULL on error.
+ */
MPG123_EXPORT const char* mpg123_current_decoder(mpg123_handle *mh);
/*@}*/
* @{
*/
-/** An enum over all sample types possibly known to mpg123.
- * The values are designed as bit flags to allow bitmasking for encoding families.
- *
- * Note that (your build of) libmpg123 does not necessarily support all these.
- * Usually, you can expect the 8bit encodings and signed 16 bit.
- * Also 32bit float will be usual beginning with mpg123-1.7.0 .
- * What you should bear in mind is that (SSE, etc) optimized routines may be absent
- * for some formats. We do have SSE for 16, 32 bit and float, though.
- * 24 bit integer is done via postprocessing of 32 bit output -- just cutting
- * the last byte, no rounding, even. If you want better, do it yourself.
- *
- * All formats are in native byte order. If you need different endinaness, you
- * can simply postprocess the output buffers (libmpg123 wouldn't do anything else).
- * mpg123_encsize() can be helpful there.
- */
-enum mpg123_enc_enum
-{
- MPG123_ENC_8 = 0x00f /**< 0000 0000 1111 Some 8 bit integer encoding. */
- ,MPG123_ENC_16 = 0x040 /**< 0000 0100 0000 Some 16 bit integer encoding. */
- ,MPG123_ENC_24 = 0x4000 /**< 0100 0000 0000 0000 Some 24 bit integer encoding. */
- ,MPG123_ENC_32 = 0x100 /**< 0001 0000 0000 Some 32 bit integer encoding. */
- ,MPG123_ENC_SIGNED = 0x080 /**< 0000 1000 0000 Some signed integer encoding. */
- ,MPG123_ENC_FLOAT = 0xe00 /**< 1110 0000 0000 Some float encoding. */
- ,MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10) /**< 1101 0000 signed 16 bit */
- ,MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20) /**< 0110 0000 unsigned 16 bit */
- ,MPG123_ENC_UNSIGNED_8 = 0x01 /**< 0000 0001 unsigned 8 bit */
- ,MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED|0x02) /**< 1000 0010 signed 8 bit */
- ,MPG123_ENC_ULAW_8 = 0x04 /**< 0000 0100 ulaw 8 bit */
- ,MPG123_ENC_ALAW_8 = 0x08 /**< 0000 1000 alaw 8 bit */
- ,MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000 /**< 0001 0001 1000 0000 signed 32 bit */
- ,MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000 /**< 0010 0001 0000 0000 unsigned 32 bit */
- ,MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000 /**< 0101 0000 1000 0000 signed 24 bit */
- ,MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000 /**< 0110 0000 0000 0000 unsigned 24 bit */
- ,MPG123_ENC_FLOAT_32 = 0x200 /**< 0010 0000 0000 32bit float */
- ,MPG123_ENC_FLOAT_64 = 0x400 /**< 0100 0000 0000 64bit float */
- ,MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16 | MPG123_ENC_UNSIGNED_8
- | MPG123_ENC_SIGNED_8 | MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
- | MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
- | MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
- | MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 ) /**< Any encoding on the list. */
-};
-
/** They can be combined into one number (3) to indicate mono and stereo... */
enum mpg123_channelcount
{
- MPG123_MONO = 1
- ,MPG123_STEREO = 2
+ MPG123_MONO = 1 /**< mono */
+ ,MPG123_STEREO = 2 /**< stereo */
};
/** An array of supported standard sample rates
/** Configure a mpg123 handle to accept no output format at all,
* use before specifying supported formats with mpg123_format
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_format_none(mpg123_handle *mh);
/** Configure mpg123 handle to accept all formats
* (also any custom rate you may set) -- this is default.
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_format_all(mpg123_handle *mh);
/** Set the audio format support of a mpg123_handle in detail:
- * \param mh audio decoder handle
+ * \param mh handle
* \param rate The sample rate value (in Hertz).
* \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_format(mpg123_handle *mh, long rate, int channels, int encodings);
+MPG123_EXPORT int mpg123_format( 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
+ * \param rate sampling rate
+ * \param encoding encoding
* \return 0 for no support (that includes invalid parameters), MPG123_STEREO,
* MPG123_MONO or MPG123_STEREO|MPG123_MONO. */
-MPG123_EXPORT int mpg123_format_support(mpg123_handle *mh, long rate, int encoding);
+MPG123_EXPORT int mpg123_format_support( mpg123_handle *mh
+, long rate, int encoding );
/** Get the current output format written to the addresses given.
+ * \param mh handle
+ * \param rate sampling rate return address
+ * \param channels channel count return address
+ * \param encoding encoding return address
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding);
+MPG123_EXPORT int mpg123_getformat( mpg123_handle *mh
+, long *rate, 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.
* If you want to decode internet streams, use mpg123_open_fd() or mpg123_open_feed().
+ * \param mh handle
* \param path filesystem path
* \return MPG123_OK on success
*/
/** Use an already opened file descriptor as the bitstream input
* mpg123_close() will _not_ close the file descriptor.
+ * \param mh handle
+ * \param fd file descriptor
+ * \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_fd(mpg123_handle *mh, int fd);
/** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_replace_reader_handle()!
* mpg123_close() will call the cleanup callback for your handle (if you gave one).
+ * \param mh handle
+ * \param iohandle your handle
* \return MPG123_OK on success
*/
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.
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh);
/** Closes the source, if libmpg123 opened it.
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_close(mpg123_handle *mh);
/** Read from stream and decode up to outmemsize bytes.
+ * \param mh handle
* \param outmemory address of output buffer to write to
* \param outmemsize maximum number of bytes to write
* \param done address to store the number of actually decoded bytes to
* \return MPG123_OK or error/message code
*/
-MPG123_EXPORT int mpg123_read(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done);
+MPG123_EXPORT int mpg123_read(mpg123_handle *mh
+, unsigned char *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.
+ * \param mh handle
* \param in input buffer
* \param size number of input bytes
* \return MPG123_OK or error/message code.
*/
-MPG123_EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size);
+MPG123_EXPORT int mpg123_feed( mpg123_handle *mh
+, const unsigned char *in, size_t size );
/** Decode MPEG Audio from inmemory to outmemory.
* This is very close to a drop-in replacement for old mpglib.
* 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.
+ * \param mh handle
* \param inmemory input buffer
* \param inmemsize number of input bytes
* \param outmemory output buffer
* \param done address to store the number of actually decoded bytes to
* \return error/message code (watch out especially for MPG123_NEED_MORE)
*/
-MPG123_EXPORT int mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done);
+MPG123_EXPORT int mpg123_decode( mpg123_handle *mh
+, const unsigned char *inmemory, size_t inmemsize
+, unsigned char *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.
+ * \param mh handle
* \param num current frame offset gets stored there
* \param audio This pointer is set to the internal buffer to read the decoded audio from.
* \param bytes number of output bytes ready in the buffer
* \return MPG123_OK or error/message code
*/
-MPG123_EXPORT int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes);
+MPG123_EXPORT int mpg123_decode_frame( mpg123_handle *mh
+, off_t *num, unsigned char **audio, size_t *bytes );
/** Decode current MPEG frame to internal buffer.
* Warning: This is experimental API that might change in future releases!
* Please watch mpg123 development closely when using it.
+ * \param mh handle
* \param num last frame offset gets stored there
* \param audio this pointer is set to the internal buffer to read the decoded audio from.
* \param bytes number of output bytes ready in the buffer
* \return MPG123_OK or error/message code
*/
-MPG123_EXPORT int mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes);
+MPG123_EXPORT int mpg123_framebyframe_decode( mpg123_handle *mh
+, off_t *num, unsigned char **audio, size_t *bytes );
/** Find, read and parse the next mp3 frame
* Warning: This is experimental API that might change in future releases!
* Please watch mpg123 development closely when using it.
+ * \param mh handle
* \return MPG123_OK or error/message code
*/
MPG123_EXPORT int mpg123_framebyframe_next(mpg123_handle *mh);
* A more sane use would be to use this for CRC checking (see mpg123_info() and MPG123_CRC), the first two bytes of the body make up the CRC16 checksum, if present.
* You can provide NULL for a parameter pointer when you are not interested in the value.
*
+ * \param mh handle
* \param header the 4-byte MPEG header
* \param bodydata pointer to the frame body stored in the handle (without the header)
* \param bodybytes size of frame body in bytes (without the header)
* explanation, the error state of the mpg123_handle is not modified by
* this function).
*/
-MPG123_EXPORT int mpg123_framedata(mpg123_handle *mh, unsigned long *header, unsigned char **bodydata, size_t *bodybytes);
+MPG123_EXPORT int mpg123_framedata( mpg123_handle *mh
+, unsigned long *header, unsigned char **bodydata, size_t *bodybytes );
/** Get the input position (byte offset in stream) of the last parsed frame.
- * This can be used for external seek index building, for example.
- * It just returns the internally stored offset, regardless of validity -- you ensure that a valid frame has been parsed before! */
+ * This can be used for external seek index building, for example.
+ * It just returns the internally stored offset, regardless of validity --
+ * you ensure that a valid frame has been parsed before!
+ * \param mh handle
+ * \return byte offset in stream
+ */
MPG123_EXPORT off_t mpg123_framepos(mpg123_handle *mh);
/*@}*/
/** Returns the current position in samples.
* On the next successful read, you'd get that sample.
+ * \param mh handle
* \return sample offset or MPG123_ERR (null handle)
*/
MPG123_EXPORT off_t mpg123_tell(mpg123_handle *mh);
/** Returns the frame number that the next read will give you data from.
+ * \param mh handle
* \return frame offset or MPG123_ERR (null handle)
*/
MPG123_EXPORT off_t mpg123_tellframe(mpg123_handle *mh);
/** Returns the current byte offset in the input stream.
+ * \param mh handle
* \return byte offset or MPG123_ERR (null handle)
*/
MPG123_EXPORT off_t mpg123_tell_stream(mpg123_handle *mh);
-/** Seek to a desired sample offset.
- * Set whence to SEEK_SET, SEEK_CUR or SEEK_END.
- * \return The resulting offset >= 0 or error/message code */
-MPG123_EXPORT off_t mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence);
+/** Seek to a desired sample offset.
+ * Usage is modelled afer the standard lseek().
+ * \param mh handle
+ * \param sampleoff offset in PCM samples
+ * \param whence one of SEEK_SET, SEEK_CUR or SEEK_END
+ * \return The resulting offset >= 0 or error/message code
+ */
+MPG123_EXPORT off_t mpg123_seek( mpg123_handle *mh
+, off_t sampleoff, int whence );
/** Seek to a desired sample offset in data feeding mode.
* This just prepares things to be right only if you ensure that the next chunk of input data will be from input_offset byte position.
+ * \param mh handle
+ * \param sampleoff offset in PCM samples
+ * \param whence one of SEEK_SET, SEEK_CUR or SEEK_END
* \param input_offset The position it expects to be at the
* next time data is fed to mpg123_decode().
* \return The resulting offset >= 0 or error/message code */
-MPG123_EXPORT off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset);
-
-/** Seek to a desired MPEG frame index.
- * Set whence to SEEK_SET, SEEK_CUR or SEEK_END.
- * \return The resulting offset >= 0 or error/message code */
-MPG123_EXPORT off_t mpg123_seek_frame(mpg123_handle *mh, off_t frameoff, int whence);
+MPG123_EXPORT off_t mpg123_feedseek( mpg123_handle *mh
+, off_t sampleoff, int whence, off_t *input_offset );
+
+/** Seek to a desired MPEG frame offset.
+ * Usage is modelled afer the standard lseek().
+ * \param mh handle
+ * \param frameoff offset in MPEG frames
+ * \param whence one of SEEK_SET, SEEK_CUR or SEEK_END
+ * \return The resulting offset >= 0 or error/message code */
+MPG123_EXPORT off_t mpg123_seek_frame( mpg123_handle *mh
+, off_t frameoff, int whence );
/** Return a MPEG frame offset corresponding to an offset in seconds.
* This assumes that the samples per frame do not change in the file/stream, which is a good assumption for any sane file/stream only.
/** Give access to the frame index table that is managed for seeking.
* You are asked not to modify the values... Use mpg123_set_index to set the
* seek index
+ * \param mh handle
* \param offsets pointer to the index array
* \param step one index byte offset advances this many MPEG frames
* \param fill number of recorded index offsets; size of the array
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill);
+MPG123_EXPORT int mpg123_index( mpg123_handle *mh
+, off_t **offsets, off_t *step, size_t *fill );
/** Set the frame index table
* Setting offsets to NULL and fill > 0 will allocate fill entries. Setting offsets
* to NULL and fill to 0 will clear the index and free the allocated memory used by the index.
+ * \param mh handle
* \param offsets pointer to the index array
* \param step one index byte offset advances this many MPEG frames
* \param fill number of recorded index offsets; size of the array
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill);
-
-/** Get information about current and remaining frames/seconds.
- * WARNING: This function is there because of special usage by standalone mpg123 and may be removed in the final version of libmpg123!
- * You provide an offset (in frames) from now and a number of output bytes
- * served by libmpg123 but not yet played. You get the projected current frame
- * and seconds, as well as the remaining frames/seconds. This does _not_ care
- * about skipped samples due to gapless playback. */
+MPG123_EXPORT int mpg123_set_index( mpg123_handle *mh
+, off_t *offsets, off_t step, size_t fill );
+
+/** An old crutch to keep old mpg123 binaries happy.
+ * WARNING: This function is there only to avoid runtime linking errors with
+ * standalone mpg123 before version 1.23.0 (if you strangely update the
+ * library but not the end-user program) and actually is broken
+ * for various cases (p.ex. 24 bit output). Do never use. It might eventually
+ * be purged from the library.
+ */
MPG123_EXPORT int mpg123_position( mpg123_handle *mh, off_t frame_offset, off_t buffered_bytes, off_t *current_frame, off_t *frames_left, double *current_seconds, double *seconds_left);
/*@}*/
* @{
*/
+/** another channel enumeration, for left/right choice */
enum mpg123_channels
{
MPG123_LEFT=0x1 /**< The Left Channel. */
};
/** Set the 32 Band Audio Equalizer settings.
+ * \param mh handle
* \param channel Can be MPG123_LEFT, MPG123_RIGHT or MPG123_LEFT|MPG123_RIGHT for both.
* \param band The equaliser band to change (from 0 to 31)
* \param val The (linear) adjustment factor.
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val);
+MPG123_EXPORT int mpg123_eq( mpg123_handle *mh
+, enum mpg123_channels channel, int band, double val );
/** Get the 32 Band Audio Equalizer settings.
+ * \param mh handle
* \param channel Can be MPG123_LEFT, MPG123_RIGHT or MPG123_LEFT|MPG123_RIGHT for (arithmetic mean of) both.
* \param band The equaliser band to change (from 0 to 31)
* \return The (linear) adjustment factor (zero for pad parameters) */
-MPG123_EXPORT double mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band);
+MPG123_EXPORT double mpg123_geteq(mpg123_handle *mh
+ , enum mpg123_channels channel, int band);
/** Reset the 32 Band Audio Equalizer settings to flat
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_reset_eq(mpg123_handle *mh);
/** Set the absolute output volume including the RVA setting,
- * vol<0 just applies (a possibly changed) RVA setting. */
+ * vol<0 just applies (a possibly changed) RVA setting.
+ * \param mh handle
+ * \param vol volume value (linear factor)
+ * \return MPG123_OK on success
+ */
MPG123_EXPORT int mpg123_volume(mpg123_handle *mh, double vol);
-/** Adjust output volume including the RVA setting by chosen amount */
+/** Adjust output volume including the RVA setting by chosen amount
+ * \param mh handle
+ * \param change volume value (linear factor increment)
+ * \return MPG123_OK on success
+ */
MPG123_EXPORT int mpg123_volume_change(mpg123_handle *mh, double change);
/** Return current volume setting, the actual value due to RVA, and the RVA
* adjustment itself. It's all as double float value to abstract the sample
* format. The volume values are linear factors / amplitudes (not percent)
- * and the RVA value is in decibels. */
+ * and the RVA value is in decibels.
+ * \param mh handle
+ * \param base return address for base volume (linear factor)
+ * \param really return address for actual volume (linear factor)
+ * \param rva_db return address for RVA value (decibels)
+ * \return MPG123_OK on success
+ */
MPG123_EXPORT int mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db);
/* TODO: Set some preamp in addition / to replace internal RVA handling? */
};
/** 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
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi);
-/** Get the safe output buffer size for all cases (when you want to replace the internal buffer) */
-MPG123_EXPORT size_t mpg123_safe_buffer(void);
+/** Get the safe output buffer size for all cases
+ * (when you want to replace the internal buffer)
+ * \return safe buffer size
+ */
+MPG123_EXPORT size_t mpg123_safe_buffer(void);
-/** Make a full parsing scan of each frame in the file. ID3 tags are found. An accurate length
- * value is stored. Seek index will be filled. A seek back to current position
- * is performed. At all, this function refuses work when stream is
- * not seekable.
+/** Make a full parsing scan of each frame in the file. ID3 tags are found. An
+ * accurate length value is stored. Seek index will be filled. A seek back to
+ * current position is performed. At all, this function refuses work when
+ * stream is not seekable.
+ * \param mh handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_scan(mpg123_handle *mh);
+/** Return, if possible, the full (expected) length of current track in 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 length >= 0 or MPG123_ERR if there is no length guess possible. */
+ * \param mh handle
+ * \return length >= 0 or MPG123_ERR if there is no length guess possible.
+ */
MPG123_EXPORT off_t mpg123_length(mpg123_handle *mh);
/** Override the value for file size in bytes.
- * Useful for getting sensible track length values in feed mode or for HTTP streams.
- * \return MPG123_OK on success
- */
+ * Useful for getting sensible track length values in feed mode or for HTTP streams.
+ * \param mh handle
+ * \param size file size in bytes
+ * \return MPG123_OK on success
+ */
MPG123_EXPORT int mpg123_set_filesize(mpg123_handle *mh, off_t size);
-/** Returns the time (seconds) per frame; <0 is error. */
+/** Get MPEG frame duration in seconds.
+ * \param mh handle
+ * \return frame duration in seconds, <0 on error
+ */
MPG123_EXPORT double mpg123_tpf(mpg123_handle *mh);
-/** Returns the samples per frame for the most recently parsed frame; <0 is error. */
+/** Get MPEG frame duration in samples.
+ * \param mh handle
+ * \return samples per frame for the most recently parsed frame; <0 on errors
+ */
MPG123_EXPORT int mpg123_spf(mpg123_handle *mh);
-/** Get and reset the clip count. */
+/** Get and reset the clip count.
+ * \param mh handle
+ * \return count of clipped samples
+ */
MPG123_EXPORT long mpg123_clip(mpg123_handle *mh);
};
/** Get various current decoder/stream state information.
+ * \param mh handle
* \param key the key to identify the information to give.
* \param val the address to return (long) integer values to
* \param fval the address to return floating point values to
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval);
+MPG123_EXPORT int mpg123_getstate( mpg123_handle *mh
+, enum mpg123_state key, long *val, double *fval );
/*@}*/
size_t fill; /**< number of used bytes (including closing zero byte) */
} mpg123_string;
-/** Create and allocate memory for a new mpg123_string */
+/** Create and allocate memory for a new mpg123_string
+ * \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 mempory for an existing mpg123_string
+ * \param sb string handle
+ */
MPG123_EXPORT void mpg123_free_string(mpg123_string* sb);
/** Change the size of a mpg123_string
- * \return 0 on error, 1 on success */
-MPG123_EXPORT int mpg123_resize_string(mpg123_string* sb, size_t news);
+ * \param sb string handle
+ * \param news new size in bytes
+ * \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_resize_string(mpg123_string* sb, size_t news);
/** Increase size of a mpg123_string if necessary (it may stay larger).
- * Note that the functions for adding and setting in current libmpg123 use this instead of mpg123_resize_string().
- * That way, you can preallocate memory and safely work afterwards with pieces.
- * \return 0 on error, 1 on success */
-MPG123_EXPORT int mpg123_grow_string(mpg123_string* sb, size_t news);
+ * Note that the functions for adding and setting in current libmpg123
+ * use this instead of mpg123_resize_string().
+ * That way, you can preallocate memory and safely work afterwards with
+ * pieces.
+ * \param sb string handle
+ * \param news new minimum size
+ * \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_grow_string(mpg123_string* sb, size_t news);
/** Copy the contents of one mpg123_string string to another.
- * \return 0 on error, 1 on success */
-MPG123_EXPORT int mpg123_copy_string(mpg123_string* from, mpg123_string* to);
+ * Yes the order of arguments is reversed compated to memcpy().
+ * \param from string handle
+ * \param to string handle
+ * \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_copy_string(mpg123_string* from, mpg123_string* to);
/** Append a C-String to an mpg123_string
- * \return 0 on error, 1 on success */
-MPG123_EXPORT int mpg123_add_string(mpg123_string* sb, const char* stuff);
+ * \param sb string handle
+ * \param stuff to append
+ * \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_add_string(mpg123_string* sb, const char* stuff);
/** Append a C-substring to an mpg123 string
- * \return 0 on error, 1 on success
+ * \param sb string handle
+ * \param stuff content to copy
* \param from offset to copy from
- * \param count number of characters to copy (a null-byte is always appended) */
-MPG123_EXPORT int mpg123_add_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count);
-
-/** Set the conents of a mpg123_string to a C-string
- * \return 0 on error, 1 on success */
-MPG123_EXPORT int mpg123_set_string(mpg123_string* sb, const char* stuff);
+ * \param count number of characters to copy (a null-byte is always appended)
+ * \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_add_substring( mpg123_string *sb
+, const char *stuff, size_t from, size_t count );
-/** Set the contents of a mpg123_string to a C-substring
+/** Set the content of a mpg123_string to a C-string
+ * \param sb string handle
+ * \param stuff content to copy
* \return 0 on error, 1 on success
+ */
+MPG123_EXPORT int mpg123_set_string(mpg123_string* sb, const char* stuff);
+
+/** Set the content of a mpg123_string to a C-substring
+ * \param sb string handle
+ * \param stuff the future content
* \param from offset to copy from
- * \param count number of characters to copy (a null-byte is always appended) */
-MPG123_EXPORT int mpg123_set_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count);
+ * \param count number of characters to copy (a null-byte is always appended)
+ * \return 0 on error, 1 on success
+ */
+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).
- * \return character count
- * \param sb the string
- * \param utf8 a flag to tell if the string is in utf8 encoding
* Even with the fill property, the character count is not obvious as there could be multiple trailing null bytes.
+ * \param sb string handle
+ * \param utf8 a flag to tell if the string is in utf8 encoding
+ * \return character count
*/
MPG123_EXPORT size_t mpg123_strlen(mpg123_string *sb, int utf8);
-/** Remove trailing \r and \n, if present.
+/** Remove trailing \\r and \\n, if present.
+ * \param sb string handle
* \return 0 on error, 1 on success
- * \param sb the string
*/
MPG123_EXPORT int mpg123_chomp_string(mpg123_string *sb);
,mpg123_id3_enc_max = 3 /**< Placeholder to check valid range of encoding byte. */
};
-/** Convert ID3 encoding byte to mpg123 encoding index. */
+/** Convert ID3 encoding byte to mpg123 encoding index.
+ * \param id3_enc_byte the ID3 encoding code
+ * \return the mpg123 encoding index
+ */
+
MPG123_EXPORT enum mpg123_text_encoding mpg123_enc_from_id3(unsigned char id3_enc_byte);
/** Store text data in string, after converting to UTF-8 from indicated encoding
- * \return 0 on error, 1 on success (on error, mpg123_free_string is called on sb)
+ * A prominent error can be that you provided an unknown encoding value, or this build of libmpg123 lacks support for certain encodings (ID3 or ICY stuff missing).
+ * Also, you might want to take a bit of care with preparing the data; for example, strip leading zeroes (I have seen that).
* \param sb target string
* \param enc mpg123 text encoding value
* \param source source buffer with plain unsigned bytes (you might need to cast from char *)
* \param source_size number of bytes in the source buffer
- *
- * A prominent error can be that you provided an unknown encoding value, or this build of libmpg123 lacks support for certain encodings (ID3 or ICY stuff missing).
- * Also, you might want to take a bit of care with preparing the data; for example, strip leading zeroes (I have seen that).
+ * \return 0 on error, 1 on success (on error, mpg123_free_string is called on sb)
*/
MPG123_EXPORT int mpg123_store_utf8(mpg123_string *sb, enum mpg123_text_encoding enc, const unsigned char *source, size_t source_size);
/** The picture type values from ID3v2. */
enum mpg123_id3_pic_type
{
- mpg123_id3_pic_other = 0
- ,mpg123_id3_pic_icon = 1
- ,mpg123_id3_pic_other_icon = 2
- ,mpg123_id3_pic_front_cover = 3
- ,mpg123_id3_pic_back_cover = 4
- ,mpg123_id3_pic_leaflet = 5
- ,mpg123_id3_pic_media = 6
- ,mpg123_id3_pic_lead = 7
- ,mpg123_id3_pic_artist = 8
- ,mpg123_id3_pic_conductor = 9
- ,mpg123_id3_pic_orchestra = 10
- ,mpg123_id3_pic_composer = 11
- ,mpg123_id3_pic_lyricist = 12
- ,mpg123_id3_pic_location = 13
- ,mpg123_id3_pic_recording = 14
- ,mpg123_id3_pic_performance = 15
- ,mpg123_id3_pic_video = 16
- ,mpg123_id3_pic_fish = 17
- ,mpg123_id3_pic_illustration = 18
- ,mpg123_id3_pic_artist_logo = 19
- ,mpg123_id3_pic_publisher_logo = 20
+ mpg123_id3_pic_other = 0 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_icon = 1 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_other_icon = 2 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_front_cover = 3 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_back_cover = 4 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_leaflet = 5 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_media = 6 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_lead = 7 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_artist = 8 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_conductor = 9 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_orchestra = 10 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_composer = 11 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_lyricist = 12 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_location = 13 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_recording = 14 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_performance = 15 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_video = 16 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_fish = 17 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_illustration = 18 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_artist_logo = 19 /**< see ID3v2 docs */
+ ,mpg123_id3_pic_publisher_logo = 20 /**< see ID3v2 docs */
};
/** Sub data structure for ID3v2, for storing picture data including comment.
* here to separate from MPEG frames). */
typedef struct
{
- char type;
- mpg123_string description;
- mpg123_string mime_type;
- size_t size;
- unsigned char* data;
+ char type; /**< mpg123_id3_pic_type value */
+ mpg123_string description; /**< description string */
+ mpg123_string mime_type; /**< MIME type */
+ size_t size; /**< size in bytes */
+ unsigned char* data; /**< pointer to the image data */
} mpg123_picture;
/** Data structure for storing IDV3v2 tags.
#define MPG123_NEW_ICY 0x4 /**< 0100 There is ICY info that changed since last call to mpg123_icy. */
/** Query if there is (new) meta info, be it ID3 or ICY (or something new in future).
- The check function returns a combination of flags. */
-MPG123_EXPORT int mpg123_meta_check(mpg123_handle *mh); /* On error (no valid handle) just 0 is returned. */
+ * \param mh handle
+ * \return combination of flags, 0 on error (same as "nothing new")
+ */
+MPG123_EXPORT int mpg123_meta_check(mpg123_handle *mh);
-/** Clean up meta data storage (ID3v2 and ICY), freeing memory. */
+/** Clean up meta data storage (ID3v2 and ICY), freeing memory.
+ * \param mh handle
+ */
MPG123_EXPORT void mpg123_meta_free(mpg123_handle *mh);
/** Point v1 and v2 to existing data structures wich may change on any next read/decode function call.
* v1 and/or v2 can be set to NULL when there is no corresponding data.
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2);
+MPG123_EXPORT int mpg123_id3( mpg123_handle *mh
+, mpg123_id3v1 **v1, mpg123_id3v2 **v2 );
/** 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)
* \return MPG123_OK on success
*/
-MPG123_EXPORT int mpg123_icy(mpg123_handle *mh, char **icy_meta); /* same for ICY meta string */
+MPG123_EXPORT int mpg123_icy(mpg123_handle *mh, char **icy_meta);
/** Decode from windows-1252 (the encoding ICY metainfo used) to UTF-8.
* Note that this is very similar to mpg123_store_utf8(&sb, mpg123_text_icy, icy_text, strlen(icy_text+1)) .
/** Opaque structure for the libmpg123 decoder parameters. */
typedef struct mpg123_pars_struct mpg123_pars;
-/** Create a handle with preset parameters. */
-MPG123_EXPORT mpg123_handle *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error);
+/** Create a handle with preset parameters.
+ * \param mp parameter handle
+ * \param decoder decoder choice
+ * \param error error code return address
+ * \return mpg123 handle
+ */
+MPG123_EXPORT mpg123_handle *mpg123_parnew( mpg123_pars *mp
+, const char* decoder, int *error );
-/** Allocate memory for and return a pointer to a new mpg123_pars */
+/** Allocate memory for and return a pointer to a new mpg123_pars
+ * \param error error code return address
+ * \return new parameter handle
+ */
MPG123_EXPORT mpg123_pars *mpg123_new_pars(int *error);
-/** Delete and free up memory used by a mpg123_pars data structure */
-MPG123_EXPORT void mpg123_delete_pars(mpg123_pars* mp);
+/** Delete and free up memory used by a mpg123_pars data structure
+ * \param mp parameter handle
+ */
+MPG123_EXPORT void mpg123_delete_pars(mpg123_pars* mp);
/** Configure mpg123 parameters to accept no output format at all,
- * use before specifying supported formats with mpg123_format
+ * use before specifying supported formats with mpg123_format
+ * \param mp parameter handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_fmt_none(mpg123_pars *mp);
/** Configure mpg123 parameters to accept all formats
* (also any custom rate you may set) -- this is default.
+ * \param mp parameter handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_fmt_all(mpg123_pars *mp);
/** Set the audio format support of a mpg123_pars in detail:
- \param rate The sample rate value (in Hertz).
- \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
+ * \param mp parameter handle
+ * \param rate The sample rate value (in Hertz).
+ * \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_fmt(mpg123_pars *mp, long rate, int channels, int encodings); /* 0 is good, -1 is error */
+MPG123_EXPORT int mpg123_fmt(mpg123_pars *mp
+, long rate, int channels, int encodings);
-/** Check to see if a specific format at a specific rate is supported
+/** Check to see if a specific format at a specific rate is supported
* by mpg123_pars.
+ * \param mp parameter handle
+ * \param rate sampling rate
+ * \param encoding encoding
* \return 0 for no support (that includes invalid parameters), MPG123_STEREO,
* MPG123_MONO or MPG123_STEREO|MPG123_MONO. */
-MPG123_EXPORT int mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding);
+MPG123_EXPORT int mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding);
/** Set a specific parameter, for a specific mpg123_pars, using a parameter
- * type key chosen from the mpg123_parms enumeration, to the specified value. */
-MPG123_EXPORT int mpg123_par(mpg123_pars *mp, enum mpg123_parms type, long value, double fvalue);
+ * type key chosen from the mpg123_parms enumeration, to the specified value.
+ * \param mp parameter handle
+ * \param type parameter choice
+ * \param value integer value
+ * \param fvalue floating point value
+ * \return MPG123_OK on success
+ */
+MPG123_EXPORT int mpg123_par( mpg123_pars *mp
+, enum mpg123_parms type, long value, double fvalue );
/** Get a specific parameter, for a specific mpg123_pars.
- * See the mpg123_parms enumeration for a list of available parameters. */
-MPG123_EXPORT int mpg123_getpar(mpg123_pars *mp, enum mpg123_parms type, long *val, double *fval);
+ * See the mpg123_parms enumeration for a list of available parameters.
+ * \param mp parameter handle
+ * \param type parameter choice
+ * \param value integer value return address
+ * \param fvalue floating point value return address
+ * \return MPG123_OK on success
+ */
+MPG123_EXPORT int mpg123_getpar( mpg123_pars *mp
+, enum mpg123_parms type, long *value, double *fvalue);
/* @} */
* Instead of working on it's own private buffer, mpg123 will directly use the one you provide for storing decoded audio.
* 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.
+ * storage for 24 bit output).
+ * \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);
+MPG123_EXPORT int mpg123_replace_buffer(mpg123_handle *mh
+, unsigned char *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. */
+ * Use that to determine an appropriate minimum buffer size for decoding one frame.
+ * \param mh handle
+ * \return maximum decoded data size in bytes
+ */
MPG123_EXPORT size_t mpg123_outblock(mpg123_handle *mh);
/** Replace low-level stream access functions; read and lseek as known in POSIX.
* You can use this to make any fancy file opening/closing yourself,
- * using mpg123_open_fd() to set the file descriptor for your read/lseek (doesn't need to be a "real" file descriptor...).
+ * using mpg123_open_fd() to set the file descriptor for your read/lseek
+ * (doesn't need to be a "real" file descriptor...).
* Setting a function to NULL means that the default internal read is
* used (active from next mpg123_open call on).
* Note: As it would be troublesome to mess with this while having a file open,
- * this implies mpg123_close(). */
-MPG123_EXPORT int mpg123_replace_reader(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), off_t (*r_lseek)(int, off_t, int));
+ * this implies mpg123_close().
+ * \param mh handle
+ * \param r_read callback for reading (behaviour like POSIX read)
+ * \param r_lseek callback for seeking (like POSIX lseek)
+ * \return MPG123_OK on success
+ */
+MPG123_EXPORT int mpg123_replace_reader( mpg123_handle *mh
+, ssize_t (*r_read) (int, void *, size_t)
+, off_t (*r_lseek)(int, off_t, int)
+);
-/** Replace I/O functions with your own ones operating on some kind of handle instead of integer descriptors.
+/** Replace I/O functions with your own ones operating on some kind of
+ * handle instead of integer descriptors.
* The handle is a void pointer, so you can pass any data you want...
* mpg123_open_handle() is the call you make to use the I/O defined here.
* There is no fallback to internal read/seek here.
* Note: As it would be troublesome to mess with this while having a file open,
* this mpg123_close() is implied here.
- * \param r_read The callback for reading (behaviour like posix read).
- * \param r_lseek The callback for seeking (like posix lseek).
- * \param cleanup A callback to clean up an I/O handle on mpg123_close, can be NULL for none (you take care of cleaning your handles). */
-MPG123_EXPORT int mpg123_replace_reader_handle(mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*));
+ * \param mh handle
+ * \param r_read callback for reading (behaviour like POSIXread)
+ * \param r_lseek callback for seeking (like POSIX lseek)
+ * \param cleanup A callback to clean up an I/O handle on mpg123_close,
+ * can be NULL for none (you take care of cleaning your handles).
+ * \return MPG123_OK on success
+ */
+MPG123_EXPORT int mpg123_replace_reader_handle( mpg123_handle *mh
+, ssize_t (*r_read) (void *, void *, size_t)
+, off_t (*r_lseek)(void *, off_t, int)
+, void (*cleanup)(void*) );
/* @} */
}
#endif
+#undef MPG123_EXPORT
+
#endif
real *b0, **buf; /* (*buf)[0x110]; */
int clip = 0;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
int clip = 0;
int bo1;
int ntom;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/libmpg123)
list(APPEND SOURCE
- compat.c
+ compat/compat.c
dct64.c
dct64_i386.c
equalizer.c
add_library(libmpg123 ${SOURCE} optimize.c)
add_dependencies(libmpg123 psdk)
add_pch(libmpg123 precomp.h SOURCE)
-
-if((NOT MSVC) AND (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang"))
- add_target_compile_flags(libmpg123 "-Wno-unused-but-set-variable")
-endif()
--- /dev/null
+/*
+ Just to ensure that libraries and programs get their separate
+ compatibility object. There should be a compatibility library,
+ I presume, but I don't want to create another glib, I just want
+ some internal functions to ease coding.
+
+ I'll sort it out properly sometime.
+
+ I smell symbol conflicts, anyway. Actually wondering why it
+ worked so far.
+*/
+
+#include "config.h"
+#include "intsym.h"
+#define NO_CATCHSIGNAL
+#include "compat/compat_impl.h"
}
#endif
+/* Always add a default permission mask in case of flags|O_CREAT. */
int compat_open(const char *filename, int flags)
{
int ret;
wchar_t *frag = NULL;
ret = win32_utf8_wide(filename, &frag, NULL);
- if ((frag == NULL) || (ret == 0)) goto fallback; /* Fallback to plain open when ucs-2 conversion fails */
+ /* Fallback to plain open when ucs-2 conversion fails */
+ if((frag == NULL) || (ret == 0))
+ goto open_fallback;
- ret = _wopen(frag, flags); /*Try _wopen */
- if (ret != -1 ) goto open_ok; /* msdn says -1 means failure */
+ /*Try _wopen */
+ ret = _wopen(frag, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
+ if(ret != -1 )
+ goto open_ok; /* msdn says -1 means failure */
-fallback:
+open_fallback:
#endif
-#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
- ret = _open(filename, flags); /* Try plain old _open(), if it fails, do nothing */
+#if (defined(WIN32) && !defined (__CYGWIN__))
+ /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
+ /* Try plain old _open(), if it fails, do nothing */
+ ret = _open(filename, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
#else
- /* On UNIX, we always add a default permission mask in case flags|O_CREAT. */
ret = open(filename, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
#endif
#if defined (WANT_WIN32_UNICODE)
open_ok:
- free ((void *)frag); /* Freeing a NULL should be OK */
+ /* A cast to void*? Does Windows need that?! */
+ free((void *)frag);
#endif
return ret;
}
+/* Moved over from wav.c, logic with fallbacks added from the
+ example of compat_open(). */
+FILE* compat_fopen(const char *filename, const char *mode)
+{
+ FILE* stream = NULL;
+#ifdef WANT_WIN32_UNICODE
+ int cnt = 0;
+ wchar_t *wname = NULL;
+ wchar_t *wmode = NULL;
+
+ cnt = win32_utf8_wide(filename, &wname, NULL);
+ if( (wname == NULL) || (cnt == 0))
+ goto fopen_fallback;
+ cnt = win32_utf8_wide(mode, &wmode, NULL);
+ if( (wmode == NULL) || (cnt == 0))
+ goto fopen_fallback;
+
+ stream = _wfopen(wname, wmode);
+ if(stream) goto fopen_ok;
+
+fopen_fallback:
+#endif
+ stream = fopen(filename, mode);
+#ifdef WANT_WIN32_UNICODE
+
+fopen_ok:
+ free(wmode);
+ free(wname);
+#endif
+ return stream;
+}
+
int compat_close(int infd)
{
#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
#endif
}
+int compat_fclose(FILE *stream)
+{
+ return fclose(stream);
+}
+
/* Windows Unicode stuff */
#ifdef WANT_WIN32_UNICODE
return ret; /* Number of characters written */
}
#endif
+
+
+/* This shall survive signals and any return value less than given byte count
+ is an error */
+size_t unintr_write(int fd, void const *buffer, size_t bytes)
+{
+ size_t written = 0;
+ while(bytes)
+ {
+ ssize_t part = write(fd, (char*)buffer+written, bytes);
+ if(part < 0 && errno != EINTR)
+ break;
+ bytes -= part;
+ written += part;
+ }
+ return written;
+}
+
+/* Same for reading the data. */
+size_t unintr_read(int fd, void *buffer, size_t bytes)
+{
+ size_t got = 0;
+ while(bytes)
+ {
+ ssize_t part = read(fd, (char*)buffer+got, bytes);
+ if(part < 0 && errno != EINTR)
+ break;
+ bytes -= part;
+ got += part;
+ }
+ return got;
+}
+
+#ifndef NO_CATCHSIGNAL
+#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
+void (*catchsignal(int signum, void(*handler)()))()
+{
+ struct sigaction new_sa;
+ struct sigaction old_sa;
+
+#ifdef DONT_CATCH_SIGNALS
+ fprintf (stderr, "Not catching any signals.\n");
+ return ((void (*)()) -1);
+#endif
+
+ new_sa.sa_handler = handler;
+ sigemptyset(&new_sa.sa_mask);
+ new_sa.sa_flags = 0;
+ if(sigaction(signum, &new_sa, &old_sa) == -1)
+ return ((void (*)()) -1);
+ return (old_sa.sa_handler);
+}
+#endif
+#endif
-/*
- dither: Generate shaped noise for dithering
-
- copyright 2009 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 Taihei Monma
-*/
-
-#include "config.h"
-#include "compat.h"
-#include "dither.h"
-
-static const uint32_t init_seed = 2463534242UL;
-
-#define LAP 100
-
-/*
- xorshift random number generator, with output scaling to [-0.5, 0.5]
- This is the white noise...
- See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
-*/
-static float rand_xorshift32(uint32_t *seed)
-{
- union
- {
- uint32_t i;
- float f;
- } fi;
-
- fi.i = *seed;
- fi.i ^= (fi.i<<13);
- fi.i ^= (fi.i>>17);
- fi.i ^= (fi.i<<5);
- *seed = fi.i;
-
- /* scale the number to [-0.5, 0.5] */
-#ifdef IEEE_FLOAT
- fi.i = (fi.i>>9)|0x3f800000;
- fi.f -= 1.5f;
-#else
- fi.f = (double)fi.i / 4294967295.0;
- fi.f -= 0.5f;
-#endif
- return fi.f;
-}
-
-static void white_noise(float *table, size_t count)
-{
- size_t i;
- uint32_t seed = init_seed;
-
- for(i=0; i<count; ++i)
- table[i] = rand_xorshift32(&seed);
-}
-
-static void tpdf_noise(float *table, size_t count)
-{
- size_t i;
- uint32_t seed = init_seed;
-
- for(i=0; i<count; ++i)
- table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
-}
-
-static void highpass_tpdf_noise(float *table, size_t count)
-{
- size_t i;
- uint32_t seed = init_seed;
- /* Ensure some minimum lap for keeping the high-pass filter circular. */
- size_t lap = count > 2*LAP ? LAP : count/2;
-
- float input_noise;
- float xv[9], yv[9];
-
- for(i=0;i<9;i++)
- {
- xv[i] = yv[i] = 0.0f;
- }
-
- for(i=0;i<count+lap;i++)
- {
- if(i==count) seed=init_seed;
-
- /* generate and add 2 random numbers, to make a TPDF noise distribution */
- input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
-
- /* apply 8th order Chebyshev high-pass IIR filter */
- /* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
- Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
- xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8];
- xv[8] = input_noise / 1.382814179e+07;
- yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8];
- yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
- - 56 * (xv[3] + xv[5]) + 70 * xv[4]
- + ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
- + (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
- + (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
- + (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
- if(i>=lap) table[i-lap] = yv[8] * 3.0f;
- }
-}
-
-void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
-{
- switch(noisetype)
- {
- case mpg123_white_noise: white_noise(table, count); break;
- case mpg123_tpdf_noise: tpdf_noise(table, count); break;
- case mpg123_highpass_tpdf_noise:
- highpass_tpdf_noise(table, count);
- break;
- }
-}
-
-/* Generate white noise and shape it with a high pass filter. */
-void dither_table_init(float *dithertable)
-{
- highpass_tpdf_noise(dithertable, DITHERSIZE);
-}
+/* Hack to allow building the same code with and without libtool. */
+#include "intsym.h"
+#include "dither_impl.h"
#else
return 0;
#endif
+ case MPG123_FEATURE_EQUALIZER:
+#ifndef NO_EQUALIZER
+ return 1;
+#else
+ return 0;
+#endif
default: return 0;
}
int attribute_align_arg mpg123_encsize(int encoding)
{
- if(encoding & MPG123_ENC_8)
- return 1;
- else if(encoding & MPG123_ENC_16)
- return 2;
- else if(encoding & MPG123_ENC_24)
- return 3;
- else if(encoding & MPG123_ENC_32 || encoding == MPG123_ENC_FLOAT_32)
- return 4;
- else if(encoding == MPG123_ENC_FLOAT_64)
- return 8;
- else
- return 0;
+ return MPG123_SAMPLESIZE(encoding);
}
/* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
{
int i;
if(mh == NULL) return MPG123_BAD_HANDLE;
-
+#ifndef NO_EQUALIZER
mh->have_eq_settings = 0;
for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);
-
+#endif
return MPG123_OK;
}
void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
{
off_t gapless_samples = fr->gapless_frames*fr->spf;
+ if(fr->gapless_frames < 1) return;
+
debug2("gapless update with new sample count %"OFF_P" as opposed to known %"OFF_P, total_samples, gapless_samples);
if(NOQUIET && total_samples != gapless_samples)
fprintf(stderr, "\nWarning: Real sample count %"OFF_P" differs from given gapless sample count %"OFF_P". Frankenstein stream?\n"
/*
icy: Puny code to pretend for a serious ICY data structure.
- copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1
+ copyright 2007-2015 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
*/
+#include "intsym.h"
#include "icy.h"
void init_icy(struct icy_meta *icy)
* Convert from ICY encoding (windows-1252 codepage) to UTF-8
*/
+#include "config.h"
+#include "intsym.h"
/* Includes string and stdlib headers... */
#include "compat.h"
/*
index: frame index data structure and functions
- copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
+ copyright 2007-2015 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
*/
+#include "intsym.h"
#include "index.h"
#include "debug.h"
return NATIVE_NAME(mpg123_position)(mh, frame_offset, buffered_bytes, current_frame, frames_left, current_seconds, seconds_left);
}
+lfs_alias_t NATIVE_NAME(mpg123_framelength)(mpg123_handle *mh);
+lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_framelength)(mpg123_handle *mh)
+{
+ return NATIVE_NAME(mpg123_framelength)(mh);
+}
+
lfs_alias_t NATIVE_NAME(mpg123_length)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_length)(mpg123_handle *mh)
{
return MPG123_OK;
}
+#undef mpg123_framelength
+/* off_t mpg123_framelength(mpg123_handle *mh); */
+long attribute_align_arg mpg123_framelength(mpg123_handle *mh)
+{
+ long val;
+ off_t largeval;
+
+ largeval = MPG123_LARGENAME(mpg123_framelength)(mh);
+ val = largeval;
+ if(val != largeval)
+ {
+ mh->err = MPG123_LFS_OVERFLOW;
+ return MPG123_ERR;
+ }
+ return val;
+}
+
#undef mpg123_length
/* off_t mpg123_length(mpg123_handle *mh); */
long attribute_align_arg mpg123_length(mpg123_handle *mh)
return ret;
}
-
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
{
+#ifndef NO_EQUALIZER
if(mh == NULL) return MPG123_BAD_HANDLE;
if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
switch(channel)
return MPG123_ERR;
}
mh->have_eq_settings = TRUE;
+#endif
return MPG123_OK;
}
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
{
double ret = 0.;
+#ifndef NO_EQUALIZER
/* Handle this gracefully. When there is no band, it has no volume. */
if(mh != NULL && band > -1 && band < 32)
case MPG123_RIGHT: ret = REAL_TO_DOUBLE(mh->equalizer[1][band]); break;
/* Default case is already handled: ret = 0 */
}
-
+#endif
return ret;
}
-
/* plain file access, no http! */
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
{
return MPG123_OK;
}
+off_t attribute_align_arg mpg123_framelength(mpg123_handle *mh)
+{
+ int b;
+ if(mh == NULL)
+ return MPG123_ERR;
+ b = init_track(mh);
+ if(b<0)
+ return b;
+ if(mh->track_frames > 0)
+ return mh->track_frames;
+ if(mh->rdat.filelen > 0)
+ { /* A bad estimate. Ignoring tags 'n stuff. */
+ double bpf = mh->mean_framesize > 0.
+ ? mh->mean_framesize
+ : compute_bpf(mh);
+ return (off_t)((double)(mh->rdat.filelen)/bpf+0.5);
+ }
+ /* Last resort: No view of the future, can at least count the frames that
+ were already parsed. */
+ if(mh->num > -1)
+ return mh->num+1;
+ /* Giving up. */
+ return MPG123_ERR;
+}
+
off_t attribute_align_arg mpg123_length(mpg123_handle *mh)
{
int b;
return length;
}
+
int attribute_align_arg mpg123_scan(mpg123_handle *mh)
{
int b;
# endif
# ifndef NO_REAL
fr->synths.plain[r_1to1][f_real] = synth_1to1_real_avx;
- fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_avx;
+ fr->synths.stereo[r_1to1][f_real] = synth_1to1_fltst_avx;
# endif
# ifndef NO_32BIT
fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_avx;
# endif
# ifndef NO_REAL
fr->synths.plain[r_1to1][f_real] = synth_1to1_real_altivec;
- fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_altivec;
+ fr->synths.stereo[r_1to1][f_real] = synth_1to1_fltst_altivec;
# endif
# ifndef NO_32BIT
fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_altivec;
# endif
# ifndef NO_REAL
fr->synths.plain[r_1to1][f_real] = synth_1to1_real_neon64;
- fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_neon64;
+ fr->synths.stereo[r_1to1][f_real] = synth_1to1_fltst_neon64;
# endif
# ifndef NO_32BIT
fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_neon64;
- fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32_stereo_neon64;
+ fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32st_neon64;
# endif
done = 1;
}
{
unsigned char gt = fr->bsbuf[lame_offset] >> 5;
unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7;
- float factor = (fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1;
+ float factor = (fr->bsbuf[lame_offset] & 0x2) ? -0.1f : 0.1f;
unsigned short gain = bit_read_short(fr->bsbuf, &lame_offset) & 0x1ff; /* 19 in (2 cycles) */
if(origin == 0 || gt < 1 || gt > 2) continue;
return PARSE_AGAIN;
}
+static int handle_apetag(mpg123_handle *fr, unsigned long newhead)
+{
+ unsigned char apebuf[28];
+ unsigned long val;
+ int i, ret;
+
+ fr->oldhead = 0;
+
+ /* Apetag headers are 32 bytes, newhead contains 4, read the rest */
+ if((ret=fr->rd->fullread(fr,apebuf,28)) < 0) return ret;
+
+ /* Apetags start with "APETAGEX", "APET" is already tested. */
+ if(strncmp((char *)apebuf,"AGEX",4) != 0)
+ goto apetag_bad;
+
+ /* Version must be 2.000 / 2000 */
+ val = (apebuf[7]<<24)|(apebuf[6]<<16)|(apebuf[5]<<8)|apebuf[4];
+ if(val != 2000)
+ goto apetag_bad;
+
+ /* Last 8 bytes must be 0 */
+ for(i=20; i<28; i++)
+ if(apebuf[i])
+ goto apetag_bad;
+
+ /* Looks good, skip the rest. */
+ val = (apebuf[11]<<24)|(apebuf[10]<<16)|(apebuf[9]<<8)|apebuf[8];
+ if((ret=fr->rd->skip_bytes(fr,val)) < 0) return ret;
+
+ return PARSE_AGAIN;
+
+apetag_bad:
+ if(fr->rd->back_bytes(fr,31) < 0 && NOQUIET)
+ error("Cannot seek 31 bytes back!");
+
+ return PARSE_AGAIN; /* Give the resync code a chance to fix things */
+}
+
/* Advance a byte in stream to get next possible header and forget
buffered data if possible (for feed reader). */
#define FORGET_INTERVAL 1024 /* Used by callers to set forget flag each <n> bytes. */
{
return handle_id3v2(fr, newhead);
}
+ /* Check for an apetag header */
+ if(newhead == ('A'<<24)+('P'<<16)+('E'<<8)+'T')
+ {
+ return handle_apetag(fr, newhead);
+ }
else if(NOQUIET && fr->silent_resync == 0)
{
fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset %"OFF_P".\n",
void attribute_align_arg mpg123_init_string(mpg123_string* sb)
{
+ /* Handing in NULL here is a fatal mistake and rightfully so. */
sb->p = NULL;
sb->size = 0;
sb->fill = 0;
void attribute_align_arg mpg123_free_string(mpg123_string* sb)
{
+ if(!sb)
+ return;
if(sb->p != NULL) free(sb->p);
mpg123_init_string(sb);
}
int attribute_align_arg mpg123_grow_string(mpg123_string* sb, size_t new)
{
+ if(!sb)
+ return 0;
if(sb->size < new) return mpg123_resize_string(sb, new);
else return 1;
}
int attribute_align_arg mpg123_resize_string(mpg123_string* sb, size_t new)
{
+ if(!sb)
+ return 0;
debug3("resizing string pointer %p from %lu to %lu", (void*) sb->p, (unsigned long)sb->size, (unsigned long)new);
if(new == 0)
{
{
size_t fill;
char *text;
- if(to == NULL) return -1;
debug2("called copy_string with %p -> %p", (void*)from, (void*)to);
+ if(to == NULL)
+ return 0;
if(from == NULL)
{
fill = 0;
int attribute_align_arg mpg123_add_string(mpg123_string* sb, const char* stuff)
{
debug1("adding %s", stuff);
- return mpg123_add_substring(sb, stuff, 0, strlen(stuff));
+ return mpg123_add_substring(sb, stuff, 0, stuff ? strlen(stuff) : 0);
}
int attribute_align_arg mpg123_add_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count)
{
debug("adding a substring");
+ if(!sb || !stuff)
+ return 0;
if(sb->fill) /* includes zero byte... */
{
if( (SIZE_MAX - sb->fill >= count) /* Avoid overflow. */
int attribute_align_arg mpg123_set_substring(mpg123_string* sb, const char* stuff, size_t from, size_t count)
{
+ if(!sb)
+ return 0;
sb->fill = 0;
return mpg123_add_substring(sb, stuff, from, count);
}
int attribute_align_arg mpg123_set_string(mpg123_string* sb, const char* stuff)
{
+ if(!sb)
+ return 0;
sb->fill = 0;
return mpg123_add_string(sb, stuff);
}
size_t bytelen;
/* Notions of empty string. If there's only a single character, it has to be the trailing zero, and if the first is the trailing zero anyway, we got empty. */
- if(sb->fill < 2 || sb->p[0] == 0) return 0;
+ if(!sb || sb->fill < 2 || sb->p[0] == 0) return 0;
/* Find the first non-null character from the back.
We already established that the first character is non-null
int synth_1to1_i586(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
int ret;
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
ret = synth_1to1_i586_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
if(final) fr->buffer.fill += 128;
return ret;
{
int ret;
int bo_dither[2]; /* Temporary workaround? Could expand the asm code. */
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
/* Applying this hack, to change the asm only bit by bit (adding dithernoise pointer). */
bo_dither[0] = fr->bo;
bo_dither[1] = fr->ditherindex;
int synth_1to1_3dnow(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
int ret;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer_3dnow(bandPtr,channel,fr->equalizer);
-
+#endif
/* this is in asm, can be dither or not */
/* uh, is this return from pointer correct? */
ret = (int) synth_1to1_3dnow_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
/* This is just a hull to use the mpg123 handle. */
int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
/* in asm */
synth_1to1_MMX(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
if(final) fr->buffer.fill += 128;
real *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
/* This is just a hull to use the mpg123 handle. */
int synth_1to1_sse(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
synth_1to1_sse_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
if(final) fr->buffer.fill += 128;
return 0;
/* This is just a hull to use the mpg123 handle. */
int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
synth_1to1_3dnowext_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
if(final) fr->buffer.fill += 128;
return 0;
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
short *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
short *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->short_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
short *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
short *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->short_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
short *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
short *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->short_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
short *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
short *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->short_buffs[0];
real *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
return 0;
}
-int synth_1to1_real_stereo_altivec(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
+int synth_1to1_fltst_altivec(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
return 0;
}
-int synth_1to1_real_stereo_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
+int synth_1to1_fltst_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
return 0;
}
-int synth_1to1_real_stereo_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
+int synth_1to1_fltst_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
real *b0l, *b0r, **bufl, **bufr;
int bo1;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
real *b0, **buf;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
-
+#endif
if(!channel)
{
fr->bo--;
return clip;
}
-int synth_1to1_s32_stereo_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
+int synth_1to1_s32st_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
int32_t *samples = (int32_t *) (fr->buffer.data+fr->buffer.fill);
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
-
+#ifndef NO_EQUALIZER
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
-
+#endif
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
#endif
#endif
+#ifdef REAL_IS_FIXED
+/* Need saturating multiplication that keeps table values in 32 bit range,
+ with the option to swap sign at will (so -2**31 is out).
+ This code is far from the decoder core and so assembly optimization might
+ be overkill. */
+static int32_t sat_mul32(int32_t a, int32_t b)
+{
+ int64_t prod = (int64_t)a * (int64_t)b;
+ /* TODO: record the clipping? An extra flag? */
+ if(prod > 2147483647L) return 2147483647L;
+ if(prod < -2147483647L) return -2147483647L;
+ return (int32_t)prod;
+}
+#endif
+
void make_decode_tables(mpg123_handle *fr)
{
int i,j;
debug1("decode tables with scaleval %g", scaleval);
#ifdef REAL_IS_FIXED
scaleval_long = DOUBLE_TO_REAL_15(scaleval);
+ debug1("decode table with fixed scaleval %li", (long)scaleval_long);
+ if(scaleval_long > 28618 || scaleval_long < -28618)
+ {
+ /* TODO: Limit the scaleval itself or limit the multiplication afterwards?
+ The former basically disables significant amplification for fixed-point
+ decoders, but avoids (possibly subtle) distortion. */
+ /* This would limit the amplification instead:
+ scaleval_long = scaleval_long < 0 ? -28618 : 28618; */
+ if(NOQUIET) warning("Desired amplification may introduce distortion.");
+ }
#endif
for(i=0,j=0;i<256;i++,j++,idx+=32)
{
if(idx < 512+16)
#ifdef REAL_IS_FIXED
- fr->decwin[idx+16] = fr->decwin[idx] = REAL_SCALE_WINDOW(intwinbase[j] * scaleval_long);
+ fr->decwin[idx+16] = fr->decwin[idx] =
+ REAL_SCALE_WINDOW(sat_mul32(intwinbase[j],scaleval_long));
#else
fr->decwin[idx+16] = fr->decwin[idx] = DOUBLE_TO_REAL((double) intwinbase[j] * scaleval);
#endif
{
if(idx < 512+16)
#ifdef REAL_IS_FIXED
- fr->decwin[idx+16] = fr->decwin[idx] = REAL_SCALE_WINDOW(intwinbase[j] * scaleval_long);
+ fr->decwin[idx+16] = fr->decwin[idx] =
+ REAL_SCALE_WINDOW(sat_mul32(intwinbase[j],scaleval_long));
#else
fr->decwin[idx+16] = fr->decwin[idx] = DOUBLE_TO_REAL((double) intwinbase[j] * scaleval);
#endif