Sync winemp3.acm with Wine HEAD. This one uses libmpg123 which was added in Version...
[reactos.git] / reactos / include / reactos / libs / libmpg123 / sample.h
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 short idiv_signed_rounded(long x, int shift)
18 {
19 x >>= (shift - 1);
20 x += (x & 1);
21 return (short)(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 /* Define the accurate rounding function. */
36 # if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
37 /* This function is only available for IEEE754 single-precision values
38 This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */
39 static inline short ftoi16(float x)
40 {
41 union
42 {
43 float f;
44 int32_t i;
45 } u_fi;
46 u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */
47 return (short)u_fi.i;
48 }
49 # define REAL_TO_SHORT_ACCURATE(x) ftoi16(x)
50 # else
51 /* The "proper" rounding, plain C, a bit slow. */
52 # define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5)
53 # endif
54
55 /* Now define the normal rounding. */
56 # ifdef ACCURATE_ROUNDING
57 # define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x)
58 # else
59 /* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */
60 # define REAL_TO_SHORT(x) (short)(x)
61 # endif
62
63 #endif /* REAL_TO_SHORT */
64
65 /* We should add dithering for S32, too? */
66 #ifndef REAL_TO_S32
67 # ifdef ACCURATE_ROUNDING
68 # define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
69 # else
70 # define REAL_TO_S32(x) (int32_t)(x)
71 # endif
72 #endif
73
74 #ifndef REAL_PLUS_32767
75 # define REAL_PLUS_32767 32767.0
76 #endif
77 #ifndef REAL_MINUS_32768
78 # define REAL_MINUS_32768 -32768.0
79 #endif
80 #ifndef REAL_PLUS_S32
81 # define REAL_PLUS_S32 2147483647.0
82 #endif
83 #ifndef REAL_MINUS_S32
84 # define REAL_MINUS_S32 -2147483648.0
85 #endif
86
87
88 /* The actual storage of a decoded sample is separated in the following macros.
89 We can handle different types, we could also handle dithering here. */
90
91 /* Macro to produce a short (signed 16bit) output sample from internal representation,
92 which may be float, double or indeed some integer for fixed point handling. */
93 #define WRITE_SHORT_SAMPLE(samples,sum,clip) \
94 if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
95 else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
96 else { *(samples) = REAL_TO_SHORT(sum); }
97
98 /* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
99 #define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \
100 if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
101 else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
102 else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); }
103
104 /*
105 32bit signed
106 We do clipping with the same old borders... but different conversion.
107 We see here that we need extra work for non-16bit output... we optimized for 16bit.
108 -0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC
109 does not give a compile time warning.
110 */
111 #define WRITE_S32_SAMPLE(samples,sum,clip) \
112 { \
113 real tmpsum = REAL_MUL((sum),S32_RESCALE); \
114 if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
115 else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
116 else { *(samples) = REAL_TO_S32(tmpsum); } \
117 }
118
119 /* Produce an 8bit sample, via 16bit intermediate. */
120 #define WRITE_8BIT_SAMPLE(samples,sum,clip) \
121 { \
122 short write_8bit_tmp; \
123 if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
124 else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
125 else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
126 *(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
127 }
128 #ifndef REAL_IS_FIXED
129 #define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
130 #endif
131
132 #endif