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