@@ -44,6 +44,7 @@ Division::Division(Engine& engine, const String& name)
4444 , _swellFilterStateR{}
4545 , _stops{}
4646 , _activeVoices{}
47+ , _keysState{}
4748 , _triggerFlag{}
4849 , _volumeLevel{}
4950{
@@ -327,28 +328,10 @@ void Division::noteOn(int note, int midiChannel)
327328
328329 _triggerFlag = true ;
329330
330- for (const auto & stop : _stops) {
331- if (!stop.isEnabled ())
332- continue ;
333-
334- for (const auto & zone : stop.getZones ()) {
335- if (zone.isForKey (note)) {
336- for (auto * rw : zone.rankwaves ) {
337- auto state = rw->trigger (note);
331+ for (int stopIndex = 0 ; stopIndex < (int )_stops.size (); ++stopIndex)
332+ triggerVoicesForStop (stopIndex, note);
338333
339- // Rankwave may be in the middle of construction, in this case
340- // we don't trigger a voice.
341- if (state.isTriggered ()) {
342- state.gain = stop.getGain ();
343- state.chiffGain = stop.getChiffGain ();
344-
345- if (auto * voice = _engine.getVoicePool ().trigger (state))
346- _activeVoices.append (voice);
347- }
348- }
349- }
350- }
351- }
334+ _keysState.set (note);
352335
353336 // Forward to the linked divisions
354337 for (auto & link : _linkedDivisions) {
@@ -377,6 +360,8 @@ void Division::noteOff(int note, int midiChannel)
377360 voice = voice->next ();
378361 }
379362
363+ _keysState.reset (note);
364+
380365 // Forward to the linked divisions
381366 for (auto & link : _linkedDivisions) {
382367 if (link.enabled ) {
@@ -387,6 +372,8 @@ void Division::noteOff(int note, int midiChannel)
387372
388373void Division::allNotesOff ()
389374{
375+ _keysState.reset ();
376+
390377 auto * voice = _activeVoices.first ();
391378
392379 while (voice != nullptr ) {
@@ -400,6 +387,9 @@ bool Division::process(AudioBuffer<float>& targetBuffer, AudioBuffer<float>& voi
400387 jassert (targetBuffer.getNumSamples () == SUB_FRAME_LENGTH);
401388 jassert (voiceBuffer.getNumSamples () == SUB_FRAME_LENGTH);
402389
390+ releaseVoicesOfDisabledStops ();
391+ triggerVoicesOfEnabledStops ();
392+
403393 auto * voice = _activeVoices.first ();
404394
405395 if (voice == nullptr )
@@ -500,4 +490,90 @@ void Division::modulate(juce::AudioBuffer<float>& targetBuffer, const juce::Audi
500490#endif
501491}
502492
493+ void Division::releaseVoicesOfDisabledStops ()
494+ {
495+ auto * voice = _activeVoices.first ();
496+
497+ while (voice != nullptr ) {
498+ if (voice->isActive ()) {
499+ const int stopIndex = voice->stopIndex ();
500+
501+ if (isPositiveAndBelow (stopIndex, _stops.size ())) {
502+ const auto & stop = _stops[stopIndex];
503+
504+ if (!stop.isEnabled ())
505+ voice->release ();
506+ }
507+ }
508+
509+ voice = voice->next ();
510+ }
511+ }
512+
513+ void Division::triggerVoicesOfEnabledStops ()
514+ {
515+ for (int stopIndex = 0 ; stopIndex < _stops.size (); ++stopIndex) {
516+ auto & stop = _stops[stopIndex];
517+
518+ if (!stop.isEnabled ())
519+ continue ;
520+
521+ bool hasVoices = false ;
522+
523+ auto * voice = _activeVoices.first ();
524+
525+ while (voice != nullptr ) {
526+ if (voice->stopIndex () == stopIndex) {
527+ hasVoices = true ;
528+ break ;
529+ }
530+
531+ voice = voice->next ();
532+ }
533+
534+ // Trigger voices for enabled stops
535+ if (!hasVoices) {
536+ for (int note = 0 ; note < _keysState.size (); ++note) {
537+ if (_keysState[note])
538+ triggerVoicesForStop (stopIndex, note);
539+ }
540+ }
541+ }
542+ }
543+
544+ bool Division::triggerVoicesForStop (int stopIndex, int note)
545+ {
546+ jassert (isPositiveAndBelow (stopIndex, _stops.size ()));
547+
548+ const auto & stop = _stops[stopIndex];
549+
550+ if (!stop.isEnabled ())
551+ return false ;
552+
553+ bool voiceTriggered = false ;
554+
555+ for (const auto & zone : stop.getZones ()) {
556+ if (zone.isForKey (note)) {
557+ for (auto * rw : zone.rankwaves ) {
558+ auto state = rw->trigger (note);
559+
560+ // Rankwave may be in the middle of construction, in this case
561+ // we don't trigger a voice.
562+ if (state.isTriggered ()) {
563+ state.gain = stop.getGain ();
564+ state.chiffGain = stop.getChiffGain ();
565+
566+ if (auto * voice = _engine.getVoicePool ().trigger (state)) {
567+ voice->setStopIndex (stopIndex);
568+ _activeVoices.append (voice);
569+ voiceTriggered = true ;
570+ }
571+ }
572+ }
573+ }
574+ }
575+
576+ return voiceTriggered;
577+ }
578+
503579AEOLUS_NAMESPACE_END
0 commit comments