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 # include <stdio.h> 17 # define TRACE(x...) printf(x) 18 #else 19 # define TRACE(x...) 20 #endif 21 22 23 struct ReadFloat { 24 inline int operator()(const void* buffer) const { 25 // 0 == mid, -1.0 == bottom, 1.0 == top 26 float b = *(float*)buffer; 27 if (b < -1.0f) 28 b = -1.0f; 29 else if (b > 1.0f) 30 b = 1.0f; 31 return (int)((double)b * (double)0x7fffffff); 32 } 33 }; 34 35 struct ReadInt { 36 inline int operator()(const void* buffer) const { 37 // 0 == mid, 0x80000001 == bottom, 0x7fffffff == top 38 int b = *(int*)buffer; 39 if (b == INT_MIN) 40 b++; 41 return b; 42 } 43 }; 44 45 struct ReadShort { 46 inline int operator()(const void* buffer) const { 47 // 0 == mid, -32767 == bottom, +32767 48 short b = *(short*)buffer; 49 if (b == -32768) 50 b++; 51 return int(int64(b) * 0x7fffffff / 32767); 52 } 53 }; 54 55 struct ReadUChar { 56 inline int operator()(const void* buffer) const { 57 // 128 == mid, 1 == bottom, 255 == top 58 uchar b = *(uchar*)buffer; 59 if (b == 0) 60 b++; 61 return int((int64(b) - 0x80) * 0x7fffffff / 127); 62 } 63 }; 64 65 struct ReadChar { 66 inline int operator()(const void* buffer) const { 67 // 0 == mid, -127 == bottom, +127 == top 68 char b = *(char*)buffer; 69 if (b == 0) 70 b++; 71 return int(int64(b) * 0x7fffffff / 127); 72 } 73 }; 74 75 struct WriteFloat { 76 inline void operator()(void* buffer, int value) const { 77 *(float*)buffer = (double)value / (double)0x7fffffff; 78 } 79 80 }; 81 82 struct WriteInt { 83 inline void operator()(void* buffer, int value) const { 84 *(int*)buffer = value; 85 } 86 }; 87 88 struct WriteShort { 89 inline void operator()(void* buffer, int value) const { 90 *(short*)buffer = (short)(value / (int)0x10000); 91 } 92 }; 93 94 struct WriteUChar { 95 inline void operator()(void* buffer, int value) const { 96 *(uchar*)buffer = (uchar)(value / (int)0x1000000 + 128); 97 } 98 }; 99 100 struct WriteChar { 101 inline void operator()(void* buffer, int value) const { 102 *(char*)buffer = (char)(value / (int)0x1000000); 103 } 104 }; 105 106 107 template<typename ReadT, typename WriteT> 108 static void 109 convert(const ReadT& read, const WriteT& write, 110 const char* inBuffer, char* outBuffer, int32 frames, 111 int32 inSampleSize, int32 outSampleSize, int32 channelCount) 112 { 113 for (int32 i = 0; i < frames; i++) { 114 for (int32 c = 0; c < channelCount; c++) { 115 write(outBuffer, read(inBuffer)); 116 inBuffer += inSampleSize; 117 outBuffer += outSampleSize; 118 } 119 } 120 } 121 122 123 static void 124 swap_sample_byte_order(void* buffer, uint32 format, size_t length) 125 { 126 type_code type = B_ANY_TYPE; 127 switch (format) { 128 case media_raw_audio_format::B_AUDIO_FLOAT: 129 type = B_FLOAT_TYPE; 130 break; 131 case media_raw_audio_format::B_AUDIO_INT: 132 type = B_INT32_TYPE; 133 break; 134 case media_raw_audio_format::B_AUDIO_SHORT: 135 type = B_INT16_TYPE; 136 break; 137 case media_raw_audio_format::B_AUDIO_UCHAR: 138 break; 139 case media_raw_audio_format::B_AUDIO_CHAR: 140 break; 141 } 142 if (type != B_ANY_TYPE) 143 swap_data(type, buffer, length, B_SWAP_ALWAYS); 144 } 145 146 147 // #pragma mark - 148 149 150 AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format, 151 uint32 byteOrder) 152 : 153 AudioReader(), 154 fSource(NULL) 155 { 156 uint32 hostByteOrder 157 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; 158 if (source && source->Format().type == B_MEDIA_RAW_AUDIO 159 && source->Format().u.raw_audio.byte_order == hostByteOrder) { 160 fFormat = source->Format(); 161 fFormat.u.raw_audio.format = format; 162 fFormat.u.raw_audio.byte_order = byteOrder; 163 int32 inSampleSize = source->Format().u.raw_audio.format 164 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 165 int32 outSampleSize = fFormat.u.raw_audio.format 166 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 167 if (inSampleSize != outSampleSize) { 168 fFormat.u.raw_audio.buffer_size 169 = source->Format().u.raw_audio.buffer_size * outSampleSize 170 / inSampleSize; 171 } 172 } else 173 source = NULL; 174 fSource = source; 175 } 176 177 178 AudioFormatConverter::~AudioFormatConverter() 179 { 180 } 181 182 183 bigtime_t 184 AudioFormatConverter::InitialLatency() const 185 { 186 return fSource->InitialLatency(); 187 } 188 189 status_t 190 AudioFormatConverter::Read(void* buffer, int64 pos, int64 frames) 191 { 192 TRACE("AudioFormatConverter::Read(%p, %lld, %lld)\n", buffer, pos, frames); 193 status_t error = InitCheck(); 194 if (error != B_OK) { 195 TRACE("AudioFormatConverter::Read() done 1\n"); 196 return error; 197 } 198 pos += fOutOffset; 199 200 if (fFormat.u.raw_audio.format == fSource->Format().u.raw_audio.format 201 && fFormat.u.raw_audio.byte_order 202 == fSource->Format().u.raw_audio.byte_order) { 203 TRACE("AudioFormatConverter::Read() done 2\n"); 204 return fSource->Read(buffer, pos, frames); 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