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