PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/add-ons/media/plugins/raw_decoder/AudioConversion.cpp

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