xref: /haiku/src/add-ons/media/plugins/raw_decoder/AudioConversion.cpp (revision db10640de90f7f9519ba2da9577b7c1af3c64f6b)
1 #include <ByteOrder.h>
2 #include <OS.h>
3 #include "AudioConversion.h"
4 #include "RawFormats.h"
5 
6 // XXX GCC doesn't always generate nice code...
7 
8 typedef float float32;
9 typedef double float64;
10 
11 class uint8_sample
12 {
13 public:
14 	inline operator uint8() { return data; }
15 	inline operator int8()  { return (int32)data - 128; }
16 	inline operator int16() { return ((int32)data - 128) << 8; }
17 	inline operator int32() { return ((int32)data - 128) << 24; }
18 	inline operator float() { return ((int32)data - 128) * (1.0f / 127.0f); }
19 private:
20 	uint8 data;
21 } _PACKED;
22 
23 class int8_sample
24 {
25 public:
26 	inline operator uint8() { return (int32)data + 128; }
27 	inline operator int8()  { return data; }
28 	inline operator int16() { return (int16)data << 8; }
29 	inline operator int32() { return (int32)data << 24; }
30 	inline operator float() { return (int32)data * (1.0f / 127.0f); }
31 private:
32 	int8 data;
33 } _PACKED;
34 
35 class int16_sample
36 {
37 public:
38 	inline operator uint8() { return (uint8)((int8)(data >> 8) + 128); }
39 	inline operator int8()  { return (int8)(data >> 8); }
40 	inline operator int16() { return data; }
41 	inline operator int32() { return (int32)data << 16; }
42 	inline operator float() { return data * (1.0f / 32767.0f); }
43 private:
44 	int16 data;
45 } _PACKED;
46 
47 class int24_sample
48 {
49 public:
50 #if B_HOST_IS_LENDIAN
51 	inline operator uint8() { return (int32)data[2] + 128; }
52 	inline operator int8()  { return (int8)data[2]; }
53 	inline operator int16() { return (int16)((uint32)data[2] << 8 | (uint32)data[1]); }
54 	inline operator int32() { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8); }
55 	inline operator float() { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8) * (1.0f / 2147483647.0f); }
56 #else
57 	inline operator uint8() { return (int32)data[0] + 128; }
58 	inline operator int8()  { return (int8)data[0]; }
59 	inline operator int16() { return (int16)((uint32)data[0] << 8 | (uint32)data[1]); }
60 	inline operator int32() { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8); }
61 	inline operator float() { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8) * (1.0f / 2147483647.0f); }
62 #endif
63 private:
64 	uint8 data[3];
65 } _PACKED;
66 
67 class int32_sample
68 {
69 public:
70 	inline operator uint8() { return (int8)(data >> 24) + 128; }
71 	inline operator int8()  { return (int8)(data >> 24); }
72 	inline operator int16() { return (int16)(data >> 16); }
73 	inline operator int32() { return data; }
74 	inline operator float() { return data * (1.0f / 2147483647.0f); }
75 private:
76 	int32 data;
77 } _PACKED;
78 
79 class float32_sample
80 {
81 public:
82 	inline operator uint8() { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
83 	inline operator int8()  { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
84 	inline operator int16() { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
85 	inline operator int32() { float32 v; if (data < -1.0f) v = -1.0f; else if (data > 1.0f) v = 1.0f; else v = data; return (int32)(v * 2147483647.0f); }
86 	inline operator float() { return data; }
87 private:
88 	float32 data;
89 } _PACKED;
90 
91 class float64_sample
92 {
93 public:
94 	inline operator uint8() { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
95 	inline operator int8()  { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
96 	inline operator int16() { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
97 	inline operator int32() { float64 v; if (data < -1.0) v = -1.0; else if (data > 1.0) v = 1.0; else v = data; return (int32)(v * 2147483647.0f); }
98 	inline operator float() { return data; }
99 private:
100 	float64 data;
101 } _PACKED;
102 
103 #define CONVERT(src_type, dst_type)				\
104 void src_type##_to_##dst_type (void *dst, void *src, int32 count) \
105 {												\
106 	register src_type##_sample *s = (src_type##_sample *) src;	\
107 	register dst_type *d = (dst_type *) dst;	\
108 	register int32 c = count >> 4;				\
109 	if (!c) goto fin1;							\
110 	do {										\
111 		d[0] = s[0]; d[1] = s[1];				\
112 		d[2] = s[2]; d[3] = s[3];				\
113 		d[4] = s[4]; d[5] = s[5];				\
114 		d[6] = s[6]; d[7] = s[7];				\
115 		d[8] = s[8]; d[9] = s[9];				\
116 		d[10] = s[10]; d[11] = s[11];			\
117 		d[12] = s[12]; d[13] = s[13];			\
118 		d[14] = s[14]; d[15] = s[15];			\
119 		s += 16; d += 16;						\
120 	} while (--c);								\
121 fin1:											\
122 	c = count & 15;								\
123 	if (!c) goto fin2;							\
124 	do {										\
125 		*(d++) = *(s++);						\
126 	} while (--c);								\
127 fin2:											\
128 	;											\
129 }
130 
131 
132 CONVERT(uint8, uint8)
133 CONVERT(uint8, int8)
134 CONVERT(uint8, int16)
135 CONVERT(uint8, int32)
136 CONVERT(uint8, float32)
137 
138 CONVERT(int8, uint8)
139 CONVERT(int8, int8)
140 CONVERT(int8, int16)
141 CONVERT(int8, int32)
142 CONVERT(int8, float32)
143 
144 CONVERT(int16, uint8)
145 CONVERT(int16, int8)
146 CONVERT(int16, int16)
147 CONVERT(int16, int32)
148 CONVERT(int16, float32)
149 
150 CONVERT(int24, uint8)
151 CONVERT(int24, int8)
152 CONVERT(int24, int16)
153 CONVERT(int24, int32)
154 CONVERT(int24, float32)
155 
156 CONVERT(int32, uint8)
157 CONVERT(int32, int8)
158 CONVERT(int32, int16)
159 CONVERT(int32, int32)
160 CONVERT(int32, float32)
161 
162 CONVERT(float32, uint8)
163 CONVERT(float32, int8)
164 CONVERT(float32, int16)
165 CONVERT(float32, int32)
166 CONVERT(float32, float32)
167 
168 CONVERT(float64, uint8)
169 CONVERT(float64, int8)
170 CONVERT(float64, int16)
171 CONVERT(float64, int32)
172 CONVERT(float64, float32)
173 
174 void
175 swap_int16(void *data, int32 count)
176 {
177 	swap_data(B_INT16_TYPE, data, count * 2, B_SWAP_ALWAYS);
178 }
179 
180 void
181 swap_int24(void *data, int32 count)
182 {
183 	register int32 c = count;
184 	register uint8 *d = (uint8 *)data;
185 	if (!c)
186 		return;
187 	do {
188 		register uint8 temp = d[0];
189 		d[0] = d[2];
190 		d[2] = temp;
191 		d += 3;
192 	} while (--c);
193 }
194 
195 void
196 swap_int32(void *data, int32 count)
197 {
198 	swap_data(B_INT32_TYPE, data, count * 4, B_SWAP_ALWAYS);
199 }
200 
201 void
202 swap_float32(void *data, int32 count)
203 {
204 	swap_data(B_FLOAT_TYPE, data, count * 4, B_SWAP_ALWAYS);
205 }
206 
207 void
208 swap_float64(void *data, int32 count)
209 {
210 	swap_data(B_INT64_TYPE, data, count * 8, B_SWAP_ALWAYS);
211 }
212