1@*********************************************************** 2@ Function: WT_InterpolateNoLoop 3@ Processor: ARM-E 4@ Description: the main synthesis function when fetching 5@ wavetable samples. 6@ C-callable. 7@ 8@ Usage: 9@ void WT_InterpolateNoLoop( 10@ S_WT_VOICE *pWTVoice, 11@ S_WT_FRAME *pWTFrame); 12@ 13@ Copyright Sonic Network Inc. 2004 14@**************************************************************** 15@ Revision Control: 16@ $Revision: 496 $ 17@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $ 18@**************************************************************** 19@ 20@ where: 21@ S_WT_VOICE *pWTVoice 22@ PASSED IN: r0 23@ 24@ S_WT_FRAME *pWTFrame; 25@ PASSED IN: r1 26@**************************************************************** 27 28 #include "ARM_synth_constants_gnu.inc" 29 30 .arm 31 .text 32 33 34 .global WT_InterpolateNoLoop 35 36 37@ Register usage 38@ -------------- 39pWTVoice .req r0 40pWTFrame .req r1 41pOutputBuffer .req r2 42numSamples .req r3 43 44phaseIncrement .req r4 45pPhaseAccum .req r5 46phaseFrac .req r6 47phaseFracMask .req r7 48 49tmp0 .req r1 @ reuse register 50tmp1 .req r8 51tmp2 .req r9 52 53 54@SaveRegs RLIST {r4-r9,lr} 55@RestoreRegs RLIST {r4-r9,pc} 56 57 .func WT_InterpolateNoLoop 58WT_InterpolateNoLoop: 59 60 STMFD sp!, {r4-r9,lr} 61 62@ 63@ Fetch parameters from structures 64@---------------------------------------------------------------- 65 66 LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer] 67 LDR numSamples, [pWTFrame, #m_numSamples] 68 69 LDR phaseIncrement, [pWTFrame, #m_phaseIncrement] 70 LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum] 71 LDR phaseFrac, [pWTVoice, #m_phaseFrac] 72 LDR phaseFracMask,=PHASE_FRAC_MASK 73 74InterpolationLoop: 75 76 .ifdef SAMPLES_8_BIT 77 LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0 78 LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1 79 .else 80 LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0 81 LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1 82 .endif 83 84 ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall 85 86 SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0 87 SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2 88 89@ This section performs a gain adjustment of -12dB for 16-bit samples 90@ or +36dB for 8-bit samples. For a high quality synthesizer, the output 91@ can be set to full scale, however if the filter is used, it can overflow 92@ with certain coefficients and signal sources. In this case, either a 93@ saturation operation should take in the filter before scaling back to 94@ 16 bits or the signal path should be increased to 18 bits or more. 95 96 .ifdef SAMPLES_8_BIT 97 MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB 98 .else 99 MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB 100 .endif 101 102 ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6)) 103 @ = x0 + f * (x1 - x0) == interpolated result 104 105 STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result 106 107@ carry overflow from fraction to integer portion 108 ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT) 109 AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part 110 111 SUBS numSamples, numSamples, #1 112 BGT InterpolationLoop 113 114@ Clean up and store any changes that were caused during the loop 115@---------------------------------------------------------------- 116 117 @ update and store phase 118 STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum] 119 STR phaseFrac, [pWTVoice, #m_phaseFrac] 120 121@ 122@ Return to calling function 123@---------------------------------------------------------------- 124 125 LDMFD sp!,{r4-r9,lr} 126 BX lr 127 128 .endfunc 129 .end 130 131