1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
@***********************************************************
@ 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
|