#ifndef SAMPLE_H
#define SAMPLE_H
#ifdef REAL_IS_FIXED
static inline int16_t idiv_signed_rounded(int32_t x, int shift)
{
x >>= (shift - 1);
x += (x & 1);
return (int16_t)(x >> 1);
}
# define REAL_PLUS_32767 ( 32767 << 15 )
# define REAL_MINUS_32768 ( -32768 << 15 )
# define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15))
# define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x)
# define REAL_TO_S32(x) (x)
#endif
#ifndef REAL_TO_SHORT
#if (defined FORCE_ACCURATE) || (defined ACCURATE_ROUNDING)
# if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
static inline int16_t ftoi16(float x)
{
union
{
float f;
int32_t i;
} u_fi;
u_fi.f = x + 12582912.0f;
return (int16_t)u_fi.i;
}
# define REAL_TO_SHORT_ACCURATE(x) ftoi16(x)
# else
# define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5)
# endif
#endif
# ifdef ACCURATE_ROUNDING
# define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x)
# else
# define REAL_TO_SHORT(x) (short)(x)
# endif
#endif
#ifndef REAL_TO_S32
# ifdef ACCURATE_ROUNDING
# define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
# else
# define REAL_TO_S32(x) (int32_t)(x)
# endif
#endif
#ifndef REAL_PLUS_32767
# define REAL_PLUS_32767 32767.0
#endif
#ifndef REAL_MINUS_32768
# define REAL_MINUS_32768 -32768.0
#endif
#ifndef REAL_PLUS_S32
# define REAL_PLUS_S32 2147483647.0
#endif
#ifndef REAL_MINUS_S32
# define REAL_MINUS_S32 -2147483648.0
#endif
#ifdef NEWOLD_WRITE_SAMPLE
#if WORDS_BIGENDIAN
#define MANTISSA_OFFSET 1
#else
#define MANTISSA_OFFSET 0
#endif
#define WRITE_SHORT_SAMPLE(samples,sum,clip) { \
union { double dtemp; int itemp[2]; } u; int v; \
u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\
v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \
if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = v; } \
}
#else
#define WRITE_SHORT_SAMPLE(samples,sum,clip) \
if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = REAL_TO_SHORT(sum); }
#endif
#define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \
if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = REAL_TO_SHORT_ACCURATE(sum); }
#define WRITE_S32_SAMPLE(samples,sum,clip) \
{ \
real tmpsum = REAL_MUL((sum),S32_RESCALE); \
if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
else { *(samples) = REAL_TO_S32(tmpsum); } \
}
#define WRITE_8BIT_SAMPLE(samples,sum,clip) \
{ \
int16_t write_8bit_tmp; \
if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
*(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
}
#ifndef REAL_IS_FIXED
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
#endif
#define CONV_SU32(s) \
( (s >= 0) \
? ((uint32_t)s + (uint32_t)2147483648UL) \
: (s == -2147483647L-1L \
? 0 \
: (uint32_t)2147483648UL - (uint32_t)(-s) ) \
)
#define CONV_SU16(s) (uint16_t)((int32_t)(s)+32768)
#define CONV_SU8(s) (uint8_t)((int16_t)s+128)
#define CONV_US32(u) \
( (u >= 2147483648UL) \
? (int32_t)((uint32_t)u - (uint32_t)2147483648UL) \
: ((u == 0) \
? (int32_t)(-2147483647L-1L) \
: -(int32_t)((uint32_t)2147483648UL - u) ) \
)
#define CONV_US16(s) (int16_t)((int32_t)s-32768)
#define CONV_US8(s) (int8_t)((int16_t)s-128)
#ifdef WORDS_BIGENDIAN
#define DROP4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2];}
#define ADD4BYTE(w,r) {(w)[0]=(r)[0]; (w)[1]=(r)[1]; (w)[2]=(r)[2]; (w)[3]=0;}
#else
#define DROP4BYTE(w,r) {(w)[0]=(r)[1]; (w)[1]=(r)[2]; (w)[2]=(r)[3];}
#define ADD4BYTE(w,r) {(w)[0]=0; (w)[1]=(r)[0]; (w)[2]=(r)[1]; (w)[3]=(r)[2];}
#endif
#endif