Files

copied
Last update 6 years 1 month by Olivier Gillet
Filesedges
..
bootloader
hardware_design
resources
__init__.py
adc_acquisition.cc
adc_acquisition.h
audio_buffer.cc
audio_buffer.h
digital_oscillator.cc
digital_oscillator.h
edges.cc
hardware_config.h
makefile
midi.h
midi_handler.cc
midi_handler.h
note_stack.h
resources.cc
resources.h
settings.cc
settings.h
storage.h
timer_oscillator.cc
timer_oscillator.h
ui.cc
ui.h
voice_allocator.cc
voice_allocator.h
midi_handler.h
// Copyright 2012 Olivier Gillet. // // Author: Olivier Gillet (ol.gillet@gmail.com) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // ----------------------------------------------------------------------------- #ifndef EDGES_MIDI_HANDLER_H_ #define EDGES_MIDI_HANDLER_H_ #include "avrlibx/avrlibx.h" #include "edges/hardware_config.h" #include "edges/midi.h" #include "edges/note_stack.h" #include "edges/settings.h" #include "edges/voice_allocator.h" namespace edges { enum MidiMode { MIDI_MODE_MULTITIMBRAL, MIDI_MODE_POLYPHONIC }; class MidiHandler : public midi::MidiDevice { public: MidiHandler() { } static inline void Init() { for (uint8_t channel = 0; channel < kNumChannels; ++channel) { stack_[channel].Init(); } allocator_.Init(); allocator_.set_size(4); learning_ = false; memset(gate_, false, sizeof(gate_)); memset(pitch_, -1, sizeof(pitch_)); } static void ToggleMidiMode() { settings.ToggleMidiMode(); Init(); } static void DisableMidiCoupling() { Init(); } static void ResetAllControllers(uint8_t channel) { channel = (channel - base_channel()) & 0xf; pitch_bend_[channel] = 0; } static inline void NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) { channel = (channel - base_channel()) & 0xf; if (velocity == 0) { NoteOff(channel, note, 0); } if (midi_mode() == MIDI_MODE_MULTITIMBRAL) { stack_[channel].NoteOn(note, velocity); pitch_[channel] = stack_[channel].most_recent_note().note << 7; } else { channel = allocator_.NoteOn(note); pitch_[channel] = note << 7; } gate_[channel] = true; } static inline void NoteOff(uint8_t channel, uint8_t note, uint8_t velocity) { channel = (channel - base_channel()) & 0xf; if (midi_mode() == MIDI_MODE_MULTITIMBRAL) { stack_[channel].NoteOff(note); if (stack_[channel].size()) { pitch_[channel] = stack_[channel].most_recent_note().note << 7; } gate_[channel] = stack_[channel].size() != 0; } else { channel = allocator_.NoteOff(note); if (channel != 0xff) { gate_[channel] = false; } } } static inline void PitchBend(uint8_t channel, uint16_t value) { channel = (channel - base_channel()) & 0xf; int16_t v = value; v -= 8192; v >>= 5; if (midi_mode() == MIDI_MODE_MULTITIMBRAL) { pitch_bend_[channel] = v; } else { for (uint8_t i = 0; i < kNumChannels; ++i) { pitch_bend_[i] = v; } } } static inline void RawMidiData( uint8_t status, uint8_t* data, uint8_t data_size, uint8_t accepted_channel) { if (learning_ && (status & 0xf0) == 0x90) { settings.set_midi_channel(status & 0xf); learning_ = false; } } static uint8_t CheckChannel(uint8_t channel) { if (midi_mode() == MIDI_MODE_MULTITIMBRAL) { return ((channel - base_channel()) & 0xf) < kNumChannels; } else { return channel == base_channel(); } } static void Learn() { learning_ = true; } static inline bool learning() { return learning_; } static inline bool gate(uint8_t channel) { return gate_[channel]; } static int16_t shift_pitch(uint8_t channel, int16_t pitch) { if (pitch_[channel] == -1) { return pitch; } else { pitch -= (60 << 7); pitch += pitch_[channel]; pitch += pitch_bend_[channel]; if (pitch < 0) { pitch = 0; } else if (pitch > 16383) { pitch = 16383; } return pitch; } return pitch; } static inline uint8_t base_channel() { return settings.midi_channel(); } static inline MidiMode midi_mode() { return static_cast<MidiMode>(settings.midi_mode()); } private: static bool learning_; static bool gate_[kNumChannels]; static int16_t pitch_[kNumChannels]; static int16_t pitch_bend_[kNumChannels]; static NoteStack<10> stack_[kNumChannels]; static VoiceAllocator allocator_; DISALLOW_COPY_AND_ASSIGN(MidiHandler); }; extern MidiHandler midi_handler; } // namespace edges #endif // EDGES_MIDI_HANDLER_H_
Report a bug