Subversion Repositories Kolibri OS

Rev

Rev 1905 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1905 Rev 3960
1
/*
1
/*
2
	sample.h: The conversion from internal data to output samples of differing formats.
2
	sample.h: The conversion from internal data to output samples of differing formats.
3
 
3
 
4
	copyright 2007-9 by the mpg123 project - free software under the terms of the LGPL 2.1
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
5
	see COPYING and AUTHORS files in distribution or http://mpg123.org
6
	initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c
6
	initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c
7
	Later added the end-conversion specific macros here, too.
7
	Later added the end-conversion specific macros here, too.
8
*/
8
*/
9
 
9
 
10
#ifndef SAMPLE_H
10
#ifndef SAMPLE_H
11
#define SAMPLE_H
11
#define SAMPLE_H
12
 
12
 
13
/* mpg123lib_intern.h is included already, right? */
13
/* mpg123lib_intern.h is included already, right? */
14
 
14
 
15
/* Special case is fixed point math... which does work, but not that nice yet.  */
15
/* Special case is fixed point math... which does work, but not that nice yet.  */
16
#ifdef REAL_IS_FIXED
16
#ifdef REAL_IS_FIXED
17
static inline short idiv_signed_rounded(long x, int shift)
17
static inline short idiv_signed_rounded(long x, int shift)
18
{
18
{
19
	x >>= (shift - 1);
19
	x >>= (shift - 1);
20
	x += (x & 1);
20
	x += (x & 1);
21
	return (short)(x >> 1);
21
	return (short)(x >> 1);
22
}
22
}
23
#  define REAL_PLUS_32767       ( 32767 << 15 )
23
#  define REAL_PLUS_32767       ( 32767 << 15 )
24
#  define REAL_MINUS_32768      ( -32768 << 15 )
24
#  define REAL_MINUS_32768      ( -32768 << 15 )
25
#  define REAL_TO_SHORT(x)      (idiv_signed_rounded(x, 15))
25
#  define REAL_TO_SHORT(x)      (idiv_signed_rounded(x, 15))
26
/* No better code (yet).  */
26
/* No better code (yet).  */
27
#  define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x)
27
#  define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x)
28
/* This is just here for completeness, it is not used! */
28
/* This is just here for completeness, it is not used! */
29
# define REAL_TO_S32(x)        (x)
29
# define REAL_TO_S32(x)        (x)
30
#endif
30
#endif
31
 
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. */
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
33
#ifndef REAL_TO_SHORT
34
 
34
 
35
/* Define the accurate rounding function. */
35
/* Define the accurate rounding function. */
36
# if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
36
# if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
37
/* This function is only available for IEEE754 single-precision values
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 */
38
   This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */
39
static inline short ftoi16(float x)
39
static inline short ftoi16(float x)
40
{
40
{
41
	union
41
	union
42
	{
42
	{
43
		float f;
43
		float f;
44
		int32_t i;
44
		int32_t i;
45
	} u_fi;
45
	} u_fi;
46
	u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */
46
	u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */
47
	return (short)u_fi.i;
47
	return (short)u_fi.i;
48
}
48
}
49
#  define REAL_TO_SHORT_ACCURATE(x)      ftoi16(x)
49
#  define REAL_TO_SHORT_ACCURATE(x)      ftoi16(x)
50
# else
50
# else
51
/* The "proper" rounding, plain C, a bit slow. */
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)
52
#  define REAL_TO_SHORT_ACCURATE(x)      (short)((x)>0.0?(x)+0.5:(x)-0.5)
53
# endif
53
# endif
54
 
54
 
55
/* Now define the normal rounding. */
55
/* Now define the normal rounding. */
56
# ifdef ACCURATE_ROUNDING
56
# ifdef ACCURATE_ROUNDING
57
#  define REAL_TO_SHORT(x)      REAL_TO_SHORT_ACCURATE(x)
57
#  define REAL_TO_SHORT(x)      REAL_TO_SHORT_ACCURATE(x)
58
# else
58
# else
59
/* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */
59
/* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */
60
#  define REAL_TO_SHORT(x)      (short)(x)
60
#  define REAL_TO_SHORT(x)      (short)(x)
61
# endif
61
# endif
62
 
62
 
63
#endif /* REAL_TO_SHORT */
63
#endif /* REAL_TO_SHORT */
64
 
64
 
65
/* We should add dithering for S32, too? */
65
/* We should add dithering for S32, too? */
66
#ifndef REAL_TO_S32
66
#ifndef REAL_TO_S32
67
# ifdef ACCURATE_ROUNDING
67
# ifdef ACCURATE_ROUNDING
68
#  define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
68
#  define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
69
# else
69
# else
70
#  define REAL_TO_S32(x) (int32_t)(x)
70
#  define REAL_TO_S32(x) (int32_t)(x)
71
# endif
71
# endif
72
#endif
72
#endif
73
 
73
 
74
#ifndef REAL_PLUS_32767
74
#ifndef REAL_PLUS_32767
75
# define REAL_PLUS_32767 32767.0
75
# define REAL_PLUS_32767 32767.0
76
#endif
76
#endif
77
#ifndef REAL_MINUS_32768
77
#ifndef REAL_MINUS_32768
78
# define REAL_MINUS_32768 -32768.0
78
# define REAL_MINUS_32768 -32768.0
79
#endif
79
#endif
80
#ifndef REAL_PLUS_S32
80
#ifndef REAL_PLUS_S32
81
# define REAL_PLUS_S32 2147483647.0
81
# define REAL_PLUS_S32 2147483647.0
82
#endif
82
#endif
83
#ifndef REAL_MINUS_S32
83
#ifndef REAL_MINUS_S32
84
# define REAL_MINUS_S32 -2147483648.0
84
# define REAL_MINUS_S32 -2147483648.0
85
#endif
85
#endif
86
 
86
 
87
 
87
 
88
/* The actual storage of a decoded sample is separated in the following macros.
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. */
89
   We can handle different types, we could also handle dithering here. */
-
 
90
 
-
 
91
#ifdef NEWOLD_WRITE_SAMPLE
-
 
92
 
-
 
93
/* This is the old new mpg123 WRITE_SAMPLE, fixed for newer GCC by MPlayer folks.
-
 
94
   Makes a huge difference on old machines. */
-
 
95
#if WORDS_BIGENDIAN 
-
 
96
#define MANTISSA_OFFSET 1
-
 
97
#else
-
 
98
#define MANTISSA_OFFSET 0
-
 
99
#endif
-
 
100
#define WRITE_SHORT_SAMPLE(samples,sum,clip) { \
-
 
101
  union { double dtemp; int itemp[2]; } u; int v; \
-
 
102
  u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\
-
 
103
  v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \
-
 
104
  if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
-
 
105
  else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
-
 
106
  else { *(samples) = v; }  \
-
 
107
}
-
 
108
 
90
 
109
#else
91
/* Macro to produce a short (signed 16bit) output sample from internal representation,
110
/* 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. */
111
   which may be float, double or indeed some integer for fixed point handling. */
93
#define WRITE_SHORT_SAMPLE(samples,sum,clip) \
112
#define WRITE_SHORT_SAMPLE(samples,sum,clip) \
94
  if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
113
  if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
95
  else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
114
  else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
96
  else { *(samples) = REAL_TO_SHORT(sum); }
115
  else { *(samples) = REAL_TO_SHORT(sum); }
-
 
116
#endif
97
 
117
 
98
/* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
118
/* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
99
#define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \
119
#define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \
100
  if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
120
  if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
101
  else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
121
  else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
102
  else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); }
122
  else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); }
103
 
123
 
104
/*
124
/*
105
	32bit signed 
125
	32bit signed 
106
	We do clipping with the same old borders... but different conversion.
126
	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.
127
	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 
128
	-0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC 
109
	does not give a compile time warning.
129
	does not give a compile time warning.
110
*/
130
*/
111
#define WRITE_S32_SAMPLE(samples,sum,clip) \
131
#define WRITE_S32_SAMPLE(samples,sum,clip) \
112
	{ \
132
	{ \
113
		real tmpsum = REAL_MUL((sum),S32_RESCALE); \
133
		real tmpsum = REAL_MUL((sum),S32_RESCALE); \
114
		if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
134
		if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
115
		else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
135
		else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
116
		else { *(samples) = REAL_TO_S32(tmpsum); } \
136
		else { *(samples) = REAL_TO_S32(tmpsum); } \
117
	}
137
	}
118
 
138
 
119
/* Produce an 8bit sample, via 16bit intermediate. */
139
/* Produce an 8bit sample, via 16bit intermediate. */
120
#define WRITE_8BIT_SAMPLE(samples,sum,clip) \
140
#define WRITE_8BIT_SAMPLE(samples,sum,clip) \
121
{ \
141
{ \
122
	short write_8bit_tmp; \
142
	short write_8bit_tmp; \
123
	if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
143
	if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
124
	else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
144
	else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
125
	else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
145
	else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
126
	*(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
146
	*(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
127
}
147
}
128
#ifndef REAL_IS_FIXED
148
#ifndef REAL_IS_FIXED
129
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
149
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
130
#endif
150
#endif
131
 
151
 
132
#endif
152
#endif