;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ