summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k/lib_src/eas_wtengine.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-wt-22k/lib_src/eas_wtengine.c')
-rw-r--r--arm-wt-22k/lib_src/eas_wtengine.c661
1 files changed, 661 insertions, 0 deletions
diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c
new file mode 100644
index 0000000..dd46f22
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_wtengine.c
@@ -0,0 +1,661 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wtengine.c
+ *
+ * Contents and purpose:
+ * This file contains the critical synthesizer components that need to
+ * be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2004-2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 844 $
+ * $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_types.h"
+#include "eas_math.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_wtengine.h"
+#include "eas_mixer.h"
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+extern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+extern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+
+#if defined(_OPTIMIZED_MONO)
+extern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+#else
+extern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
+#endif
+
+#if defined(_FILTER_ENABLED)
+extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
+#endif
+
+#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_VoiceGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Output gain for individual voice
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pWTVoice) reserved for future use */
+void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pInputBuffer;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I32 numSamples;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainLeft, gainRight;
+#endif
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+ pInputBuffer = pWTIntFrame->pAudioBuffer;
+
+ /*lint -e{703} <avoid multiply for performance>*/
+ gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ /*lint -e{703} <avoid multiply for performance>*/
+ gain = pWTIntFrame->prevGain << 16;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainLeft = pWTVoice->gainLeft;
+ gainRight = pWTVoice->gainRight;
+#endif
+
+ while (numSamples--) {
+
+ /* incremental gain step to prevent zipper noise */
+ tmp0 = *pInputBuffer++;
+ gain += gainIncrement;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = gain >> 16;
+
+ /* scale sample by gain */
+ tmp2 *= tmp0;
+
+
+ /* stereo output */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> 14;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* left channel */
+ tmp0 = tmp2 * gainLeft;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+
+ /* right channel */
+ tmp0 = tmp2 * gainRight;
+ /*lint -e{704} <avoid divide>*/
+ tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
+ tmp1 += tmp0;
+ *pMixBuffer++ = tmp1;
+
+ /* mono output */
+#else
+
+ /* get the current sample in the final mix buffer */
+ tmp1 = *pMixBuffer;
+ /*lint -e{704} <avoid divide>*/
+ tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
+ tmp1 += tmp2;
+ *pMixBuffer++ = tmp1;
+#endif
+
+ }
+}
+#endif
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * WT_Interpolate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Interpolation engine for wavetable synth
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ const EAS_SAMPLE *loopEnd;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ /*lint -e{713} truncation is OK */
+ phaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* fetch adjacent samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* check for loop end */
+ acc0 = (EAS_I32) (pSamples - loopEnd);
+ if (acc0 >= 0)
+ pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
+
+ /* fetch new samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+}
+#endif
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * WT_InterpolateNoLoop
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Interpolation engine for wavetable synth
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 phaseFrac;
+ EAS_I32 acc0;
+ const EAS_SAMPLE *pSamples;
+ EAS_I32 samp1;
+ EAS_I32 samp2;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+ pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
+ phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
+
+ /* fetch adjacent samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+
+ while (numSamples--) {
+
+
+ /* linear interpolation */
+ acc0 = samp2 - samp1;
+ acc0 = acc0 * phaseFrac;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
+
+ /* save new output sample in buffer */
+ /*lint -e{704} <avoid divide>*/
+ *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
+
+ /* increment phase */
+ phaseFrac += phaseInc;
+ /*lint -e{704} <avoid divide>*/
+ acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
+
+ /* next sample */
+ if (acc0 > 0) {
+
+ /* advance sample pointer */
+ pSamples += acc0;
+ phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
+
+ /* fetch new samples */
+#if defined(_8_BIT_SAMPLES)
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp1 = pSamples[0] << 8;
+ /*lint -e{701} <avoid multiply for performance>*/
+ samp2 = pSamples[1] << 8;
+#else
+ samp1 = pSamples[0];
+ samp2 = pSamples[1];
+#endif
+ }
+ }
+
+ /* save pointer and phase */
+ pWTVoice->phaseAccum = (EAS_U32) pSamples;
+ pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
+}
+#endif
+
+#if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_VoiceFilter
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Implements a 2-pole filter
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_PCM *pAudioBuffer;
+ EAS_I32 k;
+ EAS_I32 b1;
+ EAS_I32 b2;
+ EAS_I32 z1;
+ EAS_I32 z2;
+ EAS_I32 acc0;
+ EAS_I32 acc1;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pAudioBuffer = pWTIntFrame->pAudioBuffer;
+
+ z1 = pFilter->z1;
+ z2 = pFilter->z2;
+ b1 = -pWTIntFrame->frame.b1;
+
+ /*lint -e{702} <avoid divide> */
+ b2 = -pWTIntFrame->frame.b2 >> 1;
+
+ /*lint -e{702} <avoid divide> */
+ k = pWTIntFrame->frame.k >> 1;
+
+ while (numSamples--)
+ {
+
+ /* do filter calculations */
+ acc0 = *pAudioBuffer;
+ acc1 = z1 * b1;
+ acc1 += z2 * b2;
+ acc0 = acc1 + k * acc0;
+ z2 = z1;
+
+ /*lint -e{702} <avoid divide> */
+ z1 = acc0 >> 14;
+ *pAudioBuffer++ = (EAS_I16) z1;
+ }
+
+ /* save delay values */
+ pFilter->z1 = (EAS_I16) z1;
+ pFilter->z2 = (EAS_I16) z2;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WT_NoiseGenerator
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Generate pseudo-white noise using PRNG and interpolation engine
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ * This output is scaled -12dB to prevent saturation in the filter. For a
+ * high quality synthesizer, the output can be set to full scale, however
+ * if the filter is used, it can overflow with certain coefficients. In this
+ * case, either a saturation operation should take in the filter before
+ * scaling back to 16 bits or the signal path should be increased to 18 bits
+ * or more.
+ *----------------------------------------------------------------------------
+*/
+ void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+ {
+ EAS_PCM *pOutputBuffer;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 nInterpolatedSample;
+ EAS_I32 numSamples;
+
+ /* initialize some local variables */
+ numSamples = pWTIntFrame->numSamples;
+ pOutputBuffer = pWTIntFrame->pAudioBuffer;
+ phaseInc = pWTIntFrame->frame.phaseIncrement;
+
+ /* get last two samples generated */
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
+ /*lint -e{704} <avoid divide for performance>*/
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+
+ /* generate a buffer of noise */
+ while (numSamples--) {
+ nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
+ nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
+ *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
+
+ /* update PRNG */
+ pWTVoice->phaseFrac += (EAS_U32) phaseInc;
+ if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
+ tmp0 = tmp1;
+ pWTVoice->phaseAccum = pWTVoice->loopEnd;
+ pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
+ tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
+ pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
+ }
+
+ }
+}
+
+#ifndef _OPTIMIZED_MONO
+/*----------------------------------------------------------------------------
+ * WT_ProcessVoice
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the block processing for one voice. It is isolated
+ * from the main synth code to allow for various implementation-specific
+ * optimizations. It calls the interpolator, filter, and gain routines
+ * appropriate for a particular configuration.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+
+ /* use noise generator */
+ if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
+
+ /* generate interpolated samples for looped waves */
+ else if (pWTVoice->loopStart != pWTVoice->loopEnd)
+ WT_Interpolate(pWTVoice, pWTIntFrame);
+
+ /* generate interpolated samples for unlooped waves */
+ else
+ {
+ WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
+ }
+
+#ifdef _FILTER_ENABLED
+ if (pWTIntFrame->frame.k != 0)
+ WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
+#endif
+
+//2 TEST NEW MIXER FUNCTION
+#ifdef UNIFIED_MIXER
+ {
+ EAS_I32 gainLeft, gainIncLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+ gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
+ gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
+ gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ gainRight,
+ gainIncLeft,
+ gainIncRight,
+ MIX_FLAGS_STEREO_OUTPUT);
+
+#else
+ EAS_MixStream(
+ pWTIntFrame->pAudioBuffer,
+ pWTIntFrame->pMixBuffer,
+ pWTIntFrame->numSamples,
+ gainLeft,
+ 0,
+ gainIncLeft,
+ 0,
+ 0);
+#endif
+ }
+
+#else
+ /* apply gain, and left and right gain */
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
+#endif
+}
+#endif
+
+#if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL)
+/*----------------------------------------------------------------------------
+ * WT_InterpolateMono
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * A C version of the sample interpolation + gain routine, optimized for mono.
+ * It's not pretty, but it matches the assembly code exactly.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+ EAS_I32 *pMixBuffer;
+ const EAS_I8 *pLoopEnd;
+ const EAS_I8 *pCurrentPhaseInt;
+ EAS_I32 numSamples;
+ EAS_I32 gain;
+ EAS_I32 gainIncrement;
+ EAS_I32 currentPhaseFrac;
+ EAS_I32 phaseInc;
+ EAS_I32 tmp0;
+ EAS_I32 tmp1;
+ EAS_I32 tmp2;
+ EAS_I8 *pLoopStart;
+
+ numSamples = pWTIntFrame->numSamples;
+ pMixBuffer = pWTIntFrame->pMixBuffer;
+
+ /* calculate gain increment */
+ gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
+ if (gainIncrement < 0)
+ gainIncrement++;
+ gain = pWTIntFrame->prevGain << 16;
+
+ pCurrentPhaseInt = pWTVoice->pPhaseAccum;
+ currentPhaseFrac = pWTVoice->phaseFrac;
+ phaseInc = pWTIntFrame->phaseIncrement;
+
+ pLoopStart = pWTVoice->pLoopStart;
+ pLoopEnd = pWTVoice->pLoopEnd + 1;
+
+InterpolationLoop:
+ tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
+ if (tmp0 >= 0)
+ pCurrentPhaseInt = pLoopStart + tmp0;
+
+ tmp0 = *pCurrentPhaseInt;
+ tmp1 = *(pCurrentPhaseInt + 1);
+
+ tmp2 = phaseInc + currentPhaseFrac;
+
+ tmp1 = tmp1 - tmp0;
+ tmp1 = tmp1 * currentPhaseFrac;
+
+ tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
+
+ pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
+ currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
+
+ gain += gainIncrement;
+ tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+
+ tmp0 = *pMixBuffer;
+ tmp2 = tmp1 * tmp2;
+ tmp2 = (tmp2 >> 9);
+ tmp0 = tmp2 + tmp0;
+ *pMixBuffer++ = tmp0;
+
+ numSamples--;
+ if (numSamples > 0)
+ goto InterpolationLoop;
+
+ pWTVoice->pPhaseAccum = pCurrentPhaseInt;
+ pWTVoice->phaseFrac = currentPhaseFrac;
+ /*lint -e{702} <avoid divide>*/
+ pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
+}
+#endif
+
+#ifdef _OPTIMIZED_MONO
+/*----------------------------------------------------------------------------
+ * WT_ProcessVoice
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the block processing for one voice. It is isolated
+ * from the main synth code to allow for various implementation-specific
+ * optimizations. It calls the interpolator, filter, and gain routines
+ * appropriate for a particular configuration.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ * This special version works handles an optimized mono-only signal
+ * without filters
+ *----------------------------------------------------------------------------
+*/
+void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
+{
+
+ /* use noise generator */
+ if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
+ {
+ WT_NoiseGenerator(pWTVoice, pWTIntFrame);
+ WT_VoiceGain(pWTVoice, pWTIntFrame);
+ }
+
+ /* or generate interpolated samples */
+ else
+ {
+ WT_InterpolateMono(pWTVoice, pWTIntFrame);
+ }
+}
+#endif
+