156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * File:
456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * eas_wtsynth.c
556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contents and purpose:
756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Implements the synthesizer functions.
856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Copyright Sonic Network Inc. 2004
107df30109963092559d3760c0661a020f9daf1030The Android Open Source Project
117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * you may not use this file except in compliance with the License.
137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * You may obtain a copy of the License at
147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * See the License for the specific language governing permissions and
217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * limitations under the License.
2256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Revision Control:
2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Revision: 795 $
2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// includes
3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_data.h"
3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_report.h"
3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_host.h"
3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_math.h"
3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_synth_protos.h"
3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_wtsynth.h"
3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_pan.h"
3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_dlssynth.h"
4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _METRICS_ENABLED
4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_perf.h"
4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/* local prototypes */
4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT WT_Initialize(S_VOICE_MGR *pVoiceMgr);
4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents);
5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain);
5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv);
5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern EAS_BOOL WTE_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern EAS_BOOL WTE_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt);
6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _STATS
7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern double statsPhaseIncrement;
7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern double statsMaxPhaseIncrement;
7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern long statsPhaseSampleCount;
7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern double statsSampleSize;
7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern long statsSampleCount;
7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Synthesizer interface
7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksconst S_SYNTH_INTERFACE wtSynth =
8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_Initialize,
8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_StartVoice,
8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_UpdateVoice,
8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_ReleaseVoice,
8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_MuteVoice,
8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_SustainPedal,
9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_UpdateChannel
9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksconst S_FRAME_INTERFACE wtFrameInterface =
9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WTE_StartFrame,
9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WTE_EndFrame
9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_Initialize()
10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - pointer to voice to initialize
10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT WT_Initialize (S_VOICE_MGR *pVoiceMgr)
11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_INT i;
11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    for (i = 0; i < NUM_WT_VOICES; i++)
11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].artIndex = DEFAULT_ARTICULATION_INDEX;
12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg1State = DEFAULT_EG1_STATE;
12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg1Value = DEFAULT_EG1_VALUE;
12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg1Increment = DEFAULT_EG1_INCREMENT;
12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg2State = DEFAULT_EG2_STATE;
12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg2Value = DEFAULT_EG2_VALUE;
12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].eg2Increment = DEFAULT_EG2_INCREMENT;
12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* left and right gain values are needed only if stereo output */
13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].gainLeft = DEFAULT_VOICE_GAIN;
13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].gainRight = DEFAULT_VOICE_GAIN;
13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].phaseFrac = DEFAULT_PHASE_FRAC;
13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].phaseAccum = DEFAULT_PHASE_INT;
13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].filter.z1 = DEFAULT_FILTER_ZERO;
14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pVoiceMgr->wtVoices[i].filter.z2 = DEFAULT_FILTER_ZERO;
14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_TRUE;
14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_ReleaseVoice()
15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * The selected voice is being released.
15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to S_EAS_DATA
15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - pointer to voice to release
15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * None
16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pVoice) used in some implementations */
16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_VOICE *pWTVoice;
16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const S_ARTICULATION *pArticulation;
16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        DLS_ReleaseVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pArticulation = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* release EG1 */
18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1State = eEnvelopeStateRelease;
18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1Increment = pArticulation->eg1.releaseTime;
18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    The spec says we should release EG2, but doing so with the current
18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    voicing is causing clicks. This fix will need to be coordinated with
18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    a new sound library release
18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* release EG2 */
19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2State = eEnvelopeStateRelease;
19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2Increment = pArticulation->eg2.releaseTime;
19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_MuteVoice()
19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * The selected voice is being muted.
19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - pointer to voice to release
20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * None
20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pSynth) used in some implementations */
20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        DLS_MuteVoice(pVoiceMgr, pSynth, pVoice, voiceNum);
21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* clear deferred action flags */
22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->voiceFlags &=
22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        VOICE_FLAG_DEFER_MUTE);
22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* set the envelope state */
22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateMuted;
22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateMuted;
22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_SustainPedal()
23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * The selected voice is held due to sustain pedal
23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - pointer to voice to sustain
23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * None
24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pChannel) used in some implementations */
24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_VOICE *pWTVoice;
24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        DLS_SustainPedal(pVoiceMgr, pSynth, pVoice, pChannel, voiceNum);
25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* don't catch the voice if below the sustain level */
25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pWTVoice->eg1Value < pSynth->pEAS->pArticulations[pWTVoice->artIndex].eg1.sustainLevel)
25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* sustain flag is set, damper pedal is on */
26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* defer releasing this note until the damper pedal is off */
26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1State = eEnvelopeStateDecay;
26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->voiceState = eVoiceStatePlay;
26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    because sustain pedal is on, this voice
26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    should defer releasing its note
26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_SYNTH
27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_SustainPedal: defer note off because sustain pedal is on\n"); */ }
27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_StartVoice()
27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Assign the region for the given instrument using the midi key number
28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * and the RPN2 (coarse tuning) value. By using RPN2 as part of the
28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * region selection process, we reduce the amount a given sample has
28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * to be transposed by selecting the closest recorded root instead.
28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This routine is the second half of SynthAssignRegion().
28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * If the region was successfully found by SynthFindRegionIndex(),
28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * then assign the region's parameters to the voice.
28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Setup and initialize the following voice parameters:
29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * m_nRegionIndex
29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the voice we have assigned for this channel
29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nRegionIndex - index of the region
29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * success - could find and assign the region for this voice's note otherwise
30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * failure - could not find nor assign the region for this voice's note
30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * psSynthObject->m_sVoice[].m_nRegionIndex is assigned
30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * psSynthObject->m_sVoice[] parameters are assigned
30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT WT_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_VOICE *pWTVoice;
31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const S_WT_REGION *pRegion;
31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const S_ARTICULATION *pArt;
31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_SYNTH_CHANNEL *pChannel;
31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_INT pan;
31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_CONFIG wtConfig;
32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* no samples have been synthesized for this note yet */
32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->regionIndex = regionIndex;
32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* get the articulation index for this region */
32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel = &pSynth->channels[pVoice->channel & 15];
32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update static channel parameters */
33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return DLS_StartVoice(pVoiceMgr, pSynth, pVoice, voiceNum, regionIndex);
33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pRegion = &(pSynth->pEAS->pWTRegions[regionIndex]);
34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->artIndex = pRegion->artIndex;
34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_SYNTH
34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* MIDI note on puts this voice into attack state */
34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1State = eEnvelopeStateAttack;
35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1Value = 0;
35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1Increment = pArt->eg1.attackTime;
35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2State = eEnvelopeStateAttack;
35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2Value = 0;
35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2Increment = pArt->eg2.attackTime;
35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* init the LFO */
35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->modLFO.lfoValue = 0;
35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->modLFO.lfoPhase = -pArt->lfoDelay;
35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->gain = 0;
36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    Get the Midi CC10 pan value for this voice's channel
36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    convert the pan value to an "angle" representation suitable for
36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    our sin, cos calculator. This representation is NOT necessarily the same
36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    as the transform in the GM manuals because of our sin, cos calculator.
36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    "angle" = (CC10 - 64)/128
36956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
37056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pan = (EAS_INT) pSynth->channels[pVoice->channel & 15].pan - 64;
37156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pan += pArt->pan;
37256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_CalcPanControl(pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
37356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
37456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
37556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
37656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* clear out the filter states */
37756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->filter.z1 = 0;
37856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->filter.z2 = 0;
37956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
38056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* if this wave is to be generated using noise generator */
38256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pRegion->region.keyGroupAndFlags & REGION_FLAG_USE_WAVE_GENERATOR)
38356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
38456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->phaseAccum = 4574296;
38556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->loopStart = WT_NOISE_GENERATOR;
38656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->loopEnd = 4574295;
38756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
38856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* normal sample */
39056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
39156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
39256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
39356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
39456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (voiceNum < NUM_PRIMARY_VOICES)
39556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
39656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        else
39756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->phaseAccum = pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
39856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
39956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->phaseAccum = (EAS_U32) pSynth->pEAS->pSamples + pSynth->pEAS->pSampleOffsets[pRegion->waveIndex];
40056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
40156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
40256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pRegion->region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
40356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
40456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->loopStart = pWTVoice->phaseAccum + pRegion->loopStart;
40556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->loopEnd = pWTVoice->phaseAccum + pRegion->loopEnd - 1;
40656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
40756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        else
40856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pEAS->pSampleLen[pRegion->waveIndex] - 1;
40956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
41056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
41156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
41256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* configure off-chip voices */
41356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (voiceNum >= NUM_PRIMARY_VOICES)
41456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
41556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.phaseAccum = pWTVoice->phaseAccum;
41656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.loopStart = pWTVoice->loopStart;
41756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.loopEnd = pWTVoice->loopEnd;
41856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.gain = pVoice->gain;
41956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
42056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if (NUM_OUTPUT_CHANNELS == 2)
42156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.gainLeft = pWTVoice->gainLeft;
42256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        wtConfig.gainRight = pWTVoice->gainRight;
42356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
42456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
42556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WTE_ConfigVoice(voiceNum - NUM_PRIMARY_VOICES, &wtConfig, pVoiceMgr->pFrameBuffer);
42656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
42756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
42856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
42956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
43056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
43156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
43256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
43356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_CheckSampleEnd
43456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
43556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
43656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Check for end of sample and calculate number of samples to synthesize
43756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
43856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
43956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
44056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
44156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
44256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
44356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
44456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
44556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
44656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksEAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update)
44756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
44856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_U32 endPhaseAccum;
44956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_U32 endPhaseFrac;
45056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 numSamples;
45156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_BOOL done = EAS_FALSE;
45256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
45356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check to see if we hit the end of the waveform this time */
45456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{703} use shift for performance */
45556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    endPhaseFrac = pWTVoice->phaseFrac + (pWTIntFrame->frame.phaseIncrement << SYNTH_UPDATE_PERIOD_IN_BITS);
45656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    endPhaseAccum = pWTVoice->phaseAccum + GET_PHASE_INT_PART(endPhaseFrac);
45756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (endPhaseAccum >= pWTVoice->loopEnd)
45856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
45956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* calculate how far current ptr is from end */
46056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        numSamples = (EAS_I32) (pWTVoice->loopEnd - pWTVoice->phaseAccum);
46156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
46256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* now account for the fractional portion */
46356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{703} use shift for performance */
46456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        numSamples = (EAS_I32) ((numSamples << NUM_PHASE_FRAC_BITS) - pWTVoice->phaseFrac);
46556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement);
46656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
46756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* sound will be done this frame */
46856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        done = EAS_TRUE;
46956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
47056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
47156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update data for off-chip synth */
47256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (update)
47356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
47456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->phaseFrac = endPhaseFrac;
47556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pWTVoice->phaseAccum = endPhaseAccum;
47656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
47756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
47856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return done;
47956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
48056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
48156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
48256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateVoice()
48356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
48456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
48556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Synthesize a block of samples for the given voice.
48656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Use linear interpolation.
48756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
48856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
48956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
49056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
49156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
49256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * number of samples actually written to buffer
49356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
49456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
49556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - samples are added to the presently free buffer
49656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
49756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
49856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
49956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_BOOL WT_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32  numSamples)
50056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
50156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_VOICE *pWTVoice;
50256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_WT_INT_FRAME intFrame;
50356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_SYNTH_CHANNEL *pChannel;
50456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const S_WT_REGION *pWTRegion;
50556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    const S_ARTICULATION *pArt;
50656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
50756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_BOOL done;
50856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef DLS_SYNTHESIZER
51056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pVoice->regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
51156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return DLS_UpdateVoice(pVoiceMgr, pSynth, pVoice, voiceNum, pMixBuffer, numSamples);
51256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
51356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
51456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* establish pointers to critical data */
51556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
51656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTRegion = &pSynth->pEAS->pWTRegions[pVoice->regionIndex & REGION_INDEX_MASK];
51756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pArt = &pSynth->pEAS->pArticulations[pWTVoice->artIndex];
51856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel = &pSynth->channels[pVoice->channel & 15];
51956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.prevGain = pVoice->gain;
52056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update the envelopes */
52256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_UpdateEG1(pWTVoice, &pArt->eg1);
52356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_UpdateEG2(pWTVoice, &pArt->eg2);
52456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update the LFO */
52656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_UpdateLFO(&pWTVoice->modLFO, pArt->lfoFreq);
52756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
52956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate filter if library uses filter */
53056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pSynth->pEAS->libAttr & LIB_FORMAT_FILTER_ENABLED)
53156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_UpdateFilter(pWTVoice, &intFrame, pArt);
53256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
53356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        intFrame.frame.k = 0;
53456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
53556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update the gain */
53756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.frame.gainTarget = WT_UpdateGain(pVoice, pWTVoice, pArt, pChannel, pWTRegion->gain);
53856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate base pitch*/
54056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = pChannel->staticPitch + pWTRegion->tuning;
54156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
54256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* include global transpose */
54356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
54456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp += pVoice->note * 100;
54556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
54656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp += (pVoice->note + pSynth->globalTranspose) * 100;
54756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.frame.phaseIncrement = WT_UpdatePhaseInc(pWTVoice, pArt, pChannel, temp);
54856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
54956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* call into engine to generate samples */
55056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
55156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.pMixBuffer = pMixBuffer;
55256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    intFrame.numSamples = numSamples;
55356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check for end of sample */
55556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
55656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        done = WT_CheckSampleEnd(pWTVoice, &intFrame, (EAS_BOOL) (voiceNum >= NUM_PRIMARY_VOICES));
55756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
55856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        done = EAS_FALSE;
55956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
56056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef EAS_SPLIT_WT_SYNTH
56156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (voiceNum < NUM_PRIMARY_VOICES)
56256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
56356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifndef _SPLIT_WT_TEST_HARNESS
56456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WT_ProcessVoice(pWTVoice, &intFrame);
56556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
56656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
56756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
56856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        WTE_ProcessVoice(voiceNum - NUM_PRIMARY_VOICES, &intFrame.frame, pVoiceMgr->pFrameBuffer);
56956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
57056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_ProcessVoice(pWTVoice, &intFrame);
57156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
57256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
57356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* clear flag */
57456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
57556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
57656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* if voice has finished, set flag for voice manager */
57756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
57856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        done = EAS_TRUE;
57956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* if the update interval has elapsed, then force the current gain to the next
58156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     * gain since we never actually reach the next gain when ramping -- we just get
58256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     * very close to the target gain.
58356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     */
58456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
58556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return done;
58756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
58856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
58956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
59056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdatePhaseInc()
59156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
59256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
59356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate the phase increment
59456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
59556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
59656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - pointer to the voice being updated
59756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * psRegion - pointer to the region
59856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * psArticulation - pointer to the articulation
59956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nChannelPitchForThisVoice - the portion of the pitch that is fixed for this
60056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *                  voice during the duration of this synthesis
60156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
60256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
60356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
60456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
60556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
60656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * set the phase increment for this voice
60756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
60856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
60956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_I32 WT_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
61056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
61156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
61256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
61356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*pitchCents due to CC1 = LFO * (CC1 / 128) * DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS */
61456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
61556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        ((pChannel->modWheel) << (NUM_EG1_FRAC_BITS -7)));
61656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
61756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* pitchCents due to channel pressure = LFO * (channel pressure / 128) * DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS */
61856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp += MULT_EG1_EG1(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
61956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks         ((pChannel->channelPressure) << (NUM_EG1_FRAC_BITS -7)));
62056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
62156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* now multiply the (channel pressure + CC1) pitch values by the LFO value */
62256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, temp);
62356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
62456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
62556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    add in the LFO pitch due to
62656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    channel pressure and CC1 along with
62756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    the LFO pitch, the EG2 pitch, and the
62856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    "static" pitch for this voice on this channel
62956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
63056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp += pitchCents +
63156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        (MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToPitch)) +
63256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        (MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToPitch));
63356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
63456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* convert from cents to linear phase increment */
63556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_Calculate2toX(temp);
63656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
63756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
63856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
63956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateChannel()
64056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
64156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
64256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate and assign static channel parameters
64356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * These values only need to be updated if one of the controller values
64456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * for this channel changes
64556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
64656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
64756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nChannel - channel to update
64856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
64956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
65056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
65156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
65256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
65356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - the given channel's static gain and static pitch are updated
65456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
65556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
65656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pVoiceMgr) reserved for future use */
65756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
65856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
65956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 staticGain;
66056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 pitchBend;
66156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    S_SYNTH_CHANNEL *pChannel;
66256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
66356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel = &pSynth->channels[channel];
66456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
66556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
66656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    nChannelGain = (CC7 * CC11)^2  * master volume
66756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    where CC7 == 100 by default, CC11 == 127, master volume == 32767
66856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
66956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    staticGain = MULT_EG1_EG1((pChannel->volume) << (NUM_EG1_FRAC_BITS - 7),
67056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        (pChannel->expression) << (NUM_EG1_FRAC_BITS - 7));
67156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
67256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* staticGain has to be squared */
67356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    staticGain = MULT_EG1_EG1(staticGain, staticGain);
67456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
67556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel->staticGain = (EAS_I16) MULT_EG1_EG1(staticGain, pSynth->masterVolume);
67656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
67756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
67856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    calculate pitch bend: RPN0 * ((2*pitch wheel)/16384  -1)
67956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    However, if we use the EG1 macros, remember that EG1 has a full
68056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    scale value of 32768 (instead of 16384). So instead of multiplying
68156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    by 2, multiply by 4 (left shift by 2), and subtract by 32768 instead
68256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    of 16384. This utilizes the fact that the EG1 macro places a binary
68356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    point 15 places to the left instead of 14 places.
68456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
68556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{703} <avoid multiply for performance>*/
68656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pitchBend =
68756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        (((EAS_I32)(pChannel->pitchBend) << 2)
68856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        - 32768);
68956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
69056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel->staticPitch =
69156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        MULT_EG1_EG1(pitchBend, pChannel->pitchBendSensitivity);
69256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
69356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* if this is not a drum channel, then add in the per-channel tuning */
69456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
69556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pChannel->staticPitch += pChannel->finePitch + (pChannel->coarsePitch * 100);
69656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
69756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* clear update flag */
69856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
69956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return;
70056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
70156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
70256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
70356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateGain()
70456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
70556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
70656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate and assign static voice parameters as part of WT_UpdateVoice()
70756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
70856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
70956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the synth voice that we want to synthesize
71056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
71156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
71256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
71356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
71456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
71556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - various voice parameters are calculated and assigned
71656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
71756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
71856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
71956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_I32 WT_UpdateGain (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, const S_ARTICULATION *pArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain)
72056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
72156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 lfoGain;
72256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
72356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
72456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
72556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    If this voice was stolen, then the velocity is actually
72656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    for the new note, not the note that we are currently ramping down.
72756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    So we really shouldn't use this velocity. However, that would require
72856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    more memory to store the velocity value, and the improvement may
72956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    not be sufficient to warrant the added memory.
73056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
73156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* velocity is fixed at note start for a given voice and must be squared */
73256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = (pVoice->velocity) << (NUM_EG1_FRAC_BITS - 7);
73356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(temp, temp);
73456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
73556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* region gain is fixed as part of the articulation */
73656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(temp, gain);
73756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
73856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* include the channel gain */
73956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(temp, pChannel->staticGain);
74056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
74156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate LFO gain using an approximation for 10^x */
74256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    lfoGain = MULT_EG1_EG1(pWTVoice->modLFO.lfoValue, pArt->lfoToGain);
74356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    lfoGain = MULT_EG1_EG1(lfoGain, LFO_GAIN_TO_CENTS);
74456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
74556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* convert from a dB-like value to linear gain */
74656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    lfoGain = EAS_Calculate2toX(lfoGain);
74756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_EG1_EG1(temp, lfoGain);
74856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
74956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate the voice's gain */
75056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = (EAS_I16)MULT_EG1_EG1(temp, pWTVoice->eg1Value);
75156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
75256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return temp;
75356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
75456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
75556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
75656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateEG1()
75756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
75856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
75956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate the EG1 envelope for the given voice (but do not update any
76056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * state)
76156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
76256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
76356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the voice whose envelope we want to update
76456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nVoice - this voice's number - used only for debug
76556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
76656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
76756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
76856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nValue - the envelope value
76956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
77056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
77156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - updates EG1 state value for the given voice
77256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
77356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
77456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateEG1 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
77556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
77656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
77756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
77856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    switch (pWTVoice->eg1State)
77956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
78056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateAttack:
78156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = pWTVoice->eg1Value + pWTVoice->eg1Increment;
78256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
78356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* check if we have reached peak amplitude */
78456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
78556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
78656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* limit the volume */
78756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = SYNTH_FULL_SCALE_EG1_GAIN;
78856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
78956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* prepare to move to decay state */
79056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg1State = eEnvelopeStateDecay;
79156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg1Increment = pEnv->decayTime;
79256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
79356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
79456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
79556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
79656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* exponential decay */
79756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateDecay:
79856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
79956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
80056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* check if we have reached sustain level */
80156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp <= pEnv->sustainLevel)
80256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
80356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* enforce the sustain level */
80456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = pEnv->sustainLevel;
80556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
80656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* if sustain level is zero, skip sustain & release the voice */
80756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (temp > 0)
80856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    pWTVoice->eg1State = eEnvelopeStateSustain;
80956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
81056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* move to sustain state */
81156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                else
81256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    pWTVoice->eg1State = eEnvelopeStateMuted;
81356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
81456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
81556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
81656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
81756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateSustain:
81856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return;
81956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
82056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateRelease:
82156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = MULT_EG1_EG1(pWTVoice->eg1Value, pWTVoice->eg1Increment);
82256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
82356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* if we hit zero, this voice isn't contributing any audio */
82456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp <= 0)
82556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
82656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = 0;
82756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg1State = eEnvelopeStateMuted;
82856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
82956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
83056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
83156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* voice is muted, set target to zero */
83256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateMuted:
83356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = 0;
83456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
83556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
83656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateInvalid:
83756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        default:
83856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = 0;
83956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef  _DEBUG_SYNTH
84056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG1: error, %d is an unrecognized state\n",
84156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg1State); */ }
84256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
84356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
84456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
84556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
84656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
84756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg1Value = (EAS_I16) temp;
84856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
84956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
85056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
85156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateEG2()
85256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
85356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
85456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Update the EG2 envelope for the given voice
85556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
85656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
85756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the voice whose envelope we want to update
85856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
85956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
86056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
86156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
86256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
86356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - updates EG2 values for the given voice
86456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
86556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
86656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
86756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateEG2 (S_WT_VOICE *pWTVoice, const S_ENVELOPE *pEnv)
86856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
86956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
87056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
87156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    switch (pWTVoice->eg2State)
87256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
87356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateAttack:
87456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = pWTVoice->eg2Value + pWTVoice->eg2Increment;
87556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
87656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* check if we have reached peak amplitude */
87756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp >= SYNTH_FULL_SCALE_EG1_GAIN)
87856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
87956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* limit the volume */
88056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = SYNTH_FULL_SCALE_EG1_GAIN;
88156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
88256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* prepare to move to decay state */
88356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg2State = eEnvelopeStateDecay;
88456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
88556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg2Increment = pEnv->decayTime;
88656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
88756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
88856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
88956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
89056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* implement linear pitch decay in cents */
89156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateDecay:
89256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = pWTVoice->eg2Value -pWTVoice->eg2Increment;
89356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
89456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* check if we have reached sustain level */
89556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp <= pEnv->sustainLevel)
89656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
89756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* enforce the sustain level */
89856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = pEnv->sustainLevel;
89956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
90056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* prepare to move to sustain state */
90156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg2State = eEnvelopeStateSustain;
90256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
90356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
90456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
90556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateSustain:
90656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return;
90756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
90856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateRelease:
90956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = pWTVoice->eg2Value - pWTVoice->eg2Increment;
91056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
91156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (temp <= 0)
91256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
91356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                temp = 0;
91456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg2State = eEnvelopeStateMuted;
91556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
91656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
91756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
91856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
91956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* voice is muted, set target to zero */
92056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateMuted:
92156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = 0;
92256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
92356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
92456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eEnvelopeStateInvalid:
92556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        default:
92656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = 0;
92756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef  _DEBUG_SYNTH
92856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WT_UpdateEG2: error, %d is an unrecognized state\n",
92956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pWTVoice->eg2State); */ }
93056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
93156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
93256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
93356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
93456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pWTVoice->eg2Value = (EAS_I16) temp;
93556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
93656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
93756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
93856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateLFO ()
93956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
94056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
94156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate the LFO for the given voice
94256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
94356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
94456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pLFO         - ptr to the LFO data
94556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * phaseInc     - phase increment
94656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
94756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
94856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
94956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
95056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - updates LFO values for the given voice
95156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
95256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
95356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc)
95456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
95556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
95656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* To save memory, if m_nPhaseValue is negative, we are in the
95756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     * delay phase, and m_nPhaseValue represents the time left
95856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     * in the delay.
95956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     */
96056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     if (pLFO->lfoPhase < 0)
96156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     {
96256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pLFO->lfoPhase++;
96356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
96456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks     }
96556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
96656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate LFO output from phase value */
96756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{701} Use shift for performance */
96856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pLFO->lfoValue = (EAS_I16) (pLFO->lfoPhase << 2);
96956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{502} <shortcut to turn sawtooth into triangle wave> */
97056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if ((pLFO->lfoPhase > 0x1fff) && (pLFO->lfoPhase < 0x6000))
97156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pLFO->lfoValue = ~pLFO->lfoValue;
97256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
97356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* update LFO phase */
97456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pLFO->lfoPhase = (pLFO->lfoPhase + phaseInc) & 0x7fff;
97556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
97656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
97756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _FILTER_ENABLED
97856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
97956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_UpdateFilter()
98056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
98156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
98256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Update the Filter parameters
98356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
98456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
98556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the voice whose filter we want to update
98656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
98756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
98856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
98956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
99056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
99156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - updates Filter values for the given voice
99256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
99356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
99456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void WT_UpdateFilter (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, const S_ARTICULATION *pArt)
99556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
99656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 cutoff;
99756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
99856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* no need to calculate filter coefficients if it is bypassed */
99956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pArt->filterCutoff == DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY)
100056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
100156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pIntFrame->frame.k = 0;
100256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
100356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
100456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
100556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* determine the dynamic cutoff frequency */
100656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    cutoff = MULT_EG1_EG1(pWTVoice->eg2Value, pArt->eg2ToFc);
100756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    cutoff += pArt->filterCutoff;
100856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
100956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* subtract the A5 offset and the sampling frequency */
101056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
101156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
101256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* limit the cutoff frequency */
101356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
101456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
101556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
101656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
101756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
101856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    WT_SetFilterCoeffs(pIntFrame, cutoff, pArt->filterQ);
101956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
102056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
102156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
102256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
102356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
102456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * coef
102556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
102656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Table of filter coefficients for low-pass filter
102756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
102856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
102956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * polynomial coefficients are based on 8kHz sampling frequency
103056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * filter coef b2 = k2 = k2g0*k^0 + k2g1*k^1*(2^x) + k2g2*k^2*(2^x)
103156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
103256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *where k2g0, k2g1, k2g2 are from the truncated power series expansion on theta
103356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *(k*2^x = theta, but we incorporate the k along with the k2g0, k2g1, k2g2)
103456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *note: this is a power series in 2^x, not k*2^x
103556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *where k = (2*pi*440)/8kHz == convert octaves to radians
103656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
103756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  so actually, the following coefs listed as k2g0, k2g1, k2g2 are really
103856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  k2g0*k^0 = k2g0
103956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  k2g1*k^1
104056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  k2g2*k^2
104156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
104256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
104356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * filter coef n1 = numerator = n1g0*k^0 + n1g1*k^1*(2^x) + n1g2*k^2*(2^x) + n1g3*k^3*(2^x)
104456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
104556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *where n1g0, n1g1, n1g2, n1g3 are from the truncated power series expansion on theta
104656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *(k*2^x = theta, but we incorporate the k along with the n1g0, n1g1, n1g2, n2g3)
104756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *note: this is a power series in 2^x, not k*2^x
104856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *where k = (2*pi*440)/8kHz == convert octaves to radians
104956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *we also include the optimization factor of 0.81
105056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
105156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  so actually, the following coefs listed as n1g0, n1g1, n1g2, n2g3 are really
105256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  n1g0*k^0 = n1g0
105356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  n1g1*k^1
105456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  n1g2*k^2
105556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  n1g3*k^3
105656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
105756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *  NOTE that n1g0 == n1g1 == 0, always, so we only need to store n1g2 and n1g3
105856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
105956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
106056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
106156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 nk1g0 = -32768;
106256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 nk1g2 = 1580;
106356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 k2g0 = 32767;
106456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
106556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 k2g1[] =
106656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
106756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -11324, /* k2g1[0] = -0.3455751918948761 */
106856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -10387, /* k2g1[1] = -0.3169878073928751 */
106956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -9528,  /* k2g1[2] = -0.29076528753345476 */
107056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -8740,  /* k2g1[3] = -0.2667120011011279 */
107156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -8017,  /* k2g1[4] = -0.24464850028971705 */
107256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -7353,  /* k2g1[5] = -0.22441018194495696 */
107356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -6745,  /* k2g1[6] = -0.20584605955455101 */
107456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -6187,  /* k2g1[7] = -0.18881763682420102 */
107556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -5675,  /* k2g1[8] = -0.1731978744360067 */
107656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -5206,  /* k2g1[9] = -0.15887024228080968 */
107756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -4775,  /* k2g1[10] = -0.14572785009373057 */
107856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -4380,  /* k2g1[11] = -0.13367265000706827 */
107956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -4018,  /* k2g1[12] = -0.1226147050712642 */
108056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -3685,  /* k2g1[13] = -0.11247151828678581 */
108156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -3381,  /* k2g1[14] = -0.10316741714122014 */
108256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -3101,  /* k2g1[15] = -0.0946329890599603 */
108356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -2844,  /* k2g1[16] = -0.08680456355870586 */
108456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -2609,  /* k2g1[17] = -0.07962373723441349 */
108556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -2393,  /* k2g1[18] = -0.07303693805092666 */
108656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -2195,  /* k2g1[19] = -0.06699502566866912 */
108756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -2014,  /* k2g1[20] = -0.06145292483669077 */
108856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1847,  /* k2g1[21] = -0.056369289112013346 */
108956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1694,  /* k2g1[22] = -0.05170619239747895 */
109056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1554,  /* k2g1[23] = -0.04742884599684141 */
109156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1426,  /* k2g1[24] = -0.043505339076210514 */
109256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1308,  /* k2g1[25] = -0.03990640059558053 */
109356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1199,  /* k2g1[26] = -0.03660518093435039 */
109456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1100,  /* k2g1[27] = -0.03357705158166837 */
109556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -1009,  /* k2g1[28] = -0.030799421397205727 */
109656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -926,   /* k2g1[29] = -0.028251568071585884 */
109756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -849    /* k2g1[30] = -0.025914483529091967 */
109856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
109956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
110056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 k2g2[] =
110156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
110256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1957,   /* k2g2[0] = 0.059711106626580836 */
110356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1646,   /* k2g2[1] = 0.05024063501786333 */
110456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1385,   /* k2g2[2] = 0.042272226217199664 */
110556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1165,   /* k2g2[3] = 0.03556764576567844 */
110656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        981,    /* k2g2[4] = 0.029926444346999134 */
110756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        825,    /* k2g2[5] = 0.025179964880280382 */
110856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        694,    /* k2g2[6] = 0.02118630011706455 */
110956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        584,    /* k2g2[7] = 0.01782604998793514 */
111056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        491,    /* k2g2[8] = 0.014998751854573014 */
111156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        414,    /* k2g2[9] = 0.012619876941179595 */
111256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        348,    /* k2g2[10] = 0.010618303146468736 */
111356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        293,    /* k2g2[11] = 0.008934188679954682 */
111456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        246,    /* k2g2[12] = 0.007517182949855368 */
111556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        207,    /* k2g2[13] = 0.006324921212866403 */
111656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        174,    /* k2g2[14] = 0.005321757979794424 */
111756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        147,    /* k2g2[15] = 0.004477701309210577 */
111856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        123,    /* k2g2[16] = 0.00376751612730811 */
111956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        104,    /* k2g2[17] = 0.0031699697655869644 */
112056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        87,     /* k2g2[18] = 0.00266719715992703 */
112156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        74,     /* k2g2[19] = 0.0022441667321724647 */
112256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        62,     /* k2g2[20] = 0.0018882309854916855 */
112356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        52,     /* k2g2[21] = 0.0015887483774966232 */
112456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        44,     /* k2g2[22] = 0.0013367651661223448 */
112556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        37,     /* k2g2[23] = 0.0011247477162958733 */
112656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        31,     /* k2g2[24] = 0.0009463572640678758 */
112756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        26,     /* k2g2[25] = 0.0007962604042473498 */
112856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        22,     /* k2g2[26] = 0.0006699696356181593 */
112956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        18,     /* k2g2[27] = 0.0005637091964589207 */
113056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        16,     /* k2g2[28] = 0.00047430217920125243 */
113156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        13,     /* k2g2[29] = 0.00039907554925166274 */
113256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        11      /* k2g2[30] = 0.00033578022828973666 */
113356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
113456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
113556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 n1g2[] =
113656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
113756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        3170,   /* n1g2[0] = 0.0967319927350769 */
113856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        3036,   /* n1g2[1] = 0.0926446051254155 */
113956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2908,   /* n1g2[2] = 0.08872992911818503 */
114056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2785,   /* n1g2[3] = 0.08498066682523227 */
114156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2667,   /* n1g2[4] = 0.08138982872895201 */
114256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2554,   /* n1g2[5] = 0.07795072065216213 */
114356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2446,   /* n1g2[6] = 0.0746569312785634 */
114456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2343,   /* n1g2[7] = 0.07150232020051943 */
114556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2244,   /* n1g2[8] = 0.06848100647187474 */
114656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2149,   /* n1g2[9] = 0.06558735764447099 */
114756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        2058,   /* n1g2[10] = 0.06281597926792246 */
114856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1971,   /* n1g2[11] = 0.06016170483307614 */
114956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1888,   /* n1g2[12] = 0.05761958614040857 */
115056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1808,   /* n1g2[13] = 0.05518488407540374 */
115156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1732,   /* n1g2[14] = 0.052853059773715245 */
115256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1659,   /* n1g2[15] = 0.05061976615964251 */
115356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1589,   /* n1g2[16] = 0.04848083984214659 */
115456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1521,   /* n1g2[17] = 0.046432293353298 */
115556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1457,   /* n1g2[18] = 0.04447030771468711 */
115656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1396,   /* n1g2[19] = 0.04259122531793907 */
115756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1337,   /* n1g2[20] = 0.040791543106060944 */
115856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1280,   /* n1g2[21] = 0.03906790604290942 */
115956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1226,   /* n1g2[22] = 0.037417100858604564 */
116056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1174,   /* n1g2[23] = 0.035836050059229754 */
116156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1125,   /* n1g2[24] = 0.03432180618965023 */
116256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1077,   /* n1g2[25] = 0.03287154633875494 */
116356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        1032,   /* n1g2[26] = 0.03148256687687814 */
116456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        988,    /* n1g2[27] = 0.030152278415589925 */
116556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        946,    /* n1g2[28] = 0.028878200980459685 */
116656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        906,    /* n1g2[29] = 0.02765795938779331 */
116756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        868     /* n1g2[30] = 0.02648927881672521 */
116856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
116956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
117056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic const EAS_I16 n1g3[] =
117156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
117256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -548,   /* n1g3[0] = -0.016714088475899017 */
117356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -481,   /* n1g3[1] = -0.014683605122742116 */
117456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -423,   /* n1g3[2] = -0.012899791676436092 */
117556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -371,   /* n1g3[3] = -0.01133268185193299 */
117656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -326,   /* n1g3[4] = -0.00995594976868754 */
117756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -287,   /* n1g3[5] = -0.008746467702146129 */
117856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -252,   /* n1g3[6] = -0.00768391756106361 */
117956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -221,   /* n1g3[7] = -0.006750449563854721 */
118056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -194,   /* n1g3[8] = -0.005930382380083576 */
118156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -171,   /* n1g3[9] = -0.005209939699767622 */
118256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -150,   /* n1g3[10] = -0.004577018805123356 */
118356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -132,   /* n1g3[11] = -0.004020987256990177 */
118456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -116,   /* n1g3[12] = -0.003532504280467257 */
118556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -102,   /* n1g3[13] = -0.00310336384922047 */
118656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -89,    /* n1g3[14] = -0.002726356832432369 */
118756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -78,    /* n1g3[15] = -0.002395149888601605 */
118856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -69,    /* n1g3[16] = -0.0021041790717285314 */
118956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -61,    /* n1g3[17] = -0.0018485563625771063 */
119056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -53,    /* n1g3[18] = -0.001623987554831628 */
119156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -47,    /* n1g3[19] = -0.0014267001167177025 */
119256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -41,    /* n1g3[20] = -0.0012533798162347005 */
119356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -36,    /* n1g3[21] = -0.0011011150453668693 */
119456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -32,    /* n1g3[22] = -0.0009673479079754438 */
119556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -28,    /* n1g3[23] = -0.0008498312496971563 */
119656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -24,    /* n1g3[24] = -0.0007465909079943587 */
119756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -21,    /* n1g3[25] = -0.0006558925481952733 */
119856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -19,    /* n1g3[26] = -0.0005762125284029567 */
119956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -17,    /* n1g3[27] = -0.0005062123038325457 */
120056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -15,    /* n1g3[28] = -0.0004447159405951901 */
120156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -13,    /* n1g3[29] = -0.00039069036118270117 */
120256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        -11     /* n1g3[30] = -0.00034322798979677605 */
120356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
120456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
120556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
120656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * WT_SetFilterCoeffs()
120756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
120856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
120956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Update the Filter parameters
121056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
121156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
121256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pVoice - ptr to the voice whose filter we want to update
121356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData - pointer to overall EAS data structure
121456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
121556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
121656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
121756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
121856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * - updates Filter values for the given voice
121956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
122056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
122156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance)
122256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
122356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
122456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
122556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*
122656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    Convert the cutoff, which has had A5 subtracted, using the 2^x approx
122756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    Note, this cutoff is related to theta cutoff by
122856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    theta = k * 2^x
122956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    We use 2^x and incorporate k in the power series coefs instead
123056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    */
123156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    cutoff = EAS_Calculate2toX(cutoff);
123256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
123356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate b2 coef */
123456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = k2g1[resonance] + MULT_AUDIO_COEF(cutoff, k2g2[resonance]);
123556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = k2g0 + MULT_AUDIO_COEF(cutoff, temp);
123656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pIntFrame->frame.b2 = temp;
123756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
123856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate b1 coef */
123956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_AUDIO_COEF(cutoff, nk1g2);
124056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = nk1g0 + MULT_AUDIO_COEF(cutoff, temp);
124156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp += MULT_AUDIO_COEF(temp, pIntFrame->frame.b2);
124256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pIntFrame->frame.b1 = temp >> 1;
124356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
124456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* calculate K coef */
124556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = n1g2[resonance] + MULT_AUDIO_COEF(cutoff, n1g3[resonance]);
124656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_AUDIO_COEF(cutoff, temp);
124756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    temp = MULT_AUDIO_COEF(cutoff, temp);
124856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pIntFrame->frame.k = temp;
124956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
125056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
125156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
1252