Rev 1905 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1905 | Rev 3960 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | sample.h: The conversion from internal data to output samples of differing formats. |
2 | sample.h: The conversion from internal data to output samples of differing formats. |
3 | 3 | ||
4 | copyright 2007-9 by the mpg123 project - free software under the terms of the LGPL 2.1 |
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 |
5 | see COPYING and AUTHORS files in distribution or http://mpg123.org |
6 | initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c |
6 | initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c |
7 | Later added the end-conversion specific macros here, too. |
7 | Later added the end-conversion specific macros here, too. |
8 | */ |
8 | */ |
9 | 9 | ||
10 | #ifndef SAMPLE_H |
10 | #ifndef SAMPLE_H |
11 | #define SAMPLE_H |
11 | #define SAMPLE_H |
12 | 12 | ||
13 | /* mpg123lib_intern.h is included already, right? */ |
13 | /* mpg123lib_intern.h is included already, right? */ |
14 | 14 | ||
15 | /* Special case is fixed point math... which does work, but not that nice yet. */ |
15 | /* Special case is fixed point math... which does work, but not that nice yet. */ |
16 | #ifdef REAL_IS_FIXED |
16 | #ifdef REAL_IS_FIXED |
17 | static inline short idiv_signed_rounded(long x, int shift) |
17 | static inline short idiv_signed_rounded(long x, int shift) |
18 | { |
18 | { |
19 | x >>= (shift - 1); |
19 | x >>= (shift - 1); |
20 | x += (x & 1); |
20 | x += (x & 1); |
21 | return (short)(x >> 1); |
21 | return (short)(x >> 1); |
22 | } |
22 | } |
23 | # define REAL_PLUS_32767 ( 32767 << 15 ) |
23 | # define REAL_PLUS_32767 ( 32767 << 15 ) |
24 | # define REAL_MINUS_32768 ( -32768 << 15 ) |
24 | # define REAL_MINUS_32768 ( -32768 << 15 ) |
25 | # define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15)) |
25 | # define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15)) |
26 | /* No better code (yet). */ |
26 | /* No better code (yet). */ |
27 | # define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x) |
27 | # define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x) |
28 | /* This is just here for completeness, it is not used! */ |
28 | /* This is just here for completeness, it is not used! */ |
29 | # define REAL_TO_S32(x) (x) |
29 | # define REAL_TO_S32(x) (x) |
30 | #endif |
30 | #endif |
31 | 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. */ |
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 |
33 | #ifndef REAL_TO_SHORT |
34 | 34 | ||
35 | /* Define the accurate rounding function. */ |
35 | /* Define the accurate rounding function. */ |
36 | # if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT) |
36 | # if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT) |
37 | /* This function is only available for IEEE754 single-precision values |
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 */ |
38 | This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */ |
39 | static inline short ftoi16(float x) |
39 | static inline short ftoi16(float x) |
40 | { |
40 | { |
41 | union |
41 | union |
42 | { |
42 | { |
43 | float f; |
43 | float f; |
44 | int32_t i; |
44 | int32_t i; |
45 | } u_fi; |
45 | } u_fi; |
46 | u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */ |
46 | u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */ |
47 | return (short)u_fi.i; |
47 | return (short)u_fi.i; |
48 | } |
48 | } |
49 | # define REAL_TO_SHORT_ACCURATE(x) ftoi16(x) |
49 | # define REAL_TO_SHORT_ACCURATE(x) ftoi16(x) |
50 | # else |
50 | # else |
51 | /* The "proper" rounding, plain C, a bit slow. */ |
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) |
52 | # define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5) |
53 | # endif |
53 | # endif |
54 | 54 | ||
55 | /* Now define the normal rounding. */ |
55 | /* Now define the normal rounding. */ |
56 | # ifdef ACCURATE_ROUNDING |
56 | # ifdef ACCURATE_ROUNDING |
57 | # define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x) |
57 | # define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x) |
58 | # else |
58 | # else |
59 | /* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */ |
59 | /* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */ |
60 | # define REAL_TO_SHORT(x) (short)(x) |
60 | # define REAL_TO_SHORT(x) (short)(x) |
61 | # endif |
61 | # endif |
62 | 62 | ||
63 | #endif /* REAL_TO_SHORT */ |
63 | #endif /* REAL_TO_SHORT */ |
64 | 64 | ||
65 | /* We should add dithering for S32, too? */ |
65 | /* We should add dithering for S32, too? */ |
66 | #ifndef REAL_TO_S32 |
66 | #ifndef REAL_TO_S32 |
67 | # ifdef ACCURATE_ROUNDING |
67 | # ifdef ACCURATE_ROUNDING |
68 | # define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5) |
68 | # define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5) |
69 | # else |
69 | # else |
70 | # define REAL_TO_S32(x) (int32_t)(x) |
70 | # define REAL_TO_S32(x) (int32_t)(x) |
71 | # endif |
71 | # endif |
72 | #endif |
72 | #endif |
73 | 73 | ||
74 | #ifndef REAL_PLUS_32767 |
74 | #ifndef REAL_PLUS_32767 |
75 | # define REAL_PLUS_32767 32767.0 |
75 | # define REAL_PLUS_32767 32767.0 |
76 | #endif |
76 | #endif |
77 | #ifndef REAL_MINUS_32768 |
77 | #ifndef REAL_MINUS_32768 |
78 | # define REAL_MINUS_32768 -32768.0 |
78 | # define REAL_MINUS_32768 -32768.0 |
79 | #endif |
79 | #endif |
80 | #ifndef REAL_PLUS_S32 |
80 | #ifndef REAL_PLUS_S32 |
81 | # define REAL_PLUS_S32 2147483647.0 |
81 | # define REAL_PLUS_S32 2147483647.0 |
82 | #endif |
82 | #endif |
83 | #ifndef REAL_MINUS_S32 |
83 | #ifndef REAL_MINUS_S32 |
84 | # define REAL_MINUS_S32 -2147483648.0 |
84 | # define REAL_MINUS_S32 -2147483648.0 |
85 | #endif |
85 | #endif |
86 | 86 | ||
87 | 87 | ||
88 | /* The actual storage of a decoded sample is separated in the following macros. |
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. */ |
89 | We can handle different types, we could also handle dithering here. */ |
- | 90 | ||
- | 91 | #ifdef NEWOLD_WRITE_SAMPLE |
|
- | 92 | ||
- | 93 | /* This is the old new mpg123 WRITE_SAMPLE, fixed for newer GCC by MPlayer folks. |
|
- | 94 | Makes a huge difference on old machines. */ |
|
- | 95 | #if WORDS_BIGENDIAN |
|
- | 96 | #define MANTISSA_OFFSET 1 |
|
- | 97 | #else |
|
- | 98 | #define MANTISSA_OFFSET 0 |
|
- | 99 | #endif |
|
- | 100 | #define WRITE_SHORT_SAMPLE(samples,sum,clip) { \ |
|
- | 101 | union { double dtemp; int itemp[2]; } u; int v; \ |
|
- | 102 | u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\ |
|
- | 103 | v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \ |
|
- | 104 | if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \ |
|
- | 105 | else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \ |
|
- | 106 | else { *(samples) = v; } \ |
|
- | 107 | } |
|
- | 108 | ||
90 | 109 | #else |
|
91 | /* Macro to produce a short (signed 16bit) output sample from internal representation, |
110 | /* 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. */ |
111 | which may be float, double or indeed some integer for fixed point handling. */ |
93 | #define WRITE_SHORT_SAMPLE(samples,sum,clip) \ |
112 | #define WRITE_SHORT_SAMPLE(samples,sum,clip) \ |
94 | if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ |
113 | if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ |
95 | else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ |
114 | else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ |
96 | else { *(samples) = REAL_TO_SHORT(sum); } |
115 | else { *(samples) = REAL_TO_SHORT(sum); } |
- | 116 | #endif |
|
97 | 117 | ||
98 | /* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */ |
118 | /* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */ |
99 | #define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \ |
119 | #define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \ |
100 | if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ |
120 | if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ |
101 | else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ |
121 | else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ |
102 | else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); } |
122 | else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); } |
103 | 123 | ||
104 | /* |
124 | /* |
105 | 32bit signed |
125 | 32bit signed |
106 | We do clipping with the same old borders... but different conversion. |
126 | 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. |
127 | 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 |
128 | -0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC |
109 | does not give a compile time warning. |
129 | does not give a compile time warning. |
110 | */ |
130 | */ |
111 | #define WRITE_S32_SAMPLE(samples,sum,clip) \ |
131 | #define WRITE_S32_SAMPLE(samples,sum,clip) \ |
112 | { \ |
132 | { \ |
113 | real tmpsum = REAL_MUL((sum),S32_RESCALE); \ |
133 | real tmpsum = REAL_MUL((sum),S32_RESCALE); \ |
114 | if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \ |
134 | if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \ |
115 | else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \ |
135 | else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \ |
116 | else { *(samples) = REAL_TO_S32(tmpsum); } \ |
136 | else { *(samples) = REAL_TO_S32(tmpsum); } \ |
117 | } |
137 | } |
118 | 138 | ||
119 | /* Produce an 8bit sample, via 16bit intermediate. */ |
139 | /* Produce an 8bit sample, via 16bit intermediate. */ |
120 | #define WRITE_8BIT_SAMPLE(samples,sum,clip) \ |
140 | #define WRITE_8BIT_SAMPLE(samples,sum,clip) \ |
121 | { \ |
141 | { \ |
122 | short write_8bit_tmp; \ |
142 | short write_8bit_tmp; \ |
123 | if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \ |
143 | if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \ |
124 | else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \ |
144 | else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \ |
125 | else { write_8bit_tmp = REAL_TO_SHORT(sum); } \ |
145 | else { write_8bit_tmp = REAL_TO_SHORT(sum); } \ |
126 | *(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \ |
146 | *(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \ |
127 | } |
147 | } |
128 | #ifndef REAL_IS_FIXED |
148 | #ifndef REAL_IS_FIXED |
129 | #define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum) |
149 | #define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum) |
130 | #endif |
150 | #endif |
131 | 151 | ||
132 | #endif>>>>><>><> |
152 | #endif>>>>>><>><> |