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 32typedef float float32; 33typedef double float64; 34 35class uint8_sample 36{ 37public: 38 inline operator uint8() const { return data; } 39 inline operator int8() const { return (int32)data - 128; } 40 inline operator int16() const { return ((int32)data - 128) << 8; } 41 inline operator int32() const { return ((int32)data - 128) << 24; } 42 inline operator float() const { return ((int32)data - 128) * (1.0f / 127.0f); } 43private: 44 uint8 data; 45} _PACKED; 46 47class int8_sample 48{ 49public: 50 inline operator uint8() const { return (int32)data + 128; } 51 inline operator int8() const { return data; } 52 inline operator int16() const { return (int16)data << 8; } 53 inline operator int32() const { return (int32)data << 24; } 54 inline operator float() const { return (int32)data * (1.0f / 127.0f); } 55private: 56 int8 data; 57} _PACKED; 58 59class int16_sample 60{ 61public: 62 inline operator uint8() const { return (uint8)((int8)(data >> 8) + 128); } 63 inline operator int8() const { return (int8)(data >> 8); } 64 inline operator int16() const { return data; } 65 inline operator int32() const { return (int32)data << 16; } 66 inline operator float() const { return data * (1.0f / 32767.0f); } 67private: 68 int16 data; 69} _PACKED; 70 71class int24_sample 72{ 73public: 74#if B_HOST_IS_LENDIAN 75 inline operator uint8() const { return (int32)data[2] + 128; } 76 inline operator int8() const { return (int8)data[2]; } 77 inline operator int16() const { return (int16)((uint32)data[2] << 8 | (uint32)data[1]); } 78 inline operator int32() const { return (int32)((uint32)data[2] << 24 | (uint32)data[1] << 16 | (uint32)data[0] << 8); } 79 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 87private: 88 uint8 data[3]; 89} _PACKED; 90 91class int32_sample 92{ 93public: 94 inline operator uint8() const { return (int8)(data >> 24) + 128; } 95 inline operator int8() const { return (int8)(data >> 24); } 96 inline operator int16() const { return (int16)(data >> 16); } 97 inline operator int32() const { return data; } 98 inline operator float() const { return data * (1.0f / 2147483647.0f); } 99private: 100 int32 data; 101} _PACKED; 102 103class float32_sample 104{ 105public: 106 inline operator uint8() const { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; } 107 inline operator int8() const { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; } 108 inline operator int16() const { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; } 109 inline operator int32() const { if (data <= -1.0f) return INT32_MIN; if (data >= 1.0f) return INT32_MAX; return (int32)(data * INT32_MAX); } 110 inline operator float() const { return data; } 111private: 112 float32 data; 113} _PACKED; 114 115class float64_sample 116{ 117public: 118 inline operator uint8() const { int32 v = (int32)(data * 127.0f) + 128; if (v > 255) v = 255; else if (v < 0) v = 0; return v; } 119 inline operator int8() const { int32 v = (int32)(data * 127.0f); if (v > 127) v = 127; else if (v < -127) v = -127; return v; } 120 inline operator int16() const { int32 v = (int32)(data * 32767.0f); if (v > 32767) v = 32767; else if (v < -32767) v = -32767; return v; } 121 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); } 122 inline operator float() const { return data; } 123private: 124 float64 data; 125} _PACKED; 126 127#define CONVERT(src_type, dst_type) \ 128void 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); \ 145fin1: \ 146 c = count & 15; \ 147 if (!c) goto fin2; \ 148 do { \ 149 *(d++) = *(s++); \ 150 } while (--c); \ 151fin2: \ 152 ; \ 153} 154 155 156CONVERT(uint8, uint8) 157CONVERT(uint8, int8) 158CONVERT(uint8, int16) 159CONVERT(uint8, int32) 160CONVERT(uint8, float32) 161 162CONVERT(int8, uint8) 163CONVERT(int8, int8) 164CONVERT(int8, int16) 165CONVERT(int8, int32) 166CONVERT(int8, float32) 167 168CONVERT(int16, uint8) 169CONVERT(int16, int8) 170CONVERT(int16, int16) 171CONVERT(int16, int32) 172CONVERT(int16, float32) 173 174CONVERT(int24, uint8) 175CONVERT(int24, int8) 176CONVERT(int24, int16) 177CONVERT(int24, int32) 178CONVERT(int24, float32) 179 180CONVERT(int32, uint8) 181CONVERT(int32, int8) 182CONVERT(int32, int16) 183CONVERT(int32, int32) 184CONVERT(int32, float32) 185 186CONVERT(float32, uint8) 187CONVERT(float32, int8) 188CONVERT(float32, int16) 189CONVERT(float32, int32) 190CONVERT(float32, float32) 191 192CONVERT(float64, uint8) 193CONVERT(float64, int8) 194CONVERT(float64, int16) 195CONVERT(float64, int32) 196CONVERT(float64, float32) 197 198void 199swap_int16(void *data, int32 count) 200{ 201 swap_data(B_INT16_TYPE, data, count * 2, B_SWAP_ALWAYS); 202} 203 204void 205swap_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 219void 220swap_int32(void *data, int32 count) 221{ 222 swap_data(B_INT32_TYPE, data, count * 4, B_SWAP_ALWAYS); 223} 224 225void 226swap_float32(void *data, int32 count) 227{ 228 swap_data(B_FLOAT_TYPE, data, count * 4, B_SWAP_ALWAYS); 229} 230 231void 232swap_float64(void *data, int32 count) 233{ 234 swap_data(B_INT64_TYPE, data, count * 8, B_SWAP_ALWAYS); 235} 236