📄 pa_x86_plain_converters.c
字号:
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;
}
/* -------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -