1 /* 2 * Copyright (C) 2008-2015 David Robillard <d@drobilla.net> 3 * Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2010-2011 Carl Hetherington <carl@carlh.net> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #ifndef __ardour_midi_state_tracker_h__ 22 #define __ardour_midi_state_tracker_h__ 23 24 #include <glibmm/threads.h> 25 26 #include "temporal/beats.h" 27 #include "ardour/midi_buffer.h" 28 29 namespace Evoral { 30 template <typename T> class EventSink; 31 } 32 33 namespace ARDOUR { 34 35 class MidiSource; 36 37 /** Tracks played notes, so they can be resolved in potential stuck note 38 * situations (e.g. looping, transport stop, etc). 39 */ 40 class LIBARDOUR_API MidiStateTracker 41 { 42 public: 43 MidiStateTracker(); 44 45 void track (const MidiBuffer::const_iterator& from, const MidiBuffer::const_iterator& to); 46 void track (const uint8_t* evbuf); 47 void add (uint8_t note, uint8_t chn); 48 void remove (uint8_t note, uint8_t chn); 49 void resolve_notes (MidiBuffer& buffer, samplepos_t time); 50 void resolve_notes (Evoral::EventSink<samplepos_t>& buffer, samplepos_t time); 51 void resolve_notes (MidiSource& src, const Glib::Threads::Mutex::Lock& lock, Temporal::Beats time); 52 void dump (std::ostream&); 53 void reset (); empty()54 bool empty() const { return _on == 0; } on()55 uint16_t on() const { return _on; } active(uint8_t note,uint8_t channel)56 bool active (uint8_t note, uint8_t channel) { 57 return _active_notes[(channel*128)+note] > 0; 58 } 59 60 template<typename Time> track(const Evoral::Event<Time> & ev)61 void track (const Evoral::Event<Time>& ev) { 62 track (ev.buffer()); 63 } 64 65 private: 66 uint8_t _active_notes[128*16]; 67 uint16_t _on; 68 }; 69 70 71 } // namespace ARDOUR 72 73 #endif // __ardour_midi_state_tracker_h__ 74