@*********************************************************** | |
@ 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 | |