140 |
EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel); |
EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel); |
141 |
// first, get total amount of required voices (dependant on amount of layers) |
// first, get total amount of required voices (dependant on amount of layers) |
142 |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(itNoteOnEvent->Param.Note.Key); |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(itNoteOnEvent->Param.Note.Key); |
143 |
if (pRegion && !RegionSuspended(pRegion)) { |
if (!pRegion || RegionSuspended(pRegion)) |
144 |
int voicesRequired = pRegion->Layers; |
return; |
145 |
// now launch the required amount of voices |
const int voicesRequired = pRegion->Layers; |
146 |
for (int i = 0; i < voicesRequired; i++) |
if (voicesRequired <= 0) |
147 |
|
return; |
148 |
|
|
149 |
|
NoteIterator itNote = GetNotePool()->fromID(itNoteOnEvent->Param.Note.ID); |
150 |
|
if (!itNote) { |
151 |
|
dmsg(1,("gig::Engine: No Note object for triggering new voices!\n")); |
152 |
|
return; |
153 |
|
} |
154 |
|
|
155 |
|
// now launch the required amount of voices |
156 |
|
for (int i = 0; i < voicesRequired; i++) { |
157 |
|
VoiceIterator itNewVoice = |
158 |
LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts); |
LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts); |
159 |
|
if (!itNewVoice) continue; |
160 |
|
itNewVoice.moveToEndOf(itNote->pActiveVoices); |
161 |
} |
} |
162 |
} |
} |
163 |
|
|
169 |
MidiKey* pKey = &pChannel->pMIDIKeyInfo[itNoteOffEvent->Param.Note.Key]; |
MidiKey* pKey = &pChannel->pMIDIKeyInfo[itNoteOffEvent->Param.Note.Key]; |
170 |
// first, get total amount of required voices (dependant on amount of layers) |
// first, get total amount of required voices (dependant on amount of layers) |
171 |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(itNoteOffEvent->Param.Note.Key); |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(itNoteOffEvent->Param.Note.Key); |
172 |
if (pRegion) { |
if (!pRegion) |
173 |
int voicesRequired = pRegion->Layers; |
return; |
174 |
|
const int voicesRequired = pRegion->Layers; |
175 |
|
if (voicesRequired <= 0) |
176 |
|
return; |
177 |
|
|
178 |
|
NoteIterator itNote = GetNotePool()->fromID(itNoteOffEvent->Param.Note.ID); |
179 |
|
if (!itNote) { |
180 |
|
dmsg(1,("gig::Engine: No Note object for triggering new release voices!\n")); |
181 |
|
return; |
182 |
|
} |
183 |
|
|
184 |
// MIDI note-on velocity is used instead of note-off velocity |
// MIDI note-on velocity is used instead of note-off velocity |
185 |
itNoteOffEvent->Param.Note.Velocity = pKey->Velocity; |
itNoteOffEvent->Param.Note.Velocity = pKey->Velocity; |
186 |
|
|
187 |
// now launch the required amount of voices |
// now launch the required amount of voices |
188 |
for (int i = 0; i < voicesRequired; i++) |
for (int i = 0; i < voicesRequired; i++) { |
189 |
|
VoiceIterator itNewVoice = |
190 |
LaunchVoice(pChannel, itNoteOffEvent, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples |
LaunchVoice(pChannel, itNoteOffEvent, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples |
191 |
|
if (!itNewVoice) continue; |
192 |
|
itNewVoice.moveToEndOf(itNote->pActiveVoices); |
193 |
} |
} |
194 |
} |
} |
195 |
|
|
203 |
) { |
) { |
204 |
EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel); |
EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel); |
205 |
int MIDIKey = itNoteOnEvent->Param.Note.Key; |
int MIDIKey = itNoteOnEvent->Param.Note.Key; |
206 |
EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[MIDIKey]; |
//EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[MIDIKey]; |
207 |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(MIDIKey); |
::gig::Region* pRegion = pChannel->pInstrument->GetRegion(MIDIKey); |
208 |
|
|
209 |
// if nothing defined for this key |
// if nothing defined for this key |
335 |
// change has occured between note on and off) |
// change has occured between note on and off) |
336 |
if (ReleaseTriggerVoice && !(VoiceType & Voice::type_release_trigger)) return Pool<Voice>::Iterator(); |
if (ReleaseTriggerVoice && !(VoiceType & Voice::type_release_trigger)) return Pool<Voice>::Iterator(); |
337 |
|
|
338 |
|
NoteIterator itNote = GetNotePool()->fromID(itNoteOnEvent->Param.Note.ID); |
339 |
|
|
340 |
::gig::DimensionRegion* pDimRgn; |
::gig::DimensionRegion* pDimRgn; |
341 |
if (!itNoteOnEvent->Format.Gig.DimMask) { // normal case ... |
if (!itNote->Format.Gig.DimMask) { // normal case ... |
342 |
pDimRgn = pRegion->GetDimensionRegionByValue(DimValues); |
pDimRgn = pRegion->GetDimensionRegionByValue(DimValues); |
343 |
} else { // some dimension zones were overridden (i.e. by instrument script) ... |
} else { // some dimension zones were overridden (i.e. by instrument script) ... |
344 |
dmsg(3,("trigger with dim mask=%d val=%d\n", itNoteOnEvent->Format.Gig.DimMask, itNoteOnEvent->Format.Gig.DimBits)); |
dmsg(3,("trigger with dim mask=%d val=%d\n", itNote->Format.Gig.DimMask, itNote->Format.Gig.DimBits)); |
345 |
int index = pRegion->GetDimensionRegionIndexByValue(DimValues); |
int index = pRegion->GetDimensionRegionIndexByValue(DimValues); |
346 |
index &= ~itNoteOnEvent->Format.Gig.DimMask; |
index &= ~itNote->Format.Gig.DimMask; |
347 |
index |= itNoteOnEvent->Format.Gig.DimBits & itNoteOnEvent->Format.Gig.DimMask; |
index |= itNote->Format.Gig.DimBits & itNote->Format.Gig.DimMask; |
348 |
pDimRgn = pRegion->pDimensionRegions[index & 255]; |
pDimRgn = pRegion->pDimensionRegions[index & 255]; |
349 |
} |
} |
350 |
if (!pDimRgn) return Pool<Voice>::Iterator(); // error (could not resolve dimension region) |
if (!pDimRgn) return Pool<Voice>::Iterator(); // error (could not resolve dimension region) |
353 |
if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator(); |
if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator(); |
354 |
|
|
355 |
// allocate a new voice for the key |
// allocate a new voice for the key |
356 |
Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend(); |
Pool<Voice>::Iterator itNewVoice = GetVoicePool()->allocAppend(); |
357 |
|
|
358 |
int res = InitNewVoice ( |
int res = InitNewVoice ( |
359 |
pChannel, pDimRgn, itNoteOnEvent, VoiceType, iLayer, |
pChannel, pDimRgn, itNoteOnEvent, VoiceType, iLayer, |