dpvm/it/SoundDrivers/MMXMSAM.INC

389 lines
12 KiB
Plaintext
Executable File

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Align 4
include q.inc
FilterParameters DB 64 Dup (07Fh), 64 Dup (0)
Const2048 DD 16384.0
FreqMultiplier DD 3A9F7867h ; = 1/(2*PI*110.0*2^0.25)
FreqParameterMultiplier DD 0B92AAAAAh ; = -1/(24*256)
NUMBEROFFILTERBANDS = 4
IF OUTPUTFILTERENABLED
LastFilter DD NUMBEROFFILTERBANDS*2 Dup (0) ; 4 stereo values
FilterCoefficients DD NUMBEROFFILTERBANDS*2 Dup (0)
FilterVolumes DD NUMBEROFFILTERBANDS Dup (0)
ENDIF
FilterFreqValue DW 0
NewControlWord DW 7Fh
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc MixSamples ; Given DS:SI = info tables, CX = numchannels
Assume DS:Nothing
; 1. Clean buffer
; + update variables
; 2. Update parameters
; 3. Mix func
; 4. Return
Push CX
Mov CX, BytesToMix
Mov ES, CS:MixSegment
Mov DI, DMABUFFERLENGTH*2+80
Xor EAX, EAX
Mov DX, CX
Add CX, CX
Mov CS:MixTransferOffset, DI
Cmp CS:Stereo, 0
JE CS:MixSamples1
Mov DX, CX
MixSamples1:
Rep StosD
Mov CS:MixTransferRemaining, DX
Pop CX
MixSamples2:
Test Byte Ptr [SI], 1
JZ MixSamplesEnd2
Cmp Byte Ptr [SI+36h], 100
JE MixSamplesEnd2
Push CX
Mov CX, [SI]
Test CH, 2
JZ MixSamplesNoStop
And Byte Ptr [SI], Not 1
Cmp MixMode, 2
JB MixSamplesEnd
Mov DWord Ptr [SI+0Ch], 0
Jmp MixModeCommon
MixSamplesNoStop:
Test CL, 20h ; New freq?
JZ MixSamples5
Mov AX, [SI+10h]
Mov DX, [SI+12h]
Mov BX, MixSpeed
Cmp DX, BX
JAE MixSamplesHandleError
Div BX
ShL EAX, 16
Xor AX, AX
Div BX
Mov STEPVALUE, EAX
MixSamples4:
Test CH, 1
JZ MixSamples5
Xor EAX, EAX
Mov [SI+3Ch], AX ; For filter.
Mov [SI+6Eh], AX
Mov DWord Ptr [SI+1Ch], EAX ; Current Volume = 0
; for volume sliding.
Mov [SI+06h], DX
Mov [SI+5Eh], AX
Mov [SI+7Eh], AX
MixSamples5:
Test CX, 8540h ; New volume or panning?
JZ MixSamplesMix
Mov AX, 4*60
Test CH, 8 ; Muted?
JZ MixMMXNoMute
Xor EDX, EDX
Mov [SI+06h], DX
Mov [SI+0Ch], EDX
Mov [SI+5Eh], DX
Mov [SI+1Ch], EDX
Mov [SI+6Eh], DX
Mov [SI+3Ch], DX
Mov [SI+7Eh], DX
Xor BX, BX
Mov BL, [SI+3Ah]
Test BL, BL
JS MixModeCommon1
Mov DL, [CS:FilterParameters+BX]
Mov BL, [CS:FilterParameters+BX+64]
Mov [SI+5Bh], DL
Mov [SI+3Fh], BL
Jmp MixModeCommon1
MixMMXNoMute:
Xor BX, BX
Mov BL, [SI+3Ah]
Test BL, BL ; Disowned? Then use channel filters.
JNS MixGetChannelFilters
Mov BL, [SI+3Fh]
Jmp MixChannelFilters
MixGetChannelFilters:
; Filter = [FilterParameters+BX]
; Q = [FilterParameters+BX+64]
Mov AL, [CS:FilterParameters+BX] ; AX = Filter
Mov BL, [CS:FilterParameters+BX+64] ; BX = Q
; If the values are different, then force recalculate volume. (and hence mixmode)
Cmp [SI+5Bh], AL
JE MixChannelFiltersSame
Cmp [SI+3Fh], BL
JE MixChannelFiltersSame
Mov DWord Ptr [SI+0Ch], 0
MixChannelFiltersSame:
Mov [SI+5Bh], AL
Mov [SI+3Fh], BL
MixChannelFilters:
Cmp MixMode, 3
JNE MixMMXNoFilters
Mov AL, [SI+3Eh]
Mul Byte Ptr [SI+5Bh]
Mov CS:FilterFreqValue, AX
Cmp AX, 127*255
JNE MixChannelFiltersOK
Test BL, BL
JZ MixMMXNoFilters
MixChannelFiltersOK:
ShL BX, 2
FNInit
FLdCW [CS:NewControlWord]
FILD [CS:FilterFreqValue] ; 0->127*256
FMul [CS:FreqParameterMultiplier] ; -i/(24*256)
FLd ST
FRndInt
FSub ST(1), ST
FXCh
F2XM1
FLd1
FAdd
FScale ; = 2^(i/24*256)
FMul [CS:FreqMultiplier] ; = r
FLd ST ; r, r
FMul ST(1), ST ; r, r^2
FLd [CS:QualityFactorTable+BX] ; 2d, r, r^2
FMul ST(1), ST ; 2d, 2dr, r^2
FAdd
FLd1 ; 1, d+1, e
FXCh ; d+1, 1, e
FSubR ST(1), ST
FAdd ST, ST(2) ; 1+d+e, d, e
FDivR Const2048 ; 1/(1+d+e), d, e
FISt Word Ptr [SI+5Eh] ;
FLd ST(2) ; e, 1/(1+d+e), d, e
FAdd ST, ST
FAddP ST(2), ST ; 1/(1+d+e), d+2e, e
FMul ST(2), ST ; 1/(1+d+e), d+2e, e/(1+d+e)
FMul
FIStP Word Ptr [SI+6Eh]
FChs
FIStP Word Ptr [SI+7Eh]
FStP ST
Mov DWord Ptr [SI+0Ch], 0
MixMMXNoFilters:
Mov EBX, [SI+0Ch]
Cmp Stereo, 0
JNE MixMMXStereo
MixMMXMono:
Mov AX, [SI+4Ah]
Mul MixVolume
ShRD AX, DX, 9
Mov [SI+0Ch], AX
Mov [SI+0Eh], AX
Jmp MixModeVolumeCheck
MixMMXStereo:
Mov AL, [SI+37h] ; Final pan
Cmp AL, 100
JE MixMMXSurround
Mul Byte Ptr MixVolume ; 0->128
Mul Word Ptr [SI+4Ah] ; 0->32768
ShRD AX, DX, 15 ; Maxvol = 8192
Mov [SI+0Eh], AX ; Store into right volume
Mov AL, 64 ; Do left volume
Sub AL, [SI+37h] ; AL = 64-FinalPan
Mul Byte Ptr MixVolume
Mul Word Ptr [SI+4Ah]
ShRD AX, DX, 15
Mov [SI+0Ch], AX
Jmp MixModeVolumeCheck
MixMMXSurround:
Mov AX, [SI+4Ah]
Mul MixVolume
ShRD AX, DX, 10
Mov [SI+0Ch], AX
Neg AX
Mov [SI+0Eh], AX
MixModeVolumeCheck:
Test CH, 3+4
JNZ MixModeCommon
Cmp EBX, [SI+0Ch] ; Same as last volume?
JE MixSamplesMix
MixModeCommon: ; Requires AX = 30 etc. depending
; On mixing mode type.
; This will add 180 for 16-bit,
; And sort out loop types.
Mov AX, MixModeOffset
Cmp DWord Ptr [SI+0Ch], 0
JNE MixModeActualMix
Cmp MixMode, 2
JB MixMMXGeneralNoRamp
Cmp DWord Ptr [SI+1Ch], 0
JNE MixModeActualMix
MixMMXGeneralNoRamp:
Mov AX, 4*60
Jmp MixModeCommon1
MixModeActualMix:
Cmp MixMode, 3
JNE MixModeFilter
Cmp Word Ptr [SI+6Eh], 0
JNE MixModeFilter
Cmp Word Ptr [SI+7Eh], 0
JNE MixModeFilter
Sub AX, 60
MixModeFilter:
Test Byte Ptr [SI+18h], 2 ; 16 bit?
JZ MixModeCommon1
Add AX, 30
MixModeCommon1:
Cmp Byte Ptr [SI+0Ah], 8
JB MixModeCommon3 ; No loop
JE MixModeCommon2 ; Forwards loop
Add AX, 10
MixModeCommon2:
Add AX, 10
MixModeCommon3:
Add AX, Offset MixFunctionTables
Mov [SI+8], AX ; Offset...
MixSamplesMix:
Mov BX, [SI+8] ; BX = offset into
Mov EAX, [CS:BX+2]
Mov DWord Ptr PreMixFunction, EAX
Mov EAX, [CS:BX+6]
Mov DWord Ptr MixFunctionSeparateBackwards, EAX
Mov AX, BytesToMix
Mov MixBlockSize, AX
Mov MixBufferOffset, DMABUFFERLENGTH*2+80
Mov EAX, CURRENTPOSITION
Mov OLDPOSITION, EAX
Push Word Ptr [SI+8]
Call Word Ptr [CS:BX]
Pop BX
And Word Ptr [SI], 0111100010001101b
Cmp BX, Offset MixFunctionTables+60*2
JB MixSamplesEnd
Cmp BX, Offset MixFunctionTables+60*4
JAE MixSamplesEnd
MovDR AX, MM6
Mov [SI+0Ch], EAX
Mov [SI+1Ch], EAX
Cmp BX, Offset MixfunctionTables+60*3
JB MixSamplesEnd
Mov ES, CS:MixSegment
Mov DX, [ES:10h]
Mov BX, [ES:14h]
Mov [SI+3Ch], DX
Mov [SI+6h], BX
Jmp MixSamplesEnd
MixSamplesHandleError:
Mov Word Ptr [SI], 200h
Test Byte Ptr [SI+3Ah], 80h
JNZ MixSamplesEnd
Mov BX, [SI+38h]
And Byte Ptr [BX], Not 4 ; Turn off channel
MixSamplesEnd:
Pop CX
MixSamplesEnd2:
Add SI, 128
Dec CX
JNZ MixSamples2
IF OUTPUTFILTERENABLED
include equalize.inc
ENDIF
Ret
EndP MixSamples
Assume DS:Nothing
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ