1/* Copyright: © Copyright 2005-2010 Apple Computer, Inc. All rights reserved. 2 3 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. 4 ("Apple") in consideration of your agreement to the following terms, and your 5 use, installation, modification or redistribution of this Apple software 6 constitutes acceptance of these terms. If you do not agree with these terms, 7 please do not use, install, modify or redistribute this Apple software. 8 9 In consideration of your agreement to abide by the following terms, and subject 10 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s 11 copyrights in this original Apple software (the "Apple Software"), to use, 12 reproduce, modify and redistribute the Apple Software, with or without 13 modifications, in source and/or binary forms; provided that if you redistribute 14 the Apple Software in its entirety and without modifications, you must retain 15 this notice and the following text and disclaimers in all such redistributions of 16 the Apple Software. Neither the name, trademarks, service marks or logos of 17 Apple Computer, Inc. may be used to endorse or promote products derived from the 18 Apple Software without specific prior written permission from Apple. Except as 19 expressly stated in this notice, no other rights or licenses, express or implied, 20 are granted by Apple herein, including but not limited to any patent rights that 21 may be infringed by your derivative works or by other works in which the Apple 22 Software may be incorporated. 23 24 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO 25 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED 26 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN 28 COMBINATION WITH YOUR PRODUCTS. 29 30 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR 31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 32 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION 34 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT 35 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN 36 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 */ 38/*============================================================================= 39 IOAudioBlitterLib.h 40 41 =============================================================================*/ 42 43#ifndef __IOAudioBlitterLib_h__ 44#define __IOAudioBlitterLib_h__ 45 46#include <TargetConditionals.h> 47#include <libkern/OSTypes.h> 48#include <libkern/OSByteOrder.h> 49 50typedef float Float32; 51typedef double Float64; 52 53#define NO_EXPORT __attribute__((visibility("hidden"))) 54 55// ============================================================================ 56// 57// N.B. These functions should not be called directly; use the interfaces in 58// PCMBlitterLibDispatch.h. 59// 60// ============================================================================ 61 62// can turn these off for debugging 63#define PCMBLIT_PPC TARGET_CPU_PPC 64#define PCMBLIT_X86 (__i386__ || __LP64__) 65 66#if TARGET_CPU_PPC && !PCMBLIT_PPC 67#warning "PPC optimizations turned off" 68#endif 69 70#if __i386__ && !PCMBLIT_X86 71#warning "X86 optimizations turned off" 72#endif 73 74#define PCMBLIT_INTERLEAVE_SUPPORT TARGET_CPU_PPC // uses Altivec 75 76typedef const void *ConstVoidPtr; 77 78#pragma mark - 79#pragma mark Utilities 80#if TARGET_OS_MAC && TARGET_CPU_PPC 81#define SET_ROUNDMODE \ 82double oldSetting; \ 83/* Set the FPSCR to round to -Inf mode */ \ 84{ \ 85union { \ 86double d; \ 87int i[2]; \ 88} setting; \ 89register double newSetting; \ 90/* Read the the current FPSCR value */ \ 91__asm__ __volatile__ ( "mffs %0" : "=f" ( oldSetting ) ); \ 92/* Store it to the stack */ \ 93setting.d = oldSetting; \ 94/* Read in the low 32 bits and mask off the last two bits so they are zero */ \ 95/* in the integer unit. These two bits set to zero means round to nearest mode. */ \ 96/* Finally, then store the result back */ \ 97setting.i[1] |= 3; \ 98/* Load the new FPSCR setting into the FP register file again */ \ 99newSetting = setting.d; \ 100/* Change the volatile to the new setting */ \ 101__asm__ __volatile__( "mtfsf 7, %0" : : "f" (newSetting ) ); \ 102} 103 104#define RESTORE_ROUNDMODE \ 105/* restore the old FPSCR setting */ \ 106__asm__ __volatile__ ( "mtfsf 7, %0" : : "f" (oldSetting) ); 107#define DISABLE_DENORMALS 108#define RESTORE_DENORMALS 109 110#elif TARGET_OS_MAC && __i386__ 111// our compiler does ALL floating point with SSE 112#define GETCSR() ({ int _result; asm volatile ("stmxcsr %0" : "=m" (*&_result) ); /*return*/ _result; }) 113#define SETCSR( a ) { int _temp = a; asm volatile( "ldmxcsr %0" : : "m" (*&_temp ) ); } 114 115#define DISABLE_DENORMALS int _savemxcsr = GETCSR(); SETCSR(_savemxcsr | 0x8040); 116#define RESTORE_DENORMALS SETCSR(_savemxcsr); 117 118#define ROUNDMODE_NEG_INF int _savemxcsr = GETCSR(); SETCSR((_savemxcsr & ~0x6000) | 0x2000); 119#define ROUNDMODE_NEAREST int _savemxcsr = GETCSR(); SETCSR((_savemxcsr & ~0x6000)); 120 121#define RESTORE_ROUNDMODE SETCSR(_savemxcsr); 122#define SET_ROUNDMODE ROUNDMODE_NEG_INF 123#elif TARGET_OS_MAC && __LP64__ 124// our compiler does ALL floating point with SSE 125#define GETCSR() ({ int _result; asm volatile ("stmxcsr %0" : "=m" (*&_result) ); /*return*/ _result; }) 126#define SETCSR( a ) { int _temp = a; asm volatile( "ldmxcsr %0" : : "m" (*&_temp ) ); } 127 128#define DISABLE_DENORMALS int _savemxcsr = GETCSR(); SETCSR(_savemxcsr | 0x8040); 129#define RESTORE_DENORMALS SETCSR(_savemxcsr); 130 131#define ROUNDMODE_NEG_INF int _savemxcsr = GETCSR(); SETCSR((_savemxcsr & ~0x6000) | 0x2000); 132#define ROUNDMODE_NEAREST int _savemxcsr = GETCSR(); SETCSR((_savemxcsr & ~0x6000)); 133 134#define RESTORE_ROUNDMODE SETCSR(_savemxcsr); 135#define SET_ROUNDMODE ROUNDMODE_NEG_INF 136#else 137#define DISABLE_DENORMALS 138#define RESTORE_DENORMALS 139 140#define ROUNDMODE_NEG_INF 141#define RESTORE_ROUNDMODE 142#endif 143 144// ____________________________________________________________________________ 145// 146// FloatToInt 147// N.B. Functions which use this should invoke SET_ROUNDMODE / RESTORE_ROUNDMODE. 148static inline SInt32 FloatToInt(double inf, double min32, double max32) 149{ 150#if TARGET_CPU_PPC 151#pragma unused ( min32,max32) 152 SInt32 i; 153 union { 154 Float64 d; 155 UInt32 i[2]; 156 } u; 157 // fctiw rounds, doesn't truncate towards zero like fctiwz 158 __asm__ ("fctiw %0, %1" 159 /* outputs: */ : "=f" (u.d) 160 /* inputs: */ : "f" (inf)); 161 i = u.i[1]; 162 return i; 163#elif defined( __i386__ ) || defined( __LP64__ ) 164#pragma unused ( min32 ) 165 166 if (inf >= max32) return 0x7FFFFFFF; 167 return (SInt32)inf; 168#else 169 if (inf >= max32) return 0x7FFFFFFF; 170 else if (inf <= min32) return 0x80000000; 171 return (SInt32)inf; 172#endif 173} 174 175#ifdef __cplusplus 176#pragma mark - 177#pragma mark C++ templates 178// ____________________________________________________________________________ 179// 180// PCMBlitter 181class PCMBlitter { 182public: 183 virtual void Convert(const void *vsrc, void *vdest, unsigned int nSamples) = 0; 184 // nSamples = nFrames * nChannels 185 virtual ~PCMBlitter() { } 186 187#if PCMBLIT_INTERLEAVE_SUPPORT 188 // optional methods 189 virtual void Interleave(ConstVoidPtr , void *, int , unsigned int ) { } 190 virtual void Deinterleave(ConstVoidPtr , void *, int , unsigned int ) { } 191#endif 192}; 193 194// ____________________________________________________________________________ 195// 196// Types for use in templates 197class PCMFloat32 { 198public: 199 typedef Float32 value_type; 200 201 static value_type load(const value_type *p) { return *p; } 202 static void store(value_type *p, float val) { *p = val; } 203}; 204 205class PCMFloat64 { 206public: 207 typedef Float64 value_type; 208 209 static value_type load(const value_type *p) { return *p; } 210 static void store(value_type *p, value_type val) { *p = val; } 211}; 212 213class PCMSInt8 { 214public: 215 typedef SInt8 value_type; 216 217 static value_type load(const value_type *p) { return *p; } 218 static void store(value_type *p, int val) { *p = val; } 219}; 220 221class PCMUInt8 { 222public: 223 typedef SInt8 value_type; // signed so that sign-extending works right 224 225 static value_type load(const value_type *p) { return *p ^ 0x80; } 226 static void store(value_type *p, int val) { *p = val ^ 0x80; } 227}; 228 229class PCMSInt16Native { 230public: 231 typedef SInt16 value_type; 232 233 static value_type load(const value_type *p) { return *p; } 234 static void store(value_type *p, int val) { *p = val; } 235}; 236 237class PCMSInt16Swap { 238public: 239 typedef SInt16 value_type; 240 241 static value_type load(const value_type *p) 242 { 243#if PCMBLIT_PPC 244 register SInt32 result; 245 __asm__ volatile("lhbrx %0, %1, %2" 246 /* outputs: */ : "=r" (result) 247 /* inputs: */ : "b%" (0), "r" (p) 248 /* clobbers: */ : "memory"); 249 return result; 250#elif PCMBLIT_X86 && !TARGET_OS_WIN32 251 return OSReadSwapInt16(p, 0); 252#else 253 return Endian16_Swap(*p); 254#endif 255 } 256 static void store(value_type *p, int val) 257 { 258#if PCMBLIT_PPC 259 __asm__ volatile("sthbrx %0, %1, %2" : : "r" (val), "b%" (0), "r" (p) : "memory"); 260#elif PCMBLIT_X86 && !TARGET_OS_WIN32 261 OSWriteSwapInt16(p, 0, val); 262#else 263 *p = Endian16_Swap(val); 264#endif 265 } 266}; 267 268class PCMSInt32Native { 269public: 270 typedef SInt32 value_type; 271 272 static value_type load(const value_type *p) { return *p; } 273 static void store(value_type *p, int val) { *p = val; } 274}; 275 276class PCMSInt32Swap { 277public: 278 typedef UInt32 value_type; 279 280 static value_type load(const value_type *p) 281 { 282#if PCMBLIT_PPC 283 register long lwbrxResult; 284 __asm__ volatile("lwbrx %0, %1, %2" : "=r" (lwbrxResult) : "b%" (0), "r" (p) : "memory"); 285 return lwbrxResult; 286#elif PCMBLIT_X86 && !TARGET_OS_WIN32 287 return OSReadSwapInt32(p, 0); 288#else 289 return Endian32_Swap(*p); 290#endif 291 } 292 static void store(value_type *p, int val) 293 { 294 *p = val; 295#if PCMBLIT_PPC 296 __asm__ volatile("stwbrx %0, %1, %2" : : "r" (val), "b%" (0), "r" (p) : "memory"); 297#elif PCMBLIT_X86 && !TARGET_OS_WIN32 298 OSWriteSwapInt32(p, 0, val); 299#else 300 *p = Endian32_Swap(val); 301#endif 302 } 303}; 304 305class PCMFloat64Swap { 306public: 307 typedef Float64 value_type; 308 309 static value_type load(const value_type *vp) { 310 union { 311 Float64 d; 312 UInt32 i[2]; 313 } u; 314 UInt32 *p = (UInt32 *)vp; 315 u.i[0] = PCMSInt32Swap::load(p + 1); 316 u.i[1] = PCMSInt32Swap::load(p + 0); 317 return u.d; 318 } 319 static void store(value_type *vp, value_type val) { 320 union { 321 Float64 d; 322 UInt32 i[2]; 323 } u; 324 u.d = val; 325 UInt32 *p = (UInt32 *)vp; 326 PCMSInt32Swap::store(p + 1, u.i[0]); 327 PCMSInt32Swap::store(p + 0, u.i[1]); 328 } 329}; 330 331// ____________________________________________________________________________ 332// 333// FloatToIntBlitter 334class FloatToIntBlitter : public PCMBlitter { 335public: 336 FloatToIntBlitter(int bitDepth) 337 { 338 int rightShift = 32 - bitDepth; 339 mShift = rightShift; 340 mRound = (rightShift > 0) ? double(1L << (rightShift - 1)) : 0.; 341 } 342 343protected: 344 double mRound; 345 int mShift; // how far to shift a 32 bit value right 346}; 347 348// ____________________________________________________________________________ 349// 350// TFloatToIntBlitter 351// only used for: 8-bit, low-aligned, or non-PPC 352template <class FloatType, class IntType> 353class TFloatToIntBlitter : public FloatToIntBlitter { 354public: 355 typedef typename FloatType::value_type float_val; 356 typedef typename IntType::value_type int_val; 357 358 TFloatToIntBlitter(int bitDepth) : FloatToIntBlitter(bitDepth) { } 359 360 virtual void Convert(const void *vsrc, void *vdest, unsigned int nSamples) 361 { 362 const float_val *src = (const float_val *)vsrc; 363 int_val *dest = (int_val *)vdest; 364 double maxInt32 = 2147483648.0; // 1 << 31 365 double round = mRound; 366 double max32 = maxInt32 - 1.0 - round; 367 double min32 = -2147483648.0; 368 int shift = mShift, count; 369 double f1, f2, f3, f4; 370 int i1, i2, i3, i4; 371 372 SET_ROUNDMODE 373 374 if (nSamples >= 8) { 375 f1 = FloatType::load(src + 0); 376 377 f2 = FloatType::load(src + 1); 378 f1 = f1 * maxInt32 + round; 379 380 f3 = FloatType::load(src + 2); 381 f2 = f2 * maxInt32 + round; 382 i1 = FloatToInt(f1, min32, max32); 383 384 src += 3; 385 386 nSamples -= 4; 387 count = nSamples >> 2; 388 nSamples &= 3; 389 390 while (count--) { 391 f4 = FloatType::load(src + 0); 392 f3 = f3 * maxInt32 + round; 393 i2 = FloatToInt(f2, min32, max32); 394 IntType::store(dest + 0, i1 >> shift); 395 396 f1 = FloatType::load(src + 1); 397 f4 = f4 * maxInt32 + round; 398 i3 = FloatToInt(f3, min32, max32); 399 IntType::store(dest + 1, i2 >> shift); 400 401 f2 = FloatType::load(src + 2); 402 f1 = f1 * maxInt32 + round; 403 i4 = FloatToInt(f4, min32, max32); 404 IntType::store(dest + 2, i3 >> shift); 405 406 f3 = FloatType::load(src + 3); 407 f2 = f2 * maxInt32 + round; 408 i1 = FloatToInt(f1, min32, max32); 409 IntType::store(dest + 3, i4 >> shift); 410 411 src += 4; 412 dest += 4; 413 } 414 415 f4 = FloatType::load(src); 416 f3 = f3 * maxInt32 + round; 417 i2 = FloatToInt(f2, min32, max32); 418 IntType::store(dest + 0, i1 >> shift); 419 420 f4 = f4 * maxInt32 + round; 421 i3 = FloatToInt(f3, min32, max32); 422 IntType::store(dest + 1, i2 >> shift); 423 424 i4 = FloatToInt(f4, min32, max32); 425 IntType::store(dest + 2, i3 >> shift); 426 427 IntType::store(dest + 3, i4 >> shift); 428 429 src += 1; 430 dest += 4; 431 } 432 433 count = nSamples; 434 while (count--) { 435 f1 = FloatType::load(src) * maxInt32 + round; 436 i1 = FloatToInt(f1, min32, max32) >> shift; 437 IntType::store(dest, i1); 438 src += 1; 439 dest += 1; 440 } 441 RESTORE_ROUNDMODE 442 } 443 444#if 0//PCMBLIT_INTERLEAVE_SUPPORT 445 virtual void Interleave(ConstVoidPtr vsrc[], void *vdest, int nChannels, unsigned int nFrames) 446 { 447 verify_action(nChannels == 2, return); 448 449 const float_val *srcA = (const float_val *)vsrc[0]; 450 const float_val *srcB = (const float_val *)vsrc[1]; 451 int_val *dest = (int_val *)vdest; 452 double maxInt32 = 2147483648.0; // 1 << 31 453 double round = mRound; 454 double max32 = maxInt32 - 1.0 - round; 455 double min32 = -2147483648.0; 456 int shift = mShift, count; 457 double f1, f2, f3, f4; 458 int i1, i2, i3, i4; 459 460 SET_ROUNDMODE 461 // two at a time 462 count = nFrames >> 1; 463 while (count--) { 464 f1 = FloatType::load(srcA); 465 f2 = FloatType::load(srcB); 466 f3 = FloatType::load(srcA+1); 467 f4 = FloatType::load(srcB+1); 468 f1 = f1 * maxInt32 + round; 469 f2 = f2 * maxInt32 + round; 470 f3 = f3 * maxInt32 + round; 471 f4 = f4 * maxInt32 + round; 472 i1 = FloatToInt(f1, min32, max32) >> shift; 473 i2 = FloatToInt(f2, min32, max32) >> shift; 474 i3 = FloatToInt(f3, min32, max32) >> shift; 475 i4 = FloatToInt(f4, min32, max32) >> shift; 476 IntType::store(dest, i1); 477 IntType::store(dest+1, i2); 478 IntType::store(dest+2, i3); 479 IntType::store(dest+3, i4); 480 srcA += 2; 481 srcB += 2; 482 dest += 4; 483 } 484 // leftover 485 count = nFrames & 1; 486 while (count--) { 487 f1 = FloatType::load(srcA); 488 f2 = FloatType::load(srcB); 489 f1 = f1 * maxInt32 + round; 490 f2 = f2 * maxInt32 + round; 491 i1 = FloatToInt(f1, min32, max32) >> shift; 492 i2 = FloatToInt(f2, min32, max32) >> shift; 493 IntType::store(dest, i1); 494 IntType::store(dest+1, i2); 495 srcA += 1; 496 srcB += 1; 497 dest += 2; 498 } 499 RESTORE_ROUNDMODE 500 } 501#endif // PCMBLIT_INTERLEAVE_SUPPORT 502}; 503 504// ____________________________________________________________________________ 505// 506// IntToFloatBlitter 507class IntToFloatBlitter : public PCMBlitter { 508public: 509 IntToFloatBlitter(int bitDepth) : 510 mBitDepth(bitDepth) 511 { 512 mScale = static_cast<Float32>(1.0 / float(1UL << (bitDepth - 1))); 513 } 514 515 Float32 mScale; 516 UInt32 mBitDepth; 517}; 518 519// ____________________________________________________________________________ 520// 521// TIntToFloatBlitter - only used for non-PPC 522// On PPC these are roughly only half as fast as the optimized versions 523template <class IntType, class FloatType> 524class TIntToFloatBlitter : public IntToFloatBlitter { 525public: 526 typedef typename FloatType::value_type float_val; 527 typedef typename IntType::value_type int_val; 528 529 TIntToFloatBlitter(int bitDepth) : IntToFloatBlitter(bitDepth) { } 530 531 virtual void Convert(const void *vsrc, void *vdest, unsigned int nSamples) 532 { 533 const int_val *src = (const int_val *)vsrc; 534 float_val *dest = (float_val *)vdest; 535 int count = nSamples; 536 Float32 scale = mScale; 537 int_val i0, i1, i2, i3; 538 float_val f0, f1, f2, f3; 539 540 /* 541 $i = IntType::load(src); ++src; 542 $f = $i; 543 $f *= scale; 544 FloatType::store(dest, $f); ++dest; 545 */ 546 547 if (count >= 4) { 548 // Cycle 1 549 i0 = IntType::load(src); ++src; 550 551 // Cycle 2 552 i1 = IntType::load(src); ++src; 553 f0 = i0; 554 555 // Cycle 3 556 i2 = IntType::load(src); ++src; 557 f1 = i1; 558 f0 *= scale; 559 560 // Cycle 4 561 i3 = IntType::load(src); ++src; 562 f2 = i2; 563 f1 *= scale; 564 FloatType::store(dest, f0); ++dest; 565 566 count -= 4; 567 int loopCount = count / 4; 568 count -= 4 * loopCount; 569 570 while (loopCount--) { 571 // Cycle A 572 i0 = IntType::load(src); ++src; 573 f3 = i3; 574 f2 *= scale; 575 FloatType::store(dest, f1); ++dest; 576 577 // Cycle B 578 i1 = IntType::load(src); ++src; 579 f0 = i0; 580 f3 *= scale; 581 FloatType::store(dest, f2); ++dest; 582 583 // Cycle C 584 i2 = IntType::load(src); ++src; 585 f1 = i1; 586 f0 *= scale; 587 FloatType::store(dest, f3); ++dest; 588 589 // Cycle D 590 i3 = IntType::load(src); ++src; 591 f2 = i2; 592 f1 *= scale; 593 FloatType::store(dest, f0); ++dest; 594 } 595 596 // Cycle 3 597 f3 = i3; 598 f2 *= scale; 599 FloatType::store(dest, f1); ++dest; 600 601 // Cycle 2 602 f3 *= scale; 603 FloatType::store(dest, f2); ++dest; 604 605 // Cycle 1 606 FloatType::store(dest, f3); ++dest; 607 } 608 609 while (count--) { 610 i0 = IntType::load(src); ++src; 611 f0 = i0; 612 f0 *= scale; 613 FloatType::store(dest, f0); ++dest; 614 } 615 } 616 617#if 0//PCMBLIT_INTERLEAVE_SUPPORT 618 virtual void Deinterleave(ConstVoidPtr vsrc, void *vdest[], int nChannels, unsigned int nFrames) 619 { 620 verify_action(nChannels == 2, return); 621 622 const int_val *src = (const int_val *)vsrc; 623 float_val *destA = (float_val *)vdest[0]; 624 float_val *destB = (float_val *)vdest[1]; 625 int count; 626 Float32 scale = mScale; 627 628 count = nFrames; 629 while (count--) { 630 int i1 = IntType::load(src); 631 int i2 = IntType::load(src+1); 632 float_val f1 = i1 * scale; 633 float_val f2 = i2 * scale; 634 FloatType::store(destA, f1); 635 FloatType::store(destB, f2); 636 637 src += 2; 638 destA += 1; 639 destB += 1; 640 } 641 } 642#endif // PCMBLIT_INTERLEAVE_SUPPORT 643}; 644#endif // __cplusplus 645 646#ifdef __cplusplus 647extern "C" { 648#endif 649 650#if TARGET_CPU_PPC 651#pragma mark - 652#pragma mark PPC scalar 653 654 // ____________________________________________________________________________________ 655 // PPC scalar 656 NO_EXPORT void NativeInt16ToFloat32_Scalar( const SInt16 *src, Float32 *dest, unsigned int count ); 657 NO_EXPORT void SwapInt16ToFloat32_Scalar( const SInt16 *src, Float32 *dest, unsigned int count ); 658 NO_EXPORT void NativeInt24ToFloat32_Scalar( const SInt32 *src, Float32 *dest, unsigned int count ); 659 NO_EXPORT void SwapInt24ToFloat32_Scalar( const SInt32 *src, Float32 *dest, unsigned int count ); 660 NO_EXPORT void NativeInt32ToFloat32_Scalar( const SInt32 *src, Float32 *dest, unsigned int count ); 661 NO_EXPORT void SwapInt32ToFloat32_Scalar( const SInt32 *src, Float32 *dest, unsigned int count ); 662 663 NO_EXPORT void Float32ToNativeInt16_Scalar( const Float32 *src, SInt16 *dest, unsigned int count ); 664 NO_EXPORT void Float32ToSwapInt16_Scalar( const Float32 *src, SInt16 *dest, unsigned int count ); 665 NO_EXPORT void Float32ToNativeInt24_Scalar( const Float32 *src, SInt32 *dest, unsigned int count ); 666 NO_EXPORT void Float32ToSwapInt24_Scalar( const Float32 *src, SInt32 *dest, unsigned int count ); 667 NO_EXPORT void Float32ToNativeInt32_Scalar( const Float32 *src, SInt32 *dest, unsigned int count ); 668 NO_EXPORT void Float32ToSwapInt32_Scalar( const Float32 *src, SInt32 *dest, unsigned int count ); 669 670#pragma mark - 671#pragma mark PPC Altivec 672 // ____________________________________________________________________________________ 673 // PPC Altivec 674 NO_EXPORT void Float32ToInt16_Altivec(const Float32 *fsrc, SInt16 *idst, unsigned int numToConvert, int bigEndian); 675 NO_EXPORT void Float32ToInt24_Altivec(const Float32 *fsrc, UInt8 *dst, unsigned int numToConvert, int bigEndian); 676 NO_EXPORT void Float32ToInt32_Altivec(const Float32 *fsrc, SInt32 *dst, unsigned int numToConvert, int bigEndian); 677 NO_EXPORT void Int16ToFloat32_Altivec(const SInt16 *isrc, Float32 *fdst, unsigned int numToConvert, int bigEndian); 678 NO_EXPORT void Int24ToFloat32_Altivec(const UInt8 *isrc, Float32 *fdst, unsigned int numToConvert, int bigEndian); 679 NO_EXPORT void Int32ToFloat32_Altivec(const SInt32 *isrc, Float32 *fdst, unsigned int numToConvert, int bigEndian); 680 681 // These don't have wrappers; check their implementations for limitations 682 NO_EXPORT void DeinterleaveInt16ToFloat32_Altivec(const SInt16 *isrc, Float32 *dstA, Float32 *dstB, unsigned int numFrames, int bigEndian); 683 //void Deinterleave32_Altivec(const void *vsrc, void *vdstA, void *vdstB, unsigned int numFrames); untested 684 NO_EXPORT void Interleave32_Altivec(const void *vsrcA, const void *vsrcB, void *vdst, unsigned int numFrames); 685 686#elif defined( __i386__ ) || defined( __LP64__ ) 687#pragma mark - 688#pragma mark X86 SSE2 689 // ____________________________________________________________________________________ 690 // X86 SSE2 691 NO_EXPORT void NativeInt16ToFloat32_X86( const SInt16 *src, Float32 *dest, unsigned int count ); 692 NO_EXPORT void SwapInt16ToFloat32_X86( const SInt16 *src, Float32 *dest, unsigned int count ); 693 NO_EXPORT void Float32ToNativeInt16_X86( const Float32 *src, SInt16 *dest, unsigned int count ); 694 NO_EXPORT void Float32ToSwapInt16_X86( const Float32 *src, SInt16 *dest, unsigned int count ); 695 696 NO_EXPORT void Float32ToNativeInt24_X86( const Float32 *src, UInt8 *dst, unsigned int numToConvert ); 697 NO_EXPORT void Float32ToSwapInt24_X86( const Float32 *src, UInt8 *dst, unsigned int numToConvert ); 698 699 NO_EXPORT void NativeInt32ToFloat32_X86( const SInt32 *src, Float32 *dest, unsigned int count ); 700 NO_EXPORT void SwapInt32ToFloat32_X86( const SInt32 *src, Float32 *dest, unsigned int count ); 701 NO_EXPORT void Float32ToNativeInt32_X86( const Float32 *src, SInt32 *dest, unsigned int count ); 702 NO_EXPORT void Float32ToSwapInt32_X86( const Float32 *src, SInt32 *dest, unsigned int count ); 703#elif __LP64__ 704#pragma mark - 705#pragma mark X86 SSE2 706 // ____________________________________________________________________________________ 707 // X86 SSE2 708 NO_EXPORT void NativeInt16ToFloat32_X86( const SInt16 *src, Float32 *dest, unsigned int count ); 709 NO_EXPORT void SwapInt16ToFloat32_X86( const SInt16 *src, Float32 *dest, unsigned int count ); 710 NO_EXPORT void Float32ToNativeInt16_X86( const Float32 *src, SInt16 *dest, unsigned int count ); 711 NO_EXPORT void Float32ToSwapInt16_X86( const Float32 *src, SInt16 *dest, unsigned int count ); 712 713 NO_EXPORT void Float32ToNativeInt24_X86( const Float32 *src, UInt8 *dst, unsigned int numToConvert ); 714 NO_EXPORT void Float32ToSwapInt24_X86( const Float32 *src, UInt8 *dst, unsigned int numToConvert ); 715 716 NO_EXPORT void NativeInt32ToFloat32_X86( const SInt32 *src, Float32 *dest, unsigned int count ); 717 NO_EXPORT void SwapInt32ToFloat32_X86( const SInt32 *src, Float32 *dest, unsigned int count ); 718 NO_EXPORT void Float32ToNativeInt32_X86( const Float32 *src, SInt32 *dest, unsigned int count ); 719 NO_EXPORT void Float32ToSwapInt32_X86( const Float32 *src, SInt32 *dest, unsigned int count ); 720 721 722#endif 723 724#pragma mark - 725#pragma mark Portable 726 // ____________________________________________________________________________________ 727 // Portable 728 NO_EXPORT void Float32ToNativeInt16_Portable( const Float32 *src, SInt16 *dest, unsigned int count ); 729 NO_EXPORT void Float32ToSwapInt16_Portable( const Float32 *src, SInt16 *dest, unsigned int count ); 730 NO_EXPORT void NativeInt16ToFloat32_Portable( const SInt16 *src, Float32 *dest, unsigned int count ); 731 NO_EXPORT void SwapInt16ToFloat32_Portable( const SInt16 *src, Float32 *dest, unsigned int count ); 732 733 NO_EXPORT void Float32ToNativeInt24_Portable( const Float32 *src, UInt8 *dest, unsigned int count ); 734 NO_EXPORT void Float32ToSwapInt24_Portable( const Float32 *src, UInt8 *dest, unsigned int count ); 735 NO_EXPORT void NativeInt24ToFloat32_Portable( const UInt8 *src, Float32 *dest, unsigned int count ); 736 NO_EXPORT void SwapInt24ToFloat32_Portable( const UInt8 *src, Float32 *dest, unsigned int count ); 737 738 NO_EXPORT void Float32ToNativeInt32_Portable( const Float32 *src, SInt32 *dest, unsigned int count ); 739 NO_EXPORT void Float32ToSwapInt32_Portable( const Float32 *src, SInt32 *dest, unsigned int count ); 740 NO_EXPORT void NativeInt32ToFloat32_Portable( const SInt32 *src, Float32 *dest, unsigned int count ); 741 NO_EXPORT void SwapInt32ToFloat32_Portable( const SInt32 *src, Float32 *dest, unsigned int count ); 742 743#ifdef __cplusplus 744}; 745#endif 746 747#endif // __IOAudioBlitterLib_h__ 748