Path: blob/master/libs/mpg123/src/libmpg123/mpg123lib_intern.h
4394 views
/*1mpg123lib_intern: Common non-public stuff for libmpg12323copyright 1995-2023 by the mpg123 project - free software under the terms of the LGPL 2.14see COPYING and AUTHORS files in distribution or http://mpg123.org56derived from the old mpg123.h7*/89#ifndef MPG123_H_INTERN10#define MPG123_H_INTERN1112#define MPG123_RATES 913#define MPG123_ENCODINGS 121415#include "config.h" /* Load this before _anything_ */1617#include "../common/abi_align.h"1819#include "../compat/compat.h"2021// Only portable API plays a role in the library itself, outside of lfs_wrap.c.22// Also, we need to ensure no suffix renaming for the primary implementations.23// But: The _definition_ of non-portable API needs to be present for those24// primary implementations being exported for DLL builds. Just the largefile25// renaming needs to be skipped!26#define MPG123_NO_LARGENAME27#define MPG123_ENUM_API28#include "mpg123.h"2930#define SKIP_JUNK 13132#ifndef M_PI33# define M_PI 3.1415926535897932384634#endif35#ifndef M_SQRT236# define M_SQRT2 1.4142135623730950488037#endif3839#ifdef SUNOS40#define memmove(dst,src,size) bcopy(src,dst,size)41#endif4243// The real type is either 32 bit float or integer. We do not attempt44// double precision for MPEG audio decoding (or any audio storage/compression45// format, even).46// The calctables tool works in double precision float, but converts to fixed47// point 'real' on output in addition to floating point.4849// The base type used in the computation code.50// With C11 we could rely on tgmath for sin() to use the right precision.51#ifdef CALCTABLES52# define clreal double53# define COS cos54# define SIN sin55# define TAN tan56# define POW pow57#else58# define clreal float59# define COS cosf60# define SIN sinf61# define TAN tanf62# define POW powf63#endif6465#if defined(REAL_IS_FLOAT) && !defined(CALCTABLES)6667#define real float6869#elif defined(REAL_IS_FIXED) || defined(CALCTABLES)7071#ifdef RUNTIME_TABLES72#error "Runtime tables are only for floating point decoders."73#endif7475# define real int32_t76# define dreal int64_t7778/*79for fixed-point decoders, use pre-calculated tables to avoid expensive floating-point maths80undef this macro for run-time calculation81*/8283# define REAL_RADIX 2484# define REAL_FACTOR 16777216.08586static inline int32_t double_to_long_rounded(double x, double scalefac)87{88x *= scalefac;89x += (x > 0) ? 0.5 : -0.5;90return (int32_t)x;91}9293static inline int32_t scale_rounded(int32_t x, int shift)94{95x += (x >> 31);96x >>= (shift - 1);97x += (x & 1);98return (x >> 1);99}100101# ifdef __GNUC__102# if defined(OPT_I386)103/* for i386_nofpu decoder */104# define REAL_MUL_ASM(x, y, radix) \105({ \106long _x=(x), _y=(y); \107__asm__ ( \108"imull %1 \n\t" \109"shrdl %2, %%edx, %0 \n\t" \110: "+&a" (_x) \111: "mr" (_y), "I" (radix) \112: "%edx", "cc" \113); \114_x; \115})116117# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \118({ \119long _x=(x), _y=(y), _radix=(radix); \120__asm__ ( \121"imull %1 \n\t" \122"shrdl %%cl, %%edx, %0 \n\t" \123: "+&a" (_x) \124: "mr" (_y), "c" (_radix) \125: "%edx", "cc" \126); \127_x; \128})129# elif defined(OPT_PPC)130/* for powerpc */131# define REAL_MUL_ASM(x, y, radix) \132({ \133long _x=(x), _y=(y), _mull, _mulh; \134__asm__ ( \135"mullw %0, %2, %3 \n\t" \136"mulhw %1, %2, %3 \n\t" \137"srwi %0, %0, %4 \n\t" \138"rlwimi %0, %1, %5, 0, %6 \n\t" \139: "=&r" (_mull), "=&r" (_mulh) \140: "r" (_x), "r" (_y), "i" (radix), "i" (32-(radix)), "i" ((radix)-1) \141); \142_mull; \143})144145# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \146({ \147long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \148__asm__ ( \149"mullw %0, %3, %4 \n\t" \150"mulhw %1, %3, %4 \n\t" \151"subfic %2, %5, 32 \n\t" \152"srw %0, %0, %5 \n\t" \153"slw %1, %1, %2 \n\t" \154"or %0, %0, %1 \n\t" \155: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \156: "r" (_x), "r" (_y), "r" (_radix) \157: "cc" \158); \159_mull; \160})161# elif defined(OPT_ARM)162/* for arm */163# define REAL_MUL_ASM(x, y, radix) \164({ \165long _x=(x), _y=(y), _mull, _mulh; \166__asm__ ( \167"smull %0, %1, %2, %3 \n\t" \168"mov %0, %0, lsr %4 \n\t" \169"orr %0, %0, %1, lsl %5 \n\t" \170: "=&r" (_mull), "=&r" (_mulh) \171: "r" (_x), "r" (_y), "M" (radix), "M" (32-(radix)) \172); \173_mull; \174})175176# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \177({ \178long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \179__asm__ ( \180"smull %0, %1, %3, %4 \n\t" \181"mov %0, %0, lsr %5 \n\t" \182"rsb %2, %5, #32 \n\t" \183"mov %1, %1, lsl %2 \n\t" \184"orr %0, %0, %1 \n\t" \185: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \186: "r" (_x), "r" (_y), "r" (_radix) \187); \188_mull; \189})190# endif191# endif192193/* I just changed the (int) to (real) there... seemed right. */194# define DOUBLE_TO_REAL(x) (double_to_long_rounded(x, REAL_FACTOR))195# define SCALE_15 32768.0196# define DOUBLE_TO_REAL_15(x) (double_to_long_rounded(x, SCALE_15))197# define SCALE_POW43 8192.0198# define DOUBLE_TO_REAL_POW43(x) (double_to_long_rounded(x, SCALE_POW43))199# define SCALE_LAYER12 1073741824.0200# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (double_to_long_rounded(x, SCALE_LAYER12))201# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (double_to_long_rounded(x, pow(2.0,gainpow2_scale[y])))202# define REAL_TO_DOUBLE(x) ((double)(x) / REAL_FACTOR)203# ifdef REAL_MUL_ASM204# define REAL_MUL(x, y) REAL_MUL_ASM(x, y, REAL_RADIX)205# define REAL_MUL_15(x, y) REAL_MUL_ASM(x, y, 15)206# define REAL_MUL_SCALE_LAYER12(x, y) REAL_MUL_ASM(x, y, 15 + 30 - REAL_RADIX)207# else208# define REAL_MUL(x, y) (((dreal)(x) * (dreal)(y)) >> REAL_RADIX)209# define REAL_MUL_15(x, y) (((dreal)(x) * (dreal)(y)) >> 15)210# define REAL_MUL_SCALE_LAYER12(x, y) (((dreal)(x) * (dreal)(y)) >> (15 + 30 - REAL_RADIX))211# endif212# ifdef REAL_MUL_SCALE_LAYER3_ASM213# define REAL_MUL_SCALE_LAYER3(x, y, z) REAL_MUL_SCALE_LAYER3_ASM(x, y, 13 + gainpow2_scale[z] - REAL_RADIX)214# else215# define REAL_MUL_SCALE_LAYER3(x, y, z) (((dreal)(x) * (dreal)(y)) >> (13 + gainpow2_scale[z] - REAL_RADIX))216# endif217# define REAL_SCALE_LAYER12(x) ((real)((x) >> (30 - REAL_RADIX)))218# define REAL_SCALE_LAYER3(x, y) ((real)((x) >> (gainpow2_scale[y] - REAL_RADIX)))219# ifdef ACCURATE_ROUNDING220# define REAL_MUL_SYNTH(x, y) REAL_MUL(x, y)221# define REAL_SCALE_DCT64(x) (x)222# define REAL_SCALE_WINDOW(x) (x)223# else224# define REAL_MUL_SYNTH(x, y) ((x) * (y))225# define REAL_SCALE_DCT64(x) ((x) >> 8)226# define REAL_SCALE_WINDOW(x) scale_rounded(x, 16)227# endif228229#else230231#error "Simple float or fixed-point, nothing else makes sense."232233#endif234235#ifndef DOUBLE_TO_REAL236# define DOUBLE_TO_REAL(x) (real)(x)237#endif238#ifndef DOUBLE_TO_REAL_15239# define DOUBLE_TO_REAL_15(x) (real)(x)240#endif241#ifndef DOUBLE_TO_REAL_POW43242# define DOUBLE_TO_REAL_POW43(x) (real)(x)243#endif244#ifndef DOUBLE_TO_REAL_SCALE_LAYER12245# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (real)(x)246#endif247#ifndef DOUBLE_TO_REAL_SCALE_LAYER3248# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (real)(x)249#endif250#ifndef REAL_TO_DOUBLE251# define REAL_TO_DOUBLE(x) (x)252#endif253254#ifndef REAL_MUL255# define REAL_MUL(x, y) ((x) * (y))256#endif257#ifndef REAL_MUL_SYNTH258# define REAL_MUL_SYNTH(x, y) ((x) * (y))259#endif260#ifndef REAL_MUL_15261# define REAL_MUL_15(x, y) ((x) * (y))262#endif263#ifndef REAL_MUL_SCALE_LAYER12264# define REAL_MUL_SCALE_LAYER12(x, y) ((x) * (y))265#endif266#ifndef REAL_MUL_SCALE_LAYER3267# define REAL_MUL_SCALE_LAYER3(x, y, z) ((x) * (y))268#endif269#ifndef REAL_SCALE_LAYER12270# define REAL_SCALE_LAYER12(x) (x)271#endif272#ifndef REAL_SCALE_LAYER3273# define REAL_SCALE_LAYER3(x, y) (x)274#endif275#ifndef REAL_SCALE_DCT64276# define REAL_SCALE_DCT64(x) (x)277#endif278279/* used to be: AUDIOBUFSIZE = n*64 with n=1,2,3 ...280now: factor on minimum frame buffer size (which takes upsampling into account) */281#define AUDIOBUFSIZE 2282283#include "../common/true.h"284285#define MAX_NAME_SIZE 81286#define SBLIMIT 32287#define SCALE_BLOCK 12288#define SSLIMIT 18289290/* Same as MPG_M_* */291#define MPG_MD_STEREO 0292#define MPG_MD_JOINT_STEREO 1293#define MPG_MD_DUAL_CHANNEL 2294#define MPG_MD_MONO 3295296/* We support short or float output samples...297Short integer amplitude is scaled by this. */298#define SHORT_SCALE 32768299/* That scales a short-scaled value to a 32bit integer scaled one300value = 2**31/2**15 */301#define S32_RESCALE 65536302303/* Pre Shift fo 16 to 8 bit converter table */304#define AUSHIFT (3)305306#include "optimize.h"307#include "decode.h"308#include "parse.h"309#include "frame.h"310311/* fr is a mpg123_handle* by convention here... */312#define NOQUIET (!(fr->p.flags & MPG123_QUIET))313#define VERBOSE (NOQUIET && fr->p.verbose)314#define VERBOSE2 (NOQUIET && fr->p.verbose > 1)315#define VERBOSE3 (NOQUIET && fr->p.verbose > 2)316#define VERBOSE4 (NOQUIET && fr->p.verbose > 3)317#define PVERB(mp, level) (!((mp)->flags & MPG123_QUIET) && (mp)->verbose >= (level))318319int INT123_decode_update(mpg123_handle *mh);320/* residing in format.c */321int64_t INT123_decoder_synth_bytes(mpg123_handle *fr , int64_t s);322int64_t INT123_samples_to_bytes(mpg123_handle *fr , int64_t s);323int64_t INT123_bytes_to_samples(mpg123_handle *fr , int64_t b);324int64_t INT123_outblock_bytes(mpg123_handle *fr, int64_t s);325/* Postprocessing format conversion of freshly decoded buffer. */326void INT123_postprocess_buffer(mpg123_handle *fr);327328/* If networking is enabled and we really mean internal networking, the timeout_read function is available. */329#if defined (NETWORK) && !defined (WANT_WIN32_SOCKETS)330/* Does not work with win32 */331#define TIMEOUT_READ332#endif333334// Change a given linear factor by the given dB value, bounded335// to +/- 60 dB.336static inline double dbchange(double base_factor, double db)337{338double nscale = base_factor * pow(10, db/20);339if(nscale < 0.001) // -60 dB340nscale = 0.001;341if(nscale > 1000)342nscale = 1000; // +60 dB343return nscale;344}345346#endif347348349