Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/mpg123/src/libmpg123/mpg123lib_intern.h
4394 views
1
/*
2
mpg123lib_intern: Common non-public stuff for libmpg123
3
4
copyright 1995-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
5
see COPYING and AUTHORS files in distribution or http://mpg123.org
6
7
derived from the old mpg123.h
8
*/
9
10
#ifndef MPG123_H_INTERN
11
#define MPG123_H_INTERN
12
13
#define MPG123_RATES 9
14
#define MPG123_ENCODINGS 12
15
16
#include "config.h" /* Load this before _anything_ */
17
18
#include "../common/abi_align.h"
19
20
#include "../compat/compat.h"
21
22
// Only portable API plays a role in the library itself, outside of lfs_wrap.c.
23
// Also, we need to ensure no suffix renaming for the primary implementations.
24
// But: The _definition_ of non-portable API needs to be present for those
25
// primary implementations being exported for DLL builds. Just the largefile
26
// renaming needs to be skipped!
27
#define MPG123_NO_LARGENAME
28
#define MPG123_ENUM_API
29
#include "mpg123.h"
30
31
#define SKIP_JUNK 1
32
33
#ifndef M_PI
34
# define M_PI 3.14159265358979323846
35
#endif
36
#ifndef M_SQRT2
37
# define M_SQRT2 1.41421356237309504880
38
#endif
39
40
#ifdef SUNOS
41
#define memmove(dst,src,size) bcopy(src,dst,size)
42
#endif
43
44
// The real type is either 32 bit float or integer. We do not attempt
45
// double precision for MPEG audio decoding (or any audio storage/compression
46
// format, even).
47
// The calctables tool works in double precision float, but converts to fixed
48
// point 'real' on output in addition to floating point.
49
50
// The base type used in the computation code.
51
// With C11 we could rely on tgmath for sin() to use the right precision.
52
#ifdef CALCTABLES
53
# define clreal double
54
# define COS cos
55
# define SIN sin
56
# define TAN tan
57
# define POW pow
58
#else
59
# define clreal float
60
# define COS cosf
61
# define SIN sinf
62
# define TAN tanf
63
# define POW powf
64
#endif
65
66
#if defined(REAL_IS_FLOAT) && !defined(CALCTABLES)
67
68
#define real float
69
70
#elif defined(REAL_IS_FIXED) || defined(CALCTABLES)
71
72
#ifdef RUNTIME_TABLES
73
#error "Runtime tables are only for floating point decoders."
74
#endif
75
76
# define real int32_t
77
# define dreal int64_t
78
79
/*
80
for fixed-point decoders, use pre-calculated tables to avoid expensive floating-point maths
81
undef this macro for run-time calculation
82
*/
83
84
# define REAL_RADIX 24
85
# define REAL_FACTOR 16777216.0
86
87
static inline int32_t double_to_long_rounded(double x, double scalefac)
88
{
89
x *= scalefac;
90
x += (x > 0) ? 0.5 : -0.5;
91
return (int32_t)x;
92
}
93
94
static inline int32_t scale_rounded(int32_t x, int shift)
95
{
96
x += (x >> 31);
97
x >>= (shift - 1);
98
x += (x & 1);
99
return (x >> 1);
100
}
101
102
# ifdef __GNUC__
103
# if defined(OPT_I386)
104
/* for i386_nofpu decoder */
105
# define REAL_MUL_ASM(x, y, radix) \
106
({ \
107
long _x=(x), _y=(y); \
108
__asm__ ( \
109
"imull %1 \n\t" \
110
"shrdl %2, %%edx, %0 \n\t" \
111
: "+&a" (_x) \
112
: "mr" (_y), "I" (radix) \
113
: "%edx", "cc" \
114
); \
115
_x; \
116
})
117
118
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
119
({ \
120
long _x=(x), _y=(y), _radix=(radix); \
121
__asm__ ( \
122
"imull %1 \n\t" \
123
"shrdl %%cl, %%edx, %0 \n\t" \
124
: "+&a" (_x) \
125
: "mr" (_y), "c" (_radix) \
126
: "%edx", "cc" \
127
); \
128
_x; \
129
})
130
# elif defined(OPT_PPC)
131
/* for powerpc */
132
# define REAL_MUL_ASM(x, y, radix) \
133
({ \
134
long _x=(x), _y=(y), _mull, _mulh; \
135
__asm__ ( \
136
"mullw %0, %2, %3 \n\t" \
137
"mulhw %1, %2, %3 \n\t" \
138
"srwi %0, %0, %4 \n\t" \
139
"rlwimi %0, %1, %5, 0, %6 \n\t" \
140
: "=&r" (_mull), "=&r" (_mulh) \
141
: "r" (_x), "r" (_y), "i" (radix), "i" (32-(radix)), "i" ((radix)-1) \
142
); \
143
_mull; \
144
})
145
146
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
147
({ \
148
long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \
149
__asm__ ( \
150
"mullw %0, %3, %4 \n\t" \
151
"mulhw %1, %3, %4 \n\t" \
152
"subfic %2, %5, 32 \n\t" \
153
"srw %0, %0, %5 \n\t" \
154
"slw %1, %1, %2 \n\t" \
155
"or %0, %0, %1 \n\t" \
156
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
157
: "r" (_x), "r" (_y), "r" (_radix) \
158
: "cc" \
159
); \
160
_mull; \
161
})
162
# elif defined(OPT_ARM)
163
/* for arm */
164
# define REAL_MUL_ASM(x, y, radix) \
165
({ \
166
long _x=(x), _y=(y), _mull, _mulh; \
167
__asm__ ( \
168
"smull %0, %1, %2, %3 \n\t" \
169
"mov %0, %0, lsr %4 \n\t" \
170
"orr %0, %0, %1, lsl %5 \n\t" \
171
: "=&r" (_mull), "=&r" (_mulh) \
172
: "r" (_x), "r" (_y), "M" (radix), "M" (32-(radix)) \
173
); \
174
_mull; \
175
})
176
177
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
178
({ \
179
long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \
180
__asm__ ( \
181
"smull %0, %1, %3, %4 \n\t" \
182
"mov %0, %0, lsr %5 \n\t" \
183
"rsb %2, %5, #32 \n\t" \
184
"mov %1, %1, lsl %2 \n\t" \
185
"orr %0, %0, %1 \n\t" \
186
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
187
: "r" (_x), "r" (_y), "r" (_radix) \
188
); \
189
_mull; \
190
})
191
# endif
192
# endif
193
194
/* I just changed the (int) to (real) there... seemed right. */
195
# define DOUBLE_TO_REAL(x) (double_to_long_rounded(x, REAL_FACTOR))
196
# define SCALE_15 32768.0
197
# define DOUBLE_TO_REAL_15(x) (double_to_long_rounded(x, SCALE_15))
198
# define SCALE_POW43 8192.0
199
# define DOUBLE_TO_REAL_POW43(x) (double_to_long_rounded(x, SCALE_POW43))
200
# define SCALE_LAYER12 1073741824.0
201
# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (double_to_long_rounded(x, SCALE_LAYER12))
202
# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (double_to_long_rounded(x, pow(2.0,gainpow2_scale[y])))
203
# define REAL_TO_DOUBLE(x) ((double)(x) / REAL_FACTOR)
204
# ifdef REAL_MUL_ASM
205
# define REAL_MUL(x, y) REAL_MUL_ASM(x, y, REAL_RADIX)
206
# define REAL_MUL_15(x, y) REAL_MUL_ASM(x, y, 15)
207
# define REAL_MUL_SCALE_LAYER12(x, y) REAL_MUL_ASM(x, y, 15 + 30 - REAL_RADIX)
208
# else
209
# define REAL_MUL(x, y) (((dreal)(x) * (dreal)(y)) >> REAL_RADIX)
210
# define REAL_MUL_15(x, y) (((dreal)(x) * (dreal)(y)) >> 15)
211
# define REAL_MUL_SCALE_LAYER12(x, y) (((dreal)(x) * (dreal)(y)) >> (15 + 30 - REAL_RADIX))
212
# endif
213
# ifdef REAL_MUL_SCALE_LAYER3_ASM
214
# define REAL_MUL_SCALE_LAYER3(x, y, z) REAL_MUL_SCALE_LAYER3_ASM(x, y, 13 + gainpow2_scale[z] - REAL_RADIX)
215
# else
216
# define REAL_MUL_SCALE_LAYER3(x, y, z) (((dreal)(x) * (dreal)(y)) >> (13 + gainpow2_scale[z] - REAL_RADIX))
217
# endif
218
# define REAL_SCALE_LAYER12(x) ((real)((x) >> (30 - REAL_RADIX)))
219
# define REAL_SCALE_LAYER3(x, y) ((real)((x) >> (gainpow2_scale[y] - REAL_RADIX)))
220
# ifdef ACCURATE_ROUNDING
221
# define REAL_MUL_SYNTH(x, y) REAL_MUL(x, y)
222
# define REAL_SCALE_DCT64(x) (x)
223
# define REAL_SCALE_WINDOW(x) (x)
224
# else
225
# define REAL_MUL_SYNTH(x, y) ((x) * (y))
226
# define REAL_SCALE_DCT64(x) ((x) >> 8)
227
# define REAL_SCALE_WINDOW(x) scale_rounded(x, 16)
228
# endif
229
230
#else
231
232
#error "Simple float or fixed-point, nothing else makes sense."
233
234
#endif
235
236
#ifndef DOUBLE_TO_REAL
237
# define DOUBLE_TO_REAL(x) (real)(x)
238
#endif
239
#ifndef DOUBLE_TO_REAL_15
240
# define DOUBLE_TO_REAL_15(x) (real)(x)
241
#endif
242
#ifndef DOUBLE_TO_REAL_POW43
243
# define DOUBLE_TO_REAL_POW43(x) (real)(x)
244
#endif
245
#ifndef DOUBLE_TO_REAL_SCALE_LAYER12
246
# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (real)(x)
247
#endif
248
#ifndef DOUBLE_TO_REAL_SCALE_LAYER3
249
# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (real)(x)
250
#endif
251
#ifndef REAL_TO_DOUBLE
252
# define REAL_TO_DOUBLE(x) (x)
253
#endif
254
255
#ifndef REAL_MUL
256
# define REAL_MUL(x, y) ((x) * (y))
257
#endif
258
#ifndef REAL_MUL_SYNTH
259
# define REAL_MUL_SYNTH(x, y) ((x) * (y))
260
#endif
261
#ifndef REAL_MUL_15
262
# define REAL_MUL_15(x, y) ((x) * (y))
263
#endif
264
#ifndef REAL_MUL_SCALE_LAYER12
265
# define REAL_MUL_SCALE_LAYER12(x, y) ((x) * (y))
266
#endif
267
#ifndef REAL_MUL_SCALE_LAYER3
268
# define REAL_MUL_SCALE_LAYER3(x, y, z) ((x) * (y))
269
#endif
270
#ifndef REAL_SCALE_LAYER12
271
# define REAL_SCALE_LAYER12(x) (x)
272
#endif
273
#ifndef REAL_SCALE_LAYER3
274
# define REAL_SCALE_LAYER3(x, y) (x)
275
#endif
276
#ifndef REAL_SCALE_DCT64
277
# define REAL_SCALE_DCT64(x) (x)
278
#endif
279
280
/* used to be: AUDIOBUFSIZE = n*64 with n=1,2,3 ...
281
now: factor on minimum frame buffer size (which takes upsampling into account) */
282
#define AUDIOBUFSIZE 2
283
284
#include "../common/true.h"
285
286
#define MAX_NAME_SIZE 81
287
#define SBLIMIT 32
288
#define SCALE_BLOCK 12
289
#define SSLIMIT 18
290
291
/* Same as MPG_M_* */
292
#define MPG_MD_STEREO 0
293
#define MPG_MD_JOINT_STEREO 1
294
#define MPG_MD_DUAL_CHANNEL 2
295
#define MPG_MD_MONO 3
296
297
/* We support short or float output samples...
298
Short integer amplitude is scaled by this. */
299
#define SHORT_SCALE 32768
300
/* That scales a short-scaled value to a 32bit integer scaled one
301
value = 2**31/2**15 */
302
#define S32_RESCALE 65536
303
304
/* Pre Shift fo 16 to 8 bit converter table */
305
#define AUSHIFT (3)
306
307
#include "optimize.h"
308
#include "decode.h"
309
#include "parse.h"
310
#include "frame.h"
311
312
/* fr is a mpg123_handle* by convention here... */
313
#define NOQUIET (!(fr->p.flags & MPG123_QUIET))
314
#define VERBOSE (NOQUIET && fr->p.verbose)
315
#define VERBOSE2 (NOQUIET && fr->p.verbose > 1)
316
#define VERBOSE3 (NOQUIET && fr->p.verbose > 2)
317
#define VERBOSE4 (NOQUIET && fr->p.verbose > 3)
318
#define PVERB(mp, level) (!((mp)->flags & MPG123_QUIET) && (mp)->verbose >= (level))
319
320
int INT123_decode_update(mpg123_handle *mh);
321
/* residing in format.c */
322
int64_t INT123_decoder_synth_bytes(mpg123_handle *fr , int64_t s);
323
int64_t INT123_samples_to_bytes(mpg123_handle *fr , int64_t s);
324
int64_t INT123_bytes_to_samples(mpg123_handle *fr , int64_t b);
325
int64_t INT123_outblock_bytes(mpg123_handle *fr, int64_t s);
326
/* Postprocessing format conversion of freshly decoded buffer. */
327
void INT123_postprocess_buffer(mpg123_handle *fr);
328
329
/* If networking is enabled and we really mean internal networking, the timeout_read function is available. */
330
#if defined (NETWORK) && !defined (WANT_WIN32_SOCKETS)
331
/* Does not work with win32 */
332
#define TIMEOUT_READ
333
#endif
334
335
// Change a given linear factor by the given dB value, bounded
336
// to +/- 60 dB.
337
static inline double dbchange(double base_factor, double db)
338
{
339
double nscale = base_factor * pow(10, db/20);
340
if(nscale < 0.001) // -60 dB
341
nscale = 0.001;
342
if(nscale > 1000)
343
nscale = 1000; // +60 dB
344
return nscale;
345
}
346
347
#endif
348
349