Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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
  133.