blob: 4517a3d5df89e73522eab54d703c9fd8e9e759c4 [file] [log] [blame]
@***********************************************************
@ 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