📄 dtmfgai.asm
字号:
; 系数按序排列在存储区coef1st
; COEF1st .word xxxx ;coef1
; .word yyyy ;coef2
; ....
; 数据vk(n-1),vk(n-2)如下排列
; V9(n-1)
; V9(n-2) ;列的二次谐波
; V8(n-1)
; V8(n-2) ;行的二次谐波
; V7(n-1)
; V7(n-2)
; ....
; v0(n-1)
; v0(n-2) <--AR2
; FRCT=1,SXM=1
;---------------------------------------------------
LD *AR5,A
STLM A,AR1 ;AR1指向数据缓冲区
LD *AR5(1),A
ADD #19,A
STLM A,AR6 ;AR6指向抽头的末尾
STM #(N-1),BRC
goer1:
RPTB goer2-1 ;for(n=0;n<N;n++) {
MVMM AR6,AR2 ;AR2指向抽头的末尾
STM #COEF1st,AR3 ;AR3指向系数
LD *AR1+,16,A ;(A)=x(n)
;----滤波k=0---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=1---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=2---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=3---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=4---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=5---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=6---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;----滤波k=7---------------------
SUB *AR2-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR2,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR2,*AR3+,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR2 ;vk(n-1)=vk(n-2)
STH B,*AR2- ;(B)->vk(n-1)
;}
goer2:
;---------------------------------------------------
; 基频能量计算(8个频率)
; y(N)*y(N)=vk(N)*vk(N)-2coef*vk(N)*vk(N-1)+vk(N-1)*vk(N-1)
; 系数按序存放在COEF1st
; COEF1st .word xxxx ;coef0 <-AR3
; .word yyyy ;coef1
; ....
; 数据vk(n-1),vk(n-2)按序排列
; V9(n-1)
; V9(n-2) ;列的二次谐波
; V8(n-1)
; V8(n-2) ;行的二次谐波
; V7(n-1)
; V7(n-2)
; ....
; v0(n-1)
; v0(n-2) <--AR2
; FRCT=1,SXM=1
;---------------------------------------------------
goer3:
LD *AR5(1),A
ADD #19,A
STLM A,AR2 ;AR2指向滤波器抽头块的末尾
STM #COEF1st,AR3 ;AR3指向系数表的开始
LD *AR5(2),A
STLM A,AR4 ;AR4指向能量模板
STM #(8-1),BRC
RPTB goer4-1 ;for(k=0;k<8;k++) {
LD *AR2,16,A ;(A)=vk(N-1),A(32:16)loaded
MPYA *AR2- ;(B)=vk(N-1)*vk(N-1),(T)=vk(N-1)
MPY *AR2,A ;(A)=vk(N-1)*vk(N-1)
LD *AR3+,T ;(T)=coef
MPYA A ;(A)=coef*vk(N)*vk(N-1)
SUB A,1,B ;(B)=-2coef*vk(N)*vk(N-1)+vk(N-1)*vk(N-1)
LD *AR2,T ;(T)=vk(N)
MAC *AR2-,B ;(B)=vk(N)*vk(N)-2coef*vk(N)*vk(N-1)+vk(N-1)*vk(N-1)
STH B,*AR4+ ;存储结果E[k]到能量数据块
;}
goer4:
;---------------------------------------------------
; 为下一次初始化滤波器抽头
;---------------------------------------------------
LD *AR5(1),A
STLM A,AR2 ;AR2指向滤波器抽头开始
LD #0,A
RPT #(20-1) ;for(i=0;i<20;i++)
STL A,*AR2+ ;为下一次初始化滤波器抽头
goer5:
POPM AR6
POPM AR1
POPM ST1
POPM ST0
RET
*******************************************************************
* 子程序:dtmf_checks *
* 输入:指向结构DTMFENCOBJ的指针 *
* 输出:无 *
* 描述: *
* -最大值搜索 max_search *
* -DTMF状态检测 stat_check *
* -信号强度检测 sig_check *
* -行列信号比值检测 twist_check *
* -相对峰值检测 rel_check *
* -二次谐波检测 sec_check *
* -二次谐波能量的有条件计算 *
* -数字有效性检测 *
*******************************************************************
_dtmpchecks:
NOP
PSHM ST0 ;(A)=指向结构dtmfchannel
PSHM ST1
PSHM AR1
PSHM AR6
PSHM AR7
NOP
FRAME #0
SSBX FRCT
STLM A,AR5 ;AR5用于指向dtmfchannel结构
;*AR5(0)=ptr to data
;*AR5(1)=ptr to taps
;*AR5(2)=ptr to energy template
;*AR5(3)=digitptr
;*AR5(4)=digitast
;*AR5(5)=detectstat
;*AR5(6)=err_flags
;---------------------------------------------------
; 最大值搜索
; 结果:AR3指向行能量最大值ROWMAX
; AR4指向列能量最大值COLMAX
;---------------------------------------------------
max_search:
LD *AR5(2),A
STLM A,AR2 ;AR2指向ENERGY表(行能量)
MVMM AR2,AR3 ;AR3指向ENERGY表
STM #(4-1),BRC
RPTB max1-1 ;for(k=0;k<4;k++)
LD *AR3,A ;(A)=oldmax
SUB *AR2,A ;(A)=oldmax-E[k]
BC max11,AGT ;if(oldmax<E[k])
MVMM AR2,AR3 ;AR3指向新的最大值
max11:
MAR *AR2+ ;指针增加
max1: ;结果:AR3指向ROWMAX
; AR2指向列能量
MVMM AR2,AR4 ;AR4指向ENERGY表(列能量)
STM #(4-1),BRC
RPTB max2-1 ;for(k=0;k<4;k++)
LD *AR4,A ;(A)=oldmax
SUB *AR2,A ;(A)=oldmax-E[k]
BC max21,AGT ;if(oldmax<E[k])
MVMM AR2,AR4 ;AR4指向新的最大值
max21:
MAR *AR2+ ;指针增加
max2: ;结果:AR4指向ROWMAX
; AR2指向列能量
;---------------------------------------------------
; DTMF状态检测:
; if(detectstat==0)
; if(max(ROWMAX,COLMAX)<THR_PAU)
; detectstat=1,detector enabled
; terminate all checks
; else
; continue
;
;
; AR3指向ROWMAX
; AR4指向COLMAX
;---------------------------------------------------
stat_check:
ANDM #0080h,*AR5(6) ;清错误标记,OVA除外
BITF *AR5(5),#0001h
BC STAT1,NTC ;if(detectstat==1)
LD *AR5(5),A ;装入detectstat
AND #0F00h,A ;屏蔽其他位,找出持续比特
SFTL A,1 ;左移一位
ANDM #0001h,*AR5(5) ;只保存检测状态比特
OR *AR5(5),A ;与持续比特"或"操作
STL A,*AR5(5) ;写回detectstat
B sig_check ;继续执行下面sig_check
stat1:
LD *AR3,A ;else
LD *AR4,B
MAX A ;(A)=max(ROWMAX,COLMAX)
SUB #THR_PAU,A ;(A)=max(ROWMAX,COLMAX)-THR_PAU
BC stat2,ageq ;if((A)<0)
ST #0001h,*AR5(5) ;detectstat=1
stat2:
B ends ;中止所有检测
;---------------------------------------------------
; 信号强度检测:
; if(ROWMAX+COLMAX>THR_SIG1) 继续
; else 中止所有检测
; AR3指向ROWMAX
; AR4指向COLMAX
;---------------------------------------------------
sig_check:
LD *AR3,A
ADD *AR4,A ;(A)=ROWMAX+COLMAX
SUB #THR_SIG1,A,B
BC ends,BLEQ ;if(ROWMAX+COLMAX<=THR_SIG1)
;无DTMF
;中止检测
SUB #THR_SIG2,A,B
BC err_sig,BLEQ ;if(ROWMAX+COLMAX<=THR_SIG2)
;信号有可能为音频
;但是不满足THR_SIG2条件
;跳转到err_sig
B twist_check
err_sig: ;****记录信号强度错误****
ORM #0001h,*AR5(6) ;设置信号强度误差标记(b0)
B ends ;中断检测
;---------------------------------------------------
; 行列信号比值检测
; if(ROWMAX>COLMAX)
; 检测COLMAX/ROWMAX;
; if((COLMAX/ROWMAX)>THR_REVTWI) 继续
; else 终止所有检测
; else
; 检测ROWMAX/COLMAX
; if((ROWMAX/COLMAX)>THR_STDTWI) 继续
; else 中断所有检测
; AR3指向ROWMAX
; AR4指向COLMAX
;---------------------------------------------------
twist_check:
LD *AR3,A
SUB *AR4,A
BC twist2,ALEQ ;if(ROWMAX>COLMAX)
twist1:
LD *AR4,16,A ;(AH)=COLMAX
RPT #(16-1)
SUBC *AR3,A ;计算(COLMAX/ROWMAX)
AND #0ffffh,A ;保存商(AL),屏蔽余数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -