1@***********************************************************
2@ Function:    WT_VoiceGain
3@ Processor:   ARM-E
4@ Description: the main synthesis function when fetching
5@			   wavetable samples.
6@              C-callable.
7@
8@ Usage:
9@ Usage:
10@	WT_VoiceGain(
11@			S_WT_VOICE *pWTVoice,
12@			S_WT_FRAME *pWTFrame);
13@
14@ Copyright 2004, 2005 Sonic Network, Inc.
15@****************************************************************
16@ Revision Control:
17@   $Revision: 814 $
18@   $Date: 2007-08-02 10:34:53 -0700 (Thu, 02 Aug 2007) $
19@****************************************************************
20@
21@   where:
22@	S_WT_VOICE *psVoice
23@	PASSED IN: r0
24@
25@	S_WT_FRAME *pWTFrame
26@	PASSED IN: r1
27@****************************************************************
28
29
30
31	#include	"ARM_synth_constants_gnu.inc"
32
33	.arm
34	.text
35
36	.global	WT_VoiceGain
37
38@ Register usage
39@ --------------
40pWTVoice	.req	r0
41pWTFrame	.req	r1
42pInputBuffer	.req	r2
43pMixBuffer	.req	r3
44
45tmp0	.req	r4
46tmp1	.req	r5
47tmp2	.req	r1	@ reuse register
48tmp3	.req	r6
49
50numSamples	.req	r9
51
52	#if	STEREO_OUTPUT
53gainIncLeft	.req	r7
54gainIncRight	.req	r8
55gainLeft	.req	r10
56gainRight	.req	r11
57	#else
58gainIncrement	.req	r7
59gain	.req	r8
60	#endif
61
62
63@ register context for local variables
64@SaveRegs	RLIST	{r4-r11,lr}
65@RestoreRegs	RLIST	{r4-r11,pc}
66
67WT_VoiceGain:
68
69	STMFD	sp!, {r4-r11,lr}
70
71	LDR		pInputBuffer, [pWTFrame, #m_pAudioBuffer]
72	LDR		pMixBuffer, [pWTFrame, #m_pMixBuffer]
73	LDR		numSamples, [pWTFrame, #m_numSamples]
74
75@----------------------------------------------------------------
76@ Stereo version
77@----------------------------------------------------------------
78@ NOTE: instructions are reordered to reduce the effect of latency
79@ due to storage and computational dependencies.
80@----------------------------------------------------------------
81
82	#if	STEREO_OUTPUT
83
84	LDR		tmp0, [pWTFrame, #m_prevGain]
85	LDR		tmp1, [pWTFrame, #m_gainTarget]
86
87	LDRSH	gainLeft, [pWTVoice, #m_gainLeft]
88	LDRSH	gainRight, [pWTVoice, #m_gainRight]
89
90	MOV		gainIncLeft, gainLeft
91	SMULBB	gainLeft, tmp0, gainLeft
92
93	SMULBB	gainIncLeft, tmp1, gainIncLeft
94	SUB		gainIncLeft, gainIncLeft, gainLeft
95	MOV		gainLeft, gainLeft, ASR #(NUM_MIXER_GUARD_BITS - 2)
96	MOV		gainIncLeft, gainIncLeft, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
97
98	MOV		gainIncRight, gainRight
99	SMULBB	gainRight, tmp0, gainRight
100
101	SMULBB	gainIncRight, tmp1, gainIncRight
102	SUB		gainIncRight, gainIncRight, gainRight
103	MOV		gainRight, gainRight, ASR #(NUM_MIXER_GUARD_BITS - 2)
104	MOV		gainIncRight, gainIncRight, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
105
106	LDRSH		tmp0, [pInputBuffer], #2
107
108StereoGainLoop:
109	LDR		tmp1, [pMixBuffer]
110
111	ADD		gainLeft, gainLeft, gainIncLeft
112
113	SMLAWB	tmp1, gainLeft, tmp0, tmp1
114
115	LDR		tmp2, [pMixBuffer, #4]
116
117	ADD		gainRight, gainRight, gainIncRight
118
119	STR		tmp1, [pMixBuffer], #4
120
121	SMLAWB	tmp2, gainRight, tmp0, tmp2
122
123	SUBS	numSamples, numSamples, #1
124
125	LDRGTSH	tmp0, [pInputBuffer], #2
126
127	STR		tmp2, [pMixBuffer], #4
128
129	BGT		StereoGainLoop
130
131@----------------------------------------------------------------
132@ Mono version
133@----------------------------------------------------------------
134	#else
135
136	LDR		gain, [pWTFrame, #m_prevGain]
137	MOV		gain, gain, LSL #(NUM_MIXER_GUARD_BITS + 4)
138	LDR		gainIncrement, [pWTFrame, #m_gainTarget]
139	MOV		gainIncrement, gainIncrement, LSL #(NUM_MIXER_GUARD_BITS + 4)
140	SUB		gainIncrement, gainIncrement, gain
141	MOV		gainIncrement, gainIncrement, ASR #SYNTH_UPDATE_PERIOD_IN_BITS
142
143MonoGainLoop:
144
145	LDRSH	tmp0, [pInputBuffer], #NEXT_OUTPUT_PCM	@ fetch voice output
146
147	LDR		tmp1, [pMixBuffer]						@ get left channel output sample
148	ADD		gain, gain, gainIncrement				@ gain step to eliminate zipper noise
149	SMULWB	tmp0, gain, tmp0 						@ sample * local gain
150
151	MOV		tmp0, tmp0, ASR #1						@ add 6dB headroom
152	ADD 	tmp1, tmp0, tmp1
153	STR		tmp1, [pMixBuffer], #4					@ save and bump pointer
154
155	SUBS	numSamples, numSamples, #1
156	BGT		MonoGainLoop
157
158	#endif	@end Mono version
159
160	LDMFD	sp!,{r4-r11,lr}
161	BX		lr
162
163	.end
164
165