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 == -2147483647-1 /* 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)-2147483648UL \ 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