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

📄 idftreal.asm

📁 It is source code for Melp2.4kps vocoder using dsp tms320vc55x of ti
💻 ASM
📖 第 1 页 / 共 5 页
字号:
* 
* 
*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 IDFT_REAL: take inverse discrete Fourier	*/
/*	transform of real input coefficients.			*/
/*	Assume real time signal, so reduce computation		*/
/*	using symmetry between lower and upper DFT		*/
/*	coefficients.						*/
/*								*/
/*  Q values:
    real - Q13
    signal - Q15
*/
	.endif

    .mmregs

    .def    _idft_real
    .def    _idftc


FP	.set	AR0
SP	.set	AR1
count	.set	BRCR
sigptr	.set	AR2
loopcnt .set	AR3
realptr .set	AR4
idftcptr .set	AR5

; Page 9 storage
PAGE9	.set	480h
LENGTH	.set	80
SIGNAL	.set	81
REAL	.set	82

one1	.set	83
j	.set	84
i	.set	85
k_inc	.set	86
k	.set	87
length2 .set	88
w	.set	89
w2	.set	90
temp	.set	91
one_q19 .set	92	      ; caution, must load high
two_q19 .set	93	      ; caution, must load high
x05_q15 .set	94

tx	.set	95
ty	.set	96
zero	.set	97
sign	.set	98
index1	.set	99
index2	.set	100
m	.set	101
rndval	.set	102
length2_m1 .set 103
one	.set	104
pread	.set	105
savAR0	.set	106
tabptr	.set	107
length2_m2 .set 108
one_q15 .set	109
length_m1 .set	110
size	.set	111
size2	.set	112
l	.set	113
last_begin    .set 114
lengXtbls     .set 115
lengXtbls_m1  .set 116
lengXtbls_mm1 .set 117
idftcbase     .set 118
real0	      .set 119
real	      .set 120

; Constants
TBLSIZE .set	14
DFTMAX	.set	160
TWO_Q3	.set	(2*(1<<3))

ONE_Q19 .set	(1<<3)	      ; caution, must load high
TWO_Q19 .set	(2*(1<<3))    ; caution, must load high

X05_Q15 .set	16384	      ; (.5 * (1 << 15))
ONE_Q15 .set	((1 << 15) -1)


;TABLOOK .set    50            ; if lenth >= , copy cosine from ROM
TABLOOK .set    85            ; if lenth >= , copy cosine from ROM

    .bss    _idftc, (DFTMAX * TBLSIZE)
    .bss    _idftcIndx, 1

    .sect   ".cinit"
    .word   1, _idftcIndx, 0

    .text

; Save C context so that we may restore it upon exit
_idft_real  .equ    $
    LDP     #9		; Change the page pointer to on chip (fast ram)
    CNFD		; Configure B0 for data memory

; Take stack passed arguments and place them in fast direct RAM
    SBRK    3		; Point SP to first argument
    RPT     #(3-1)	; ARP assumed to be SP
      BLDD  *+,#(PAGE9+ LENGTH)  ; Move all arguments to fast memory

; Setup the C50 modes
    SSXM		; enable sign extension
    SETC    OVM 	; enable saturation mode

    SAR     AR0, savAR0

; load often used constants into memory
    LACC    #ONE_Q19,15 ; caution, must load high
    SACH    one_q19,1	; caution, must load high

    LACC    #TWO_Q19,15 ; caution, must load high
    SACH    two_q19,1	; caution, must load high

    SPLK    #X05_Q15, x05_q15
    SPLK    #ONE_Q15, one_q15
    SPLK    #8000h, rndval
    SPLK    #table, tabptr  ; load table base address into memory
    SPLK    #_idftc, idftcbase

    LAC     #1
    SACL    one
    SACL    one1
    SACH    zero

; Enable ARCR for final loop
    LACC    #(_idftc -1)
    ADD     LENGTH
    SAMM    ARCR

; compute lenth2 = length >> 1 +1
    LAC     LENGTH
    SFR
    SACL    length2_m1
    SUB     #1
    SACL    length2_m2
    ADD     #2
    SACL    length2

    LAC     LENGTH
    SUB     #1
    SACL    length_m1


; compute w = TWO_Q3/length
    LAC     #TWO_Q3,15
    RPT     #15
	SUBC	LENGTH

    SACL    w


; First determine if cosine table is in RAM from last call
    LAR     idftcptr, #_idftcIndx
    LARP    idftcptr
    LAC     LENGTH
    SUB     *
    BCNDD   cos_in_ram, EQ
	LAC	LENGTH
	SACL	*

; If Length is greater than TABLOOK, copy cos table, otherwise generate it.
; Compute index into cosine table and copy on chip
    LAC     LENGTH
    SUB     #TABLOOK
    BCND    gen_cos, LT

    ZAP 		; Compute appropriate index into COS_TABLE
    SQRA    LENGTH
    PAC
    SUB     LENGTH
    SFR
    SUB     #(((TABLOOK * TABLOOK) - TABLOOK) /2)

    ADLK    #cos_tab
    SAMM    BMAR

    LAR     idftcptr, idftcbase
    LARP    idftcptr

    RPT     length_m1
	BLPD	BMAR, *+

    BD	    loop_end
	SPM	1	; Set product mode to auto multiply by 2
	NOP

; main loop
gen_cos:

    SPM     1		; Set product mode to auto multiply by 2

    ZALS    LENGTH	; prepare loop count
    SUB     #1
    SAMM    BRCR
    SACH    i		; Initialize loop count to 0

    LAR     idftcptr, idftcbase

    RPTB    loop_end -1
    LT	    w		; compute w * i
    MPY     i
    PAC
    SACB		; save in ACCB for comparisons]

    ZALH    one_q19	; compare result to ONE_Q19
    SBB 		; ACC = ONE_Q19 - L_temp
    BCNDD   else, GEQ
	ZALH	two_q19
	SBB
    BD	    cont
	NOP
	SACB

else:
    ZALH    one_q19	; if ONE_Q19 == L_temp
    SBB
    BCNDD   cont, NEQ
	LACB		; move L_temp to ACC
	SUB	#1
    SACB		; update L_temp

cont:
    LACB		; move L_temp to ACC
    BSAR    4		; long right shift by 4 (L_temp in Q15)

;   AND     #0ffffh	; make compatible with C code

; Get result of cos_fxp(temp)
    DMOV    zero	; sign = 0

    ABS
    SACL    tx

    SUB     x05_q15	; compare tx with X05_Q15

    BCNDD   cont1, LEQ
	LAC	one_q15
	SUB	tx
    SACL    tx
    LACL    #1
    NEG
    SACL    sign

cont1:
    LAC     tx,9	; index1 = tx >> 7
    SACH    index1
    ADDH    one
    SACH    index2	; index2 = index1 +1

    LAC     index1	; compare index1 to 128
    SUB     #128
    BCNDD   cos_done,EQ ; if index1 = 128, done with answer of 0
	ZAC
	LARP	idftcptr

    LAC     tx		; compute tx - (index1 << 7)
    SUB     index1,7
    SFL 		; convert decimal part to Q15
    SACL    m,7 	; and save as m

    ZALS    tabptr	; get table[index1]
    ADD     index1
    TBLR    pread	; read table from program memory
    LAC     pread
    SACB		; and save in ACCB

    ZALS    tabptr	; get table[index2]
    ADD     index2
    TBLR    pread
    LAC     pread

    SBB 		; compute table[index2] - table[index1]
    SAMM    TREG0	; compute m * temp
    MPY     m
    PAC
    BSAR    16		; Right shift by 16

    BIT     sign,0
    ADDB		; and add table[index1] to this product
    XC	    1, TC
	NEG

cos_done:
    SACL    *+

    LAC     i		; increment loop counter
    ADD     #1
    SACL    i

loop_end:

; Now copy the cos table TBLSIZE times

    LAC     #_idftc
    SAMM    BMAR
    ADDS    LENGTH
    SAMM    AR2
    LARP    AR2

    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+
    RPT     length_m1
	BLDD	BMAR, *+

cos_in_ram:
    SPM     1

    LAC     w,15	; w = w >> 1
    SACH    w
    SFR 		; w2 = w >> 1
    SACH    w2

    LARP    realptr	; real[0] = real[0] * w2
    LAR     realptr, REAL
    LT	    *
    MPY     w2
    SPH     *+

    LAC     length2	; temp = length2 -1
    SUB     #(1+2)
    SAMM    BRCR	; save loop count
    SACB		; save for later

    RPTB    loop2_end -1
	LT  *
	MPY w
	SPH *+
loop2_end:
    LACB		; recall loop count
    ADD #2		; add back two
    SFL

    SUB     LENGTH	; compare temp to length
    LT	    w		; if temp != length
    XC	    1, EQ	; real[i] = real[i] * w
	LT  w2		; else real[i] = real[i] * w2
    MPY     *
    SPH     *, realptr

; Now copy real[] to block B0 for MACs
    LAC     REAL
    SAMM    BMAR
    LAR     realptr, #100h
    SPLK    #0fe00h, real
    RPT     length_m1
	BLDD	BMAR, *+

    CNFP
    LAR     realptr, REAL
    LAC     *
    SACL    real0

; prepare for final DFT loop first half
    SPM     0
    LT	    LENGTH
    MPY     #TBLSIZE
    PAC
    SACL    lengXtbls
    SUB     #1
    SACL    lengXtbls_m1

    MPY     #(TBLSIZE -1)
    SPL     lengXtbls_mm1

    LAC     length2_m1
    SAMM    BRCR
    ZAC 		 ; init i = 0
    SACL    i
    LAR     sigptr, SIGNAL
    LAR     realptr, REAL
    LARP    idftcptr

oloop1:
    RPTB    oloop1_end -1

;   LAC     i
;   SACL    k_inc
    DMOV    i
    SUB     #1
    BCNDD   else1, LEQ
	ADD	#1
	SACL	k

    LAC     lengXtbls_m1  ; divide length-1 /k_inc
    RPT #15
	SUBC	k_inc

    SACL    size	; compute size and size2
    ADD     #1
    SACL    size2

    SPM     0
    LAC     lengXtbls
    LT	    k_inc
    MPY     size
    BD	    endif1
	SPAC
	SACL	last_begin

else1:
    ZALS    length2
    SACL    size
    SACL    size2
    SACH    last_begin

endif1:
    DMOV    one1		; j = 1

    ZALH    real0		; get real[0] into ACCB
    SACB

while_loop1:
    LAC     length2
    SUB     j
    BCNDD   while1_done, LEQ
	LAC	size
	SACL	l
    LAC     last_begin
    SUB     k
    SPM     1
    XC	    2, GT
	LAC	size2
	SACL	l

    LAC     length2
    SUB     j
    SACL    temp
    SUB     l
    LAR     AR0, k
    XC	    2, LT
	LAC	temp
	SACL	l

    LAR     idftcptr, idftcbase ; compute and select &idftc[k]
    MAR     *0+
    LAR     AR0, k_inc

    LAC     l			; compute inner loop count
    SUB     #1
    SACL    temp

    ZALS    real
    ADDS    j
    SAMM    BMAR

    LACB			; recall L_temp
    ZPR
    RPT     temp
	MADS	*0+
    LTA     k_inc		; accumulate last product and load k_inc
    SACB			; save new L_temp in ACCB

    LAC     j
    ADD     l
    SACL    j

    SPM     0
    MPY     l
    LAC     k
    APAC
    BD	    while_loop1
	SUB	lengXtbls
	SACL	k

while1_done:
    LARP    sigptr
    LACB
    ADDS    rndval
    SACH    *+,0,idftcptr

    LAC     i
    ADD     #1
    SACL    i

oloop1_end:


; prepare for final DFT loop second half
    LAC     LENGTH	; load loop counter
    SUB     length2
    SUB     #1		; Decrement for looping
    SAMM    BRCR	; Load loop counter

    LAC     length2
    SACL    i
    LARP    idftcptr

oloop2:
    RPTB    oloop2_end-1

    ZALS    i
    ADDS    lengXtbls_mm1
    SACL    k

    LAC     LENGTH
    SUB     i
    SUB     #1

    BCNDD   else2, LEQ
	ADD	#1
	SACL	k_inc

    LAC     lengXtbls_m1  ; divide length-1 /k_inc
    RPT #15
	SUBC	k_inc

    SACL    size	  ; compute size and size2
    ADD     #1
    SACL    size2

    SPM     0
    LT	    k_inc
    BD	    endif2
	MPY	size
	SPL	last_begin

else2:
    ZALS    length2
    SACL    size
    SACL    size2
    SACH    last_begin

endif2:
    DMOV    one1		; j = 1

    ZALH    real0		; get real[0] into ACCB
    SACB

while_loop2:
    LAC     length2
    SUB     j
    BCNDD   while2_done, LEQ
	LAC	size
	SACL	l
    LAC     k
    SUB     last_begin
    SPM     1
    XC	    2, GEQ
	LAC	size2
	SACL	l

    LAC     length2
    SUB     j
    SACL    temp
    SUB     l
    LAR     AR0, k		; compute and select &idftc[k]
    XC	    2, LT
	LAC	temp
	SACL	l

    LAR     idftcptr, idftcbase
    MAR     *0+
    LAR     AR0, k_inc

    LAC     l			; compute inner loop count
    SUB     #1
    SACL    temp

    ZALS    real
    ADDS    j
    SAMM    BMAR

    LACB			; recall L_temp
    ZPR
    RPT     temp
	MADS	*0-
    LTA     k_inc		; accumulate last product and preload k_inc
    SACB			; save new L_temp in ACCB

    LAC     j
    ADD     l
    SACL    j

    SPM     0
    MPY     l
    LAC     k
    SPAC
    BD	    while_loop2
	ADD	lengXtbls
	SACL	k

while2_done:
    LARP    sigptr
    LACB
    ADDS    rndval
    SACH    *+,0,idftcptr

    LAC     i
    ADD     #1
    SACL    i

oloop2_end:


; Prepare to return to caller
exit:
    LAR     AR0, savAR0 ; recall the value of the index register
    LARP    SP		; Select ARP for "C" context re-entry
    RETD		; return to caller with delay
       SPM     0	; reset the product shift mode
       CLRC    OVM	; disable saturation mode
			; return occurs here

table:
    .word   32767, 32766, 32758, 32746, 32729, 32706, 32679, 32647, 32610
    .word   32568, 32522, 32470, 32413, 32352, 32286, 32214, 32138, 32058
    .word   31972, 31881, 31786, 31686, 31581, 31471, 31357, 31238, 31114
    .word   30986, 30853, 30715, 30572, 30425, 30274, 30118, 29957, 29792
    .word   29622, 29448, 29269, 29086, 28899, 28707, 28511, 28311, 28106
    .word   27897, 27684, 27467, 27246, 27020, 26791, 26557, 26320, 26078
    .word   25833, 25583, 25330, 25073, 24812, 24548, 24279, 24008, 23732
    .word   23453, 23170, 22884, 22595, 22302, 22006, 21706, 21403, 21097
    .word   20788, 20475, 20160, 19841, 19520, 19195, 18868, 18538, 18205
    .word   17869, 17531, 17190, 16846, 16500, 16151, 15800, 15447, 15091
    .word   14733, 14373, 14010, 13646, 13279, 12910, 12540, 12167, 11793
    .word   11417, 11039, 10660, 10279,  9896,	9512,  9127,  8740,  8351
    .word   7962,   7571,  7180,  6787,  6393,	5998,  5602,  5205,  4808
    .word   4410,   4011,  3612,  3212,  2811,	2411,  2009,  1608,  1206
    .word   804,     402,     0



cos_tab:
        .if 0

	.word	07fffh
	.word	07efdh
	.word	07bfah
	.word	07703h
	.word	0702ch
	.word	0678eh
	.word	05d51h
	.word	05199h
	.word	04498h
	.word	03683h
	.word	02791h
	.word	01802h
	.word	0080eh
	.word	0f7f8h
	.word	0e808h
	.word	0d875h
	.word	0c982h
	.word	0bb6eh
	.word	0ae6ch
	.word	0a2b6h
	.word	09875h
	.word	08fd7h
	.word	08900h
	.word	08408h
	.word	08103h
	.word	08002h
	.word	08102h
	.word	08404h
	.word	088fbh
	.word	08fd1h
	.word	0986ch
	.word	0a2abh
	.word	0ae60h
	.word	0bb61h
	.word	0c977h
	.word	0d866h
	.word	0e7f8h
	.word	0f7ech
	.word	007feh
	.word	017f2h
	.word	02782h
	.word	03675h
	.word	0448dh
	.word	0518dh
	.word	05d46h
	.word	06787h
	.word	07024h
	.word	076fdh
	.word	07bf6h
	.word	07efbh


	.word	07fffh
	.word	07f07h
	.word	07c22h
	.word	0775ah
	.word	070c5h
	.word	06879h
	.word	05e97h
	.word	05347h
	.word	046b4h
	.word	0390eh
	.word	02a8ah
	.word	01b63h
	.word	00bd0h
	.word	0fc0dh
	.word	0ec5ch
	.word	0dcf7h
	.word	0ce1ah
	.word	0bfffh
	.word	0b2dch
	.word	0a6e5h
	.word	09c47h
	.word	0932ch
	.word	08bb7h
	.word	08606h
	.word	0822fh
	.word	0803fh
	.word	0803fh
	.word	0822eh
	.word	08605h
	.word	08bb6h
	.word	0932ah
	.word	09c45h
	.word	0a6e2h
	.word	0b2dah
	.word	0bffch
	.word	0ce17h
	.word	0dcf4h
	.word	0ec59h
	.word	0fc0ah
	.word	00bcch
	.word	01b60h
	.word	02a87h
	.word	0390bh
	.word	046b1h
	.word	05344h
	.word	05e95h
	.word	06877h
	.word	070c3h
	.word	07759h
	.word	07c21h
	.word	07f07h


	.word	07fffh
	.word	07f11h
	.word	07c47h
	.word	077afh
	.word	07156h
	.word	06958h
	.word	05fd1h
	.word	054e3h
	.word	048b7h
	.word	03b7eh
	.word	02d66h
	.word	01ea5h
	.word	00f6fh
	.word	00003h
	.word	0f094h
	.word	0e161h
	.word	0d29dh
	.word	0c485h
	.word	0b74ch
	.word	0ab21h
	.word	0a032h
	.word	096aah
	.word	08each
	.word	08854h
	.word	083bah
	.word	080f0h
	.word	08002h
	.word	080efh
	.word	083b7h
	.word	08850h
	.word	08ea7h
	.word	096a5h
	.word	0a02bh
	.word	0ab1ah
	.word	0b744h
	.word	0c47dh
	.word	0d294h
	.word	0e158h
	.word	0f08ah
	.word	0fff7h
	.word	00f66h
	.word	01e9ch
	.word	02d5dh
	.word	03b75h
	.word	048afh
	.word	054dch
	.word	05fcah

⌨️ 快捷键说明

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