xref: /haiku/src/add-ons/media/plugins/raw_decoder/AudioConversion.cpp (revision da8162be21b36442f34a731873d2358a0d63c25a)
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:
operator uint8() const38 	inline operator uint8() const { return data; }
operator int8() const39 	inline operator int8()  const { return (int32)data - 128; }
operator int16() const40 	inline operator int16() const { return ((int32)data - 128) << 8; }
operator int32() const41 	inline operator int32() const { return ((int32)data - 128) << 24; }
operator float() const42 	inline operator float() const { return ((int32)data - 128) * (1.0f / 127.0f); }
43 private:
44 	uint8 data;
45 } _PACKED;
46 
47 class int8_sample
48 {
49 public:
operator uint8() const50 	inline operator uint8() const { return (int32)data + 128; }
operator int8() const51 	inline operator int8()  const { return data; }
operator int16() const52 	inline operator int16() const { return (int16)data << 8; }
operator int32() const53 	inline operator int32() const { return (int32)data << 24; }
operator float() const54 	inline operator float() const { return (int32)data * (1.0f / 127.0f); }
55 private:
56 	int8 data;
57 } _PACKED;
58 
59 class int16_sample
60 {
61 public:
operator uint8() const62 	inline operator uint8() const { return (uint8)((int8)(data >> 8) + 128); }
operator int8() const63 	inline operator int8()  const { return (int8)(data >> 8); }
operator int16() const64 	inline operator int16() const { return data; }
operator int32() const65 	inline operator int32() const { return (int32)data << 16; }
operator float() const66 	inline operator float() const { 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
operator uint8() const75 	inline operator uint8() const { return (int32)data[2] + 128; }
operator int8() const76 	inline operator int8()  const { return (int8)data[2]; }
operator int16() const77 	inline operator int16() const { return (int16)((uint32)data[2] << 8 | (uint32)data[1]); }
operator int32() const78 	inline operator int32() const { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8); }
operator float() const79 	inline operator float() const { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8) * (1.0f / 2147483647.0f); }
80 #else
81 	inline operator uint8() const { return (int32)data[0] + 128; }
82 	inline operator int8()  const { return (int8)data[0]; }
83 	inline operator int16() const { return (int16)((uint32)data[0] << 8 | (uint32)data[1]); }
84 	inline operator int32() const { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8); }
85 	inline operator float() const { return (int32)((uint32)data[0] << 24 | (uint32)data[1] << 16 | (uint32)data[2] << 8) * (1.0f / 2147483647.0f); }
86 #endif
87 private:
88 	uint8 data[3];
89 } _PACKED;
90 
91 class int32_sample
92 {
93 public:
operator uint8() const94 	inline operator uint8() const { return (int8)(data >> 24) + 128; }
operator int8() const95 	inline operator int8()  const { return (int8)(data >> 24); }
operator int16() const96 	inline operator int16() const { return (int16)(data >> 16); }
operator int32() const97 	inline operator int32() const { return data; }
operator float() const98 	inline operator float() const { return data * (1.0f / 2147483647.0f); }
99 private:
100 	int32 data;
101 } _PACKED;
102 
103 class float32_sample
104 {
105 public:
operator uint8() const106 	inline operator uint8() const { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
operator int8() const107 	inline operator int8()  const { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
operator int16() const108 	inline operator int16() const { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
operator int32() const109 	inline operator int32() const { if (data <= -1.0f) return INT32_MIN; if (data >= 1.0f) return INT32_MAX; return (int32)(data * INT32_MAX); }
operator float() const110 	inline operator float() const { return data; }
111 private:
112 	float32 data;
113 } _PACKED;
114 
115 class float64_sample
116 {
117 public:
operator uint8() const118 	inline operator uint8() const { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; }
operator int8() const119 	inline operator int8()  const { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; }
operator int16() const120 	inline operator int16() const { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; }
operator int32() const121 	inline operator int32() const { float64 v; if (data < -1.0) v = -1.0; else if (data > 1.0) v = 1.0; else v = data; return (int32)(v * INT32_MAX); }
operator float() const122 	inline operator float() const { return data; }
123 private:
124 	float64 data;
125 } _PACKED;
126 
127 #define CONVERT(src_type, dst_type)				\
128 void src_type##_to_##dst_type (void *dst, const void *src, int32 count) \
129 {												\
130 	const src_type##_sample *s = (const src_type##_sample *) src;	\
131 	dst_type *d = (dst_type *) dst;	\
132 	int32 c = count >> 4;				\
133 	if (!c) goto fin1;							\
134 	do {										\
135 		d[0] = s[0]; d[1] = s[1];				\
136 		d[2] = s[2]; d[3] = s[3];				\
137 		d[4] = s[4]; d[5] = s[5];				\
138 		d[6] = s[6]; d[7] = s[7];				\
139 		d[8] = s[8]; d[9] = s[9];				\
140 		d[10] = s[10]; d[11] = s[11];			\
141 		d[12] = s[12]; d[13] = s[13];			\
142 		d[14] = s[14]; d[15] = s[15];			\
143 		s += 16; d += 16;						\
144 	} while (--c);								\
145 fin1:											\
146 	c = count & 15;								\
147 	if (!c) goto fin2;							\
148 	do {										\
149 		*(d++) = *(s++);						\
150 	} while (--c);								\
151 fin2:											\
152 	;											\
153 }
154 
155 
CONVERT(uint8,uint8)156 CONVERT(uint8, uint8)
157 CONVERT(uint8, int8)
158 CONVERT(uint8, int16)
159 CONVERT(uint8, int32)
160 CONVERT(uint8, float32)
161 
162 CONVERT(int8, uint8)
163 CONVERT(int8, int8)
164 CONVERT(int8, int16)
165 CONVERT(int8, int32)
166 CONVERT(int8, float32)
167 
168 CONVERT(int16, uint8)
169 CONVERT(int16, int8)
170 CONVERT(int16, int16)
171 CONVERT(int16, int32)
172 CONVERT(int16, float32)
173 
174 CONVERT(int24, uint8)
175 CONVERT(int24, int8)
176 CONVERT(int24, int16)
177 CONVERT(int24, int32)
178 CONVERT(int24, float32)
179 
180 CONVERT(int32, uint8)
181 CONVERT(int32, int8)
182 CONVERT(int32, int16)
183 CONVERT(int32, int32)
184 CONVERT(int32, float32)
185 
186 CONVERT(float32, uint8)
187 CONVERT(float32, int8)
188 CONVERT(float32, int16)
189 CONVERT(float32, int32)
190 CONVERT(float32, float32)
191 
192 CONVERT(float64, uint8)
193 CONVERT(float64, int8)
194 CONVERT(float64, int16)
195 CONVERT(float64, int32)
196 CONVERT(float64, float32)
197 
198 void
199 swap_int16(void *data, int32 count)
200 {
201 	swap_data(B_INT16_TYPE, data, count * 2, B_SWAP_ALWAYS);
202 }
203 
204 void
swap_int24(void * data,int32 count)205 swap_int24(void *data, int32 count)
206 {
207 	int32 c = count;
208 	uint8 *d = (uint8 *)data;
209 	if (!c)
210 		return;
211 	do {
212 		uint8 temp = d[0];
213 		d[0] = d[2];
214 		d[2] = temp;
215 		d += 3;
216 	} while (--c);
217 }
218 
219 void
swap_int32(void * data,int32 count)220 swap_int32(void *data, int32 count)
221 {
222 	swap_data(B_INT32_TYPE, data, count * 4, B_SWAP_ALWAYS);
223 }
224 
225 void
swap_float32(void * data,int32 count)226 swap_float32(void *data, int32 count)
227 {
228 	swap_data(B_FLOAT_TYPE, data, count * 4, B_SWAP_ALWAYS);
229 }
230 
231 void
swap_float64(void * data,int32 count)232 swap_float64(void *data, int32 count)
233 {
234 	swap_data(B_INT64_TYPE, data, count * 8, B_SWAP_ALWAYS);
235 }
236