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 @ -------------- 39 pWTVoice .req r0 40 pWTFrame .req r1 41 pOutputBuffer .req r2 42 numSamples .req r3 43 44 phaseIncrement .req r4 45 pPhaseAccum .req r5 46 phaseFrac .req r6 47 phaseFracMask .req r7 48 49 tmp0 .req r1 @ reuse register 50 tmp1 .req r8 51 tmp2 .req r9 52 53 54 @SaveRegs RLIST {r4-r9,lr} 55 @RestoreRegs RLIST {r4-r9,pc} 56 57 .func WT_InterpolateNoLoop 58 WT_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 74 InterpolationLoop: 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