1 /* Copyright (C) 2003 Marcus Overhagen 2 * Released under terms of the MIT license. 3 * 4 * A simple byte order swapping class for the audio mixer. 5 */ 6 7 #include <MediaDefs.h> 8 #include <ByteOrder.h> 9 #include "ByteSwap.h" 10 #include "MixerDebug.h" 11 12 static void swap_float(void *buffer, size_t bytecount); 13 static void swap_int32(void *buffer, size_t bytecount); 14 static void swap_int16(void *buffer, size_t bytecount); 15 static void do_nothing(void *buffer, size_t bytecount); 16 17 ByteSwap::ByteSwap(uint32 format) 18 { 19 switch (format) { 20 case media_raw_audio_format::B_AUDIO_FLOAT: 21 fFunc = &swap_float; 22 break; 23 case media_raw_audio_format::B_AUDIO_INT: 24 fFunc = &swap_int32; 25 break; 26 case media_raw_audio_format::B_AUDIO_SHORT: 27 fFunc = &swap_int16; 28 break; 29 default: 30 fFunc = &do_nothing; 31 break; 32 } 33 } 34 35 ByteSwap::~ByteSwap() 36 { 37 } 38 39 void 40 do_nothing(void *buffer, size_t bytecount) 41 { 42 } 43 44 #if __INTEL__ 45 46 // optimized for IA32 platform 47 48 void 49 swap_float(void *buffer, size_t bytecount) 50 { 51 swap_data(B_FLOAT_TYPE, buffer, bytecount, B_SWAP_ALWAYS); // XXX should be optimized 52 } 53 54 void 55 swap_int32(void *buffer, size_t bytecount) 56 { 57 swap_data(B_INT32_TYPE, buffer, bytecount, B_SWAP_ALWAYS); // XXX should be optimized 58 } 59 60 void 61 swap_int16(void *buffer, size_t bytecount) 62 { 63 // GCC FAQ: To write an asm which modifies an input operand but does 64 // not output anything usable, specify that operand as an 65 // output operand outputting to an unused dummy variable. 66 uint32 dummy1; 67 uint32 dummy2; 68 // GCC is way too smart and will remove the complete asm statement 69 // if we do not specify it as __volatile__. Don't remove that! 70 __asm__ __volatile__ ( 71 "pushl %%ebx \n\t" 72 "movl %%eax, %%ebx \n\t" 73 "movl %%edx, %%eax \n\t" 74 "andl $0xFFFFFFE0,%%eax \n\t" 75 "pushl %%eax \n\t" 76 ".L_swap_loop: \n\t" 77 "rolw $8,-32(%%ebx,%%eax) \n\t" 78 "rolw $8,-30(%%ebx,%%eax) \n\t" 79 "rolw $8,-28(%%ebx,%%eax) \n\t" 80 "rolw $8,-26(%%ebx,%%eax) \n\t" 81 "rolw $8,-24(%%ebx,%%eax) \n\t" 82 "rolw $8,-22(%%ebx,%%eax) \n\t" 83 "rolw $8,-20(%%ebx,%%eax) \n\t" 84 "rolw $8,-18(%%ebx,%%eax) \n\t" 85 "rolw $8,-16(%%ebx,%%eax) \n\t" 86 "rolw $8,-14(%%ebx,%%eax) \n\t" 87 "rolw $8,-12(%%ebx,%%eax) \n\t" 88 "rolw $8,-10(%%ebx,%%eax) \n\t" 89 "rolw $8,-8(%%ebx,%%eax) \n\t" 90 "rolw $8,-6(%%ebx,%%eax) \n\t" 91 "rolw $8,-4(%%ebx,%%eax) \n\t" 92 "rolw $8,-2(%%ebx,%%eax) \n\t" 93 "subl $32,%%eax \n\t" 94 "jnz .L_swap_loop \n\t" 95 "popl %%eax \n\t" 96 "addl %%eax,%%ebx \n\t" 97 "andl $0x1F,%%edx \n\t" 98 "jz .L_swap_end \n\t" 99 "addl %%ebx, %%edx \n\t" 100 ".L_swap_loop_2: \n\t" 101 "rolw $8,(%%ebx) \n\t" 102 "addl $2,%%ebx \n\t" 103 "cmpl %%edx,%%ebx \n\t" 104 "jne .L_swap_loop_2 \n\t" 105 ".L_swap_end: \n\t" 106 "popl %%ebx \n\t" 107 : "=a" (dummy1), "=d" (dummy2) 108 : "d" (bytecount), "a" (buffer) 109 : "cc", "memory"); 110 } 111 112 #else 113 114 // non optimized default versions, do not remove 115 116 void 117 swap_float(void *buffer, size_t bytecount) 118 { 119 swap_data(B_FLOAT_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 120 } 121 122 void 123 swap_int32(void *buffer, size_t bytecount) 124 { 125 swap_data(B_INT32_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 126 } 127 128 void 129 swap_int16(void *buffer, size_t bytecount) 130 { 131 swap_data(B_INT16_TYPE, buffer, bytecount, B_SWAP_ALWAYS); 132 } 133 134 #endif 135