389 lines
12 KiB
Plaintext
Executable File
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
|
|
|
|
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|