Home | History | Annotate | Download | only in lib_src
      1 @***********************************************************
      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 
     28 	.include	"ARM_synth_constants_gnu.inc"
     29 
     30 	.arm
     31 	.text
     32 
     33 	.global	WT_Interpolate
     34 
     35 
     36 @ Register usage
     37 @ --------------
     38 pWTVoice	.req	r0
     39 pWTFrame	.req	r1
     40 
     41 numSamples	.req	r2
     42 phaseIncrement	.req	r3
     43 pOutputBuffer	.req	r4
     44 
     45 tmp0	.req	r1	@reuse register
     46 tmp1	.req	r5
     47 tmp2	.req	r6
     48 
     49 pLoopEnd	.req	r7
     50 pLoopStart	.req	r8
     51 
     52 pPhaseAccum	.req	r9
     53 phaseFrac	.req	r10
     54 phaseFracMask	.req	r11
     55 
     56 @SaveRegs	RLIST	{r4-r11,lr}
     57 @RestoreRegs	RLIST	{r4-r11,pc}
     58 
     59 	.func	WT_Interpolate
     60 WT_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 
     80 InterpolationLoop:
     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 
    132