ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sample.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.