aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/conversions.cpp
blob: 6244b1ecd0414e760703aa560a87a3ee5de1d8e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "main.h"
#include <math.h>
#pragma intrinsic(fabs)

/*
#ifndef _WIN64
__inline static int lrint(double flt) 
{
	int intgr;

	_asm
	{
		fld flt
		fistp intgr
	}

	return intgr;
} 
#else
__inline static int lrint(double flt) 
{
	return (int)flt;
} 
#endif
*/

#define PA_CLIP_( val, min, max )\
    { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }

 void Float32_To_Int16_Clip(
    void *destinationBuffer, signed int destinationStride,
    void *sourceBuffer, signed int sourceStride,
    unsigned int count)
{
    float *src = (float*)sourceBuffer;
    signed short *dest =  (signed short*)destinationBuffer;

    while( count-- )
    {
        long samp = lrint((*src * (32768.0)));

        PA_CLIP_( samp, -0x8000, 0x7FFF );
        *dest = (signed short) samp;

        src += sourceStride;
        dest += destinationStride;
    }
}

inline static double clip(double x, double a, double b)
{
   double x1 = fabs (x-a);
   double x2 = fabs (x-b);
   x = x1 + (a+b);
   x -= x2;
   x *= 0.5;
	 return x;
}

/*
benski> this might be faster than what the compiler spits out for the above function,
but we should benchmark
inline static double clip(double x, double a, double b)
{
	const double zero_point_five = 0.5;
	__asm 
	{
		fld	x
		fld a
		fld b

		fld st(2)
		fsub st(0),st(2) // x-b
		fabs
		fadd st(0),st(2) 
		fadd st(0),st(1)

		fld st(3)
		fsub st(0), st(2)
		fabs
		fsubp st(1), st(0)
		fmul zero_point_five

		ffree st(4)
		ffree st(3)
		ffree st(2)
		ffree st(1)
	}
}
*/


void Float32_To_Int24_Clip(
    void *destinationBuffer, signed int destinationStride,
    void *sourceBuffer, signed int sourceStride,
    unsigned int count)
{
    float *src = (float*)sourceBuffer;
    unsigned char *dest = (unsigned char*)destinationBuffer;

    while( count-- )
    {
        /* convert to 32 bit and drop the low 8 bits */
        double scaled = *src * 0x7FFFFFFF;
        scaled=clip( scaled, -2147483648., 2147483647.  );
        signed long temp = (signed long) scaled;

        dest[0] = (unsigned char)(temp >> 8);
        dest[1] = (unsigned char)(temp >> 16);
        dest[2] = (unsigned char)(temp >> 24);
        src += sourceStride;
        dest += destinationStride * 3;
    }
}