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
67	.func	WT_VoiceGain
68WT_VoiceGain:
69
70	STMFD	sp!, {r4-r11,lr}
71
72	LDR		pInputBuffer, [pWTFrame, #m_pAudioBuffer]
73	LDR		pMixBuffer, [pWTFrame, #m_pMixBuffer]
74	LDR		numSamples, [pWTFrame, #m_numSamples]
75
76@----------------------------------------------------------------
77@ Stereo version
78@----------------------------------------------------------------
79@ NOTE: instructions are reordered to reduce the effect of latency
80@ due to storage and computational dependencies.
81@----------------------------------------------------------------
82
83	.if	STEREO_OUTPUT
84
85	LDR		tmp0, [pWTFrame, #m_prevGain]
86	LDR		tmp1, [pWTFrame, #m_gainTarget]
87
88	LDRSH	gainLeft, [pWTVoice, #m_gainLeft]
89	LDRSH	gainRight, [pWTVoice, #m_gainRight]
90
91	MOV		gainIncLeft, gainLeft
92	SMULBB	gainLeft, tmp0, gainLeft
93
94	SMULBB	gainIncLeft, tmp1, gainIncLeft
95	SUB		gainIncLeft, gainIncLeft, gainLeft
96	MOV		gainLeft, gainLeft, ASR #(NUM_MIXER_GUARD_BITS - 2)
97	MOV		gainIncLeft, gainIncLeft, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
98
99	MOV		gainIncRight, gainRight
100	SMULBB	gainRight, tmp0, gainRight
101
102	SMULBB	gainIncRight, tmp1, gainIncRight
103	SUB		gainIncRight, gainIncRight, gainRight
104	MOV		gainRight, gainRight, ASR #(NUM_MIXER_GUARD_BITS - 2)
105	MOV		gainIncRight, gainIncRight, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
106
107	LDRSH		tmp0, [pInputBuffer], #2
108
109StereoGainLoop:
110	LDR		tmp1, [pMixBuffer]
111
112	ADD		gainLeft, gainLeft, gainIncLeft
113
114	SMLAWB	tmp1, gainLeft, tmp0, tmp1
115
116	LDR		tmp2, [pMixBuffer, #4]
117
118	ADD		gainRight, gainRight, gainIncRight
119
120	STR		tmp1, [pMixBuffer], #4
121
122	SMLAWB	tmp2, gainRight, tmp0, tmp2
123
124	SUBS	numSamples, numSamples, #1
125
126	LDRGTSH	tmp0, [pInputBuffer], #2
127
128	STR		tmp2, [pMixBuffer], #4
129
130	BGT		StereoGainLoop
131
132@----------------------------------------------------------------
133@ Mono version
134@----------------------------------------------------------------
135	.else
136
137	LDR		gain, [pWTFrame, #m_prevGain]
138	MOV		gain, gain, LSL #(NUM_MIXER_GUARD_BITS + 4)
139	LDR		gainIncrement, [pWTFrame, #m_gainTarget]
140	MOV		gainIncrement, gainIncrement, LSL #(NUM_MIXER_GUARD_BITS + 4)
141	SUB		gainIncrement, gainIncrement, gain
142	MOV		gainIncrement, gainIncrement, ASR #SYNTH_UPDATE_PERIOD_IN_BITS
143
144MonoGainLoop:
145
146	LDRSH	tmp0, [pInputBuffer], #NEXT_OUTPUT_PCM	@ fetch voice output
147
148	LDR		tmp1, [pMixBuffer]						@ get left channel output sample
149	ADD		gain, gain, gainIncrement				@ gain step to eliminate zipper noise
150	SMULWB	tmp0, gain, tmp0 						@ sample * local gain
151
152	MOV		tmp0, tmp0, ASR #1						@ add 6dB headroom
153	ADD 	tmp1, tmp0, tmp1
154	STR		tmp1, [pMixBuffer], #4					@ save and bump pointer
155
156	SUBS	numSamples, numSamples, #1
157	BGT		MonoGainLoop
158
159	.endif	@end Mono version
160
161	LDMFD	sp!,{r4-r11,lr}
162	BX		lr
163
164	.endfunc
165	.end
166
167