mirror of
https://github.com/yokemura/Magical8bitPlug2.git
synced 2025-07-17 11:04:16 -04:00
Legato
This commit is contained in:
@ -10,32 +10,107 @@
|
||||
|
||||
#include "CustomSynth.h"
|
||||
#include "BaseVoice.h"
|
||||
#include "TonalVoice.h"
|
||||
#include "PluginProcessor.h"
|
||||
|
||||
CustomSynth::CustomSynth(Magical8bitPlug2AudioProcessor& p) : processor(p) {}
|
||||
|
||||
void CustomSynth::noteOn(int midiChannel, int midiNoteNumber, float velocity) {
|
||||
// Poly
|
||||
TonalVoice* CustomSynth::getVoiceIfShouldProcessInMonoMode() {
|
||||
if (!processor.settingRefs.isMonophonic()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (processor.settingRefs.monophonicBehavior() == kNonLegato) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Try casting into TonalVoice* and return it if success(otherwise returns nullptr)
|
||||
return dynamic_cast<TonalVoice *>(voices.getFirst());
|
||||
}
|
||||
|
||||
void CustomSynth::noteOn(int midiChannel, int midiNoteNumber, float velocity) {
|
||||
TonalVoice *voice = getVoiceIfShouldProcessInMonoMode();
|
||||
|
||||
if (voice == nullptr) {
|
||||
Synthesiser::noteOn(midiChannel, midiNoteNumber, velocity);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mono
|
||||
auto voice = voices.getFirst();
|
||||
|
||||
if (voice == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Start thread guard
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (voice->isKeyDown()) {
|
||||
((BaseVoice*)voice)->changeNote(midiNoteNumber, velocity);
|
||||
// Already key on
|
||||
switch (processor.settingRefs.monophonicBehavior()) {
|
||||
case kLegato:
|
||||
voice->addLegatoNote(midiNoteNumber, velocity);
|
||||
break;
|
||||
case kArpeggioUp:
|
||||
voice->addArpeggioNoteAscending(midiNoteNumber);
|
||||
break;
|
||||
case kArpeggioDown:
|
||||
voice->addArpeggioNoteDescending(midiNoteNumber);
|
||||
break;
|
||||
default:
|
||||
// no-op
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Synthesiser::noteOn(midiChannel, midiNoteNumber, velocity);
|
||||
switch (processor.settingRefs.monophonicBehavior()) {
|
||||
case kLegato:
|
||||
// just start
|
||||
Synthesiser::noteOn(midiChannel, midiNoteNumber, velocity);
|
||||
voice->setLegatoMode(*(processor.settingRefs.portamentoTime));
|
||||
break;
|
||||
case kArpeggioUp:
|
||||
case kArpeggioDown:
|
||||
// calc arpeggio interval
|
||||
// set arpeggio mode with this note number and arp interval
|
||||
break;
|
||||
default:
|
||||
// no-op
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomSynth::noteOff(int midiChannel, int midiNoteNumber, float velocity, bool allowTailOff) {
|
||||
Synthesiser::noteOff(midiChannel, midiNoteNumber, velocity, allowTailOff);
|
||||
TonalVoice *voice = getVoiceIfShouldProcessInMonoMode();
|
||||
|
||||
if (voice == nullptr) {
|
||||
Synthesiser::noteOff(midiChannel, midiNoteNumber, velocity, allowTailOff);
|
||||
return;
|
||||
}
|
||||
|
||||
// mono
|
||||
|
||||
// Start thread guard
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (!voice->isKeyDown()) {
|
||||
// key is already off
|
||||
return;
|
||||
}
|
||||
|
||||
switch (processor.settingRefs.monophonicBehavior()) {
|
||||
case kLegato:
|
||||
{
|
||||
int numBuffer = voice->removeLegatoNote(midiNoteNumber);
|
||||
if (numBuffer < 1) {
|
||||
Synthesiser::noteOff(midiChannel, voice->getCurrentlyPlayingNote(), velocity, allowTailOff);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kArpeggioUp:
|
||||
case kArpeggioDown:
|
||||
// remove arpeggio note and get # of remaining arpeggio notes
|
||||
// if zero
|
||||
// all notes off
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomSynth::allNotesOff (const int midiChannel, const bool allowTailOff) {
|
||||
|
Reference in New Issue
Block a user