ReactOS 0.4.15-dev-7842-g558ab78
sample.h
Go to the documentation of this file.
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
17static 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 */
40static 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
INT32 int32_t
Definition: types.h:71
INT16 int16_t
Definition: types.h:70
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define f
Definition: ke_i.h:83
#define shift
Definition: input.c:1755