@*********************************************************** @ Function: WT_VoiceFilter @ Processor: ARM @ Description: @ Implements a 2-pole low-pass filter with resonanance @ @ Usage: @ void WT_VoiceFilter( @ S_FILTER CONTROL *pFilter, @ S_WT_FRAME *pWTFrame); @ @ Copyright 2005 Sonic Network, Inc. @**************************************************************** @ Revision Control: @ $Revision: 496 $ @ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $ @**************************************************************** @ @ where: @ S_FILTER_CONTROL *pFilter @ PASSED IN: r0 @ @ S_WT_FRAME *pWTFrame @ PASSED IN: r1 @**************************************************************** .include "ARM_synth_constants_gnu.inc" .arm .text .global WT_VoiceFilter @ Register usage @ -------------- pFilter .req r0 pWTFrame .req r1 pBuffer .req r2 numSamples .req r3 z1 .req r4 z2 .req r5 b1 .req r6 b2 .req r7 K .req r8 tmp0 .req r1 @ reuse register tmp1 .req r9 tmp2 .req r10 @SaveRegs RLIST {r4-r10, lr} @RestoreRegs RLIST {r4-r10, pc} .func WT_VoiceFilter WT_VoiceFilter: STMFD sp!, {r4-r10, lr} @ @ Setup passed parameters in their destination registers @---------------------------------------------------------------- LDR pBuffer, [pWTFrame, #m_pAudioBuffer] LDR numSamples, [pWTFrame, #m_numSamples] @load state variables from pFilter structure LDRSH z1, [pFilter, #m_z1] LDRSH z2, [pFilter, #m_z2] @load coefficients from pWTFrame structure LDR K, [pWTFrame, #m_k] LDR b1, [pWTFrame, #m_b1] LDR b2, [pWTFrame, #m_b2] RSB b1, b1, #0 @ b1 = -b1 RSB b2, b2, #0 @ b2 = -b2 MOV b2, b2, ASR #1 @ b2 = b2 >> 1 MOV K, K, ASR #1 @ K = K >> 1 @ @ Start processing @---------------------------------------------------------------- LDRSH tmp0, [pBuffer] @ fetch sample FilterLoop: SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1 SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2) MOV z2, z1 @ delay line SMLABB tmp0, tmp0, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2) LDRSH tmp1, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample MOV z1, tmp0, ASR #14 @ shift result to low word STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1 SUBS numSamples, numSamples, #2 @ unroll loop once SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2) SMLABB tmp1, tmp1, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2) MOV z2, z1 @ delay line MOV z1, tmp1, ASR #14 @ shift result to low word LDRGTSH tmp0, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer BGT FilterLoop @ save z terms @---------------------------------------------------------------- STRH z1, [pFilter, #m_z1] STRH z2, [pFilter, #m_z2] @ Return to calling function @---------------------------------------------------------------- LDMFD sp!,{r4-r10, lr} BX lr .endfunc .end