1 /*
2  * Copyright (C) 2006-2016 David Robillard <d@drobilla.net>
3  * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
4  * Copyright (C) 2007-2019 Paul Davis <paul@linuxaudiosystems.com>
5  * Copyright (C) 2008-2012 Hans Baier <hansfbaier@googlemail.com>
6  * Copyright (C) 2013-2016 Tim Mayberry <mojofunk@gmail.com>
7  * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
8  * Copyright (C) 2013 John Emmas <john@creativepost.co.uk>
9  * Copyright (C) 2015-2018 Ben Loftis <ben@harrisonconsoles.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 #include <cmath>
26 
27 #ifdef COMPILER_MSVC
28 #include <float.h>
29 
30 // 'std::isinf()' and 'std::isnan()' are not available in MSVC.
31 #define isinf_local(val) !((bool)_finite((double)val))
32 #define isnan_local(val) (bool)_isnan((double)val)
33 #else
34 #define isinf_local std::isinf
35 #define isnan_local std::isnan
36 #endif
37 
38 #include "pbd/enumwriter.h"
39 #include "pbd/types_convert.h"
40 #include "evoral/midi_util.h"
41 
42 #include "ardour/amp.h"
43 #include "ardour/beats_samples_converter.h"
44 #include "ardour/buffer_set.h"
45 #include "ardour/debug.h"
46 #include "ardour/delivery.h"
47 #include "ardour/disk_reader.h"
48 #include "ardour/disk_writer.h"
49 #include "ardour/event_type_map.h"
50 #include "ardour/meter.h"
51 #include "ardour/midi_playlist.h"
52 #include "ardour/midi_port.h"
53 #include "ardour/midi_region.h"
54 #include "ardour/midi_track.h"
55 #include "ardour/monitor_control.h"
56 #include "ardour/parameter_types.h"
57 #include "ardour/port.h"
58 #include "ardour/processor.h"
59 #include "ardour/profile.h"
60 #include "ardour/route_group_specialized.h"
61 #include "ardour/session.h"
62 #include "ardour/session_playlists.h"
63 #include "ardour/types_convert.h"
64 #include "ardour/utils.h"
65 
66 #include "pbd/i18n.h"
67 
68 namespace ARDOUR {
69 class InterThreadInfo;
70 class MidiSource;
71 class Region;
72 class SMFSource;
73 }
74 
75 using namespace std;
76 using namespace ARDOUR;
77 using namespace PBD;
78 
MidiTrack(Session & sess,string name,TrackMode mode)79 MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
80 	: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
81 	, _immediate_events(6096) // FIXME: size?
82 	, _immediate_event_buffer(6096)
83 	, _step_edit_ring_buffer(64) // FIXME: size?
84 	, _note_mode (Sustained)
85 	, _step_editing (false)
86 	, _input_active (true)
87 {
88 	_session.SessionLoaded.connect_same_thread (*this, boost::bind (&MidiTrack::restore_controls, this));
89 
90 	_playback_filter.ChannelModeChanged.connect_same_thread (*this, boost::bind (&Track::playlist_modified, this));
91 	_playback_filter.ChannelMaskChanged.connect_same_thread (*this, boost::bind (&Track::playlist_modified, this));
92 }
93 
~MidiTrack()94 MidiTrack::~MidiTrack ()
95 {
96 }
97 
98 int
init()99 MidiTrack::init ()
100 {
101 	if (Track::init ()) {
102 		return -1;
103 	}
104 
105 	_input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
106 
107 	_disk_writer->set_note_mode (_note_mode);
108 	_disk_reader->reset_tracker ();
109 
110 	_disk_writer->DataRecorded.connect_same_thread (*this, boost::bind (&MidiTrack::data_recorded, this, _1));
111 
112 	return 0;
113 }
114 
115 void
data_recorded(boost::weak_ptr<MidiSource> src)116 MidiTrack::data_recorded (boost::weak_ptr<MidiSource> src)
117 {
118 	DataRecorded (src); /* EMIT SIGNAL */
119 }
120 
121 bool
can_be_record_safe()122 MidiTrack::can_be_record_safe ()
123 {
124 	if (_step_editing) {
125 		return false;
126 	}
127 
128 	return Track::can_be_record_safe ();
129 }
130 
131 bool
can_be_record_enabled()132 MidiTrack::can_be_record_enabled ()
133 {
134 	if (_step_editing) {
135 		return false;
136 	}
137 
138 	return Track::can_be_record_enabled ();
139 }
140 
141 MonitorState
get_input_monitoring_state(bool recording,bool talkback) const142 MidiTrack::get_input_monitoring_state (bool recording, bool talkback) const
143 {
144 	if (!_session.config.get_layered_record_mode () && (recording || talkback)) {
145 		return MonitoringCue;
146 	} else if (!_session.config.get_layered_record_mode () || recording || talkback) {
147 		return MonitoringInput;
148 	} else {
149 		return MonitoringSilence;
150 	}
151 }
152 
153 int
set_state(const XMLNode & node,int version)154 MidiTrack::set_state (const XMLNode& node, int version)
155 {
156 	/* This must happen before Track::set_state(), as there will be a buffer
157 	   fill during that call, and we must fill buffers using the correct
158 	   _note_mode.
159 	*/
160 	if (!node.get_property (X_("note-mode"), _note_mode)) {
161 		_note_mode = Sustained;
162 	}
163 
164 	if (Track::set_state (node, version)) {
165 		return -1;
166 	}
167 
168 	// No destructive MIDI tracks (yet?)
169 	_mode = Normal;
170 
171 	bool yn;
172 	if (node.get_property ("input-active", yn)) {
173 		set_input_active (yn);
174 	}
175 
176 	ChannelMode playback_channel_mode = AllChannels;
177 	ChannelMode capture_channel_mode = AllChannels;
178 
179 	node.get_property ("playback-channel-mode", playback_channel_mode);
180 	node.get_property ("capture-channel-mode", capture_channel_mode);
181 
182 	if (node.get_property ("channel-mode", playback_channel_mode)) {
183 		/* 3.0 behaviour where capture and playback modes were not separated */
184 		capture_channel_mode = playback_channel_mode;
185 	}
186 
187 	XMLProperty const * prop;
188 
189 	unsigned int playback_channel_mask = 0xffff;
190 	unsigned int capture_channel_mask = 0xffff;
191 
192 	if ((prop = node.property ("playback-channel-mask")) != 0) {
193 		sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
194 	}
195 	if ((prop = node.property ("capture-channel-mask")) != 0) {
196 		sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
197 	}
198 	if ((prop = node.property ("channel-mask")) != 0) {
199 		sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
200 		capture_channel_mask = playback_channel_mask;
201 	}
202 
203 	set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
204 	set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
205 
206 	pending_state = const_cast<XMLNode*> (&node);
207 
208 	if (_session.loading ()) {
209 		_session.StateReady.connect_same_thread (
210 			*this, boost::bind (&MidiTrack::set_state_part_two, this));
211 	} else {
212 		set_state_part_two ();
213 	}
214 
215 	return 0;
216 }
217 
218 XMLNode&
state(bool save_template)219 MidiTrack::state(bool save_template)
220 {
221 	XMLNode& root (Track::state (save_template));
222 	XMLNode* freeze_node;
223 	char buf[64];
224 
225 	if (_freeze_record.playlist) {
226 		XMLNode* inode;
227 
228 		freeze_node = new XMLNode (X_("freeze-info"));
229 		freeze_node->set_property ("playlist", _freeze_record.playlist->name());
230 		freeze_node->set_property ("playlist-id", _freeze_record.playlist->id().to_s());
231 		freeze_node->set_property ("state", _freeze_record.state);
232 
233 		for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
234 			inode = new XMLNode (X_("processor"));
235 			inode->set_property (X_("id"), id());
236 			inode->add_child_copy ((*i)->state);
237 
238 			freeze_node->add_child_nocopy (*inode);
239 		}
240 
241 		root.add_child_nocopy (*freeze_node);
242 	}
243 
244 	root.set_property("playback-channel-mode", get_playback_channel_mode());
245 	root.set_property("capture-channel-mode", get_capture_channel_mode());
246 	snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
247 	root.set_property("playback-channel-mask", std::string(buf));
248 	snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
249 	root.set_property("capture-channel-mask", std::string(buf));
250 
251 	root.set_property ("note-mode", _note_mode);
252 	root.set_property ("step-editing", _step_editing);
253 	root.set_property ("input-active", _input_active);
254 
255 	for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
256 		if (boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) {
257 			boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c->second);
258 			assert (ac);
259 			root.add_child_nocopy (ac->get_state ());
260 		}
261 	}
262 
263 	return root;
264 }
265 
266 void
set_state_part_two()267 MidiTrack::set_state_part_two ()
268 {
269 	XMLNode* fnode;
270 	XMLProperty const * prop;
271 
272 	/* This is called after all session state has been restored but before
273 	   have been made ports and connections are established.
274 	*/
275 
276 	if (pending_state == 0) {
277 		return;
278 	}
279 
280 	if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
281 
282 		_freeze_record.state = Frozen;
283 
284 		for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
285 			delete *i;
286 		}
287 		_freeze_record.processor_info.clear ();
288 
289 		boost::shared_ptr<Playlist> freeze_pl;
290 		if ((prop = fnode->property (X_("playlist-id"))) != 0) {
291 			freeze_pl = _session.playlists()->by_id (prop->value());
292 		} else if ((prop = fnode->property (X_("playlist"))) != 0) {
293 			freeze_pl = _session.playlists()->by_name (prop->value());
294 		}
295 		if (freeze_pl) {
296 			_freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (freeze_pl);
297 			_freeze_record.playlist->use();
298 		} else {
299 			_freeze_record.playlist.reset ();
300 			_freeze_record.state = NoFreeze;
301 			return;
302 		}
303 
304 
305 		fnode->get_property (X_("state"), _freeze_record.state);
306 
307 		XMLNodeConstIterator citer;
308 		XMLNodeList clist = fnode->children();
309 
310 		std::string str;
311 		for (citer = clist.begin(); citer != clist.end(); ++citer) {
312 			if ((*citer)->name() != X_("processor")) {
313 				continue;
314 			}
315 
316 			if (!(*citer)->get_property (X_("id"), str)) {
317 				continue;
318 			}
319 
320 			FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
321 										   boost::shared_ptr<Processor>());
322 			frii->id = str;
323 			_freeze_record.processor_info.push_back (frii);
324 		}
325 	}
326 
327 	return;
328 }
329 
330 void
restore_controls()331 MidiTrack::restore_controls ()
332 {
333 	// TODO order events (CC before PGM to set banks)
334 	for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
335 		boost::shared_ptr<MidiTrack::MidiControl> mctrl = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second);
336 		if (mctrl) {
337 			mctrl->restore_value();
338 		}
339 	}
340 }
341 
342 void
update_controls(BufferSet const & bufs)343 MidiTrack::update_controls (BufferSet const& bufs)
344 {
345 	const MidiBuffer& buf = bufs.get_midi(0);
346 	for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
347 		const Evoral::Event<samplepos_t>&         ev     = *e;
348 		const Evoral::Parameter                  param   = midi_parameter(ev.buffer(), ev.size());
349 		const boost::shared_ptr<AutomationControl> control = automation_control (param);
350 		if (control) {
351 			double old = control->get_double (false, 0);
352 			control->set_double (ev.value(), 0, false);
353 			if (old != ev.value()) {
354 				control->Changed (false, Controllable::NoGroup);
355 			}
356 		}
357 	}
358 }
359 
360 int
no_roll_unlocked(pframes_t nframes,samplepos_t start_sample,samplepos_t end_sample,bool state_changing)361 MidiTrack::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing)
362 {
363 	int ret = Track::no_roll_unlocked (nframes, start_sample, end_sample, state_changing);
364 
365 	if (ret == 0 && _step_editing) {
366 		push_midi_input_to_step_edit_ringbuffer (nframes);
367 	}
368 
369 	return ret;
370 }
371 
372 void
realtime_locate(bool for_loop_end)373 MidiTrack::realtime_locate (bool for_loop_end)
374 {
375 	Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
376 
377 	if (!lm.locked ()) {
378 		return;
379 	}
380 
381 	for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
382 		(*i)->realtime_locate (for_loop_end);
383 	}
384 }
385 
386 void
non_realtime_locate(samplepos_t pos)387 MidiTrack::non_realtime_locate (samplepos_t pos)
388 {
389 	Track::non_realtime_locate(pos);
390 
391 	boost::shared_ptr<MidiPlaylist> playlist = _disk_writer->midi_playlist();
392 	if (!playlist) {
393 		return;
394 	}
395 
396 	/* Get the top unmuted region at this position. */
397 	boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(playlist->top_unmuted_region_at(pos));
398 
399 	if (!region) {
400 		return;
401 	}
402 
403 	/* the source may be missing, but the control still referenced in the GUI */
404 	if (!region->midi_source() || !region->model()) {
405 		return;
406 	}
407 
408 	Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
409 	if (!lm.locked()) {
410 		return;
411 	}
412 
413 	/* Update track controllers based on its "automation". */
414 	const samplepos_t     origin = region->position() - region->start();
415 	BeatsSamplesConverter bfc(_session.tempo_map(), origin);
416 
417 	for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
418 
419 		boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c->second);
420 
421 		if (!ac->automation_playback()) {
422 			continue;
423 		}
424 
425 		boost::shared_ptr<MidiTrack::MidiControl> tcontrol;
426 		boost::shared_ptr<Evoral::Control>        rcontrol;
427 
428 		if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
429 
430 		    (rcontrol = region->control(tcontrol->parameter()))) {
431 			const Temporal::Beats pos_beats = bfc.from(pos - origin);
432 			if (rcontrol->list()->size() > 0) {
433 				tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup);
434 			}
435 		}
436 	}
437 }
438 
439 void
push_midi_input_to_step_edit_ringbuffer(samplecnt_t nframes)440 MidiTrack::push_midi_input_to_step_edit_ringbuffer (samplecnt_t nframes)
441 {
442 	PortSet& ports (_input->ports());
443 
444 	for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
445 
446 		Buffer& b (p->get_buffer (nframes));
447 		const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
448 		assert (mb);
449 
450 		for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
451 
452 			const Evoral::Event<samplepos_t> ev(*e, false);
453 
454 			/* note on, since for step edit, note length is determined
455 			   elsewhere
456 			*/
457 
458 			if (ev.is_note_on()) {
459 				/* we don't care about the time for this purpose */
460 				_step_edit_ring_buffer.write (0, ev.event_type(), ev.size(), ev.buffer());
461 			}
462 		}
463 	}
464 }
465 
466 void
snapshot_out_of_band_data(samplecnt_t nframes)467 MidiTrack::snapshot_out_of_band_data (samplecnt_t nframes)
468 {
469 	_immediate_event_buffer.clear ();
470 	if (0 == _immediate_events.read_space()) {
471 		return;
472 	}
473 
474 	assert (nframes > 0);
475 
476 	DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n", name(), _immediate_events.read_space()));
477 
478 	/* write as many of the immediate events as we can, but give "true" as
479 	 * the last argument ("stop on overflow in destination") so that we'll
480 	 * ship the rest out next time.
481 	 *
482 	 * the (nframes-1) argument puts all these events at the last
483 	 * possible position of the output buffer, so that we do not
484 	 * violate monotonicity when writing.
485 	 */
486 
487 	_immediate_events.read (_immediate_event_buffer, 0, 1, nframes - 1, true);
488 }
489 
490 void
write_out_of_band_data(BufferSet & bufs,samplecnt_t nframes) const491 MidiTrack::write_out_of_band_data (BufferSet& bufs, samplecnt_t nframes) const
492 {
493 	MidiBuffer& buf (bufs.get_midi (0));
494 	buf.merge_from (_immediate_event_buffer, nframes);
495 }
496 
497 int
export_stuff(BufferSet & buffers,samplepos_t start,samplecnt_t nframes,boost::shared_ptr<Processor> endpoint,bool include_endpoint,bool for_export,bool for_freeze,MidiStateTracker & tracker)498 MidiTrack::export_stuff (BufferSet&                   buffers,
499                          samplepos_t                  start,
500                          samplecnt_t                  nframes,
501                          boost::shared_ptr<Processor> endpoint,
502                          bool                         include_endpoint,
503                          bool                         for_export,
504                          bool                         for_freeze,
505                          MidiStateTracker&            tracker)
506 {
507 	if (buffers.count().n_midi() == 0) {
508 		return -1;
509 	}
510 
511 	Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
512 
513 	boost::shared_ptr<MidiPlaylist> mpl = _disk_writer->midi_playlist();
514 	if (!mpl) {
515 		return -2;
516 	}
517 
518 	buffers.get_midi(0).clear();
519 
520 	/* Can't use a note tracker here, because the note off's might be in a
521 	 * subsequent call
522 	 */
523 
524 	MidiStateTracker ignored;
525 
526 	/* XXX this doesn't fail, other than if the lock cannot be obtained */
527 	mpl->rendered()->read (buffers.get_midi(0), start, start+nframes, ignored, start);
528 
529 	MidiBuffer& buf = buffers.get_midi(0);
530 
531 	if (endpoint && !for_export) {
532 		for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
533 			MidiBuffer::TimeType *t = i.timeptr ();
534 			*t -= start;
535 		}
536 		bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
537 	}
538 
539 	/* Add to tracker so that we can resolve at the end of the export (in Session::write_one_track()) */
540 
541 	for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
542 		tracker.track (*i);
543 	}
544 
545 	return 0;
546 }
547 
548 boost::shared_ptr<Region>
bounce(InterThreadInfo & itt,std::string const & name)549 MidiTrack::bounce (InterThreadInfo& itt, std::string const& name)
550 {
551 	return bounce_range (_session.current_start_sample(), _session.current_end_sample(), itt, main_outs(), false, name);
552 }
553 
554 boost::shared_ptr<Region>
bounce_range(samplepos_t start,samplepos_t end,InterThreadInfo & itt,boost::shared_ptr<Processor> endpoint,bool include_endpoint,std::string const & name)555 MidiTrack::bounce_range (samplepos_t                  start,
556                          samplepos_t                  end,
557                          InterThreadInfo&             itt,
558                          boost::shared_ptr<Processor> endpoint,
559                          bool                         include_endpoint,
560                          std::string const&           name)
561 {
562 	vector<boost::shared_ptr<Source> > srcs;
563 	return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false, name);
564 }
565 
566 void
freeze_me(InterThreadInfo &)567 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
568 {
569 	std::cerr << "MIDI freeze currently unsupported" << std::endl;
570 }
571 
572 void
unfreeze()573 MidiTrack::unfreeze ()
574 {
575 	_freeze_record.state = UnFrozen;
576 	FreezeChange (); /* EMIT SIGNAL */
577 }
578 
579 void
set_note_mode(NoteMode m)580 MidiTrack::set_note_mode (NoteMode m)
581 {
582 	_note_mode = m;
583 	_disk_writer->set_note_mode(m);
584 }
585 
586 std::string
describe_parameter(Evoral::Parameter param)587 MidiTrack::describe_parameter (Evoral::Parameter param)
588 {
589 	const std::string str(instrument_info().get_controller_name(param));
590 	return str.empty() ? Automatable::describe_parameter(param) : str;
591 }
592 
593 void
midi_panic()594 MidiTrack::midi_panic()
595 {
596 	DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
597 	for (uint8_t channel = 0; channel <= 0xF; channel++) {
598 		uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
599 		write_immediate_event (Evoral::MIDI_EVENT, 3, ev);
600 		ev[1] = MIDI_CTL_ALL_NOTES_OFF;
601 		write_immediate_event (Evoral::MIDI_EVENT, 3, ev);
602 		ev[1] = MIDI_CTL_RESET_CONTROLLERS;
603 		write_immediate_event (Evoral::MIDI_EVENT, 3, ev);
604 	}
605 }
606 
607 /** \return true on success, false on failure (no buffer space left)
608  */
609 bool
write_immediate_event(Evoral::EventType event_type,size_t size,const uint8_t * buf)610 MidiTrack::write_immediate_event(Evoral::EventType event_type, size_t size, const uint8_t* buf)
611 {
612 	if (!Evoral::midi_event_is_valid(buf, size)) {
613 		cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
614 		return false;
615 	}
616 	return (_immediate_events.write (0, event_type, size, buf) == size);
617 }
618 
619 void
set_parameter_automation_state(Evoral::Parameter param,AutoState state)620 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
621 {
622 	switch (param.type()) {
623 	case MidiCCAutomation:
624 	case MidiPgmChangeAutomation:
625 	case MidiPitchBenderAutomation:
626 	case MidiChannelPressureAutomation:
627 	case MidiNotePressureAutomation:
628 	case MidiSystemExclusiveAutomation:
629 		/* The track control for MIDI parameters is for immediate events to act
630 		   as a control surface, write/touch for them is not currently
631 		   supported. */
632 		return;
633 	default:
634 		Automatable::set_parameter_automation_state(param, state);
635 	}
636 }
637 
638 void
restore_value()639 MidiTrack::MidiControl::restore_value ()
640 {
641 	actually_set_value (get_value(), Controllable::NoGroup);
642 }
643 
644 void
actually_set_value(double val,PBD::Controllable::GroupControlDisposition group_override)645 MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
646 {
647 	const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
648 	const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
649 
650 	bool valid = false;
651 	if (isinf_local(val)) {
652 		cerr << "MIDIControl value is infinity" << endl;
653 	} else if (isnan_local(val)) {
654 		cerr << "MIDIControl value is NaN" << endl;
655 	} else if (val < desc.lower) {
656 		cerr << "MIDIControl value is < " << desc.lower << endl;
657 	} else if (val > desc.upper) {
658 		cerr << "MIDIControl value is > " << desc.upper << endl;
659 	} else {
660 		valid = true;
661 	}
662 
663 	if (!valid) {
664 		return;
665 	}
666 
667 	assert(val <= desc.upper);
668 	if ( ! _list || ! automation_playback()) {
669 		size_t size = 3;
670 		uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
671 		switch(parameter.type()) {
672 		case MidiCCAutomation:
673 			ev[0] |= MIDI_CMD_CONTROL;
674 			ev[1] = parameter.id();
675 			ev[2] = int(val);
676 			break;
677 
678 		case MidiPgmChangeAutomation:
679 			size = 2;
680 			ev[0] |= MIDI_CMD_PGM_CHANGE;
681 			ev[1] = int(val);
682 			break;
683 
684 		case MidiChannelPressureAutomation:
685 			size = 2;
686 			ev[0] |= MIDI_CMD_CHANNEL_PRESSURE;
687 			ev[1] = int(val);
688 			break;
689 
690 		case MidiNotePressureAutomation:
691 			ev[0] |= MIDI_CMD_NOTE_PRESSURE;
692 			ev[1] = parameter.id();
693 			ev[2] = int(val);
694 			break;
695 
696 		case MidiPitchBenderAutomation:
697 			ev[0] |= MIDI_CMD_BENDER;
698 			ev[1] = 0x7F & int(val);
699 			ev[2] = 0x7F & (int(val) >> 7);
700 			break;
701 
702 		default:
703 			size = 0;
704 			assert(false);
705 		}
706 		_route->write_immediate_event(Evoral::LIVE_MIDI_EVENT, size, ev);
707 	}
708 
709 	AutomationControl::actually_set_value(val, group_override);
710 }
711 
712 void
set_step_editing(bool yn)713 MidiTrack::set_step_editing (bool yn)
714 {
715 	if (_session.record_status() != Session::Disabled) {
716 		return;
717 	}
718 
719 	if (yn != _step_editing) {
720 		_step_editing = yn;
721 		StepEditStatusChange (yn);
722 	}
723 }
724 
725 boost::shared_ptr<SMFSource>
write_source(uint32_t)726 MidiTrack::write_source (uint32_t)
727 {
728 	return _disk_writer->midi_write_source ();
729 }
730 
731 void
set_playback_channel_mode(ChannelMode mode,uint16_t mask)732 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
733 {
734 	if (_playback_filter.set_channel_mode(mode, mask)) {
735 		_session.set_dirty();
736 	}
737 }
738 
739 void
set_capture_channel_mode(ChannelMode mode,uint16_t mask)740 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
741 {
742 	if (_capture_filter.set_channel_mode(mode, mask)) {
743 		_session.set_dirty();
744 	}
745 }
746 
747 void
set_playback_channel_mask(uint16_t mask)748 MidiTrack::set_playback_channel_mask (uint16_t mask)
749 {
750 	if (_playback_filter.set_channel_mask(mask)) {
751 		_session.set_dirty();
752 	}
753 }
754 
755 void
set_capture_channel_mask(uint16_t mask)756 MidiTrack::set_capture_channel_mask (uint16_t mask)
757 {
758 	if (_capture_filter.set_channel_mask(mask)) {
759 		_session.set_dirty();
760 	}
761 }
762 
763 boost::shared_ptr<MidiPlaylist>
midi_playlist()764 MidiTrack::midi_playlist ()
765 {
766 	return boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
767 }
768 
769 bool
input_active() const770 MidiTrack::input_active () const
771 {
772 	return _input_active;
773 }
774 
775 void
set_input_active(bool yn)776 MidiTrack::set_input_active (bool yn)
777 {
778 	if (yn != _input_active) {
779 		_input_active = yn;
780 		map_input_active (yn);
781 		InputActiveChanged (); /* EMIT SIGNAL */
782 	}
783 }
784 
785 void
map_input_active(bool yn)786 MidiTrack::map_input_active (bool yn)
787 {
788 	if (!_input) {
789 		return;
790 	}
791 
792 	PortSet& ports (_input->ports());
793 
794 	for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
795 		boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
796 		if (yn != mp->input_active()) {
797 			mp->set_input_active (yn);
798 		}
799 	}
800 }
801 
802 void
track_input_active(IOChange change,void *)803 MidiTrack::track_input_active (IOChange change, void* /* src */)
804 {
805 	if (change.type & IOChange::ConfigurationChanged) {
806 		map_input_active (_input_active);
807 	}
808 }
809 
810 boost::shared_ptr<MidiBuffer>
get_gui_feed_buffer() const811 MidiTrack::get_gui_feed_buffer () const
812 {
813 	return _disk_writer->get_gui_feed_buffer ();
814 }
815 
816 void
act_on_mute()817 MidiTrack::act_on_mute ()
818 {
819 	/* this is called right after our mute status has changed.
820 	   if we are now muted, send suitable output to shutdown
821 	   all our notes.
822 
823 	   XXX we should should also stop all relevant note trackers.
824 	*/
825 
826 	/* If we haven't got a diskstream yet, there's nothing to worry about,
827 	   and we can't call get_channel_mask() anyway.
828 	*/
829 	if (!_disk_writer) {
830 		return;
831 	}
832 
833 	if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) {
834 		/* only send messages for channels we are using */
835 
836 		uint16_t mask = _playback_filter.get_channel_mask();
837 
838 		for (uint8_t channel = 0; channel <= 0xF; channel++) {
839 
840 			if ((1<<channel) & mask) {
841 
842 				DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
843 				uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
844 				write_immediate_event (Evoral::MIDI_EVENT, 3, ev);
845 
846 				/* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
847 				   silence notes that came from another non-muted track. */
848 			}
849 		}
850 
851 		/* Resolve active notes. */
852 		_disk_reader->resolve_tracker (_immediate_events, 0);
853 	}
854 }
855 
856 void
monitoring_changed(bool self,Controllable::GroupControlDisposition gcd)857 MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd)
858 {
859 	Track::monitoring_changed (self, gcd);
860 
861 	/* monitoring state changed, so flush out any on notes at the
862 	 * port level.
863 	 */
864 
865 	PortSet& ports (_output->ports());
866 
867 	for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
868 		boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
869 		if (mp) {
870 			mp->require_resolve ();
871 		}
872 	}
873 
874 	_disk_reader->reset_tracker ();
875 }
876 
877 MonitorState
monitoring_state() const878 MidiTrack::monitoring_state () const
879 {
880 	MonitorState ms = Track::monitoring_state();
881 	if (ms == MonitoringSilence) {
882 		/* MIDI always monitor input as fallback */
883 		return MonitoringInput;
884 	}
885 	return ms;
886 }
887 
888 void
filter_input(BufferSet & bufs)889 MidiTrack::filter_input (BufferSet& bufs)
890 {
891 	_capture_filter.filter (bufs);
892 }
893 
894 void
realtime_handle_transport_stopped()895 MidiTrack::realtime_handle_transport_stopped ()
896 {
897 	Route::realtime_handle_transport_stopped ();
898 	_disk_reader->resolve_tracker (_immediate_events, 0);
899 }
900 
901 void
playlist_contents_changed()902 MidiTrack::playlist_contents_changed ()
903 
904 {
905 }
906