📄 pa_x86_plain_converters.c
字号:
mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp tempInt32 // pop st(0) into tempInt32, stack: int scaler mov edx, tempInt32 jmp Float32_To_Int24_DitherClip_store Float32_To_Int24_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFF // convert to maximum range integers Float32_To_Int24_DitherClip_store: mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2;}/* -------------------------------------------------------------------------- */static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ){/* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { short samp = (short) (*src * (32767.0f)); *dest = samp; src += sourceStride; dest += destinationStride; }*/ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord }}/* -------------------------------------------------------------------------- */static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ){/* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { long samp = (signed long) (*src * (32767.0f)); PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; }*/ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF jmp Float32_To_Int16_Clip_stored Float32_To_Int16_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_Clip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord }}/* -------------------------------------------------------------------------- */static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ){/* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither float dithered = (*src * (32766.0f)) + dither; signed long samp = (signed long) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; }*/ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt16Scaler_ // stack: int scaler Float32_To_Int16_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] // current = randSeed1>>x + randSeed2>>x mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp word ptr [edi] // store scaled int into dest, stack: int scaler jmp Float32_To_Int16_DitherClip_stored Float32_To_Int16_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_DitherClip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2;}/* -------------------------------------------------------------------------- */void PaUtil_InitializeX86PlainConverters( void ){ paConverters.Float32_To_Int32 = Float32_To_Int32; paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip; paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip; paConverters.Float32_To_Int24 = Float32_To_Int24; paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip; paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip; paConverters.Float32_To_Int16 = Float32_To_Int16; paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip; paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip;}#endif/* -------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -