#include "part.h" bool Part::is_message_handled(uint8_t channel, uint8_t note) // TODO: add origin { if (this->part_data().midi_filter_channel_enabled && channel != this->part_data().midi_filter_channel) return false; if (this->part_data().midi_filter_lowest_note > note || this->part_data().midi_filter_highest_note < note) return false; return true; } bool Part::NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { if (!is_message_handled(channel, note)) return false; if (velocity == 0) return NoteOff(channel, note, velocity); uint8_t voiceIndex = 0; if (this->part_data().part_voice_count > 1) { // only use voiceallocator for polyphonic config voiceIndex = voiceAllocator.NoteOn(note); } Voice* voice = &voices[voiceIndex]; voice->NoteOn(note, velocity); return true; } bool Part::NoteOff(uint8_t channel, uint8_t note, uint8_t velocity) { if (!is_message_handled(channel, note)) return false; uint8_t voiceIndex = 0; if (this->part_data().part_voice_count > 1) { // only use voiceallocator for polyphonic config voiceIndex = voiceAllocator.NoteOff(note); } Voice* voice = &voices[voiceIndex]; voice->NoteOff(note, velocity); return true; } bool Part::PitchBend(uint8_t channel, uint16_t pitch_bend) { if (!is_message_handled(channel, this->part_data().midi_filter_lowest_note)) return false; for (size_t i = 0; i < this->part_data().part_voice_count; i++) voices[i].PitchBend(pitch_bend); return true; } bool Part::Aftertouch(uint8_t channel, uint8_t note, uint8_t velocity) { if(!is_message_handled(channel, note)) return false; uint8_t voiceIndex = 0; if(this->part_data().part_voice_count > 1) voiceIndex = this->voiceAllocator.Find(note); voices[voiceIndex].Aftertouch(velocity); return true; } bool Part::Aftertouch(uint8_t channel, uint8_t velocity) { if(!is_message_handled(channel, this->part_data().midi_filter_lowest_note)) return false; for(size_t i = 0; i < this->part_data().part_voice_count; i++) voices[i].Aftertouch(velocity); return true; }