Added 8-point interpolation and new lowpass filter
This commit is contained in:
@@ -125,7 +125,7 @@ EXTSYM WDSPRegFC,WDSPRegFD,WDSPRegFE,WDSPRegFF,RaisePitch
|
||||
EXTSYM delay
|
||||
EXTSYM spcBuffera
|
||||
EXTSYM DSPMem
|
||||
EXTSYM InterSound
|
||||
EXTSYM SoundInterpType
|
||||
EXTSYM NoiseData,SoundCompD,Voice0Disable,csounddisable,dssel,spcRamcmp
|
||||
EXTSYM cfgecho,Surround,SoundBufEn
|
||||
EXTSYM echobuf,ENVDisable
|
||||
@@ -170,8 +170,7 @@ tempstuff db 0
|
||||
; If A is not zero, goto FFD6
|
||||
; Jump to Address [0000]
|
||||
|
||||
|
||||
ALIGN32
|
||||
section .data
|
||||
|
||||
DSPInterP:
|
||||
times 1024 dw 0
|
||||
@@ -416,6 +415,9 @@ NEWSYM NoiseSpeeds
|
||||
dd 800,1000,1300,1600,2000,2700,3200,4000,5300,6400,8000,10700,
|
||||
dd 16000,32000
|
||||
|
||||
section .text
|
||||
|
||||
|
||||
NEWSYM conv2speedb
|
||||
.next
|
||||
mov eax,[esi]
|
||||
@@ -506,8 +508,12 @@ NEWSYM conv2speed
|
||||
|
||||
|
||||
NEWSYM AdjustFrequency
|
||||
cmp byte[UseCubicSpline],1
|
||||
mov al,[SoundInterpType]
|
||||
or al,al
|
||||
je .notgaussian
|
||||
cmp al,2
|
||||
je .cubicspline
|
||||
ja .notgaussian
|
||||
; Copy from Gaussian to DSPInterP
|
||||
mov ebx,DSPInterP
|
||||
mov edx,DSPInterP+2046
|
||||
@@ -1592,6 +1598,8 @@ NEWSYM DeInitSPC
|
||||
out dx,al
|
||||
ret
|
||||
|
||||
section .data
|
||||
|
||||
;SoundBlaster DSP Ports
|
||||
NEWSYM SBPort, dw 220
|
||||
NEWSYM SBInt, db 5+8
|
||||
@@ -1601,6 +1609,7 @@ NEWSYM SBDMAPage, db 83
|
||||
NEWSYM SBHDMA, db 0
|
||||
NEWSYM SBHDMAPage, db 0
|
||||
NEWSYM vibracard, db 0
|
||||
dw 0 ; padding
|
||||
|
||||
; ViBRA16X fixes!
|
||||
EXTSYM MsgCount ; points to counter
|
||||
@@ -1608,6 +1617,8 @@ EXTSYM MessageOn ; points to "message" delay counter
|
||||
EXTSYM Msgptr ; points to the message to be displayed
|
||||
NEWSYM vibmsg, db 'VIBRA16X MODE ENABLED', 0
|
||||
|
||||
section .text
|
||||
|
||||
NEWSYM ResetSBDSP
|
||||
mov dx,[SBPort]
|
||||
add dl,06h
|
||||
@@ -1648,7 +1659,9 @@ NEWSYM ResetSBDSP
|
||||
int 21h ;to print a string
|
||||
jmp DosExit
|
||||
|
||||
section .data
|
||||
NEWSYM initfailed, db 'Sound card failed to initialize!',13,10,'$'
|
||||
section .text
|
||||
|
||||
; Write AL into DSP port
|
||||
NEWSYM WriteDSP
|
||||
@@ -1688,17 +1701,21 @@ NEWSYM Interror
|
||||
int 21h ;to print a string
|
||||
call DosExit
|
||||
|
||||
section .data
|
||||
.nohand db 'Cannot process interrupt handler!',13,10,'$'
|
||||
|
||||
NEWSYM oldhandSBs, dw 0
|
||||
NEWSYM oldhandSBo, dd 0
|
||||
NEWSYM SBswitch, db 0 ; which block to process next
|
||||
|
||||
PSampleBuf times 22*8 dd 0
|
||||
PSampleBuf times 26*8 dd 0
|
||||
|
||||
NEWSYM LPFsample1, dd 0
|
||||
NEWSYM LPFsample2, dd 0
|
||||
|
||||
NEWSYM DLPFsamples, times 8*26 dd 0
|
||||
section .text
|
||||
|
||||
%macro ProcessA 0
|
||||
shr al,4
|
||||
%endmacro
|
||||
@@ -1732,6 +1749,7 @@ NEWSYM LPFsample2, dd 0
|
||||
add edx,eax
|
||||
|
||||
mov eax,[prev0]
|
||||
mov [prev0],edx
|
||||
mov [prev1],eax
|
||||
cmp edx,-32768
|
||||
jnl %%notless
|
||||
@@ -1743,10 +1761,208 @@ NEWSYM LPFsample2, dd 0
|
||||
mov edx,32767
|
||||
mov byte[filteron],1
|
||||
%%notgreater
|
||||
movsx edx,dx
|
||||
mov [prev0],edx
|
||||
%endmacro
|
||||
|
||||
EXTSYM fir_downsample
|
||||
|
||||
%macro ProcessDynamicLowPass 0
|
||||
mov ecx,[curvoice]
|
||||
mov edx, [Voice0Freq+ecx*4]
|
||||
cmp edx, dword 1000000h
|
||||
ja %%DLPF
|
||||
ret
|
||||
%%DLPF
|
||||
lea ebx,[ecx*4]
|
||||
lea ebx,[ebx*4]
|
||||
lea ecx,[ecx*4+ecx]
|
||||
lea ebx,[ecx*2+ebx]
|
||||
lea ebx,[DLPFsamples+ebx*4]
|
||||
cmp byte[LowPassFilterType],3
|
||||
je near %%DLPF_fir
|
||||
DLPF_dynamic:
|
||||
mov eax,[ebx+21*4]
|
||||
mov [ebx],eax
|
||||
mov eax,[ebx+22*4]
|
||||
mov [ebx+1*4],eax
|
||||
mov eax,[ebx+23*4]
|
||||
mov [ebx+2*4],eax
|
||||
mov eax,[ebx+24*4]
|
||||
mov [ebx+3*4],eax
|
||||
mov eax,[ebx+25*4]
|
||||
mov [ebx+4*4],eax
|
||||
sub edi,32
|
||||
movsx eax,word[edi+22]
|
||||
mov [ebx+21*4],eax
|
||||
movsx eax,word[edi+24]
|
||||
mov [ebx+22*4],eax
|
||||
movsx eax,word[edi+26]
|
||||
mov [ebx+23*4],eax
|
||||
movsx eax,word[edi+28]
|
||||
mov [ebx+24*4],eax
|
||||
movsx eax,word[edi+30]
|
||||
mov [ebx+25*4],eax
|
||||
mov ecx,16
|
||||
shr edx,24
|
||||
cmp dl,2
|
||||
jle %%dlpf_by_2
|
||||
cmp dl,3
|
||||
jle %%dlpf_by_3
|
||||
cmp dl,4
|
||||
jle %%dlpf_by_4
|
||||
jmp %%dlpf_by_5
|
||||
|
||||
%%dlpf_by_2
|
||||
mov eax,[ebx+4*4]
|
||||
jmp Short %%dlpf_by_2_loop
|
||||
|
||||
ALIGN16
|
||||
%%dlpf_by_2_loop
|
||||
movsx edx,word[edi]
|
||||
add eax,edx
|
||||
sar eax,1
|
||||
mov [edi],ax
|
||||
mov eax,edx
|
||||
add edi,2
|
||||
dec ecx
|
||||
jnz %%dlpf_by_2_loop
|
||||
ret
|
||||
|
||||
%%dlpf_by_3
|
||||
push ebx
|
||||
mov eax,[ebx+3*4]
|
||||
mov ebp,[ebx+4*4]
|
||||
jmp Short %%dlpf_by_3_loop
|
||||
|
||||
ALIGN16
|
||||
%%dlpf_by_3_loop
|
||||
movsx ebx,word[edi]
|
||||
add eax,ebx
|
||||
add eax,ebp
|
||||
mov edx,55555555h ; (1/3)
|
||||
imul edx
|
||||
mov [edi],dx
|
||||
add edi,2
|
||||
mov eax,ebp
|
||||
mov ebp,ebx
|
||||
dec ecx
|
||||
jnz %%dlpf_by_3_loop
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
%%dlpf_by_4
|
||||
push ebx
|
||||
mov ebp,[ebx+2*4]
|
||||
mov edx,[ebx+3*4]
|
||||
mov eax,[ebx+4*4]
|
||||
jmp Short %%dlpf_by_4_loop
|
||||
|
||||
ALIGN16
|
||||
%%dlpf_by_4_loop
|
||||
movsx ebx,word[edi]
|
||||
add eax,ebx
|
||||
add eax,edx
|
||||
add eax,ebp
|
||||
sar eax,2
|
||||
mov [edi],ax
|
||||
add edi,2
|
||||
mov eax,edx
|
||||
mov edx,ebp
|
||||
mov ebp,ebx
|
||||
dec ecx
|
||||
jnz %%dlpf_by_4_loop
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
%%dlpf_by_5
|
||||
push ebx
|
||||
push ecx
|
||||
mov ecx,[ebx+1*4]
|
||||
mov ebp,[ebx+2*4]
|
||||
mov esi,[ebx+3*4]
|
||||
mov eax,[ebx+4*4]
|
||||
jmp Short %%dlpf_by_5_loop
|
||||
|
||||
ALIGN16
|
||||
%%dlpf_by_5_loop
|
||||
movsx ebx,word[edi]
|
||||
add eax,ebx
|
||||
add eax,esi
|
||||
add eax,ebp
|
||||
add eax,ecx
|
||||
mov edx,33333333h ; 1/5
|
||||
mov [edi],dx
|
||||
add edi,2
|
||||
mov eax,esi
|
||||
mov esi,ebp
|
||||
mov ebp,ecx
|
||||
mov ecx,ebx
|
||||
dec dword [esp]
|
||||
jnz %%dlpf_by_5_loop
|
||||
pop ecx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
%%DLPF_fir
|
||||
mov eax,[ebx+21*4]
|
||||
mov [ebx],eax
|
||||
mov eax,[ebx+22*4]
|
||||
mov [ebx+4],eax
|
||||
mov eax,[ebx+23*4]
|
||||
mov [ebx+2*4],eax
|
||||
mov eax,[ebx+24*4]
|
||||
mov [ebx+3*4],eax
|
||||
mov eax,[ebx+25*4]
|
||||
mov [ebx+4*4],eax
|
||||
sub edi,32
|
||||
movsx eax,word[edi]
|
||||
mov [ebx+5*4],eax
|
||||
movsx eax,word[edi+2]
|
||||
mov [ebx+6*4],eax
|
||||
movsx eax,word[edi+4]
|
||||
mov [ebx+7*4],eax
|
||||
movsx eax,word[edi+6]
|
||||
mov [ebx+8*4],eax
|
||||
movsx eax,word[edi+8]
|
||||
mov [ebx+9*4],eax
|
||||
movsx eax,word[edi+10]
|
||||
mov [ebx+10*4],eax
|
||||
movsx eax,word[edi+12]
|
||||
mov [ebx+11*4],eax
|
||||
movsx eax,word[edi+14]
|
||||
mov [ebx+12*4],eax
|
||||
movsx eax,word[edi+16]
|
||||
mov [ebx+13*4],eax
|
||||
movsx eax,word[edi+18]
|
||||
mov [ebx+14*4],eax
|
||||
movsx eax,word[edi+20]
|
||||
mov [ebx+15*4],eax
|
||||
movsx eax,word[edi+22]
|
||||
mov [ebx+16*4],eax
|
||||
mov [ebx+21*4],eax
|
||||
movsx eax,word[edi+24]
|
||||
mov [ebx+17*4],eax
|
||||
mov [ebx+22*4],eax
|
||||
movsx eax,word[edi+26]
|
||||
mov [ebx+18*4],eax
|
||||
mov [ebx+23*4],eax
|
||||
movsx eax,word[edi+28]
|
||||
mov [ebx+19*4],eax
|
||||
mov [ebx+24*4],eax
|
||||
movsx eax,word[edi+30]
|
||||
mov [ebx+20*4],eax
|
||||
mov [ebx+25*4],eax
|
||||
|
||||
|
||||
push edi
|
||||
push ebx
|
||||
push edx
|
||||
call fir_downsample
|
||||
add esp,+12
|
||||
add edi,32
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
section .data
|
||||
NEWSYM lastblockbrr, times 8 dd 0
|
||||
NEWSYM curvoice, dd 0
|
||||
|
||||
@@ -1816,7 +2032,7 @@ BRRDecode:
|
||||
|
||||
pop ecx
|
||||
cmp byte[VoiceNoiseEn+ecx],10
|
||||
je .yesfilter
|
||||
je near .yesfilter
|
||||
cmp byte[VoiceNoiseEn+ecx],0
|
||||
je .nofilter2
|
||||
cmp byte[VoiceNoiseEn+ecx],10
|
||||
@@ -1828,9 +2044,9 @@ BRRDecode:
|
||||
inc byte[VoiceNoiseEn+ecx]
|
||||
.nofilter2
|
||||
cmp byte[filteron],1
|
||||
jne .nofilter
|
||||
jne near .nofilter
|
||||
cmp byte[NoiseDisTemp+ecx],0
|
||||
jne .nofilter
|
||||
jne near .nofilter
|
||||
cmp byte[VoiceNoiseEn+ecx],100
|
||||
je .strfilter
|
||||
cmp byte[VoiceNoiseEn+ecx],101
|
||||
@@ -1842,11 +2058,13 @@ BRRDecode:
|
||||
test byte[esi+9],01h
|
||||
jnz .nofilter
|
||||
mov byte[VoiceNoiseEn+ecx],10
|
||||
.nofilter
|
||||
ret
|
||||
;.nofilter
|
||||
; ret
|
||||
jmp .nofilter
|
||||
.strfilter
|
||||
mov byte[VoiceNoiseEn+ecx],8
|
||||
ret
|
||||
jmp .nofilter
|
||||
; ret
|
||||
|
||||
.yesfilter
|
||||
cmp byte[SoundNoiseDis],1
|
||||
@@ -1868,6 +2086,16 @@ BRRDecode:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
.nofilter
|
||||
cmp byte[LowPassFilterType],1
|
||||
ja .dlpf
|
||||
ret
|
||||
|
||||
.dlpf
|
||||
|
||||
ProcessDynamicLowPass
|
||||
|
||||
section .data
|
||||
ALIGN32
|
||||
|
||||
; Original Values
|
||||
@@ -2559,7 +2787,7 @@ dspconvb equ marksave-Voice0Freq
|
||||
NEWSYM PHdspsave, dd dspsave
|
||||
NEWSYM PHdspconvb, dd dspconvb
|
||||
|
||||
|
||||
section .text
|
||||
|
||||
|
||||
NEWSYM PrepareSaveState
|
||||
@@ -2881,9 +3109,11 @@ spc700temp dd 0,0
|
||||
mov byte [Voice0Loop+%1],0
|
||||
mov byte[VoiceNoiseEn+%1],0
|
||||
mov dword[WaveIndex+%1*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+19*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+20*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+21*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+21*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+22*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+23*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+24*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+25*4],0
|
||||
mov byte[SoundLooped0+%1],0
|
||||
mov byte[echoon0+%1],0
|
||||
test byte[DSPMem+4Dh],%2
|
||||
@@ -2999,9 +3229,11 @@ NEWSYM Voice7Start
|
||||
mov byte [Voice0Loop+%1],0
|
||||
mov byte[VoiceNoiseEn+%1],0
|
||||
mov dword[WaveIndex+%1*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+19*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+20*4],0
|
||||
mov dword[PSampleBuf+%1*22*4+21*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+21*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+22*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+23*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+24*4],0
|
||||
mov dword[PSampleBuf+%1*26*4+25*4],0
|
||||
pop edx
|
||||
ret
|
||||
%%nope
|
||||
@@ -3018,9 +3250,11 @@ NEWSYM VoiceStarter
|
||||
VoiceStarterM 7
|
||||
ret
|
||||
|
||||
section .data
|
||||
NEWSYM NoiseInc, dd 0
|
||||
NEWSYM NoisePointer, dd 0
|
||||
NEWSYM LastNoise, dd 0
|
||||
section .text
|
||||
|
||||
%macro CalculatePMod 1
|
||||
xor eax,eax
|
||||
@@ -3281,11 +3515,17 @@ WaveIndex times 8 dd 0
|
||||
; add eax,edx ;
|
||||
;%%DontFilter1 ;
|
||||
|
||||
EXTSYM fir_interpolate
|
||||
|
||||
%macro DSPInterpolate 1
|
||||
|
||||
cmp byte[SoundInterpType],3
|
||||
je near %%fir_interpolate
|
||||
|
||||
xor ebx,ebx
|
||||
mov bl,[BRRPlace0+%1*8+2]
|
||||
|
||||
mov ax,[PSampleBuf+edx*4+0+%1*22*4]
|
||||
mov ax,[PSampleBuf+edx*4+8+%1*26*4]
|
||||
mov dx,[DSPInterP+ebx*2+256*6]
|
||||
imul dx
|
||||
shl edx,16
|
||||
@@ -3293,7 +3533,7 @@ WaveIndex times 8 dd 0
|
||||
mov eax,[BRRPlace0+%1*8+3]
|
||||
mov ecx,edx
|
||||
|
||||
mov ax,[PSampleBuf+eax*4+4+%1*22*4]
|
||||
mov ax,[PSampleBuf+eax*4+12+%1*26*4]
|
||||
mov dx,[DSPInterP+ebx*2+256*4]
|
||||
imul dx
|
||||
shl edx,16
|
||||
@@ -3301,7 +3541,7 @@ WaveIndex times 8 dd 0
|
||||
mov eax,[BRRPlace0+%1*8+3]
|
||||
add ecx,edx
|
||||
|
||||
mov ax,[PSampleBuf+eax*4+8+%1*22*4]
|
||||
mov ax,[PSampleBuf+eax*4+16+%1*26*4]
|
||||
mov dx,[DSPInterP+ebx*2+256*2]
|
||||
imul dx
|
||||
shl edx,16
|
||||
@@ -3309,7 +3549,7 @@ WaveIndex times 8 dd 0
|
||||
mov eax,[BRRPlace0+%1*8+3]
|
||||
add ecx,edx
|
||||
|
||||
mov ax,[PSampleBuf+eax*4+12+%1*22*4]
|
||||
mov ax,[PSampleBuf+eax*4+20+%1*26*4]
|
||||
mov dx,[DSPInterP+ebx*2]
|
||||
imul dx
|
||||
shl edx,16
|
||||
@@ -3318,6 +3558,22 @@ WaveIndex times 8 dd 0
|
||||
|
||||
sar ecx,11
|
||||
mov ax,cx
|
||||
jmp %%end
|
||||
|
||||
%%fir_interpolate
|
||||
push dword PSampleBuf+(%1*26*4)
|
||||
push dword [BRRPlace0+%1*8]
|
||||
call fir_interpolate
|
||||
add esp,+8
|
||||
cmp eax,32767
|
||||
jle %%clip1
|
||||
mov eax,32767
|
||||
%%clip1
|
||||
cmp eax,-32768
|
||||
jge %%clip2
|
||||
mov eax,-32768
|
||||
%%clip2
|
||||
%%end
|
||||
%endmacro
|
||||
|
||||
%macro NonEchoMonoInterpolated 4
|
||||
@@ -4023,8 +4279,8 @@ WaveIndex times 8 dd 0
|
||||
mov ebx,[Voice0Freq+%1*4]
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound
|
||||
cmp byte [StereoSound],1
|
||||
je near %%EndofProcessNEnvsi
|
||||
jmp %%EndofProcessNEnvi
|
||||
@@ -4066,8 +4322,8 @@ WaveIndex times 8 dd 0
|
||||
mov ebx,[Voice0Freq+%1*4]
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound2
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound2
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound2
|
||||
cmp byte [StereoSound],1
|
||||
je near %%EndofProcessNEnvsi
|
||||
jmp %%EndofProcessNEnvi
|
||||
@@ -4083,8 +4339,8 @@ WaveIndex times 8 dd 0
|
||||
mov ebx,[Voice0Freq+%1*4]
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound3
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound3
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound3
|
||||
cmp byte [StereoSound],1
|
||||
je near %%EndofProcessNEnvsi
|
||||
jmp %%EndofProcessNEnvi
|
||||
@@ -4093,6 +4349,11 @@ WaveIndex times 8 dd 0
|
||||
je near %%EndofProcessNEnvs
|
||||
jmp %%EndofProcessNEnv
|
||||
%%EndofSamp
|
||||
mov dword[DLPFsamples+%1*26+21*4],0
|
||||
mov dword[DLPFsamples+%1*26+22*4],0
|
||||
mov dword[DLPFsamples+%1*26+23*4],0
|
||||
mov dword[DLPFsamples+%1*26+24*4],0
|
||||
mov dword[DLPFsamples+%1*26+25*4],0
|
||||
mov dword[Voice0EnvInc+%1*4],0
|
||||
mov dword[Voice0IncNumber+%1*4],0
|
||||
mov byte [Voice0Status+%1],0
|
||||
@@ -4216,8 +4477,8 @@ WaveIndex times 8 dd 0
|
||||
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound4
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound4
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound4
|
||||
cmp byte [StereoSound],1
|
||||
je near %%NextSampleSi
|
||||
jmp %%NextSamplei
|
||||
@@ -4331,12 +4592,16 @@ WaveIndex times 8 dd 0
|
||||
; cmp byte[Voice0Looped+%1],0
|
||||
; je %%nobrrcheck
|
||||
|
||||
mov eax,[PSampleBuf+19*4+%1*22*4]
|
||||
mov [PSampleBuf+0*4+%1*22*4],eax
|
||||
mov eax,[PSampleBuf+20*4+%1*22*4]
|
||||
mov [PSampleBuf+1*4+%1*22*4],eax
|
||||
mov eax,[PSampleBuf+21*4+%1*22*4]
|
||||
mov [PSampleBuf+2*4+%1*22*4],eax
|
||||
mov eax,[PSampleBuf+21*4+%1*26*4]
|
||||
mov [PSampleBuf+0*4+%1*26*4],eax
|
||||
mov eax,[PSampleBuf+22*4+%1*26*4]
|
||||
mov [PSampleBuf+1*4+%1*26*4],eax
|
||||
mov eax,[PSampleBuf+23*4+%1*26*4]
|
||||
mov [PSampleBuf+2*4+%1*26*4],eax
|
||||
mov eax,[PSampleBuf+24*4+%1*26*4]
|
||||
mov [PSampleBuf+3*4+%1*26*4],eax
|
||||
mov eax,[PSampleBuf+25*4+%1*26*4]
|
||||
mov [PSampleBuf+4*4+%1*26*4],eax
|
||||
|
||||
cmp byte[SoundBufEn],0
|
||||
je near %%convertBRR2
|
||||
@@ -4373,46 +4638,48 @@ WaveIndex times 8 dd 0
|
||||
mov ebx,[Voice0Freq+%1*4]
|
||||
mov [Voice0BufPtr+%1*4],edi
|
||||
|
||||
mov ax,[edi]
|
||||
mov [PSampleBuf+3*4+%1*22*4],eax
|
||||
mov ax,[edi+2*1]
|
||||
mov [PSampleBuf+4*4+%1*22*4],eax
|
||||
mov ax,[edi+2*2]
|
||||
mov [PSampleBuf+5*4+%1*22*4],eax
|
||||
mov ax,[edi+2*3]
|
||||
mov [PSampleBuf+6*4+%1*22*4],eax
|
||||
mov ax,[edi+2*4]
|
||||
mov [PSampleBuf+7*4+%1*22*4],eax
|
||||
mov ax,[edi+2*5]
|
||||
mov [PSampleBuf+8*4+%1*22*4],eax
|
||||
mov ax,[edi+2*6]
|
||||
mov [PSampleBuf+9*4+%1*22*4],eax
|
||||
mov ax,[edi+2*7]
|
||||
mov [PSampleBuf+10*4+%1*22*4],eax
|
||||
mov ax,[edi+2*8]
|
||||
mov [PSampleBuf+11*4+%1*22*4],eax
|
||||
mov ax,[edi+2*9]
|
||||
mov [PSampleBuf+12*4+%1*22*4],eax
|
||||
mov ax,[edi+2*10]
|
||||
mov [PSampleBuf+13*4+%1*22*4],eax
|
||||
mov ax,[edi+2*11]
|
||||
mov [PSampleBuf+14*4+%1*22*4],eax
|
||||
mov ax,[edi+2*12]
|
||||
mov [PSampleBuf+15*4+%1*22*4],eax
|
||||
mov ax,[edi+2*13]
|
||||
mov [PSampleBuf+16*4+%1*22*4],eax
|
||||
mov [PSampleBuf+19*4+%1*22*4],eax
|
||||
mov ax,[edi+2*14]
|
||||
mov [PSampleBuf+17*4+%1*22*4],eax
|
||||
mov [PSampleBuf+20*4+%1*22*4],eax
|
||||
mov ax,[edi+2*15]
|
||||
mov [PSampleBuf+18*4+%1*22*4],eax
|
||||
mov [PSampleBuf+21*4+%1*22*4],eax
|
||||
movsx eax,word [edi]
|
||||
mov [PSampleBuf+5*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*1]
|
||||
mov [PSampleBuf+6*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*2]
|
||||
mov [PSampleBuf+7*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*3]
|
||||
mov [PSampleBuf+8*4+%1*26*4],eax
|
||||
movsx eax,word[edi+2*4]
|
||||
mov [PSampleBuf+9*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*5]
|
||||
mov [PSampleBuf+10*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*6]
|
||||
mov [PSampleBuf+11*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*7]
|
||||
mov [PSampleBuf+12*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*8]
|
||||
mov [PSampleBuf+13*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*9]
|
||||
mov [PSampleBuf+14*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*10]
|
||||
mov [PSampleBuf+15*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*11]
|
||||
mov [PSampleBuf+16*4+%1*26*4],eax
|
||||
mov [PSampleBuf+21*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*12]
|
||||
mov [PSampleBuf+17*4+%1*26*4],eax
|
||||
mov [PSampleBuf+22*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*13]
|
||||
mov [PSampleBuf+18*4+%1*26*4],eax
|
||||
mov [PSampleBuf+23*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*14]
|
||||
mov [PSampleBuf+19*4+%1*26*4],eax
|
||||
mov [PSampleBuf+24*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*15]
|
||||
mov [PSampleBuf+20*4+%1*26*4],eax
|
||||
mov [PSampleBuf+25*4+%1*26*4],eax
|
||||
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound5
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound5
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound5
|
||||
cmp byte [StereoSound],1
|
||||
je near %%NextSampleSi
|
||||
jmp %%NextSamplei
|
||||
@@ -4443,41 +4710,43 @@ WaveIndex times 8 dd 0
|
||||
pop esi
|
||||
mov edi,[Voice0BufPtr+%1*4]
|
||||
|
||||
mov ax,[edi]
|
||||
mov [PSampleBuf+3*4+%1*22*4],eax
|
||||
mov ax,[edi+2*1]
|
||||
mov [PSampleBuf+4*4+%1*22*4],eax
|
||||
mov ax,[edi+2*2]
|
||||
mov [PSampleBuf+5*4+%1*22*4],eax
|
||||
mov ax,[edi+2*3]
|
||||
mov [PSampleBuf+6*4+%1*22*4],eax
|
||||
mov ax,[edi+2*4]
|
||||
mov [PSampleBuf+7*4+%1*22*4],eax
|
||||
mov ax,[edi+2*5]
|
||||
mov [PSampleBuf+8*4+%1*22*4],eax
|
||||
mov ax,[edi+2*6]
|
||||
mov [PSampleBuf+9*4+%1*22*4],eax
|
||||
mov ax,[edi+2*7]
|
||||
mov [PSampleBuf+10*4+%1*22*4],eax
|
||||
mov ax,[edi+2*8]
|
||||
mov [PSampleBuf+11*4+%1*22*4],eax
|
||||
mov ax,[edi+2*9]
|
||||
mov [PSampleBuf+12*4+%1*22*4],eax
|
||||
mov ax,[edi+2*10]
|
||||
mov [PSampleBuf+13*4+%1*22*4],eax
|
||||
mov ax,[edi+2*11]
|
||||
mov [PSampleBuf+14*4+%1*22*4],eax
|
||||
mov ax,[edi+2*12]
|
||||
mov [PSampleBuf+15*4+%1*22*4],eax
|
||||
mov ax,[edi+2*13]
|
||||
mov [PSampleBuf+16*4+%1*22*4],eax
|
||||
mov [PSampleBuf+19*4+%1*22*4],eax
|
||||
mov ax,[edi+2*14]
|
||||
mov [PSampleBuf+17*4+%1*22*4],eax
|
||||
mov [PSampleBuf+20*4+%1*22*4],eax
|
||||
mov ax,[edi+2*15]
|
||||
mov [PSampleBuf+18*4+%1*22*4],eax
|
||||
mov [PSampleBuf+21*4+%1*22*4],eax
|
||||
movsx eax,word [edi]
|
||||
mov [PSampleBuf+5*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*1]
|
||||
mov [PSampleBuf+6*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*2]
|
||||
mov [PSampleBuf+7*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*3]
|
||||
mov [PSampleBuf+8*4+%1*26*4],eax
|
||||
movsx eax,word[edi+2*4]
|
||||
mov [PSampleBuf+9*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*5]
|
||||
mov [PSampleBuf+10*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*6]
|
||||
mov [PSampleBuf+11*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*7]
|
||||
mov [PSampleBuf+12*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*8]
|
||||
mov [PSampleBuf+13*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*9]
|
||||
mov [PSampleBuf+14*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*10]
|
||||
mov [PSampleBuf+15*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*11]
|
||||
mov [PSampleBuf+16*4+%1*26*4],eax
|
||||
mov [PSampleBuf+21*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*12]
|
||||
mov [PSampleBuf+17*4+%1*26*4],eax
|
||||
mov [PSampleBuf+22*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*13]
|
||||
mov [PSampleBuf+18*4+%1*26*4],eax
|
||||
mov [PSampleBuf+23*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*14]
|
||||
mov [PSampleBuf+19*4+%1*26*4],eax
|
||||
mov [PSampleBuf+24*4+%1*26*4],eax
|
||||
movsx eax,word [edi+2*15]
|
||||
mov [PSampleBuf+20*4+%1*26*4],eax
|
||||
mov [PSampleBuf+25*4+%1*26*4],eax
|
||||
|
||||
mov eax,dword [prev0]
|
||||
mov [Voice0Prev0+%1*4],eax
|
||||
@@ -4491,8 +4760,8 @@ WaveIndex times 8 dd 0
|
||||
add dword [Voice0Ptr+%1*4],9
|
||||
; cmp byte[VoiceNoiseEn+%1],10
|
||||
; je %%notinterpsound6
|
||||
cmp byte [InterSound],1
|
||||
jne %%notinterpsound6
|
||||
cmp byte [SoundInterpType],0
|
||||
je %%notinterpsound6
|
||||
cmp byte [StereoSound],1
|
||||
je near %%NextSampleSi
|
||||
jmp %%NextSamplei
|
||||
@@ -4548,6 +4817,11 @@ WaveIndex times 8 dd 0
|
||||
or byte [DSPMem+7Ch],%3
|
||||
mov byte [DSPMem+08h+%1*10h],0
|
||||
%%SkipStuff4
|
||||
mov dword[DLPFsamples+%1*26+21*4],0
|
||||
mov dword[DLPFsamples+%1*26+22*4],0
|
||||
mov dword[DLPFsamples+%1*26+23*4],0
|
||||
mov dword[DLPFsamples+%1*26+24*4],0
|
||||
mov dword[DLPFsamples+%1*26+25*4],0
|
||||
; and byte [DSPMem+5Ch],%4
|
||||
mov dword[Voice0EnvInc+%1*4],0
|
||||
mov dword[Voice0IncNumber+%1*4],0
|
||||
@@ -5020,7 +5294,9 @@ NEWSYM handlersbseg
|
||||
sti
|
||||
jmp Startprocsbdata
|
||||
|
||||
echowrittento db 0
|
||||
section .data
|
||||
echowrittento db 0 ,0,0,0 ; padding
|
||||
section .text
|
||||
|
||||
NEWSYM stopsbsound
|
||||
; mov byte[Voice0Status],0
|
||||
@@ -5092,7 +5368,9 @@ NEWSYM stopsbsound
|
||||
sti
|
||||
iretd
|
||||
|
||||
section .data
|
||||
NEWSYM sbhandexec, dd 0
|
||||
section .text
|
||||
|
||||
; Process 20 blocks * 8 voices (no pitch yet)
|
||||
NEWSYM SBHandler16
|
||||
@@ -5334,8 +5612,8 @@ NEWSYM ProcessVoice816
|
||||
loop .revstloop
|
||||
.norevstereo
|
||||
|
||||
cmp byte[LowPassFilterType],0
|
||||
je near LPFexit
|
||||
cmp byte[LowPassFilterType],1
|
||||
jne near LPFexit
|
||||
mov esi,DSPBuffer
|
||||
cmp byte[StereoSound],1
|
||||
jz near LPFstereo
|
||||
@@ -5466,11 +5744,13 @@ NEWSYM stopsbsound16
|
||||
; Sound Blaster Initialization Stuff
|
||||
;****************************************************
|
||||
|
||||
section .data
|
||||
NEWSYM memoryloc, dd 0 ; Memory offset in conventional memory
|
||||
NEWSYM memoryloc2, dd 0 ; Memory offset in conventional memory
|
||||
NEWSYM sbselec, dw 0 ; Selector of Memory location
|
||||
NEWSYM sbselec, dw 0 ,0,0,0 ; Selector of Memory location
|
||||
NEWSYM sbpmofs, dd 0 ; offset of Memory location
|
||||
SBDeinitType db 0
|
||||
section .text
|
||||
|
||||
NEWSYM initSB
|
||||
mov eax,[SoundQuality]
|
||||
|
||||
@@ -1 +1 @@
|
||||
/Fezsnesw.exe chips\dsp1proc.obj dos\sw.obj dos\gppro.obj dos\vesa12.obj dos\zsipx.obj dos\modemrtn.obj dos\joy.obj dos\debug.obj dos\vesa2.obj dos\initvid.obj cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj video\procvid.obj win\copyvwin.obj win\winintrf.obj win\winlink.obj win\zloaderw.obj win\ztcp.obj win\zfilew.obj win\zipxw.obj video\makev16b.obj video\makev16t.obj video\makevid.obj video\mode716.obj video\mode716b.obj video\mode716d.obj video\mode716e.obj video\mode716t.obj video\mode7.obj video\mode7ext.obj video\mv16tms.obj video\newg162.obj video\newgfx16.obj video\newgfx2.obj video\newgfx.obj video\m716text.obj video\2xsaiw.obj gui\gui.obj gui\menu.obj cpu\addrni.obj cpu\dma.obj cpu\dsp.obj cpu\dspproc.obj cpu\execute.obj cpu\irq.obj cpu\memory.obj cpu\spc700.obj cpu\stable.obj cpu\table.obj cpu\tableb.obj cpu\tablec.obj chips\dsp1emu.obj chips\fxemu2.obj chips\fxemu2b.obj chips\fxemu2c.obj chips\fxtable.obj chips\sa1proc.obj chips\sa1regs.obj chips\sfxproc.obj zip\unzip.obj zip\zzip.obj zip\zpng.obj obj\libpng.lib zlib.lib wsock32.lib user32.lib gdi32.lib shell32.lib winmm.lib ddraw.lib dsound.lib dinput8.lib d3dx.lib /link /section:.text,erw
|
||||
/Fezsnesw.exe chips\dsp1proc.obj dos\sw.obj dos\gppro.obj dos\vesa12.obj dos\zsipx.obj dos\modemrtn.obj dos\joy.obj dos\debug.obj dos\vesa2.obj dos\initvid.obj cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj video\procvid.obj win\copyvwin.obj win\winintrf.obj win\winlink.obj win\zloaderw.obj win\ztcp.obj win\zfilew.obj win\zipxw.obj video\makev16b.obj video\makev16t.obj video\makevid.obj video\mode716.obj video\mode716b.obj video\mode716d.obj video\mode716e.obj video\mode716t.obj video\mode7.obj video\mode7ext.obj video\mv16tms.obj video\newg162.obj video\newgfx16.obj video\newgfx2.obj video\newgfx.obj video\m716text.obj video\2xsaiw.obj gui\gui.obj gui\menu.obj cpu\addrni.obj cpu\dma.obj cpu\dsp.obj cpu\dspproc.obj cpu\execute.obj cpu\irq.obj cpu\memory.obj cpu\spc700.obj cpu\stable.obj cpu\table.obj cpu\tableb.obj cpu\tablec.obj chips\dsp1emu.obj chips\fxemu2.obj chips\fxemu2b.obj chips\fxemu2c.obj chips\fxtable.obj chips\sa1proc.obj chips\sa1regs.obj chips\sfxproc.obj zip\unzip.obj zip\zzip.obj zip\zpng.obj zip\fir_proc.obj obj\libpng.lib zlib.lib wsock32.lib user32.lib gdi32.lib shell32.lib winmm.lib ddraw.lib dsound.lib dinput8.lib d3dx.lib /link /section:.text,erw
|
||||
|
||||
@@ -52,7 +52,7 @@ WINOBJ=${WINDIR}/copywin.o ${WINDIR}/winintrf.o ${WINDIR}/winlink.o\
|
||||
|
||||
PREOBJ=${OBJDIR}/dosbuff.o ${OBJDIR}/ipx.o ${OBJDIR}/zipx.o
|
||||
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o
|
||||
ZIPOBJ=${ZIPDIR}/zzip.o ${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o ${ZIPDIR}/fir_proc.o
|
||||
|
||||
MAINOBJ=cfgload.o endmem.o fixsin.o init.o ui.o vcache.o water.o
|
||||
|
||||
@@ -94,6 +94,7 @@ ${DOSDIR}/zfile.o: ${DOSDIR}/zfile.c
|
||||
${ZIPDIR}/unzip.o: ${ZIPDIR}/unzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zzip.o: ${ZIPDIR}/zzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zpng.o: ${ZIPDIR}/zpng.c ${ZIPDIR}/zpng.h ${ZIPDIR}/png.h
|
||||
${ZIPDIR}/fir_proc.o: ${ZIPDIR}/fir_proc.cpp
|
||||
${VIDEODIR}/procvid.o: ${VIDEODIR}/procvid.asm macros.mac ${VIDEODIR}/copyvid.inc ${VIDEODIR}/2xSaImmx.inc
|
||||
${CHIPDIR}/dsp1proc.o: ${CHIPDIR}/dsp1proc.asm macros.mac
|
||||
${CHIPDIR}/sa1regs.o: ${CHIPDIR}/sa1regs.asm macros.mac\
|
||||
|
||||
@@ -61,7 +61,7 @@ WINDOSOBJ=${DOSDIR}/debug.obj ${DOSDIR}/joy.obj ${DOSDIR}/modemrtn.obj ${DOSDIR}
|
||||
|
||||
PREOBJ=
|
||||
|
||||
ZIPOBJ=${ZIPDIR}/zzip.obj ${ZIPDIR}/unzip.obj ${ZIPDIR}/zpng.obj
|
||||
ZIPOBJ=${ZIPDIR}/zzip.obj ${ZIPDIR}/unzip.obj ${ZIPDIR}/zpng.obj ${ZIPDIR}/fir_proc.obj
|
||||
|
||||
MAINOBJ=cfgload.obj endmem.obj fixsin.obj init.obj ui.obj vcache.obj water.obj
|
||||
|
||||
@@ -100,6 +100,7 @@ ${WINDIR}/winlink.obj: ${WINDIR}/winlink.cpp ${WINDIR}/resource.h
|
||||
${ZIPDIR}/unzip.obj: ${ZIPDIR}/unzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zzip.obj: ${ZIPDIR}/zzip.c ${ZIPDIR}/unzip.h
|
||||
${ZIPDIR}/zpng.obj: ${ZIPDIR}/zpng.c ${ZIPDIR}/zpng.h ${ZIPDIR}/png.h
|
||||
${ZIPDIR}/fir_proc.obj: ${ZIPDIR}/fir_proc.cpp
|
||||
${DOSDIR}/initvid.o:${DOSDIR}/initvid.asm macros.mac
|
||||
${DOSDIR}/modemrtn.o: ${DOSDIR}/modemrtn.asm macros.mac
|
||||
${DOSDIR}/zsipx.o: ${DOSDIR}/zsipx.asm
|
||||
|
||||
318
zsnes/src/zip/fir_proc.cpp
Normal file
318
zsnes/src/zip/fir_proc.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the license or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Authors: Markus Fick <webmaster@mark-f.de> fir-resampler
|
||||
* Chris Moeller <chris@kode54.net> C/C++ fir_interpolate functions based off original macros
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef log2
|
||||
inline float log2(float f) {
|
||||
float t;
|
||||
#ifdef __GNUC__
|
||||
__asm__ ("
|
||||
fld1\n
|
||||
fxch\n
|
||||
fyl2x\n
|
||||
fst (%1)"
|
||||
:
|
||||
: "st" (f), "r" (&t)
|
||||
);
|
||||
#else
|
||||
__asm {
|
||||
fld1
|
||||
fld f
|
||||
fyl2x
|
||||
fstp t
|
||||
}
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
fir interpolation doc,
|
||||
(derived from "an engineer's guide to fir digital filters", n.j. loy)
|
||||
|
||||
calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
|
||||
c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
|
||||
|
||||
then apply selected window to coefficients
|
||||
c[-N..N] *= w(0..N)
|
||||
with n in 2*N and w(n) being a window function (see loy)
|
||||
|
||||
then calculate gain and scale filter coefs to have unity gain.
|
||||
------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
// quantizer scale of window coefs
|
||||
#define WFIR_QUANTBITS 15
|
||||
#define WFIR_QUANTSCALE (1L<<WFIR_QUANTBITS)
|
||||
#define WFIR_8SHIFT (WFIR_QUANTBITS-8)
|
||||
#define WFIR_16BITSHIFT (WFIR_QUANTBITS)
|
||||
// log2(number)-1 of precalculated taps range is [4..12]
|
||||
#define WFIR_FRACBITS 10
|
||||
#define WFIR_LUTLEN ((1L<<(WFIR_FRACBITS+1))+1)
|
||||
// number of samples in window
|
||||
#define WFIR_LOG2WIDTH 3
|
||||
#define WFIR_WIDTH (1L<<WFIR_LOG2WIDTH)
|
||||
#define WFIR_SMPSPERWING ((WFIR_WIDTH-1)>>1)
|
||||
// cutoff (1.0 == pi/2)
|
||||
#define WFIR_CUTOFF 0.90f
|
||||
#define WFIR_CUTOFFBITS 12
|
||||
#define WFIR_CUTOFFLEN (1L<<(WFIR_CUTOFFBITS))
|
||||
// wfir type
|
||||
#define WFIR_HANN 0
|
||||
#define WFIR_HAMMING 1
|
||||
#define WFIR_BLACKMANEXACT 2
|
||||
#define WFIR_BLACKMAN3T61 3
|
||||
#define WFIR_BLACKMAN3T67 4
|
||||
#define WFIR_BLACKMAN4T92 5
|
||||
#define WFIR_BLACKMAN4T74 6
|
||||
#define WFIR_KAISER4T 7
|
||||
#define WFIR_TYPE WFIR_BLACKMANEXACT
|
||||
// wfir help
|
||||
#ifndef M_zPI
|
||||
#define M_zPI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
#define M_zEPS 1e-8
|
||||
#define M_zBESSELEPS 1e-21
|
||||
|
||||
class CzWINDOWEDFIR
|
||||
{ public:
|
||||
CzWINDOWEDFIR( );
|
||||
~CzWINDOWEDFIR( );
|
||||
float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
|
||||
{ double _LWidthM1 = _PWidth-1;
|
||||
double _LWidthM1Half = 0.5*_LWidthM1;
|
||||
double _LPosU = ((double)_PCnr - _POfs);
|
||||
double _LPos = _LPosU-_LWidthM1Half;
|
||||
double _LPIdl = 2.0*M_zPI/_LWidthM1;
|
||||
double _LWc,_LSi;
|
||||
if( fabs(_LPos)<M_zEPS )
|
||||
{ _LWc = 1.0;
|
||||
_LSi = _PCut;
|
||||
}
|
||||
else
|
||||
{ switch( _PType )
|
||||
{ case WFIR_HANN:
|
||||
_LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_HAMMING:
|
||||
_LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMANEXACT:
|
||||
_LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T61:
|
||||
_LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T67:
|
||||
_LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T92:
|
||||
_LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T74:
|
||||
_LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_KAISER4T:
|
||||
_LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
default:
|
||||
_LWc = 1.0;
|
||||
break;
|
||||
}
|
||||
_LPos *= M_zPI;
|
||||
_LSi = sin(_PCut*_LPos)/_LPos;
|
||||
}
|
||||
return (float)(_LWc*_LSi);
|
||||
}
|
||||
static signed int lut[WFIR_LUTLEN*WFIR_WIDTH];
|
||||
static signed int lut_co[WFIR_CUTOFFLEN*WFIR_WIDTH];
|
||||
};
|
||||
|
||||
signed int CzWINDOWEDFIR::lut[WFIR_LUTLEN*WFIR_WIDTH];
|
||||
signed int CzWINDOWEDFIR::lut_co[WFIR_CUTOFFLEN*WFIR_WIDTH];
|
||||
|
||||
CzWINDOWEDFIR::CzWINDOWEDFIR()
|
||||
{ int _LPcl;
|
||||
float _LPcllen = (float)(1L<<WFIR_FRACBITS); // number of precalculated lines for 0..1 (-1..0)
|
||||
float _LNorm = 1.0f / (float)(2.0f * _LPcllen);
|
||||
float _LCut = WFIR_CUTOFF;
|
||||
float _LScale = (float)WFIR_QUANTSCALE;
|
||||
float _LGain,_LCoefs[WFIR_WIDTH];
|
||||
for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
|
||||
{
|
||||
float _LOfs = ((float)_LPcl-_LPcllen)*_LNorm;
|
||||
int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
|
||||
for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{ _LGain += (_LCoefs[_LCc] = coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{ float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
|
||||
lut[_LIdx+_LCc] = (signed int)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
|
||||
}
|
||||
}
|
||||
for( _LPcl=0;_LPcl<WFIR_CUTOFFLEN;_LPcl++ )
|
||||
{
|
||||
int _LCc,_LIdx = _LPcl<<WFIR_LOG2WIDTH;
|
||||
_LCut = WFIR_CUTOFF / (1.0f + ((float)_LPcl / (WFIR_CUTOFFLEN / 15.0f)));
|
||||
for(_LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
_LGain += (_LCoefs[_LCc] = coef( _LCc, -0.5f, _LCut, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for( _LCc=0; _LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
|
||||
lut_co[_LIdx+_LCc] = (signed int)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CzWINDOWEDFIR::~CzWINDOWEDFIR()
|
||||
{ // nothing todo
|
||||
}
|
||||
|
||||
/*
|
||||
float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
|
||||
{
|
||||
double _LWidthM1 = _PWidth-1;
|
||||
double _LWidthM1Half = 0.5*_LWidthM1;
|
||||
double _LPosU = ((double)_PCnr - _POfs);
|
||||
double _LPos = _LPosU-_LWidthM1Half;
|
||||
double _LPIdl = 2.0*M_zPI/_LWidthM1;
|
||||
double _LWc,_LSi;
|
||||
if( fabs(_LPos)<M_zEPS )
|
||||
{ _LWc = 1.0;
|
||||
_LSi = _PCut;
|
||||
}
|
||||
else
|
||||
{ switch( _PType )
|
||||
{ case WFIR_HANN:
|
||||
_LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_HAMMING:
|
||||
_LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMANEXACT:
|
||||
_LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T61:
|
||||
_LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN3T67:
|
||||
_LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T92:
|
||||
_LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_BLACKMAN4T74:
|
||||
_LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
case WFIR_KAISER4T:
|
||||
_LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
|
||||
break;
|
||||
default:
|
||||
_LWc = 1.0;
|
||||
break;
|
||||
}
|
||||
_LPos *= M_zPI;
|
||||
_LSi = sin(_PCut*_LPos)/_LPos;
|
||||
}
|
||||
return (float)(_LWc*_LSi);
|
||||
}
|
||||
*/
|
||||
|
||||
CzWINDOWEDFIR sfir;
|
||||
|
||||
// fir interpolation
|
||||
#define WFIR_FRACSHIFT (16-(WFIR_FRACBITS+1+WFIR_LOG2WIDTH))
|
||||
#define WFIR_FRACMASK ((((1L<<(17-WFIR_FRACSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
|
||||
#define WFIR_FRACHALVE (1L<<(16-(WFIR_FRACBITS+2)))
|
||||
|
||||
inline int __fir_interpolate(unsigned int nPos, int *p)
|
||||
{
|
||||
int poshi = nPos >> 24;
|
||||
int poslo = ((nPos >> 8) & 0xFFFF);
|
||||
int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK;
|
||||
int vol = (CzWINDOWEDFIR::lut[firidx+0]*p[poshi+0]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+1]*p[poshi+1]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+2]*p[poshi+2]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+3]*p[poshi+3]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+4]*p[poshi+4]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+5]*p[poshi+5]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+6]*p[poshi+6]);
|
||||
vol += (CzWINDOWEDFIR::lut[firidx+7]*p[poshi+7]);
|
||||
vol >>= WFIR_16BITSHIFT;
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
extern "C" int fir_interpolate(unsigned int nPos, int *p)
|
||||
{
|
||||
return __fir_interpolate(nPos, p);
|
||||
}
|
||||
|
||||
#define WFIR_CUTOFFSHIFT (32-(WFIR_CUTOFFBITS+WFIR_LOG2WIDTH))
|
||||
#define WFIR_CUTOFFMASK ((((1L<<(32-WFIR_CUTOFFSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
|
||||
#define WFIR_CUTOFFHALVE (1L<<(32-(WFIR_CUTOFFBITS+1)))
|
||||
|
||||
inline void __fir_downsample(unsigned int freq, signed int *p, signed short *out)
|
||||
{
|
||||
/*
|
||||
float cutoff = WFIR_CUTOFF / (1.0f + log2((float)freq / 16777216.0f));
|
||||
float _LGain, _LCoefs[WFIR_WIDTH];
|
||||
int _LCc;
|
||||
for(_LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
|
||||
{
|
||||
_LGain += (_LCoefs[_LCc] = coef( _LCc, -0.5f, cutoff, WFIR_WIDTH, WFIR_TYPE ));
|
||||
}
|
||||
_LGain = 1.0f/_LGain;
|
||||
for(int ct=0;ct<16;ct++)
|
||||
{
|
||||
signed int vol;
|
||||
float acc = (_LCoefs[0] * _LGain * (float)p[ct+0]);
|
||||
acc += (_LCoefs[1] * _LGain * (float)p[ct+1]);
|
||||
acc += (_LCoefs[2] * _LGain * (float)p[ct+2]);
|
||||
acc += (_LCoefs[3] * _LGain * (float)p[ct+3]);
|
||||
acc += (_LCoefs[4] * _LGain * (float)p[ct+4]);
|
||||
acc += (_LCoefs[5] * _LGain * (float)p[ct+5]);
|
||||
acc += (_LCoefs[6] * _LGain * (float)p[ct+6]);
|
||||
acc += (_LCoefs[7] * _LGain * (float)p[ct+7]);
|
||||
|
||||
vol = (signed int)acc;
|
||||
if (vol > 32767) vol=32767;
|
||||
else if (vol < -32768) vol=-32768;
|
||||
out[ct]=(signed short)vol;
|
||||
}
|
||||
*/
|
||||
int firidx = (((freq-16777216)+WFIR_CUTOFFHALVE)>>WFIR_CUTOFFSHIFT) & WFIR_CUTOFFMASK;
|
||||
for(int ct=0;ct<16;ct++)
|
||||
{
|
||||
int vol = (CzWINDOWEDFIR::lut_co[firidx+0]*p[ct+0]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+1]*p[ct+1]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+2]*p[ct+2]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+3]*p[ct+3]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+4]*p[ct+4]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+5]*p[ct+5]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+6]*p[ct+6]);
|
||||
vol += (CzWINDOWEDFIR::lut_co[firidx+7]*p[ct+7]);
|
||||
vol >>= WFIR_16BITSHIFT;
|
||||
if (vol > 32767) vol=32767;
|
||||
else if (vol < -32768) vol=-32768;
|
||||
out[ct]=(signed short)vol;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void fir_downsample(unsigned int freq, signed int *p, signed short *out)
|
||||
{
|
||||
__fir_downsample(freq, p, out);
|
||||
}
|
||||
Reference in New Issue
Block a user