1 /*
2  * Copyright (C) 2006-2015 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) 2014-2019 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef __ardour_midi_track_h__
23 #define __ardour_midi_track_h__
24 
25 #include "ardour/midi_channel_filter.h"
26 #include "ardour/midi_ring_buffer.h"
27 #include "ardour/track.h"
28 
29 namespace ARDOUR
30 {
31 
32 class InterThreadInfo;
33 class MidiPlaylist;
34 class RouteGroup;
35 class SMFSource;
36 class Session;
37 
38 class LIBARDOUR_API MidiTrack : public Track
39 {
40 public:
41 	MidiTrack (Session&, std::string name = "", TrackMode m = Normal);
42 	~MidiTrack ();
43 
44 	int init ();
45 
46 	void realtime_locate (bool);
47 	void non_realtime_locate (samplepos_t);
48 
49 	bool can_be_record_enabled ();
50 	bool can_be_record_safe ();
51 
52 	void freeze_me (InterThreadInfo&);
53 	void unfreeze ();
54 
bounceable(boost::shared_ptr<Processor>,bool)55 	bool bounceable (boost::shared_ptr<Processor>, bool) const { return false; }
56 	boost::shared_ptr<Region> bounce (InterThreadInfo&, std::string const&);
57 	boost::shared_ptr<Region> bounce_range (samplepos_t                  start,
58 	                                        samplepos_t                  end,
59 	                                        InterThreadInfo&             iti,
60 	                                        boost::shared_ptr<Processor> endpoint,
61 	                                        bool                         include_endpoint,
62 	                                        std::string const&           name);
63 
64 	int export_stuff (BufferSet&                   bufs,
65 	                  samplepos_t                  start_sample,
66 	                  samplecnt_t                  end_sample,
67 	                  boost::shared_ptr<Processor> endpoint,
68 	                  bool                         include_endpoint,
69 	                  bool                         for_export,
70 	                  bool                         for_freeze,
71 	                  MidiStateTracker&            tracker);
72 
73 	int set_state (const XMLNode&, int version);
74 
75 	void midi_panic(void);
76 	bool write_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf);
77 
78 	/** A control that will send "immediate" events to a MIDI track when twiddled */
79 	struct MidiControl : public AutomationControl {
80 		MidiControl(MidiTrack* route, const Evoral::Parameter& param,
81 			    boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>())
82 			: AutomationControl (route->session(), param, ParameterDescriptor(param), al)
83 			, _route (route)
84 		{}
85 
writableMidiControl86 		bool writable() const { return true; }
87 		void restore_value ();
88 
89 		MidiTrack* _route;
90 
91 	private:
92 		void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
93 	};
94 
95 	virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
96 
note_mode()97 	NoteMode note_mode() const { return _note_mode; }
98 	void set_note_mode (NoteMode m);
99 
100 	std::string describe_parameter (Evoral::Parameter param);
101 
step_editing()102 	bool step_editing() const { return _step_editing; }
103 	void set_step_editing (bool yn);
step_edit_ring_buffer()104 	MidiRingBuffer<samplepos_t>& step_edit_ring_buffer() { return _step_edit_ring_buffer; }
105 
106 	PBD::Signal1<void,bool> StepEditStatusChange;
107 
108 	boost::shared_ptr<SMFSource> write_source (uint32_t n = 0);
109 
110 	/* Configure capture/playback channels (see MidiChannelFilter). */
111 	void set_capture_channel_mode (ChannelMode mode, uint16_t mask);
112 	void set_playback_channel_mode (ChannelMode mode, uint16_t mask);
113 	void set_playback_channel_mask (uint16_t mask);
114 	void set_capture_channel_mask (uint16_t mask);
115 
get_playback_channel_mode()116 	ChannelMode get_playback_channel_mode() const { return _playback_filter.get_channel_mode(); }
get_capture_channel_mode()117 	ChannelMode get_capture_channel_mode()  const { return _capture_filter.get_channel_mode(); }
get_playback_channel_mask()118 	uint16_t    get_playback_channel_mask() const { return _playback_filter.get_channel_mask(); }
get_capture_channel_mask()119 	uint16_t    get_capture_channel_mask()  const { return _capture_filter.get_channel_mask(); }
120 
playback_filter()121 	MidiChannelFilter& playback_filter() { return _playback_filter; }
capture_filter()122 	MidiChannelFilter& capture_filter()  { return _capture_filter; }
123 
124 	virtual void filter_input (BufferSet& bufs);
125 
126 	boost::shared_ptr<MidiPlaylist> midi_playlist ();
127 
128 	PBD::Signal1<void, boost::weak_ptr<MidiSource> > DataRecorded;
129 	boost::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
130 
131 	MonitorState monitoring_state () const;
132 	MonitorState get_input_monitoring_state (bool recording, bool talkback) const;
133 
immediate_event_buffer()134 	MidiBuffer const& immediate_event_buffer () const { return _immediate_event_buffer; }
immediate_events()135 	MidiRingBuffer<samplepos_t>& immediate_events () { return _immediate_events; }
136 
137 	void set_input_active (bool);
138 	bool input_active () const;
139 	PBD::Signal0<void> InputActiveChanged;
140 
141 	void realtime_handle_transport_stopped ();
142 	void region_edited (boost::shared_ptr<Region>);
143 
144 protected:
145 
146 	XMLNode& state (bool save_template);
147 
148 	void act_on_mute ();
149 	void monitoring_changed (bool, PBD::Controllable::GroupControlDisposition);
150 
151 	void snapshot_out_of_band_data (samplecnt_t nframes);
152 	void write_out_of_band_data (BufferSet& bufs, samplecnt_t /* nframes */) const;
153 
154 
155 private:
156 	MidiRingBuffer<samplepos_t> _immediate_events;
157 	MidiBuffer                  _immediate_event_buffer;
158 	MidiRingBuffer<samplepos_t> _step_edit_ring_buffer;
159 	NoteMode                    _note_mode;
160 	bool                        _step_editing;
161 	bool                        _input_active;
162 	MidiChannelFilter           _playback_filter;
163 	MidiChannelFilter           _capture_filter;
164 
165 	void set_state_part_two ();
166 	void set_state_part_three ();
167 
168 	int no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing);
169 	void push_midi_input_to_step_edit_ringbuffer (samplecnt_t nframes);
170 
171 	void track_input_active (IOChange, void*);
172 	void map_input_active (bool);
173 
174 	void data_recorded (boost::weak_ptr<MidiSource> src);
175 
176 	/** Update automation controls to reflect any changes in buffers. */
177 	void update_controls (BufferSet const& bufs);
178 	void restore_controls ();
179 
180 	void playlist_contents_changed ();
181 	PBD::ScopedConnection playlist_content_change_connection;
182 };
183 
184 } /* namespace ARDOUR*/
185 
186 #endif /* __ardour_midi_track_h__ */
187