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

📄 dtmfgai.txt

📁 程序名称:DTMF双音频检测 描述:初始化数字正弦振荡器状态 它将指定状态集的状态复制到通道对应的振荡器状态缓冲区中
💻 TXT
📖 第 1 页 / 共 3 页
字号:
*************************************************************
*  程序名称:DTMF双音频检测                                 *              
*************************************************************

          .mmregs
          .include  "globals.inc"                   ;全局标号
          .include  "tables.inc"                    ;变量表
          .text

*******************************************************************
*  子程序:initoscis                                              *              
*  输入:指向结构DTMFENCOBJ的指针                                 *
*  输出:无                                                       *
*  描述:初始化数字正弦振荡器状态                                 *
*  它将指定状态集的状态复制到通道对应的振荡器状态缓冲区中         *
*******************************************************************

_initoscis:
    NOP
	PSHM	ST0
    PSHM    ST1
    PSHM	AR1
    PSHM    AR6
    PSHM    AR7
    NOP
                                                    ;(A)=指向结构DTMFENCOBJ
                                                    ;*SP(6)=数字
    STLM    A,AR6                                   ;AR6用作指向结构元素的指针
                                                    ;*AR6(0)=指向数据
                                                    ;*AR6(1)=指向振荡器状态
    LD      #0,ASM                                  ;ASM=0
    STM     #OSCIS,AR2								;AR2指向振荡器状态表
    LD      *AR6(1),A								
    STLM    A,AR3                                   ;AR3指向通道振荡器状态表        
    LD		*AR2+,16,A								;装入第一个值
    RPT	    #(16-1)									;for(k=0;k<16;k++){
    ST 	    A,*AR3+									;store(AH)
    ||LD 	*AR2+,A									;load(AH)
                                                    ;}
    POPM	AR7
    POPM	AR6
    POPM	AR1
    POPM	ST1
    POPM	ST0
    RET
     
*******************************************************************
*  子程序:dtmftone                                               *              
*  输入:指向结构DTMFENCOBJ的指针                                 *
*  输出:无                                                       *
*  描述:计算DTMF双音频的102个采样值                              *
*  子程序根据指针值取出数字,并将其送入堆栈进行编码               *
*******************************************************************

_dtmftone:
	
	NOP
	PSHM	ST0
	PSHM	ST1
	PSHM	AR1
	PSHM	AR6
	PSHM	AR7
	NOP
	FRAME	#-2										;----局部变量----
													;*SP(0)=衰减值
													;----参数--------			 
													;(A)=指向结构DTMFENCOBJ
													;*SP(8)=数字
	STLM	A,AR6                                   ;AR6用作指针指向结构元素
	                                                ;*AR6(0)=指向数据
	                                                ;*AR6(1)=指向振荡器
	                                                ;*AR6(2)=音频衰减值				
	SSBX    FRCT                                    ;设置分数模式
;----数字解包,指针指向振荡器抽头系数----
	LD		*SP(8),A
	STLM	A,AR0									;AR0为映射表的偏移量
	STM		#KEYS,AR2								;AR2指向数字映射表首地址
	NOP
	MAR		*AR2+0									;AR2指向映射表中对应的数字
	LD		*AR2,A									;数字装入A
	LD		A,B								        ;(A)->(B)
	AND		#0F00h,A								;取行部分
	SFTL	A,-8									;(A)右移8位
	STLM	A,AR2									;AR2包含行音频的系数表偏移量
	SFTL	A,1										;(A)<<1
	STLM	A,AR4									;AR4包含行音频振荡器表偏移量
	AND		#000Fh,B								;取列部分
	ADD 	#4,B                                    ;B+4=列音频的系数表偏移量
	STLM	B,AR3									;AR3包含列音频的系数表偏移量		
	SFTL	B,1										;(B)<<1
	STM		#COEFFS,AR0								;AR0指向系数表
	STLM	B,AR5									;AR5包含列音频振荡器表偏移量
	MAR		*AR2+0									;AR2指向行音频系数
	MAR		*AR3+0									;AR3指向列音频系数
	LD   	*AR6(1),A								;装入指向数据的指针	
	STLM	A,AR0									;AR0指向振荡器表
	LD		*AR6(2),B								;载入衰减值
	STL		B,*SP(0)								;存储到局部变量区
	MAR		*AR4+0									;AR4指向行音频振荡器	
	MAR		*AR5+0									;AR5指向列音频振荡器
	MAR		*AR4+									;AR4指向行音频y(n-2)
	MAR		*AR5+									;AR5指向列音频y(n-2)
;----产生DTMF音频------------------------
    LD		*AR6(0),A
    STLM    A,AR1									;AR1指向数据
    STM		#(N-1),BRC
    RPTB 	oscil-1									;for(n=0;n<N;n++){
    LD 	 	#0,A								;----产生行音频采样值----
    SUB     *AR4-,16,A								;(A)=-y(n-2)
    MAC  	*AR4,*AR2,A								;(A)=coef*y(n-1)-y(n-2)
    MAC  	*AR4,*AR2,A								;(A)=2coef*y(n-1)-y(n-2)
	DELAY	*AR4									;y(n-1)->y(n-2)
	STH		A,*AR4									;(A)   ->y(n-1)
	LD		#0,A								;----产生列音频采样值----
	SUB		*AR5-,16,A								;(A)=-y(n-2)
	MAC		*AR5,*AR3,A								;(A)=coef*y(n-1)-y(n-2)
	MAC		*AR5,*AR3,A								;(A)=2coef*y(n-1)-y(n-2)
	DELAY 	*AR5									;y(n-1)->y(n-2)
	STH		A,*AR5+									;(A)   ->y(n-1)
	ADD 	*AR4+,16,A								;(A)=row-tone+tol-tone
	MPYA	*SP(0)									;(A)=attn*(AH)
	STH 	B,*AR1+									;(A)->x(n)}
osci1:
 	FRAME	#2
 	NOP
 	POPM	AR7	
	POPM	AR6
	POPM	AR1
	POPM 	ST1
	POPM	ST0
	RET

*******************************************************************
*  子程序:gaincntrl                                              *              
*  输入:指向结构DTMFENCOBJ的指针                                 *
*  输出:无                                                       *
*  描述:定标数据块,确保执行goertzel算法时无溢出                 *
*            gain_power=(1/64)*SUM{0,N-1}[x(n)*x(n)]              *
*					   =(1/64)*N*signalpower                      *
*     		 gain_lim  =(1/64)*(1/N)                              *
*           		   =minimum signalpower(-..dB)                *
*            gain_const=0.5*sqrt(2)*sqrt(64/N)                    * 
*            gain_amp  =gain_const*sqrt(ain_power)                *
*            gain_lev  =1/N                                       *
*            gain_scale=gain_lev/gain_amp                         *
*            x(n)=x(n)*gain_scale                                 *
*  FRCT=1,SXM=1                                                   *
*******************************************************************
	
_gaincntrl:	
	NOP
	PSHM	ST0
	PSHM	ST1
	PSHM	AR1
	PSHM	AR6
	PSHM	AR7
	NOP
	FRAME	#-10									;----局部变量----
	                                                ;*SP(0)=gain_pow(HI)
	                                                ;*SP(1)=gain_pow(LO)
	                                                ;*SP(2)=gain_lim(HI)
	                                                ;*SP(3)=gain_lim(LO)
	                                                ;*SP(4)=gain_amp
	                                                ;*SP(5)=gain_lev
	                                                ;*SP(6)=gain_scale
	                                                ;*SP(7)=gain_const
	                                                ;*SP(8)=gain_delta
	                                                ;*SP(9)=ptr to data
	                                                ;----arguments----
	                                                ;(A)=ptr to DTMFDECOBJ
	STLM	A,AR5                                   
	NOP
	NOP
	NOP
	LD		*AR5,A
	STL		A,*SP(9)
;----变量初始化----------------------	
	LD		#0005h,16,A								;(A)=00050000h
	OR		#0505h,A								;(A)=00050505h=1/(64*N)(Q31)	
	STH		A,*SP(2)								;(A)->gain_lim (32bit)
	STL		A,*SP(3)								
	LD		#00E3h,A								;(AL)=00E3h=(0.5*sqrt(2))/N			
	STL		A,*SP(5)								;(AL)->gain_lev (16bit)
	LD		#6564h,A								;(AL)=6564h=sqrt(64/102)
	STL		A,*SP(7)								;(AL)->gain_const
	LD		#4000h,A								;(AL)=4000h=0.5
	STL		A,*SP(8)								;(AL)->gain_delta
	SSBX	FRCT
;----计算信号能量--------------------	
	LD		*SP(9),A
	STLM	A,AR2									;AR2指向数据缓冲区
	RPTZ	B,#(N-1)								;for(n=0;n<N-1;n++)
	SQURA	*AR2+,B									;(B)=(B)+x(n)*x(n)
	SFTA	B,-6									;(B)=(1/64)*(B)		
	STH		B,*SP(0)								;(B)->gain_pow (32bit)
	STL		B,*SP(1)								;gain_pow=(N/64)*sigpower
	LD		*SP(2),16,A								;(A)=gain_lim=1/(N/64) (32bit)	
	OR		*SP(3),A									
	SUB		A,B										;(B)=gain_pow-gain_lim
	BC		gain2,BLEQ	 							;if(gain_pow>gain_lim
													;{
;----计算gain_amp=sqrt(gain_pow)-----
	ST  	#4000h,*SP(4)							;初始化gain_amp
	ST 		#4000h,*SP(8)							;初始化gain_delta
	MVMM	SP,AR2
	MAR		*+AR2(8)								;AR2指向gain_delta
	STM		#(sqrt_iterations-1),BRC
	RPTBD	sqrtloopend-1
	SQUR	*SP(4),A								;(A)=yold*yold
	DSUB	*SP(0),A								;(A)=yold*yold-x
sqrtloop:
    BCD		sqrt1,AGT
    LD		*SP(4),16,B								;(B)=yold
    SUB		*AR2,15,B								;(B)=yold-(1/2)*delta
    												;if(y needs to be larger)
    ADD 	*AR2,16,B								;(B)=yold+(1/2)*delta
sqrt1:
	STH		B,*SP(4)								;(BH)->ynew
	LD		*AR2,15,A								;(AH)=(1/2)*delta
	STH		A,*AR2									;(AH)->delta new
	SQUR	*SP(4),A
	DSUB	*SP(0),A								;(A)=yold*yold-x
sqrtloopend
;----计算gain_amp=sqrt(64/N)*gain_amp------
    LD		*SP(7),T 								;(T)=gain_const
    MPY		*SP(4),A								;(A)=sqrt(64/102)*gain_amp
    STH		A,*SP(4)								;(AH)->gain_amp
;----计算gain_lev/gain_amp-----------------
	LD		*SP(5),16,A								;(AH)=gain_lev
	RPT		#(16-1)
	SUBC	*SP(4),A								;计算(gain_lev/gain_amp)
	AND		#0FFFFh,A								;保留商(AL),屏蔽余数
	SFTA	A,15									;左移商到累加器高位
	STH		A,*SP(6)								;(AH)->gain_scale
;----用(gain_lev/gain_amp)定标数据---------
	LD		*SP(9),A
	STLM	A,AR2									;AR2指向数据
	MVMM	SP,AR3
	MAR		*+AR3(6)								;AR3指向gain_scale
	STM		#(N-1),BRC
	RPTB	gain1-1									;for(n=0;n<N;n++)
	MPY		*AR2,*AR3,A								;(A)=x(n)*(gain_lev/gain_amp)
	STH		A,*AR2+									;(AH)->x(n)	

gain1:												

gain2:
    FRAME	#10
    NOP
    POPM	AR7
    POPM	AR6
    POPM	AR1
    POPM	ST1
    POPM	ST0
    RET	
    
*******************************************************************
*  子程序:goetzel                                                *              
*  输入:指向结构DTMFENCOBJ的指针                                 *
*  输出:无                                                       *
*  描述:该程序对102个数据计算差分方程                            *
*  因为有增益控制保护可能的溢出,故程序不检查溢出                 *
*  由于二次谐波在子程序dtmfchecks()中计算,故这里只计算基频(8个)  *
*  子程序同样计算8个基频的能量模板                                *
*  随后复位滤波器抽头系数为0,准备下一次计算                      * 
*******************************************************************
    		
_goertzel:	
	NOP
	PSHM	ST0
	PSHM	ST1
	PSHM	AR1
	PSHM	AR6
	PSHM	AR7
													;----参数-----------
													;(A)=指向DTMFDECOBJ
	RSBX	OVA
	SSBX	FRCT
	STLM	A,AR5									;AR5指向结构DTMFDECOBJ
													;*AR5(0)=ptr to data
													;*AR5(1)=ptr to taps
													;*AR5(2)=ptr to energy template
													;*AR5(3)=digiptr                                                                                                                                                                                                                                 
													;*AR5(4)=digitlast
													;*AR5(5)=detectstat
													;*AR5(6)=err_flags
;---------------------------------------------------
;   Goertzel滤波器计算									
;   vk(n)=2coef*vk(n-1)-vk(n-2)+x(n)					

⌨️ 快捷键说明

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