Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensample.h
Go to the documentation of this file.
00001 /* 00002 sample.h: The conversion from internal data to output samples of differing formats. 00003 00004 copyright 2007-9 by the mpg123 project - free software under the terms of the LGPL 2.1 00005 see COPYING and AUTHORS files in distribution or http://mpg123.org 00006 initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c 00007 Later added the end-conversion specific macros here, too. 00008 */ 00009 00010 #ifndef SAMPLE_H 00011 #define SAMPLE_H 00012 00013 /* mpg123lib_intern.h is included already, right? */ 00014 00015 /* Special case is fixed point math... which does work, but not that nice yet. */ 00016 #ifdef REAL_IS_FIXED 00017 static inline short idiv_signed_rounded(long x, int shift) 00018 { 00019 x >>= (shift - 1); 00020 x += (x & 1); 00021 return (short)(x >> 1); 00022 } 00023 # define REAL_PLUS_32767 ( 32767 << 15 ) 00024 # define REAL_MINUS_32768 ( -32768 << 15 ) 00025 # define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15)) 00026 /* No better code (yet). */ 00027 # define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x) 00028 /* This is just here for completeness, it is not used! */ 00029 # define REAL_TO_S32(x) (x) 00030 #endif 00031 00032 /* From now on for single precision float... double precision is a possible option once we added some bits. But, it would be rather insane. */ 00033 #ifndef REAL_TO_SHORT 00034 00035 /* Define the accurate rounding function. */ 00036 # if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT) 00037 /* This function is only available for IEEE754 single-precision values 00038 This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */ 00039 static inline short ftoi16(float x) 00040 { 00041 union 00042 { 00043 float f; 00044 int32_t i; 00045 } u_fi; 00046 u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */ 00047 return (short)u_fi.i; 00048 } 00049 # define REAL_TO_SHORT_ACCURATE(x) ftoi16(x) 00050 # else 00051 /* The "proper" rounding, plain C, a bit slow. */ 00052 # define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5) 00053 # endif 00054 00055 /* Now define the normal rounding. */ 00056 # ifdef ACCURATE_ROUNDING 00057 # define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x) 00058 # else 00059 /* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */ 00060 # define REAL_TO_SHORT(x) (short)(x) 00061 # endif 00062 00063 #endif /* REAL_TO_SHORT */ 00064 00065 /* We should add dithering for S32, too? */ 00066 #ifndef REAL_TO_S32 00067 # ifdef ACCURATE_ROUNDING 00068 # define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5) 00069 # else 00070 # define REAL_TO_S32(x) (int32_t)(x) 00071 # endif 00072 #endif 00073 00074 #ifndef REAL_PLUS_32767 00075 # define REAL_PLUS_32767 32767.0 00076 #endif 00077 #ifndef REAL_MINUS_32768 00078 # define REAL_MINUS_32768 -32768.0 00079 #endif 00080 #ifndef REAL_PLUS_S32 00081 # define REAL_PLUS_S32 2147483647.0 00082 #endif 00083 #ifndef REAL_MINUS_S32 00084 # define REAL_MINUS_S32 -2147483648.0 00085 #endif 00086 00087 00088 /* The actual storage of a decoded sample is separated in the following macros. 00089 We can handle different types, we could also handle dithering here. */ 00090 00091 /* Macro to produce a short (signed 16bit) output sample from internal representation, 00092 which may be float, double or indeed some integer for fixed point handling. */ 00093 #define WRITE_SHORT_SAMPLE(samples,sum,clip) \ 00094 if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ 00095 else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ 00096 else { *(samples) = REAL_TO_SHORT(sum); } 00097 00098 /* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */ 00099 #define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \ 00100 if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \ 00101 else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \ 00102 else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); } 00103 00104 /* 00105 32bit signed 00106 We do clipping with the same old borders... but different conversion. 00107 We see here that we need extra work for non-16bit output... we optimized for 16bit. 00108 -0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC 00109 does not give a compile time warning. 00110 */ 00111 #define WRITE_S32_SAMPLE(samples,sum,clip) \ 00112 { \ 00113 real tmpsum = REAL_MUL((sum),S32_RESCALE); \ 00114 if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \ 00115 else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \ 00116 else { *(samples) = REAL_TO_S32(tmpsum); } \ 00117 } 00118 00119 /* Produce an 8bit sample, via 16bit intermediate. */ 00120 #define WRITE_8BIT_SAMPLE(samples,sum,clip) \ 00121 { \ 00122 short write_8bit_tmp; \ 00123 if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \ 00124 else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \ 00125 else { write_8bit_tmp = REAL_TO_SHORT(sum); } \ 00126 *(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \ 00127 } 00128 #ifndef REAL_IS_FIXED 00129 #define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum) 00130 #endif 00131 00132 #endif Generated on Sun May 27 2012 04:33:12 for ReactOS by
1.7.6.1
|