xref: /haiku/src/add-ons/media/plugins/raw_decoder/AudioConversion.cpp (revision 95bac3fda53a4cb21880712d7b43f8c21db32a2e)
1 /*
2  * Copyright (c) 2003-2004, Marcus Overhagen
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  *  * Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23  * OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include <ByteOrder.h>
26 #include <OS.h>
27 #include "AudioConversion.h"
28 #include "RawFormats.h"
29 
30 // XXX GCC doesn't always generate nice code...
31 
32 typedef float float32;
33 typedef double float64;
34 
35 class uint8_sample
36 {
37 public:
38 	inline operator uint8() { return data; }
39 	inline operator int8()  { return (int32)data - 128; }
40 	inline operator int16() { return ((int32)data - 128) << 8; }
41 	inline operator int32() { return ((int32)data - 128) << 24; }
42 	inline operator float() { return ((int32)data - 128) * (1.0f / 127.0f); }
43 private:
44 	uint8 data;
45 } _PACKED;
46 
47 class int8_sample
48 {
49 public:
50 	inline operator uint8() { return (int32)data + 128; }
51 	inline operator int8()  { return data; }
52 	inline operator int16() { return (int16)data << 8; }
53 	inline operator int32() { return (int32)data << 24; }
54 	inline operator float() { return (int32)data * (1.0f / 127.0f); }
55 private:
56 	int8 data;
57 } _PACKED;
58 
59 class int16_sample
60 {
61 public:
62 	inline operator uint8() { return (uint8)((int8)(data >> 8) + 128); }
63 	inline operator int8()  { return (int8)(data >> 8); }
64 	inline operator int16() { return data; }
65 	inline operator int32() { return (int32)data << 16; }
66 	inline operator float() { return data * (1.0f / 32767.0f); }
67 private:
68 	int16 data;
69 } _PACKED;
70 
71 class int24_sample
72 {
73 public:
74 #if B_HOST_IS_LENDIAN
75 	inline operator uint8() { return (int32)data[2] + 128; }
76 	inline operator int8()  { return (int8)data[2]; }
77 	inline operator int16() { return (int16)((uint32)data[2] << 8 | (uint32)data[1]); }
78 	inline operator int32() { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8); }
79 	inline operator float() { return (int32)((uint32)data[2] << 16 | (uint32)data[1] << 8 | (uint32)data[0]) * (1.0f / (2147483647.0f / 256)); }
80 // XXX is the line above correct? long version:
81 //	inline operator float() { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8) * (1.0f / 2147483647.0f); }
82 #else
83 	inline operator uint8() { return (int32)data[0] + 128; }
84 	inline operator int8()  { return (int8)data[0]; }
85 	inline operator int16() { return (int16)((uint32)data[0] << 8 | (uint32)data[1]); }
86 	inline operator int32() { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8); }
87 	inline operator float() { return (int32)((uint32)data[0] << 16 | (uint32)data[1] << 8 | (uint32)data[2]) * (1.0f / (2147483647.0f / 256)); }
88 // XXX is the line above correct? long version:
89 //	inline operator float() { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8) * (1.0f / 2147483647.0f); }
90 #endif
91 private:
92 	uint8 data[3];
93 } _PACKED;
94 
95 class int32_sample
96 {
97 public:
98 	inline operator uint8() { return (int8)(data >> 24) + 128; }
99 	inline operator int8()  { return (int8)(data >> 24); }
100 	inline operator int16() { return (int16)(data >> 16); }
101 	inline operator int32() { return data; }
102 	inline operator float() { return data * (1.0f / 2147483647.0f); }
103 private:
104 	int32 data;
105 } _PACKED;
106 
107 class float32_sample
108 {
109 public:
110 	inline operator uint8() { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
111 	inline operator int8()  { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
112 	inline operator int16() { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
113 	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); }
114 	inline operator float() { return data; }
115 private:
116 	float32 data;
117 } _PACKED;
118 
119 class float64_sample
120 {
121 public:
122 	inline operator uint8() { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
123 	inline operator int8()  { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
124 	inline operator int16() { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
125 	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); }
126 	inline operator float() { return data; }
127 private:
128 	float64 data;
129 } _PACKED;
130 
131 #define CONVERT(src_type, dst_type)				\
132 void src_type##_to_##dst_type (void *dst, void *src, int32 count) \
133 {												\
134 	register src_type##_sample *s = (src_type##_sample *) src;	\
135 	register dst_type *d = (dst_type *) dst;	\
136 	register int32 c = count >> 4;				\
137 	if (!c) goto fin1;							\
138 	do {										\
139 		d[0] = s[0]; d[1] = s[1];				\
140 		d[2] = s[2]; d[3] = s[3];				\
141 		d[4] = s[4]; d[5] = s[5];				\
142 		d[6] = s[6]; d[7] = s[7];				\
143 		d[8] = s[8]; d[9] = s[9];				\
144 		d[10] = s[10]; d[11] = s[11];			\
145 		d[12] = s[12]; d[13] = s[13];			\
146 		d[14] = s[14]; d[15] = s[15];			\
147 		s += 16; d += 16;						\
148 	} while (--c);								\
149 fin1:											\
150 	c = count & 15;								\
151 	if (!c) goto fin2;							\
152 	do {										\
153 		*(d++) = *(s++);						\
154 	} while (--c);								\
155 fin2:											\
156 	;											\
157 }
158 
159 
160 CONVERT(uint8, uint8)
161 CONVERT(uint8, int8)
162 CONVERT(uint8, int16)
163 CONVERT(uint8, int32)
164 CONVERT(uint8, float32)
165 
166 CONVERT(int8, uint8)
167 CONVERT(int8, int8)
168 CONVERT(int8, int16)
169 CONVERT(int8, int32)
170 CONVERT(int8, float32)
171 
172 CONVERT(int16, uint8)
173 CONVERT(int16, int8)
174 CONVERT(int16, int16)
175 CONVERT(int16, int32)
176 CONVERT(int16, float32)
177 
178 CONVERT(int24, uint8)
179 CONVERT(int24, int8)
180 CONVERT(int24, int16)
181 CONVERT(int24, int32)
182 CONVERT(int24, float32)
183 
184 CONVERT(int32, uint8)
185 CONVERT(int32, int8)
186 CONVERT(int32, int16)
187 CONVERT(int32, int32)
188 CONVERT(int32, float32)
189 
190 CONVERT(float32, uint8)
191 CONVERT(float32, int8)
192 CONVERT(float32, int16)
193 CONVERT(float32, int32)
194 CONVERT(float32, float32)
195 
196 CONVERT(float64, uint8)
197 CONVERT(float64, int8)
198 CONVERT(float64, int16)
199 CONVERT(float64, int32)
200 CONVERT(float64, float32)
201 
202 void
203 swap_int16(void *data, int32 count)
204 {
205 	swap_data(B_INT16_TYPE, data, count * 2, B_SWAP_ALWAYS);
206 }
207 
208 void
209 swap_int24(void *data, int32 count)
210 {
211 	register int32 c = count;
212 	register uint8 *d = (uint8 *)data;
213 	if (!c)
214 		return;
215 	do {
216 		register uint8 temp = d[0];
217 		d[0] = d[2];
218 		d[2] = temp;
219 		d += 3;
220 	} while (--c);
221 }
222 
223 void
224 swap_int32(void *data, int32 count)
225 {
226 	swap_data(B_INT32_TYPE, data, count * 4, B_SWAP_ALWAYS);
227 }
228 
229 void
230 swap_float32(void *data, int32 count)
231 {
232 	swap_data(B_FLOAT_TYPE, data, count * 4, B_SWAP_ALWAYS);
233 }
234 
235 void
236 swap_float64(void *data, int32 count)
237 {
238 	swap_data(B_INT64_TYPE, data, count * 8, B_SWAP_ALWAYS);
239 }
240