📄 idftreal.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 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 + -