xref: /aosp_15_r20/external/sonivox/arm-wt-22k/lib_src/eas_dlssynth.c (revision f81fb7c475c4b71ff83bdcc517de2a8c174e4e5c)
1*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2*f81fb7c4SAndroid Build Coastguard Worker  *
3*f81fb7c4SAndroid Build Coastguard Worker  * File:
4*f81fb7c4SAndroid Build Coastguard Worker  * eas_dlssynth.c
5*f81fb7c4SAndroid Build Coastguard Worker  *
6*f81fb7c4SAndroid Build Coastguard Worker  * Contents and purpose:
7*f81fb7c4SAndroid Build Coastguard Worker  * Implements the Mobile DLS synthesizer.
8*f81fb7c4SAndroid Build Coastguard Worker  *
9*f81fb7c4SAndroid Build Coastguard Worker  * Copyright Sonic Network Inc. 2006
10*f81fb7c4SAndroid Build Coastguard Worker 
11*f81fb7c4SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
12*f81fb7c4SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
13*f81fb7c4SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
14*f81fb7c4SAndroid Build Coastguard Worker  *
15*f81fb7c4SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
16*f81fb7c4SAndroid Build Coastguard Worker  *
17*f81fb7c4SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
18*f81fb7c4SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
19*f81fb7c4SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20*f81fb7c4SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
21*f81fb7c4SAndroid Build Coastguard Worker  * limitations under the License.
22*f81fb7c4SAndroid Build Coastguard Worker  *
23*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
24*f81fb7c4SAndroid Build Coastguard Worker  * Revision Control:
25*f81fb7c4SAndroid Build Coastguard Worker  *   $Revision: 795 $
26*f81fb7c4SAndroid Build Coastguard Worker  *   $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
27*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
28*f81fb7c4SAndroid Build Coastguard Worker */
29*f81fb7c4SAndroid Build Coastguard Worker 
30*f81fb7c4SAndroid Build Coastguard Worker // includes
31*f81fb7c4SAndroid Build Coastguard Worker #include "eas_data.h"
32*f81fb7c4SAndroid Build Coastguard Worker #include "eas_report.h"
33*f81fb7c4SAndroid Build Coastguard Worker #include "eas_host.h"
34*f81fb7c4SAndroid Build Coastguard Worker #include "eas_math.h"
35*f81fb7c4SAndroid Build Coastguard Worker #include "eas_synth_protos.h"
36*f81fb7c4SAndroid Build Coastguard Worker #include "eas_wtsynth.h"
37*f81fb7c4SAndroid Build Coastguard Worker #include "eas_pan.h"
38*f81fb7c4SAndroid Build Coastguard Worker #include "eas_mdls.h"
39*f81fb7c4SAndroid Build Coastguard Worker #include "eas_dlssynth.h"
40*f81fb7c4SAndroid Build Coastguard Worker 
41*f81fb7c4SAndroid Build Coastguard Worker #ifdef _METRICS_ENABLED
42*f81fb7c4SAndroid Build Coastguard Worker #include "eas_perf.h"
43*f81fb7c4SAndroid Build Coastguard Worker #endif
44*f81fb7c4SAndroid Build Coastguard Worker 
45*f81fb7c4SAndroid Build Coastguard Worker static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel,  const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState);
46*f81fb7c4SAndroid Build Coastguard Worker 
47*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
48*f81fb7c4SAndroid Build Coastguard Worker  * DLS_MuteVoice()
49*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
50*f81fb7c4SAndroid Build Coastguard Worker  * Mute the voice using shutdown time from the DLS articulation data
51*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
52*f81fb7c4SAndroid Build Coastguard Worker */
DLS_MuteVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice,EAS_I32 voiceNum)53*f81fb7c4SAndroid Build Coastguard Worker void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
54*f81fb7c4SAndroid Build Coastguard Worker {
55*f81fb7c4SAndroid Build Coastguard Worker     S_WT_VOICE *pWTVoice;
56*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_ARTICULATION *pDLSArt;
57*f81fb7c4SAndroid Build Coastguard Worker 
58*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
59*f81fb7c4SAndroid Build Coastguard Worker     pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
60*f81fb7c4SAndroid Build Coastguard Worker 
61*f81fb7c4SAndroid Build Coastguard Worker     /* clear deferred action flags */
62*f81fb7c4SAndroid Build Coastguard Worker     pVoice->voiceFlags &=
63*f81fb7c4SAndroid Build Coastguard Worker         ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
64*f81fb7c4SAndroid Build Coastguard Worker         VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
65*f81fb7c4SAndroid Build Coastguard Worker         VOICE_FLAG_DEFER_MUTE);
66*f81fb7c4SAndroid Build Coastguard Worker 
67*f81fb7c4SAndroid Build Coastguard Worker     /* set the envelope state */
68*f81fb7c4SAndroid Build Coastguard Worker     pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateRelease;
69*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg1Increment = pDLSArt->eg1ShutdownTime;
70*f81fb7c4SAndroid Build Coastguard Worker     pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateRelease;
71*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime;
72*f81fb7c4SAndroid Build Coastguard Worker }
73*f81fb7c4SAndroid Build Coastguard Worker 
74*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
75*f81fb7c4SAndroid Build Coastguard Worker  * DLS_ReleaseVoice()
76*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
77*f81fb7c4SAndroid Build Coastguard Worker  * Release the selected voice.
78*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
79*f81fb7c4SAndroid Build Coastguard Worker */
80*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pVoice) standard API, pVoice may be used by other synthesizers */
DLS_ReleaseVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice,EAS_I32 voiceNum)81*f81fb7c4SAndroid Build Coastguard Worker void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
82*f81fb7c4SAndroid Build Coastguard Worker {
83*f81fb7c4SAndroid Build Coastguard Worker     S_WT_VOICE *pWTVoice;
84*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_ARTICULATION *pDLSArt;
85*f81fb7c4SAndroid Build Coastguard Worker 
86*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
87*f81fb7c4SAndroid Build Coastguard Worker     pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
88*f81fb7c4SAndroid Build Coastguard Worker 
89*f81fb7c4SAndroid Build Coastguard Worker     /* if still in attack phase, convert units to log */
90*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{732} eg1Value is never negative */
91*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{703} use shift for performance */
92*f81fb7c4SAndroid Build Coastguard Worker     if (pWTVoice->eg1State == eEnvelopeStateAttack)
93*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048);
94*f81fb7c4SAndroid Build Coastguard Worker 
95*f81fb7c4SAndroid Build Coastguard Worker     /* release EG1 */
96*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg1State = eEnvelopeStateRelease;
97*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg1Increment = pDLSArt->eg1.releaseTime;
98*f81fb7c4SAndroid Build Coastguard Worker 
99*f81fb7c4SAndroid Build Coastguard Worker     /* release EG2 */
100*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg2State = eEnvelopeStateRelease;
101*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime;
102*f81fb7c4SAndroid Build Coastguard Worker }
103*f81fb7c4SAndroid Build Coastguard Worker 
104*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
105*f81fb7c4SAndroid Build Coastguard Worker  * DLS_SustainPedal()
106*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
107*f81fb7c4SAndroid Build Coastguard Worker  * The sustain pedal was just depressed. If the voice is still
108*f81fb7c4SAndroid Build Coastguard Worker  * above the sustain level, catch the voice and continue holding.
109*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
110*f81fb7c4SAndroid Build Coastguard Worker */
111*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pChannel) pChannel reserved for future use */
DLS_SustainPedal(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice,S_SYNTH_CHANNEL * pChannel,EAS_I32 voiceNum)112*f81fb7c4SAndroid Build Coastguard Worker void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
113*f81fb7c4SAndroid Build Coastguard Worker {
114*f81fb7c4SAndroid Build Coastguard Worker     S_WT_VOICE *pWTVoice;
115*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_ARTICULATION *pDLSArt;
116*f81fb7c4SAndroid Build Coastguard Worker 
117*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
118*f81fb7c4SAndroid Build Coastguard Worker     pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
119*f81fb7c4SAndroid Build Coastguard Worker 
120*f81fb7c4SAndroid Build Coastguard Worker     /* don't catch the voice if below the sustain level */
121*f81fb7c4SAndroid Build Coastguard Worker     if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel)
122*f81fb7c4SAndroid Build Coastguard Worker         return;
123*f81fb7c4SAndroid Build Coastguard Worker 
124*f81fb7c4SAndroid Build Coastguard Worker     /* defer releasing this note until the damper pedal is off */
125*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg1State = eEnvelopeStateDecay;
126*f81fb7c4SAndroid Build Coastguard Worker     pVoice->voiceState = eVoiceStatePlay;
127*f81fb7c4SAndroid Build Coastguard Worker     pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
128*f81fb7c4SAndroid Build Coastguard Worker 
129*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_SYNTH
130*f81fb7c4SAndroid Build Coastguard Worker     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_SustainPedal: defer note off because sustain pedal is on\n"); */ }
131*f81fb7c4SAndroid Build Coastguard Worker #endif
132*f81fb7c4SAndroid Build Coastguard Worker }
133*f81fb7c4SAndroid Build Coastguard Worker 
134*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
135*f81fb7c4SAndroid Build Coastguard Worker  * DLS_UpdatePhaseInc()
136*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
137*f81fb7c4SAndroid Build Coastguard Worker  * Calculate the oscillator phase increment for the next frame
138*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
139*f81fb7c4SAndroid Build Coastguard Worker */
DLS_UpdatePhaseInc(S_WT_VOICE * pWTVoice,const S_DLS_ARTICULATION * pDLSArt,S_SYNTH_CHANNEL * pChannel,EAS_I32 pitchCents)140*f81fb7c4SAndroid Build Coastguard Worker static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
141*f81fb7c4SAndroid Build Coastguard Worker {
142*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 temp;
143*f81fb7c4SAndroid Build Coastguard Worker 
144*f81fb7c4SAndroid Build Coastguard Worker     /* start with base mod LFO modulation */
145*f81fb7c4SAndroid Build Coastguard Worker     temp = pDLSArt->modLFOToPitch;
146*f81fb7c4SAndroid Build Coastguard Worker 
147*f81fb7c4SAndroid Build Coastguard Worker     /* add mod wheel effect */
148*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
149*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7);
150*f81fb7c4SAndroid Build Coastguard Worker 
151*f81fb7c4SAndroid Build Coastguard Worker     /* add channel pressure effect */
152*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
153*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7);
154*f81fb7c4SAndroid Build Coastguard Worker 
155*f81fb7c4SAndroid Build Coastguard Worker     /* add total mod LFO effect */
156*f81fb7c4SAndroid Build Coastguard Worker     pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
157*f81fb7c4SAndroid Build Coastguard Worker 
158*f81fb7c4SAndroid Build Coastguard Worker     /* start with base vib LFO modulation */
159*f81fb7c4SAndroid Build Coastguard Worker     temp = pDLSArt->vibLFOToPitch;
160*f81fb7c4SAndroid Build Coastguard Worker 
161*f81fb7c4SAndroid Build Coastguard Worker     /* add mod wheel effect */
162*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
163*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7);
164*f81fb7c4SAndroid Build Coastguard Worker 
165*f81fb7c4SAndroid Build Coastguard Worker     /* add channel pressure effect */
166*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
167*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7);
168*f81fb7c4SAndroid Build Coastguard Worker 
169*f81fb7c4SAndroid Build Coastguard Worker     /* add total vibrato LFO effect */
170*f81fb7c4SAndroid Build Coastguard Worker     pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue);
171*f81fb7c4SAndroid Build Coastguard Worker 
172*f81fb7c4SAndroid Build Coastguard Worker     /* add EG2 effect */
173*f81fb7c4SAndroid Build Coastguard Worker     pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value);
174*f81fb7c4SAndroid Build Coastguard Worker 
175*f81fb7c4SAndroid Build Coastguard Worker     /* convert from cents to linear phase increment */
176*f81fb7c4SAndroid Build Coastguard Worker     return EAS_Calculate2toX(pitchCents);
177*f81fb7c4SAndroid Build Coastguard Worker }
178*f81fb7c4SAndroid Build Coastguard Worker 
179*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
180*f81fb7c4SAndroid Build Coastguard Worker  * DLS_UpdateGain()
181*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
182*f81fb7c4SAndroid Build Coastguard Worker  * Calculate the gain for the next frame
183*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
184*f81fb7c4SAndroid Build Coastguard Worker */
DLS_UpdateGain(S_WT_VOICE * pWTVoice,const S_DLS_ARTICULATION * pDLSArt,S_SYNTH_CHANNEL * pChannel,EAS_I32 gain,EAS_U8 velocity)185*f81fb7c4SAndroid Build Coastguard Worker static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain, EAS_U8 velocity)
186*f81fb7c4SAndroid Build Coastguard Worker {
187*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 temp;
188*f81fb7c4SAndroid Build Coastguard Worker 
189*f81fb7c4SAndroid Build Coastguard Worker     /* start with base mod LFO modulation */
190*f81fb7c4SAndroid Build Coastguard Worker     temp = pDLSArt->modLFOToGain;
191*f81fb7c4SAndroid Build Coastguard Worker 
192*f81fb7c4SAndroid Build Coastguard Worker     /* add mod wheel effect */
193*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
194*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7);
195*f81fb7c4SAndroid Build Coastguard Worker 
196*f81fb7c4SAndroid Build Coastguard Worker     /* add channel pressure effect */
197*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
198*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7);
199*f81fb7c4SAndroid Build Coastguard Worker 
200*f81fb7c4SAndroid Build Coastguard Worker     /* add total mod LFO effect */
201*f81fb7c4SAndroid Build Coastguard Worker     gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
202*f81fb7c4SAndroid Build Coastguard Worker     if (gain > 0)
203*f81fb7c4SAndroid Build Coastguard Worker         gain = 0;
204*f81fb7c4SAndroid Build Coastguard Worker 
205*f81fb7c4SAndroid Build Coastguard Worker     /* convert to linear gain including EG1 */
206*f81fb7c4SAndroid Build Coastguard Worker     if (pWTVoice->eg1State != eEnvelopeStateAttack)
207*f81fb7c4SAndroid Build Coastguard Worker     {
208*f81fb7c4SAndroid Build Coastguard Worker         gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
209*f81fb7c4SAndroid Build Coastguard Worker         /*lint -e{702} use shift for performance */
210*f81fb7c4SAndroid Build Coastguard Worker #if 1
211*f81fb7c4SAndroid Build Coastguard Worker         gain += (pWTVoice->eg1Value - 32767) >> 1;
212*f81fb7c4SAndroid Build Coastguard Worker         gain = EAS_LogToLinear16(gain);
213*f81fb7c4SAndroid Build Coastguard Worker #else
214*f81fb7c4SAndroid Build Coastguard Worker         gain = EAS_LogToLinear16(gain);
215*f81fb7c4SAndroid Build Coastguard Worker         temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1);
216*f81fb7c4SAndroid Build Coastguard Worker         gain = FMUL_15x15(gain, temp);
217*f81fb7c4SAndroid Build Coastguard Worker #endif
218*f81fb7c4SAndroid Build Coastguard Worker     }
219*f81fb7c4SAndroid Build Coastguard Worker     else
220*f81fb7c4SAndroid Build Coastguard Worker     {
221*f81fb7c4SAndroid Build Coastguard Worker         gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
222*f81fb7c4SAndroid Build Coastguard Worker         gain = EAS_LogToLinear16(gain);
223*f81fb7c4SAndroid Build Coastguard Worker         gain = FMUL_15x15(gain, pWTVoice->eg1Value);
224*f81fb7c4SAndroid Build Coastguard Worker     }
225*f81fb7c4SAndroid Build Coastguard Worker 
226*f81fb7c4SAndroid Build Coastguard Worker     /* include MIDI channel gain */
227*f81fb7c4SAndroid Build Coastguard Worker     gain = FMUL_15x15(gain, pChannel->staticGain);
228*f81fb7c4SAndroid Build Coastguard Worker 
229*f81fb7c4SAndroid Build Coastguard Worker     /* include velocity */
230*f81fb7c4SAndroid Build Coastguard Worker     if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE)
231*f81fb7c4SAndroid Build Coastguard Worker     {
232*f81fb7c4SAndroid Build Coastguard Worker         temp = velocity << 8;
233*f81fb7c4SAndroid Build Coastguard Worker         temp = FMUL_15x15(temp, temp);
234*f81fb7c4SAndroid Build Coastguard Worker         gain = FMUL_15x15(gain, temp);
235*f81fb7c4SAndroid Build Coastguard Worker     }
236*f81fb7c4SAndroid Build Coastguard Worker 
237*f81fb7c4SAndroid Build Coastguard Worker     /* return gain */
238*f81fb7c4SAndroid Build Coastguard Worker     return gain;
239*f81fb7c4SAndroid Build Coastguard Worker }
240*f81fb7c4SAndroid Build Coastguard Worker 
241*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
242*f81fb7c4SAndroid Build Coastguard Worker  * DLS_UpdateFilter()
243*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
244*f81fb7c4SAndroid Build Coastguard Worker  * Update the Filter parameters
245*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
246*f81fb7c4SAndroid Build Coastguard Worker */
DLS_UpdateFilter(S_SYNTH_VOICE * pVoice,S_WT_VOICE * pWTVoice,S_WT_INT_FRAME * pIntFrame,S_SYNTH_CHANNEL * pChannel,const S_DLS_ARTICULATION * pDLSArt)247*f81fb7c4SAndroid Build Coastguard Worker static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, S_SYNTH_CHANNEL *pChannel, const S_DLS_ARTICULATION *pDLSArt)
248*f81fb7c4SAndroid Build Coastguard Worker {
249*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 cutoff;
250*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 temp;
251*f81fb7c4SAndroid Build Coastguard Worker 
252*f81fb7c4SAndroid Build Coastguard Worker     /* no need to calculate filter coefficients if it is bypassed */
253*f81fb7c4SAndroid Build Coastguard Worker     if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY)
254*f81fb7c4SAndroid Build Coastguard Worker     {
255*f81fb7c4SAndroid Build Coastguard Worker         pIntFrame->frame.k = 0;
256*f81fb7c4SAndroid Build Coastguard Worker         return;
257*f81fb7c4SAndroid Build Coastguard Worker     }
258*f81fb7c4SAndroid Build Coastguard Worker 
259*f81fb7c4SAndroid Build Coastguard Worker     /* start with base cutoff frequency */
260*f81fb7c4SAndroid Build Coastguard Worker     cutoff = pDLSArt->filterCutoff;
261*f81fb7c4SAndroid Build Coastguard Worker 
262*f81fb7c4SAndroid Build Coastguard Worker     /* get base mod LFO modulation */
263*f81fb7c4SAndroid Build Coastguard Worker     temp = pDLSArt->modLFOToFc;
264*f81fb7c4SAndroid Build Coastguard Worker 
265*f81fb7c4SAndroid Build Coastguard Worker     /* add mod wheel effect */
266*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
267*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7);
268*f81fb7c4SAndroid Build Coastguard Worker 
269*f81fb7c4SAndroid Build Coastguard Worker     /* add channel pressure effect */
270*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
271*f81fb7c4SAndroid Build Coastguard Worker     temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7);
272*f81fb7c4SAndroid Build Coastguard Worker 
273*f81fb7c4SAndroid Build Coastguard Worker     /* add total mod LFO effect */
274*f81fb7c4SAndroid Build Coastguard Worker     cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
275*f81fb7c4SAndroid Build Coastguard Worker 
276*f81fb7c4SAndroid Build Coastguard Worker     /* add EG2 effect */
277*f81fb7c4SAndroid Build Coastguard Worker     cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc);
278*f81fb7c4SAndroid Build Coastguard Worker 
279*f81fb7c4SAndroid Build Coastguard Worker     /* add velocity effect */
280*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
281*f81fb7c4SAndroid Build Coastguard Worker     cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7;
282*f81fb7c4SAndroid Build Coastguard Worker 
283*f81fb7c4SAndroid Build Coastguard Worker     /* add velocity effect */
284*f81fb7c4SAndroid Build Coastguard Worker     /*lint -e{702} use shift for performance */
285*f81fb7c4SAndroid Build Coastguard Worker     cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7;
286*f81fb7c4SAndroid Build Coastguard Worker 
287*f81fb7c4SAndroid Build Coastguard Worker     /* subtract the A5 offset and the sampling frequency */
288*f81fb7c4SAndroid Build Coastguard Worker     cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
289*f81fb7c4SAndroid Build Coastguard Worker 
290*f81fb7c4SAndroid Build Coastguard Worker     /* limit the cutoff frequency */
291*f81fb7c4SAndroid Build Coastguard Worker     if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
292*f81fb7c4SAndroid Build Coastguard Worker         cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
293*f81fb7c4SAndroid Build Coastguard Worker     else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
294*f81fb7c4SAndroid Build Coastguard Worker         cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
295*f81fb7c4SAndroid Build Coastguard Worker 
296*f81fb7c4SAndroid Build Coastguard Worker     WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK);
297*f81fb7c4SAndroid Build Coastguard Worker }
298*f81fb7c4SAndroid Build Coastguard Worker 
299*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
300*f81fb7c4SAndroid Build Coastguard Worker  * DLS_StartVoice()
301*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
302*f81fb7c4SAndroid Build Coastguard Worker  * Start up a DLS voice
303*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
304*f81fb7c4SAndroid Build Coastguard Worker */
DLS_StartVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice,EAS_I32 voiceNum,EAS_U16 regionIndex)305*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
306*f81fb7c4SAndroid Build Coastguard Worker {
307*f81fb7c4SAndroid Build Coastguard Worker     S_WT_VOICE *pWTVoice;
308*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_REGION *pDLSRegion;
309*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_ARTICULATION *pDLSArt;
310*f81fb7c4SAndroid Build Coastguard Worker     S_SYNTH_CHANNEL *pChannel;
311*f81fb7c4SAndroid Build Coastguard Worker 
312*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_SYNTH
313*f81fb7c4SAndroid Build Coastguard Worker     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
314*f81fb7c4SAndroid Build Coastguard Worker #endif
315*f81fb7c4SAndroid Build Coastguard Worker 
316*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
317*f81fb7c4SAndroid Build Coastguard Worker     pChannel = &pSynth->channels[pVoice->channel & 15];
318*f81fb7c4SAndroid Build Coastguard Worker     pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK];
319*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex;
320*f81fb7c4SAndroid Build Coastguard Worker     pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
321*f81fb7c4SAndroid Build Coastguard Worker 
322*f81fb7c4SAndroid Build Coastguard Worker     /* initialize the envelopes */
323*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg1State = eEnvelopeStateInit;
324*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
325*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->eg2State = eEnvelopeStateInit;
326*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
327*f81fb7c4SAndroid Build Coastguard Worker 
328*f81fb7c4SAndroid Build Coastguard Worker     /* initialize the LFOs */
329*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->modLFO.lfoValue = 0;
330*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay;
331*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->vibLFO.lfoValue = 0;
332*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay;
333*f81fb7c4SAndroid Build Coastguard Worker 
334*f81fb7c4SAndroid Build Coastguard Worker     /* initalize the envelopes and calculate initial gain */
335*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
336*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
337*f81fb7c4SAndroid Build Coastguard Worker     pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
338*f81fb7c4SAndroid Build Coastguard Worker 
339*f81fb7c4SAndroid Build Coastguard Worker #if (NUM_OUTPUT_CHANNELS == 2)
340*f81fb7c4SAndroid Build Coastguard Worker     EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
341*f81fb7c4SAndroid Build Coastguard Worker #endif
342*f81fb7c4SAndroid Build Coastguard Worker 
343*f81fb7c4SAndroid Build Coastguard Worker     /* initialize the filter states */
344*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->filter.z1 = 0;
345*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->filter.z2 = 0;
346*f81fb7c4SAndroid Build Coastguard Worker 
347*f81fb7c4SAndroid Build Coastguard Worker     /* initialize the oscillator */
348*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex];
349*f81fb7c4SAndroid Build Coastguard Worker     if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
350*f81fb7c4SAndroid Build Coastguard Worker     {
351*f81fb7c4SAndroid Build Coastguard Worker #if defined (_8_BIT_SAMPLES)
352*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart;
353*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1;
354*f81fb7c4SAndroid Build Coastguard Worker #else //_16_BIT_SAMPLES
355*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->loopStart = pWTVoice->phaseAccum + (pDLSRegion->wtRegion.loopStart<<1);
356*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->loopEnd = pWTVoice->phaseAccum + (pDLSRegion->wtRegion.loopEnd<<1) - 2;
357*f81fb7c4SAndroid Build Coastguard Worker #endif
358*f81fb7c4SAndroid Build Coastguard Worker     }
359*f81fb7c4SAndroid Build Coastguard Worker     else
360*f81fb7c4SAndroid Build Coastguard Worker     {
361*f81fb7c4SAndroid Build Coastguard Worker #if defined (_8_BIT_SAMPLES)
362*f81fb7c4SAndroid Build Coastguard Worker        pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum
363*f81fb7c4SAndroid Build Coastguard Worker                 + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1;
364*f81fb7c4SAndroid Build Coastguard Worker #else //_16_BIT_SAMPLES
365*f81fb7c4SAndroid Build Coastguard Worker         pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum
366*f81fb7c4SAndroid Build Coastguard Worker                 + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 2;
367*f81fb7c4SAndroid Build Coastguard Worker #endif
368*f81fb7c4SAndroid Build Coastguard Worker     }
369*f81fb7c4SAndroid Build Coastguard Worker 
370*f81fb7c4SAndroid Build Coastguard Worker     return EAS_SUCCESS;
371*f81fb7c4SAndroid Build Coastguard Worker }
372*f81fb7c4SAndroid Build Coastguard Worker 
373*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
374*f81fb7c4SAndroid Build Coastguard Worker  * DLS_UpdateVoice()
375*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
376*f81fb7c4SAndroid Build Coastguard Worker  * Purpose:
377*f81fb7c4SAndroid Build Coastguard Worker  * Synthesize a block of samples for the given voice.
378*f81fb7c4SAndroid Build Coastguard Worker  * Use linear interpolation.
379*f81fb7c4SAndroid Build Coastguard Worker  *
380*f81fb7c4SAndroid Build Coastguard Worker  * Inputs:
381*f81fb7c4SAndroid Build Coastguard Worker  * pEASData - pointer to overall EAS data structure
382*f81fb7c4SAndroid Build Coastguard Worker  *
383*f81fb7c4SAndroid Build Coastguard Worker  * Outputs:
384*f81fb7c4SAndroid Build Coastguard Worker  * number of samples actually written to buffer
385*f81fb7c4SAndroid Build Coastguard Worker  *
386*f81fb7c4SAndroid Build Coastguard Worker  * Side Effects:
387*f81fb7c4SAndroid Build Coastguard Worker  * - samples are added to the presently free buffer
388*f81fb7c4SAndroid Build Coastguard Worker  *
389*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
390*f81fb7c4SAndroid Build Coastguard Worker */
DLS_UpdateVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice,EAS_I32 voiceNum,EAS_I32 * pMixBuffer,EAS_I32 numSamples)391*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
392*f81fb7c4SAndroid Build Coastguard Worker {
393*f81fb7c4SAndroid Build Coastguard Worker     S_WT_VOICE *pWTVoice;
394*f81fb7c4SAndroid Build Coastguard Worker     S_SYNTH_CHANNEL *pChannel;
395*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_REGION *pDLSRegion;
396*f81fb7c4SAndroid Build Coastguard Worker     const S_DLS_ARTICULATION *pDLSArt;
397*f81fb7c4SAndroid Build Coastguard Worker     S_WT_INT_FRAME intFrame;
398*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 temp;
399*f81fb7c4SAndroid Build Coastguard Worker     EAS_BOOL done = EAS_FALSE;
400*f81fb7c4SAndroid Build Coastguard Worker 
401*f81fb7c4SAndroid Build Coastguard Worker     /* establish pointers to critical data */
402*f81fb7c4SAndroid Build Coastguard Worker     pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
403*f81fb7c4SAndroid Build Coastguard Worker     pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK];
404*f81fb7c4SAndroid Build Coastguard Worker     pChannel = &pSynth->channels[pVoice->channel & 15];
405*f81fb7c4SAndroid Build Coastguard Worker     pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
406*f81fb7c4SAndroid Build Coastguard Worker 
407*f81fb7c4SAndroid Build Coastguard Worker     /* update the envelopes */
408*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
409*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
410*f81fb7c4SAndroid Build Coastguard Worker 
411*f81fb7c4SAndroid Build Coastguard Worker     /* update the LFOs using the EAS synth function */
412*f81fb7c4SAndroid Build Coastguard Worker     WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq);
413*f81fb7c4SAndroid Build Coastguard Worker     WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq);
414*f81fb7c4SAndroid Build Coastguard Worker 
415*f81fb7c4SAndroid Build Coastguard Worker     /* calculate base frequency */
416*f81fb7c4SAndroid Build Coastguard Worker     temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning +
417*f81fb7c4SAndroid Build Coastguard Worker         (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7);
418*f81fb7c4SAndroid Build Coastguard Worker 
419*f81fb7c4SAndroid Build Coastguard Worker     /* don't transpose rhythm channel */
420*f81fb7c4SAndroid Build Coastguard Worker     if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0)
421*f81fb7c4SAndroid Build Coastguard Worker         temp += pSynth->globalTranspose * 100;
422*f81fb7c4SAndroid Build Coastguard Worker 
423*f81fb7c4SAndroid Build Coastguard Worker     /* calculate phase increment including modulation effects */
424*f81fb7c4SAndroid Build Coastguard Worker     intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp);
425*f81fb7c4SAndroid Build Coastguard Worker 
426*f81fb7c4SAndroid Build Coastguard Worker     /* calculate gain including modulation effects */
427*f81fb7c4SAndroid Build Coastguard Worker     intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
428*f81fb7c4SAndroid Build Coastguard Worker     intFrame.prevGain = pVoice->gain;
429*f81fb7c4SAndroid Build Coastguard Worker 
430*f81fb7c4SAndroid Build Coastguard Worker     DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt);
431*f81fb7c4SAndroid Build Coastguard Worker 
432*f81fb7c4SAndroid Build Coastguard Worker     /* call into engine to generate samples */
433*f81fb7c4SAndroid Build Coastguard Worker     intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
434*f81fb7c4SAndroid Build Coastguard Worker     intFrame.pMixBuffer = pMixBuffer;
435*f81fb7c4SAndroid Build Coastguard Worker     intFrame.numSamples = numSamples;
436*f81fb7c4SAndroid Build Coastguard Worker     if (numSamples < 0)
437*f81fb7c4SAndroid Build Coastguard Worker         return EAS_FALSE;
438*f81fb7c4SAndroid Build Coastguard Worker 
439*f81fb7c4SAndroid Build Coastguard Worker     /* check for end of sample */
440*f81fb7c4SAndroid Build Coastguard Worker     if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
441*f81fb7c4SAndroid Build Coastguard Worker         done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE);
442*f81fb7c4SAndroid Build Coastguard Worker 
443*f81fb7c4SAndroid Build Coastguard Worker     WT_ProcessVoice(pWTVoice, &intFrame);
444*f81fb7c4SAndroid Build Coastguard Worker 
445*f81fb7c4SAndroid Build Coastguard Worker     /* clear flag */
446*f81fb7c4SAndroid Build Coastguard Worker     pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
447*f81fb7c4SAndroid Build Coastguard Worker 
448*f81fb7c4SAndroid Build Coastguard Worker     /* if the update interval has elapsed, then force the current gain to the next
449*f81fb7c4SAndroid Build Coastguard Worker      * gain since we never actually reach the next gain when ramping -- we just get
450*f81fb7c4SAndroid Build Coastguard Worker      * very close to the target gain.
451*f81fb7c4SAndroid Build Coastguard Worker      */
452*f81fb7c4SAndroid Build Coastguard Worker     pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
453*f81fb7c4SAndroid Build Coastguard Worker 
454*f81fb7c4SAndroid Build Coastguard Worker     /* if voice has finished, set flag for voice manager */
455*f81fb7c4SAndroid Build Coastguard Worker     if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
456*f81fb7c4SAndroid Build Coastguard Worker         done = EAS_TRUE;
457*f81fb7c4SAndroid Build Coastguard Worker 
458*f81fb7c4SAndroid Build Coastguard Worker     return done;
459*f81fb7c4SAndroid Build Coastguard Worker }
460*f81fb7c4SAndroid Build Coastguard Worker 
461*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
462*f81fb7c4SAndroid Build Coastguard Worker  * DLS_UpdateEnvelope()
463*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
464*f81fb7c4SAndroid Build Coastguard Worker  * Purpose:
465*f81fb7c4SAndroid Build Coastguard Worker  * Synthesize a block of samples for the given voice.
466*f81fb7c4SAndroid Build Coastguard Worker  * Use linear interpolation.
467*f81fb7c4SAndroid Build Coastguard Worker  *
468*f81fb7c4SAndroid Build Coastguard Worker  * Inputs:
469*f81fb7c4SAndroid Build Coastguard Worker  * pEASData - pointer to overall EAS data structure
470*f81fb7c4SAndroid Build Coastguard Worker  *
471*f81fb7c4SAndroid Build Coastguard Worker  * Outputs:
472*f81fb7c4SAndroid Build Coastguard Worker  * number of samples actually written to buffer
473*f81fb7c4SAndroid Build Coastguard Worker  *
474*f81fb7c4SAndroid Build Coastguard Worker  * Side Effects:
475*f81fb7c4SAndroid Build Coastguard Worker  * - samples are added to the presently free buffer
476*f81fb7c4SAndroid Build Coastguard Worker  *
477*f81fb7c4SAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
478*f81fb7c4SAndroid Build Coastguard Worker */
479*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pChannel) pChannel not used in this instance */
DLS_UpdateEnvelope(S_SYNTH_VOICE * pVoice,S_SYNTH_CHANNEL * pChannel,const S_DLS_ENVELOPE * pEnvParams,EAS_I16 * pValue,EAS_I16 * pIncrement,EAS_U8 * pState)480*f81fb7c4SAndroid Build Coastguard Worker static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel,  const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState)
481*f81fb7c4SAndroid Build Coastguard Worker {
482*f81fb7c4SAndroid Build Coastguard Worker     EAS_I32 temp;
483*f81fb7c4SAndroid Build Coastguard Worker 
484*f81fb7c4SAndroid Build Coastguard Worker     switch (*pState)
485*f81fb7c4SAndroid Build Coastguard Worker     {
486*f81fb7c4SAndroid Build Coastguard Worker         /* initial state */
487*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateInit:
488*f81fb7c4SAndroid Build Coastguard Worker             *pState = eEnvelopeStateDelay;
489*f81fb7c4SAndroid Build Coastguard Worker             *pValue = 0;
490*f81fb7c4SAndroid Build Coastguard Worker             *pIncrement = pEnvParams->delayTime;
491*f81fb7c4SAndroid Build Coastguard Worker             if (*pIncrement != 0)
492*f81fb7c4SAndroid Build Coastguard Worker                 return;
493*f81fb7c4SAndroid Build Coastguard Worker             /*lint -e{825} falls through to next case */
494*f81fb7c4SAndroid Build Coastguard Worker 
495*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateDelay:
496*f81fb7c4SAndroid Build Coastguard Worker             if (*pIncrement)
497*f81fb7c4SAndroid Build Coastguard Worker             {
498*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = *pIncrement - 1;
499*f81fb7c4SAndroid Build Coastguard Worker                 return;
500*f81fb7c4SAndroid Build Coastguard Worker             }
501*f81fb7c4SAndroid Build Coastguard Worker 
502*f81fb7c4SAndroid Build Coastguard Worker             /* calculate attack rate */
503*f81fb7c4SAndroid Build Coastguard Worker             *pState = eEnvelopeStateAttack;
504*f81fb7c4SAndroid Build Coastguard Worker             if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS)
505*f81fb7c4SAndroid Build Coastguard Worker             {
506*f81fb7c4SAndroid Build Coastguard Worker                 /*lint -e{702} use shift for performance */
507*f81fb7c4SAndroid Build Coastguard Worker                 temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7);
508*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = ConvertRate(temp);
509*f81fb7c4SAndroid Build Coastguard Worker                 return;
510*f81fb7c4SAndroid Build Coastguard Worker             }
511*f81fb7c4SAndroid Build Coastguard Worker 
512*f81fb7c4SAndroid Build Coastguard Worker             *pValue = SYNTH_FULL_SCALE_EG1_GAIN;
513*f81fb7c4SAndroid Build Coastguard Worker             /*lint -e{825} falls through to next case */
514*f81fb7c4SAndroid Build Coastguard Worker 
515*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateAttack:
516*f81fb7c4SAndroid Build Coastguard Worker             if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN)
517*f81fb7c4SAndroid Build Coastguard Worker             {
518*f81fb7c4SAndroid Build Coastguard Worker                 temp = *pValue + *pIncrement;
519*f81fb7c4SAndroid Build Coastguard Worker                 *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN);
520*f81fb7c4SAndroid Build Coastguard Worker                 return;
521*f81fb7c4SAndroid Build Coastguard Worker             }
522*f81fb7c4SAndroid Build Coastguard Worker 
523*f81fb7c4SAndroid Build Coastguard Worker             /* calculate hold time */
524*f81fb7c4SAndroid Build Coastguard Worker             *pState = eEnvelopeStateHold;
525*f81fb7c4SAndroid Build Coastguard Worker             if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS)
526*f81fb7c4SAndroid Build Coastguard Worker             {
527*f81fb7c4SAndroid Build Coastguard Worker                 /*lint -e{702} use shift for performance */
528*f81fb7c4SAndroid Build Coastguard Worker                 temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7);
529*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = ConvertDelay(temp);
530*f81fb7c4SAndroid Build Coastguard Worker                 return;
531*f81fb7c4SAndroid Build Coastguard Worker             }
532*f81fb7c4SAndroid Build Coastguard Worker             else
533*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = 0;
534*f81fb7c4SAndroid Build Coastguard Worker             /*lint -e{825} falls through to next case */
535*f81fb7c4SAndroid Build Coastguard Worker 
536*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateHold:
537*f81fb7c4SAndroid Build Coastguard Worker             if (*pIncrement)
538*f81fb7c4SAndroid Build Coastguard Worker             {
539*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = *pIncrement - 1;
540*f81fb7c4SAndroid Build Coastguard Worker                 return;
541*f81fb7c4SAndroid Build Coastguard Worker             }
542*f81fb7c4SAndroid Build Coastguard Worker 
543*f81fb7c4SAndroid Build Coastguard Worker             /* calculate decay rate */
544*f81fb7c4SAndroid Build Coastguard Worker             *pState = eEnvelopeStateDecay;
545*f81fb7c4SAndroid Build Coastguard Worker             if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS)
546*f81fb7c4SAndroid Build Coastguard Worker             {
547*f81fb7c4SAndroid Build Coastguard Worker                 /*lint -e{702} use shift for performance */
548*f81fb7c4SAndroid Build Coastguard Worker                 temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7);
549*f81fb7c4SAndroid Build Coastguard Worker                 *pIncrement = ConvertRate(temp);
550*f81fb7c4SAndroid Build Coastguard Worker                 return;
551*f81fb7c4SAndroid Build Coastguard Worker             }
552*f81fb7c4SAndroid Build Coastguard Worker 
553*f81fb7c4SAndroid Build Coastguard Worker //          *pValue = pEnvParams->sustainLevel;
554*f81fb7c4SAndroid Build Coastguard Worker             /*lint -e{825} falls through to next case */
555*f81fb7c4SAndroid Build Coastguard Worker 
556*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateDecay:
557*f81fb7c4SAndroid Build Coastguard Worker             if (*pValue > pEnvParams->sustainLevel)
558*f81fb7c4SAndroid Build Coastguard Worker             {
559*f81fb7c4SAndroid Build Coastguard Worker                 temp = *pValue - *pIncrement;
560*f81fb7c4SAndroid Build Coastguard Worker                 *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel);
561*f81fb7c4SAndroid Build Coastguard Worker                 return;
562*f81fb7c4SAndroid Build Coastguard Worker             }
563*f81fb7c4SAndroid Build Coastguard Worker 
564*f81fb7c4SAndroid Build Coastguard Worker             *pState = eEnvelopeStateSustain;
565*f81fb7c4SAndroid Build Coastguard Worker             *pValue = pEnvParams->sustainLevel;
566*f81fb7c4SAndroid Build Coastguard Worker             /*lint -e{825} falls through to next case */
567*f81fb7c4SAndroid Build Coastguard Worker 
568*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateSustain:
569*f81fb7c4SAndroid Build Coastguard Worker             return;
570*f81fb7c4SAndroid Build Coastguard Worker 
571*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateRelease:
572*f81fb7c4SAndroid Build Coastguard Worker             temp = *pValue - *pIncrement;
573*f81fb7c4SAndroid Build Coastguard Worker             if (temp <= 0)
574*f81fb7c4SAndroid Build Coastguard Worker             {
575*f81fb7c4SAndroid Build Coastguard Worker                 *pState = eEnvelopeStateMuted;
576*f81fb7c4SAndroid Build Coastguard Worker                 *pValue = 0;
577*f81fb7c4SAndroid Build Coastguard Worker             }
578*f81fb7c4SAndroid Build Coastguard Worker             else
579*f81fb7c4SAndroid Build Coastguard Worker                 *pValue = (EAS_I16) temp;
580*f81fb7c4SAndroid Build Coastguard Worker             break;
581*f81fb7c4SAndroid Build Coastguard Worker 
582*f81fb7c4SAndroid Build Coastguard Worker         case eEnvelopeStateMuted:
583*f81fb7c4SAndroid Build Coastguard Worker             *pValue = 0;
584*f81fb7c4SAndroid Build Coastguard Worker             return;
585*f81fb7c4SAndroid Build Coastguard Worker 
586*f81fb7c4SAndroid Build Coastguard Worker         default:
587*f81fb7c4SAndroid Build Coastguard Worker             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ }
588*f81fb7c4SAndroid Build Coastguard Worker             break;
589*f81fb7c4SAndroid Build Coastguard Worker     }
590*f81fb7c4SAndroid Build Coastguard Worker }
591*f81fb7c4SAndroid Build Coastguard Worker 
592