1 /* 2 * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de> 3 * Copyright © 2008 Stephan Aßmus <superstippi@gmx.de> 4 * All rights reserved. Distributed under the terms of the MIT licensce. 5 */ 6 7 #include "AudioFormatConverter.h" 8 9 #include <ByteOrder.h> 10 #include <MediaDefs.h> 11 12 13 //#define TRACE_AUDIO_CONVERTER 14 #ifdef TRACE_AUDIO_CONVERTER 15 # define TRACE(x...) printf(x) 16 #else 17 # define TRACE(x...) 18 #endif 19 20 21 AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format, 22 uint32 byte_order) 23 : AudioReader(), 24 fSource(NULL) 25 { 26 uint32 hostByteOrder 27 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; 28 if (source && source->Format().type == B_MEDIA_RAW_AUDIO 29 && source->Format().u.raw_audio.byte_order == hostByteOrder) { 30 fFormat = source->Format(); 31 fFormat.u.raw_audio.format = format; 32 fFormat.u.raw_audio.byte_order = byte_order; 33 int32 inSampleSize = source->Format().u.raw_audio.format 34 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 35 int32 outSampleSize = fFormat.u.raw_audio.format 36 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 37 if (inSampleSize != outSampleSize) { 38 fFormat.u.raw_audio.buffer_size 39 = source->Format().u.raw_audio.buffer_size * outSampleSize 40 / inSampleSize; 41 } 42 } else 43 source = NULL; 44 fSource = source; 45 } 46 47 48 AudioFormatConverter::~AudioFormatConverter() 49 { 50 } 51 52 53 struct ReadFloat { 54 inline int operator()(const void* buffer) const { 55 // 0 == mid, -1.0 == bottom, 1.0 == top 56 float b = *(float*)buffer; 57 if (b < -1.0f) 58 b = -1.0f; 59 else if (b > 1.0f) 60 b = 1.0f; 61 return (int)((double)b * (double)0x7fffffff); 62 } 63 }; 64 65 struct ReadInt { 66 inline int operator()(const void* buffer) const { 67 // 0 == mid, 0x80000001 == bottom, 0x7fffffff == top 68 short b = *(int*)buffer; 69 if (b == 0x80000000) 70 b++; 71 return b; 72 } 73 }; 74 75 struct ReadShort { 76 inline int operator()(const void* buffer) const { 77 // 0 == mid, -32767 == bottom, +32767 78 short b = *(short*)buffer; 79 if (b == -32768) 80 b++; 81 return int(int64(b) * 0x7fffffff / 32767); 82 } 83 }; 84 85 struct ReadUChar { 86 inline int operator()(const void* buffer) const { 87 // 128 == mid, 1 == bottom, 255 == top 88 uchar b = *(uchar*)buffer; 89 if (b == 0) 90 b++; 91 return int((int64(b) - 0x80) * 0x7fffffff / 127); 92 } 93 }; 94 95 struct ReadChar { 96 inline int operator()(const void* buffer) const { 97 // 0 == mid, -127 == bottom, +127 == top 98 char b = *(char*)buffer; 99 if (b == 0) 100 b++; 101 return int(int64(b) * 0x7fffffff / 127); 102 } 103 }; 104 105 struct WriteFloat { 106 inline void operator()(void* buffer, int value) const { 107 *(float*)buffer = (double)value / (double)0x7fffffff; 108 } 109 110 }; 111 112 struct WriteInt { 113 inline void operator()(void* buffer, int value) const { 114 *(int*)buffer = value; 115 } 116 }; 117 118 struct WriteShort { 119 inline void operator()(void* buffer, int value) const { 120 *(short*)buffer = (short)(value / (int)0x10000); 121 } 122 }; 123 124 struct WriteUChar { 125 inline void operator()(void* buffer, int value) const { 126 *(uchar*)buffer = (uchar)(value / (int)0x1000000 + 128); 127 } 128 }; 129 130 struct WriteChar { 131 inline void operator()(void* buffer, int value) const { 132 *(char*)buffer = (char)(value / (int)0x1000000); 133 } 134 }; 135 136 137 template<typename ReadT, typename WriteT> 138 static void 139 convert(const ReadT& read, const WriteT& write, 140 const char* inBuffer, char* outBuffer, int32 frames, 141 int32 inSampleSize, int32 outSampleSize, int32 channelCount) 142 { 143 for (int32 i = 0; i < frames; i++) { 144 for (int32 c = 0; c < channelCount; c++) { 145 write(outBuffer, read(inBuffer)); 146 inBuffer += inSampleSize; 147 outBuffer += outSampleSize; 148 } 149 } 150 } 151 152 153 static 154 void 155 swap_sample_byte_order(void* buffer, uint32 format, size_t length) 156 { 157 type_code type = B_ANY_TYPE; 158 switch (format) { 159 case media_raw_audio_format::B_AUDIO_FLOAT: 160 type = B_FLOAT_TYPE; 161 break; 162 case media_raw_audio_format::B_AUDIO_INT: 163 type = B_INT32_TYPE; 164 break; 165 case media_raw_audio_format::B_AUDIO_SHORT: 166 type = B_INT16_TYPE; 167 break; 168 case media_raw_audio_format::B_AUDIO_UCHAR: 169 break; 170 case media_raw_audio_format::B_AUDIO_CHAR: 171 break; 172 } 173 if (type != B_ANY_TYPE) 174 swap_data(type, buffer, length, B_SWAP_ALWAYS); 175 } 176 177 178 status_t 179 AudioFormatConverter::Read(void* buffer, int64 pos, int64 frames) 180 { 181 TRACE("AudioFormatConverter::Read(%p, %Ld, %Ld)\n", buffer, pos, frames); 182 status_t error = InitCheck(); 183 if (error != B_OK) { 184 TRACE("AudioFormatConverter::Read() done 1\n"); 185 return error; 186 } 187 pos += fOutOffset; 188 189 if (fFormat.u.raw_audio.format == fSource->Format().u.raw_audio.format 190 && fFormat.u.raw_audio.byte_order 191 == fSource->Format().u.raw_audio.byte_order) { 192 TRACE("AudioFormatConverter::Read() done 2\n"); 193 return fSource->Read(buffer, pos, frames); 194 } 195 196 197 int32 inSampleSize = fSource->Format().u.raw_audio.format 198 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 199 int32 outSampleSize = fFormat.u.raw_audio.format 200 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 201 int32 channelCount = fFormat.u.raw_audio.channel_count; 202 int32 inFrameSize = inSampleSize * channelCount; 203 int32 outFrameSize = outSampleSize * channelCount; 204 char* reformatBuffer = NULL; 205 char* inBuffer = (char*)buffer; 206 207 #ifdef TRACE_AUDIO_CONVERTER 208 char formatString[256]; 209 string_for_format(fSource->Format(), formatString, 256); 210 TRACE(" source format: %s\n", formatString); 211 TRACE(" in format : format: %lx, sample size: %ld, channels: %ld, " 212 "byte order: %lu\n", fSource->Format().u.raw_audio.format, 213 inSampleSize, channelCount, 214 fSource->Format().u.raw_audio.byte_order); 215 TRACE(" out format: format: %lx, sample size: %ld, channels: %ld, " 216 "byte order: %lu\n", fFormat.u.raw_audio.format, outSampleSize, 217 channelCount, fFormat.u.raw_audio.byte_order); 218 #endif // TRACE_AUDIO_CONVERTER 219 220 if (inSampleSize != outSampleSize) { 221 reformatBuffer = new char[frames * inFrameSize]; 222 inBuffer = reformatBuffer; 223 } 224 error = fSource->Read(inBuffer, pos, frames); 225 // convert samples to host endianess 226 uint32 hostByteOrder 227 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; 228 if (fSource->Format().u.raw_audio.byte_order != hostByteOrder) { 229 swap_sample_byte_order(inBuffer, fSource->Format().u.raw_audio.format, 230 frames * inFrameSize); 231 } 232 // convert the sample type 233 switch (fSource->Format().u.raw_audio.format) { 234 // float 235 case media_raw_audio_format::B_AUDIO_FLOAT: 236 switch (fFormat.u.raw_audio.format) { 237 case media_raw_audio_format::B_AUDIO_FLOAT: 238 break; 239 case media_raw_audio_format::B_AUDIO_INT: 240 convert(ReadFloat(), WriteInt(), inBuffer, (char*)buffer, 241 frames, inSampleSize, outSampleSize, channelCount); 242 break; 243 case media_raw_audio_format::B_AUDIO_SHORT: 244 convert(ReadFloat(), WriteShort(), inBuffer, (char*)buffer, 245 frames, inSampleSize, outSampleSize, channelCount); 246 break; 247 case media_raw_audio_format::B_AUDIO_UCHAR: 248 convert(ReadFloat(), WriteUChar(), inBuffer, (char*)buffer, 249 frames, inSampleSize, outSampleSize, channelCount); 250 break; 251 case media_raw_audio_format::B_AUDIO_CHAR: 252 convert(ReadFloat(), WriteChar(), inBuffer, (char*)buffer, 253 frames, inSampleSize, outSampleSize, channelCount); 254 break; 255 } 256 break; 257 // int 258 case media_raw_audio_format::B_AUDIO_INT: 259 switch (fFormat.u.raw_audio.format) { 260 case media_raw_audio_format::B_AUDIO_FLOAT: 261 convert(ReadInt(), WriteFloat(), inBuffer, (char*)buffer, 262 frames, inSampleSize, outSampleSize, channelCount); 263 break; 264 case media_raw_audio_format::B_AUDIO_INT: 265 break; 266 case media_raw_audio_format::B_AUDIO_SHORT: 267 convert(ReadInt(), WriteShort(), inBuffer, (char*)buffer, 268 frames, inSampleSize, outSampleSize, channelCount); 269 break; 270 case media_raw_audio_format::B_AUDIO_UCHAR: 271 convert(ReadInt(), WriteUChar(), inBuffer, (char*)buffer, 272 frames, inSampleSize, outSampleSize, channelCount); 273 break; 274 case media_raw_audio_format::B_AUDIO_CHAR: 275 convert(ReadInt(), WriteChar(), inBuffer, (char*)buffer, 276 frames, inSampleSize, outSampleSize, channelCount); 277 break; 278 } 279 break; 280 // short 281 case media_raw_audio_format::B_AUDIO_SHORT: 282 switch (fFormat.u.raw_audio.format) { 283 case media_raw_audio_format::B_AUDIO_FLOAT: 284 convert(ReadShort(), WriteFloat(), inBuffer, (char*)buffer, 285 frames, inSampleSize, outSampleSize, channelCount); 286 break; 287 case media_raw_audio_format::B_AUDIO_INT: 288 convert(ReadShort(), WriteInt(), inBuffer, (char*)buffer, 289 frames, inSampleSize, outSampleSize, channelCount); 290 break; 291 case media_raw_audio_format::B_AUDIO_SHORT: 292 break; 293 case media_raw_audio_format::B_AUDIO_UCHAR: 294 convert(ReadShort(), WriteUChar(), inBuffer, (char*)buffer, 295 frames, inSampleSize, outSampleSize, channelCount); 296 break; 297 case media_raw_audio_format::B_AUDIO_CHAR: 298 convert(ReadShort(), WriteChar(), inBuffer, (char*)buffer, 299 frames, inSampleSize, outSampleSize, channelCount); 300 break; 301 } 302 break; 303 // uchar 304 case media_raw_audio_format::B_AUDIO_UCHAR: 305 switch (fFormat.u.raw_audio.format) { 306 case media_raw_audio_format::B_AUDIO_FLOAT: 307 convert(ReadUChar(), WriteFloat(), inBuffer, (char*)buffer, 308 frames, inSampleSize, outSampleSize, channelCount); 309 break; 310 case media_raw_audio_format::B_AUDIO_INT: 311 convert(ReadUChar(), WriteInt(), inBuffer, (char*)buffer, 312 frames, inSampleSize, outSampleSize, channelCount); 313 break; 314 case media_raw_audio_format::B_AUDIO_SHORT: 315 convert(ReadUChar(), WriteShort(), inBuffer, (char*)buffer, 316 frames, inSampleSize, outSampleSize, channelCount); 317 break; 318 case media_raw_audio_format::B_AUDIO_UCHAR: 319 break; 320 case media_raw_audio_format::B_AUDIO_CHAR: 321 convert(ReadUChar(), WriteChar(), inBuffer, (char*)buffer, 322 frames, inSampleSize, outSampleSize, channelCount); 323 break; 324 } 325 break; 326 // char 327 case media_raw_audio_format::B_AUDIO_CHAR: 328 switch (fFormat.u.raw_audio.format) { 329 case media_raw_audio_format::B_AUDIO_FLOAT: 330 convert(ReadChar(), WriteFloat(), inBuffer, (char*)buffer, 331 frames, inSampleSize, outSampleSize, channelCount); 332 break; 333 case media_raw_audio_format::B_AUDIO_INT: 334 convert(ReadChar(), WriteInt(), inBuffer, (char*)buffer, 335 frames, inSampleSize, outSampleSize, channelCount); 336 break; 337 case media_raw_audio_format::B_AUDIO_SHORT: 338 convert(ReadChar(), WriteShort(), inBuffer, (char*)buffer, 339 frames, inSampleSize, outSampleSize, channelCount); 340 break; 341 case media_raw_audio_format::B_AUDIO_UCHAR: 342 convert(ReadChar(), WriteUChar(), inBuffer, (char*)buffer, 343 frames, inSampleSize, outSampleSize, channelCount); 344 break; 345 case media_raw_audio_format::B_AUDIO_CHAR: 346 break; 347 } 348 break; 349 } 350 // convert samples to output endianess 351 if (fFormat.u.raw_audio.byte_order != hostByteOrder) { 352 swap_sample_byte_order(buffer, fFormat.u.raw_audio.format, 353 frames * outFrameSize); 354 } 355 356 delete[] reformatBuffer; 357 TRACE("AudioFormatConverter::Read() done\n"); 358 return B_OK; 359 } 360 361 362 status_t 363 AudioFormatConverter::InitCheck() const 364 { 365 status_t error = AudioReader::InitCheck(); 366 if (error == B_OK && !fSource) 367 error = B_NO_INIT; 368 if (error == B_OK) 369 error = fSource->InitCheck(); 370 return error; 371 } 372 373 374 AudioReader* 375 AudioFormatConverter::Source() const 376 { 377 return fSource; 378 } 379 380