@*********************************************************** @ 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