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