📄 dtmfasm.s55
字号:
ac1 = ac0;
ac1 = ac1 & #0xffff;
ac1 = ac1 << #16; unsigned
ac2 = ac1 * *ar3;
ac2 = ac2 << #-16
ac2 = ac2 + (ac0 * *ar3);
ac2 = ac2 + t3; ; t3 still keeps max energy
*ar1(#(DTMF_tSc.sLoMaxFreqEn)) = ac2;
;
; -- hi band dft
;
; ar2 = psOut
; ar3 = psI data
; ar4 = psQ data
; t1 = sSz*2-1
; cdp = filterbank
; t0 = 2
; ac2 = energy, both lin and log
;
xcdp = #_dtmf_aHi;
xar2 = mar(*ar1(#(DTMF_tSc.asHiMainEn)));
xar3 = mar(*ar1(#(DTMF_tSc.asHiData)));
xar4 = mar(*ar1(#(DTMF_tSc.asHiData+1)));
mar (t1 = #(DTMF_HI_DFT_SZ*2-2))
brc0 = #(4-1)
mar (t0 = #2); ; extra ...
|| localrepeat {
ac0 = *(ar3+t0) * coef( *cdp+),
ac1 = *(ar4+t0) * coef(*cdp+);
|| repeat(#(DTMF_HI_DFT_SZ-3))
ac0=ac0+(*(ar3+t0)*coef(*cdp+)),
ac1=ac1+(*(ar4+t0)*coef(*cdp+));
ac0 = ac0+(*(ar3-t1)*coef(*cdp+)),
ac1 = ac1+(*(ar4-t1)*coef(*cdp+));
|| repeat(#(DTMF_HI_DFT_SZ-2))
ac0 = ac0-(*(ar4+t0)*coef(*cdp+)),
ac1 = ac1+(*(ar3+t0)*coef(*cdp+));
ac0 = ac0-(*(ar4-t1)*coef(*cdp+)),
ac1 = ac1+(*(ar3-t1)*coef(*cdp+));
ac2=ac0*ac0;
ac2=ac2+(ac1*ac1);
macro_en2log ac2, t2; ; [5]
*ar2+ = ac2;
} ; [(DFT_SZ*2+8)*4]
;
; -- sort hi frequencies ---
;
mar (ar2 - #4)
|| t2 = #0
ac3 = #0;
|| brc0 = #(4-2);
ac0 = *ar2+
|| localrepeat {
ac1 = *ar2+ || ac3 = ac3 + #1;
ac0 = max (ac1, ac0) ; carry = 0 if ac1>ac0
if (!CARRY) execute(D_unit) ;
|| t2 = ac3
}
;
; t3 = ac0 = max of all freqs
; t2 = max idx
*ar1(#(DTMF_tSc.sHiFreqNo)) = t2;
t3 = ac0;
;
|| mar (ar2 - #4);
ac0 = #-32767;
brc0 = #(4-1);
.if 0 ; REPEAT CORRECTION OF 2002/11/20 for hi band
localrepeat {
ac1 = *ar2+ - t3;
|| bit(st0, #ST0_CARRY) = #1;
if(ac1 != #0) execute(D_unit)
|| ac0 = max(ac1, ac0); ; carry = 0 if ac1>ac0
if(!CARRY) execute(D_unit)
|| ac2 = ac0;
}
ac2 = ac2 + t3;
.else
localrepeat {
ac1 = *ar2+;
|| bit(st0, #ST0_CARRY) = #1;
if(t2 != #0) execute(D_unit)
|| ac0 = max(ac1, ac0); ; carry = 0 if ac1>ac0
if(!CARRY) execute(D_unit)
|| ac2 = ac0;
t2 = t2 - #1;
}
t2 = t2 + #4;
.endif
*ar1(#(DTMF_tSc.sHiNextEn)) = ac2;
;
; -- hi band dft for deviations
;
; cdp = filterbank
; t0 = 2
; ac2 = energy, both lin and log
;
xar2 = #__apsHiDev;
mar (ar2+t2);
mar (ar2+t2); ; long (2 w) storage for
; large data mem model
xcdp = dbl(*ar2);
brc0 = #(4-1)
xar2 = mar(*ar1(#(DTMF_tSc.asHiDevEn)));
localrepeat {
ac0 = *(ar3+t0) * coef( *cdp+),
ac1 = *(ar4+t0) * coef(*cdp+);
|| repeat(#(DTMF_HI_DFT_SZ-3))
ac0=ac0+(*(ar3+t0)*coef(*cdp+)),
ac1=ac1+(*(ar4+t0)*coef(*cdp+));
ac0 = ac0+(*(ar3-t1)*coef(*cdp+)),
ac1 = ac1+(*(ar4-t1)*coef(*cdp+));
|| repeat(#(DTMF_HI_DFT_SZ-2))
ac0 = ac0-(*(ar4+t0)*coef(*cdp+)),
ac1 = ac1+(*(ar3+t0)*coef(*cdp+));
ac0 = ac0-(*(ar4-t1)*coef(*cdp+)),
ac1 = ac1+(*(ar3-t1)*coef(*cdp+));
ac2=ac0*ac0;
ac2=ac2+(ac1*ac1);
macro_en2log ac2, t2; ; [5]
*ar2+ = ac2;
} ; [(DFT_SZ*2+8)*4]
;
; --- get hi band frequency deviation
;
; ar2 = psDev
; ar3 = psDevFlt
;
t2 = *ar1(#(DTMF_tSc.sHiFreqNo))
mar (ar2 - #4); ; return ptr back
xar3 = #__aasHiDevFlt;
mar (ar3+t2);
mar (ar3+t2);
ac0 = *ar2(#3)
ac0 = ac0 - *ar2; /* offset 0 */
ac0 = ac0 + *ar2(#2)
ac0 = ac0 - *ar2(#1)
ac0 = ac0 << #16;
ac0 = *ar3+ * ac0;
ac1 = #(170*5) << #16;
ac0 = min(ac1, ac0);
ac1 = #(-170*5) << #16;
ac0 = max(ac1, ac0);
*ar1(#(DTMF_tSc.sHiFreqDev)) = HI(ac0);
ac0 = ac0*ac0;
ac1 = ac0;
ac1 = ac1 & #0xffff;
ac1 = ac1 << #16; unsigned
ac2 = ac1 * *ar3;
ac2 = ac2 << #-16
ac2 = ac2 + (ac0 * *ar3);
ac2 = ac2 + t3;
*ar1(#(DTMF_tSc.sHiMaxFreqEn)) = ac2;
;
; --- get new frame energy
;
.if (IDTMF_FR_SZ == 40)
xar2 = mar(*ar1(#(DTMF_tSc.as2kData)))
ac0 = *ar2 * *ar2+;
|| repeat (#(IDTMF_FR_SZ-2))
ac0 = ac0 + (*ar2 * *ar2+);
dbl(*ar1(#(DTMF_tSc.slFrameEn))) = ac0;
.else
xar2 = mar(*ar1(#(DTMF_tSc.as2kData)))
ac0 = *ar2 * *ar2+;
|| repeat (#(IDTMF_FR_SZ/2-2))
ac0 = ac0 + (*ar2 * *ar2+);
ac1 = *ar2 * *ar2+;
|| repeat (#(IDTMF_FR_SZ/2-2))
ac1 = ac1 + (*ar2 * *ar2+);
ac0 = ac0 << #-3;
ac1 = ac1 << #-3;
ac0 = ac0 + ac1;
macro_en2log ac0, t0
*ar1(#(DTMF_tSc.sFrameEn)) = ac0;
.endif
;
;*-------------------------------------------------------------------------*/
;
; ar4 = DTMF_tCfg *pCfg
; ar0 = DTMF_tDb *ar0,
; ar1 = DTMF_tSc *ar1
;
xar4 = dbl(*ar0(#(DTMF_tDb.pCfg)));
ac3 = #0;
;
; min energy thr
ac0 = *ar1(#(DTMF_tSc.sSumEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sMinEnThr));
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_MIN_EN;
;
; sum energy
.if (IDTMF_FR_SZ == 40)
ac0 = *ar0(#(DTMF_tDb.v.sZFrameEn));
.else
ac0 = *ar1(#(DTMF_tSc.sFrameEn));
.endif
ac0 = ac0 - *ar1(#(DTMF_tSc.sSumDialEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sSumEnThr));
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_SUM_EN;
;
; rising edge
.if (IDTMF_FR_SZ == 40)
ac0 = *ar0(#(DTMF_tDb.v.asSumEn));
ac1 = *ar0(#(DTMF_tDb.v.asSumEn+1));
ac0 = min(ac1, ac0);
ac1 = *ar0(#(DTMF_tDb.v.asSumEn+4));
ac2 = *ar0(#(DTMF_tDb.v.asSumEn+5));
ac1 = max(ac2, ac1);
ac0 = ac0 - ac1;
.else
ac0 = *ar0(#(DTMF_tDb.v.asSumEn));
ac0 = ac0 - *ar0(#(DTMF_tDb.v.asSumEn+2));
.endif
ac0 = ac0 - *ar4(#(DTMF_tCfg.sNoiseThr));
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_RS_EDGE;
;
; falling edge
ac0 = *ar0(#(DTMF_tDb.v.Stat.sEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sSumEn))
ac0 = ac0 - *ar4(#(DTMF_tCfg.sNoiseThr))
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_FL_EDGE;
;
; levels' stability
ac0 = *ar1(#(DTMF_tSc.sLoMaxFreqEn));
ac0 = ac0 - *ar0(#(DTMF_tDb.v.Stat.sLoEn))
ac0 = |ac0|;
ac0 = ac0 - *ar4(#(DTMF_tCfg.sVarThr))
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_STABLE;
;
ac0 = *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar0(#(DTMF_tDb.v.Stat.sHiEn))
ac0 = |ac0|;
ac0 = ac0 - *ar4(#(DTMF_tCfg.sVarThr))
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_STABLE;
;
; 2K bound
ac0 = *ar1(#(DTMF_tSc.s2kEnDlt));
ac0 = ac0 - *ar4(#(DTMF_tCfg.s2kUpThr))
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_2K_BOUND
;
; test that twists are ok
ac0 = *ar1(#(DTMF_tSc.sHiBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sLoBpEn));
ac1 = ac0 - *ar4(#(DTMF_tCfg.sFwdTwistThr))
ac1 = ac1 - #DTMF_FWD_TWIST_CORR;
if (ac1 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_FWD_TWIST;
ac1 = ac0 + *ar4(#(DTMF_tCfg.sRevTwistThr));
ac1 = ac1 - #DTMF_REV_TWIST_CORR;
if (ac1 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_REV_TWIST;
;
ac0 = *ar0(#(DTMF_tDb.v.sState));
ac0 = ac0 - #DTMF_ST_TONE;
if (ac0 >= #0 ) goto L1;
;
; DFT delay lines are not full. at least one frame less.
; we shall account for wider sinc mainlobe and lower energy.
; Noise does not have much influence on the parameters
; in this case, so the threshold are hard coded.
; tuning criteria was chosen the number of early-on hits
; on talk-off imunity test.
; varying those thrs shall affect early detection delay
; and talk-off immunity as well.
;
ac0 = *ar1(#(DTMF_tSc.sLoBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sLoMaxFreqEn));
ac0 = ac0 - #(6*DTMF_1DB);
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_LO_PART;
;
ac0 = *ar1(#(DTMF_tSc.sLoMaxFreqEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sLoNextEn));
ac0 = ac0 - #(5*DTMF_1DB);
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_LO_CLEAN;
;
.if (IDTMF_FR_SZ == 40)
ac0 = *ar1(#(DTMF_tSc.sHiBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - #(4*DTMF_1DB);
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_PART;
;
ac0 = *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiNextEn));
ac0 = ac0 - #(7*DTMF_1DB);
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_CLEAN;
;
.endif
goto L2
L1
;
ac0 = *ar1(#(DTMF_tSc.sLoBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sLoMaxFreqEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sPartThr))
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_LO_PART;
;
ac0 = *ar1(#(DTMF_tSc.sLoMaxFreqEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sLoNextEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sCleanThr));
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_LO_CLEAN;
;
.if (IDTMF_FR_SZ == 40)
ac0 = *ar1(#(DTMF_tSc.sHiBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sPartThr));
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_PART;
;
ac0 = *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiNextEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sCleanThr));
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_CLEAN;
.endif
;
L2
;
.if (IDTMF_FR_SZ == 80)
ac0 = *ar1(#(DTMF_tSc.sHiBpEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sPartThr));
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_PART;
;
ac0 = *ar1(#(DTMF_tSc.sHiMaxFreqEn));
ac0 = ac0 - *ar1(#(DTMF_tSc.sHiNextEn));
ac0 = ac0 - *ar4(#(DTMF_tCfg.sCleanThr));
if (ac0 < #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_CLEAN;
.endif
;
ac0 = *ar1(#(DTMF_tSc.sLoFreqDev));
ac0 = |ac0|;
ac0 = ac0 - *ar4(#(DTMF_tCfg.sMaxFreqDevThr));
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_LO_INRANGE;
;
ac0 = *ar1(#(DTMF_tSc.sHiFreqDev));
ac0 = |ac0|;
ac0 = ac0 - *ar4(#(DTMF_tCfg.sMaxFreqDevThr));
if (ac0 > #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_HI_INRANGE;
;
ac0 = *ar1(#(DTMF_tSc.sLoFreqNo));
ac0 = ac0 + (*ar1(#(DTMF_tSc.sHiFreqNo)) << #2);
*ar1(#(DTMF_tSc.sDigit)) = ac0;
;
ac0 = ac0 - *ar0(#(DTMF_tDb.v.sLastDigit));
if (ac0 != #0) execute (D_unit)
|| ac3 = ac3 | #DTMF_MASK_SAME_FRQ;
*ar1(#(DTMF_tSc.sTestFailed)) = ac3;
;
; --- move scratch to db ---
;
.if (IDTMF_FR_SZ == 40)
ac1 = dbl(*ar1(#(DTMF_tSc.slFrameEn)))
ac0 = ac1 + dbl(*ar0(#(DTMF_tDb.v.slFrameEn)));
ac0 = ac0 << #-3;
macro_en2log ac0, t0
*ar0(#(DTMF_tDb.v.sZFrameEn)) = ac0;
dbl(*ar0(#(DTMF_tDb.v.slFrameEn))) = ac1;
.else
.endif
xar2 = mar(*ar0(#(DTMF_tDb.as2kDataSav)))
xar3 = mar(*ar1(#(DTMF_tSc.as2kData+IDTMF_FR_SZ)))
repeat(#(DTMF_2KFLT_SZ-1))
*ar2+ = *ar3+;
;
xar3 = mar(*ar1(#(DTMF_tSc.asBpData+DTMF_BPFR_SZ)))
repeat (#(DTMF_BPFLT_SZ-1))
*ar2+ = *ar3+;
;
xar3 = mar(*ar1(#(DTMF_tSc.asLoData+DTMF_DFR_SZ*2)))
repeat (#(DTMF_LOSD_SZ-1))
*ar2+ = *ar3+;
;
.if (IDTMF_FR_SZ != 80)
xar3 = mar(*ar1(#(DTMF_tSc.asHiData+DTMF_DFR_SZ*2)))
repeat (#(DTMF_HISD_SZ-1))
*ar2+ = *ar3+;
.endif
;
; --- restore context ---
;
bit(ST2, #ST2_ARMS) = #1;
.arms_on
t3 = pop()
t2 = pop()
return
;-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -