Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/mpg123/src/common/sample.h
4389 views
1
/*
2
sample.h: The conversion from internal data to output samples of differing formats.
3
4
copyright 2007-9 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
initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c
7
Later added the end-conversion specific macros here, too.
8
*/
9
10
#ifndef SAMPLE_H
11
#define SAMPLE_H
12
13
/* mpg123lib_intern.h is included already, right? */
14
15
/* Special case is fixed point math... which does work, but not that nice yet. */
16
#ifdef REAL_IS_FIXED
17
static inline int16_t idiv_signed_rounded(int32_t x, int shift)
18
{
19
x >>= (shift - 1);
20
x += (x & 1);
21
return (int16_t)(x >> 1);
22
}
23
# define REAL_PLUS_32767 ( 32767 << 15 )
24
# define REAL_MINUS_32768 ( -32768 << 15 )
25
# define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15))
26
/* No better code (yet). */
27
# define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x)
28
/* This is just here for completeness, it is not used! */
29
# define REAL_TO_S32(x) (x)
30
#endif
31
32
/* From now on for single precision float... double precision is a possible option once we added some bits. But, it would be rather insane. */
33
#ifndef REAL_TO_SHORT
34
35
#if (defined FORCE_ACCURATE) || (defined ACCURATE_ROUNDING)
36
/* Define the accurate rounding function. */
37
# if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
38
/* This function is only available for IEEE754 single-precision values
39
This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */
40
static inline int16_t ftoi16(float x)
41
{
42
union
43
{
44
float f;
45
int32_t i;
46
} u_fi;
47
u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */
48
return (int16_t)u_fi.i;
49
}
50
# define REAL_TO_SHORT_ACCURATE(x) ftoi16(x)
51
# else
52
/* The "proper" rounding, plain C, a bit slow. */
53
# define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5)
54
# endif
55
#endif
56
57
/* Now define the normal rounding. */
58
# ifdef ACCURATE_ROUNDING
59
# define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x)
60
# else
61
/* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */
62
# define REAL_TO_SHORT(x) (short)(x)
63
# endif
64
65
#endif /* REAL_TO_SHORT */
66
67
/* We should add dithering for S32, too? */
68
#ifndef REAL_TO_S32
69
# ifdef ACCURATE_ROUNDING
70
# define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
71
# else
72
# define REAL_TO_S32(x) (int32_t)(x)
73
# endif
74
#endif
75
76
#ifndef REAL_PLUS_32767
77
# define REAL_PLUS_32767 32767.0
78
#endif
79
#ifndef REAL_MINUS_32768
80
# define REAL_MINUS_32768 -32768.0
81
#endif
82
#ifndef REAL_PLUS_S32
83
# define REAL_PLUS_S32 2147483647.0
84
#endif
85
#ifndef REAL_MINUS_S32
86
# define REAL_MINUS_S32 -2147483648.0
87
#endif
88
89
90
/* The actual storage of a decoded sample is separated in the following macros.
91
We can handle different types, we could also handle dithering here. */
92
93
#ifdef NEWOLD_WRITE_SAMPLE
94
95
/* This is the old new mpg123 WRITE_SAMPLE, fixed for newer GCC by MPlayer folks.
96
Makes a huge difference on old machines. */
97
#if WORDS_BIGENDIAN
98
#define MANTISSA_OFFSET 1
99
#else
100
#define MANTISSA_OFFSET 0
101
#endif
102
#define WRITE_SHORT_SAMPLE(samples,sum,clip) { \
103
union { double dtemp; int itemp[2]; } u; int v; \
104
u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\
105
v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \
106
if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
107
else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
108
else { *(samples) = v; } \
109
}
110
111
#else
112
/* Macro to produce a short (signed 16bit) output sample from internal representation,
113
which may be float, double or indeed some integer for fixed point handling. */
114
#define WRITE_SHORT_SAMPLE(samples,sum,clip) \
115
if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
116
else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
117
else { *(samples) = REAL_TO_SHORT(sum); }
118
#endif
119
120
/* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
121
#define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \
122
if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
123
else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
124
else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); }
125
126
/*
127
32bit signed
128
We do clipping with the same old borders... but different conversion.
129
We see here that we need extra work for non-16bit output... we optimized for 16bit.
130
-0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC
131
does not give a compile time warning.
132
*/
133
#define WRITE_S32_SAMPLE(samples,sum,clip) \
134
{ \
135
real tmpsum = REAL_MUL((sum),S32_RESCALE); \
136
if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
137
else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
138
else { *(samples) = REAL_TO_S32(tmpsum); } \
139
}
140
141
/* Produce an 8bit sample, via 16bit intermediate. */
142
#define WRITE_8BIT_SAMPLE(samples,sum,clip) \
143
{ \
144
int16_t write_8bit_tmp; \
145
if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
146
else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
147
else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
148
*(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
149
}
150
#ifndef REAL_IS_FIXED
151
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
152
#endif
153
154
/* Finished 32 bit sample to unsigned 32 bit sample. */
155
#define CONV_SU32(s) \
156
( (s >= 0) \
157
? ((uint32_t)s + (uint32_t)2147483648UL) \
158
: (s == -2147483647L-1L /* Work around to prevent a non-conformant MSVC warning/error */ \
159
? 0 /* Separate because negation would overflow. */ \
160
: (uint32_t)2147483648UL - (uint32_t)(-s) ) \
161
)
162
163
/* Finished 16 bit sample to unsigned 16 bit sample. */
164
#define CONV_SU16(s) (uint16_t)((int32_t)(s)+32768)
165
166
/* Same style for syn123 generic conversion. */
167
#define CONV_SU8(s) (uint8_t)((int16_t)s+128)
168
169
/* Unsigned 32 bit sample to signed 32 bit sample. */
170
#define CONV_US32(u) \
171
( (u >= 2147483648UL) \
172
? (int32_t)((uint32_t)u - (uint32_t)2147483648UL) \
173
: ((u == 0) \
174
? (int32_t)(-2147483647L-1L) \
175
: -(int32_t)((uint32_t)2147483648UL - u) ) \
176
)
177
178
/* Unsigned 16 bit sample to signed 16 bit sample. */
179
#define CONV_US16(s) (int16_t)((int32_t)s-32768)
180
181
/* Same style for syn123 generic conversion. */
182
#define CONV_US8(s) (int8_t)((int16_t)s-128)
183
184
/* 24 bit conversion: drop or add a least significant byte. */
185
#ifdef WORDS_BIGENDIAN
186
/* Highest byte first. Drop last. */
187
#define DROP4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2];}
188
#define ADD4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2]; (w)[3]=0;}
189
#else
190
/* Lowest byte first, drop that. */
191
#define DROP4BYTE(w,r) {(w)[0]=(r)[1]; (w)[1]=(r)[2]; (w)[2]=(r)[3];}
192
#define ADD4BYTE(w,r) {(w)[0]=0; (w)[1]=(r)[0]; (w)[2]=(r)[1]; (w)[3]=(r)[2];}
193
#endif
194
195
#endif
196
197