1*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2*f81fb7c4SAndroid Build Coastguard Worker *
3*f81fb7c4SAndroid Build Coastguard Worker * File:
4*f81fb7c4SAndroid Build Coastguard Worker * eas_voicemgt.c
5*f81fb7c4SAndroid Build Coastguard Worker *
6*f81fb7c4SAndroid Build Coastguard Worker * Contents and purpose:
7*f81fb7c4SAndroid Build Coastguard Worker * Implements the synthesizer functions.
8*f81fb7c4SAndroid Build Coastguard Worker *
9*f81fb7c4SAndroid Build Coastguard Worker * Copyright Sonic Network Inc. 2004
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: 794 $
26*f81fb7c4SAndroid Build Coastguard Worker * $Date: 2007-08-01 00:08:48 -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.h"
32*f81fb7c4SAndroid Build Coastguard Worker #include "eas_data.h"
33*f81fb7c4SAndroid Build Coastguard Worker #include "eas_config.h"
34*f81fb7c4SAndroid Build Coastguard Worker #include "eas_report.h"
35*f81fb7c4SAndroid Build Coastguard Worker #include "eas_midictrl.h"
36*f81fb7c4SAndroid Build Coastguard Worker #include "eas_host.h"
37*f81fb7c4SAndroid Build Coastguard Worker #include "eas_synth_protos.h"
38*f81fb7c4SAndroid Build Coastguard Worker #include "eas_vm_protos.h"
39*f81fb7c4SAndroid Build Coastguard Worker
40*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
41*f81fb7c4SAndroid Build Coastguard Worker #include "eas_mdls.h"
42*f81fb7c4SAndroid Build Coastguard Worker #endif
43*f81fb7c4SAndroid Build Coastguard Worker
44*f81fb7c4SAndroid Build Coastguard Worker // #define _DEBUG_VM
45*f81fb7c4SAndroid Build Coastguard Worker
46*f81fb7c4SAndroid Build Coastguard Worker /* some defines for workload */
47*f81fb7c4SAndroid Build Coastguard Worker #define WORKLOAD_AMOUNT_SMALL_INCREMENT 5
48*f81fb7c4SAndroid Build Coastguard Worker #define WORKLOAD_AMOUNT_START_NOTE 10
49*f81fb7c4SAndroid Build Coastguard Worker #define WORKLOAD_AMOUNT_STOP_NOTE 10
50*f81fb7c4SAndroid Build Coastguard Worker #define WORKLOAD_AMOUNT_KEY_GROUP 10
51*f81fb7c4SAndroid Build Coastguard Worker #define WORKLOAD_AMOUNT_POLY_LIMIT 10
52*f81fb7c4SAndroid Build Coastguard Worker
53*f81fb7c4SAndroid Build Coastguard Worker /* pointer to base sound library */
54*f81fb7c4SAndroid Build Coastguard Worker extern S_EAS easSoundLib;
55*f81fb7c4SAndroid Build Coastguard Worker
56*f81fb7c4SAndroid Build Coastguard Worker #ifdef TEST_HARNESS
57*f81fb7c4SAndroid Build Coastguard Worker extern S_EAS easTestLib;
VMGetLibHandle(EAS_INT libNum)58*f81fb7c4SAndroid Build Coastguard Worker EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum)
59*f81fb7c4SAndroid Build Coastguard Worker {
60*f81fb7c4SAndroid Build Coastguard Worker switch (libNum)
61*f81fb7c4SAndroid Build Coastguard Worker {
62*f81fb7c4SAndroid Build Coastguard Worker case 0:
63*f81fb7c4SAndroid Build Coastguard Worker return &easSoundLib;
64*f81fb7c4SAndroid Build Coastguard Worker #ifdef _WT_SYNTH
65*f81fb7c4SAndroid Build Coastguard Worker case 1:
66*f81fb7c4SAndroid Build Coastguard Worker return &easTestLib;
67*f81fb7c4SAndroid Build Coastguard Worker #endif
68*f81fb7c4SAndroid Build Coastguard Worker default:
69*f81fb7c4SAndroid Build Coastguard Worker return NULL;
70*f81fb7c4SAndroid Build Coastguard Worker }
71*f81fb7c4SAndroid Build Coastguard Worker }
72*f81fb7c4SAndroid Build Coastguard Worker #endif
73*f81fb7c4SAndroid Build Coastguard Worker
74*f81fb7c4SAndroid Build Coastguard Worker /* pointer to synthesizer interface(s) */
75*f81fb7c4SAndroid Build Coastguard Worker #ifdef _WT_SYNTH
76*f81fb7c4SAndroid Build Coastguard Worker extern const S_SYNTH_INTERFACE wtSynth;
77*f81fb7c4SAndroid Build Coastguard Worker #endif
78*f81fb7c4SAndroid Build Coastguard Worker
79*f81fb7c4SAndroid Build Coastguard Worker #ifdef _FM_SYNTH
80*f81fb7c4SAndroid Build Coastguard Worker extern const S_SYNTH_INTERFACE fmSynth;
81*f81fb7c4SAndroid Build Coastguard Worker #endif
82*f81fb7c4SAndroid Build Coastguard Worker
83*f81fb7c4SAndroid Build Coastguard Worker typedef S_SYNTH_INTERFACE *S_SYNTH_INTERFACE_HANDLE;
84*f81fb7c4SAndroid Build Coastguard Worker
85*f81fb7c4SAndroid Build Coastguard Worker /* wavetable on MCU */
86*f81fb7c4SAndroid Build Coastguard Worker #if defined(EAS_WT_SYNTH)
87*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
88*f81fb7c4SAndroid Build Coastguard Worker
89*f81fb7c4SAndroid Build Coastguard Worker /* FM on MCU */
90*f81fb7c4SAndroid Build Coastguard Worker #elif defined(EAS_FM_SYNTH)
91*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
92*f81fb7c4SAndroid Build Coastguard Worker
93*f81fb7c4SAndroid Build Coastguard Worker /* wavetable drums on MCU, FM melodic on DSP */
94*f81fb7c4SAndroid Build Coastguard Worker #elif defined(EAS_HYBRID_SYNTH)
95*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
96*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
97*f81fb7c4SAndroid Build Coastguard Worker
98*f81fb7c4SAndroid Build Coastguard Worker /* wavetable drums on MCU, wavetable melodic on DSP */
99*f81fb7c4SAndroid Build Coastguard Worker #elif defined(EAS_SPLIT_WT_SYNTH)
100*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
101*f81fb7c4SAndroid Build Coastguard Worker extern const S_FRAME_INTERFACE wtFrameInterface;
102*f81fb7c4SAndroid Build Coastguard Worker const S_FRAME_INTERFACE *const pFrameInterface = &wtFrameInterface;
103*f81fb7c4SAndroid Build Coastguard Worker
104*f81fb7c4SAndroid Build Coastguard Worker /* wavetable drums on MCU, FM melodic on DSP */
105*f81fb7c4SAndroid Build Coastguard Worker #elif defined(EAS_SPLIT_HYBRID_SYNTH)
106*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &wtSynth;
107*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pSecondarySynth = &fmSynth;
108*f81fb7c4SAndroid Build Coastguard Worker extern const S_FRAME_INTERFACE fmFrameInterface;
109*f81fb7c4SAndroid Build Coastguard Worker const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
110*f81fb7c4SAndroid Build Coastguard Worker
111*f81fb7c4SAndroid Build Coastguard Worker /* FM on DSP */
112*f81fb7c4SAndroid Build Coastguard Worker #elif defined(EAS_SPLIT_FM_SYNTH)
113*f81fb7c4SAndroid Build Coastguard Worker const S_SYNTH_INTERFACE *const pPrimarySynth = &fmSynth;
114*f81fb7c4SAndroid Build Coastguard Worker extern const S_FRAME_INTERFACE fmFrameInterface;
115*f81fb7c4SAndroid Build Coastguard Worker const S_FRAME_INTERFACE *const pFrameInterface = &fmFrameInterface;
116*f81fb7c4SAndroid Build Coastguard Worker
117*f81fb7c4SAndroid Build Coastguard Worker #else
118*f81fb7c4SAndroid Build Coastguard Worker #error "Undefined architecture option"
119*f81fb7c4SAndroid Build Coastguard Worker #endif
120*f81fb7c4SAndroid Build Coastguard Worker
121*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
122*f81fb7c4SAndroid Build Coastguard Worker * inline functions
123*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
124*f81fb7c4SAndroid Build Coastguard Worker */
GetRegionPtr(S_SYNTH * pSynth,EAS_U16 regionIndex)125*f81fb7c4SAndroid Build Coastguard Worker EAS_INLINE const S_REGION* GetRegionPtr (S_SYNTH *pSynth, EAS_U16 regionIndex)
126*f81fb7c4SAndroid Build Coastguard Worker {
127*f81fb7c4SAndroid Build Coastguard Worker #if defined(DLS_SYNTHESIZER)
128*f81fb7c4SAndroid Build Coastguard Worker if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
129*f81fb7c4SAndroid Build Coastguard Worker return &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK].wtRegion.region;
130*f81fb7c4SAndroid Build Coastguard Worker #endif
131*f81fb7c4SAndroid Build Coastguard Worker #if defined(_HYBRID_SYNTH)
132*f81fb7c4SAndroid Build Coastguard Worker if (regionIndex & FLAG_RGN_IDX_FM_SYNTH)
133*f81fb7c4SAndroid Build Coastguard Worker return &pSynth->pEAS->pFMRegions[regionIndex & REGION_INDEX_MASK].region;
134*f81fb7c4SAndroid Build Coastguard Worker else
135*f81fb7c4SAndroid Build Coastguard Worker return &pSynth->pEAS->pWTRegions[regionIndex].region;
136*f81fb7c4SAndroid Build Coastguard Worker #elif defined(_WT_SYNTH)
137*f81fb7c4SAndroid Build Coastguard Worker return &pSynth->pEAS->pWTRegions[regionIndex].region;
138*f81fb7c4SAndroid Build Coastguard Worker #elif defined(_FM_SYNTH)
139*f81fb7c4SAndroid Build Coastguard Worker return &pSynth->pEAS->pFMRegions[regionIndex].region;
140*f81fb7c4SAndroid Build Coastguard Worker #endif
141*f81fb7c4SAndroid Build Coastguard Worker }
142*f81fb7c4SAndroid Build Coastguard Worker
143*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, voiceNum) used in some implementation */
GetSynthPtr(EAS_INT voiceNum)144*f81fb7c4SAndroid Build Coastguard Worker EAS_INLINE const S_SYNTH_INTERFACE* GetSynthPtr (EAS_INT voiceNum)
145*f81fb7c4SAndroid Build Coastguard Worker {
146*f81fb7c4SAndroid Build Coastguard Worker #if defined(_HYBRID_SYNTH)
147*f81fb7c4SAndroid Build Coastguard Worker if (voiceNum < NUM_PRIMARY_VOICES)
148*f81fb7c4SAndroid Build Coastguard Worker return pPrimarySynth;
149*f81fb7c4SAndroid Build Coastguard Worker else
150*f81fb7c4SAndroid Build Coastguard Worker return pSecondarySynth;
151*f81fb7c4SAndroid Build Coastguard Worker #else
152*f81fb7c4SAndroid Build Coastguard Worker return pPrimarySynth;
153*f81fb7c4SAndroid Build Coastguard Worker #endif
154*f81fb7c4SAndroid Build Coastguard Worker }
155*f81fb7c4SAndroid Build Coastguard Worker
GetAdjustedVoiceNum(EAS_INT voiceNum)156*f81fb7c4SAndroid Build Coastguard Worker EAS_INLINE EAS_INT GetAdjustedVoiceNum (EAS_INT voiceNum)
157*f81fb7c4SAndroid Build Coastguard Worker {
158*f81fb7c4SAndroid Build Coastguard Worker #if defined(_HYBRID_SYNTH)
159*f81fb7c4SAndroid Build Coastguard Worker if (voiceNum >= NUM_PRIMARY_VOICES)
160*f81fb7c4SAndroid Build Coastguard Worker return voiceNum - NUM_PRIMARY_VOICES;
161*f81fb7c4SAndroid Build Coastguard Worker #endif
162*f81fb7c4SAndroid Build Coastguard Worker return voiceNum;
163*f81fb7c4SAndroid Build Coastguard Worker }
164*f81fb7c4SAndroid Build Coastguard Worker
VSynthToChannel(S_SYNTH * pSynth,EAS_U8 channel)165*f81fb7c4SAndroid Build Coastguard Worker EAS_INLINE EAS_U8 VSynthToChannel (S_SYNTH *pSynth, EAS_U8 channel)
166*f81fb7c4SAndroid Build Coastguard Worker {
167*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{734} synthNum is always 0-15 */
168*f81fb7c4SAndroid Build Coastguard Worker return channel | (pSynth->vSynthNum << 4);
169*f81fb7c4SAndroid Build Coastguard Worker }
170*f81fb7c4SAndroid Build Coastguard Worker
171*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
172*f81fb7c4SAndroid Build Coastguard Worker * InitVoice()
173*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
174*f81fb7c4SAndroid Build Coastguard Worker * Initialize a synthesizer voice
175*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
176*f81fb7c4SAndroid Build Coastguard Worker */
InitVoice(S_SYNTH_VOICE * pVoice)177*f81fb7c4SAndroid Build Coastguard Worker void InitVoice (S_SYNTH_VOICE *pVoice)
178*f81fb7c4SAndroid Build Coastguard Worker {
179*f81fb7c4SAndroid Build Coastguard Worker pVoice->channel = UNASSIGNED_SYNTH_CHANNEL;
180*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
181*f81fb7c4SAndroid Build Coastguard Worker pVoice->note = pVoice->nextNote = DEFAULT_KEY_NUMBER;
182*f81fb7c4SAndroid Build Coastguard Worker pVoice->velocity = pVoice->nextVelocity = DEFAULT_VELOCITY;
183*f81fb7c4SAndroid Build Coastguard Worker pVoice->regionIndex = DEFAULT_REGION_INDEX;
184*f81fb7c4SAndroid Build Coastguard Worker pVoice->age = DEFAULT_AGE;
185*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceFlags = DEFAULT_VOICE_FLAGS;
186*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = DEFAULT_VOICE_STATE;
187*f81fb7c4SAndroid Build Coastguard Worker }
188*f81fb7c4SAndroid Build Coastguard Worker
189*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
190*f81fb7c4SAndroid Build Coastguard Worker * IncVoicePoolCount()
191*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
192*f81fb7c4SAndroid Build Coastguard Worker * Updates the voice pool count when a voice changes state
193*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
194*f81fb7c4SAndroid Build Coastguard Worker */
IncVoicePoolCount(S_VOICE_MGR * pVoiceMgr,S_SYNTH_VOICE * pVoice)195*f81fb7c4SAndroid Build Coastguard Worker static void IncVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
196*f81fb7c4SAndroid Build Coastguard Worker {
197*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
198*f81fb7c4SAndroid Build Coastguard Worker EAS_INT pool;
199*f81fb7c4SAndroid Build Coastguard Worker
200*f81fb7c4SAndroid Build Coastguard Worker /* ignore muting voices */
201*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateMuting)
202*f81fb7c4SAndroid Build Coastguard Worker return;
203*f81fb7c4SAndroid Build Coastguard Worker
204*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateStolen)
205*f81fb7c4SAndroid Build Coastguard Worker {
206*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
207*f81fb7c4SAndroid Build Coastguard Worker pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
208*f81fb7c4SAndroid Build Coastguard Worker }
209*f81fb7c4SAndroid Build Coastguard Worker else
210*f81fb7c4SAndroid Build Coastguard Worker {
211*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
212*f81fb7c4SAndroid Build Coastguard Worker pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
213*f81fb7c4SAndroid Build Coastguard Worker }
214*f81fb7c4SAndroid Build Coastguard Worker
215*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[pool]++;
216*f81fb7c4SAndroid Build Coastguard Worker
217*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
218*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IncVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
219*f81fb7c4SAndroid Build Coastguard Worker #endif
220*f81fb7c4SAndroid Build Coastguard Worker }
221*f81fb7c4SAndroid Build Coastguard Worker
222*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
223*f81fb7c4SAndroid Build Coastguard Worker * DecVoicePoolCount()
224*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
225*f81fb7c4SAndroid Build Coastguard Worker * Updates the voice pool count when a voice changes state
226*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
227*f81fb7c4SAndroid Build Coastguard Worker */
DecVoicePoolCount(S_VOICE_MGR * pVoiceMgr,S_SYNTH_VOICE * pVoice)228*f81fb7c4SAndroid Build Coastguard Worker static void DecVoicePoolCount (S_VOICE_MGR *pVoiceMgr, S_SYNTH_VOICE *pVoice)
229*f81fb7c4SAndroid Build Coastguard Worker {
230*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
231*f81fb7c4SAndroid Build Coastguard Worker EAS_INT pool;
232*f81fb7c4SAndroid Build Coastguard Worker
233*f81fb7c4SAndroid Build Coastguard Worker /* ignore muting voices */
234*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateMuting)
235*f81fb7c4SAndroid Build Coastguard Worker return;
236*f81fb7c4SAndroid Build Coastguard Worker
237*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateStolen)
238*f81fb7c4SAndroid Build Coastguard Worker {
239*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
240*f81fb7c4SAndroid Build Coastguard Worker pool = pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool;
241*f81fb7c4SAndroid Build Coastguard Worker }
242*f81fb7c4SAndroid Build Coastguard Worker else
243*f81fb7c4SAndroid Build Coastguard Worker {
244*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
245*f81fb7c4SAndroid Build Coastguard Worker pool = pSynth->channels[GET_CHANNEL(pVoice->channel)].pool;
246*f81fb7c4SAndroid Build Coastguard Worker }
247*f81fb7c4SAndroid Build Coastguard Worker
248*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[pool]--;
249*f81fb7c4SAndroid Build Coastguard Worker
250*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
251*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "DecVoicePoolCount: Synth=%d pool=%d\n", pSynth->vSynthNum, pool); */ }
252*f81fb7c4SAndroid Build Coastguard Worker #endif
253*f81fb7c4SAndroid Build Coastguard Worker }
254*f81fb7c4SAndroid Build Coastguard Worker
255*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
256*f81fb7c4SAndroid Build Coastguard Worker * VMInitialize()
257*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
258*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
259*f81fb7c4SAndroid Build Coastguard Worker *
260*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
261*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
262*f81fb7c4SAndroid Build Coastguard Worker *
263*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
264*f81fb7c4SAndroid Build Coastguard Worker *
265*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
266*f81fb7c4SAndroid Build Coastguard Worker */
VMInitialize(S_EAS_DATA * pEASData)267*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMInitialize (S_EAS_DATA *pEASData)
268*f81fb7c4SAndroid Build Coastguard Worker {
269*f81fb7c4SAndroid Build Coastguard Worker S_VOICE_MGR *pVoiceMgr;
270*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
271*f81fb7c4SAndroid Build Coastguard Worker
272*f81fb7c4SAndroid Build Coastguard Worker /* check Configuration Module for data allocation */
273*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->staticMemoryModel)
274*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr = EAS_CMEnumData(EAS_CM_SYNTH_DATA);
275*f81fb7c4SAndroid Build Coastguard Worker else
276*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_VOICE_MGR));
277*f81fb7c4SAndroid Build Coastguard Worker if (!pVoiceMgr)
278*f81fb7c4SAndroid Build Coastguard Worker {
279*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitialize: Failed to allocate synthesizer memory\n"); */ }
280*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_MALLOC_FAILED;
281*f81fb7c4SAndroid Build Coastguard Worker }
282*f81fb7c4SAndroid Build Coastguard Worker EAS_HWMemSet(pVoiceMgr, 0, sizeof(S_VOICE_MGR));
283*f81fb7c4SAndroid Build Coastguard Worker
284*f81fb7c4SAndroid Build Coastguard Worker /* initialize non-zero variables */
285*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->pGlobalEAS = (S_EAS*) &easSoundLib;
286*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->maxPolyphony = (EAS_U16) MAX_SYNTH_VOICES;
287*f81fb7c4SAndroid Build Coastguard Worker
288*f81fb7c4SAndroid Build Coastguard Worker #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
289*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->maxPolyphonyPrimary = NUM_PRIMARY_VOICES;
290*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->maxPolyphonySecondary = NUM_SECONDARY_VOICES;
291*f81fb7c4SAndroid Build Coastguard Worker #endif
292*f81fb7c4SAndroid Build Coastguard Worker
293*f81fb7c4SAndroid Build Coastguard Worker /* set max workload to zero */
294*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->maxWorkLoad = 0;
295*f81fb7c4SAndroid Build Coastguard Worker
296*f81fb7c4SAndroid Build Coastguard Worker /* initialize the voice manager parameters */
297*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
298*f81fb7c4SAndroid Build Coastguard Worker InitVoice(&pVoiceMgr->voices[i]);
299*f81fb7c4SAndroid Build Coastguard Worker
300*f81fb7c4SAndroid Build Coastguard Worker /* initialize the synth */
301*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{522} return unused at this time */
302*f81fb7c4SAndroid Build Coastguard Worker pPrimarySynth->pfInitialize(pVoiceMgr);
303*f81fb7c4SAndroid Build Coastguard Worker
304*f81fb7c4SAndroid Build Coastguard Worker /* initialize the off-chip synth */
305*f81fb7c4SAndroid Build Coastguard Worker #ifdef _HYBRID_SYNTH
306*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{522} return unused at this time */
307*f81fb7c4SAndroid Build Coastguard Worker pSecondarySynth->pfInitialize(pVoiceMgr);
308*f81fb7c4SAndroid Build Coastguard Worker #endif
309*f81fb7c4SAndroid Build Coastguard Worker
310*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr = pVoiceMgr;
311*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
312*f81fb7c4SAndroid Build Coastguard Worker }
313*f81fb7c4SAndroid Build Coastguard Worker
314*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
315*f81fb7c4SAndroid Build Coastguard Worker * VMInitMIDI()
316*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
317*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
318*f81fb7c4SAndroid Build Coastguard Worker *
319*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
320*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
321*f81fb7c4SAndroid Build Coastguard Worker *
322*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
323*f81fb7c4SAndroid Build Coastguard Worker *
324*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
325*f81fb7c4SAndroid Build Coastguard Worker */
VMInitMIDI(S_EAS_DATA * pEASData,S_SYNTH ** ppSynth)326*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMInitMIDI (S_EAS_DATA *pEASData, S_SYNTH **ppSynth)
327*f81fb7c4SAndroid Build Coastguard Worker {
328*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT result;
329*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
330*f81fb7c4SAndroid Build Coastguard Worker EAS_INT virtualSynthNum;
331*f81fb7c4SAndroid Build Coastguard Worker
332*f81fb7c4SAndroid Build Coastguard Worker *ppSynth = NULL;
333*f81fb7c4SAndroid Build Coastguard Worker
334*f81fb7c4SAndroid Build Coastguard Worker /* static memory model only allows one synth */
335*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->staticMemoryModel)
336*f81fb7c4SAndroid Build Coastguard Worker {
337*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pSynth[0] != NULL)
338*f81fb7c4SAndroid Build Coastguard Worker {
339*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: No virtual synthesizer support for static memory model\n"); */ }
340*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
341*f81fb7c4SAndroid Build Coastguard Worker }
342*f81fb7c4SAndroid Build Coastguard Worker
343*f81fb7c4SAndroid Build Coastguard Worker /* check Configuration Module for data allocation */
344*f81fb7c4SAndroid Build Coastguard Worker pSynth = EAS_CMEnumData(EAS_CM_MIDI_DATA);
345*f81fb7c4SAndroid Build Coastguard Worker virtualSynthNum = 0;
346*f81fb7c4SAndroid Build Coastguard Worker }
347*f81fb7c4SAndroid Build Coastguard Worker
348*f81fb7c4SAndroid Build Coastguard Worker /* dynamic memory model */
349*f81fb7c4SAndroid Build Coastguard Worker else
350*f81fb7c4SAndroid Build Coastguard Worker {
351*f81fb7c4SAndroid Build Coastguard Worker for (virtualSynthNum = 0; virtualSynthNum < MAX_VIRTUAL_SYNTHESIZERS; virtualSynthNum++)
352*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pSynth[virtualSynthNum] == NULL)
353*f81fb7c4SAndroid Build Coastguard Worker break;
354*f81fb7c4SAndroid Build Coastguard Worker if (virtualSynthNum == MAX_VIRTUAL_SYNTHESIZERS)
355*f81fb7c4SAndroid Build Coastguard Worker {
356*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Exceeded number of active virtual synthesizers"); */ }
357*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_NO_VIRTUAL_SYNTHESIZER;
358*f81fb7c4SAndroid Build Coastguard Worker }
359*f81fb7c4SAndroid Build Coastguard Worker pSynth = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SYNTH));
360*f81fb7c4SAndroid Build Coastguard Worker }
361*f81fb7c4SAndroid Build Coastguard Worker
362*f81fb7c4SAndroid Build Coastguard Worker /* make sure we have a valid memory pointer */
363*f81fb7c4SAndroid Build Coastguard Worker if (pSynth == NULL)
364*f81fb7c4SAndroid Build Coastguard Worker {
365*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI: Failed to allocate synthesizer memory\n"); */ }
366*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_MALLOC_FAILED;
367*f81fb7c4SAndroid Build Coastguard Worker }
368*f81fb7c4SAndroid Build Coastguard Worker EAS_HWMemSet(pSynth, 0, sizeof(S_SYNTH));
369*f81fb7c4SAndroid Build Coastguard Worker
370*f81fb7c4SAndroid Build Coastguard Worker /* set the sound library pointer */
371*f81fb7c4SAndroid Build Coastguard Worker if ((result = VMSetEASLib(pSynth, pEASData->pVoiceMgr->pGlobalEAS)) != EAS_SUCCESS)
372*f81fb7c4SAndroid Build Coastguard Worker {
373*f81fb7c4SAndroid Build Coastguard Worker VMMIDIShutdown(pEASData, pSynth);
374*f81fb7c4SAndroid Build Coastguard Worker return result;
375*f81fb7c4SAndroid Build Coastguard Worker }
376*f81fb7c4SAndroid Build Coastguard Worker
377*f81fb7c4SAndroid Build Coastguard Worker /* link in DLS bank if downloaded */
378*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
379*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pGlobalDLS)
380*f81fb7c4SAndroid Build Coastguard Worker {
381*f81fb7c4SAndroid Build Coastguard Worker pSynth->pDLS = pEASData->pVoiceMgr->pGlobalDLS;
382*f81fb7c4SAndroid Build Coastguard Worker DLSAddRef(pSynth->pDLS);
383*f81fb7c4SAndroid Build Coastguard Worker }
384*f81fb7c4SAndroid Build Coastguard Worker #endif
385*f81fb7c4SAndroid Build Coastguard Worker
386*f81fb7c4SAndroid Build Coastguard Worker /* initialize MIDI state variables */
387*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags = DEFAULT_SYNTH_FLAGS;
388*f81fb7c4SAndroid Build Coastguard Worker pSynth->masterVolume = DEFAULT_SYNTH_MASTER_VOLUME;
389*f81fb7c4SAndroid Build Coastguard Worker pSynth->refCount = 1;
390*f81fb7c4SAndroid Build Coastguard Worker pSynth->priority = DEFAULT_SYNTH_PRIORITY;
391*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolAlloc[0] = (EAS_U8) pEASData->pVoiceMgr->maxPolyphony;
392*f81fb7c4SAndroid Build Coastguard Worker
393*f81fb7c4SAndroid Build Coastguard Worker VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
394*f81fb7c4SAndroid Build Coastguard Worker
395*f81fb7c4SAndroid Build Coastguard Worker pSynth->vSynthNum = (EAS_U8) virtualSynthNum;
396*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr->pSynth[virtualSynthNum] = pSynth;
397*f81fb7c4SAndroid Build Coastguard Worker
398*f81fb7c4SAndroid Build Coastguard Worker *ppSynth = pSynth;
399*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
400*f81fb7c4SAndroid Build Coastguard Worker }
401*f81fb7c4SAndroid Build Coastguard Worker
402*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
403*f81fb7c4SAndroid Build Coastguard Worker * VMReset()
404*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
405*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
406*f81fb7c4SAndroid Build Coastguard Worker * We call this routine to start the process of reseting the synth.
407*f81fb7c4SAndroid Build Coastguard Worker * This routine sets a flag for the entire synth indicating that we want
408*f81fb7c4SAndroid Build Coastguard Worker * to reset.
409*f81fb7c4SAndroid Build Coastguard Worker * We also force all voices to mute quickly.
410*f81fb7c4SAndroid Build Coastguard Worker * However, we do not actually perform any synthesis in this routine. That
411*f81fb7c4SAndroid Build Coastguard Worker * is, we do not ramp the voices down from this routine, but instead, we
412*f81fb7c4SAndroid Build Coastguard Worker * let the "regular" synth processing steps take care of adding the ramp
413*f81fb7c4SAndroid Build Coastguard Worker * down samples to the output buffer. After we are sure that all voices
414*f81fb7c4SAndroid Build Coastguard Worker * have completed ramping down, we continue the process of resetting the
415*f81fb7c4SAndroid Build Coastguard Worker * synth (from another routine).
416*f81fb7c4SAndroid Build Coastguard Worker *
417*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
418*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
419*f81fb7c4SAndroid Build Coastguard Worker * force - force reset even if voices are active
420*f81fb7c4SAndroid Build Coastguard Worker *
421*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
422*f81fb7c4SAndroid Build Coastguard Worker *
423*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
424*f81fb7c4SAndroid Build Coastguard Worker * - set a flag (in psSynthObject->m_nFlags) indicating synth reset requested.
425*f81fb7c4SAndroid Build Coastguard Worker * - force all voices to update their envelope states to mute
426*f81fb7c4SAndroid Build Coastguard Worker *
427*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
428*f81fb7c4SAndroid Build Coastguard Worker */
VMReset(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_BOOL force)429*f81fb7c4SAndroid Build Coastguard Worker void VMReset (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_BOOL force)
430*f81fb7c4SAndroid Build Coastguard Worker {
431*f81fb7c4SAndroid Build Coastguard Worker
432*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
433*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: request to reset synth. Force = %d\n", force); */ }
434*f81fb7c4SAndroid Build Coastguard Worker #endif
435*f81fb7c4SAndroid Build Coastguard Worker
436*f81fb7c4SAndroid Build Coastguard Worker /* force voices to off state - may cause audio artifacts */
437*f81fb7c4SAndroid Build Coastguard Worker if (force)
438*f81fb7c4SAndroid Build Coastguard Worker {
439*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->activeVoices -= pSynth->numActiveVoices;
440*f81fb7c4SAndroid Build Coastguard Worker pSynth->numActiveVoices = 0;
441*f81fb7c4SAndroid Build Coastguard Worker VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
442*f81fb7c4SAndroid Build Coastguard Worker }
443*f81fb7c4SAndroid Build Coastguard Worker else
444*f81fb7c4SAndroid Build Coastguard Worker VMMuteAllVoices(pVoiceMgr, pSynth);
445*f81fb7c4SAndroid Build Coastguard Worker
446*f81fb7c4SAndroid Build Coastguard Worker /* don't reset if voices are still playing */
447*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->numActiveVoices == 0)
448*f81fb7c4SAndroid Build Coastguard Worker {
449*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
450*f81fb7c4SAndroid Build Coastguard Worker
451*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
452*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReset: complete the reset process\n"); */ }
453*f81fb7c4SAndroid Build Coastguard Worker #endif
454*f81fb7c4SAndroid Build Coastguard Worker
455*f81fb7c4SAndroid Build Coastguard Worker VMInitializeAllChannels(pVoiceMgr, pSynth);
456*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
457*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[i] = 0;
458*f81fb7c4SAndroid Build Coastguard Worker
459*f81fb7c4SAndroid Build Coastguard Worker /* set polyphony */
460*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->maxPolyphony < pVoiceMgr->maxPolyphony)
461*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolAlloc[0] = (EAS_U8) pVoiceMgr->maxPolyphony;
462*f81fb7c4SAndroid Build Coastguard Worker else
463*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolAlloc[0] = (EAS_U8) pSynth->maxPolyphony;
464*f81fb7c4SAndroid Build Coastguard Worker
465*f81fb7c4SAndroid Build Coastguard Worker /* clear reset flag */
466*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
467*f81fb7c4SAndroid Build Coastguard Worker }
468*f81fb7c4SAndroid Build Coastguard Worker
469*f81fb7c4SAndroid Build Coastguard Worker /* handle reset after voices are muted */
470*f81fb7c4SAndroid Build Coastguard Worker else
471*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags |= SYNTH_FLAG_RESET_IS_REQUESTED;
472*f81fb7c4SAndroid Build Coastguard Worker }
473*f81fb7c4SAndroid Build Coastguard Worker
474*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
475*f81fb7c4SAndroid Build Coastguard Worker * VMInitializeAllChannels()
476*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
477*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
478*f81fb7c4SAndroid Build Coastguard Worker *
479*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
480*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
481*f81fb7c4SAndroid Build Coastguard Worker *
482*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
483*f81fb7c4SAndroid Build Coastguard Worker *
484*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
485*f81fb7c4SAndroid Build Coastguard Worker */
VMInitializeAllChannels(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)486*f81fb7c4SAndroid Build Coastguard Worker void VMInitializeAllChannels (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
487*f81fb7c4SAndroid Build Coastguard Worker {
488*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
489*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
490*f81fb7c4SAndroid Build Coastguard Worker
491*f81fb7c4SAndroid Build Coastguard Worker VMResetControllers(pSynth);
492*f81fb7c4SAndroid Build Coastguard Worker
493*f81fb7c4SAndroid Build Coastguard Worker /* init each channel */
494*f81fb7c4SAndroid Build Coastguard Worker pChannel = pSynth->channels;
495*f81fb7c4SAndroid Build Coastguard Worker
496*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
497*f81fb7c4SAndroid Build Coastguard Worker {
498*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags = DEFAULT_CHANNEL_FLAGS;
499*f81fb7c4SAndroid Build Coastguard Worker pChannel->staticGain = DEFAULT_CHANNEL_STATIC_GAIN;
500*f81fb7c4SAndroid Build Coastguard Worker pChannel->staticPitch = DEFAULT_CHANNEL_STATIC_PITCH;
501*f81fb7c4SAndroid Build Coastguard Worker pChannel->pool = 0;
502*f81fb7c4SAndroid Build Coastguard Worker
503*f81fb7c4SAndroid Build Coastguard Worker /* the drum channel needs a different init */
504*f81fb7c4SAndroid Build Coastguard Worker if (i == DEFAULT_DRUM_CHANNEL)
505*f81fb7c4SAndroid Build Coastguard Worker {
506*f81fb7c4SAndroid Build Coastguard Worker pChannel->bankNum = DEFAULT_RHYTHM_BANK_NUMBER;
507*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
508*f81fb7c4SAndroid Build Coastguard Worker }
509*f81fb7c4SAndroid Build Coastguard Worker else
510*f81fb7c4SAndroid Build Coastguard Worker pChannel->bankNum = DEFAULT_MELODY_BANK_NUMBER;
511*f81fb7c4SAndroid Build Coastguard Worker
512*f81fb7c4SAndroid Build Coastguard Worker VMProgramChange(pVoiceMgr, pSynth, (EAS_U8) i, DEFAULT_SYNTH_PROGRAM_NUMBER);
513*f81fb7c4SAndroid Build Coastguard Worker }
514*f81fb7c4SAndroid Build Coastguard Worker
515*f81fb7c4SAndroid Build Coastguard Worker }
516*f81fb7c4SAndroid Build Coastguard Worker
517*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
518*f81fb7c4SAndroid Build Coastguard Worker * VMResetControllers()
519*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
520*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
521*f81fb7c4SAndroid Build Coastguard Worker *
522*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
523*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
524*f81fb7c4SAndroid Build Coastguard Worker *
525*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
526*f81fb7c4SAndroid Build Coastguard Worker *
527*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
528*f81fb7c4SAndroid Build Coastguard Worker */
VMResetControllers(S_SYNTH * pSynth)529*f81fb7c4SAndroid Build Coastguard Worker void VMResetControllers (S_SYNTH *pSynth)
530*f81fb7c4SAndroid Build Coastguard Worker {
531*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
532*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
533*f81fb7c4SAndroid Build Coastguard Worker
534*f81fb7c4SAndroid Build Coastguard Worker pChannel = pSynth->channels;
535*f81fb7c4SAndroid Build Coastguard Worker
536*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++, pChannel++)
537*f81fb7c4SAndroid Build Coastguard Worker {
538*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBend = DEFAULT_PITCH_BEND;
539*f81fb7c4SAndroid Build Coastguard Worker pChannel->modWheel = DEFAULT_MOD_WHEEL;
540*f81fb7c4SAndroid Build Coastguard Worker pChannel->volume = DEFAULT_CHANNEL_VOLUME;
541*f81fb7c4SAndroid Build Coastguard Worker pChannel->pan = DEFAULT_PAN;
542*f81fb7c4SAndroid Build Coastguard Worker pChannel->expression = DEFAULT_EXPRESSION;
543*f81fb7c4SAndroid Build Coastguard Worker
544*f81fb7c4SAndroid Build Coastguard Worker #ifdef _REVERB
545*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].reverbSend = DEFAULT_REVERB_SEND;
546*f81fb7c4SAndroid Build Coastguard Worker #endif
547*f81fb7c4SAndroid Build Coastguard Worker
548*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHORUS
549*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].chorusSend = DEFAULT_CHORUS_SEND;
550*f81fb7c4SAndroid Build Coastguard Worker #endif
551*f81fb7c4SAndroid Build Coastguard Worker
552*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
553*f81fb7c4SAndroid Build Coastguard Worker pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
554*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
555*f81fb7c4SAndroid Build Coastguard Worker pChannel->finePitch = DEFAULT_FINE_PITCH;
556*f81fb7c4SAndroid Build Coastguard Worker pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
557*f81fb7c4SAndroid Build Coastguard Worker
558*f81fb7c4SAndroid Build Coastguard Worker /* update all voices on this channel */
559*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
560*f81fb7c4SAndroid Build Coastguard Worker }
561*f81fb7c4SAndroid Build Coastguard Worker }
562*f81fb7c4SAndroid Build Coastguard Worker
563*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
564*f81fb7c4SAndroid Build Coastguard Worker * VMInitializeAllVoices()
565*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
566*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
567*f81fb7c4SAndroid Build Coastguard Worker *
568*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
569*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
570*f81fb7c4SAndroid Build Coastguard Worker *
571*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
572*f81fb7c4SAndroid Build Coastguard Worker *
573*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
574*f81fb7c4SAndroid Build Coastguard Worker */
VMInitializeAllVoices(S_VOICE_MGR * pVoiceMgr,EAS_INT vSynthNum)575*f81fb7c4SAndroid Build Coastguard Worker void VMInitializeAllVoices (S_VOICE_MGR *pVoiceMgr, EAS_INT vSynthNum)
576*f81fb7c4SAndroid Build Coastguard Worker {
577*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
578*f81fb7c4SAndroid Build Coastguard Worker
579*f81fb7c4SAndroid Build Coastguard Worker /* initialize the voice manager parameters */
580*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
581*f81fb7c4SAndroid Build Coastguard Worker {
582*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
583*f81fb7c4SAndroid Build Coastguard Worker {
584*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == vSynthNum)
585*f81fb7c4SAndroid Build Coastguard Worker InitVoice(&pVoiceMgr->voices[i]);
586*f81fb7c4SAndroid Build Coastguard Worker }
587*f81fb7c4SAndroid Build Coastguard Worker else
588*f81fb7c4SAndroid Build Coastguard Worker {
589*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == vSynthNum)
590*f81fb7c4SAndroid Build Coastguard Worker InitVoice(&pVoiceMgr->voices[i]);
591*f81fb7c4SAndroid Build Coastguard Worker }
592*f81fb7c4SAndroid Build Coastguard Worker }
593*f81fb7c4SAndroid Build Coastguard Worker }
594*f81fb7c4SAndroid Build Coastguard Worker
595*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
596*f81fb7c4SAndroid Build Coastguard Worker * VMMuteVoice()
597*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
598*f81fb7c4SAndroid Build Coastguard Worker * Mute the selected voice
599*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
600*f81fb7c4SAndroid Build Coastguard Worker */
VMMuteVoice(S_VOICE_MGR * pVoiceMgr,EAS_I32 voiceNum)601*f81fb7c4SAndroid Build Coastguard Worker void VMMuteVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
602*f81fb7c4SAndroid Build Coastguard Worker {
603*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
604*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
605*f81fb7c4SAndroid Build Coastguard Worker
606*f81fb7c4SAndroid Build Coastguard Worker /* take no action if voice is already muted */
607*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pVoiceMgr->voices[voiceNum];
608*f81fb7c4SAndroid Build Coastguard Worker if ((pVoice->voiceState == eVoiceStateMuting) || (pVoice->voiceState == eVoiceStateFree))
609*f81fb7c4SAndroid Build Coastguard Worker return;
610*f81fb7c4SAndroid Build Coastguard Worker
611*f81fb7c4SAndroid Build Coastguard Worker /* one less voice in pool */
612*f81fb7c4SAndroid Build Coastguard Worker DecVoicePoolCount(pVoiceMgr, pVoice);
613*f81fb7c4SAndroid Build Coastguard Worker
614*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
615*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
616*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = eVoiceStateMuting;
617*f81fb7c4SAndroid Build Coastguard Worker
618*f81fb7c4SAndroid Build Coastguard Worker }
619*f81fb7c4SAndroid Build Coastguard Worker
620*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
621*f81fb7c4SAndroid Build Coastguard Worker * VMReleaseVoice()
622*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
623*f81fb7c4SAndroid Build Coastguard Worker * Release the selected voice
624*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
625*f81fb7c4SAndroid Build Coastguard Worker */
VMReleaseVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_I32 voiceNum)626*f81fb7c4SAndroid Build Coastguard Worker void VMReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum)
627*f81fb7c4SAndroid Build Coastguard Worker {
628*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
629*f81fb7c4SAndroid Build Coastguard Worker
630*f81fb7c4SAndroid Build Coastguard Worker /* take no action if voice is already free, muting, or releasing */
631*f81fb7c4SAndroid Build Coastguard Worker if (( pVoice->voiceState == eVoiceStateMuting) ||
632*f81fb7c4SAndroid Build Coastguard Worker (pVoice->voiceState == eVoiceStateFree) ||
633*f81fb7c4SAndroid Build Coastguard Worker (pVoice->voiceState == eVoiceStateRelease))
634*f81fb7c4SAndroid Build Coastguard Worker return;
635*f81fb7c4SAndroid Build Coastguard Worker
636*f81fb7c4SAndroid Build Coastguard Worker /* stolen voices should just be muted */
637*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateStolen)
638*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, voiceNum);
639*f81fb7c4SAndroid Build Coastguard Worker
640*f81fb7c4SAndroid Build Coastguard Worker /* release this voice */
641*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfReleaseVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
642*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = eVoiceStateRelease;
643*f81fb7c4SAndroid Build Coastguard Worker }
644*f81fb7c4SAndroid Build Coastguard Worker
645*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
646*f81fb7c4SAndroid Build Coastguard Worker * VMInitMIPTable()
647*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
648*f81fb7c4SAndroid Build Coastguard Worker * Initialize the SP-MIDI MIP table in preparation for receiving MIP message
649*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
650*f81fb7c4SAndroid Build Coastguard Worker */
VMInitMIPTable(S_SYNTH * pSynth)651*f81fb7c4SAndroid Build Coastguard Worker void VMInitMIPTable (S_SYNTH *pSynth)
652*f81fb7c4SAndroid Build Coastguard Worker {
653*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
654*f81fb7c4SAndroid Build Coastguard Worker
655*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
656*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMInitMIPTable\n"); */ }
657*f81fb7c4SAndroid Build Coastguard Worker #endif
658*f81fb7c4SAndroid Build Coastguard Worker
659*f81fb7c4SAndroid Build Coastguard Worker /* clear SP-MIDI flag */
660*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags &= ~SYNTH_FLAG_SP_MIDI_ON;
661*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
662*f81fb7c4SAndroid Build Coastguard Worker {
663*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].pool = 0;
664*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].mip = 0;
665*f81fb7c4SAndroid Build Coastguard Worker }
666*f81fb7c4SAndroid Build Coastguard Worker }
667*f81fb7c4SAndroid Build Coastguard Worker
668*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
669*f81fb7c4SAndroid Build Coastguard Worker * VMSetMIPEntry()
670*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
671*f81fb7c4SAndroid Build Coastguard Worker * Sets the priority and MIP level for a MIDI channel
672*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
673*f81fb7c4SAndroid Build Coastguard Worker */
674*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pVoiceMgr) reserved for future use */
VMSetMIPEntry(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 priority,EAS_U8 mip)675*f81fb7c4SAndroid Build Coastguard Worker void VMSetMIPEntry (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 priority, EAS_U8 mip)
676*f81fb7c4SAndroid Build Coastguard Worker {
677*f81fb7c4SAndroid Build Coastguard Worker
678*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
679*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMSetMIPEntry: channel=%d, priority=%d, MIP=%d\n", channel, priority, mip); */ }
680*f81fb7c4SAndroid Build Coastguard Worker #endif
681*f81fb7c4SAndroid Build Coastguard Worker
682*f81fb7c4SAndroid Build Coastguard Worker /* save data for use by MIP message processing */
683*f81fb7c4SAndroid Build Coastguard Worker if (priority < NUM_SYNTH_CHANNELS)
684*f81fb7c4SAndroid Build Coastguard Worker {
685*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].pool = priority;
686*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].mip = mip;
687*f81fb7c4SAndroid Build Coastguard Worker }
688*f81fb7c4SAndroid Build Coastguard Worker }
689*f81fb7c4SAndroid Build Coastguard Worker
690*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
691*f81fb7c4SAndroid Build Coastguard Worker * VMMIPUpdateChannelMuting()
692*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
693*f81fb7c4SAndroid Build Coastguard Worker * This routine is called after an SP-MIDI message is received and
694*f81fb7c4SAndroid Build Coastguard Worker * any time the allocated polyphony changes. It mutes or unmutes
695*f81fb7c4SAndroid Build Coastguard Worker * channels based on polyphony.
696*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
697*f81fb7c4SAndroid Build Coastguard Worker */
VMMIPUpdateChannelMuting(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)698*f81fb7c4SAndroid Build Coastguard Worker void VMMIPUpdateChannelMuting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
699*f81fb7c4SAndroid Build Coastguard Worker {
700*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
701*f81fb7c4SAndroid Build Coastguard Worker EAS_INT maxPolyphony;
702*f81fb7c4SAndroid Build Coastguard Worker EAS_INT channel;
703*f81fb7c4SAndroid Build Coastguard Worker EAS_INT vSynthNum;
704*f81fb7c4SAndroid Build Coastguard Worker EAS_INT pool;
705*f81fb7c4SAndroid Build Coastguard Worker
706*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
707*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
708*f81fb7c4SAndroid Build Coastguard Worker #endif
709*f81fb7c4SAndroid Build Coastguard Worker
710*f81fb7c4SAndroid Build Coastguard Worker /* determine max polyphony */
711*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->maxPolyphony)
712*f81fb7c4SAndroid Build Coastguard Worker maxPolyphony = pSynth->maxPolyphony;
713*f81fb7c4SAndroid Build Coastguard Worker else
714*f81fb7c4SAndroid Build Coastguard Worker maxPolyphony = pVoiceMgr->maxPolyphony;
715*f81fb7c4SAndroid Build Coastguard Worker
716*f81fb7c4SAndroid Build Coastguard Worker /* process channels */
717*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
718*f81fb7c4SAndroid Build Coastguard Worker {
719*f81fb7c4SAndroid Build Coastguard Worker
720*f81fb7c4SAndroid Build Coastguard Worker /* channel must be in MIP message and must meet allocation target */
721*f81fb7c4SAndroid Build Coastguard Worker if ((pSynth->channels[i].mip != 0) && (pSynth->channels[i].mip <= maxPolyphony))
722*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_MUTE;
723*f81fb7c4SAndroid Build Coastguard Worker else
724*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].channelFlags |= CHANNEL_FLAG_MUTE;
725*f81fb7c4SAndroid Build Coastguard Worker
726*f81fb7c4SAndroid Build Coastguard Worker /* reset voice pool count */
727*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[i] = 0;
728*f81fb7c4SAndroid Build Coastguard Worker }
729*f81fb7c4SAndroid Build Coastguard Worker
730*f81fb7c4SAndroid Build Coastguard Worker /* mute any voices on muted channels, and count unmuted voices */
731*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
732*f81fb7c4SAndroid Build Coastguard Worker {
733*f81fb7c4SAndroid Build Coastguard Worker
734*f81fb7c4SAndroid Build Coastguard Worker /* ignore free voices */
735*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[i].voiceState == eVoiceStateFree)
736*f81fb7c4SAndroid Build Coastguard Worker continue;
737*f81fb7c4SAndroid Build Coastguard Worker
738*f81fb7c4SAndroid Build Coastguard Worker /* get channel and virtual synth */
739*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[i].voiceState != eVoiceStateStolen)
740*f81fb7c4SAndroid Build Coastguard Worker {
741*f81fb7c4SAndroid Build Coastguard Worker vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].channel);
742*f81fb7c4SAndroid Build Coastguard Worker channel = GET_CHANNEL(pVoiceMgr->voices[i].channel);
743*f81fb7c4SAndroid Build Coastguard Worker }
744*f81fb7c4SAndroid Build Coastguard Worker else
745*f81fb7c4SAndroid Build Coastguard Worker {
746*f81fb7c4SAndroid Build Coastguard Worker vSynthNum = GET_VSYNTH(pVoiceMgr->voices[i].nextChannel);
747*f81fb7c4SAndroid Build Coastguard Worker channel = GET_CHANNEL(pVoiceMgr->voices[i].nextChannel);
748*f81fb7c4SAndroid Build Coastguard Worker }
749*f81fb7c4SAndroid Build Coastguard Worker
750*f81fb7c4SAndroid Build Coastguard Worker /* ignore voices on other synths */
751*f81fb7c4SAndroid Build Coastguard Worker if (vSynthNum != pSynth->vSynthNum)
752*f81fb7c4SAndroid Build Coastguard Worker continue;
753*f81fb7c4SAndroid Build Coastguard Worker
754*f81fb7c4SAndroid Build Coastguard Worker /* count voices */
755*f81fb7c4SAndroid Build Coastguard Worker pool = pSynth->channels[channel].pool;
756*f81fb7c4SAndroid Build Coastguard Worker
757*f81fb7c4SAndroid Build Coastguard Worker /* deal with muted channels */
758*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_MUTE)
759*f81fb7c4SAndroid Build Coastguard Worker {
760*f81fb7c4SAndroid Build Coastguard Worker /* mute stolen voices scheduled to play on this channel */
761*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
762*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[i].voiceState = eVoiceStateMuting;
763*f81fb7c4SAndroid Build Coastguard Worker
764*f81fb7c4SAndroid Build Coastguard Worker /* release voices that aren't already muting */
765*f81fb7c4SAndroid Build Coastguard Worker else if (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting)
766*f81fb7c4SAndroid Build Coastguard Worker {
767*f81fb7c4SAndroid Build Coastguard Worker VMReleaseVoice(pVoiceMgr, pSynth, i);
768*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[pool]++;
769*f81fb7c4SAndroid Build Coastguard Worker }
770*f81fb7c4SAndroid Build Coastguard Worker }
771*f81fb7c4SAndroid Build Coastguard Worker
772*f81fb7c4SAndroid Build Coastguard Worker /* not muted, count this voice */
773*f81fb7c4SAndroid Build Coastguard Worker else
774*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolCount[pool]++;
775*f81fb7c4SAndroid Build Coastguard Worker }
776*f81fb7c4SAndroid Build Coastguard Worker }
777*f81fb7c4SAndroid Build Coastguard Worker
778*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
779*f81fb7c4SAndroid Build Coastguard Worker * VMUpdateMIPTable()
780*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
781*f81fb7c4SAndroid Build Coastguard Worker * This routine is called at the end of the SysEx message to allow
782*f81fb7c4SAndroid Build Coastguard Worker * the Voice Manager to complete the initialization of the MIP
783*f81fb7c4SAndroid Build Coastguard Worker * table. It assigns channels to the appropriate voice pool based
784*f81fb7c4SAndroid Build Coastguard Worker * on the MIP setting and calculates the voices allocated for each
785*f81fb7c4SAndroid Build Coastguard Worker * pool.
786*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
787*f81fb7c4SAndroid Build Coastguard Worker */
788*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pVoiceMgr) reserved for future use */
VMUpdateMIPTable(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)789*f81fb7c4SAndroid Build Coastguard Worker void VMUpdateMIPTable (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
790*f81fb7c4SAndroid Build Coastguard Worker {
791*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
792*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
793*f81fb7c4SAndroid Build Coastguard Worker EAS_INT currentMIP;
794*f81fb7c4SAndroid Build Coastguard Worker EAS_INT currentPool;
795*f81fb7c4SAndroid Build Coastguard Worker EAS_INT priority[NUM_SYNTH_CHANNELS];
796*f81fb7c4SAndroid Build Coastguard Worker
797*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
798*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateMIPTable\n"); */ }
799*f81fb7c4SAndroid Build Coastguard Worker #endif
800*f81fb7c4SAndroid Build Coastguard Worker
801*f81fb7c4SAndroid Build Coastguard Worker /* set SP-MIDI flag */
802*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
803*f81fb7c4SAndroid Build Coastguard Worker
804*f81fb7c4SAndroid Build Coastguard Worker /* sort channels into priority order */
805*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
806*f81fb7c4SAndroid Build Coastguard Worker priority[i] = -1;
807*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
808*f81fb7c4SAndroid Build Coastguard Worker {
809*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[i].pool != DEFAULT_SP_MIDI_PRIORITY)
810*f81fb7c4SAndroid Build Coastguard Worker priority[pSynth->channels[i].pool] = i;
811*f81fb7c4SAndroid Build Coastguard Worker }
812*f81fb7c4SAndroid Build Coastguard Worker
813*f81fb7c4SAndroid Build Coastguard Worker /* process channels in priority order */
814*f81fb7c4SAndroid Build Coastguard Worker currentMIP = 0;
815*f81fb7c4SAndroid Build Coastguard Worker currentPool = -1;
816*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
817*f81fb7c4SAndroid Build Coastguard Worker {
818*f81fb7c4SAndroid Build Coastguard Worker /* stop when we run out of channels */
819*f81fb7c4SAndroid Build Coastguard Worker if (priority[i] == -1)
820*f81fb7c4SAndroid Build Coastguard Worker break;
821*f81fb7c4SAndroid Build Coastguard Worker
822*f81fb7c4SAndroid Build Coastguard Worker pChannel = &pSynth->channels[priority[i]];
823*f81fb7c4SAndroid Build Coastguard Worker
824*f81fb7c4SAndroid Build Coastguard Worker /* when 2 or more channels have the same MIP setting, they
825*f81fb7c4SAndroid Build Coastguard Worker * share a common voice pool
826*f81fb7c4SAndroid Build Coastguard Worker */
827*f81fb7c4SAndroid Build Coastguard Worker if (pChannel->mip == currentMIP && currentPool != -1)
828*f81fb7c4SAndroid Build Coastguard Worker pChannel->pool = (EAS_U8) currentPool;
829*f81fb7c4SAndroid Build Coastguard Worker
830*f81fb7c4SAndroid Build Coastguard Worker /* new voice pool */
831*f81fb7c4SAndroid Build Coastguard Worker else
832*f81fb7c4SAndroid Build Coastguard Worker {
833*f81fb7c4SAndroid Build Coastguard Worker currentPool++;
834*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolAlloc[currentPool] = (EAS_U8) (pChannel->mip - currentMIP);
835*f81fb7c4SAndroid Build Coastguard Worker currentMIP = pChannel->mip;
836*f81fb7c4SAndroid Build Coastguard Worker }
837*f81fb7c4SAndroid Build Coastguard Worker }
838*f81fb7c4SAndroid Build Coastguard Worker
839*f81fb7c4SAndroid Build Coastguard Worker /* set SP-MIDI flag */
840*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags |= SYNTH_FLAG_SP_MIDI_ON;
841*f81fb7c4SAndroid Build Coastguard Worker
842*f81fb7c4SAndroid Build Coastguard Worker /* update channel muting */
843*f81fb7c4SAndroid Build Coastguard Worker VMMIPUpdateChannelMuting (pVoiceMgr, pSynth);
844*f81fb7c4SAndroid Build Coastguard Worker }
845*f81fb7c4SAndroid Build Coastguard Worker
846*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
847*f81fb7c4SAndroid Build Coastguard Worker * VMMuteAllVoices()
848*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
849*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
850*f81fb7c4SAndroid Build Coastguard Worker * We call this in an emergency reset situation.
851*f81fb7c4SAndroid Build Coastguard Worker * This forces all voices to mute quickly.
852*f81fb7c4SAndroid Build Coastguard Worker *
853*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
854*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
855*f81fb7c4SAndroid Build Coastguard Worker *
856*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
857*f81fb7c4SAndroid Build Coastguard Worker *
858*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
859*f81fb7c4SAndroid Build Coastguard Worker * - forces all voices to update their envelope states to mute
860*f81fb7c4SAndroid Build Coastguard Worker *
861*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
862*f81fb7c4SAndroid Build Coastguard Worker */
VMMuteAllVoices(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)863*f81fb7c4SAndroid Build Coastguard Worker void VMMuteAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
864*f81fb7c4SAndroid Build Coastguard Worker {
865*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
866*f81fb7c4SAndroid Build Coastguard Worker
867*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
868*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMMuteAllVoices: about to mute all voices!!\n"); */ }
869*f81fb7c4SAndroid Build Coastguard Worker #endif
870*f81fb7c4SAndroid Build Coastguard Worker
871*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
872*f81fb7c4SAndroid Build Coastguard Worker {
873*f81fb7c4SAndroid Build Coastguard Worker /* for stolen voices, check new channel */
874*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[i].voiceState == eVoiceStateStolen)
875*f81fb7c4SAndroid Build Coastguard Worker {
876*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
877*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, i);
878*f81fb7c4SAndroid Build Coastguard Worker }
879*f81fb7c4SAndroid Build Coastguard Worker
880*f81fb7c4SAndroid Build Coastguard Worker else if (pSynth->vSynthNum == GET_VSYNTH(pVoiceMgr->voices[i].channel))
881*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, i);
882*f81fb7c4SAndroid Build Coastguard Worker }
883*f81fb7c4SAndroid Build Coastguard Worker }
884*f81fb7c4SAndroid Build Coastguard Worker
885*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
886*f81fb7c4SAndroid Build Coastguard Worker * VMReleaseAllVoices()
887*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
888*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
889*f81fb7c4SAndroid Build Coastguard Worker * We call this after we've encountered the end of the Midi file.
890*f81fb7c4SAndroid Build Coastguard Worker * This ensures all voices are either in release (because we received their
891*f81fb7c4SAndroid Build Coastguard Worker * note off already) or forces them to mute quickly.
892*f81fb7c4SAndroid Build Coastguard Worker * We use this as a safety to prevent bad midi files from playing forever.
893*f81fb7c4SAndroid Build Coastguard Worker *
894*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
895*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
896*f81fb7c4SAndroid Build Coastguard Worker *
897*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
898*f81fb7c4SAndroid Build Coastguard Worker *
899*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
900*f81fb7c4SAndroid Build Coastguard Worker * - forces all voices to update their envelope states to release or mute
901*f81fb7c4SAndroid Build Coastguard Worker *
902*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
903*f81fb7c4SAndroid Build Coastguard Worker */
VMReleaseAllVoices(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)904*f81fb7c4SAndroid Build Coastguard Worker void VMReleaseAllVoices (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
905*f81fb7c4SAndroid Build Coastguard Worker {
906*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
907*f81fb7c4SAndroid Build Coastguard Worker
908*f81fb7c4SAndroid Build Coastguard Worker /* release sustain pedal on all channels */
909*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < NUM_SYNTH_CHANNELS; i++)
910*f81fb7c4SAndroid Build Coastguard Worker {
911*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[ i ].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
912*f81fb7c4SAndroid Build Coastguard Worker {
913*f81fb7c4SAndroid Build Coastguard Worker VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, (EAS_U8) i);
914*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[i].channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
915*f81fb7c4SAndroid Build Coastguard Worker }
916*f81fb7c4SAndroid Build Coastguard Worker }
917*f81fb7c4SAndroid Build Coastguard Worker
918*f81fb7c4SAndroid Build Coastguard Worker /* release all voices */
919*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
920*f81fb7c4SAndroid Build Coastguard Worker {
921*f81fb7c4SAndroid Build Coastguard Worker
922*f81fb7c4SAndroid Build Coastguard Worker switch (pVoiceMgr->voices[i].voiceState)
923*f81fb7c4SAndroid Build Coastguard Worker {
924*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateStart:
925*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStatePlay:
926*f81fb7c4SAndroid Build Coastguard Worker /* only release voices on this synth */
927*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].channel) == pSynth->vSynthNum)
928*f81fb7c4SAndroid Build Coastguard Worker VMReleaseVoice(pVoiceMgr, pSynth, i);
929*f81fb7c4SAndroid Build Coastguard Worker break;
930*f81fb7c4SAndroid Build Coastguard Worker
931*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateStolen:
932*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) == pSynth->vSynthNum)
933*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, i);
934*f81fb7c4SAndroid Build Coastguard Worker break;
935*f81fb7c4SAndroid Build Coastguard Worker
936*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateFree:
937*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateRelease:
938*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateMuting:
939*f81fb7c4SAndroid Build Coastguard Worker break;
940*f81fb7c4SAndroid Build Coastguard Worker
941*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateInvalid:
942*f81fb7c4SAndroid Build Coastguard Worker default:
943*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
944*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllVoices: error, %d is an unrecognized state\n",
945*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[i].voiceState); */ }
946*f81fb7c4SAndroid Build Coastguard Worker #endif
947*f81fb7c4SAndroid Build Coastguard Worker break;
948*f81fb7c4SAndroid Build Coastguard Worker }
949*f81fb7c4SAndroid Build Coastguard Worker }
950*f81fb7c4SAndroid Build Coastguard Worker }
951*f81fb7c4SAndroid Build Coastguard Worker
952*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
953*f81fb7c4SAndroid Build Coastguard Worker * VMAllNotesOff()
954*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
955*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
956*f81fb7c4SAndroid Build Coastguard Worker * Quickly mute all notes on the given channel.
957*f81fb7c4SAndroid Build Coastguard Worker *
958*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
959*f81fb7c4SAndroid Build Coastguard Worker * nChannel - quickly turn off all notes on this channel
960*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
961*f81fb7c4SAndroid Build Coastguard Worker *
962*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
963*f81fb7c4SAndroid Build Coastguard Worker *
964*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
965*f81fb7c4SAndroid Build Coastguard Worker * - forces all voices on this channel to update their envelope states to mute
966*f81fb7c4SAndroid Build Coastguard Worker *
967*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
968*f81fb7c4SAndroid Build Coastguard Worker */
VMAllNotesOff(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel)969*f81fb7c4SAndroid Build Coastguard Worker void VMAllNotesOff (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
970*f81fb7c4SAndroid Build Coastguard Worker {
971*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
972*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
973*f81fb7c4SAndroid Build Coastguard Worker
974*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
975*f81fb7c4SAndroid Build Coastguard Worker if (channel >= NUM_SYNTH_CHANNELS)
976*f81fb7c4SAndroid Build Coastguard Worker {
977*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAllNotesOff: error, %d invalid channel number\n",
978*f81fb7c4SAndroid Build Coastguard Worker channel); */ }
979*f81fb7c4SAndroid Build Coastguard Worker return;
980*f81fb7c4SAndroid Build Coastguard Worker }
981*f81fb7c4SAndroid Build Coastguard Worker #endif
982*f81fb7c4SAndroid Build Coastguard Worker
983*f81fb7c4SAndroid Build Coastguard Worker /* increment workload */
984*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
985*f81fb7c4SAndroid Build Coastguard Worker
986*f81fb7c4SAndroid Build Coastguard Worker /* check each voice */
987*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
988*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
989*f81fb7c4SAndroid Build Coastguard Worker {
990*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pVoiceMgr->voices[voiceNum];
991*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState != eVoiceStateFree)
992*f81fb7c4SAndroid Build Coastguard Worker {
993*f81fb7c4SAndroid Build Coastguard Worker if (((pVoice->voiceState != eVoiceStateStolen) && (channel == pVoice->channel)) ||
994*f81fb7c4SAndroid Build Coastguard Worker ((pVoice->voiceState == eVoiceStateStolen) && (channel == pVoice->nextChannel)))
995*f81fb7c4SAndroid Build Coastguard Worker {
996*f81fb7c4SAndroid Build Coastguard Worker /* this voice is assigned to the requested channel */
997*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pSynth, pVoice, GetAdjustedVoiceNum(voiceNum));
998*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = eVoiceStateMuting;
999*f81fb7c4SAndroid Build Coastguard Worker }
1000*f81fb7c4SAndroid Build Coastguard Worker }
1001*f81fb7c4SAndroid Build Coastguard Worker }
1002*f81fb7c4SAndroid Build Coastguard Worker }
1003*f81fb7c4SAndroid Build Coastguard Worker
1004*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1005*f81fb7c4SAndroid Build Coastguard Worker * VMDeferredStopNote()
1006*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1007*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1008*f81fb7c4SAndroid Build Coastguard Worker * Stop the notes that had deferred note-off requests.
1009*f81fb7c4SAndroid Build Coastguard Worker *
1010*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1011*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1012*f81fb7c4SAndroid Build Coastguard Worker *
1013*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1014*f81fb7c4SAndroid Build Coastguard Worker * None.
1015*f81fb7c4SAndroid Build Coastguard Worker *
1016*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1017*f81fb7c4SAndroid Build Coastguard Worker * voices that have had deferred note-off requests are now put into release
1018*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[i].m_nFlags has the VOICE_FLAG_DEFER_MIDI_NOTE_OFF
1019*f81fb7c4SAndroid Build Coastguard Worker * cleared
1020*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1021*f81fb7c4SAndroid Build Coastguard Worker */
VMDeferredStopNote(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)1022*f81fb7c4SAndroid Build Coastguard Worker void VMDeferredStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
1023*f81fb7c4SAndroid Build Coastguard Worker {
1024*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1025*f81fb7c4SAndroid Build Coastguard Worker EAS_INT channel;
1026*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL deferredNoteOff;
1027*f81fb7c4SAndroid Build Coastguard Worker
1028*f81fb7c4SAndroid Build Coastguard Worker deferredNoteOff = EAS_FALSE;
1029*f81fb7c4SAndroid Build Coastguard Worker
1030*f81fb7c4SAndroid Build Coastguard Worker /* check each voice to see if it requires a deferred note off */
1031*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
1032*f81fb7c4SAndroid Build Coastguard Worker {
1033*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
1034*f81fb7c4SAndroid Build Coastguard Worker {
1035*f81fb7c4SAndroid Build Coastguard Worker /* check if this voice was stolen */
1036*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
1037*f81fb7c4SAndroid Build Coastguard Worker {
1038*f81fb7c4SAndroid Build Coastguard Worker /*
1039*f81fb7c4SAndroid Build Coastguard Worker This voice was stolen, AND it also has a deferred note-off.
1040*f81fb7c4SAndroid Build Coastguard Worker The stolen note must be completely ramped down at this point.
1041*f81fb7c4SAndroid Build Coastguard Worker The note that caused the stealing to occur, however, must
1042*f81fb7c4SAndroid Build Coastguard Worker have received a note-off request before the note that caused
1043*f81fb7c4SAndroid Build Coastguard Worker stealing ever had a chance to even start. We want to give
1044*f81fb7c4SAndroid Build Coastguard Worker the note that caused the stealing a chance to play, so we
1045*f81fb7c4SAndroid Build Coastguard Worker start it on the next update interval, and we defer sending
1046*f81fb7c4SAndroid Build Coastguard Worker the note-off request until the subsequent update interval.
1047*f81fb7c4SAndroid Build Coastguard Worker So do not send the note-off request for this voice because
1048*f81fb7c4SAndroid Build Coastguard Worker this voice was stolen and should have completed ramping down,
1049*f81fb7c4SAndroid Build Coastguard Worker Also, do not clear the global flag nor this voice's flag
1050*f81fb7c4SAndroid Build Coastguard Worker because we must indicate that the subsequent update interval,
1051*f81fb7c4SAndroid Build Coastguard Worker after the note that caused stealing has started, should
1052*f81fb7c4SAndroid Build Coastguard Worker then send the deferred note-off request.
1053*f81fb7c4SAndroid Build Coastguard Worker */
1054*f81fb7c4SAndroid Build Coastguard Worker deferredNoteOff = EAS_TRUE;
1055*f81fb7c4SAndroid Build Coastguard Worker
1056*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1057*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: defer request to stop voice %d (channel=%d note=%d) - voice not started\n",
1058*f81fb7c4SAndroid Build Coastguard Worker voiceNum,
1059*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].nextChannel,
1060*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].note); */ }
1061*f81fb7c4SAndroid Build Coastguard Worker
1062*f81fb7c4SAndroid Build Coastguard Worker /* sanity check: this stolen voice better be ramped to zero */
1063*f81fb7c4SAndroid Build Coastguard Worker if (0 != pVoiceMgr->voices[voiceNum].gain)
1064*f81fb7c4SAndroid Build Coastguard Worker {
1065*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: warning, this voice did not complete its ramp to zero\n"); */ }
1066*f81fb7c4SAndroid Build Coastguard Worker }
1067*f81fb7c4SAndroid Build Coastguard Worker #endif // #ifdef _DEBUG_VM
1068*f81fb7c4SAndroid Build Coastguard Worker
1069*f81fb7c4SAndroid Build Coastguard Worker }
1070*f81fb7c4SAndroid Build Coastguard Worker else
1071*f81fb7c4SAndroid Build Coastguard Worker {
1072*f81fb7c4SAndroid Build Coastguard Worker /* clear the flag using exor */
1073*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags ^=
1074*f81fb7c4SAndroid Build Coastguard Worker VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
1075*f81fb7c4SAndroid Build Coastguard Worker
1076*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1077*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMDeferredStopNote: Stop voice %d (channel=%d note=%d)\n",
1078*f81fb7c4SAndroid Build Coastguard Worker voiceNum,
1079*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].nextChannel,
1080*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].note); */ }
1081*f81fb7c4SAndroid Build Coastguard Worker #endif
1082*f81fb7c4SAndroid Build Coastguard Worker
1083*f81fb7c4SAndroid Build Coastguard Worker channel = pVoiceMgr->voices[voiceNum].channel & 15;
1084*f81fb7c4SAndroid Build Coastguard Worker
1085*f81fb7c4SAndroid Build Coastguard Worker /* check if sustain pedal is on */
1086*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
1087*f81fb7c4SAndroid Build Coastguard Worker {
1088*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
1089*f81fb7c4SAndroid Build Coastguard Worker }
1090*f81fb7c4SAndroid Build Coastguard Worker
1091*f81fb7c4SAndroid Build Coastguard Worker /* release this voice */
1092*f81fb7c4SAndroid Build Coastguard Worker else
1093*f81fb7c4SAndroid Build Coastguard Worker VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
1094*f81fb7c4SAndroid Build Coastguard Worker
1095*f81fb7c4SAndroid Build Coastguard Worker }
1096*f81fb7c4SAndroid Build Coastguard Worker
1097*f81fb7c4SAndroid Build Coastguard Worker }
1098*f81fb7c4SAndroid Build Coastguard Worker
1099*f81fb7c4SAndroid Build Coastguard Worker }
1100*f81fb7c4SAndroid Build Coastguard Worker
1101*f81fb7c4SAndroid Build Coastguard Worker /* clear the deferred note-off flag, unless there's another one pending */
1102*f81fb7c4SAndroid Build Coastguard Worker if (deferredNoteOff == EAS_FALSE)
1103*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags ^= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
1104*f81fb7c4SAndroid Build Coastguard Worker }
1105*f81fb7c4SAndroid Build Coastguard Worker
1106*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1107*f81fb7c4SAndroid Build Coastguard Worker * VMReleaseAllDeferredNoteOffs()
1108*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1109*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1110*f81fb7c4SAndroid Build Coastguard Worker * Call this functin when the sustain flag is presently set but
1111*f81fb7c4SAndroid Build Coastguard Worker * we are now transitioning from damper pedal on to
1112*f81fb7c4SAndroid Build Coastguard Worker * damper pedal off. This means all notes in this channel
1113*f81fb7c4SAndroid Build Coastguard Worker * that received a note off while the damper pedal was on, and
1114*f81fb7c4SAndroid Build Coastguard Worker * had their note-off requests deferred, should now proceed to
1115*f81fb7c4SAndroid Build Coastguard Worker * the release state.
1116*f81fb7c4SAndroid Build Coastguard Worker *
1117*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1118*f81fb7c4SAndroid Build Coastguard Worker * nChannel - this channel has its sustain pedal transitioning from on to off
1119*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1120*f81fb7c4SAndroid Build Coastguard Worker *
1121*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1122*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1123*f81fb7c4SAndroid Build Coastguard Worker * any voice with deferred note offs on this channel are updated such that
1124*f81fb7c4SAndroid Build Coastguard Worker * pVoice->m_sEG1.m_eState = eEnvelopeStateRelease
1125*f81fb7c4SAndroid Build Coastguard Worker * pVoice->m_sEG1.m_nIncrement = release increment
1126*f81fb7c4SAndroid Build Coastguard Worker * pVoice->m_nFlags = clear the deferred note off flag
1127*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1128*f81fb7c4SAndroid Build Coastguard Worker */
VMReleaseAllDeferredNoteOffs(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel)1129*f81fb7c4SAndroid Build Coastguard Worker void VMReleaseAllDeferredNoteOffs (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
1130*f81fb7c4SAndroid Build Coastguard Worker {
1131*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
1132*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1133*f81fb7c4SAndroid Build Coastguard Worker
1134*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1135*f81fb7c4SAndroid Build Coastguard Worker if (channel >= NUM_SYNTH_CHANNELS)
1136*f81fb7c4SAndroid Build Coastguard Worker {
1137*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMReleaseAllDeferredNoteOffs: error, %d invalid channel number\n",
1138*f81fb7c4SAndroid Build Coastguard Worker channel); */ }
1139*f81fb7c4SAndroid Build Coastguard Worker return;
1140*f81fb7c4SAndroid Build Coastguard Worker }
1141*f81fb7c4SAndroid Build Coastguard Worker #endif /* #ifdef _DEBUG_VM */
1142*f81fb7c4SAndroid Build Coastguard Worker
1143*f81fb7c4SAndroid Build Coastguard Worker /* increment workload */
1144*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
1145*f81fb7c4SAndroid Build Coastguard Worker
1146*f81fb7c4SAndroid Build Coastguard Worker /* find all the voices assigned to this channel */
1147*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
1148*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
1149*f81fb7c4SAndroid Build Coastguard Worker {
1150*f81fb7c4SAndroid Build Coastguard Worker
1151*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pVoiceMgr->voices[voiceNum];
1152*f81fb7c4SAndroid Build Coastguard Worker if (channel == pVoice->channel)
1153*f81fb7c4SAndroid Build Coastguard Worker {
1154*f81fb7c4SAndroid Build Coastguard Worker
1155*f81fb7c4SAndroid Build Coastguard Worker /* does this voice have a deferred note off? */
1156*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceFlags & VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF)
1157*f81fb7c4SAndroid Build Coastguard Worker {
1158*f81fb7c4SAndroid Build Coastguard Worker /* release voice */
1159*f81fb7c4SAndroid Build Coastguard Worker VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
1160*f81fb7c4SAndroid Build Coastguard Worker
1161*f81fb7c4SAndroid Build Coastguard Worker /* use exor to flip bit, clear the flag */
1162*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceFlags &= ~VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
1163*f81fb7c4SAndroid Build Coastguard Worker
1164*f81fb7c4SAndroid Build Coastguard Worker }
1165*f81fb7c4SAndroid Build Coastguard Worker
1166*f81fb7c4SAndroid Build Coastguard Worker }
1167*f81fb7c4SAndroid Build Coastguard Worker }
1168*f81fb7c4SAndroid Build Coastguard Worker
1169*f81fb7c4SAndroid Build Coastguard Worker return;
1170*f81fb7c4SAndroid Build Coastguard Worker }
1171*f81fb7c4SAndroid Build Coastguard Worker
1172*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1173*f81fb7c4SAndroid Build Coastguard Worker * VMCatchNotesForSustainPedal()
1174*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1175*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1176*f81fb7c4SAndroid Build Coastguard Worker * Call this function when the sustain flag is presently clear and
1177*f81fb7c4SAndroid Build Coastguard Worker * the damper pedal is off and we are transitioning from damper pedal OFF to
1178*f81fb7c4SAndroid Build Coastguard Worker * damper pedal ON. Currently sounding notes should be left
1179*f81fb7c4SAndroid Build Coastguard Worker * unchanged. However, we should try to "catch" notes if possible.
1180*f81fb7c4SAndroid Build Coastguard Worker * If any notes are in release and have levels >= sustain level, catch them,
1181*f81fb7c4SAndroid Build Coastguard Worker * otherwise, let them continue to release.
1182*f81fb7c4SAndroid Build Coastguard Worker *
1183*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1184*f81fb7c4SAndroid Build Coastguard Worker * nChannel - this channel has its sustain pedal transitioning from on to off
1185*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1186*f81fb7c4SAndroid Build Coastguard Worker *
1187*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1188*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1189*f81fb7c4SAndroid Build Coastguard Worker */
VMCatchNotesForSustainPedal(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel)1190*f81fb7c4SAndroid Build Coastguard Worker void VMCatchNotesForSustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
1191*f81fb7c4SAndroid Build Coastguard Worker {
1192*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1193*f81fb7c4SAndroid Build Coastguard Worker
1194*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1195*f81fb7c4SAndroid Build Coastguard Worker if (channel >= NUM_SYNTH_CHANNELS)
1196*f81fb7c4SAndroid Build Coastguard Worker {
1197*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCatchNotesForSustainPedal: error, %d invalid channel number\n",
1198*f81fb7c4SAndroid Build Coastguard Worker channel); */ }
1199*f81fb7c4SAndroid Build Coastguard Worker return;
1200*f81fb7c4SAndroid Build Coastguard Worker }
1201*f81fb7c4SAndroid Build Coastguard Worker #endif
1202*f81fb7c4SAndroid Build Coastguard Worker
1203*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_SMALL_INCREMENT;
1204*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
1205*f81fb7c4SAndroid Build Coastguard Worker
1206*f81fb7c4SAndroid Build Coastguard Worker /* find all the voices assigned to this channel */
1207*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
1208*f81fb7c4SAndroid Build Coastguard Worker {
1209*f81fb7c4SAndroid Build Coastguard Worker if (channel == pVoiceMgr->voices[voiceNum].channel)
1210*f81fb7c4SAndroid Build Coastguard Worker {
1211*f81fb7c4SAndroid Build Coastguard Worker if (eVoiceStateRelease == pVoiceMgr->voices[voiceNum].voiceState)
1212*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfSustainPedal(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], &pSynth->channels[channel], GetAdjustedVoiceNum(voiceNum));
1213*f81fb7c4SAndroid Build Coastguard Worker }
1214*f81fb7c4SAndroid Build Coastguard Worker }
1215*f81fb7c4SAndroid Build Coastguard Worker }
1216*f81fb7c4SAndroid Build Coastguard Worker
1217*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1218*f81fb7c4SAndroid Build Coastguard Worker * VMUpdateAllNotesAge()
1219*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1220*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1221*f81fb7c4SAndroid Build Coastguard Worker * Increment the note age for all of the active voices.
1222*f81fb7c4SAndroid Build Coastguard Worker *
1223*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1224*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1225*f81fb7c4SAndroid Build Coastguard Worker *
1226*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1227*f81fb7c4SAndroid Build Coastguard Worker *
1228*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1229*f81fb7c4SAndroid Build Coastguard Worker * m_nAge for all voices is incremented
1230*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1231*f81fb7c4SAndroid Build Coastguard Worker */
VMUpdateAllNotesAge(S_VOICE_MGR * pVoiceMgr,EAS_U16 age)1232*f81fb7c4SAndroid Build Coastguard Worker void VMUpdateAllNotesAge (S_VOICE_MGR *pVoiceMgr, EAS_U16 age)
1233*f81fb7c4SAndroid Build Coastguard Worker {
1234*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
1235*f81fb7c4SAndroid Build Coastguard Worker
1236*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
1237*f81fb7c4SAndroid Build Coastguard Worker {
1238*f81fb7c4SAndroid Build Coastguard Worker if (age - pVoiceMgr->voices[i].age > 0)
1239*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[i].age++;
1240*f81fb7c4SAndroid Build Coastguard Worker }
1241*f81fb7c4SAndroid Build Coastguard Worker }
1242*f81fb7c4SAndroid Build Coastguard Worker
1243*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1244*f81fb7c4SAndroid Build Coastguard Worker * VMStolenVoice()
1245*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1246*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1247*f81fb7c4SAndroid Build Coastguard Worker * The selected voice is being stolen. Sets the parameters so that the
1248*f81fb7c4SAndroid Build Coastguard Worker * voice will begin playing the new sound on the next buffer.
1249*f81fb7c4SAndroid Build Coastguard Worker *
1250*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1251*f81fb7c4SAndroid Build Coastguard Worker * pVoice - pointer to voice to steal
1252*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the channel to start a note on
1253*f81fb7c4SAndroid Build Coastguard Worker * nKeyNumber - the key number to start a note for
1254*f81fb7c4SAndroid Build Coastguard Worker * nNoteVelocity - the key velocity from this note
1255*f81fb7c4SAndroid Build Coastguard Worker *
1256*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1257*f81fb7c4SAndroid Build Coastguard Worker * None
1258*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1259*f81fb7c4SAndroid Build Coastguard Worker */
VMStolenVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_I32 voiceNum,EAS_U8 channel,EAS_U8 note,EAS_U8 velocity,EAS_U16 regionIndex)1260*f81fb7c4SAndroid Build Coastguard Worker static void VMStolenVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 voiceNum, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
1261*f81fb7c4SAndroid Build Coastguard Worker {
1262*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
1263*f81fb7c4SAndroid Build Coastguard Worker
1264*f81fb7c4SAndroid Build Coastguard Worker /* one less voice in old pool */
1265*f81fb7c4SAndroid Build Coastguard Worker DecVoicePoolCount(pVoiceMgr, pVoice);
1266*f81fb7c4SAndroid Build Coastguard Worker
1267*f81fb7c4SAndroid Build Coastguard Worker /* mute the sound that is currently playing */
1268*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfMuteVoice(pVoiceMgr, pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)], &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum));
1269*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = eVoiceStateStolen;
1270*f81fb7c4SAndroid Build Coastguard Worker
1271*f81fb7c4SAndroid Build Coastguard Worker /* set new note data */
1272*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextChannel = VSynthToChannel(pSynth, channel);
1273*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextNote = note;
1274*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextVelocity = velocity;
1275*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextRegionIndex = regionIndex;
1276*f81fb7c4SAndroid Build Coastguard Worker
1277*f81fb7c4SAndroid Build Coastguard Worker /* one more voice in new pool */
1278*f81fb7c4SAndroid Build Coastguard Worker IncVoicePoolCount(pVoiceMgr, pVoice);
1279*f81fb7c4SAndroid Build Coastguard Worker
1280*f81fb7c4SAndroid Build Coastguard Worker /* clear the deferred flags */
1281*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceFlags &=
1282*f81fb7c4SAndroid Build Coastguard Worker ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
1283*f81fb7c4SAndroid Build Coastguard Worker VOICE_FLAG_DEFER_MUTE |
1284*f81fb7c4SAndroid Build Coastguard Worker VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF);
1285*f81fb7c4SAndroid Build Coastguard Worker
1286*f81fb7c4SAndroid Build Coastguard Worker /* all notes older than this one get "younger" */
1287*f81fb7c4SAndroid Build Coastguard Worker VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
1288*f81fb7c4SAndroid Build Coastguard Worker
1289*f81fb7c4SAndroid Build Coastguard Worker /* assign current age to this note and increment for the next note */
1290*f81fb7c4SAndroid Build Coastguard Worker pVoice->age = pVoiceMgr->age++;
1291*f81fb7c4SAndroid Build Coastguard Worker }
1292*f81fb7c4SAndroid Build Coastguard Worker
1293*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1294*f81fb7c4SAndroid Build Coastguard Worker * VMFreeVoice()
1295*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1296*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1297*f81fb7c4SAndroid Build Coastguard Worker * The selected voice is done playing and being returned to the
1298*f81fb7c4SAndroid Build Coastguard Worker * pool of free voices
1299*f81fb7c4SAndroid Build Coastguard Worker *
1300*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1301*f81fb7c4SAndroid Build Coastguard Worker * pVoice - pointer to voice to free
1302*f81fb7c4SAndroid Build Coastguard Worker *
1303*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1304*f81fb7c4SAndroid Build Coastguard Worker * None
1305*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1306*f81fb7c4SAndroid Build Coastguard Worker */
VMFreeVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,S_SYNTH_VOICE * pVoice)1307*f81fb7c4SAndroid Build Coastguard Worker static void VMFreeVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
1308*f81fb7c4SAndroid Build Coastguard Worker {
1309*f81fb7c4SAndroid Build Coastguard Worker
1310*f81fb7c4SAndroid Build Coastguard Worker /* do nothing if voice is already free */
1311*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState == eVoiceStateFree)
1312*f81fb7c4SAndroid Build Coastguard Worker {
1313*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMFreeVoice: Attempt to free voice that is already free\n"); */ }
1314*f81fb7c4SAndroid Build Coastguard Worker return;
1315*f81fb7c4SAndroid Build Coastguard Worker }
1316*f81fb7c4SAndroid Build Coastguard Worker
1317*f81fb7c4SAndroid Build Coastguard Worker /* if we jump directly to free without passing muting stage,
1318*f81fb7c4SAndroid Build Coastguard Worker * we need to adjust the voice count */
1319*f81fb7c4SAndroid Build Coastguard Worker DecVoicePoolCount(pVoiceMgr, pVoice);
1320*f81fb7c4SAndroid Build Coastguard Worker
1321*f81fb7c4SAndroid Build Coastguard Worker
1322*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1323*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMFreeVoice: Synth=%d\n", pSynth->vSynthNum); */ }
1324*f81fb7c4SAndroid Build Coastguard Worker #endif
1325*f81fb7c4SAndroid Build Coastguard Worker
1326*f81fb7c4SAndroid Build Coastguard Worker /* return to free voice pool */
1327*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->activeVoices--;
1328*f81fb7c4SAndroid Build Coastguard Worker pSynth->numActiveVoices--;
1329*f81fb7c4SAndroid Build Coastguard Worker InitVoice(pVoice);
1330*f81fb7c4SAndroid Build Coastguard Worker
1331*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1332*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFreeVoice: free voice %d\n", pVoice - pVoiceMgr->voices); */ }
1333*f81fb7c4SAndroid Build Coastguard Worker #endif
1334*f81fb7c4SAndroid Build Coastguard Worker
1335*f81fb7c4SAndroid Build Coastguard Worker /* all notes older than this one get "younger" */
1336*f81fb7c4SAndroid Build Coastguard Worker VMUpdateAllNotesAge(pVoiceMgr, pVoice->age);
1337*f81fb7c4SAndroid Build Coastguard Worker }
1338*f81fb7c4SAndroid Build Coastguard Worker
1339*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1340*f81fb7c4SAndroid Build Coastguard Worker * VMRetargetStolenVoice()
1341*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1342*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1343*f81fb7c4SAndroid Build Coastguard Worker * The selected voice has been stolen and needs to be initalized with
1344*f81fb7c4SAndroid Build Coastguard Worker * the paramters of its new note.
1345*f81fb7c4SAndroid Build Coastguard Worker *
1346*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1347*f81fb7c4SAndroid Build Coastguard Worker * pVoice - pointer to voice to retarget
1348*f81fb7c4SAndroid Build Coastguard Worker *
1349*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1350*f81fb7c4SAndroid Build Coastguard Worker * None
1351*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1352*f81fb7c4SAndroid Build Coastguard Worker */
VMRetargetStolenVoice(S_VOICE_MGR * pVoiceMgr,EAS_I32 voiceNum)1353*f81fb7c4SAndroid Build Coastguard Worker static EAS_BOOL VMRetargetStolenVoice (S_VOICE_MGR *pVoiceMgr, EAS_I32 voiceNum)
1354*f81fb7c4SAndroid Build Coastguard Worker {
1355*f81fb7c4SAndroid Build Coastguard Worker EAS_U8 flags;
1356*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pMIDIChannel;
1357*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
1358*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
1359*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pNextSynth;
1360*f81fb7c4SAndroid Build Coastguard Worker
1361*f81fb7c4SAndroid Build Coastguard Worker /* establish some pointers */
1362*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pVoiceMgr->voices[voiceNum];
1363*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->channel)];
1364*f81fb7c4SAndroid Build Coastguard Worker pMIDIChannel = &pSynth->channels[pVoice->channel & 15];
1365*f81fb7c4SAndroid Build Coastguard Worker pNextSynth = pVoiceMgr->pSynth[GET_VSYNTH(pVoice->nextChannel)];
1366*f81fb7c4SAndroid Build Coastguard Worker
1367*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1368*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: retargeting stolen voice %d on channel %d\n",
1369*f81fb7c4SAndroid Build Coastguard Worker voiceNum, pVoice->channel); */ }
1370*f81fb7c4SAndroid Build Coastguard Worker
1371*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\to channel %d note: %d velocity: %d\n",
1372*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextChannel, pVoice->nextNote, pVoice->nextVelocity); */ }
1373*f81fb7c4SAndroid Build Coastguard Worker #endif
1374*f81fb7c4SAndroid Build Coastguard Worker
1375*f81fb7c4SAndroid Build Coastguard Worker /* make sure new channel hasn't been muted by SP-MIDI since the voice was stolen */
1376*f81fb7c4SAndroid Build Coastguard Worker if ((pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON) &&
1377*f81fb7c4SAndroid Build Coastguard Worker (pMIDIChannel->channelFlags & CHANNEL_FLAG_MUTE))
1378*f81fb7c4SAndroid Build Coastguard Worker {
1379*f81fb7c4SAndroid Build Coastguard Worker VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
1380*f81fb7c4SAndroid Build Coastguard Worker return EAS_FALSE;
1381*f81fb7c4SAndroid Build Coastguard Worker }
1382*f81fb7c4SAndroid Build Coastguard Worker
1383*f81fb7c4SAndroid Build Coastguard Worker /* if assigned to a new synth, correct the active voice count */
1384*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->channel != pVoice->nextChannel)
1385*f81fb7c4SAndroid Build Coastguard Worker {
1386*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1387*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetStolenVoice: Note assigned to different virtual synth, adjusting numActiveVoices\n"); */ }
1388*f81fb7c4SAndroid Build Coastguard Worker #endif
1389*f81fb7c4SAndroid Build Coastguard Worker pSynth->numActiveVoices--;
1390*f81fb7c4SAndroid Build Coastguard Worker pNextSynth->numActiveVoices++;
1391*f81fb7c4SAndroid Build Coastguard Worker }
1392*f81fb7c4SAndroid Build Coastguard Worker
1393*f81fb7c4SAndroid Build Coastguard Worker /* assign new channel number, and increase channel voice count */
1394*f81fb7c4SAndroid Build Coastguard Worker pVoice->channel = pVoice->nextChannel;
1395*f81fb7c4SAndroid Build Coastguard Worker pMIDIChannel = &pNextSynth->channels[pVoice->channel & 15];
1396*f81fb7c4SAndroid Build Coastguard Worker
1397*f81fb7c4SAndroid Build Coastguard Worker /* assign other data */
1398*f81fb7c4SAndroid Build Coastguard Worker pVoice->note = pVoice->nextNote;
1399*f81fb7c4SAndroid Build Coastguard Worker pVoice->velocity = pVoice->nextVelocity;
1400*f81fb7c4SAndroid Build Coastguard Worker pVoice->nextChannel = UNASSIGNED_SYNTH_CHANNEL;
1401*f81fb7c4SAndroid Build Coastguard Worker pVoice->regionIndex = pVoice->nextRegionIndex;
1402*f81fb7c4SAndroid Build Coastguard Worker
1403*f81fb7c4SAndroid Build Coastguard Worker /* save the flags, pfStartVoice() will clear them */
1404*f81fb7c4SAndroid Build Coastguard Worker flags = pVoice->voiceFlags;
1405*f81fb7c4SAndroid Build Coastguard Worker
1406*f81fb7c4SAndroid Build Coastguard Worker /* keep track of the note-start related workload */
1407*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_START_NOTE;
1408*f81fb7c4SAndroid Build Coastguard Worker
1409*f81fb7c4SAndroid Build Coastguard Worker /* setup the voice parameters */
1410*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceState = eVoiceStateStart;
1411*f81fb7c4SAndroid Build Coastguard Worker
1412*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{522} return not used at this time */
1413*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pNextSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pVoice->regionIndex);
1414*f81fb7c4SAndroid Build Coastguard Worker
1415*f81fb7c4SAndroid Build Coastguard Worker /* did the new note already receive a MIDI note-off request? */
1416*f81fb7c4SAndroid Build Coastguard Worker if (flags & VOICE_FLAG_DEFER_MIDI_NOTE_OFF)
1417*f81fb7c4SAndroid Build Coastguard Worker {
1418*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1419*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMRetargetVoice: stolen note note-off request deferred\n"); */ }
1420*f81fb7c4SAndroid Build Coastguard Worker #endif
1421*f81fb7c4SAndroid Build Coastguard Worker pVoice->voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
1422*f81fb7c4SAndroid Build Coastguard Worker pNextSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
1423*f81fb7c4SAndroid Build Coastguard Worker }
1424*f81fb7c4SAndroid Build Coastguard Worker
1425*f81fb7c4SAndroid Build Coastguard Worker return EAS_TRUE;
1426*f81fb7c4SAndroid Build Coastguard Worker }
1427*f81fb7c4SAndroid Build Coastguard Worker
1428*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1429*f81fb7c4SAndroid Build Coastguard Worker * VMCheckKeyGroup()
1430*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1431*f81fb7c4SAndroid Build Coastguard Worker * If the note that we've been asked to start is in the same key group as
1432*f81fb7c4SAndroid Build Coastguard Worker * any currently playing notes, then we must shut down the currently playing
1433*f81fb7c4SAndroid Build Coastguard Worker * note in the same key group
1434*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1435*f81fb7c4SAndroid Build Coastguard Worker */
VMCheckKeyGroup(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U16 keyGroup,EAS_U8 channel)1436*f81fb7c4SAndroid Build Coastguard Worker void VMCheckKeyGroup (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U16 keyGroup, EAS_U8 channel)
1437*f81fb7c4SAndroid Build Coastguard Worker {
1438*f81fb7c4SAndroid Build Coastguard Worker const S_REGION *pRegion;
1439*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1440*f81fb7c4SAndroid Build Coastguard Worker
1441*f81fb7c4SAndroid Build Coastguard Worker /* increment frame workload */
1442*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_KEY_GROUP;
1443*f81fb7c4SAndroid Build Coastguard Worker
1444*f81fb7c4SAndroid Build Coastguard Worker /* need to check all voices in case this is a layered sound */
1445*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
1446*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
1447*f81fb7c4SAndroid Build Coastguard Worker {
1448*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
1449*f81fb7c4SAndroid Build Coastguard Worker {
1450*f81fb7c4SAndroid Build Coastguard Worker /* voice must be on the same channel */
1451*f81fb7c4SAndroid Build Coastguard Worker if (channel == pVoiceMgr->voices[voiceNum].channel)
1452*f81fb7c4SAndroid Build Coastguard Worker {
1453*f81fb7c4SAndroid Build Coastguard Worker /* check key group */
1454*f81fb7c4SAndroid Build Coastguard Worker pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].regionIndex);
1455*f81fb7c4SAndroid Build Coastguard Worker if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
1456*f81fb7c4SAndroid Build Coastguard Worker {
1457*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1458*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
1459*f81fb7c4SAndroid Build Coastguard Worker #endif
1460*f81fb7c4SAndroid Build Coastguard Worker
1461*f81fb7c4SAndroid Build Coastguard Worker /* if this voice was just started, set it to mute on the next buffer */
1462*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
1463*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
1464*f81fb7c4SAndroid Build Coastguard Worker
1465*f81fb7c4SAndroid Build Coastguard Worker /* mute immediately */
1466*f81fb7c4SAndroid Build Coastguard Worker else
1467*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, voiceNum);
1468*f81fb7c4SAndroid Build Coastguard Worker }
1469*f81fb7c4SAndroid Build Coastguard Worker }
1470*f81fb7c4SAndroid Build Coastguard Worker }
1471*f81fb7c4SAndroid Build Coastguard Worker
1472*f81fb7c4SAndroid Build Coastguard Worker /* for stolen voice, check new values */
1473*f81fb7c4SAndroid Build Coastguard Worker else
1474*f81fb7c4SAndroid Build Coastguard Worker {
1475*f81fb7c4SAndroid Build Coastguard Worker /* voice must be on the same channel */
1476*f81fb7c4SAndroid Build Coastguard Worker if (channel == pVoiceMgr->voices[voiceNum].nextChannel)
1477*f81fb7c4SAndroid Build Coastguard Worker {
1478*f81fb7c4SAndroid Build Coastguard Worker /* check key group */
1479*f81fb7c4SAndroid Build Coastguard Worker pRegion = GetRegionPtr(pSynth, pVoiceMgr->voices[voiceNum].nextRegionIndex);
1480*f81fb7c4SAndroid Build Coastguard Worker if (keyGroup == (pRegion->keyGroupAndFlags & 0x0f00))
1481*f81fb7c4SAndroid Build Coastguard Worker {
1482*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1483*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckKeyGroup: voice %d matches key group %d\n", voiceNum, keyGroup >> 8); */ }
1484*f81fb7c4SAndroid Build Coastguard Worker #endif
1485*f81fb7c4SAndroid Build Coastguard Worker
1486*f81fb7c4SAndroid Build Coastguard Worker /* if this voice was just started, set it to mute on the next buffer */
1487*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
1488*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MUTE;
1489*f81fb7c4SAndroid Build Coastguard Worker
1490*f81fb7c4SAndroid Build Coastguard Worker /* mute immediately */
1491*f81fb7c4SAndroid Build Coastguard Worker else
1492*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, voiceNum);
1493*f81fb7c4SAndroid Build Coastguard Worker }
1494*f81fb7c4SAndroid Build Coastguard Worker }
1495*f81fb7c4SAndroid Build Coastguard Worker
1496*f81fb7c4SAndroid Build Coastguard Worker }
1497*f81fb7c4SAndroid Build Coastguard Worker }
1498*f81fb7c4SAndroid Build Coastguard Worker }
1499*f81fb7c4SAndroid Build Coastguard Worker
1500*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1501*f81fb7c4SAndroid Build Coastguard Worker * VMCheckPolyphonyLimiting()
1502*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1503*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1504*f81fb7c4SAndroid Build Coastguard Worker * We only play at most 2 of the same note on a MIDI channel.
1505*f81fb7c4SAndroid Build Coastguard Worker * E.g., if we are asked to start note 36, and there are already two voices
1506*f81fb7c4SAndroid Build Coastguard Worker * that are playing note 36, then we must steal the voice playing
1507*f81fb7c4SAndroid Build Coastguard Worker * the oldest note 36 and use that stolen voice to play the new note 36.
1508*f81fb7c4SAndroid Build Coastguard Worker *
1509*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1510*f81fb7c4SAndroid Build Coastguard Worker * nChannel - synth channel that wants to start a new note
1511*f81fb7c4SAndroid Build Coastguard Worker * nKeyNumber - new note's midi note number
1512*f81fb7c4SAndroid Build Coastguard Worker * nNoteVelocity - new note's velocity
1513*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1514*f81fb7c4SAndroid Build Coastguard Worker *
1515*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1516*f81fb7c4SAndroid Build Coastguard Worker * pbVoiceStealingRequired - flag: this routine sets true if we needed to
1517*f81fb7c4SAndroid Build Coastguard Worker * steal a voice
1518*f81fb7c4SAndroid Build Coastguard Worker * *
1519*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1520*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nKeyNumber may be assigned
1521*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nVelocity may be assigned
1522*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1523*f81fb7c4SAndroid Build Coastguard Worker */
VMCheckPolyphonyLimiting(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 note,EAS_U8 velocity,EAS_U16 regionIndex,EAS_I32 lowVoice,EAS_I32 highVoice)1524*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL VMCheckPolyphonyLimiting (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex, EAS_I32 lowVoice, EAS_I32 highVoice)
1525*f81fb7c4SAndroid Build Coastguard Worker {
1526*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1527*f81fb7c4SAndroid Build Coastguard Worker EAS_INT oldestVoiceNum;
1528*f81fb7c4SAndroid Build Coastguard Worker EAS_INT numVoicesPlayingNote;
1529*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 age;
1530*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 oldestNoteAge;
1531*f81fb7c4SAndroid Build Coastguard Worker
1532*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_POLY_LIMIT;
1533*f81fb7c4SAndroid Build Coastguard Worker
1534*f81fb7c4SAndroid Build Coastguard Worker numVoicesPlayingNote = 0;
1535*f81fb7c4SAndroid Build Coastguard Worker oldestVoiceNum = MAX_SYNTH_VOICES;
1536*f81fb7c4SAndroid Build Coastguard Worker oldestNoteAge = 0;
1537*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
1538*f81fb7c4SAndroid Build Coastguard Worker
1539*f81fb7c4SAndroid Build Coastguard Worker /* examine each voice on this channel playing this note */
1540*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
1541*f81fb7c4SAndroid Build Coastguard Worker {
1542*f81fb7c4SAndroid Build Coastguard Worker /* check stolen notes separately */
1543*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateStolen)
1544*f81fb7c4SAndroid Build Coastguard Worker {
1545*f81fb7c4SAndroid Build Coastguard Worker
1546*f81fb7c4SAndroid Build Coastguard Worker /* same channel and note ? */
1547*f81fb7c4SAndroid Build Coastguard Worker if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
1548*f81fb7c4SAndroid Build Coastguard Worker {
1549*f81fb7c4SAndroid Build Coastguard Worker numVoicesPlayingNote++;
1550*f81fb7c4SAndroid Build Coastguard Worker age = pVoiceMgr->age - pVoiceMgr->voices[voiceNum].age;
1551*f81fb7c4SAndroid Build Coastguard Worker
1552*f81fb7c4SAndroid Build Coastguard Worker /* is this the oldest voice for this note? */
1553*f81fb7c4SAndroid Build Coastguard Worker if (age >= oldestNoteAge)
1554*f81fb7c4SAndroid Build Coastguard Worker {
1555*f81fb7c4SAndroid Build Coastguard Worker oldestNoteAge = age;
1556*f81fb7c4SAndroid Build Coastguard Worker oldestVoiceNum = voiceNum;
1557*f81fb7c4SAndroid Build Coastguard Worker }
1558*f81fb7c4SAndroid Build Coastguard Worker }
1559*f81fb7c4SAndroid Build Coastguard Worker }
1560*f81fb7c4SAndroid Build Coastguard Worker
1561*f81fb7c4SAndroid Build Coastguard Worker /* handle stolen voices */
1562*f81fb7c4SAndroid Build Coastguard Worker else
1563*f81fb7c4SAndroid Build Coastguard Worker {
1564*f81fb7c4SAndroid Build Coastguard Worker /* same channel and note ? */
1565*f81fb7c4SAndroid Build Coastguard Worker if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
1566*f81fb7c4SAndroid Build Coastguard Worker {
1567*f81fb7c4SAndroid Build Coastguard Worker numVoicesPlayingNote++;
1568*f81fb7c4SAndroid Build Coastguard Worker }
1569*f81fb7c4SAndroid Build Coastguard Worker }
1570*f81fb7c4SAndroid Build Coastguard Worker }
1571*f81fb7c4SAndroid Build Coastguard Worker
1572*f81fb7c4SAndroid Build Coastguard Worker /* check to see if we exceeded poly limit */
1573*f81fb7c4SAndroid Build Coastguard Worker if (numVoicesPlayingNote < DEFAULT_CHANNEL_POLYPHONY_LIMIT)
1574*f81fb7c4SAndroid Build Coastguard Worker return EAS_FALSE;
1575*f81fb7c4SAndroid Build Coastguard Worker
1576*f81fb7c4SAndroid Build Coastguard Worker /* make sure we have a voice to steal */
1577*f81fb7c4SAndroid Build Coastguard Worker if (oldestVoiceNum != MAX_SYNTH_VOICES)
1578*f81fb7c4SAndroid Build Coastguard Worker {
1579*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1580*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMCheckPolyphonyLimiting: voice %d has the oldest note\n", oldestVoiceNum); */ }
1581*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMCheckPolyphonyLimiting: polyphony limiting requires shutting down note %d \n", pVoiceMgr->voices[oldestVoiceNum].note); */ }
1582*f81fb7c4SAndroid Build Coastguard Worker #endif
1583*f81fb7c4SAndroid Build Coastguard Worker VMStolenVoice(pVoiceMgr, pSynth, oldestVoiceNum, channel, note, velocity, regionIndex);
1584*f81fb7c4SAndroid Build Coastguard Worker return EAS_TRUE;
1585*f81fb7c4SAndroid Build Coastguard Worker }
1586*f81fb7c4SAndroid Build Coastguard Worker
1587*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1588*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMCheckPolyphonyLimiting: No oldest voice to steal\n"); */ }
1589*f81fb7c4SAndroid Build Coastguard Worker #endif
1590*f81fb7c4SAndroid Build Coastguard Worker return EAS_FALSE;
1591*f81fb7c4SAndroid Build Coastguard Worker }
1592*f81fb7c4SAndroid Build Coastguard Worker
1593*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1594*f81fb7c4SAndroid Build Coastguard Worker * VMStartVoice()
1595*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1596*f81fb7c4SAndroid Build Coastguard Worker * Starts a voice given a region index
1597*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1598*f81fb7c4SAndroid Build Coastguard Worker */
VMStartVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 note,EAS_U8 velocity,EAS_U16 regionIndex)1599*f81fb7c4SAndroid Build Coastguard Worker void VMStartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity, EAS_U16 regionIndex)
1600*f81fb7c4SAndroid Build Coastguard Worker {
1601*f81fb7c4SAndroid Build Coastguard Worker const S_REGION *pRegion;
1602*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
1603*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1604*f81fb7c4SAndroid Build Coastguard Worker EAS_INT maxSynthPoly;
1605*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 lowVoice, highVoice;
1606*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 keyGroup;
1607*f81fb7c4SAndroid Build Coastguard Worker
1608*f81fb7c4SAndroid Build Coastguard Worker pChannel = &pSynth->channels[channel];
1609*f81fb7c4SAndroid Build Coastguard Worker pRegion = GetRegionPtr(pSynth, regionIndex);
1610*f81fb7c4SAndroid Build Coastguard Worker
1611*f81fb7c4SAndroid Build Coastguard Worker /* select correct synth */
1612*f81fb7c4SAndroid Build Coastguard Worker #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
1613*f81fb7c4SAndroid Build Coastguard Worker {
1614*f81fb7c4SAndroid Build Coastguard Worker #ifdef EAS_SPLIT_WT_SYNTH
1615*f81fb7c4SAndroid Build Coastguard Worker if ((pRegion->keyGroupAndFlags & REGION_FLAG_OFF_CHIP) == 0)
1616*f81fb7c4SAndroid Build Coastguard Worker #else
1617*f81fb7c4SAndroid Build Coastguard Worker if ((regionIndex & FLAG_RGN_IDX_FM_SYNTH) == 0)
1618*f81fb7c4SAndroid Build Coastguard Worker #endif
1619*f81fb7c4SAndroid Build Coastguard Worker {
1620*f81fb7c4SAndroid Build Coastguard Worker lowVoice = 0;
1621*f81fb7c4SAndroid Build Coastguard Worker highVoice = NUM_PRIMARY_VOICES - 1;
1622*f81fb7c4SAndroid Build Coastguard Worker }
1623*f81fb7c4SAndroid Build Coastguard Worker else
1624*f81fb7c4SAndroid Build Coastguard Worker {
1625*f81fb7c4SAndroid Build Coastguard Worker lowVoice = NUM_PRIMARY_VOICES;
1626*f81fb7c4SAndroid Build Coastguard Worker highVoice = MAX_SYNTH_VOICES - 1;
1627*f81fb7c4SAndroid Build Coastguard Worker }
1628*f81fb7c4SAndroid Build Coastguard Worker }
1629*f81fb7c4SAndroid Build Coastguard Worker #else
1630*f81fb7c4SAndroid Build Coastguard Worker lowVoice = 0;
1631*f81fb7c4SAndroid Build Coastguard Worker highVoice = MAX_SYNTH_VOICES - 1;
1632*f81fb7c4SAndroid Build Coastguard Worker #endif
1633*f81fb7c4SAndroid Build Coastguard Worker
1634*f81fb7c4SAndroid Build Coastguard Worker /* keep track of the note-start related workload */
1635*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload+= WORKLOAD_AMOUNT_START_NOTE;
1636*f81fb7c4SAndroid Build Coastguard Worker
1637*f81fb7c4SAndroid Build Coastguard Worker /* other voices in pool, check for key group and poly limiting */
1638*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->poolCount[pChannel->pool] != 0)
1639*f81fb7c4SAndroid Build Coastguard Worker {
1640*f81fb7c4SAndroid Build Coastguard Worker
1641*f81fb7c4SAndroid Build Coastguard Worker /* check for key group exclusivity */
1642*f81fb7c4SAndroid Build Coastguard Worker keyGroup = pRegion->keyGroupAndFlags & 0x0f00;
1643*f81fb7c4SAndroid Build Coastguard Worker if (keyGroup!= 0)
1644*f81fb7c4SAndroid Build Coastguard Worker VMCheckKeyGroup(pVoiceMgr, pSynth, keyGroup, channel);
1645*f81fb7c4SAndroid Build Coastguard Worker
1646*f81fb7c4SAndroid Build Coastguard Worker /* check polyphony limit and steal a voice if necessary */
1647*f81fb7c4SAndroid Build Coastguard Worker if ((pRegion->keyGroupAndFlags & REGION_FLAG_NON_SELF_EXCLUSIVE) == 0)
1648*f81fb7c4SAndroid Build Coastguard Worker {
1649*f81fb7c4SAndroid Build Coastguard Worker if (VMCheckPolyphonyLimiting(pVoiceMgr, pSynth, channel, note, velocity, regionIndex, lowVoice, highVoice) == EAS_TRUE)
1650*f81fb7c4SAndroid Build Coastguard Worker return;
1651*f81fb7c4SAndroid Build Coastguard Worker }
1652*f81fb7c4SAndroid Build Coastguard Worker }
1653*f81fb7c4SAndroid Build Coastguard Worker
1654*f81fb7c4SAndroid Build Coastguard Worker /* check max poly allocation */
1655*f81fb7c4SAndroid Build Coastguard Worker if ((pSynth->maxPolyphony == 0) || (pVoiceMgr->maxPolyphony < pSynth->maxPolyphony))
1656*f81fb7c4SAndroid Build Coastguard Worker maxSynthPoly = pVoiceMgr->maxPolyphony;
1657*f81fb7c4SAndroid Build Coastguard Worker else
1658*f81fb7c4SAndroid Build Coastguard Worker maxSynthPoly = pSynth->maxPolyphony;
1659*f81fb7c4SAndroid Build Coastguard Worker
1660*f81fb7c4SAndroid Build Coastguard Worker /* any free voices? */
1661*f81fb7c4SAndroid Build Coastguard Worker if ((pVoiceMgr->activeVoices < pVoiceMgr->maxPolyphony) &&
1662*f81fb7c4SAndroid Build Coastguard Worker (pSynth->numActiveVoices < maxSynthPoly) &&
1663*f81fb7c4SAndroid Build Coastguard Worker (EAS_SUCCESS == VMFindAvailableVoice(pVoiceMgr, &voiceNum, lowVoice, highVoice)))
1664*f81fb7c4SAndroid Build Coastguard Worker {
1665*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice = &pVoiceMgr->voices[voiceNum];
1666*f81fb7c4SAndroid Build Coastguard Worker
1667*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1668*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMStartVoice: Synth=%d\n", pSynth->vSynthNum); */ }
1669*f81fb7c4SAndroid Build Coastguard Worker #endif
1670*f81fb7c4SAndroid Build Coastguard Worker
1671*f81fb7c4SAndroid Build Coastguard Worker /* bump voice counts */
1672*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->activeVoices++;
1673*f81fb7c4SAndroid Build Coastguard Worker pSynth->numActiveVoices++;
1674*f81fb7c4SAndroid Build Coastguard Worker
1675*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1676*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: voice %d assigned to channel %d note %d velocity %d\n",
1677*f81fb7c4SAndroid Build Coastguard Worker voiceNum, channel, note, velocity); */ }
1678*f81fb7c4SAndroid Build Coastguard Worker #endif
1679*f81fb7c4SAndroid Build Coastguard Worker
1680*f81fb7c4SAndroid Build Coastguard Worker /* save parameters */
1681*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].channel = VSynthToChannel(pSynth, channel);
1682*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].note = note;
1683*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].velocity = velocity;
1684*f81fb7c4SAndroid Build Coastguard Worker
1685*f81fb7c4SAndroid Build Coastguard Worker /* establish note age for voice stealing */
1686*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].age = pVoiceMgr->age++;
1687*f81fb7c4SAndroid Build Coastguard Worker
1688*f81fb7c4SAndroid Build Coastguard Worker /* setup the synthesis parameters */
1689*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceState = eVoiceStateStart;
1690*f81fb7c4SAndroid Build Coastguard Worker
1691*f81fb7c4SAndroid Build Coastguard Worker /* increment voice pool count */
1692*f81fb7c4SAndroid Build Coastguard Worker IncVoicePoolCount(pVoiceMgr, pVoice);
1693*f81fb7c4SAndroid Build Coastguard Worker
1694*f81fb7c4SAndroid Build Coastguard Worker /* start voice on correct synth */
1695*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{522} return not used at this time */
1696*f81fb7c4SAndroid Build Coastguard Worker GetSynthPtr(voiceNum)->pfStartVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), regionIndex);
1697*f81fb7c4SAndroid Build Coastguard Worker return;
1698*f81fb7c4SAndroid Build Coastguard Worker }
1699*f81fb7c4SAndroid Build Coastguard Worker
1700*f81fb7c4SAndroid Build Coastguard Worker /* no free voices, we have to steal one using appropriate algorithm */
1701*f81fb7c4SAndroid Build Coastguard Worker if (VMStealVoice(pVoiceMgr, pSynth, &voiceNum, channel, note, lowVoice, highVoice) == EAS_SUCCESS)
1702*f81fb7c4SAndroid Build Coastguard Worker VMStolenVoice(pVoiceMgr, pSynth, voiceNum, channel, note, velocity, regionIndex);
1703*f81fb7c4SAndroid Build Coastguard Worker
1704*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1705*f81fb7c4SAndroid Build Coastguard Worker else
1706*f81fb7c4SAndroid Build Coastguard Worker {
1707*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStartVoice: Could not steal a voice for channel %d note %d velocity %d\n",
1708*f81fb7c4SAndroid Build Coastguard Worker channel, note, velocity); */ }
1709*f81fb7c4SAndroid Build Coastguard Worker }
1710*f81fb7c4SAndroid Build Coastguard Worker #endif
1711*f81fb7c4SAndroid Build Coastguard Worker
1712*f81fb7c4SAndroid Build Coastguard Worker return;
1713*f81fb7c4SAndroid Build Coastguard Worker }
1714*f81fb7c4SAndroid Build Coastguard Worker
1715*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1716*f81fb7c4SAndroid Build Coastguard Worker * VMStartNote()
1717*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1718*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1719*f81fb7c4SAndroid Build Coastguard Worker * Update the synth's state to play the requested note on the requested
1720*f81fb7c4SAndroid Build Coastguard Worker * channel if possible.
1721*f81fb7c4SAndroid Build Coastguard Worker *
1722*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1723*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the channel to start a note on
1724*f81fb7c4SAndroid Build Coastguard Worker * nKeyNumber - the key number to start a note for
1725*f81fb7c4SAndroid Build Coastguard Worker * nNoteVelocity - the key velocity from this note
1726*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1727*f81fb7c4SAndroid Build Coastguard Worker *
1728*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1729*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1730*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_nNumActiveVoices may be incremented
1731*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
1732*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
1733*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
1734*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1735*f81fb7c4SAndroid Build Coastguard Worker */
VMStartNote(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 note,EAS_U8 velocity)1736*f81fb7c4SAndroid Build Coastguard Worker void VMStartNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
1737*f81fb7c4SAndroid Build Coastguard Worker {
1738*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
1739*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 regionIndex;
1740*f81fb7c4SAndroid Build Coastguard Worker EAS_I16 adjustedNote;
1741*f81fb7c4SAndroid Build Coastguard Worker
1742*f81fb7c4SAndroid Build Coastguard Worker /* bump note count */
1743*f81fb7c4SAndroid Build Coastguard Worker pSynth->totalNoteCount++;
1744*f81fb7c4SAndroid Build Coastguard Worker
1745*f81fb7c4SAndroid Build Coastguard Worker pChannel = &pSynth->channels[channel];
1746*f81fb7c4SAndroid Build Coastguard Worker
1747*f81fb7c4SAndroid Build Coastguard Worker /* check channel mute */
1748*f81fb7c4SAndroid Build Coastguard Worker if (pChannel->channelFlags & CHANNEL_FLAG_MUTE)
1749*f81fb7c4SAndroid Build Coastguard Worker return;
1750*f81fb7c4SAndroid Build Coastguard Worker
1751*f81fb7c4SAndroid Build Coastguard Worker #ifdef EXTERNAL_AUDIO
1752*f81fb7c4SAndroid Build Coastguard Worker /* pass event to external audio when requested */
1753*f81fb7c4SAndroid Build Coastguard Worker if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
1754*f81fb7c4SAndroid Build Coastguard Worker {
1755*f81fb7c4SAndroid Build Coastguard Worker S_EXT_AUDIO_EVENT event;
1756*f81fb7c4SAndroid Build Coastguard Worker event.channel = channel;
1757*f81fb7c4SAndroid Build Coastguard Worker event.note = note;
1758*f81fb7c4SAndroid Build Coastguard Worker event.velocity = velocity;
1759*f81fb7c4SAndroid Build Coastguard Worker event.noteOn = EAS_TRUE;
1760*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
1761*f81fb7c4SAndroid Build Coastguard Worker return;
1762*f81fb7c4SAndroid Build Coastguard Worker }
1763*f81fb7c4SAndroid Build Coastguard Worker #endif
1764*f81fb7c4SAndroid Build Coastguard Worker
1765*f81fb7c4SAndroid Build Coastguard Worker /* start search at first region */
1766*f81fb7c4SAndroid Build Coastguard Worker regionIndex = pChannel->regionIndex;
1767*f81fb7c4SAndroid Build Coastguard Worker
1768*f81fb7c4SAndroid Build Coastguard Worker /* handle transposition */
1769*f81fb7c4SAndroid Build Coastguard Worker adjustedNote = note;
1770*f81fb7c4SAndroid Build Coastguard Worker if (pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
1771*f81fb7c4SAndroid Build Coastguard Worker adjustedNote += pChannel->coarsePitch;
1772*f81fb7c4SAndroid Build Coastguard Worker else
1773*f81fb7c4SAndroid Build Coastguard Worker adjustedNote += pChannel->coarsePitch + pSynth->globalTranspose;
1774*f81fb7c4SAndroid Build Coastguard Worker
1775*f81fb7c4SAndroid Build Coastguard Worker /* limit adjusted key number so it does not wraparound, over/underflow */
1776*f81fb7c4SAndroid Build Coastguard Worker if (adjustedNote < 0)
1777*f81fb7c4SAndroid Build Coastguard Worker {
1778*f81fb7c4SAndroid Build Coastguard Worker adjustedNote = 0;
1779*f81fb7c4SAndroid Build Coastguard Worker }
1780*f81fb7c4SAndroid Build Coastguard Worker else if (adjustedNote > 127)
1781*f81fb7c4SAndroid Build Coastguard Worker {
1782*f81fb7c4SAndroid Build Coastguard Worker adjustedNote = 127;
1783*f81fb7c4SAndroid Build Coastguard Worker }
1784*f81fb7c4SAndroid Build Coastguard Worker
1785*f81fb7c4SAndroid Build Coastguard Worker #if defined(DLS_SYNTHESIZER)
1786*f81fb7c4SAndroid Build Coastguard Worker if (regionIndex & FLAG_RGN_IDX_DLS_SYNTH)
1787*f81fb7c4SAndroid Build Coastguard Worker {
1788*f81fb7c4SAndroid Build Coastguard Worker /* DLS voice */
1789*f81fb7c4SAndroid Build Coastguard Worker for (;;)
1790*f81fb7c4SAndroid Build Coastguard Worker {
1791*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{740,826} cast OK, we know this is actually a DLS region */
1792*f81fb7c4SAndroid Build Coastguard Worker const S_DLS_REGION *pDLSRegion = (S_DLS_REGION*) GetRegionPtr(pSynth, regionIndex);
1793*f81fb7c4SAndroid Build Coastguard Worker
1794*f81fb7c4SAndroid Build Coastguard Worker /* check key against this region's key and velocity range */
1795*f81fb7c4SAndroid Build Coastguard Worker if (((adjustedNote >= pDLSRegion->wtRegion.region.rangeLow) && (adjustedNote <= pDLSRegion->wtRegion.region.rangeHigh)) &&
1796*f81fb7c4SAndroid Build Coastguard Worker ((velocity >= pDLSRegion->velLow) && (velocity <= pDLSRegion->velHigh)))
1797*f81fb7c4SAndroid Build Coastguard Worker {
1798*f81fb7c4SAndroid Build Coastguard Worker VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
1799*f81fb7c4SAndroid Build Coastguard Worker }
1800*f81fb7c4SAndroid Build Coastguard Worker
1801*f81fb7c4SAndroid Build Coastguard Worker /* last region in program? */
1802*f81fb7c4SAndroid Build Coastguard Worker if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
1803*f81fb7c4SAndroid Build Coastguard Worker break;
1804*f81fb7c4SAndroid Build Coastguard Worker
1805*f81fb7c4SAndroid Build Coastguard Worker /* advance to next region */
1806*f81fb7c4SAndroid Build Coastguard Worker regionIndex++;
1807*f81fb7c4SAndroid Build Coastguard Worker }
1808*f81fb7c4SAndroid Build Coastguard Worker }
1809*f81fb7c4SAndroid Build Coastguard Worker else
1810*f81fb7c4SAndroid Build Coastguard Worker #endif
1811*f81fb7c4SAndroid Build Coastguard Worker
1812*f81fb7c4SAndroid Build Coastguard Worker /* braces here for #if clause */
1813*f81fb7c4SAndroid Build Coastguard Worker {
1814*f81fb7c4SAndroid Build Coastguard Worker /* EAS voice */
1815*f81fb7c4SAndroid Build Coastguard Worker for (;;)
1816*f81fb7c4SAndroid Build Coastguard Worker {
1817*f81fb7c4SAndroid Build Coastguard Worker const S_REGION *pRegion = GetRegionPtr(pSynth, regionIndex);
1818*f81fb7c4SAndroid Build Coastguard Worker
1819*f81fb7c4SAndroid Build Coastguard Worker /* check key against this region's keyrange */
1820*f81fb7c4SAndroid Build Coastguard Worker if ((adjustedNote >= pRegion->rangeLow) && (adjustedNote <= pRegion->rangeHigh))
1821*f81fb7c4SAndroid Build Coastguard Worker {
1822*f81fb7c4SAndroid Build Coastguard Worker VMStartVoice(pVoiceMgr, pSynth, channel, note, velocity, regionIndex);
1823*f81fb7c4SAndroid Build Coastguard Worker break;
1824*f81fb7c4SAndroid Build Coastguard Worker }
1825*f81fb7c4SAndroid Build Coastguard Worker
1826*f81fb7c4SAndroid Build Coastguard Worker /* last region in program? */
1827*f81fb7c4SAndroid Build Coastguard Worker if (pRegion->keyGroupAndFlags & REGION_FLAG_LAST_REGION)
1828*f81fb7c4SAndroid Build Coastguard Worker break;
1829*f81fb7c4SAndroid Build Coastguard Worker
1830*f81fb7c4SAndroid Build Coastguard Worker /* advance to next region */
1831*f81fb7c4SAndroid Build Coastguard Worker regionIndex++;
1832*f81fb7c4SAndroid Build Coastguard Worker }
1833*f81fb7c4SAndroid Build Coastguard Worker }
1834*f81fb7c4SAndroid Build Coastguard Worker }
1835*f81fb7c4SAndroid Build Coastguard Worker
1836*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1837*f81fb7c4SAndroid Build Coastguard Worker * VMStopNote()
1838*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1839*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1840*f81fb7c4SAndroid Build Coastguard Worker * Update the synth's state to end the requested note on the requested
1841*f81fb7c4SAndroid Build Coastguard Worker * channel.
1842*f81fb7c4SAndroid Build Coastguard Worker *
1843*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1844*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the channel to stop a note on
1845*f81fb7c4SAndroid Build Coastguard Worker * nKeyNumber - the key number for this note off
1846*f81fb7c4SAndroid Build Coastguard Worker * nNoteVelocity - the note-off velocity
1847*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1848*f81fb7c4SAndroid Build Coastguard Worker *
1849*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1850*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
1851*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nSynthChannel may be assigned
1852*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nKeyNumber is assigned
1853*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sVoice[free voice num].m_nVelocity is assigned
1854*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1855*f81fb7c4SAndroid Build Coastguard Worker */
1856*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, velocity) reserved for future use */
VMStopNote(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 note,EAS_U8 velocity)1857*f81fb7c4SAndroid Build Coastguard Worker void VMStopNote (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 note, EAS_U8 velocity)
1858*f81fb7c4SAndroid Build Coastguard Worker {
1859*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
1860*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1861*f81fb7c4SAndroid Build Coastguard Worker
1862*f81fb7c4SAndroid Build Coastguard Worker pChannel = &(pSynth->channels[channel]);
1863*f81fb7c4SAndroid Build Coastguard Worker
1864*f81fb7c4SAndroid Build Coastguard Worker #ifdef EXTERNAL_AUDIO
1865*f81fb7c4SAndroid Build Coastguard Worker if ((pChannel->channelFlags & CHANNEL_FLAG_EXTERNAL_AUDIO) && (pSynth->cbEventFunc != NULL))
1866*f81fb7c4SAndroid Build Coastguard Worker {
1867*f81fb7c4SAndroid Build Coastguard Worker S_EXT_AUDIO_EVENT event;
1868*f81fb7c4SAndroid Build Coastguard Worker event.channel = channel;
1869*f81fb7c4SAndroid Build Coastguard Worker event.note = note;
1870*f81fb7c4SAndroid Build Coastguard Worker event.velocity = velocity;
1871*f81fb7c4SAndroid Build Coastguard Worker event.noteOn = EAS_FALSE;
1872*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->cbEventFunc(pSynth->pExtAudioInstData, &event))
1873*f81fb7c4SAndroid Build Coastguard Worker return;
1874*f81fb7c4SAndroid Build Coastguard Worker }
1875*f81fb7c4SAndroid Build Coastguard Worker #endif
1876*f81fb7c4SAndroid Build Coastguard Worker
1877*f81fb7c4SAndroid Build Coastguard Worker /* keep track of the note-start workload */
1878*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload += WORKLOAD_AMOUNT_STOP_NOTE;
1879*f81fb7c4SAndroid Build Coastguard Worker
1880*f81fb7c4SAndroid Build Coastguard Worker channel = VSynthToChannel(pSynth, channel);
1881*f81fb7c4SAndroid Build Coastguard Worker
1882*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum=0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
1883*f81fb7c4SAndroid Build Coastguard Worker {
1884*f81fb7c4SAndroid Build Coastguard Worker
1885*f81fb7c4SAndroid Build Coastguard Worker /* stolen notes are handled separately */
1886*f81fb7c4SAndroid Build Coastguard Worker if (eVoiceStateStolen != pVoiceMgr->voices[voiceNum].voiceState)
1887*f81fb7c4SAndroid Build Coastguard Worker {
1888*f81fb7c4SAndroid Build Coastguard Worker
1889*f81fb7c4SAndroid Build Coastguard Worker /* channel and key number must match */
1890*f81fb7c4SAndroid Build Coastguard Worker if ((channel == pVoiceMgr->voices[voiceNum].channel) && (note == pVoiceMgr->voices[voiceNum].note))
1891*f81fb7c4SAndroid Build Coastguard Worker {
1892*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1893*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n",
1894*f81fb7c4SAndroid Build Coastguard Worker voiceNum, channel, note); */ }
1895*f81fb7c4SAndroid Build Coastguard Worker #endif
1896*f81fb7c4SAndroid Build Coastguard Worker
1897*f81fb7c4SAndroid Build Coastguard Worker /* if sustain pedal is down, set deferred note-off flag */
1898*f81fb7c4SAndroid Build Coastguard Worker if (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
1899*f81fb7c4SAndroid Build Coastguard Worker {
1900*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
1901*f81fb7c4SAndroid Build Coastguard Worker continue;
1902*f81fb7c4SAndroid Build Coastguard Worker }
1903*f81fb7c4SAndroid Build Coastguard Worker
1904*f81fb7c4SAndroid Build Coastguard Worker /* if this note just started, wait before we stop it */
1905*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
1906*f81fb7c4SAndroid Build Coastguard Worker {
1907*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1908*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tDeferred: Not started yet\n"); */ }
1909*f81fb7c4SAndroid Build Coastguard Worker #endif
1910*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
1911*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags |= SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING;
1912*f81fb7c4SAndroid Build Coastguard Worker }
1913*f81fb7c4SAndroid Build Coastguard Worker
1914*f81fb7c4SAndroid Build Coastguard Worker /* release voice */
1915*f81fb7c4SAndroid Build Coastguard Worker else
1916*f81fb7c4SAndroid Build Coastguard Worker VMReleaseVoice(pVoiceMgr, pSynth, voiceNum);
1917*f81fb7c4SAndroid Build Coastguard Worker
1918*f81fb7c4SAndroid Build Coastguard Worker }
1919*f81fb7c4SAndroid Build Coastguard Worker }
1920*f81fb7c4SAndroid Build Coastguard Worker
1921*f81fb7c4SAndroid Build Coastguard Worker /* process stolen notes, new channel and key number must match */
1922*f81fb7c4SAndroid Build Coastguard Worker else if ((channel == pVoiceMgr->voices[voiceNum].nextChannel) && (note == pVoiceMgr->voices[voiceNum].nextNote))
1923*f81fb7c4SAndroid Build Coastguard Worker {
1924*f81fb7c4SAndroid Build Coastguard Worker
1925*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1926*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStopNote: voice %d channel %d note %d\n\tDeferred: Stolen voice\n",
1927*f81fb7c4SAndroid Build Coastguard Worker voiceNum, channel, note); */ }
1928*f81fb7c4SAndroid Build Coastguard Worker #endif
1929*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags |= VOICE_FLAG_DEFER_MIDI_NOTE_OFF;
1930*f81fb7c4SAndroid Build Coastguard Worker }
1931*f81fb7c4SAndroid Build Coastguard Worker }
1932*f81fb7c4SAndroid Build Coastguard Worker }
1933*f81fb7c4SAndroid Build Coastguard Worker
1934*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1935*f81fb7c4SAndroid Build Coastguard Worker * VMFindAvailableVoice()
1936*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1937*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1938*f81fb7c4SAndroid Build Coastguard Worker * Find an available voice and return the voice number if available.
1939*f81fb7c4SAndroid Build Coastguard Worker *
1940*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1941*f81fb7c4SAndroid Build Coastguard Worker * pnVoiceNumber - really an output, returns the voice number found
1942*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1943*f81fb7c4SAndroid Build Coastguard Worker *
1944*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1945*f81fb7c4SAndroid Build Coastguard Worker * success - if there is an available voice
1946*f81fb7c4SAndroid Build Coastguard Worker * failure - otherwise
1947*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1948*f81fb7c4SAndroid Build Coastguard Worker */
VMFindAvailableVoice(S_VOICE_MGR * pVoiceMgr,EAS_INT * pVoiceNumber,EAS_I32 lowVoice,EAS_I32 highVoice)1949*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMFindAvailableVoice (S_VOICE_MGR *pVoiceMgr, EAS_INT *pVoiceNumber, EAS_I32 lowVoice, EAS_I32 highVoice)
1950*f81fb7c4SAndroid Build Coastguard Worker {
1951*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
1952*f81fb7c4SAndroid Build Coastguard Worker
1953*f81fb7c4SAndroid Build Coastguard Worker /* Check each voice to see if it has been assigned to a synth channel */
1954*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
1955*f81fb7c4SAndroid Build Coastguard Worker {
1956*f81fb7c4SAndroid Build Coastguard Worker /* check if this voice has been assigned to a synth channel */
1957*f81fb7c4SAndroid Build Coastguard Worker if ( pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateFree)
1958*f81fb7c4SAndroid Build Coastguard Worker {
1959*f81fb7c4SAndroid Build Coastguard Worker *pVoiceNumber = voiceNum; /* this voice is available */
1960*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
1961*f81fb7c4SAndroid Build Coastguard Worker }
1962*f81fb7c4SAndroid Build Coastguard Worker }
1963*f81fb7c4SAndroid Build Coastguard Worker
1964*f81fb7c4SAndroid Build Coastguard Worker /* if we reach here, we have not found a free voice */
1965*f81fb7c4SAndroid Build Coastguard Worker *pVoiceNumber = UNASSIGNED_SYNTH_VOICE;
1966*f81fb7c4SAndroid Build Coastguard Worker
1967*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
1968*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMFindAvailableVoice: error, could not find an available voice\n"); */ }
1969*f81fb7c4SAndroid Build Coastguard Worker #endif
1970*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
1971*f81fb7c4SAndroid Build Coastguard Worker }
1972*f81fb7c4SAndroid Build Coastguard Worker
1973*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
1974*f81fb7c4SAndroid Build Coastguard Worker * VMStealVoice()
1975*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
1976*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
1977*f81fb7c4SAndroid Build Coastguard Worker * Steal a voice and return the voice number
1978*f81fb7c4SAndroid Build Coastguard Worker *
1979*f81fb7c4SAndroid Build Coastguard Worker * Stealing algorithm: steal the best choice with minimal work, taking into
1980*f81fb7c4SAndroid Build Coastguard Worker * account SP-Midi channel priorities and polyphony allocation.
1981*f81fb7c4SAndroid Build Coastguard Worker *
1982*f81fb7c4SAndroid Build Coastguard Worker * In one pass through all the voices, figure out which voice to steal
1983*f81fb7c4SAndroid Build Coastguard Worker * taking into account a number of different factors:
1984*f81fb7c4SAndroid Build Coastguard Worker * Priority of the voice's MIDI channel
1985*f81fb7c4SAndroid Build Coastguard Worker * Number of voices over the polyphony allocation for voice's MIDI channel
1986*f81fb7c4SAndroid Build Coastguard Worker * Amplitude of the voice
1987*f81fb7c4SAndroid Build Coastguard Worker * Note age
1988*f81fb7c4SAndroid Build Coastguard Worker * Key velocity (for voices that haven't been started yet)
1989*f81fb7c4SAndroid Build Coastguard Worker * If any matching notes are found
1990*f81fb7c4SAndroid Build Coastguard Worker *
1991*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
1992*f81fb7c4SAndroid Build Coastguard Worker * pnVoiceNumber - really an output, see below
1993*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the channel that this voice wants to be started on
1994*f81fb7c4SAndroid Build Coastguard Worker * nKeyNumber - the key number for this new voice
1995*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
1996*f81fb7c4SAndroid Build Coastguard Worker *
1997*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
1998*f81fb7c4SAndroid Build Coastguard Worker * pnVoiceNumber - voice number of the voice that was stolen
1999*f81fb7c4SAndroid Build Coastguard Worker * EAS_RESULT EAS_SUCCESS - always successful
2000*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2001*f81fb7c4SAndroid Build Coastguard Worker */
VMStealVoice(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_INT * pVoiceNumber,EAS_U8 channel,EAS_U8 note,EAS_I32 lowVoice,EAS_I32 highVoice)2002*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMStealVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_INT *pVoiceNumber, EAS_U8 channel, EAS_U8 note, EAS_I32 lowVoice, EAS_I32 highVoice)
2003*f81fb7c4SAndroid Build Coastguard Worker {
2004*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pCurrVoice;
2005*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pCurrSynth;
2006*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
2007*f81fb7c4SAndroid Build Coastguard Worker EAS_INT bestCandidate;
2008*f81fb7c4SAndroid Build Coastguard Worker EAS_U8 currChannel;
2009*f81fb7c4SAndroid Build Coastguard Worker EAS_U8 currNote;
2010*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 bestPriority;
2011*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 currentPriority;
2012*f81fb7c4SAndroid Build Coastguard Worker
2013*f81fb7c4SAndroid Build Coastguard Worker /* determine which voice to steal */
2014*f81fb7c4SAndroid Build Coastguard Worker bestPriority = 0;
2015*f81fb7c4SAndroid Build Coastguard Worker bestCandidate = MAX_SYNTH_VOICES;
2016*f81fb7c4SAndroid Build Coastguard Worker
2017*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = lowVoice; voiceNum <= highVoice; voiceNum++)
2018*f81fb7c4SAndroid Build Coastguard Worker {
2019*f81fb7c4SAndroid Build Coastguard Worker pCurrVoice = &pVoiceMgr->voices[voiceNum];
2020*f81fb7c4SAndroid Build Coastguard Worker
2021*f81fb7c4SAndroid Build Coastguard Worker /* ignore free voices */
2022*f81fb7c4SAndroid Build Coastguard Worker if (pCurrVoice->voiceState == eVoiceStateFree)
2023*f81fb7c4SAndroid Build Coastguard Worker continue;
2024*f81fb7c4SAndroid Build Coastguard Worker
2025*f81fb7c4SAndroid Build Coastguard Worker /* for stolen voices, use the new parameters, not the old */
2026*f81fb7c4SAndroid Build Coastguard Worker if (pCurrVoice->voiceState == eVoiceStateStolen)
2027*f81fb7c4SAndroid Build Coastguard Worker {
2028*f81fb7c4SAndroid Build Coastguard Worker pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->nextChannel)];
2029*f81fb7c4SAndroid Build Coastguard Worker currChannel = pCurrVoice->nextChannel;
2030*f81fb7c4SAndroid Build Coastguard Worker currNote = pCurrVoice->nextNote;
2031*f81fb7c4SAndroid Build Coastguard Worker }
2032*f81fb7c4SAndroid Build Coastguard Worker else
2033*f81fb7c4SAndroid Build Coastguard Worker {
2034*f81fb7c4SAndroid Build Coastguard Worker pCurrSynth = pVoiceMgr->pSynth[GET_VSYNTH(pCurrVoice->channel)];
2035*f81fb7c4SAndroid Build Coastguard Worker currChannel = pCurrVoice->channel;
2036*f81fb7c4SAndroid Build Coastguard Worker currNote = pCurrVoice->note;
2037*f81fb7c4SAndroid Build Coastguard Worker }
2038*f81fb7c4SAndroid Build Coastguard Worker
2039*f81fb7c4SAndroid Build Coastguard Worker /* ignore voices that are higher priority */
2040*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->priority > pCurrSynth->priority)
2041*f81fb7c4SAndroid Build Coastguard Worker continue;
2042*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2043*f81fb7c4SAndroid Build Coastguard Worker // { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: New priority = %d exceeds old priority = %d\n", pSynth->priority, pCurrSynth->priority); */ }
2044*f81fb7c4SAndroid Build Coastguard Worker #endif
2045*f81fb7c4SAndroid Build Coastguard Worker
2046*f81fb7c4SAndroid Build Coastguard Worker /* if voice is stolen or just started, reduce the likelihood it will be stolen */
2047*f81fb7c4SAndroid Build Coastguard Worker if (( pCurrVoice->voiceState == eVoiceStateStolen) || (pCurrVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
2048*f81fb7c4SAndroid Build Coastguard Worker {
2049*f81fb7c4SAndroid Build Coastguard Worker currentPriority = 128 - pCurrVoice->nextVelocity;
2050*f81fb7c4SAndroid Build Coastguard Worker }
2051*f81fb7c4SAndroid Build Coastguard Worker else
2052*f81fb7c4SAndroid Build Coastguard Worker {
2053*f81fb7c4SAndroid Build Coastguard Worker /* compute the priority of this voice, higher means better for stealing */
2054*f81fb7c4SAndroid Build Coastguard Worker /* use not age */
2055*f81fb7c4SAndroid Build Coastguard Worker currentPriority = (EAS_I32) pCurrVoice->age << NOTE_AGE_STEAL_WEIGHT;
2056*f81fb7c4SAndroid Build Coastguard Worker
2057*f81fb7c4SAndroid Build Coastguard Worker /* include note gain -higher gain is lower steal value */
2058*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{704} use shift for performance */
2059*f81fb7c4SAndroid Build Coastguard Worker currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
2060*f81fb7c4SAndroid Build Coastguard Worker ((EAS_I32) pCurrVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
2061*f81fb7c4SAndroid Build Coastguard Worker }
2062*f81fb7c4SAndroid Build Coastguard Worker
2063*f81fb7c4SAndroid Build Coastguard Worker /* in SP-MIDI mode, include over poly allocation and channel priority */
2064*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
2065*f81fb7c4SAndroid Build Coastguard Worker {
2066*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel = &pCurrSynth->channels[GET_CHANNEL(currChannel)];
2067*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{701} use shift for performance */
2068*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->poolCount[pChannel->pool] >= pSynth->poolAlloc[pChannel->pool])
2069*f81fb7c4SAndroid Build Coastguard Worker currentPriority += (pSynth->poolCount[pChannel->pool] -pSynth->poolAlloc[pChannel->pool] + 1) << CHANNEL_POLY_STEAL_WEIGHT;
2070*f81fb7c4SAndroid Build Coastguard Worker
2071*f81fb7c4SAndroid Build Coastguard Worker /* include channel priority */
2072*f81fb7c4SAndroid Build Coastguard Worker currentPriority += (EAS_I32)(pChannel->pool << CHANNEL_PRIORITY_STEAL_WEIGHT);
2073*f81fb7c4SAndroid Build Coastguard Worker }
2074*f81fb7c4SAndroid Build Coastguard Worker
2075*f81fb7c4SAndroid Build Coastguard Worker /* if a note is already playing that matches this note, consider stealing it more readily */
2076*f81fb7c4SAndroid Build Coastguard Worker if ((note == currNote) && (channel == currChannel))
2077*f81fb7c4SAndroid Build Coastguard Worker currentPriority += NOTE_MATCH_PENALTY;
2078*f81fb7c4SAndroid Build Coastguard Worker
2079*f81fb7c4SAndroid Build Coastguard Worker /* is this the best choice so far? */
2080*f81fb7c4SAndroid Build Coastguard Worker if (currentPriority >= bestPriority)
2081*f81fb7c4SAndroid Build Coastguard Worker {
2082*f81fb7c4SAndroid Build Coastguard Worker bestPriority = currentPriority;
2083*f81fb7c4SAndroid Build Coastguard Worker bestCandidate = voiceNum;
2084*f81fb7c4SAndroid Build Coastguard Worker }
2085*f81fb7c4SAndroid Build Coastguard Worker }
2086*f81fb7c4SAndroid Build Coastguard Worker
2087*f81fb7c4SAndroid Build Coastguard Worker /* may happen if all voices are allocated to a higher priority virtual synth */
2088*f81fb7c4SAndroid Build Coastguard Worker if (bestCandidate == MAX_SYNTH_VOICES)
2089*f81fb7c4SAndroid Build Coastguard Worker {
2090*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Unable to allocate a voice\n"); */ }
2091*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_NO_VOICE_ALLOCATED;
2092*f81fb7c4SAndroid Build Coastguard Worker }
2093*f81fb7c4SAndroid Build Coastguard Worker
2094*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2095*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMStealVoice: Voice %d stolen\n", bestCandidate); */ }
2096*f81fb7c4SAndroid Build Coastguard Worker
2097*f81fb7c4SAndroid Build Coastguard Worker /* are we stealing a stolen voice? */
2098*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[bestCandidate].voiceState == eVoiceStateStolen)
2099*f81fb7c4SAndroid Build Coastguard Worker {
2100*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMStealVoice: Voice %d is already marked as stolen and was scheduled to play ch: %d note: %d vel: %d\n",
2101*f81fb7c4SAndroid Build Coastguard Worker bestCandidate,
2102*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[bestCandidate].nextChannel,
2103*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[bestCandidate].nextNote,
2104*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[bestCandidate].nextVelocity); */ }
2105*f81fb7c4SAndroid Build Coastguard Worker }
2106*f81fb7c4SAndroid Build Coastguard Worker #endif
2107*f81fb7c4SAndroid Build Coastguard Worker
2108*f81fb7c4SAndroid Build Coastguard Worker *pVoiceNumber = (EAS_U16) bestCandidate;
2109*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2110*f81fb7c4SAndroid Build Coastguard Worker }
2111*f81fb7c4SAndroid Build Coastguard Worker
2112*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2113*f81fb7c4SAndroid Build Coastguard Worker * VMChannelPressure()
2114*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2115*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2116*f81fb7c4SAndroid Build Coastguard Worker * Change the channel pressure for the given channel
2117*f81fb7c4SAndroid Build Coastguard Worker *
2118*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2119*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the MIDI channel
2120*f81fb7c4SAndroid Build Coastguard Worker * nVelocity - the channel pressure value
2121*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2122*f81fb7c4SAndroid Build Coastguard Worker *
2123*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2124*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2125*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sChannel[nChannel].m_nChannelPressure is updated
2126*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2127*f81fb7c4SAndroid Build Coastguard Worker */
VMChannelPressure(S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 value)2128*f81fb7c4SAndroid Build Coastguard Worker void VMChannelPressure (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 value)
2129*f81fb7c4SAndroid Build Coastguard Worker {
2130*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
2131*f81fb7c4SAndroid Build Coastguard Worker
2132*f81fb7c4SAndroid Build Coastguard Worker pChannel = &(pSynth->channels[channel]);
2133*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelPressure = value;
2134*f81fb7c4SAndroid Build Coastguard Worker
2135*f81fb7c4SAndroid Build Coastguard Worker /*
2136*f81fb7c4SAndroid Build Coastguard Worker set a channel flag to request parameter updates
2137*f81fb7c4SAndroid Build Coastguard Worker for all the voices associated with this channel
2138*f81fb7c4SAndroid Build Coastguard Worker */
2139*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
2140*f81fb7c4SAndroid Build Coastguard Worker }
2141*f81fb7c4SAndroid Build Coastguard Worker
2142*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2143*f81fb7c4SAndroid Build Coastguard Worker * VMPitchBend()
2144*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2145*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2146*f81fb7c4SAndroid Build Coastguard Worker * Change the pitch wheel value for the given channel.
2147*f81fb7c4SAndroid Build Coastguard Worker * This routine constructs the proper 14-bit argument when the calling routine
2148*f81fb7c4SAndroid Build Coastguard Worker * passes the pitch LSB and MSB.
2149*f81fb7c4SAndroid Build Coastguard Worker *
2150*f81fb7c4SAndroid Build Coastguard Worker * Note: some midi disassemblers display a bipolar pitch bend value.
2151*f81fb7c4SAndroid Build Coastguard Worker * We can display the bipolar value using
2152*f81fb7c4SAndroid Build Coastguard Worker * if m_nPitchBend >= 0x2000
2153*f81fb7c4SAndroid Build Coastguard Worker * bipolar pitch bend = postive (m_nPitchBend - 0x2000)
2154*f81fb7c4SAndroid Build Coastguard Worker * else
2155*f81fb7c4SAndroid Build Coastguard Worker * bipolar pitch bend = negative (0x2000 - m_nPitchBend)
2156*f81fb7c4SAndroid Build Coastguard Worker *
2157*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2158*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the MIDI channel
2159*f81fb7c4SAndroid Build Coastguard Worker * nPitchLSB - the LSB byte of the pitch bend message
2160*f81fb7c4SAndroid Build Coastguard Worker * nPitchMSB - the MSB byte of the pitch bend message
2161*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2162*f81fb7c4SAndroid Build Coastguard Worker *
2163*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2164*f81fb7c4SAndroid Build Coastguard Worker *
2165*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2166*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sChannel[nChannel].m_nPitchBend is changed
2167*f81fb7c4SAndroid Build Coastguard Worker *
2168*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2169*f81fb7c4SAndroid Build Coastguard Worker */
VMPitchBend(S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 nPitchLSB,EAS_U8 nPitchMSB)2170*f81fb7c4SAndroid Build Coastguard Worker void VMPitchBend (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 nPitchLSB, EAS_U8 nPitchMSB)
2171*f81fb7c4SAndroid Build Coastguard Worker {
2172*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
2173*f81fb7c4SAndroid Build Coastguard Worker
2174*f81fb7c4SAndroid Build Coastguard Worker pChannel = &(pSynth->channels[channel]);
2175*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBend = (EAS_I16) ((nPitchMSB << 7) | nPitchLSB);
2176*f81fb7c4SAndroid Build Coastguard Worker
2177*f81fb7c4SAndroid Build Coastguard Worker /*
2178*f81fb7c4SAndroid Build Coastguard Worker set a channel flag to request parameter updates
2179*f81fb7c4SAndroid Build Coastguard Worker for all the voices associated with this channel
2180*f81fb7c4SAndroid Build Coastguard Worker */
2181*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
2182*f81fb7c4SAndroid Build Coastguard Worker }
2183*f81fb7c4SAndroid Build Coastguard Worker
2184*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2185*f81fb7c4SAndroid Build Coastguard Worker * VMControlChange()
2186*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2187*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2188*f81fb7c4SAndroid Build Coastguard Worker * Change the controller (or mode) for the given channel.
2189*f81fb7c4SAndroid Build Coastguard Worker *
2190*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2191*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the MIDI channel
2192*f81fb7c4SAndroid Build Coastguard Worker * nControllerNumber - the MIDI controller number
2193*f81fb7c4SAndroid Build Coastguard Worker * nControlValue - the value for this controller message
2194*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2195*f81fb7c4SAndroid Build Coastguard Worker *
2196*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2197*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2198*f81fb7c4SAndroid Build Coastguard Worker * psSynthObject->m_sChannel[nChannel] controller is changed
2199*f81fb7c4SAndroid Build Coastguard Worker *
2200*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2201*f81fb7c4SAndroid Build Coastguard Worker */
VMControlChange(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 controller,EAS_U8 value)2202*f81fb7c4SAndroid Build Coastguard Worker void VMControlChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
2203*f81fb7c4SAndroid Build Coastguard Worker {
2204*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
2205*f81fb7c4SAndroid Build Coastguard Worker
2206*f81fb7c4SAndroid Build Coastguard Worker pChannel = &(pSynth->channels[channel]);
2207*f81fb7c4SAndroid Build Coastguard Worker
2208*f81fb7c4SAndroid Build Coastguard Worker /*
2209*f81fb7c4SAndroid Build Coastguard Worker set a channel flag to request parameter updates
2210*f81fb7c4SAndroid Build Coastguard Worker for all the voices associated with this channel
2211*f81fb7c4SAndroid Build Coastguard Worker */
2212*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
2213*f81fb7c4SAndroid Build Coastguard Worker
2214*f81fb7c4SAndroid Build Coastguard Worker switch ( controller )
2215*f81fb7c4SAndroid Build Coastguard Worker {
2216*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_BANK_SELECT_MSB:
2217*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2218*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select MSB: msb 0x%X\n", value); */ }
2219*f81fb7c4SAndroid Build Coastguard Worker #endif
2220*f81fb7c4SAndroid Build Coastguard Worker /* use this MSB with a zero LSB, until we get an LSB message */
2221*f81fb7c4SAndroid Build Coastguard Worker pChannel->bankNum = value << 8;
2222*f81fb7c4SAndroid Build Coastguard Worker break;
2223*f81fb7c4SAndroid Build Coastguard Worker
2224*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_MOD_WHEEL:
2225*f81fb7c4SAndroid Build Coastguard Worker /* we treat mod wheel as a 7-bit controller and only use the MSB */
2226*f81fb7c4SAndroid Build Coastguard Worker pChannel->modWheel = value;
2227*f81fb7c4SAndroid Build Coastguard Worker break;
2228*f81fb7c4SAndroid Build Coastguard Worker
2229*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_VOLUME:
2230*f81fb7c4SAndroid Build Coastguard Worker /* we treat volume as a 7-bit controller and only use the MSB */
2231*f81fb7c4SAndroid Build Coastguard Worker pChannel->volume = value;
2232*f81fb7c4SAndroid Build Coastguard Worker break;
2233*f81fb7c4SAndroid Build Coastguard Worker
2234*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_PAN:
2235*f81fb7c4SAndroid Build Coastguard Worker /* we treat pan as a 7-bit controller and only use the MSB */
2236*f81fb7c4SAndroid Build Coastguard Worker pChannel->pan = value;
2237*f81fb7c4SAndroid Build Coastguard Worker break;
2238*f81fb7c4SAndroid Build Coastguard Worker
2239*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_EXPRESSION:
2240*f81fb7c4SAndroid Build Coastguard Worker /* we treat expression as a 7-bit controller and only use the MSB */
2241*f81fb7c4SAndroid Build Coastguard Worker pChannel->expression = value;
2242*f81fb7c4SAndroid Build Coastguard Worker break;
2243*f81fb7c4SAndroid Build Coastguard Worker
2244*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_BANK_SELECT_LSB:
2245*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2246*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: Bank Select LSB: lsb 0x%X\n", value); */ }
2247*f81fb7c4SAndroid Build Coastguard Worker #endif
2248*f81fb7c4SAndroid Build Coastguard Worker /*
2249*f81fb7c4SAndroid Build Coastguard Worker construct bank number as 7-bits (stored as 8) of existing MSB
2250*f81fb7c4SAndroid Build Coastguard Worker and 7-bits of new LSB (also stored as 8(
2251*f81fb7c4SAndroid Build Coastguard Worker */
2252*f81fb7c4SAndroid Build Coastguard Worker pChannel->bankNum =
2253*f81fb7c4SAndroid Build Coastguard Worker (pChannel->bankNum & 0xFF00) | value;
2254*f81fb7c4SAndroid Build Coastguard Worker
2255*f81fb7c4SAndroid Build Coastguard Worker break;
2256*f81fb7c4SAndroid Build Coastguard Worker
2257*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SUSTAIN_PEDAL:
2258*f81fb7c4SAndroid Build Coastguard Worker /* we treat sustain pedal as a boolean on/off bit flag */
2259*f81fb7c4SAndroid Build Coastguard Worker if (value < 64)
2260*f81fb7c4SAndroid Build Coastguard Worker {
2261*f81fb7c4SAndroid Build Coastguard Worker /*
2262*f81fb7c4SAndroid Build Coastguard Worker we are requested to turn the pedal off, but first check
2263*f81fb7c4SAndroid Build Coastguard Worker if the pedal is already on
2264*f81fb7c4SAndroid Build Coastguard Worker */
2265*f81fb7c4SAndroid Build Coastguard Worker if (0 !=
2266*f81fb7c4SAndroid Build Coastguard Worker (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
2267*f81fb7c4SAndroid Build Coastguard Worker )
2268*f81fb7c4SAndroid Build Coastguard Worker {
2269*f81fb7c4SAndroid Build Coastguard Worker /*
2270*f81fb7c4SAndroid Build Coastguard Worker The sustain flag is presently set and the damper pedal is on.
2271*f81fb7c4SAndroid Build Coastguard Worker We are therefore transitioning from damper pedal ON to
2272*f81fb7c4SAndroid Build Coastguard Worker damper pedal OFF. This means all notes in this channel
2273*f81fb7c4SAndroid Build Coastguard Worker that received a note off while the damper pedal was on, and
2274*f81fb7c4SAndroid Build Coastguard Worker had their note-off requests deferred, should now proceed to
2275*f81fb7c4SAndroid Build Coastguard Worker the release state.
2276*f81fb7c4SAndroid Build Coastguard Worker */
2277*f81fb7c4SAndroid Build Coastguard Worker VMReleaseAllDeferredNoteOffs(pVoiceMgr, pSynth, channel);
2278*f81fb7c4SAndroid Build Coastguard Worker } /* end if sustain pedal is already on */
2279*f81fb7c4SAndroid Build Coastguard Worker
2280*f81fb7c4SAndroid Build Coastguard Worker /* turn the sustain pedal off */
2281*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
2282*f81fb7c4SAndroid Build Coastguard Worker }
2283*f81fb7c4SAndroid Build Coastguard Worker else
2284*f81fb7c4SAndroid Build Coastguard Worker {
2285*f81fb7c4SAndroid Build Coastguard Worker /*
2286*f81fb7c4SAndroid Build Coastguard Worker we are requested to turn the pedal on, but first check
2287*f81fb7c4SAndroid Build Coastguard Worker if the pedal is already off
2288*f81fb7c4SAndroid Build Coastguard Worker */
2289*f81fb7c4SAndroid Build Coastguard Worker if (0 ==
2290*f81fb7c4SAndroid Build Coastguard Worker (pChannel->channelFlags & CHANNEL_FLAG_SUSTAIN_PEDAL)
2291*f81fb7c4SAndroid Build Coastguard Worker )
2292*f81fb7c4SAndroid Build Coastguard Worker {
2293*f81fb7c4SAndroid Build Coastguard Worker /*
2294*f81fb7c4SAndroid Build Coastguard Worker The sustain flag is presently clear and the damper pedal is off.
2295*f81fb7c4SAndroid Build Coastguard Worker We are therefore transitioning from damper pedal OFF to
2296*f81fb7c4SAndroid Build Coastguard Worker damper pedal ON. Currently sounding notes should be left
2297*f81fb7c4SAndroid Build Coastguard Worker unchanged. However, we should try to "catch" notes if possible.
2298*f81fb7c4SAndroid Build Coastguard Worker If any notes have levels >= sustain level, catch them,
2299*f81fb7c4SAndroid Build Coastguard Worker otherwise, let them continue to release.
2300*f81fb7c4SAndroid Build Coastguard Worker */
2301*f81fb7c4SAndroid Build Coastguard Worker VMCatchNotesForSustainPedal(pVoiceMgr, pSynth, channel);
2302*f81fb7c4SAndroid Build Coastguard Worker }
2303*f81fb7c4SAndroid Build Coastguard Worker
2304*f81fb7c4SAndroid Build Coastguard Worker /* turn the sustain pedal on */
2305*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_SUSTAIN_PEDAL;
2306*f81fb7c4SAndroid Build Coastguard Worker }
2307*f81fb7c4SAndroid Build Coastguard Worker
2308*f81fb7c4SAndroid Build Coastguard Worker break;
2309*f81fb7c4SAndroid Build Coastguard Worker #ifdef _REVERB
2310*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_REVERB_SEND:
2311*f81fb7c4SAndroid Build Coastguard Worker /* we treat send as a 7-bit controller and only use the MSB */
2312*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].reverbSend = value;
2313*f81fb7c4SAndroid Build Coastguard Worker break;
2314*f81fb7c4SAndroid Build Coastguard Worker #endif
2315*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHORUS
2316*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_CHORUS_SEND:
2317*f81fb7c4SAndroid Build Coastguard Worker /* we treat send as a 7-bit controller and only use the MSB */
2318*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].chorusSend = value;
2319*f81fb7c4SAndroid Build Coastguard Worker break;
2320*f81fb7c4SAndroid Build Coastguard Worker #endif
2321*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_RESET_CONTROLLERS:
2322*f81fb7c4SAndroid Build Coastguard Worker /* despite the Midi message name, not ALL controllers are reset */
2323*f81fb7c4SAndroid Build Coastguard Worker pChannel->modWheel = DEFAULT_MOD_WHEEL;
2324*f81fb7c4SAndroid Build Coastguard Worker pChannel->expression = DEFAULT_EXPRESSION;
2325*f81fb7c4SAndroid Build Coastguard Worker
2326*f81fb7c4SAndroid Build Coastguard Worker /* turn the sustain pedal off as default/reset */
2327*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags &= ~CHANNEL_FLAG_SUSTAIN_PEDAL;
2328*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBend = DEFAULT_PITCH_BEND;
2329*f81fb7c4SAndroid Build Coastguard Worker
2330*f81fb7c4SAndroid Build Coastguard Worker /* reset channel pressure */
2331*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelPressure = DEFAULT_CHANNEL_PRESSURE;
2332*f81fb7c4SAndroid Build Coastguard Worker
2333*f81fb7c4SAndroid Build Coastguard Worker /* reset RPN values */
2334*f81fb7c4SAndroid Build Coastguard Worker pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
2335*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBendSensitivity = DEFAULT_PITCH_BEND_SENSITIVITY;
2336*f81fb7c4SAndroid Build Coastguard Worker pChannel->finePitch = DEFAULT_FINE_PITCH;
2337*f81fb7c4SAndroid Build Coastguard Worker pChannel->coarsePitch = DEFAULT_COARSE_PITCH;
2338*f81fb7c4SAndroid Build Coastguard Worker
2339*f81fb7c4SAndroid Build Coastguard Worker /*
2340*f81fb7c4SAndroid Build Coastguard Worker program change, bank select, channel volume CC7, pan CC10
2341*f81fb7c4SAndroid Build Coastguard Worker are NOT reset
2342*f81fb7c4SAndroid Build Coastguard Worker */
2343*f81fb7c4SAndroid Build Coastguard Worker break;
2344*f81fb7c4SAndroid Build Coastguard Worker
2345*f81fb7c4SAndroid Build Coastguard Worker /*
2346*f81fb7c4SAndroid Build Coastguard Worker For logical reasons, the RPN data entry are grouped together.
2347*f81fb7c4SAndroid Build Coastguard Worker However, keep in mind that these cases are not necessarily in
2348*f81fb7c4SAndroid Build Coastguard Worker ascending order.
2349*f81fb7c4SAndroid Build Coastguard Worker e.g., MIDI_CONTROLLER_DATA_ENTRY_MSB == 6,
2350*f81fb7c4SAndroid Build Coastguard Worker whereas MIDI_CONTROLLER_SUSTAIN_PEDAL == 64.
2351*f81fb7c4SAndroid Build Coastguard Worker So arrange these case statements in whatever manner is more efficient for
2352*f81fb7c4SAndroid Build Coastguard Worker the processor / compiler.
2353*f81fb7c4SAndroid Build Coastguard Worker */
2354*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ENTER_DATA_MSB:
2355*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ENTER_DATA_LSB:
2356*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_RPN_LSB:
2357*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_RPN_MSB:
2358*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_NRPN_MSB:
2359*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_NRPN_LSB:
2360*f81fb7c4SAndroid Build Coastguard Worker VMUpdateRPNStateMachine(pSynth, channel, controller, value);
2361*f81fb7c4SAndroid Build Coastguard Worker break;
2362*f81fb7c4SAndroid Build Coastguard Worker
2363*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ALL_SOUND_OFF:
2364*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ALL_NOTES_OFF:
2365*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_OMNI_OFF:
2366*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_OMNI_ON:
2367*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_MONO_ON_POLY_OFF:
2368*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_POLY_ON_MONO_OFF:
2369*f81fb7c4SAndroid Build Coastguard Worker /* NOTE: we treat all sounds off the same as all notes off */
2370*f81fb7c4SAndroid Build Coastguard Worker VMAllNotesOff(pVoiceMgr, pSynth, channel);
2371*f81fb7c4SAndroid Build Coastguard Worker break;
2372*f81fb7c4SAndroid Build Coastguard Worker
2373*f81fb7c4SAndroid Build Coastguard Worker default:
2374*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2375*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMControlChange: controller %d not yet implemented\n", controller); */ }
2376*f81fb7c4SAndroid Build Coastguard Worker #endif
2377*f81fb7c4SAndroid Build Coastguard Worker break;
2378*f81fb7c4SAndroid Build Coastguard Worker
2379*f81fb7c4SAndroid Build Coastguard Worker }
2380*f81fb7c4SAndroid Build Coastguard Worker
2381*f81fb7c4SAndroid Build Coastguard Worker return;
2382*f81fb7c4SAndroid Build Coastguard Worker }
2383*f81fb7c4SAndroid Build Coastguard Worker
2384*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2385*f81fb7c4SAndroid Build Coastguard Worker * VMUpdateRPNStateMachine()
2386*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2387*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2388*f81fb7c4SAndroid Build Coastguard Worker * Call this function when we want to parse RPN related controller messages.
2389*f81fb7c4SAndroid Build Coastguard Worker * We only support RPN0 (pitch bend sensitivity), RPN1 (fine tuning) and
2390*f81fb7c4SAndroid Build Coastguard Worker * RPN2 (coarse tuning). Any other RPNs or NRPNs are ignored for now.
2391*f81fb7c4SAndroid Build Coastguard Worker *.
2392*f81fb7c4SAndroid Build Coastguard Worker * Supports any order, so not a state machine anymore. This function was
2393*f81fb7c4SAndroid Build Coastguard Worker * rewritten to work correctly regardless of order.
2394*f81fb7c4SAndroid Build Coastguard Worker *
2395*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2396*f81fb7c4SAndroid Build Coastguard Worker * nChannel - the channel this controller message is coming from
2397*f81fb7c4SAndroid Build Coastguard Worker * nControllerNumber - which RPN related controller
2398*f81fb7c4SAndroid Build Coastguard Worker * nControlValue - the value of the RPN related controller
2399*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2400*f81fb7c4SAndroid Build Coastguard Worker *
2401*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2402*f81fb7c4SAndroid Build Coastguard Worker * returns EAS_RESULT, which is typically EAS_SUCCESS, since there are
2403*f81fb7c4SAndroid Build Coastguard Worker * few possible errors
2404*f81fb7c4SAndroid Build Coastguard Worker *
2405*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2406*f81fb7c4SAndroid Build Coastguard Worker * gsSynthObject.m_sChannel[nChannel].m_nPitchBendSensitivity
2407*f81fb7c4SAndroid Build Coastguard Worker * (or m_nFinePitch or m_nCoarsePitch)
2408*f81fb7c4SAndroid Build Coastguard Worker * will be updated if the proper RPN message is received.
2409*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2410*f81fb7c4SAndroid Build Coastguard Worker */
VMUpdateRPNStateMachine(S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 controller,EAS_U8 value)2411*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMUpdateRPNStateMachine (S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
2412*f81fb7c4SAndroid Build Coastguard Worker {
2413*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
2414*f81fb7c4SAndroid Build Coastguard Worker
2415*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2416*f81fb7c4SAndroid Build Coastguard Worker if (channel >= NUM_SYNTH_CHANNELS)
2417*f81fb7c4SAndroid Build Coastguard Worker {
2418*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMUpdateRPNStateMachines: error, %d invalid channel number\n",
2419*f81fb7c4SAndroid Build Coastguard Worker channel); */ }
2420*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
2421*f81fb7c4SAndroid Build Coastguard Worker }
2422*f81fb7c4SAndroid Build Coastguard Worker #endif
2423*f81fb7c4SAndroid Build Coastguard Worker
2424*f81fb7c4SAndroid Build Coastguard Worker pChannel = &(pSynth->channels[channel]);
2425*f81fb7c4SAndroid Build Coastguard Worker
2426*f81fb7c4SAndroid Build Coastguard Worker switch (controller)
2427*f81fb7c4SAndroid Build Coastguard Worker {
2428*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_NRPN_MSB:
2429*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_NRPN_LSB:
2430*f81fb7c4SAndroid Build Coastguard Worker pChannel->registeredParam = DEFAULT_REGISTERED_PARAM;
2431*f81fb7c4SAndroid Build Coastguard Worker break;
2432*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_RPN_MSB:
2433*f81fb7c4SAndroid Build Coastguard Worker pChannel->registeredParam =
2434*f81fb7c4SAndroid Build Coastguard Worker (pChannel->registeredParam & 0x7F) | (value<<7);
2435*f81fb7c4SAndroid Build Coastguard Worker break;
2436*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_SELECT_RPN_LSB:
2437*f81fb7c4SAndroid Build Coastguard Worker pChannel->registeredParam =
2438*f81fb7c4SAndroid Build Coastguard Worker (pChannel->registeredParam & 0x7F00) | value;
2439*f81fb7c4SAndroid Build Coastguard Worker break;
2440*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ENTER_DATA_MSB:
2441*f81fb7c4SAndroid Build Coastguard Worker switch (pChannel->registeredParam)
2442*f81fb7c4SAndroid Build Coastguard Worker {
2443*f81fb7c4SAndroid Build Coastguard Worker case 0:
2444*f81fb7c4SAndroid Build Coastguard Worker pChannel->pitchBendSensitivity = value * 100;
2445*f81fb7c4SAndroid Build Coastguard Worker break;
2446*f81fb7c4SAndroid Build Coastguard Worker case 1:
2447*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{702} <avoid division for performance reasons>*/
2448*f81fb7c4SAndroid Build Coastguard Worker pChannel->finePitch = (EAS_I8)((((value << 7) - 8192) * 100) >> 13);
2449*f81fb7c4SAndroid Build Coastguard Worker break;
2450*f81fb7c4SAndroid Build Coastguard Worker case 2:
2451*f81fb7c4SAndroid Build Coastguard Worker pChannel->coarsePitch = (EAS_I8)(value - 64);
2452*f81fb7c4SAndroid Build Coastguard Worker break;
2453*f81fb7c4SAndroid Build Coastguard Worker default:
2454*f81fb7c4SAndroid Build Coastguard Worker break;
2455*f81fb7c4SAndroid Build Coastguard Worker }
2456*f81fb7c4SAndroid Build Coastguard Worker break;
2457*f81fb7c4SAndroid Build Coastguard Worker case MIDI_CONTROLLER_ENTER_DATA_LSB:
2458*f81fb7c4SAndroid Build Coastguard Worker switch (pChannel->registeredParam)
2459*f81fb7c4SAndroid Build Coastguard Worker {
2460*f81fb7c4SAndroid Build Coastguard Worker case 0:
2461*f81fb7c4SAndroid Build Coastguard Worker //ignore lsb
2462*f81fb7c4SAndroid Build Coastguard Worker break;
2463*f81fb7c4SAndroid Build Coastguard Worker case 1:
2464*f81fb7c4SAndroid Build Coastguard Worker //ignore lsb
2465*f81fb7c4SAndroid Build Coastguard Worker break;
2466*f81fb7c4SAndroid Build Coastguard Worker case 2:
2467*f81fb7c4SAndroid Build Coastguard Worker //ignore lsb
2468*f81fb7c4SAndroid Build Coastguard Worker break;
2469*f81fb7c4SAndroid Build Coastguard Worker default:
2470*f81fb7c4SAndroid Build Coastguard Worker break;
2471*f81fb7c4SAndroid Build Coastguard Worker }
2472*f81fb7c4SAndroid Build Coastguard Worker break;
2473*f81fb7c4SAndroid Build Coastguard Worker default:
2474*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE; //not a RPN related controller
2475*f81fb7c4SAndroid Build Coastguard Worker }
2476*f81fb7c4SAndroid Build Coastguard Worker
2477*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2478*f81fb7c4SAndroid Build Coastguard Worker }
2479*f81fb7c4SAndroid Build Coastguard Worker
2480*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2481*f81fb7c4SAndroid Build Coastguard Worker * VMUpdateStaticChannelParameters()
2482*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2483*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2484*f81fb7c4SAndroid Build Coastguard Worker * Update all of the static channel parameters for channels that have had
2485*f81fb7c4SAndroid Build Coastguard Worker * a controller change values
2486*f81fb7c4SAndroid Build Coastguard Worker * Or if the synth has signalled that all channels must forcibly
2487*f81fb7c4SAndroid Build Coastguard Worker * be updated
2488*f81fb7c4SAndroid Build Coastguard Worker *
2489*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2490*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2491*f81fb7c4SAndroid Build Coastguard Worker *
2492*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2493*f81fb7c4SAndroid Build Coastguard Worker * none
2494*f81fb7c4SAndroid Build Coastguard Worker *
2495*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2496*f81fb7c4SAndroid Build Coastguard Worker * - psSynthObject->m_sChannel[].m_nStaticGain and m_nStaticPitch
2497*f81fb7c4SAndroid Build Coastguard Worker * are updated for channels whose controller values have changed
2498*f81fb7c4SAndroid Build Coastguard Worker * or if the synth has signalled that all channels must forcibly
2499*f81fb7c4SAndroid Build Coastguard Worker * be updated
2500*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2501*f81fb7c4SAndroid Build Coastguard Worker */
VMUpdateStaticChannelParameters(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth)2502*f81fb7c4SAndroid Build Coastguard Worker void VMUpdateStaticChannelParameters (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth)
2503*f81fb7c4SAndroid Build Coastguard Worker {
2504*f81fb7c4SAndroid Build Coastguard Worker EAS_INT channel;
2505*f81fb7c4SAndroid Build Coastguard Worker
2506*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->synthFlags & SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS)
2507*f81fb7c4SAndroid Build Coastguard Worker {
2508*f81fb7c4SAndroid Build Coastguard Worker /*
2509*f81fb7c4SAndroid Build Coastguard Worker the synth wants us to forcibly update all channel
2510*f81fb7c4SAndroid Build Coastguard Worker parameters. This event occurs when we are about to
2511*f81fb7c4SAndroid Build Coastguard Worker finish resetting the synth
2512*f81fb7c4SAndroid Build Coastguard Worker */
2513*f81fb7c4SAndroid Build Coastguard Worker for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
2514*f81fb7c4SAndroid Build Coastguard Worker {
2515*f81fb7c4SAndroid Build Coastguard Worker #ifdef _HYBRID_SYNTH
2516*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
2517*f81fb7c4SAndroid Build Coastguard Worker pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2518*f81fb7c4SAndroid Build Coastguard Worker else
2519*f81fb7c4SAndroid Build Coastguard Worker pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2520*f81fb7c4SAndroid Build Coastguard Worker #else
2521*f81fb7c4SAndroid Build Coastguard Worker pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2522*f81fb7c4SAndroid Build Coastguard Worker #endif
2523*f81fb7c4SAndroid Build Coastguard Worker }
2524*f81fb7c4SAndroid Build Coastguard Worker
2525*f81fb7c4SAndroid Build Coastguard Worker /*
2526*f81fb7c4SAndroid Build Coastguard Worker clear the flag to indicates we have now forcibly
2527*f81fb7c4SAndroid Build Coastguard Worker updated all channel parameters
2528*f81fb7c4SAndroid Build Coastguard Worker */
2529*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags &= ~SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
2530*f81fb7c4SAndroid Build Coastguard Worker }
2531*f81fb7c4SAndroid Build Coastguard Worker else
2532*f81fb7c4SAndroid Build Coastguard Worker {
2533*f81fb7c4SAndroid Build Coastguard Worker
2534*f81fb7c4SAndroid Build Coastguard Worker /* only update channel params if signalled by a channel flag */
2535*f81fb7c4SAndroid Build Coastguard Worker for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
2536*f81fb7c4SAndroid Build Coastguard Worker {
2537*f81fb7c4SAndroid Build Coastguard Worker if ( 0 != (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS))
2538*f81fb7c4SAndroid Build Coastguard Worker {
2539*f81fb7c4SAndroid Build Coastguard Worker #ifdef _HYBRID_SYNTH
2540*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[channel].regionIndex & FLAG_RGN_IDX_FM_SYNTH)
2541*f81fb7c4SAndroid Build Coastguard Worker pSecondarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2542*f81fb7c4SAndroid Build Coastguard Worker else
2543*f81fb7c4SAndroid Build Coastguard Worker pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2544*f81fb7c4SAndroid Build Coastguard Worker #else
2545*f81fb7c4SAndroid Build Coastguard Worker pPrimarySynth->pfUpdateChannel(pVoiceMgr, pSynth, (EAS_U8) channel);
2546*f81fb7c4SAndroid Build Coastguard Worker #endif
2547*f81fb7c4SAndroid Build Coastguard Worker }
2548*f81fb7c4SAndroid Build Coastguard Worker }
2549*f81fb7c4SAndroid Build Coastguard Worker
2550*f81fb7c4SAndroid Build Coastguard Worker }
2551*f81fb7c4SAndroid Build Coastguard Worker
2552*f81fb7c4SAndroid Build Coastguard Worker return;
2553*f81fb7c4SAndroid Build Coastguard Worker }
2554*f81fb7c4SAndroid Build Coastguard Worker
2555*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2556*f81fb7c4SAndroid Build Coastguard Worker * VMFindProgram()
2557*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2558*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2559*f81fb7c4SAndroid Build Coastguard Worker * Look up an individual program in sound library. This function
2560*f81fb7c4SAndroid Build Coastguard Worker * searches the bank list for a program, then the individual program
2561*f81fb7c4SAndroid Build Coastguard Worker * list.
2562*f81fb7c4SAndroid Build Coastguard Worker *
2563*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2564*f81fb7c4SAndroid Build Coastguard Worker *
2565*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2566*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2567*f81fb7c4SAndroid Build Coastguard Worker */
VMFindProgram(const S_EAS * pEAS,EAS_U32 bank,EAS_U8 programNum,EAS_U16 * pRegionIndex)2568*f81fb7c4SAndroid Build Coastguard Worker static EAS_RESULT VMFindProgram (const S_EAS *pEAS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
2569*f81fb7c4SAndroid Build Coastguard Worker {
2570*f81fb7c4SAndroid Build Coastguard Worker EAS_U32 locale;
2571*f81fb7c4SAndroid Build Coastguard Worker const S_PROGRAM *p;
2572*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 i;
2573*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 regionIndex;
2574*f81fb7c4SAndroid Build Coastguard Worker
2575*f81fb7c4SAndroid Build Coastguard Worker /* make sure we have a valid sound library */
2576*f81fb7c4SAndroid Build Coastguard Worker if (pEAS == NULL)
2577*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
2578*f81fb7c4SAndroid Build Coastguard Worker
2579*f81fb7c4SAndroid Build Coastguard Worker /* search the banks */
2580*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < pEAS->numBanks; i++)
2581*f81fb7c4SAndroid Build Coastguard Worker {
2582*f81fb7c4SAndroid Build Coastguard Worker if (bank == (EAS_U32) pEAS->pBanks[i].locale)
2583*f81fb7c4SAndroid Build Coastguard Worker {
2584*f81fb7c4SAndroid Build Coastguard Worker regionIndex = pEAS->pBanks[i].regionIndex[programNum];
2585*f81fb7c4SAndroid Build Coastguard Worker if (regionIndex != INVALID_REGION_INDEX)
2586*f81fb7c4SAndroid Build Coastguard Worker {
2587*f81fb7c4SAndroid Build Coastguard Worker *pRegionIndex = regionIndex;
2588*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2589*f81fb7c4SAndroid Build Coastguard Worker }
2590*f81fb7c4SAndroid Build Coastguard Worker break;
2591*f81fb7c4SAndroid Build Coastguard Worker }
2592*f81fb7c4SAndroid Build Coastguard Worker }
2593*f81fb7c4SAndroid Build Coastguard Worker
2594*f81fb7c4SAndroid Build Coastguard Worker /* establish locale */
2595*f81fb7c4SAndroid Build Coastguard Worker locale = ( bank << 8) | programNum;
2596*f81fb7c4SAndroid Build Coastguard Worker
2597*f81fb7c4SAndroid Build Coastguard Worker /* search for program */
2598*f81fb7c4SAndroid Build Coastguard Worker for (i = 0, p = pEAS->pPrograms; i < pEAS->numPrograms; i++, p++)
2599*f81fb7c4SAndroid Build Coastguard Worker {
2600*f81fb7c4SAndroid Build Coastguard Worker if (p->locale == locale)
2601*f81fb7c4SAndroid Build Coastguard Worker {
2602*f81fb7c4SAndroid Build Coastguard Worker *pRegionIndex = p->regionIndex;
2603*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2604*f81fb7c4SAndroid Build Coastguard Worker }
2605*f81fb7c4SAndroid Build Coastguard Worker }
2606*f81fb7c4SAndroid Build Coastguard Worker
2607*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
2608*f81fb7c4SAndroid Build Coastguard Worker }
2609*f81fb7c4SAndroid Build Coastguard Worker
2610*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
2611*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2612*f81fb7c4SAndroid Build Coastguard Worker * VMFindDLSProgram()
2613*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2614*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2615*f81fb7c4SAndroid Build Coastguard Worker * Look up an individual program in sound library. This function
2616*f81fb7c4SAndroid Build Coastguard Worker * searches the bank list for a program, then the individual program
2617*f81fb7c4SAndroid Build Coastguard Worker * list.
2618*f81fb7c4SAndroid Build Coastguard Worker *
2619*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2620*f81fb7c4SAndroid Build Coastguard Worker *
2621*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2622*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2623*f81fb7c4SAndroid Build Coastguard Worker */
VMFindDLSProgram(const S_DLS * pDLS,EAS_U32 bank,EAS_U8 programNum,EAS_U16 * pRegionIndex)2624*f81fb7c4SAndroid Build Coastguard Worker static EAS_RESULT VMFindDLSProgram (const S_DLS *pDLS, EAS_U32 bank, EAS_U8 programNum, EAS_U16 *pRegionIndex)
2625*f81fb7c4SAndroid Build Coastguard Worker {
2626*f81fb7c4SAndroid Build Coastguard Worker EAS_U32 locale;
2627*f81fb7c4SAndroid Build Coastguard Worker const S_PROGRAM *p;
2628*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 i;
2629*f81fb7c4SAndroid Build Coastguard Worker
2630*f81fb7c4SAndroid Build Coastguard Worker /* make sure we have a valid sound library */
2631*f81fb7c4SAndroid Build Coastguard Worker if (pDLS == NULL)
2632*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
2633*f81fb7c4SAndroid Build Coastguard Worker
2634*f81fb7c4SAndroid Build Coastguard Worker /* establish locale */
2635*f81fb7c4SAndroid Build Coastguard Worker locale = (bank << 8) | programNum;
2636*f81fb7c4SAndroid Build Coastguard Worker
2637*f81fb7c4SAndroid Build Coastguard Worker /* search for program */
2638*f81fb7c4SAndroid Build Coastguard Worker for (i = 0, p = pDLS->pDLSPrograms; i < pDLS->numDLSPrograms; i++, p++)
2639*f81fb7c4SAndroid Build Coastguard Worker {
2640*f81fb7c4SAndroid Build Coastguard Worker if (p->locale == locale)
2641*f81fb7c4SAndroid Build Coastguard Worker {
2642*f81fb7c4SAndroid Build Coastguard Worker *pRegionIndex = p->regionIndex;
2643*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2644*f81fb7c4SAndroid Build Coastguard Worker }
2645*f81fb7c4SAndroid Build Coastguard Worker }
2646*f81fb7c4SAndroid Build Coastguard Worker
2647*f81fb7c4SAndroid Build Coastguard Worker return EAS_FAILURE;
2648*f81fb7c4SAndroid Build Coastguard Worker }
2649*f81fb7c4SAndroid Build Coastguard Worker #endif
2650*f81fb7c4SAndroid Build Coastguard Worker
2651*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2652*f81fb7c4SAndroid Build Coastguard Worker * VMProgramChange()
2653*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2654*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2655*f81fb7c4SAndroid Build Coastguard Worker * Change the instrument (program) for the given channel.
2656*f81fb7c4SAndroid Build Coastguard Worker *
2657*f81fb7c4SAndroid Build Coastguard Worker * Depending on the program number, and the bank selected for this channel, the
2658*f81fb7c4SAndroid Build Coastguard Worker * program may be in ROM, RAM (from SMAF or CMX related RAM wavetable), or
2659*f81fb7c4SAndroid Build Coastguard Worker * Alternate wavetable (from mobile DLS or other DLS file)
2660*f81fb7c4SAndroid Build Coastguard Worker *
2661*f81fb7c4SAndroid Build Coastguard Worker * This function figures out what wavetable should be used, and sets it up as the
2662*f81fb7c4SAndroid Build Coastguard Worker * wavetable to use for this channel. Also the channel may switch from a melodic
2663*f81fb7c4SAndroid Build Coastguard Worker * channel to a rhythm channel, or vice versa.
2664*f81fb7c4SAndroid Build Coastguard Worker *
2665*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2666*f81fb7c4SAndroid Build Coastguard Worker *
2667*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2668*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2669*f81fb7c4SAndroid Build Coastguard Worker * gsSynthObject.m_sChannel[nChannel].m_nProgramNumber is likely changed
2670*f81fb7c4SAndroid Build Coastguard Worker * gsSynthObject.m_sChannel[nChannel].m_psEAS may be changed
2671*f81fb7c4SAndroid Build Coastguard Worker * gsSynthObject.m_sChannel[nChannel].m_bRhythmChannel may be changed
2672*f81fb7c4SAndroid Build Coastguard Worker *
2673*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2674*f81fb7c4SAndroid Build Coastguard Worker */
2675*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pVoiceMgr) reserved for future use */
VMProgramChange(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_U8 channel,EAS_U8 program)2676*f81fb7c4SAndroid Build Coastguard Worker void VMProgramChange (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel, EAS_U8 program)
2677*f81fb7c4SAndroid Build Coastguard Worker {
2678*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_CHANNEL *pChannel;
2679*f81fb7c4SAndroid Build Coastguard Worker EAS_U32 bank;
2680*f81fb7c4SAndroid Build Coastguard Worker EAS_U16 regionIndex;
2681*f81fb7c4SAndroid Build Coastguard Worker
2682*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2683*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "VMProgramChange: vSynthNum=%d, channel=%d, program=%d\n", pSynth->vSynthNum, channel, program); */ }
2684*f81fb7c4SAndroid Build Coastguard Worker #endif
2685*f81fb7c4SAndroid Build Coastguard Worker
2686*f81fb7c4SAndroid Build Coastguard Worker /* setup pointer to MIDI channel data */
2687*f81fb7c4SAndroid Build Coastguard Worker pChannel = &pSynth->channels[channel];
2688*f81fb7c4SAndroid Build Coastguard Worker bank = pChannel->bankNum;
2689*f81fb7c4SAndroid Build Coastguard Worker
2690*f81fb7c4SAndroid Build Coastguard Worker /* allow channels to switch between being melodic or rhythm channels, using GM2 CC values */
2691*f81fb7c4SAndroid Build Coastguard Worker if ((bank & 0xFF00) == DEFAULT_RHYTHM_BANK_NUMBER)
2692*f81fb7c4SAndroid Build Coastguard Worker {
2693*f81fb7c4SAndroid Build Coastguard Worker /* make it a rhythm channel */
2694*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_RHYTHM_CHANNEL;
2695*f81fb7c4SAndroid Build Coastguard Worker }
2696*f81fb7c4SAndroid Build Coastguard Worker else if ((bank & 0xFF00) == DEFAULT_MELODY_BANK_NUMBER)
2697*f81fb7c4SAndroid Build Coastguard Worker {
2698*f81fb7c4SAndroid Build Coastguard Worker /* make it a melody channel */
2699*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags &= ~CHANNEL_FLAG_RHYTHM_CHANNEL;
2700*f81fb7c4SAndroid Build Coastguard Worker }
2701*f81fb7c4SAndroid Build Coastguard Worker
2702*f81fb7c4SAndroid Build Coastguard Worker regionIndex = DEFAULT_REGION_INDEX;
2703*f81fb7c4SAndroid Build Coastguard Worker
2704*f81fb7c4SAndroid Build Coastguard Worker #ifdef EXTERNAL_AUDIO
2705*f81fb7c4SAndroid Build Coastguard Worker /* give the external audio interface a chance to handle it */
2706*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->cbProgChgFunc != NULL)
2707*f81fb7c4SAndroid Build Coastguard Worker {
2708*f81fb7c4SAndroid Build Coastguard Worker S_EXT_AUDIO_PRG_CHG prgChg;
2709*f81fb7c4SAndroid Build Coastguard Worker prgChg.channel = channel;
2710*f81fb7c4SAndroid Build Coastguard Worker prgChg.bank = (EAS_U16) bank;
2711*f81fb7c4SAndroid Build Coastguard Worker prgChg.program = program;
2712*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->cbProgChgFunc(pSynth->pExtAudioInstData, &prgChg))
2713*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_EXTERNAL_AUDIO;
2714*f81fb7c4SAndroid Build Coastguard Worker }
2715*f81fb7c4SAndroid Build Coastguard Worker
2716*f81fb7c4SAndroid Build Coastguard Worker #endif
2717*f81fb7c4SAndroid Build Coastguard Worker
2718*f81fb7c4SAndroid Build Coastguard Worker
2719*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
2720*f81fb7c4SAndroid Build Coastguard Worker /* first check for DLS program that may overlay the internal instrument */
2721*f81fb7c4SAndroid Build Coastguard Worker if (VMFindDLSProgram(pSynth->pDLS, bank, program, ®ionIndex) != EAS_SUCCESS)
2722*f81fb7c4SAndroid Build Coastguard Worker #endif
2723*f81fb7c4SAndroid Build Coastguard Worker
2724*f81fb7c4SAndroid Build Coastguard Worker /* braces to support 'if' clause above */
2725*f81fb7c4SAndroid Build Coastguard Worker {
2726*f81fb7c4SAndroid Build Coastguard Worker
2727*f81fb7c4SAndroid Build Coastguard Worker /* look in the internal banks */
2728*f81fb7c4SAndroid Build Coastguard Worker if (VMFindProgram(pSynth->pEAS, bank, program, ®ionIndex) != EAS_SUCCESS)
2729*f81fb7c4SAndroid Build Coastguard Worker
2730*f81fb7c4SAndroid Build Coastguard Worker /* fall back to default bank */
2731*f81fb7c4SAndroid Build Coastguard Worker {
2732*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->channels[channel].channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL)
2733*f81fb7c4SAndroid Build Coastguard Worker bank = DEFAULT_RHYTHM_BANK_NUMBER;
2734*f81fb7c4SAndroid Build Coastguard Worker else
2735*f81fb7c4SAndroid Build Coastguard Worker bank = DEFAULT_MELODY_BANK_NUMBER;
2736*f81fb7c4SAndroid Build Coastguard Worker
2737*f81fb7c4SAndroid Build Coastguard Worker if (VMFindProgram(pSynth->pEAS, bank, program, ®ionIndex) != EAS_SUCCESS)
2738*f81fb7c4SAndroid Build Coastguard Worker
2739*f81fb7c4SAndroid Build Coastguard Worker /* switch to program 0 in the default bank */
2740*f81fb7c4SAndroid Build Coastguard Worker {
2741*f81fb7c4SAndroid Build Coastguard Worker if (VMFindProgram(pSynth->pEAS, bank, 0, ®ionIndex) != EAS_SUCCESS)
2742*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMProgramChange: No program @ %03d:%03d:%03d\n",
2743*f81fb7c4SAndroid Build Coastguard Worker (bank >> 8) & 0x7f, bank & 0x7f, program); */ }
2744*f81fb7c4SAndroid Build Coastguard Worker }
2745*f81fb7c4SAndroid Build Coastguard Worker }
2746*f81fb7c4SAndroid Build Coastguard Worker }
2747*f81fb7c4SAndroid Build Coastguard Worker
2748*f81fb7c4SAndroid Build Coastguard Worker /* we have our new program change for this channel */
2749*f81fb7c4SAndroid Build Coastguard Worker pChannel->programNum = program;
2750*f81fb7c4SAndroid Build Coastguard Worker pChannel->regionIndex = regionIndex;
2751*f81fb7c4SAndroid Build Coastguard Worker
2752*f81fb7c4SAndroid Build Coastguard Worker /*
2753*f81fb7c4SAndroid Build Coastguard Worker set a channel flag to request parameter updates
2754*f81fb7c4SAndroid Build Coastguard Worker for all the voices associated with this channel
2755*f81fb7c4SAndroid Build Coastguard Worker */
2756*f81fb7c4SAndroid Build Coastguard Worker pChannel->channelFlags |= CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
2757*f81fb7c4SAndroid Build Coastguard Worker
2758*f81fb7c4SAndroid Build Coastguard Worker return;
2759*f81fb7c4SAndroid Build Coastguard Worker }
2760*f81fb7c4SAndroid Build Coastguard Worker
2761*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2762*f81fb7c4SAndroid Build Coastguard Worker * VMAddSamples()
2763*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2764*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2765*f81fb7c4SAndroid Build Coastguard Worker * Synthesize the requested number of samples (block based processing)
2766*f81fb7c4SAndroid Build Coastguard Worker *
2767*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2768*f81fb7c4SAndroid Build Coastguard Worker * nNumSamplesToAdd - number of samples to write to buffer
2769*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2770*f81fb7c4SAndroid Build Coastguard Worker *
2771*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2772*f81fb7c4SAndroid Build Coastguard Worker * number of voices rendered
2773*f81fb7c4SAndroid Build Coastguard Worker *
2774*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2775*f81fb7c4SAndroid Build Coastguard Worker * - samples are added to the presently free buffer
2776*f81fb7c4SAndroid Build Coastguard Worker *
2777*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2778*f81fb7c4SAndroid Build Coastguard Worker */
VMAddSamples(S_VOICE_MGR * pVoiceMgr,EAS_I32 * pMixBuffer,EAS_I32 numSamples)2779*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 VMAddSamples (S_VOICE_MGR *pVoiceMgr, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
2780*f81fb7c4SAndroid Build Coastguard Worker {
2781*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
2782*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voicesRendered;
2783*f81fb7c4SAndroid Build Coastguard Worker EAS_INT voiceNum;
2784*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL done;
2785*f81fb7c4SAndroid Build Coastguard Worker
2786*f81fb7c4SAndroid Build Coastguard Worker #ifdef _REVERB
2787*f81fb7c4SAndroid Build Coastguard Worker EAS_PCM *pReverbSendBuffer;
2788*f81fb7c4SAndroid Build Coastguard Worker #endif // ifdef _REVERB
2789*f81fb7c4SAndroid Build Coastguard Worker
2790*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHORUS
2791*f81fb7c4SAndroid Build Coastguard Worker EAS_PCM *pChorusSendBuffer;
2792*f81fb7c4SAndroid Build Coastguard Worker #endif // ifdef _CHORUS
2793*f81fb7c4SAndroid Build Coastguard Worker
2794*f81fb7c4SAndroid Build Coastguard Worker voicesRendered = 0;
2795*f81fb7c4SAndroid Build Coastguard Worker for (voiceNum = 0; voiceNum < MAX_SYNTH_VOICES; voiceNum++)
2796*f81fb7c4SAndroid Build Coastguard Worker {
2797*f81fb7c4SAndroid Build Coastguard Worker
2798*f81fb7c4SAndroid Build Coastguard Worker /* retarget stolen voices */
2799*f81fb7c4SAndroid Build Coastguard Worker if ((pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen) && (pVoiceMgr->voices[voiceNum].gain <= 0))
2800*f81fb7c4SAndroid Build Coastguard Worker VMRetargetStolenVoice(pVoiceMgr, voiceNum);
2801*f81fb7c4SAndroid Build Coastguard Worker
2802*f81fb7c4SAndroid Build Coastguard Worker /* get pointer to virtual synth */
2803*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[pVoiceMgr->voices[voiceNum].channel >> 4];
2804*f81fb7c4SAndroid Build Coastguard Worker
2805*f81fb7c4SAndroid Build Coastguard Worker /* synthesize active voices */
2806*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState != eVoiceStateFree)
2807*f81fb7c4SAndroid Build Coastguard Worker {
2808*f81fb7c4SAndroid Build Coastguard Worker done = GetSynthPtr(voiceNum)->pfUpdateVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum], GetAdjustedVoiceNum(voiceNum), pMixBuffer, numSamples);
2809*f81fb7c4SAndroid Build Coastguard Worker voicesRendered++;
2810*f81fb7c4SAndroid Build Coastguard Worker
2811*f81fb7c4SAndroid Build Coastguard Worker /* voice is finished */
2812*f81fb7c4SAndroid Build Coastguard Worker if (done == EAS_TRUE)
2813*f81fb7c4SAndroid Build Coastguard Worker {
2814*f81fb7c4SAndroid Build Coastguard Worker /* set gain of stolen voice to zero so it will be restarted */
2815*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStolen)
2816*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].gain = 0;
2817*f81fb7c4SAndroid Build Coastguard Worker
2818*f81fb7c4SAndroid Build Coastguard Worker /* or return it to the free voice pool */
2819*f81fb7c4SAndroid Build Coastguard Worker else
2820*f81fb7c4SAndroid Build Coastguard Worker VMFreeVoice(pVoiceMgr, pSynth, &pVoiceMgr->voices[voiceNum]);
2821*f81fb7c4SAndroid Build Coastguard Worker }
2822*f81fb7c4SAndroid Build Coastguard Worker
2823*f81fb7c4SAndroid Build Coastguard Worker /* if this voice is scheduled to be muted, set the mute flag */
2824*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceFlags & VOICE_FLAG_DEFER_MUTE)
2825*f81fb7c4SAndroid Build Coastguard Worker {
2826*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceFlags &= ~(VOICE_FLAG_DEFER_MUTE | VOICE_FLAG_DEFER_MIDI_NOTE_OFF);
2827*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, voiceNum);
2828*f81fb7c4SAndroid Build Coastguard Worker }
2829*f81fb7c4SAndroid Build Coastguard Worker
2830*f81fb7c4SAndroid Build Coastguard Worker /* if voice just started, advance state to play */
2831*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->voices[voiceNum].voiceState == eVoiceStateStart)
2832*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->voices[voiceNum].voiceState = eVoiceStatePlay;
2833*f81fb7c4SAndroid Build Coastguard Worker }
2834*f81fb7c4SAndroid Build Coastguard Worker }
2835*f81fb7c4SAndroid Build Coastguard Worker
2836*f81fb7c4SAndroid Build Coastguard Worker return voicesRendered;
2837*f81fb7c4SAndroid Build Coastguard Worker }
2838*f81fb7c4SAndroid Build Coastguard Worker
2839*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2840*f81fb7c4SAndroid Build Coastguard Worker * VMRender()
2841*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2842*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2843*f81fb7c4SAndroid Build Coastguard Worker * This routine renders a frame of audio
2844*f81fb7c4SAndroid Build Coastguard Worker *
2845*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2846*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
2847*f81fb7c4SAndroid Build Coastguard Worker *
2848*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2849*f81fb7c4SAndroid Build Coastguard Worker * pVoicesRendered - number of voices rendered this frame
2850*f81fb7c4SAndroid Build Coastguard Worker *
2851*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2852*f81fb7c4SAndroid Build Coastguard Worker *
2853*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2854*f81fb7c4SAndroid Build Coastguard Worker */
VMRender(S_VOICE_MGR * pVoiceMgr,EAS_I32 numSamples,EAS_I32 * pMixBuffer,EAS_I32 * pVoicesRendered)2855*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMRender (S_VOICE_MGR *pVoiceMgr, EAS_I32 numSamples, EAS_I32 *pMixBuffer, EAS_I32 *pVoicesRendered)
2856*f81fb7c4SAndroid Build Coastguard Worker {
2857*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
2858*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
2859*f81fb7c4SAndroid Build Coastguard Worker EAS_INT channel;
2860*f81fb7c4SAndroid Build Coastguard Worker
2861*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHECKED_BUILD
2862*f81fb7c4SAndroid Build Coastguard Worker SanityCheck(pVoiceMgr);
2863*f81fb7c4SAndroid Build Coastguard Worker #endif
2864*f81fb7c4SAndroid Build Coastguard Worker
2865*f81fb7c4SAndroid Build Coastguard Worker /* update MIDI channel parameters */
2866*f81fb7c4SAndroid Build Coastguard Worker *pVoicesRendered = 0;
2867*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
2868*f81fb7c4SAndroid Build Coastguard Worker {
2869*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->pSynth[i] != NULL)
2870*f81fb7c4SAndroid Build Coastguard Worker VMUpdateStaticChannelParameters(pVoiceMgr, pVoiceMgr->pSynth[i]);
2871*f81fb7c4SAndroid Build Coastguard Worker }
2872*f81fb7c4SAndroid Build Coastguard Worker
2873*f81fb7c4SAndroid Build Coastguard Worker /* synthesize a buffer of audio */
2874*f81fb7c4SAndroid Build Coastguard Worker *pVoicesRendered = VMAddSamples(pVoiceMgr, pMixBuffer, numSamples);
2875*f81fb7c4SAndroid Build Coastguard Worker
2876*f81fb7c4SAndroid Build Coastguard Worker /*
2877*f81fb7c4SAndroid Build Coastguard Worker * check for deferred note-off messages
2878*f81fb7c4SAndroid Build Coastguard Worker * If flag is set, that means one or more voices are expecting deferred
2879*f81fb7c4SAndroid Build Coastguard Worker * midi note-off messages because the midi note-on and corresponding midi
2880*f81fb7c4SAndroid Build Coastguard Worker * note-off requests occurred during the same update interval. The goal
2881*f81fb7c4SAndroid Build Coastguard Worker * is the defer the note-off request so that the note can at least start.
2882*f81fb7c4SAndroid Build Coastguard Worker */
2883*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
2884*f81fb7c4SAndroid Build Coastguard Worker {
2885*f81fb7c4SAndroid Build Coastguard Worker pSynth = pVoiceMgr->pSynth[i];
2886*f81fb7c4SAndroid Build Coastguard Worker
2887*f81fb7c4SAndroid Build Coastguard Worker if (pSynth== NULL)
2888*f81fb7c4SAndroid Build Coastguard Worker continue;
2889*f81fb7c4SAndroid Build Coastguard Worker
2890*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->synthFlags & SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING)
2891*f81fb7c4SAndroid Build Coastguard Worker VMDeferredStopNote(pVoiceMgr, pSynth);
2892*f81fb7c4SAndroid Build Coastguard Worker
2893*f81fb7c4SAndroid Build Coastguard Worker /* check if we need to reset the synth */
2894*f81fb7c4SAndroid Build Coastguard Worker if ((pSynth->synthFlags & SYNTH_FLAG_RESET_IS_REQUESTED) &&
2895*f81fb7c4SAndroid Build Coastguard Worker (pSynth->numActiveVoices == 0))
2896*f81fb7c4SAndroid Build Coastguard Worker {
2897*f81fb7c4SAndroid Build Coastguard Worker /*
2898*f81fb7c4SAndroid Build Coastguard Worker complete the process of resetting the synth now that
2899*f81fb7c4SAndroid Build Coastguard Worker all voices have muted
2900*f81fb7c4SAndroid Build Coastguard Worker */
2901*f81fb7c4SAndroid Build Coastguard Worker #ifdef _DEBUG_VM
2902*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "VMAddSamples: complete the reset process\n"); */ }
2903*f81fb7c4SAndroid Build Coastguard Worker #endif
2904*f81fb7c4SAndroid Build Coastguard Worker
2905*f81fb7c4SAndroid Build Coastguard Worker VMInitializeAllChannels(pVoiceMgr, pSynth);
2906*f81fb7c4SAndroid Build Coastguard Worker VMInitializeAllVoices(pVoiceMgr, pSynth->vSynthNum);
2907*f81fb7c4SAndroid Build Coastguard Worker
2908*f81fb7c4SAndroid Build Coastguard Worker /* clear the reset flag */
2909*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags &= ~SYNTH_FLAG_RESET_IS_REQUESTED;
2910*f81fb7c4SAndroid Build Coastguard Worker }
2911*f81fb7c4SAndroid Build Coastguard Worker
2912*f81fb7c4SAndroid Build Coastguard Worker /* clear channel update flags */
2913*f81fb7c4SAndroid Build Coastguard Worker for (channel = 0; channel < NUM_SYNTH_CHANNELS; channel++)
2914*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
2915*f81fb7c4SAndroid Build Coastguard Worker
2916*f81fb7c4SAndroid Build Coastguard Worker }
2917*f81fb7c4SAndroid Build Coastguard Worker
2918*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHECKED_BUILD
2919*f81fb7c4SAndroid Build Coastguard Worker SanityCheck(pVoiceMgr);
2920*f81fb7c4SAndroid Build Coastguard Worker #endif
2921*f81fb7c4SAndroid Build Coastguard Worker
2922*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
2923*f81fb7c4SAndroid Build Coastguard Worker }
2924*f81fb7c4SAndroid Build Coastguard Worker
2925*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2926*f81fb7c4SAndroid Build Coastguard Worker * VMInitWorkload()
2927*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2928*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2929*f81fb7c4SAndroid Build Coastguard Worker * Clears the workload counter
2930*f81fb7c4SAndroid Build Coastguard Worker *
2931*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2932*f81fb7c4SAndroid Build Coastguard Worker * pVoiceMgr - pointer to instance data
2933*f81fb7c4SAndroid Build Coastguard Worker *
2934*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2935*f81fb7c4SAndroid Build Coastguard Worker *
2936*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2937*f81fb7c4SAndroid Build Coastguard Worker *
2938*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2939*f81fb7c4SAndroid Build Coastguard Worker */
VMInitWorkload(S_VOICE_MGR * pVoiceMgr)2940*f81fb7c4SAndroid Build Coastguard Worker void VMInitWorkload (S_VOICE_MGR *pVoiceMgr)
2941*f81fb7c4SAndroid Build Coastguard Worker {
2942*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->workload = 0;
2943*f81fb7c4SAndroid Build Coastguard Worker }
2944*f81fb7c4SAndroid Build Coastguard Worker
2945*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2946*f81fb7c4SAndroid Build Coastguard Worker * VMSetWorkload()
2947*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2948*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2949*f81fb7c4SAndroid Build Coastguard Worker * Sets the max workload for a single frame.
2950*f81fb7c4SAndroid Build Coastguard Worker *
2951*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2952*f81fb7c4SAndroid Build Coastguard Worker * pVoiceMgr - pointer to instance data
2953*f81fb7c4SAndroid Build Coastguard Worker *
2954*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2955*f81fb7c4SAndroid Build Coastguard Worker *
2956*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2957*f81fb7c4SAndroid Build Coastguard Worker *
2958*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2959*f81fb7c4SAndroid Build Coastguard Worker */
VMSetWorkload(S_VOICE_MGR * pVoiceMgr,EAS_I32 maxWorkLoad)2960*f81fb7c4SAndroid Build Coastguard Worker void VMSetWorkload (S_VOICE_MGR *pVoiceMgr, EAS_I32 maxWorkLoad)
2961*f81fb7c4SAndroid Build Coastguard Worker {
2962*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->maxWorkLoad = maxWorkLoad;
2963*f81fb7c4SAndroid Build Coastguard Worker }
2964*f81fb7c4SAndroid Build Coastguard Worker
2965*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2966*f81fb7c4SAndroid Build Coastguard Worker * VMCheckWorkload()
2967*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2968*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2969*f81fb7c4SAndroid Build Coastguard Worker * Checks to see if work load has been exceeded on this frame.
2970*f81fb7c4SAndroid Build Coastguard Worker *
2971*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2972*f81fb7c4SAndroid Build Coastguard Worker * pVoiceMgr - pointer to instance data
2973*f81fb7c4SAndroid Build Coastguard Worker *
2974*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2975*f81fb7c4SAndroid Build Coastguard Worker *
2976*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
2977*f81fb7c4SAndroid Build Coastguard Worker *
2978*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2979*f81fb7c4SAndroid Build Coastguard Worker */
VMCheckWorkload(S_VOICE_MGR * pVoiceMgr)2980*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL VMCheckWorkload (S_VOICE_MGR *pVoiceMgr)
2981*f81fb7c4SAndroid Build Coastguard Worker {
2982*f81fb7c4SAndroid Build Coastguard Worker if (pVoiceMgr->maxWorkLoad > 0)
2983*f81fb7c4SAndroid Build Coastguard Worker return (EAS_BOOL) (pVoiceMgr->workload >= pVoiceMgr->maxWorkLoad);
2984*f81fb7c4SAndroid Build Coastguard Worker return EAS_FALSE;
2985*f81fb7c4SAndroid Build Coastguard Worker }
2986*f81fb7c4SAndroid Build Coastguard Worker
2987*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
2988*f81fb7c4SAndroid Build Coastguard Worker * VMActiveVoices()
2989*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
2990*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
2991*f81fb7c4SAndroid Build Coastguard Worker * Returns the number of active voices in the synthesizer.
2992*f81fb7c4SAndroid Build Coastguard Worker *
2993*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
2994*f81fb7c4SAndroid Build Coastguard Worker * pEASData - pointer to instance data
2995*f81fb7c4SAndroid Build Coastguard Worker *
2996*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
2997*f81fb7c4SAndroid Build Coastguard Worker * Returns the number of active voices
2998*f81fb7c4SAndroid Build Coastguard Worker *
2999*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3000*f81fb7c4SAndroid Build Coastguard Worker *
3001*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3002*f81fb7c4SAndroid Build Coastguard Worker */
VMActiveVoices(S_SYNTH * pSynth)3003*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 VMActiveVoices (S_SYNTH *pSynth)
3004*f81fb7c4SAndroid Build Coastguard Worker {
3005*f81fb7c4SAndroid Build Coastguard Worker return pSynth->numActiveVoices;
3006*f81fb7c4SAndroid Build Coastguard Worker }
3007*f81fb7c4SAndroid Build Coastguard Worker
3008*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3009*f81fb7c4SAndroid Build Coastguard Worker * VMSetPolyphony()
3010*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3011*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3012*f81fb7c4SAndroid Build Coastguard Worker * Set the virtual synth polyphony. 0 = no limit (i.e. can use
3013*f81fb7c4SAndroid Build Coastguard Worker * all available voices).
3014*f81fb7c4SAndroid Build Coastguard Worker *
3015*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3016*f81fb7c4SAndroid Build Coastguard Worker * pVoiceMgr pointer to synthesizer data
3017*f81fb7c4SAndroid Build Coastguard Worker * polyphonyCount desired polyphony count
3018*f81fb7c4SAndroid Build Coastguard Worker * pSynth pointer to virtual synth
3019*f81fb7c4SAndroid Build Coastguard Worker *
3020*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3021*f81fb7c4SAndroid Build Coastguard Worker * Returns error code
3022*f81fb7c4SAndroid Build Coastguard Worker *
3023*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3024*f81fb7c4SAndroid Build Coastguard Worker *
3025*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3026*f81fb7c4SAndroid Build Coastguard Worker */
VMSetPolyphony(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_I32 polyphonyCount)3027*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMSetPolyphony (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 polyphonyCount)
3028*f81fb7c4SAndroid Build Coastguard Worker {
3029*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
3030*f81fb7c4SAndroid Build Coastguard Worker EAS_INT activeVoices;
3031*f81fb7c4SAndroid Build Coastguard Worker
3032*f81fb7c4SAndroid Build Coastguard Worker /* check limits */
3033*f81fb7c4SAndroid Build Coastguard Worker if (polyphonyCount < 0)
3034*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_PARAMETER_RANGE;
3035*f81fb7c4SAndroid Build Coastguard Worker
3036*f81fb7c4SAndroid Build Coastguard Worker /* zero is max polyphony */
3037*f81fb7c4SAndroid Build Coastguard Worker if ((polyphonyCount == 0) || (polyphonyCount > MAX_SYNTH_VOICES))
3038*f81fb7c4SAndroid Build Coastguard Worker {
3039*f81fb7c4SAndroid Build Coastguard Worker pSynth->maxPolyphony = 0;
3040*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3041*f81fb7c4SAndroid Build Coastguard Worker }
3042*f81fb7c4SAndroid Build Coastguard Worker
3043*f81fb7c4SAndroid Build Coastguard Worker /* set new polyphony */
3044*f81fb7c4SAndroid Build Coastguard Worker pSynth->maxPolyphony = (EAS_U16) polyphonyCount;
3045*f81fb7c4SAndroid Build Coastguard Worker
3046*f81fb7c4SAndroid Build Coastguard Worker /* max polyphony is minimum of virtual synth and actual synth */
3047*f81fb7c4SAndroid Build Coastguard Worker if (polyphonyCount > pVoiceMgr->maxPolyphony)
3048*f81fb7c4SAndroid Build Coastguard Worker polyphonyCount = pVoiceMgr->maxPolyphony;
3049*f81fb7c4SAndroid Build Coastguard Worker
3050*f81fb7c4SAndroid Build Coastguard Worker /* if SP-MIDI mode, update the channel muting */
3051*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->synthFlags & SYNTH_FLAG_SP_MIDI_ON)
3052*f81fb7c4SAndroid Build Coastguard Worker VMMIPUpdateChannelMuting(pVoiceMgr, pSynth);
3053*f81fb7c4SAndroid Build Coastguard Worker else
3054*f81fb7c4SAndroid Build Coastguard Worker pSynth->poolAlloc[0] = (EAS_U8) polyphonyCount;
3055*f81fb7c4SAndroid Build Coastguard Worker
3056*f81fb7c4SAndroid Build Coastguard Worker /* are we under polyphony limit? */
3057*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->numActiveVoices <= polyphonyCount)
3058*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3059*f81fb7c4SAndroid Build Coastguard Worker
3060*f81fb7c4SAndroid Build Coastguard Worker /* count the number of active voices */
3061*f81fb7c4SAndroid Build Coastguard Worker activeVoices = 0;
3062*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
3063*f81fb7c4SAndroid Build Coastguard Worker {
3064*f81fb7c4SAndroid Build Coastguard Worker /* this synth? */
3065*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoiceMgr->voices[i].nextChannel) != pSynth->vSynthNum)
3066*f81fb7c4SAndroid Build Coastguard Worker continue;
3067*f81fb7c4SAndroid Build Coastguard Worker
3068*f81fb7c4SAndroid Build Coastguard Worker /* is voice active? */
3069*f81fb7c4SAndroid Build Coastguard Worker if ((pVoiceMgr->voices[i].voiceState != eVoiceStateFree) && (pVoiceMgr->voices[i].voiceState != eVoiceStateMuting))
3070*f81fb7c4SAndroid Build Coastguard Worker activeVoices++;
3071*f81fb7c4SAndroid Build Coastguard Worker }
3072*f81fb7c4SAndroid Build Coastguard Worker
3073*f81fb7c4SAndroid Build Coastguard Worker /* we may have to mute voices to reach new target */
3074*f81fb7c4SAndroid Build Coastguard Worker while (activeVoices > polyphonyCount)
3075*f81fb7c4SAndroid Build Coastguard Worker {
3076*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
3077*f81fb7c4SAndroid Build Coastguard Worker EAS_I32 currentPriority, bestPriority;
3078*f81fb7c4SAndroid Build Coastguard Worker EAS_INT bestCandidate;
3079*f81fb7c4SAndroid Build Coastguard Worker
3080*f81fb7c4SAndroid Build Coastguard Worker /* find the lowest priority voice */
3081*f81fb7c4SAndroid Build Coastguard Worker bestPriority = bestCandidate = -1;
3082*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
3083*f81fb7c4SAndroid Build Coastguard Worker {
3084*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pVoiceMgr->voices[i];
3085*f81fb7c4SAndroid Build Coastguard Worker
3086*f81fb7c4SAndroid Build Coastguard Worker /* this synth? */
3087*f81fb7c4SAndroid Build Coastguard Worker if (GET_VSYNTH(pVoice->nextChannel) != pSynth->vSynthNum)
3088*f81fb7c4SAndroid Build Coastguard Worker continue;
3089*f81fb7c4SAndroid Build Coastguard Worker
3090*f81fb7c4SAndroid Build Coastguard Worker /* if voice is stolen or just started, reduce the likelihood it will be stolen */
3091*f81fb7c4SAndroid Build Coastguard Worker if (( pVoice->voiceState == eVoiceStateStolen) || (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET))
3092*f81fb7c4SAndroid Build Coastguard Worker {
3093*f81fb7c4SAndroid Build Coastguard Worker /* include velocity */
3094*f81fb7c4SAndroid Build Coastguard Worker currentPriority = 128 - pVoice->nextVelocity;
3095*f81fb7c4SAndroid Build Coastguard Worker
3096*f81fb7c4SAndroid Build Coastguard Worker /* include channel priority */
3097*f81fb7c4SAndroid Build Coastguard Worker currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
3098*f81fb7c4SAndroid Build Coastguard Worker }
3099*f81fb7c4SAndroid Build Coastguard Worker else
3100*f81fb7c4SAndroid Build Coastguard Worker {
3101*f81fb7c4SAndroid Build Coastguard Worker /* include age */
3102*f81fb7c4SAndroid Build Coastguard Worker currentPriority = (EAS_I32) pVoice->age << NOTE_AGE_STEAL_WEIGHT;
3103*f81fb7c4SAndroid Build Coastguard Worker
3104*f81fb7c4SAndroid Build Coastguard Worker /* include note gain -higher gain is lower steal value */
3105*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{704} use shift for performance */
3106*f81fb7c4SAndroid Build Coastguard Worker currentPriority += ((32768 >> (12 - NOTE_GAIN_STEAL_WEIGHT)) + 256) -
3107*f81fb7c4SAndroid Build Coastguard Worker ((EAS_I32) pVoice->gain >> (12 - NOTE_GAIN_STEAL_WEIGHT));
3108*f81fb7c4SAndroid Build Coastguard Worker
3109*f81fb7c4SAndroid Build Coastguard Worker /* include channel priority */
3110*f81fb7c4SAndroid Build Coastguard Worker currentPriority += pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool << CHANNEL_PRIORITY_STEAL_WEIGHT;
3111*f81fb7c4SAndroid Build Coastguard Worker }
3112*f81fb7c4SAndroid Build Coastguard Worker
3113*f81fb7c4SAndroid Build Coastguard Worker /* is this the best choice so far? */
3114*f81fb7c4SAndroid Build Coastguard Worker if (currentPriority > bestPriority)
3115*f81fb7c4SAndroid Build Coastguard Worker {
3116*f81fb7c4SAndroid Build Coastguard Worker bestPriority = currentPriority;
3117*f81fb7c4SAndroid Build Coastguard Worker bestCandidate = i;
3118*f81fb7c4SAndroid Build Coastguard Worker }
3119*f81fb7c4SAndroid Build Coastguard Worker }
3120*f81fb7c4SAndroid Build Coastguard Worker
3121*f81fb7c4SAndroid Build Coastguard Worker /* shutdown best candidate */
3122*f81fb7c4SAndroid Build Coastguard Worker if (bestCandidate < 0)
3123*f81fb7c4SAndroid Build Coastguard Worker {
3124*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "VMSetPolyphony: Unable to reduce polyphony\n"); */ }
3125*f81fb7c4SAndroid Build Coastguard Worker break;
3126*f81fb7c4SAndroid Build Coastguard Worker }
3127*f81fb7c4SAndroid Build Coastguard Worker
3128*f81fb7c4SAndroid Build Coastguard Worker /* shut down this voice */
3129*f81fb7c4SAndroid Build Coastguard Worker VMMuteVoice(pVoiceMgr, bestCandidate);
3130*f81fb7c4SAndroid Build Coastguard Worker activeVoices--;
3131*f81fb7c4SAndroid Build Coastguard Worker }
3132*f81fb7c4SAndroid Build Coastguard Worker
3133*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3134*f81fb7c4SAndroid Build Coastguard Worker }
3135*f81fb7c4SAndroid Build Coastguard Worker
3136*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3137*f81fb7c4SAndroid Build Coastguard Worker * VMSetPriority()
3138*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3139*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3140*f81fb7c4SAndroid Build Coastguard Worker * Set the virtual synth priority
3141*f81fb7c4SAndroid Build Coastguard Worker *
3142*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3143*f81fb7c4SAndroid Build Coastguard Worker * pVoiceMgr pointer to synthesizer data
3144*f81fb7c4SAndroid Build Coastguard Worker * priority new priority
3145*f81fb7c4SAndroid Build Coastguard Worker * pSynth pointer to virtual synth
3146*f81fb7c4SAndroid Build Coastguard Worker *
3147*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3148*f81fb7c4SAndroid Build Coastguard Worker * Returns error code
3149*f81fb7c4SAndroid Build Coastguard Worker *
3150*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3151*f81fb7c4SAndroid Build Coastguard Worker *
3152*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3153*f81fb7c4SAndroid Build Coastguard Worker */
3154*f81fb7c4SAndroid Build Coastguard Worker /*lint -esym(715, pVoiceMgr) reserved for future use */
VMSetPriority(S_VOICE_MGR * pVoiceMgr,S_SYNTH * pSynth,EAS_I32 priority)3155*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMSetPriority (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_I32 priority)
3156*f81fb7c4SAndroid Build Coastguard Worker {
3157*f81fb7c4SAndroid Build Coastguard Worker pSynth->priority = (EAS_U8) priority ;
3158*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3159*f81fb7c4SAndroid Build Coastguard Worker }
3160*f81fb7c4SAndroid Build Coastguard Worker
3161*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3162*f81fb7c4SAndroid Build Coastguard Worker * VMSetVolume()
3163*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3164*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3165*f81fb7c4SAndroid Build Coastguard Worker * Set the master volume for this synthesizer for this sequence.
3166*f81fb7c4SAndroid Build Coastguard Worker *
3167*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3168*f81fb7c4SAndroid Build Coastguard Worker * nSynthVolume - the desired master volume
3169*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3170*f81fb7c4SAndroid Build Coastguard Worker *
3171*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3172*f81fb7c4SAndroid Build Coastguard Worker *
3173*f81fb7c4SAndroid Build Coastguard Worker *
3174*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3175*f81fb7c4SAndroid Build Coastguard Worker * overrides any previously set master volume from sysex
3176*f81fb7c4SAndroid Build Coastguard Worker *
3177*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3178*f81fb7c4SAndroid Build Coastguard Worker */
VMSetVolume(S_SYNTH * pSynth,EAS_U16 masterVolume)3179*f81fb7c4SAndroid Build Coastguard Worker void VMSetVolume (S_SYNTH *pSynth, EAS_U16 masterVolume)
3180*f81fb7c4SAndroid Build Coastguard Worker {
3181*f81fb7c4SAndroid Build Coastguard Worker pSynth->masterVolume = masterVolume;
3182*f81fb7c4SAndroid Build Coastguard Worker pSynth->synthFlags |= SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS;
3183*f81fb7c4SAndroid Build Coastguard Worker }
3184*f81fb7c4SAndroid Build Coastguard Worker
3185*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3186*f81fb7c4SAndroid Build Coastguard Worker * VMSetPitchBendRange()
3187*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3188*f81fb7c4SAndroid Build Coastguard Worker * Set the pitch bend range for the given channel.
3189*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3190*f81fb7c4SAndroid Build Coastguard Worker */
VMSetPitchBendRange(S_SYNTH * pSynth,EAS_INT channel,EAS_I16 pitchBendRange)3191*f81fb7c4SAndroid Build Coastguard Worker void VMSetPitchBendRange (S_SYNTH *pSynth, EAS_INT channel, EAS_I16 pitchBendRange)
3192*f81fb7c4SAndroid Build Coastguard Worker {
3193*f81fb7c4SAndroid Build Coastguard Worker pSynth->channels[channel].pitchBendSensitivity = pitchBendRange;
3194*f81fb7c4SAndroid Build Coastguard Worker }
3195*f81fb7c4SAndroid Build Coastguard Worker
3196*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3197*f81fb7c4SAndroid Build Coastguard Worker * VMValidateEASLib()
3198*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3199*f81fb7c4SAndroid Build Coastguard Worker * Validates an EAS library
3200*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3201*f81fb7c4SAndroid Build Coastguard Worker */
VMValidateEASLib(EAS_SNDLIB_HANDLE pEAS)3202*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMValidateEASLib (EAS_SNDLIB_HANDLE pEAS)
3203*f81fb7c4SAndroid Build Coastguard Worker {
3204*f81fb7c4SAndroid Build Coastguard Worker /* validate the sound library */
3205*f81fb7c4SAndroid Build Coastguard Worker if (pEAS)
3206*f81fb7c4SAndroid Build Coastguard Worker {
3207*f81fb7c4SAndroid Build Coastguard Worker if (pEAS->identifier != _EAS_LIBRARY_VERSION)
3208*f81fb7c4SAndroid Build Coastguard Worker {
3209*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sound library mismatch in sound library: Read 0x%08x, expected 0x%08x\n",
3210*f81fb7c4SAndroid Build Coastguard Worker pEAS->identifier, _EAS_LIBRARY_VERSION); */ }
3211*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_SOUND_LIBRARY;
3212*f81fb7c4SAndroid Build Coastguard Worker }
3213*f81fb7c4SAndroid Build Coastguard Worker
3214*f81fb7c4SAndroid Build Coastguard Worker /* check sample rate */
3215*f81fb7c4SAndroid Build Coastguard Worker if ((pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK) != _OUTPUT_SAMPLE_RATE)
3216*f81fb7c4SAndroid Build Coastguard Worker {
3217*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Sample rate mismatch in sound library: Read %lu, expected %lu\n",
3218*f81fb7c4SAndroid Build Coastguard Worker pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
3219*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_SOUND_LIBRARY;
3220*f81fb7c4SAndroid Build Coastguard Worker }
3221*f81fb7c4SAndroid Build Coastguard Worker
3222*f81fb7c4SAndroid Build Coastguard Worker #ifdef _WT_SYNTH
3223*f81fb7c4SAndroid Build Coastguard Worker /* check sample bit depth */
3224*f81fb7c4SAndroid Build Coastguard Worker #ifdef _8_BIT_SAMPLES
3225*f81fb7c4SAndroid Build Coastguard Worker if (pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES)
3226*f81fb7c4SAndroid Build Coastguard Worker {
3227*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 8-bit samples and found 16-bit\n",
3228*f81fb7c4SAndroid Build Coastguard Worker pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
3229*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_SOUND_LIBRARY;
3230*f81fb7c4SAndroid Build Coastguard Worker }
3231*f81fb7c4SAndroid Build Coastguard Worker #endif
3232*f81fb7c4SAndroid Build Coastguard Worker #ifdef _16_BIT_SAMPLES
3233*f81fb7c4SAndroid Build Coastguard Worker if ((pEAS->libAttr & LIB_FORMAT_16_BIT_SAMPLES) == 0)
3234*f81fb7c4SAndroid Build Coastguard Worker {
3235*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMValidateEASLib: Expected 16-bit samples and found 8-bit\n",
3236*f81fb7c4SAndroid Build Coastguard Worker pEAS->libAttr & LIBFORMAT_SAMPLE_RATE_MASK, _OUTPUT_SAMPLE_RATE); */ }
3237*f81fb7c4SAndroid Build Coastguard Worker return EAS_ERROR_SOUND_LIBRARY;
3238*f81fb7c4SAndroid Build Coastguard Worker }
3239*f81fb7c4SAndroid Build Coastguard Worker #endif
3240*f81fb7c4SAndroid Build Coastguard Worker #endif
3241*f81fb7c4SAndroid Build Coastguard Worker }
3242*f81fb7c4SAndroid Build Coastguard Worker
3243*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3244*f81fb7c4SAndroid Build Coastguard Worker }
3245*f81fb7c4SAndroid Build Coastguard Worker
3246*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3247*f81fb7c4SAndroid Build Coastguard Worker * VMSetEASLib()
3248*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3249*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3250*f81fb7c4SAndroid Build Coastguard Worker * Sets the EAS library to be used by the synthesizer
3251*f81fb7c4SAndroid Build Coastguard Worker *
3252*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3253*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3254*f81fb7c4SAndroid Build Coastguard Worker *
3255*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3256*f81fb7c4SAndroid Build Coastguard Worker *
3257*f81fb7c4SAndroid Build Coastguard Worker *
3258*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3259*f81fb7c4SAndroid Build Coastguard Worker *
3260*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3261*f81fb7c4SAndroid Build Coastguard Worker */
VMSetEASLib(S_SYNTH * pSynth,EAS_SNDLIB_HANDLE pEAS)3262*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMSetEASLib (S_SYNTH *pSynth, EAS_SNDLIB_HANDLE pEAS)
3263*f81fb7c4SAndroid Build Coastguard Worker {
3264*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT result;
3265*f81fb7c4SAndroid Build Coastguard Worker
3266*f81fb7c4SAndroid Build Coastguard Worker result = VMValidateEASLib(pEAS);
3267*f81fb7c4SAndroid Build Coastguard Worker if (result != EAS_SUCCESS)
3268*f81fb7c4SAndroid Build Coastguard Worker return result;
3269*f81fb7c4SAndroid Build Coastguard Worker
3270*f81fb7c4SAndroid Build Coastguard Worker pSynth->pEAS = pEAS;
3271*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3272*f81fb7c4SAndroid Build Coastguard Worker }
3273*f81fb7c4SAndroid Build Coastguard Worker
3274*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
3275*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3276*f81fb7c4SAndroid Build Coastguard Worker * VMSetDLSLib()
3277*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3278*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3279*f81fb7c4SAndroid Build Coastguard Worker * Sets the DLS library to be used by the synthesizer
3280*f81fb7c4SAndroid Build Coastguard Worker *
3281*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3282*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3283*f81fb7c4SAndroid Build Coastguard Worker *
3284*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3285*f81fb7c4SAndroid Build Coastguard Worker *
3286*f81fb7c4SAndroid Build Coastguard Worker *
3287*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3288*f81fb7c4SAndroid Build Coastguard Worker *
3289*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3290*f81fb7c4SAndroid Build Coastguard Worker */
VMSetDLSLib(S_SYNTH * pSynth,EAS_DLSLIB_HANDLE pDLS)3291*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMSetDLSLib (S_SYNTH *pSynth, EAS_DLSLIB_HANDLE pDLS)
3292*f81fb7c4SAndroid Build Coastguard Worker {
3293*f81fb7c4SAndroid Build Coastguard Worker pSynth->pDLS = pDLS;
3294*f81fb7c4SAndroid Build Coastguard Worker return EAS_SUCCESS;
3295*f81fb7c4SAndroid Build Coastguard Worker }
3296*f81fb7c4SAndroid Build Coastguard Worker #endif
3297*f81fb7c4SAndroid Build Coastguard Worker
3298*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3299*f81fb7c4SAndroid Build Coastguard Worker * VMSetTranposition()
3300*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3301*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3302*f81fb7c4SAndroid Build Coastguard Worker * Sets the global key transposition used by the synthesizer.
3303*f81fb7c4SAndroid Build Coastguard Worker * Transposes all melodic instruments up or down by the specified
3304*f81fb7c4SAndroid Build Coastguard Worker * amount. Range is limited to +/-12 semitones.
3305*f81fb7c4SAndroid Build Coastguard Worker *
3306*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3307*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3308*f81fb7c4SAndroid Build Coastguard Worker *
3309*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3310*f81fb7c4SAndroid Build Coastguard Worker *
3311*f81fb7c4SAndroid Build Coastguard Worker *
3312*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3313*f81fb7c4SAndroid Build Coastguard Worker *
3314*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3315*f81fb7c4SAndroid Build Coastguard Worker */
VMSetTranposition(S_SYNTH * pSynth,EAS_I32 transposition)3316*f81fb7c4SAndroid Build Coastguard Worker void VMSetTranposition (S_SYNTH *pSynth, EAS_I32 transposition)
3317*f81fb7c4SAndroid Build Coastguard Worker {
3318*f81fb7c4SAndroid Build Coastguard Worker pSynth->globalTranspose = (EAS_I8) transposition;
3319*f81fb7c4SAndroid Build Coastguard Worker }
3320*f81fb7c4SAndroid Build Coastguard Worker
3321*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3322*f81fb7c4SAndroid Build Coastguard Worker * VMMIDIShutdown()
3323*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3324*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3325*f81fb7c4SAndroid Build Coastguard Worker * Clean up any Synth related system issues.
3326*f81fb7c4SAndroid Build Coastguard Worker *
3327*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3328*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3329*f81fb7c4SAndroid Build Coastguard Worker *
3330*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3331*f81fb7c4SAndroid Build Coastguard Worker * None
3332*f81fb7c4SAndroid Build Coastguard Worker *
3333*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3334*f81fb7c4SAndroid Build Coastguard Worker *
3335*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3336*f81fb7c4SAndroid Build Coastguard Worker */
VMMIDIShutdown(S_EAS_DATA * pEASData,S_SYNTH * pSynth)3337*f81fb7c4SAndroid Build Coastguard Worker void VMMIDIShutdown (S_EAS_DATA *pEASData, S_SYNTH *pSynth)
3338*f81fb7c4SAndroid Build Coastguard Worker {
3339*f81fb7c4SAndroid Build Coastguard Worker EAS_INT vSynthNum;
3340*f81fb7c4SAndroid Build Coastguard Worker
3341*f81fb7c4SAndroid Build Coastguard Worker /* decrement reference count, free if all references are gone */
3342*f81fb7c4SAndroid Build Coastguard Worker if (--pSynth->refCount > 0)
3343*f81fb7c4SAndroid Build Coastguard Worker return;
3344*f81fb7c4SAndroid Build Coastguard Worker
3345*f81fb7c4SAndroid Build Coastguard Worker vSynthNum = pSynth->vSynthNum;
3346*f81fb7c4SAndroid Build Coastguard Worker
3347*f81fb7c4SAndroid Build Coastguard Worker /* cleanup DLS load */
3348*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
3349*f81fb7c4SAndroid Build Coastguard Worker /*lint -e{550} result used only in debugging code */
3350*f81fb7c4SAndroid Build Coastguard Worker if (pSynth->pDLS != NULL)
3351*f81fb7c4SAndroid Build Coastguard Worker {
3352*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT result;
3353*f81fb7c4SAndroid Build Coastguard Worker if ((result = DLSCleanup(pEASData->hwInstData, pSynth->pDLS)) != EAS_SUCCESS)
3354*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMMIDIShutdown: Error %ld cleaning up DLS collection\n", result); */ }
3355*f81fb7c4SAndroid Build Coastguard Worker pSynth->pDLS = NULL;
3356*f81fb7c4SAndroid Build Coastguard Worker }
3357*f81fb7c4SAndroid Build Coastguard Worker #endif
3358*f81fb7c4SAndroid Build Coastguard Worker
3359*f81fb7c4SAndroid Build Coastguard Worker VMReset(pEASData->pVoiceMgr, pSynth, EAS_TRUE);
3360*f81fb7c4SAndroid Build Coastguard Worker
3361*f81fb7c4SAndroid Build Coastguard Worker /* check Configuration Module for static memory allocation */
3362*f81fb7c4SAndroid Build Coastguard Worker if (!pEASData->staticMemoryModel)
3363*f81fb7c4SAndroid Build Coastguard Worker EAS_HWFree(pEASData->hwInstData, pSynth);
3364*f81fb7c4SAndroid Build Coastguard Worker
3365*f81fb7c4SAndroid Build Coastguard Worker /* clear pointer to MIDI state */
3366*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr->pSynth[vSynthNum] = NULL;
3367*f81fb7c4SAndroid Build Coastguard Worker }
3368*f81fb7c4SAndroid Build Coastguard Worker
3369*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3370*f81fb7c4SAndroid Build Coastguard Worker * VMShutdown()
3371*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3372*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3373*f81fb7c4SAndroid Build Coastguard Worker * Clean up any Synth related system issues.
3374*f81fb7c4SAndroid Build Coastguard Worker *
3375*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3376*f81fb7c4SAndroid Build Coastguard Worker * psEASData - pointer to overall EAS data structure
3377*f81fb7c4SAndroid Build Coastguard Worker *
3378*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3379*f81fb7c4SAndroid Build Coastguard Worker * None
3380*f81fb7c4SAndroid Build Coastguard Worker *
3381*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3382*f81fb7c4SAndroid Build Coastguard Worker *
3383*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3384*f81fb7c4SAndroid Build Coastguard Worker */
VMShutdown(S_EAS_DATA * pEASData)3385*f81fb7c4SAndroid Build Coastguard Worker void VMShutdown (S_EAS_DATA *pEASData)
3386*f81fb7c4SAndroid Build Coastguard Worker {
3387*f81fb7c4SAndroid Build Coastguard Worker
3388*f81fb7c4SAndroid Build Coastguard Worker /* don't free a NULL pointer */
3389*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr == NULL)
3390*f81fb7c4SAndroid Build Coastguard Worker return;
3391*f81fb7c4SAndroid Build Coastguard Worker
3392*f81fb7c4SAndroid Build Coastguard Worker #ifdef DLS_SYNTHESIZER
3393*f81fb7c4SAndroid Build Coastguard Worker /* if we have a global DLS collection, clean it up */
3394*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pGlobalDLS)
3395*f81fb7c4SAndroid Build Coastguard Worker {
3396*f81fb7c4SAndroid Build Coastguard Worker DLSCleanup(pEASData->hwInstData, pEASData->pVoiceMgr->pGlobalDLS);
3397*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr->pGlobalDLS = NULL;
3398*f81fb7c4SAndroid Build Coastguard Worker }
3399*f81fb7c4SAndroid Build Coastguard Worker #endif
3400*f81fb7c4SAndroid Build Coastguard Worker
3401*f81fb7c4SAndroid Build Coastguard Worker /* check Configuration Module for static memory allocation */
3402*f81fb7c4SAndroid Build Coastguard Worker if (!pEASData->staticMemoryModel)
3403*f81fb7c4SAndroid Build Coastguard Worker EAS_HWFree(pEASData->hwInstData, pEASData->pVoiceMgr);
3404*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr = NULL;
3405*f81fb7c4SAndroid Build Coastguard Worker }
3406*f81fb7c4SAndroid Build Coastguard Worker
3407*f81fb7c4SAndroid Build Coastguard Worker #ifdef EXTERNAL_AUDIO
3408*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3409*f81fb7c4SAndroid Build Coastguard Worker * EAS_RegExtAudioCallback()
3410*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3411*f81fb7c4SAndroid Build Coastguard Worker * Register a callback for external audio processing
3412*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3413*f81fb7c4SAndroid Build Coastguard Worker */
VMRegExtAudioCallback(S_SYNTH * pSynth,EAS_VOID_PTR pInstData,EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,EAS_EXT_EVENT_FUNC cbEventFunc)3414*f81fb7c4SAndroid Build Coastguard Worker void VMRegExtAudioCallback (S_SYNTH *pSynth, EAS_VOID_PTR pInstData, EAS_EXT_PRG_CHG_FUNC cbProgChgFunc, EAS_EXT_EVENT_FUNC cbEventFunc)
3415*f81fb7c4SAndroid Build Coastguard Worker {
3416*f81fb7c4SAndroid Build Coastguard Worker pSynth->pExtAudioInstData = pInstData;
3417*f81fb7c4SAndroid Build Coastguard Worker pSynth->cbProgChgFunc = cbProgChgFunc;
3418*f81fb7c4SAndroid Build Coastguard Worker pSynth->cbEventFunc = cbEventFunc;
3419*f81fb7c4SAndroid Build Coastguard Worker }
3420*f81fb7c4SAndroid Build Coastguard Worker
3421*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3422*f81fb7c4SAndroid Build Coastguard Worker * VMGetMIDIControllers()
3423*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3424*f81fb7c4SAndroid Build Coastguard Worker * Returns the MIDI controller values on the specified channel
3425*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3426*f81fb7c4SAndroid Build Coastguard Worker */
VMGetMIDIControllers(S_SYNTH * pSynth,EAS_U8 channel,S_MIDI_CONTROLLERS * pControl)3427*f81fb7c4SAndroid Build Coastguard Worker void VMGetMIDIControllers (S_SYNTH *pSynth, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
3428*f81fb7c4SAndroid Build Coastguard Worker {
3429*f81fb7c4SAndroid Build Coastguard Worker pControl->modWheel = pSynth->channels[channel].modWheel;
3430*f81fb7c4SAndroid Build Coastguard Worker pControl->volume = pSynth->channels[channel].volume;
3431*f81fb7c4SAndroid Build Coastguard Worker pControl->pan = pSynth->channels[channel].pan;
3432*f81fb7c4SAndroid Build Coastguard Worker pControl->expression = pSynth->channels[channel].expression;
3433*f81fb7c4SAndroid Build Coastguard Worker pControl->channelPressure = pSynth->channels[channel].channelPressure;
3434*f81fb7c4SAndroid Build Coastguard Worker
3435*f81fb7c4SAndroid Build Coastguard Worker #ifdef _REVERB
3436*f81fb7c4SAndroid Build Coastguard Worker pControl->reverbSend = pSynth->channels[channel].reverbSend;
3437*f81fb7c4SAndroid Build Coastguard Worker #endif
3438*f81fb7c4SAndroid Build Coastguard Worker
3439*f81fb7c4SAndroid Build Coastguard Worker #ifdef _CHORUSE
3440*f81fb7c4SAndroid Build Coastguard Worker pControl->chorusSend = pSynth->channels[channel].chorusSend;
3441*f81fb7c4SAndroid Build Coastguard Worker #endif
3442*f81fb7c4SAndroid Build Coastguard Worker }
3443*f81fb7c4SAndroid Build Coastguard Worker #endif
3444*f81fb7c4SAndroid Build Coastguard Worker
3445*f81fb7c4SAndroid Build Coastguard Worker #ifdef _SPLIT_ARCHITECTURE
3446*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3447*f81fb7c4SAndroid Build Coastguard Worker * VMStartFrame()
3448*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3449*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3450*f81fb7c4SAndroid Build Coastguard Worker * Starts an audio frame
3451*f81fb7c4SAndroid Build Coastguard Worker *
3452*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3453*f81fb7c4SAndroid Build Coastguard Worker *
3454*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3455*f81fb7c4SAndroid Build Coastguard Worker * Returns true if EAS_MixEnginePrep should be called (onboard mixing)
3456*f81fb7c4SAndroid Build Coastguard Worker *
3457*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3458*f81fb7c4SAndroid Build Coastguard Worker *
3459*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3460*f81fb7c4SAndroid Build Coastguard Worker */
VMStartFrame(S_EAS_DATA * pEASData)3461*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL VMStartFrame (S_EAS_DATA *pEASData)
3462*f81fb7c4SAndroid Build Coastguard Worker {
3463*f81fb7c4SAndroid Build Coastguard Worker
3464*f81fb7c4SAndroid Build Coastguard Worker /* init counter for voices starts in split architecture */
3465*f81fb7c4SAndroid Build Coastguard Worker #ifdef MAX_VOICE_STARTS
3466*f81fb7c4SAndroid Build Coastguard Worker pVoiceMgr->numVoiceStarts = 0;
3467*f81fb7c4SAndroid Build Coastguard Worker #endif
3468*f81fb7c4SAndroid Build Coastguard Worker
3469*f81fb7c4SAndroid Build Coastguard Worker return pFrameInterface->pfStartFrame(pEASData->pVoiceMgr->pFrameBuffer);
3470*f81fb7c4SAndroid Build Coastguard Worker }
3471*f81fb7c4SAndroid Build Coastguard Worker
3472*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3473*f81fb7c4SAndroid Build Coastguard Worker * VMEndFrame()
3474*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3475*f81fb7c4SAndroid Build Coastguard Worker * Purpose:
3476*f81fb7c4SAndroid Build Coastguard Worker * Stops an audio frame
3477*f81fb7c4SAndroid Build Coastguard Worker *
3478*f81fb7c4SAndroid Build Coastguard Worker * Inputs:
3479*f81fb7c4SAndroid Build Coastguard Worker *
3480*f81fb7c4SAndroid Build Coastguard Worker * Outputs:
3481*f81fb7c4SAndroid Build Coastguard Worker * Returns true if EAS_MixEnginePost should be called (onboard mixing)
3482*f81fb7c4SAndroid Build Coastguard Worker *
3483*f81fb7c4SAndroid Build Coastguard Worker * Side Effects:
3484*f81fb7c4SAndroid Build Coastguard Worker *
3485*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3486*f81fb7c4SAndroid Build Coastguard Worker */
VMEndFrame(S_EAS_DATA * pEASData)3487*f81fb7c4SAndroid Build Coastguard Worker EAS_BOOL VMEndFrame (S_EAS_DATA *pEASData)
3488*f81fb7c4SAndroid Build Coastguard Worker {
3489*f81fb7c4SAndroid Build Coastguard Worker
3490*f81fb7c4SAndroid Build Coastguard Worker return pFrameInterface->pfEndFrame(pEASData->pVoiceMgr->pFrameBuffer, pEASData->pMixBuffer, pEASData->masterGain);
3491*f81fb7c4SAndroid Build Coastguard Worker }
3492*f81fb7c4SAndroid Build Coastguard Worker #endif
3493*f81fb7c4SAndroid Build Coastguard Worker
3494*f81fb7c4SAndroid Build Coastguard Worker #ifdef TEST_HARNESS
3495*f81fb7c4SAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
3496*f81fb7c4SAndroid Build Coastguard Worker * SanityCheck()
3497*f81fb7c4SAndroid Build Coastguard Worker *----------------------------------------------------------------------------
3498*f81fb7c4SAndroid Build Coastguard Worker */
VMSanityCheck(EAS_DATA_HANDLE pEASData)3499*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT VMSanityCheck (EAS_DATA_HANDLE pEASData)
3500*f81fb7c4SAndroid Build Coastguard Worker {
3501*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH_VOICE *pVoice;
3502*f81fb7c4SAndroid Build Coastguard Worker S_SYNTH *pSynth;
3503*f81fb7c4SAndroid Build Coastguard Worker EAS_INT i;
3504*f81fb7c4SAndroid Build Coastguard Worker EAS_INT j;
3505*f81fb7c4SAndroid Build Coastguard Worker EAS_INT freeVoices;
3506*f81fb7c4SAndroid Build Coastguard Worker EAS_INT activeVoices;
3507*f81fb7c4SAndroid Build Coastguard Worker EAS_INT playingVoices;
3508*f81fb7c4SAndroid Build Coastguard Worker EAS_INT stolenVoices;
3509*f81fb7c4SAndroid Build Coastguard Worker EAS_INT releasingVoices;
3510*f81fb7c4SAndroid Build Coastguard Worker EAS_INT mutingVoices;
3511*f81fb7c4SAndroid Build Coastguard Worker EAS_INT poolCount[MAX_VIRTUAL_SYNTHESIZERS][NUM_SYNTH_CHANNELS];
3512*f81fb7c4SAndroid Build Coastguard Worker EAS_INT vSynthNum;
3513*f81fb7c4SAndroid Build Coastguard Worker EAS_RESULT result = EAS_SUCCESS;
3514*f81fb7c4SAndroid Build Coastguard Worker
3515*f81fb7c4SAndroid Build Coastguard Worker /* initialize counts */
3516*f81fb7c4SAndroid Build Coastguard Worker EAS_HWMemSet(poolCount, 0, sizeof(poolCount));
3517*f81fb7c4SAndroid Build Coastguard Worker freeVoices = activeVoices = playingVoices = stolenVoices = releasingVoices = mutingVoices = 0;
3518*f81fb7c4SAndroid Build Coastguard Worker
3519*f81fb7c4SAndroid Build Coastguard Worker /* iterate through all voices */
3520*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_SYNTH_VOICES; i++)
3521*f81fb7c4SAndroid Build Coastguard Worker {
3522*f81fb7c4SAndroid Build Coastguard Worker pVoice = &pEASData->pVoiceMgr->voices[i];
3523*f81fb7c4SAndroid Build Coastguard Worker if (pVoice->voiceState != eVoiceStateFree)
3524*f81fb7c4SAndroid Build Coastguard Worker {
3525*f81fb7c4SAndroid Build Coastguard Worker vSynthNum = GET_VSYNTH(pVoice->channel);
3526*f81fb7c4SAndroid Build Coastguard Worker if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
3527*f81fb7c4SAndroid Build Coastguard Worker {
3528*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
3529*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3530*f81fb7c4SAndroid Build Coastguard Worker continue;
3531*f81fb7c4SAndroid Build Coastguard Worker }
3532*f81fb7c4SAndroid Build Coastguard Worker pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
3533*f81fb7c4SAndroid Build Coastguard Worker
3534*f81fb7c4SAndroid Build Coastguard Worker switch (pVoice->voiceState)
3535*f81fb7c4SAndroid Build Coastguard Worker {
3536*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateMuting:
3537*f81fb7c4SAndroid Build Coastguard Worker activeVoices++;
3538*f81fb7c4SAndroid Build Coastguard Worker mutingVoices++;
3539*f81fb7c4SAndroid Build Coastguard Worker break;
3540*f81fb7c4SAndroid Build Coastguard Worker
3541*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateStolen:
3542*f81fb7c4SAndroid Build Coastguard Worker vSynthNum = GET_VSYNTH(pVoice->nextChannel);
3543*f81fb7c4SAndroid Build Coastguard Worker if (vSynthNum >= MAX_VIRTUAL_SYNTHESIZERS)
3544*f81fb7c4SAndroid Build Coastguard Worker {
3545*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Voice %d has invalid virtual synth number %d\n", i, vSynthNum); */ }
3546*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3547*f81fb7c4SAndroid Build Coastguard Worker continue;
3548*f81fb7c4SAndroid Build Coastguard Worker }
3549*f81fb7c4SAndroid Build Coastguard Worker pSynth = pEASData->pVoiceMgr->pSynth[vSynthNum];
3550*f81fb7c4SAndroid Build Coastguard Worker activeVoices++;
3551*f81fb7c4SAndroid Build Coastguard Worker stolenVoices++;
3552*f81fb7c4SAndroid Build Coastguard Worker poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->nextChannel)].pool]++;
3553*f81fb7c4SAndroid Build Coastguard Worker break;
3554*f81fb7c4SAndroid Build Coastguard Worker
3555*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateStart:
3556*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStatePlay:
3557*f81fb7c4SAndroid Build Coastguard Worker activeVoices++;
3558*f81fb7c4SAndroid Build Coastguard Worker playingVoices++;
3559*f81fb7c4SAndroid Build Coastguard Worker poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
3560*f81fb7c4SAndroid Build Coastguard Worker break;
3561*f81fb7c4SAndroid Build Coastguard Worker
3562*f81fb7c4SAndroid Build Coastguard Worker case eVoiceStateRelease:
3563*f81fb7c4SAndroid Build Coastguard Worker activeVoices++;
3564*f81fb7c4SAndroid Build Coastguard Worker releasingVoices++;
3565*f81fb7c4SAndroid Build Coastguard Worker poolCount[vSynthNum][pSynth->channels[GET_CHANNEL(pVoice->channel)].pool]++;
3566*f81fb7c4SAndroid Build Coastguard Worker break;
3567*f81fb7c4SAndroid Build Coastguard Worker
3568*f81fb7c4SAndroid Build Coastguard Worker default:
3569*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck : voice %d in invalid state\n", i); */ }
3570*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3571*f81fb7c4SAndroid Build Coastguard Worker break;
3572*f81fb7c4SAndroid Build Coastguard Worker }
3573*f81fb7c4SAndroid Build Coastguard Worker }
3574*f81fb7c4SAndroid Build Coastguard Worker
3575*f81fb7c4SAndroid Build Coastguard Worker /* count free voices */
3576*f81fb7c4SAndroid Build Coastguard Worker else
3577*f81fb7c4SAndroid Build Coastguard Worker freeVoices++;
3578*f81fb7c4SAndroid Build Coastguard Worker }
3579*f81fb7c4SAndroid Build Coastguard Worker
3580*f81fb7c4SAndroid Build Coastguard Worker /* dump state info */
3581*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d free\n", freeVoices); */ }
3582*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d active\n", activeVoices); */ }
3583*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d playing\n", playingVoices); */ }
3584*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d releasing\n", releasingVoices); */ }
3585*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d muting\n", mutingVoices); */ }
3586*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "%d stolen\n", stolenVoices); */ }
3587*f81fb7c4SAndroid Build Coastguard Worker
3588*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->activeVoices != activeVoices)
3589*f81fb7c4SAndroid Build Coastguard Worker {
3590*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Active voice mismatch was %d should be %d\n",
3591*f81fb7c4SAndroid Build Coastguard Worker pEASData->pVoiceMgr->activeVoices, activeVoices); */ }
3592*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3593*f81fb7c4SAndroid Build Coastguard Worker }
3594*f81fb7c4SAndroid Build Coastguard Worker
3595*f81fb7c4SAndroid Build Coastguard Worker /* check virtual synth status */
3596*f81fb7c4SAndroid Build Coastguard Worker for (i = 0; i < MAX_VIRTUAL_SYNTHESIZERS; i++)
3597*f81fb7c4SAndroid Build Coastguard Worker {
3598*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pSynth[i] == NULL)
3599*f81fb7c4SAndroid Build Coastguard Worker continue;
3600*f81fb7c4SAndroid Build Coastguard Worker
3601*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Synth %d numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
3602*f81fb7c4SAndroid Build Coastguard Worker if (pEASData->pVoiceMgr->pSynth[i]->numActiveVoices > MAX_SYNTH_VOICES)
3603*f81fb7c4SAndroid Build Coastguard Worker {
3604*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMSanityCheck: Synth %d illegal count for numActiveVoices: %d\n", i, pEASData->pVoiceMgr->pSynth[i]->numActiveVoices); */ }
3605*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3606*f81fb7c4SAndroid Build Coastguard Worker }
3607*f81fb7c4SAndroid Build Coastguard Worker for (j = 0; j < NUM_SYNTH_CHANNELS; j++)
3608*f81fb7c4SAndroid Build Coastguard Worker {
3609*f81fb7c4SAndroid Build Coastguard Worker if (poolCount[i][j] != pEASData->pVoiceMgr->pSynth[i]->poolCount[j])
3610*f81fb7c4SAndroid Build Coastguard Worker {
3611*f81fb7c4SAndroid Build Coastguard Worker { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Pool count mismatch synth %d pool %d, was %d, should be %d\n",
3612*f81fb7c4SAndroid Build Coastguard Worker i, j, pEASData->pVoiceMgr->pSynth[i]->poolCount[j], poolCount[i][j]); */ }
3613*f81fb7c4SAndroid Build Coastguard Worker result = EAS_FAILURE;
3614*f81fb7c4SAndroid Build Coastguard Worker }
3615*f81fb7c4SAndroid Build Coastguard Worker }
3616*f81fb7c4SAndroid Build Coastguard Worker }
3617*f81fb7c4SAndroid Build Coastguard Worker
3618*f81fb7c4SAndroid Build Coastguard Worker return result;
3619*f81fb7c4SAndroid Build Coastguard Worker }
3620*f81fb7c4SAndroid Build Coastguard Worker #endif
3621*f81fb7c4SAndroid Build Coastguard Worker
3622*f81fb7c4SAndroid Build Coastguard Worker
3623