📄 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 dword ptr [edi] // pop st(0) into dest, stack: int scaler
jmp Float32_To_Int32_DitherClip_stored
Float32_To_Int32_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, 0x7FFFFFFF // convert to maximum range integers
mov dword ptr [edi], edx
Float32_To_Int32_DitherClip_stored:
//add edi, ebx // increment destination ptr
lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int32_DitherClip_loop
ffree st(0)
fincstp
fwait
fnclex
fldcw savedFpuControlWord
}
ditherGenerator->previous = ditherPrevious;
ditherGenerator->randSeed1 = ditherRandSeed1;
ditherGenerator->randSeed2 = ditherRandSeed2;
}
/* -------------------------------------------------------------------------- */
static void Float32_To_Int24(
void *destinationBuffer, signed int destinationStride,
void *sourceBuffer, signed int sourceStride,
unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
{
/*
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
signed long temp;
(void) ditherGenerator; // unused parameter
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
double scaled = *src * 0x7FFFFFFF;
temp = (signed long) scaled;
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
dest[2] = (unsigned char)(temp >> 24);
src += sourceStride;
dest += destinationStride * 3;
}
*/
short savedFpuControlWord;
signed long tempInt32;
(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
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov edx, 3 // sizeof int24
mov ebx, destinationStride
imul ebx, edx
fwait
fstcw savedFpuControlWord
fldcw fpuControlWord_
fld int24Scaler_ // stack: (int)0x7FFFFF
Float32_To_Int24_loop:
// load unscaled value into st(0)
fld dword ptr [esi] // stack: value, (int)0x7FFFFF
add esi, eax // increment source ptr
//lea esi, [esi+eax]
fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF
fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF
mov edx, tempInt32
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_loop
ffree st(0)
fincstp
fwait
fnclex
fldcw savedFpuControlWord
}
}
/* -------------------------------------------------------------------------- */
static void Float32_To_Int24_Clip(
void *destinationBuffer, signed int destinationStride,
void *sourceBuffer, signed int sourceStride,
unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
{
/*
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
signed long temp;
(void) ditherGenerator; // unused parameter
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
double scaled = *src * 0x7FFFFFFF;
PA_CLIP_( scaled, -2147483648., 2147483647. );
temp = (signed long) scaled;
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
dest[2] = (unsigned char)(temp >> 24);
src += sourceStride;
dest += destinationStride * 3;
}
*/
short savedFpuControlWord;
signed long tempInt32;
(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
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov edx, 3 // sizeof int24
mov ebx, destinationStride
imul ebx, edx
fwait
fstcw savedFpuControlWord
fldcw fpuControlWord_
fld int24Scaler_ // stack: (int)0x7FFFFF
Float32_To_Int24_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_Int24_Clip_clamp
// load unscaled value into st(0)
fld dword ptr [esi] // stack: value, (int)0x7FFFFF
add esi, eax // increment source ptr
//lea esi, [esi+eax]
fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF
fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF
mov edx, tempInt32
jmp Float32_To_Int24_Clip_store
Float32_To_Int24_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 edx, 0x7FFFFF // convert to maximum range integers
Float32_To_Int24_Clip_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_Clip_loop
ffree st(0)
fincstp
fwait
fnclex
fldcw savedFpuControlWord
}
}
/* -------------------------------------------------------------------------- */
static void Float32_To_Int24_DitherClip(
void *destinationBuffer, signed int destinationStride,
void *sourceBuffer, signed int sourceStride,
unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
{
/*
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
signed long temp;
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
// FIXME: the dither amplitude here appears to be too small by 8 bits
double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
// use smaller scaler to prevent overflow when we add the dither
double dithered = ((double)*src * (2147483646.0)) + dither;
PA_CLIP_( dithered, -2147483648., 2147483647. );
temp = (signed long) dithered;
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
dest[2] = (unsigned char)(temp >> 24);
src += sourceStride;
dest += destinationStride * 3;
}
*/
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;
signed long tempInt32;
__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
mov ecx, count
imul ecx, eax
add ecx, esi
mov edi, destinationBuffer
mov edx, 3 // sizeof int24
mov ebx, destinationStride
imul ebx, edx
fwait
fstcw savedFpuControlWord
fldcw fpuControlWord_
fld ditheredInt24Scaler_ // stack: int scaler
Float32_To_Int24_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_Int24_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]
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -