📄 fft.asm
字号:
*
*
*2.4 kbps MELP Proposed Federal Standard speech coder
*
*TMS320C5x assembly code
*
*version 1.0
*
*Copyright (c) 1998, Texas Instruments, Inc.
*
*Texas Instruments has intellectual property rights on the MELP
*algorithm. The Texas Instruments contact for licensing issues for
*commercial and non-government use is William Gordon, Director,
*Government Contracts, Texas Instruments Incorporated, Semiconductor
*Group (phone 972 480 7442).
*
*
*************************************************************************
*
* The following code was hand optimized for the Texas Instuments
* TMS320C5x DSP by DSPCon, Inc. For information, please contact DSPCon
* at:
*
* DSPCon, Inc.
* 380 Foothill Road
* Bridgewater, New Jersey 08807
* (908) 722-5656
* info@dspcon.com
* www.dspcon.com
*
*************************************************************************
.if 0
/* Subroutine FFT: Fast Fourier Transform */
/**************************************************************
* Replaces data by its DFT, if isign is 1, or replaces data *
* by inverse DFT times nn if isign is -1. data is a complex *
* array of length nn, input as a real array of length 2*nn. *
* nn MUST be an integer power of two. This is not checked *
* The real part of the number should be in the zeroeth *
* of data , and the imaginary part should be in the next *
* element. Hence all the real parts should have even indeces *
* and the imaginary parts, odd indeces. *
* Data is passed in an array starting in position 0, but the *
* code is copied from Fortran so uses an internal pointer *
* which accesses position 0 as position 1, etc. *
* This code uses e+jwt sign convention, so isign should be *
* reversed for e-jwt. *
***************************************************************/
/* Q values:
datam1 - Q14
isign - Q15 */
.endif
; Code to perform a 512 point FFT
.mmregs
.def _fft
.ref _wr_array, _wi_array
FP .set AR0
SP .set AR1
count .set BRCR
inptr .set INDX
jptr .set AR2
iptr .set AR3
ptr .set AR4
; Ram storage of page 0
L_tempi_h .set 60h ; On chip temporary storage
L_tempi_l .set 61h
istep .set 62h
mmax .set 63h
index .set 64h
index_step .set 65h
savFP .set 66h
INPUT .set 67h
wr .set 68h
wi .set 69h
j .set 6ah
nn .set 6bh
m .set 6ch
i .set 6dh
n .set 6eh
NN .set 512 ; number of point FFT
N .set NN * 2
ONE_Q15 .set ((1 << 15)-1)
.text
; Save C context so that we may restore it upon exit
_fft .equ $
LDP #0 ; Change the page pointer to on chip (fast ram)
; First save off Frame Pointer
SAR FP, savFP ; save frame pointer in internal memory
; Take stack passed arguments and place them in fast direct RAM
MAR *- ; Point SP to first argument
LAC *+,0,iptr ; Move all arguments to fast memory
SAMM iptr ; and in a AR
SUB #1 ; Make *data1 index 0 based
SACL INPUT ; Save input pointer in memory
SAMM inptr ; and in INDX register
; Setup the C50 modes for filter
SSXM ; enable sign extension
SETC OVM ; enable saturation mode
; Prepare loop count based on passed in value
LAC #(NN*2-2) ; Decrement by 2 for looping
SAMM count ; Also save in loop register
LAC #NN ; store nn into memory (nn)
SACL nn
LAC #N ; store nn into memory (n)
SACL n
; Begin FFT
LACL #1 ; init i = j = 1;
SACL j
SACL i
RPTB eloop1-1
LAC j ; if j > i
SUB i
BCNDD skip1, LEQ
LARP jptr
LAC j ; compute &data[j]
SAMM jptr
NOP ; needed due to a bug in the silicon
NOP ; needed due to a bug in the silicon
MAR *0+,iptr
ZALS *,jptr ; load data[i] into ACC low
ADDH *,iptr ; load data[j] into ACC high
SACH *+,0,jptr
SACL *+,0,iptr
ZALS *,jptr
ADDH *,iptr
SACH *-,0,jptr
SACL *-,0,iptr
skip1:
LARP iptr
ADRK 2 ; increment iptr by 2
LAC i ; and increment i by 2
ADD #2
SACL i
DMOV nn ; m = nn
loop1:
LAC j
SUB m
BCND cont1, LEQ
LAC m
SUB #2
BCND cont1, LT
LAC j
SUB m
SACL j
BD loop1
LAC m,15
SACH m
;;;;; BD loop1 occurs here
cont1:
LAC j ; j = j+m;
ADD m
SACL j
eloop1:
LAC #2 ; mmax = 2;
SACL mmax;
; Initialize index step
LAC nn
SACL index_step
; Perform loop while n > mmax
main_loop:
LAC n ; while (n > mmax)
SUB mmax
BCNDD exit, LEQ
LAC mmax,1 ; istep = shl(mmax,1)
SACL istep
ZAC ; index = 0;
SACL index
SACL wi ; wi = 0;
LAC index_step,15 ; index_step = shr(index_step,1)
SACH index_step
LAC #ONE_Q15 ; wr = ONE_Q15
SACL wr
; Set up for main loop(s)
LAC #1 ; for (m = 1)
SACL m
LAR iptr, INPUT
loopo:
DMOV m ; for (i = m)
LARP jptr
loopi:
LAC i ; j = i + mmax
ADD mmax
SACL j
ADDS INPUT ; for this loop compute iptr and jptr
SAMM jptr
LAC i
ADDS INPUT
SAMM iptr
LT wr ; wr * data[j]
MPY *+
LTP wi
MPY *
SPAC ; ACC = (wr * data[j] - wi * data[j+1])
SACB ; save in accum buffer
LT wr ; wr * data[j+1]
MPY *-
LTP wi
MPY *, iptr
APAC ; ACC = (wr * data[j+1] + wi * data[j])
SACH L_tempi_h ; store result in memory
SACL L_tempi_l
LAC *,15,jptr ; L_shr(L_deposit_h(data[i]),1)
SBB ; ACC = L_shr(L_deposit_h(data[i]),1) - L_tempr
SACH *+,0,iptr ; data[j] = extract_h(ACC);
LAC *,15,iptr ; L_shr(L_deposit_h(data[i]),1)
ADDB ; ACC = L_shr(L_deposit_h(data[i]),1) + L_tempr
SACH *+,0,iptr ; data[i] = extract_h(ACC);
ZALS L_tempi_l ; bring back imaginary part into ACCB
ADDH L_tempi_h
SACB
LAC *,15,jptr ; L_shr(L_deposit_h(data[i+1]),1)
SBB ; ACC = L_shr(L_deposit_h(data[i]),1) - L_tempi
SACH *,0,iptr ; data[j+1] = extract_h(ACC);
LAC *,15,iptr ; L_shr(L_deposit_h(data[i]),1)
ADDB ; ACC = L_shr(L_deposit_h(data[i]),1) + L_tempi
SACH *,0,jptr ; data[i+1] = extract_h(ACC);
LAC i ; check to see if inner loop done
ADD istep
SACL i
SUB n
BCNDD loopi, LEQ
LARP jptr
LAC index ; index = index + index_step
ADD index_step
SACL index
SAMM INDX
LRLK ptr, _wr_array ; compute &wr_array[index]
LARP ptr
MAR *0+
LAC * ; wr = wr_array[index];
SACL wr
LRLK ptr, _wi_array ; compute &wi_array[index]
MAR *0+
LAC * ; wi = wi_array[index];
NEG
SACL wi
LAC m ; check to see if outer loop done
ADD #2
SACL m
SUB mmax
BCND loopo, LT
BD main_loop
LAC istep ; mmax = istep;
SACL mmax
;;;; BD main_loop ; occurs here
; Prepare to return to caller
exit:
LAR FP,savFP ; recall frame pointer
RETD ; return to caller with delay
LARP SP ; select stack pointer as current ARP
CLRC OVM ; disable saturation mode
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -