1 /* 2 * Copyright (C) 2006-2016 David Robillard <d@drobilla.net> 3 * Copyright (C) 2007-2017 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 5 * Copyright (C) 2016-2017 Nick Mainsbridge <mainsbridge@gmail.com> 6 * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 */ 22 23 #ifndef __ardour_midi_region_h__ 24 #define __ardour_midi_region_h__ 25 26 #include <vector> 27 28 #include "temporal/beats.h" 29 #include "evoral/Range.h" 30 31 #include "pbd/string_convert.h" 32 33 #include "ardour/ardour.h" 34 #include "ardour/midi_cursor.h" 35 #include "ardour/region.h" 36 37 class XMLNode; 38 39 namespace ARDOUR { 40 namespace Properties { 41 LIBARDOUR_API extern PBD::PropertyDescriptor<double> start_beats; 42 LIBARDOUR_API extern PBD::PropertyDescriptor<double> length_beats; 43 } 44 } 45 46 namespace Evoral { 47 template<typename Time> class EventSink; 48 } 49 50 namespace ARDOUR { 51 52 class MidiChannelFilter; 53 class MidiFilter; 54 class MidiModel; 55 class MidiSource; 56 class MidiStateTracker; 57 class Playlist; 58 class Route; 59 class Session; 60 class ThawList; 61 62 template<typename T> class MidiRingBuffer; 63 64 class LIBARDOUR_API MidiRegion : public Region 65 { 66 public: 67 static void make_property_quarks (); 68 69 ~MidiRegion(); 70 71 bool do_export (std::string path) const; 72 73 boost::shared_ptr<MidiRegion> clone (std::string path = std::string()) const; 74 boost::shared_ptr<MidiRegion> clone (boost::shared_ptr<MidiSource>, ThawList* tl = 0) const; 75 76 boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const; 77 78 /* Stub Readable interface */ read(Sample *,samplepos_t,samplecnt_t,int)79 virtual samplecnt_t read (Sample*, samplepos_t /*pos*/, samplecnt_t /*cnt*/, int /*channel*/) const { return 0; } readable_length()80 virtual samplecnt_t readable_length() const { return length(); } 81 82 samplecnt_t read_at (Evoral::EventSink<samplepos_t>& dst, 83 samplepos_t position, 84 samplecnt_t dur, 85 Evoral::Range<samplepos_t>* loop_range, 86 MidiCursor& cursor, 87 uint32_t chan_n = 0, 88 NoteMode mode = Sustained, 89 MidiStateTracker* tracker = 0, 90 MidiChannelFilter* filter = 0) const; 91 92 samplecnt_t master_read_at (MidiRingBuffer<samplepos_t>& dst, 93 samplepos_t position, 94 samplecnt_t dur, 95 Evoral::Range<samplepos_t>* loop_range, 96 MidiCursor& cursor, 97 uint32_t chan_n = 0, 98 NoteMode mode = Sustained) const; 99 100 XMLNode& state (); 101 int set_state (const XMLNode&, int version); 102 103 int separate_by_channel (std::vector< boost::shared_ptr<Region> >&) const; 104 105 /* automation */ 106 107 boost::shared_ptr<Evoral::Control> control(const Evoral::Parameter& id, bool create=false); 108 109 virtual boost::shared_ptr<const Evoral::Control> control(const Evoral::Parameter& id) const; 110 111 /* export */ 112 113 boost::shared_ptr<MidiModel> model(); 114 boost::shared_ptr<const MidiModel> model() const; 115 116 void fix_negative_start (); start_beats()117 double start_beats () const {return _start_beats; } length_beats()118 double length_beats () const {return _length_beats; } 119 120 void clobber_sources (boost::shared_ptr<MidiSource> source); 121 122 int render (Evoral::EventSink<samplepos_t>& dst, 123 uint32_t chan_n, 124 NoteMode mode, 125 MidiChannelFilter* filter) const; 126 127 protected: 128 can_trim_start_before_source_start()129 virtual bool can_trim_start_before_source_start () const { 130 return true; 131 } 132 133 private: 134 friend class RegionFactory; 135 PBD::Property<double> _start_beats; 136 PBD::Property<double> _length_beats; 137 138 MidiRegion (const SourceList&); 139 MidiRegion (boost::shared_ptr<const MidiRegion>); 140 MidiRegion (boost::shared_ptr<const MidiRegion>, ARDOUR::MusicSample offset); 141 142 samplecnt_t _read_at (const SourceList&, Evoral::EventSink<samplepos_t>& dst, 143 samplepos_t position, 144 samplecnt_t dur, 145 Evoral::Range<samplepos_t>* loop_range, 146 MidiCursor& cursor, 147 uint32_t chan_n = 0, 148 NoteMode mode = Sustained, 149 MidiStateTracker* tracker = 0, 150 MidiChannelFilter* filter = 0) const; 151 152 void register_properties (); 153 void post_set (const PBD::PropertyChange&); 154 155 void recompute_at_start (); 156 void recompute_at_end (); 157 158 bool set_name (const std::string & str); 159 160 void set_position_internal (samplepos_t pos, bool allow_bbt_recompute, const int32_t sub_num); 161 void set_position_music_internal (double qn); 162 void set_length_internal (samplecnt_t len, const int32_t sub_num); 163 void set_start_internal (samplecnt_t, const int32_t sub_num); 164 void trim_to_internal (samplepos_t position, samplecnt_t length, const int32_t sub_num); 165 void update_length_beats (const int32_t sub_num); 166 167 void model_changed (); 168 void model_contents_changed (); 169 void model_shifted (double qn_distance); 170 void model_automation_state_changed (Evoral::Parameter const &); 171 172 void set_start_beats_from_start_samples (); 173 void update_after_tempo_map_change (bool send_change = true); 174 175 std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading 176 PBD::ScopedConnection _model_connection; 177 PBD::ScopedConnection _model_shift_connection; 178 PBD::ScopedConnection _model_changed_connection; 179 PBD::ScopedConnection _source_connection; 180 PBD::ScopedConnection _model_contents_connection; 181 bool _ignore_shift; 182 }; 183 184 } /* namespace ARDOUR */ 185 186 187 #endif /* __ardour_midi_region_h__ */ 188