⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft.asm

📁 一个不错的用汇编语言编写的FFT算法程序
💻 ASM
字号:
;---------------------------------------------------------------------
;Fast Fourier Transform(FFT) source code by Pradeeapn--arulpragasam@yahoo.com
;This code calculates both left & right 16 bit audio samples simultaneously using 3dnow! code.
;This code requires processor with 3dnow! support.
;If you found any bugs please email it to me (arulpragasam@yahoo.com).
;
;	Usage-
;		First call the InitFFT proc:
;				invoke InitFFT,FFTSize,pointer to hold RealArray offset,pointer to hold ImaginaryArray offset
;						FFTSize have to be power of 2 (256,512,1024...)	
;						Also give 2 pointers to hold the offsets.
;
;
;		To calculate the FFT  Call the FFT proc:
;				invoke FFT,sample offset,Real offset,Imaginary offset.
;						samples have to be 16 bit Stereo.
;
;		To calculate the Inverse FFT  Call the IFFT proc:
;				invoke IFFT,sample offset,Real offset,Imaginary offset.
;---------------------------------------------------------------------
;---------------------------------------------------------------------
include math.asm
InitFFT	Proto :Dword,:Dword,:Dword,:Dword,:Dword
FFT		Proto :Dword,:Dword,:Dword
IFFT	Proto :Dword,:Dword,:Dword
.DATA
Align 8
log2		DD 1.44269504,1.44269504		;1/log(2)
Pi 			DD 3.14159265,3.14159265
e1_20		DD 1.e-20

;---------------------------------------------------------------------
.DATA?
Align 8
tmp1		DD ?
nmFFTspl 	DD ?
lgFFTm		DD ?
.CODE

LdFFT Proc REX:Dword,IMX:Dword				;routine for Inverse FFT
Local SR:Qword
Local SI1:Qword
Local NM1,ND2,M,L,LE1,LE2:Dword
Local ND4,N4s2,LE22,NM11:Dword
		mov ecx,nmFFTspl
		mov eax,ecx
		mov ebx,ecx
		sub ebx,2
		mov esi,lgFFTm
		shl ebx,3
		mov N4s2,ebx
		dec eax
		mov M,esi
		shl eax,3
		mov NM1,eax
		shr ecx,1
		mov ND2,ecx
		shl ecx,3
		mov ND4,ecx
		mov esi,ecx

		mov edx,8
		mov edi,REX
		mov ebx,IMX
		mov ecx,ND4
@fl1:		cmp edx,esi
			jb @f
				movq MM3,[edi+edx]
				movq MM0,[edi+esi]
				movq [edi+esi],MM3
				movq MM1,[ebx+esi]
				movq [edi+edx],MM0
				movq MM2,[ebx+edx]
				movq [ebx+edx],MM1
				movq [ebx+esi],MM2
@@:			mov eax,ecx
			add edx,8
@@:			.If	eax<=esi
				sub esi,eax
				shr eax,1
				jmp @b
			.EndIf
		add esi,eax	
		cmp edx,N4s2
		jbe @fl1
		
		
		mov L,1
@fl2:		mov ecx,L
			mov eax,1
			shl eax,cl
			mov LE1,eax
			shr eax,1
			movd MM2,eax
			shl eax,3
			pi2fd MM2,MM2
			mov edx,eax
			movd MM0,Pi
			mov LE2,edx
			pfrcp MM7,MM2
			sub edx,8
			punpckldq MM2,MM2
			mov LE22,edx
			pfrcpit1  MM2,MM7
			add eax,eax
			pfrcpit2  MM2,MM7
			mov LE1,eax
			pfmul	  MM0,MM2				
			call cos
			movq MM2,MM0
			punpckldq MM0,MM0
			punpckhdq MM2,MM2
			movq SR,MM0
			movq MM6,ones
			pxor MM2,sh_masks
			pxor MM7,MM7
			mov ebx,IMX
			movq SI1,MM2

Align 4
			mov ecx,0
@fl3:			mov esi,ecx
@fl4:				mov eax,esi
					add eax,LE2
					
					movq MM0,[ebx+eax]
					movq MM2,MM0
					movq MM1,[edi+eax]
					pfmul MM0,MM7

					movq MM3,MM1
					pfmul MM1,MM6
					movq MM4,[edi+esi]
					pfmul MM2,MM6
					pfsub MM1,MM0
					
					movq MM5,[ebx+esi]
					pfmul MM3,MM7
					pfadd MM3,MM2

					movq MM0,MM4
					pfsub MM4,MM1
					pfadd MM0,MM1
					movq [edi+eax],MM4
					movq MM4,MM5
					movq [edi+esi],MM0
					pfsub MM5,MM3
					movq [ebx+eax],MM5
					
					pfadd MM4,MM3
					movq [ebx+esi],MM4

				add esi,LE1
				cmp esi,NM1
				jbe @fl4
				
				movq MM0,MM6
				movq MM4,SR
				movq MM2,MM6
				pfmul MM0,MM4
				movq MM1,MM7
				movq MM5,SI1
				movq MM3,MM7
				pfmul MM1,MM5
				pfsub MM0,MM1
				pfmul MM2,MM5
				movq MM6,MM0
				
				pfmul MM3,MM4
				pfadd MM2,MM3
				add ecx,8
				movq MM7,MM2
			cmp ecx,LE22
			jbe @fl3
		inc L
		mov eax,M
		cmp L,eax
		jbe @fl2

		ret
LdFFT EndP



LdFFT2 Proc REX:Dword,IMX:Dword				;routine for forward FFT
Local SR:Qword
Local SI1:Qword
Local NM1,ND2,M,L,LE1,LE2:Dword
Local ND4,N4s2,LE22,NM11:Dword
		mov ecx,nmFFTspl
		mov eax,ecx
		mov ebx,ecx
		sub ebx,2
		mov esi,lgFFTm
		shl ebx,3
		mov N4s2,ebx
		dec eax
		mov M,esi
		shl eax,3
		mov NM1,eax
		shr ecx,1
		mov ND2,ecx
		shl ecx,3
		mov ND4,ecx
		mov esi,ecx

		mov edx,8
		mov edi,REX
		mov ebx,IMX
		mov ecx,ND4
@fl1:		cmp edx,esi
			jb @f
				movq MM3,[edi+edx]
				movq MM0,[edi+esi]
				movq [edi+esi],MM3
				movq [edi+edx],MM0
@@:			mov eax,ecx
			add edx,8
@@:			.If	eax<=esi
				sub esi,eax
				shr eax,1
				jmp @b
			.EndIf
		add esi,eax	
		cmp edx,N4s2
		jbe @fl1
		
		
		mov L,1
@fl2:		mov ecx,L
			mov eax,1
			shl eax,cl
			mov LE1,eax
			shr eax,1
			movd MM2,eax
			shl eax,3
			pi2fd MM2,MM2
			mov edx,eax
			movd MM0,Pi
			mov LE2,edx
			pfrcp MM7,MM2
			sub edx,8
			punpckldq MM2,MM2
			mov LE22,edx
			pfrcpit1  MM2,MM7
			add eax,eax
			pfrcpit2  MM2,MM7
			mov LE1,eax
			pfmul	  MM0,MM2			
			call cos
			movq MM2,MM0
			punpckldq MM0,MM0
			punpckhdq MM2,MM2
			movq SR,MM0
			movq MM6,ones
			pxor MM2,sh_masks
			pxor MM7,MM7
			mov ebx,IMX
			movq SI1,MM2

Align 4
			mov ecx,0
@fl3:			mov esi,ecx
@fl4:				mov eax,esi
					add eax,LE2
					
					movq MM0,[ebx+eax]
					movq MM2,MM0
					movq MM1,[edi+eax]
					pfmul MM0,MM7

					movq MM3,MM1
					pfmul MM1,MM6
					movq MM4,[edi+esi]
					pfmul MM2,MM6
					pfsub MM1,MM0
					
					movq MM5,[ebx+esi]
					pfmul MM3,MM7
					pfadd MM3,MM2

					movq MM0,MM4
					pfsub MM4,MM1
					pfadd MM0,MM1
					movq [edi+eax],MM4
					movq MM4,MM5
					movq [edi+esi],MM0
					pfsub MM5,MM3
					movq [ebx+eax],MM5
					
					pfadd MM4,MM3
					movq [ebx+esi],MM4

				add esi,LE1
				cmp esi,NM1
				jbe @fl4
				
				movq MM0,MM6
				movq MM4,SR
				movq MM2,MM6
				pfmul MM0,MM4
				movq MM1,MM7
				movq MM5,SI1
				movq MM3,MM7
				pfmul MM1,MM5
				pfsub MM0,MM1
				pfmul MM2,MM5
				movq MM6,MM0
				
				pfmul MM3,MM4
				pfadd MM2,MM3
				add ecx,8
				movq MM7,MM2
			cmp ecx,LE22
			jbe @fl3
		inc L
		mov eax,M
		cmp L,eax
		jbe @fl2

		ret
LdFFT2 EndP



;---------------------------------------------------------------------
ldIFFT Proc REX:Dword,IMX:Dword
Local K,I:Dword
		mov edi,REX
		mov ebx,IMX
		mov ecx,nmFFTspl
		
@ifl1:	movq MM0,[ebx]
		pxor MM0,sh_masks
		movq [ebx],MM0
		add ebx,8
		loop @ifl1

		Invoke LdFFT,REX,IMX
		
		mov edi,REX
		mov ebx,IMX
		
		movd MM2,nmFFTspl
		pi2fd MM2,MM2
		pfrcp MM1,MM2
		punpckldq MM2,MM2
		pfrcpit1 MM2,MM1
		pfrcpit2 MM2,MM1

		
		mov ecx,nmFFTspl
@ifl2:		movq MM0,[edi]
			pfmul MM0,MM2
			movq MM3,[ebx]
			movq [edi],MM0
			pfmul MM3,MM2
			add edi,8
			pxor MM3,sh_masks
			movq [ebx],MM3
		add ebx,8
		loop @ifl2
		ret
ldIFFT EndP

;---------------------------------------------------------------------
;Converts	Rectangular FFT to Polar FFT
;usage: Invoke pointer to R[X],pointer to I[X]
;----------------------------------------------------------------------
RectToPol	Proc REX:Dword,IMX:Dword,Mgmem:Dword,PhMem:Dword
Local K:Dword
		mov edi,REX
		mov ebx,IMX
		mov eax,Mgmem
		mov edx,PhMem
		mov K,0
@RtP1:		mov esi,K
			movd MM0,[edi+esi*4]
			movq MM3,MM0
			pfmul MM0,MM0
			movd MM1,[ebx+esi*4]
			movq MM4,MM1
			pfmul MM1,MM1
			pfadd MM0,MM1
			
			pfrsqrt MM1,MM0
			movq MM2,MM1
			pfmul MM1,MM1
			punpckldq MM0,MM0
			pfrsqit1 MM1,MM0
			pfrcpit2 MM1,MM2
			pfmul MM0,MM1
			
			movd [eax+esi*4],MM0
			movd ecx,MM0
			.If ecx==0
				mov ecx,e1_20
				mov [eax+esi*4],ecx
			.EndIf
			
			pfrcp MM5,MM3
			punpckldq MM3,MM3
			pfrcpit1 MM3,MM5
			
			pfrcpit2 MM3,MM5
			pfmul MM4,MM3
			
			movq MM0,MM4
			call atan
			movd [edx+esi*4],MM0
			
			movd MM4,[edi+esi*4]
			movd MM5,[ebx+esi*4]
			pxor MM2,MM2
			pxor MM3,MM3
			pfcmpgt MM2,MM4
			pfcmpgt MM3,MM5
			movd ecx,MM2
			push eax
			movd eax,MM3

			.If ecx!=0
				.If eax!=0
					pfsub MM0,Qword Ptr[Pi]
				.Else
					pfadd MM0,Qword Ptr[Pi]
				.EndIf
				movd [edx+esi*4],MM0
			.EndIf
			pop eax
		inc K
		mov ecx,nmFFTspl
		;shr ecx,1
		cmp K,ecx
		jbe @RtP1
		ret
RectToPol EndP

;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;Usage:		invoke FFT,offset sample data,offset RealArray,offset Imaginary Array
;					sample data have to be at least 4 times the FTTsize
;					samples have to be 16 bit stereo.
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
FFT	Proc pSamp:Dword,REX:Dword,IMX:Dword
		mov eax,IMX
		pxor MM7,MM7
		mov ecx,nmFFTspl
		xor esi,esi
		mov ebx,REX
		mov edi,pSamp
@@:		movq MM0,[edi]
		movq [eax],MM7				;initialize the Immaginary part to 0
		punpcklwd MM0,MM0
		;mov [edi],esi				;clear the original sample - normaly not nessary
		pi2fw MM0,MM0				;convert 16bit stereo samples into 32bit float
		add eax,8
		movq [ebx],MM0				;copy the 32bit packed(Left,Right) float samples to Real part
		add edi,4
		add ebx,8
		dec ecx
		jnz @b
		Invoke LdFFT2,REX,IMX
		ret
FFT EndP

;--------------------------------------------------------------------------
;Usage:		invoke IFFT,offset sample data,offset RealArray,offset Imaginary Array
;					sample data have to atleast 4 times the FTTsize
;					samples have to be 16 bit stereo.
;--------------------------------------------------------------------------
IFFT Proc pSamp:Dword,REX:Dword,IMX:Dword
		Invoke ldIFFT,REX,IMX
		mov ecx,nmFFTspl
		mov ebx,REX
		mov edi,pSamp
@@:		movq MM0,[ebx]
		pf2id MM0,MM0
		packssdw MM0,MM0
		movd [edi],MM0
		add ebx,8
		add edi,4
		loop @b
		ret
IFFT EndP

;---------------------------------------------------------------------------------;
@Mem Macro NoBytes:req
		Invoke GetProcessHeap
		mov HeapHnd,eax	
		Invoke HeapAlloc,HeapHnd,HEAP_ZERO_MEMORY,NoBytes
		EXITM <eax>
EndM

;--------------------------------------------------------------------------
;Usage:  invoke InitFFT,FFTsize,pointer to hold RealArray offset,pointer to hold ImaginaryArray offset
;				FFTsize have to be power of 2(128,256,512...)
;--------------------------------------------------------------------------
InitFFT	Proc FFTsize:Dword,REX:Dword,IMX:Dword,MAG:Dword,PHS:Dword
		pusha
		mov esi,FFTsize
		mov nmFFTspl,esi
		movd MM0,esi
		pi2fd MM0,MM0
		call log
		pfmul MM0,Qword Ptr[log2]
		pf2id MM0,MM0
		movd lgFFTm,MM0
		shl esi,3
		mov edi,REX
		mov [edi],@Mem(esi)
		mov edi,IMX
		mov [edi],@Mem(esi)
		
		mov edi,MAG
		mov [edi],@Mem(esi)
		mov edi,PHS
		mov [edi],@Mem(esi)
		popa
		ret
InitFFT EndP

;--------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -