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

📄 fft.asm

📁 It is source code for Melp2.4kps vocoder using dsp tms320vc55x of ti
💻 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 + -