156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * File:
456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * eas_wtengine.c
556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contents and purpose:
756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This file contains the critical synthesizer components that need to
856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * be optimized for best performance.
956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
1056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Copyright Sonic Network Inc. 2004-2005
117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project
127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * you may not use this file except in compliance with the License.
147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * You may obtain a copy of the License at
157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * See the License for the specific language governing permissions and
227df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * limitations under the License.
2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Revision Control:
2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Revision: 844 $
2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $
2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*------------------------------------
3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * includes
3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *------------------------------------
3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_types.h"
3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_math.h"
3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_audioconst.h"
3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_sndlib.h"
3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_wtengine.h"
4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_mixer.h"
4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * prototypes
4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_OPTIMIZED_MONO)
5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_FILTER_ENABLED)
5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_VoiceGain
6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Output gain for individual voice
6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pWTVoice) reserved for future use */
7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 *pMixBuffer;
7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_PCM *pInputBuffer;
7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 gain;
7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 gainIncrement;
8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp0;
8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp1;
8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp2;
8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 gainLeft, gainRight;
8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* initialize some local variables */
9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMixBuffer = pWTIntFrame->pMixBuffer;
9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pInputBuffer = pWTIntFrame->pAudioBuffer;
9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{703} <avoid multiply for performance>*/
9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (gainIncrement < 0)
9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainIncrement++;
9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{703} <avoid multiply for performance>*/
9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gain = pWTIntFrame->prevGain << 16;
10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gainLeft = pWTVoice->gainLeft;
10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gainRight = pWTVoice->gainRight;
10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (numSamples--) {
10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* incremental gain step to prevent zipper noise */
10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp0 = *pInputBuffer++;
11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gain += gainIncrement;
11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp2 = gain >> 16;
11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* scale sample by gain */
11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp2 *= tmp0;
11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* stereo output */
11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp2 = tmp2 >> 14;
12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* get the current sample in the final mix buffer */
12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 = *pMixBuffer;
12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* left channel */
12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp0 = tmp2 * gainLeft;
12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 += tmp0;
13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pMixBuffer++ = tmp1;
13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* get the current sample in the final mix buffer */
13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 = *pMixBuffer;
13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* right channel */
13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp0 = tmp2 * gainRight;
13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 += tmp0;
14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pMixBuffer++ = tmp1;
14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* mono output */
14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* get the current sample in the final mix buffer */
14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 = *pMixBuffer;
14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        tmp1 += tmp2;
15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pMixBuffer++ = tmp1;
15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifndef NATIVE_EAS_KERNEL
15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_Interpolate
16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Interpolation engine for wavetable synth
16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_PCM *pOutputBuffer;
17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseInc;
17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseFrac;
17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 acc0;
17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const EAS_SAMPLE *pSamples;
17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const EAS_SAMPLE *loopEnd;
17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 samp1;
18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 samp2;
18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* initialize some local variables */
18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pOutputBuffer = pWTIntFrame->pAudioBuffer;
18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{713} truncation is OK */
19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseFrac = pWTVoice->phaseFrac;
19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseInc = pWTIntFrame->frame.phaseIncrement;
19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* fetch adjacent samples */
19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_8_BIT_SAMPLES)
19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{701} <avoid multiply for performance>*/
19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp1 = pSamples[0] << 8;
19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{701} <avoid multiply for performance>*/
19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp2 = pSamples[1] << 8;
19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp1 = pSamples[0];
20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp2 = pSamples[1];
20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (numSamples--) {
20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* linear interpolation */
20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = samp2 - samp1;
20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = acc0 * phaseFrac;
20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* save new output sample in buffer */
21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* increment phase */
21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        phaseFrac += phaseInc;
21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* next sample */
22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (acc0 > 0) {
22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* advance sample pointer */
22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pSamples += acc0;
22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* check for loop end */
22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            acc0 = (EAS_I32) (pSamples - loopEnd);
23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (acc0 >= 0)
23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* fetch new samples */
23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_8_BIT_SAMPLES)
23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /*lint -e{701} <avoid multiply for performance>*/
23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp1 = pSamples[0] << 8;
23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /*lint -e{701} <avoid multiply for performance>*/
23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp2 = pSamples[1] << 8;
23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp1 = pSamples[0];
24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp2 = pSamples[1];
24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* save pointer and phase */
24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->phaseAccum = (EAS_U32) pSamples;
24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifndef NATIVE_EAS_KERNEL
25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_InterpolateNoLoop
25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Interpolation engine for wavetable synth
25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_PCM *pOutputBuffer;
26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseInc;
26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseFrac;
27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 acc0;
27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const EAS_SAMPLE *pSamples;
27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 samp1;
27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 samp2;
27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* initialize some local variables */
27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pOutputBuffer = pWTIntFrame->pAudioBuffer;
27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseInc = pWTIntFrame->frame.phaseIncrement;
28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* fetch adjacent samples */
28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_8_BIT_SAMPLES)
28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{701} <avoid multiply for performance>*/
28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp1 = pSamples[0] << 8;
28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{701} <avoid multiply for performance>*/
28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp2 = pSamples[1] << 8;
29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp1 = pSamples[0];
29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    samp2 = pSamples[1];
29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (numSamples--) {
29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* linear interpolation */
29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = samp2 - samp1;
30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = acc0 * phaseFrac;
30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* save new output sample in buffer */
30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* increment phase */
30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        phaseFrac += phaseInc;
31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{704} <avoid divide>*/
31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* next sample */
31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (acc0 > 0) {
31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* advance sample pointer */
31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pSamples += acc0;
31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* fetch new samples */
32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_8_BIT_SAMPLES)
32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /*lint -e{701} <avoid multiply for performance>*/
32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp1 = pSamples[0] << 8;
32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /*lint -e{701} <avoid multiply for performance>*/
32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp2 = pSamples[1] << 8;
32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp1 = pSamples[0];
32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samp2 = pSamples[1];
32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* save pointer and phase */
33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->phaseAccum = (EAS_U32) pSamples;
33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL)
34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_VoiceFilter
34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Implements a 2-pole filter
34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_PCM *pAudioBuffer;
35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 k;
35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 b1;
35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 b2;
35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 z1;
35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 z2;
36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 acc0;
36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 acc1;
36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* initialize some local variables */
36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pAudioBuffer = pWTIntFrame->pAudioBuffer;
36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    z1 = pFilter->z1;
36956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    z2 = pFilter->z2;
37056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    b1 = -pWTIntFrame->frame.b1;
37156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
37256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{702} <avoid divide> */
37356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    b2 = -pWTIntFrame->frame.b2 >> 1;
37456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
37556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{702} <avoid divide> */
37656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    k = pWTIntFrame->frame.k >> 1;
37756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
37856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (numSamples--)
37956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
38056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* do filter calculations */
38256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = *pAudioBuffer;
38356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc1 = z1 * b1;
38456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc1 += z2 * b2;
38556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        acc0 = acc1 + k * acc0;
38656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        z2 = z1;
38756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{702} <avoid divide> */
38956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        z1 = acc0 >> 14;
39056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pAudioBuffer++ = (EAS_I16) z1;
39156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
39256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
39356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* save delay values     */
39456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pFilter->z1 = (EAS_I16) z1;
39556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pFilter->z2 = (EAS_I16) z2;
39656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
39756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
39856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
39956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
40056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_NoiseGenerator
40156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
40256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
40356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Generate pseudo-white noise using PRNG and interpolation engine
40456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
40556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
40656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
40756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
40856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
40956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
41056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This output is scaled -12dB to prevent saturation in the filter. For a
41156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * high quality synthesizer, the output can be set to full scale, however
41256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * if the filter is used, it can overflow with certain coefficients. In this
41356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * case, either a saturation operation should take in the filter before
41456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * scaling back to 16 bits or the signal path should be increased to 18 bits
41556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * or more.
41656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
41756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
41856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
41956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks {
42056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_PCM *pOutputBuffer;
42156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseInc;
42256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp0;
42356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp1;
42456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 nInterpolatedSample;
42556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
42656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
42756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* initialize some local variables */
42856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
42956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pOutputBuffer = pWTIntFrame->pAudioBuffer;
43056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseInc = pWTIntFrame->frame.phaseIncrement;
43156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
43256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* get last two samples generated */
43356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{704} <avoid divide for performance>*/
43456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
43556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{704} <avoid divide for performance>*/
43656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
43756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
43856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* generate a buffer of noise */
43956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (numSamples--) {
44056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
44156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
44256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        *pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
44356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
44456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* update PRNG */
44556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->phaseFrac += (EAS_U32) phaseInc;
44656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (GET_PHASE_INT_PART(pWTVoice->phaseFrac))    {
44756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            tmp0 = tmp1;
44856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->phaseAccum = pWTVoice->loopEnd;
44956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
45056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
45156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
45256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
45356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
45456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
45556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
45656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
45756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifndef _OPTIMIZED_MONO
45856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
45956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_ProcessVoice
46056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
46156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
46256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This routine does the block processing for one voice. It is isolated
46356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * from the main synth code to allow for various implementation-specific
46456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * optimizations. It calls the interpolator, filter, and gain routines
46556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * appropriate for a particular configuration.
46656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
46756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
46856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
46956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
47056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
47156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
47256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
47356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
47456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
47556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
47656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
47756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* use noise generator */
47856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
47956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_NoiseGenerator(pWTVoice, pWTIntFrame);
48056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
48156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* generate interpolated samples for looped waves */
48256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else if (pWTVoice->loopStart != pWTVoice->loopEnd)
48356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_Interpolate(pWTVoice, pWTIntFrame);
48456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
48556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* generate interpolated samples for unlooped waves */
48656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
48756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
48856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
48956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
49056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
49156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
49256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pWTIntFrame->frame.k != 0)
49356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
49456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
49556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
49656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks//2 TEST NEW MIXER FUNCTION
49756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef UNIFIED_MIXER
49856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
49956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_I32 gainLeft, gainIncLeft;
50056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
50256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_I32 gainRight, gainIncRight;
50356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
50456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
50656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
50756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
50956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
51056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
51156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_MixStream(
51256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->pAudioBuffer,
51356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->pMixBuffer,
51456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->numSamples,
51556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainLeft,
51656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainRight,
51756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainIncLeft,
51856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainIncRight,
51956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            MIX_FLAGS_STEREO_OUTPUT);
52056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
52256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_MixStream(
52356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->pAudioBuffer,
52456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->pMixBuffer,
52556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTIntFrame->numSamples,
52656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainLeft,
52756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            0,
52856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            gainIncLeft,
52956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            0,
53056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            0);
53156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
53256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
53356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
53556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* apply gain, and left and right gain */
53656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_VoiceGain(pWTVoice, pWTIntFrame);
53756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
53856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
53956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
54056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
54156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL)
54256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
54356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_InterpolateMono
54456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
54556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
54656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * A C version of the sample interpolation + gain routine, optimized for mono.
54756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * It's not pretty, but it matches the assembly code exactly.
54856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
54956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
55056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
55156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
55256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
55356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
55456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
55556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
55656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
55756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
55856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 *pMixBuffer;
55956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const EAS_I8 *pLoopEnd;
56056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const EAS_I8 *pCurrentPhaseInt;
56156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
56256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 gain;
56356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 gainIncrement;
56456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 currentPhaseFrac;
56556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 phaseInc;
56656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp0;
56756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp1;
56856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 tmp2;
56956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I8 *pLoopStart;
57056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
57156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples = pWTIntFrame->numSamples;
57256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMixBuffer = pWTIntFrame->pMixBuffer;
57356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
57456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate gain increment */
57556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
57656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (gainIncrement < 0)
57756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        gainIncrement++;
57856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gain = pWTIntFrame->prevGain << 16;
57956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pCurrentPhaseInt = pWTVoice->pPhaseAccum;
58156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    currentPhaseFrac = pWTVoice->phaseFrac;
58256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    phaseInc = pWTIntFrame->phaseIncrement;
58356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pLoopStart = pWTVoice->pLoopStart;
58556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pLoopEnd = pWTVoice->pLoopEnd + 1;
58656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksInterpolationLoop:
58856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
58956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (tmp0 >= 0)
59056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pCurrentPhaseInt = pLoopStart + tmp0;
59156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
59256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp0 = *pCurrentPhaseInt;
59356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp1 = *(pCurrentPhaseInt + 1);
59456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
59556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp2 = phaseInc + currentPhaseFrac;
59656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
59756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp1 = tmp1 - tmp0;
59856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp1 = tmp1 * currentPhaseFrac;
59956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
60056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
60156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
60256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
60356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
60456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
60556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    gain += gainIncrement;
60656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
60756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
60856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp0 = *pMixBuffer;
60956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp2 = tmp1 * tmp2;
61056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp2 = (tmp2 >> 9);
61156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    tmp0 = tmp2 + tmp0;
61256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    *pMixBuffer++ = tmp0;
61356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
61456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    numSamples--;
61556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (numSamples)
61656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        goto InterpolationLoop;
61756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
61856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->pPhaseAccum = pCurrentPhaseInt;
61956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->phaseFrac = currentPhaseFrac;
62056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{702} <avoid divide>*/
62156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
62256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
62356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
62456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
62556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _OPTIMIZED_MONO
62656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
62756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_ProcessVoice
62856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
62956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
63056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This routine does the block processing for one voice. It is isolated
63156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * from the main synth code to allow for various implementation-specific
63256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * optimizations. It calls the interpolator, filter, and gain routines
63356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * appropriate for a particular configuration.
63456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
63556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
63656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
63756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
63856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
63956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
64056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This special version works handles an optimized mono-only signal
64156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * without filters
64256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
64356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
64456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
64556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
64656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
64756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* use noise generator */
64856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
64956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
65056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_NoiseGenerator(pWTVoice, pWTIntFrame);
65156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_VoiceGain(pWTVoice, pWTIntFrame);
65256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
65356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
65456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* or generate interpolated samples */
65556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
65656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
65756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_InterpolateMono(pWTVoice, pWTIntFrame);
65856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
65956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
66056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
66156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
662