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>
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.
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.
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.
23 #ifndef __ardour_midi_region_h__
24 #define __ardour_midi_region_h__
28 #include "temporal/beats.h"
29 #include "evoral/Range.hpp"
31 #include "pbd/string_convert.h"
33 #include "ardour/ardour.h"
34 #include "ardour/midi_cursor.h"
35 #include "ardour/region.h"
40 namespace Properties {
41 LIBARDOUR_API extern PBD::PropertyDescriptor<double> start_beats;
42 LIBARDOUR_API extern PBD::PropertyDescriptor<double> length_beats;
47 template<typename Time> class EventSink;
52 class MidiChannelFilter;
56 class MidiStateTracker;
61 template<typename T> class MidiRingBuffer;
63 class LIBARDOUR_API MidiRegion : public Region
66 static void make_property_quarks ();
70 bool do_export (std::string path) const;
72 boost::shared_ptr<MidiRegion> clone (std::string path = std::string()) const;
73 boost::shared_ptr<MidiRegion> clone (boost::shared_ptr<MidiSource>) const;
75 boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
77 /* Stub Readable interface */
78 virtual samplecnt_t read (Sample*, samplepos_t /*pos*/, samplecnt_t /*cnt*/, int /*channel*/) const { return 0; }
79 virtual samplecnt_t readable_length() const { return length(); }
81 samplecnt_t read_at (Evoral::EventSink<samplepos_t>& dst,
84 Evoral::Range<samplepos_t>* loop_range,
87 NoteMode mode = Sustained,
88 MidiStateTracker* tracker = 0,
89 MidiChannelFilter* filter = 0) const;
91 samplecnt_t master_read_at (MidiRingBuffer<samplepos_t>& dst,
94 Evoral::Range<samplepos_t>* loop_range,
97 NoteMode mode = Sustained) const;
100 int set_state (const XMLNode&, int version);
102 int separate_by_channel (std::vector< boost::shared_ptr<Region> >&) const;
106 boost::shared_ptr<Evoral::Control> control(const Evoral::Parameter& id, bool create=false);
108 virtual boost::shared_ptr<const Evoral::Control> control(const Evoral::Parameter& id) const;
112 boost::shared_ptr<MidiModel> model();
113 boost::shared_ptr<const MidiModel> model() const;
115 void fix_negative_start ();
116 double start_beats () const {return _start_beats; }
117 double length_beats () const {return _length_beats; }
119 void clobber_sources (boost::shared_ptr<MidiSource> source);
121 int render (Evoral::EventSink<samplepos_t>& dst,
124 MidiChannelFilter* filter) const;
128 virtual bool can_trim_start_before_source_start () const {
133 friend class RegionFactory;
134 PBD::Property<double> _start_beats;
135 PBD::Property<double> _length_beats;
137 MidiRegion (const SourceList&);
138 MidiRegion (boost::shared_ptr<const MidiRegion>);
139 MidiRegion (boost::shared_ptr<const MidiRegion>, ARDOUR::MusicSample offset);
141 samplecnt_t _read_at (const SourceList&, Evoral::EventSink<samplepos_t>& dst,
142 samplepos_t position,
144 Evoral::Range<samplepos_t>* loop_range,
147 NoteMode mode = Sustained,
148 MidiStateTracker* tracker = 0,
149 MidiChannelFilter* filter = 0) const;
151 void register_properties ();
152 void post_set (const PBD::PropertyChange&);
154 void recompute_at_start ();
155 void recompute_at_end ();
157 void set_position_internal (samplepos_t pos, bool allow_bbt_recompute, const int32_t sub_num);
158 void set_position_music_internal (double qn);
159 void set_length_internal (samplecnt_t len, const int32_t sub_num);
160 void set_start_internal (samplecnt_t, const int32_t sub_num);
161 void trim_to_internal (samplepos_t position, samplecnt_t length, const int32_t sub_num);
162 void update_length_beats (const int32_t sub_num);
164 void model_changed ();
165 void model_shifted (double qn_distance);
166 void model_automation_state_changed (Evoral::Parameter const &);
168 void set_start_beats_from_start_samples ();
169 void update_after_tempo_map_change (bool send_change = true);
171 std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading
172 PBD::ScopedConnection _model_connection;
173 PBD::ScopedConnection _model_shift_connection;
174 PBD::ScopedConnection _source_connection;
175 PBD::ScopedConnection _model_contents_connection;
179 } /* namespace ARDOUR */
182 #endif /* __ardour_midi_region_h__ */