X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fmidi_track.cc;h=64e61e79f9f6406d2af8f7ed9cef628884a87c41;hb=3dfb0c7ae9c4863cf2e92032dcaa0baf805717db;hp=1b327ae70d69c3812222fa591e5d664f8ebfc6ba;hpb=5558b3cf06b98060438d1e68c8d5d2f4a9c2f8f6;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 1b327ae70d..64e61e79f9 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -17,35 +17,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "pbd/error.h" - #include "pbd/enumwriter.h" #include "pbd/convert.h" -#include "midi++/events.h" #include "evoral/midi_util.h" -#include "ardour/amp.h" #include "ardour/buffer_set.h" #include "ardour/debug.h" #include "ardour/delivery.h" -#include "ardour/io_processor.h" #include "ardour/meter.h" #include "ardour/midi_diskstream.h" #include "ardour/midi_playlist.h" #include "ardour/midi_port.h" -#include "ardour/midi_region.h" -#include "ardour/midi_source.h" #include "ardour/midi_track.h" -#include "ardour/panner.h" #include "ardour/port.h" #include "ardour/processor.h" -#include "ardour/route_group_specialized.h" #include "ardour/session.h" #include "ardour/session_playlists.h" #include "ardour/utils.h" #include "i18n.h" +namespace ARDOUR { +class InterThreadInfo; +class MidiSource; +class Region; +class SMFSource; +} + using namespace std; using namespace ARDOUR; using namespace PBD; @@ -107,16 +105,21 @@ MidiTrack::set_record_enabled (bool yn, void *src) void MidiTrack::set_diskstream (boost::shared_ptr ds) { + /* We have to do this here, as Track::set_diskstream will cause a buffer refill, + and the diskstream must be set up to fill its buffers using the correct _note_mode. + */ + boost::shared_ptr mds = boost::dynamic_pointer_cast (ds); + mds->set_note_mode (_note_mode); + Track::set_diskstream (ds); - midi_diskstream()->reset_tracker (); + mds->reset_tracker (); _diskstream->set_track (this); _diskstream->set_destructive (_mode == Destructive); _diskstream->set_record_enabled (false); _diskstream_data_recorded_connection.disconnect (); - boost::shared_ptr mds = boost::dynamic_pointer_cast (ds); mds->DataRecorded.connect_same_thread ( _diskstream_data_recorded_connection, boost::bind (&MidiTrack::diskstream_data_recorded, this, _1)); @@ -135,6 +138,16 @@ MidiTrack::set_state (const XMLNode& node, int version) { const XMLProperty *prop; + /* This must happen before Track::set_state(), as there will be a buffer + fill during that call, and we must fill buffers using the correct + _note_mode. + */ + if ((prop = node.property (X_("note-mode"))) != 0) { + _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode)); + } else { + _note_mode = Sustained; + } + if (Track::set_state (node, version)) { return -1; } @@ -142,12 +155,6 @@ MidiTrack::set_state (const XMLNode& node, int version) // No destructive MIDI tracks (yet?) _mode = Normal; - if ((prop = node.property (X_("note-mode"))) != 0) { - _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode)); - } else { - _note_mode = Sustained; - } - if ((prop = node.property ("midi-thru")) != 0) { set_midi_thru (string_is_affirmative (prop->value())); } @@ -269,6 +276,9 @@ MidiTrack::set_state_part_two () return; } +/** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone + * or set to false. + */ int MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler) { @@ -366,7 +376,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { boost::shared_ptr d = boost::dynamic_pointer_cast (*i); if (d) { - d->flush_buffers (nframes, end_frame - start_frame - 1); + d->flush_buffers (nframes); } } @@ -475,7 +485,8 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framep } int -MidiTrack::export_stuff (BufferSet& /*bufs*/, framecnt_t /*nframes*/, framepos_t /*end_frame*/) +MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/, + boost::shared_ptr /*endpoint*/, bool /*include_endpoint*/, bool /*forexport*/) { return -1; } @@ -489,7 +500,8 @@ MidiTrack::bounce (InterThreadInfo& /*itt*/) boost::shared_ptr -MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, bool /*enable_processing*/) +MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, + boost::shared_ptr /*endpoint*/, bool /*include_endpoint*/) { std::cerr << "MIDI bounce range currently unsupported" << std::endl; return boost::shared_ptr (); @@ -520,7 +532,7 @@ MidiTrack::midi_panic() { DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name())); for (uint8_t channel = 0; channel <= 0xF; channel++) { - uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 }; + uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 }; write_immediate_event(3, ev); ev[1] = MIDI_CTL_ALL_NOTES_OFF; write_immediate_event(3, ev); @@ -546,9 +558,9 @@ void MidiTrack::MidiControl::set_value(double val) { bool valid = false; - if (isinf(val)) { + if (std::isinf(val)) { cerr << "MIDIControl value is infinity" << endl; - } else if (isnan(val)) { + } else if (std::isnan(val)) { cerr << "MIDIControl value is NaN" << endl; } else if (val < _list->parameter().min()) { cerr << "MIDIControl value is < " << _list->parameter().min() << endl; @@ -565,7 +577,7 @@ MidiTrack::MidiControl::set_value(double val) assert(val <= _list->parameter().max()); if ( ! automation_playback()) { size_t size = 3; - uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 }; + uint8_t ev[3] = { _list->parameter().channel(), uint8_t (val), 0 }; switch(_list->parameter().type()) { case MidiCCAutomation: ev[0] += MIDI_CMD_CONTROL; @@ -728,7 +740,7 @@ MidiTrack::act_on_mute () if ((1<reset_tracker (); } } + +MonitorState +MidiTrack::monitoring_state () const +{ + /* Explicit requests */ + + if (_monitoring & MonitorInput) { + return MonitoringInput; + } + + if (_monitoring & MonitorDisk) { + return MonitoringDisk; + } + + if (_session.transport_rolling()) { + return MonitoringDisk; + } + + /* the return value here doesn't mean that we're actually monitoring + * input, let alone input *audio*. but it means that we are NOT + * monitoring silence. this allows us to still hear any audio generated + * by using internal generation techniques + */ + + return MonitoringInput; +}