blob: 2529e93441e116028b9e04e131d6bfe2bd13823b [file] [log] [blame]
The Android Open Source Project7df30102009-03-03 19:30:38 -08001@***********************************************************
2@ Function: WT_Interpolate
3@ Processor: ARM-E
4@ Description: the main synthesis function when fetching
5@ wavetable samples.
6@ C-callable.
7@
8@ Usage:
9@ void WT_Interpolate(
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
Dan Willemsencd673372016-09-21 15:32:16 -070028 #include "ARM_synth_constants_gnu.inc"
The Android Open Source Project7df30102009-03-03 19:30:38 -080029
30 .arm
31 .text
32
33 .global WT_Interpolate
34
35
36@ Register usage
37@ --------------
38pWTVoice .req r0
39pWTFrame .req r1
40
41numSamples .req r2
42phaseIncrement .req r3
43pOutputBuffer .req r4
44
45tmp0 .req r1 @reuse register
46tmp1 .req r5
47tmp2 .req r6
48
49pLoopEnd .req r7
50pLoopStart .req r8
51
52pPhaseAccum .req r9
53phaseFrac .req r10
54phaseFracMask .req r11
55
56@SaveRegs RLIST {r4-r11,lr}
57@RestoreRegs RLIST {r4-r11,pc}
58
59 .func WT_Interpolate
60WT_Interpolate:
61
62 STMFD sp!,{r4-r11,lr}
63
64@
65@ Fetch parameters from structures
66@----------------------------------------------------------------
67
68 LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer]
69 LDR numSamples, [pWTFrame, #m_numSamples]
70
71 LDR phaseIncrement, [pWTFrame, #m_phaseIncrement]
72 LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
73 LDR phaseFrac, [pWTVoice, #m_phaseFrac]
74 LDR phaseFracMask,=PHASE_FRAC_MASK
75
76 LDR pLoopStart, [pWTVoice, #m_pLoopStart]
77 LDR pLoopEnd, [pWTVoice, #m_pLoopEnd]
78 ADD pLoopEnd, pLoopEnd, #1 @ need loop end to equal last sample + 1
79
80InterpolationLoop:
81 SUBS tmp0, pPhaseAccum, pLoopEnd @ check for loop end
82 ADDGE pPhaseAccum, pLoopStart, tmp0 @ loop back to start
83
84 .ifdef SAMPLES_8_BIT
85 LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0
86 LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1
87 .else
88 LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0
89 LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1
90 .endif
91
92 ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall
93
94 SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0
95 SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2
96
97@ This section performs a gain adjustment of -12dB for 16-bit samples
98@ or +36dB for 8-bit samples. For a high quality synthesizer, the output
99@ can be set to full scale, however if the filter is used, it can overflow
100@ with certain coefficients and signal sources. In this case, either a
101@ saturation operation should take in the filter before scaling back to
102@ 16 bits or the signal path should be increased to 18 bits or more.
103
104 .ifdef SAMPLES_8_BIT
105 MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB
106 .else
107 MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB
108 .endif
109
110 ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6))
111 @ = x0 + f * (x1 - x0) == interpolated result
112
113 STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result
114
115@ carry overflow from fraction to integer portion
116 ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT)
117 AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part
118
119 SUBS numSamples, numSamples, #1
120 BGT InterpolationLoop
121
122@ update and store phase
123 STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
124 STR phaseFrac, [pWTVoice, #m_phaseFrac]
125
126 LDMFD sp!,{r4-r11,lr}
127 BX lr
128
129 .endfunc
130 .end
131