summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k/lib_src/ARM-E_voice_gain_gnu.s
blob: 4517a3d5df89e73522eab54d703c9fd8e9e759c4 (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
@***********************************************************
@ Function:    WT_VoiceGain
@ Processor:   ARM-E
@ Description: the main synthesis function when fetching 
@			   wavetable samples.
@              C-callable.
@
@ Usage: 
@ Usage: 
@	WT_VoiceGain(
@			S_WT_VOICE *pWTVoice,
@			S_WT_FRAME *pWTFrame);
@
@ Copyright 2004, 2005 Sonic Network, Inc.
@****************************************************************
@ Revision Control:
@   $Revision: 814 $
@   $Date: 2007-08-02 10:34:53 -0700 (Thu, 02 Aug 2007) $
@****************************************************************
@
@   where:
@	S_WT_VOICE *psVoice
@	PASSED IN: r0
@
@	S_WT_FRAME *pWTFrame
@	PASSED IN: r1
@****************************************************************



	.include	"ARM_synth_constants_gnu.inc"

	.arm
	.text

	.global	WT_VoiceGain
	
@ Register usage
@ --------------
pWTVoice	.req	r0
pWTFrame	.req	r1
pInputBuffer	.req	r2
pMixBuffer	.req	r3

tmp0	.req	r4
tmp1	.req	r5
tmp2	.req	r1	@ reuse register
tmp3	.req	r6

numSamples	.req	r9

	.if	STEREO_OUTPUT
gainIncLeft	.req	r7
gainIncRight	.req	r8
gainLeft	.req	r10
gainRight	.req	r11
	.else
gainIncrement	.req	r7
gain	.req	r8
	.endif


@ register context for local variables
@SaveRegs	RLIST	{r4-r11,lr}
@RestoreRegs	RLIST	{r4-r11,pc}

	.func	WT_VoiceGain
WT_VoiceGain:

	STMFD	sp!, {r4-r11,lr}

	LDR		pInputBuffer, [pWTFrame, #m_pAudioBuffer]
	LDR		pMixBuffer, [pWTFrame, #m_pMixBuffer]
	LDR		numSamples, [pWTFrame, #m_numSamples]
	
@----------------------------------------------------------------
@ Stereo version
@----------------------------------------------------------------
@ NOTE: instructions are reordered to reduce the effect of latency 
@ due to storage and computational dependencies.
@----------------------------------------------------------------

	.if	STEREO_OUTPUT

	LDR		tmp0, [pWTFrame, #m_prevGain]
	LDR		tmp1, [pWTFrame, #m_gainTarget]
	
	LDRSH	gainLeft, [pWTVoice, #m_gainLeft]
	LDRSH	gainRight, [pWTVoice, #m_gainRight]
	
	MOV		gainIncLeft, gainLeft
	SMULBB	gainLeft, tmp0, gainLeft

	SMULBB	gainIncLeft, tmp1, gainIncLeft
	SUB		gainIncLeft, gainIncLeft, gainLeft
	MOV		gainLeft, gainLeft, ASR #(NUM_MIXER_GUARD_BITS - 2)
	MOV		gainIncLeft, gainIncLeft, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)

	MOV		gainIncRight, gainRight
	SMULBB	gainRight, tmp0, gainRight

	SMULBB	gainIncRight, tmp1, gainIncRight
	SUB		gainIncRight, gainIncRight, gainRight
	MOV		gainRight, gainRight, ASR #(NUM_MIXER_GUARD_BITS - 2)
	MOV		gainIncRight, gainIncRight, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)

	LDRSH		tmp0, [pInputBuffer], #2
	
StereoGainLoop:
	LDR		tmp1, [pMixBuffer]

	ADD		gainLeft, gainLeft, gainIncLeft

	SMLAWB	tmp1, gainLeft, tmp0, tmp1

	LDR		tmp2, [pMixBuffer, #4]

	ADD		gainRight, gainRight, gainIncRight

	STR		tmp1, [pMixBuffer], #4

	SMLAWB	tmp2, gainRight, tmp0, tmp2

	SUBS	numSamples, numSamples, #1

	LDRGTSH	tmp0, [pInputBuffer], #2
	
	STR		tmp2, [pMixBuffer], #4

	BGT		StereoGainLoop

@----------------------------------------------------------------
@ Mono version
@----------------------------------------------------------------
	.else

	LDR		gain, [pWTFrame, #m_prevGain]
	MOV		gain, gain, LSL #(NUM_MIXER_GUARD_BITS + 4)
	LDR		gainIncrement, [pWTFrame, #m_gainTarget]
	MOV		gainIncrement, gainIncrement, LSL #(NUM_MIXER_GUARD_BITS + 4)
	SUB		gainIncrement, gainIncrement, gain
	MOV		gainIncrement, gainIncrement, ASR #SYNTH_UPDATE_PERIOD_IN_BITS
	
MonoGainLoop:

	LDRSH	tmp0, [pInputBuffer], #NEXT_OUTPUT_PCM	@ fetch voice output
	
	LDR		tmp1, [pMixBuffer]						@ get left channel output sample
	ADD		gain, gain, gainIncrement				@ gain step to eliminate zipper noise
	SMULWB	tmp0, gain, tmp0 						@ sample * local gain

	MOV		tmp0, tmp0, ASR #1						@ add 6dB headroom
	ADD 	tmp1, tmp0, tmp1
	STR		tmp1, [pMixBuffer], #4					@ save and bump pointer
	
	SUBS	numSamples, numSamples, #1
	BGT		MonoGainLoop

	.endif	@end Mono version

	LDMFD	sp!,{r4-r11,lr}
	BX		lr
	
	.endfunc
	.end