X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_track.cc;h=745fa75688104116ace649ad74cca3baa02f3cda;hb=8f59346592b8232e910ce0bbdc247cf8cecde4dd;hp=6b27d1b0099e700f623a1863a39fbc2871b65d73;hpb=af8c16cfe0ccfd6d4611159ba0956e98d0f08e5c;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 6b27d1b009..745fa75688 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -17,11 +17,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "pbd/error.h" -#include -#include -#include #include "pbd/enumwriter.h" +#include "pbd/convert.h" #include "midi++/events.h" #include "evoral/midi_util.h" @@ -41,6 +39,7 @@ #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" @@ -58,24 +57,6 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo , _default_channel (0) , _midi_thru (true) { - use_new_diskstream (); - - _declickable = true; - _freeze_record.state = NoFreeze; - _saved_meter_point = _meter_point; - _mode = mode; -} - -MidiTrack::MidiTrack (Session& sess, const XMLNode& node, int version) - : Track (sess, node, DataType::MIDI) - , _immediate_events(1024) // FIXME: size? - , _step_edit_ring_buffer(64) // FIXME: size? - , _note_mode(Sustained) - , _step_editing (false) - , _default_channel (0) - , _midi_thru (true) -{ - _set_state (node, Stateful::loading_state_version, false); } MidiTrack::~MidiTrack () @@ -96,56 +77,24 @@ MidiTrack::use_new_diskstream () assert(_mode != Destructive); boost::shared_ptr ds (new MidiDiskstream (_session, name(), dflags)); - _session.add_diskstream (ds); + ds->do_refill_with_alloc (); + ds->set_block_size (_session.get_block_size ()); - set_diskstream (boost::dynamic_pointer_cast (ds)); + set_diskstream (ds); } -int -MidiTrack::set_diskstream (boost::shared_ptr ds) +void +MidiTrack::set_diskstream (boost::shared_ptr ds) { - _diskstream = ds; - _diskstream->set_route (*this); + Track::set_diskstream (ds); + + _diskstream->set_track (this); _diskstream->set_destructive (_mode == Destructive); _diskstream->set_record_enabled (false); //_diskstream->monitor_input (false); - ic_connection.disconnect(); - ic_connection = _input->changed.connect (mem_fun (*_diskstream, &MidiDiskstream::handle_input_change)); - DiskstreamChanged (); /* EMIT SIGNAL */ - - return 0; -} - -int -MidiTrack::use_diskstream (string name) -{ - boost::shared_ptr dstream; - - cerr << "\n\n\nMIDI use diskstream\n"; - - if ((dstream = boost::dynamic_pointer_cast(_session.diskstream_by_name (name))) == 0) { - error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), name) << endmsg; - return -1; - } - - cerr << "\n\n\nMIDI found DS\n"; - return set_diskstream (dstream); -} - -int -MidiTrack::use_diskstream (const PBD::ID& id) -{ - boost::shared_ptr dstream; - - if ((dstream = boost::dynamic_pointer_cast (_session.diskstream_by_id (id))) == 0) { - error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), id) << endmsg; - return -1; - } - - return set_diskstream (dstream); } boost::shared_ptr @@ -187,42 +136,6 @@ MidiTrack::_set_state (const XMLNode& node, int version, bool call_base) set_default_channel ((uint8_t) atoi (prop->value())); } - if ((prop = node.property ("diskstream-id")) == 0) { - - /* some old sessions use the diskstream name rather than the ID */ - - if ((prop = node.property ("diskstream")) == 0) { - fatal << _("programming error: MidiTrack given state without diskstream!") << endmsg; - /*NOTREACHED*/ - return -1; - } - - if (use_diskstream (prop->value())) { - return -1; - } - - } else { - - PBD::ID id (prop->value()); - PBD::ID zero ("0"); - - /* this wierd hack is used when creating tracks from a template. there isn't - a particularly good time to interpose between setting the first part of - the track state (notably Route::set_state() and the track mode), and the - second part (diskstream stuff). So, we have a special ID for the diskstream - that means "you should create a new diskstream here, not look for - an old one. - */ - - cerr << "\n\n\n\n MIDI track " << name() << " found DS id " << id << endl; - - if (id == zero) { - use_new_diskstream (); - } else if (use_diskstream (id)) { - return -1; - } - } - XMLNodeList nlist; XMLNodeConstIterator niter; XMLNode *child; @@ -237,10 +150,18 @@ MidiTrack::_set_state (const XMLNode& node, int version, bool call_base) } } + if (version >= 3000) { + if ((child = find_named_node (node, X_("Diskstream"))) != 0) { + boost::shared_ptr ds (new MidiDiskstream (_session, *child)); + ds->do_refill_with_alloc (); + set_diskstream (ds); + } + } + pending_state = const_cast (&node); if (_session.state_of_the_state() & Session::Loading) { - _session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two)); + _session.StateReady.connect_same_thread (*this, boost::bind (&MidiTrack::set_state_part_two, this)); } else { set_state_part_two (); } @@ -274,25 +195,9 @@ MidiTrack::state(bool full_state) root.add_child_nocopy (*freeze_node); } - /* Alignment: act as a proxy for the diskstream */ - - XMLNode* align_node = new XMLNode (X_("Alignment")); - AlignStyle as = _diskstream->alignment_style (); - align_node->add_property (X_("style"), enum_2_string (as)); - root.add_child_nocopy (*align_node); - root.add_property (X_("note-mode"), enum_2_string (_note_mode)); - - /* we don't return diskstream state because we don't - own the diskstream exclusively. control of the diskstream - state is ceded to the Session, even if we create the - diskstream. - */ - - _diskstream->id().print (buf, sizeof(buf)); - root.add_property ("diskstream-id", buf); - root.add_child_nocopy (_rec_enable_control->get_state()); + root.add_child_nocopy (_diskstream->get_state ()); root.add_property ("step-editing", (_step_editing ? "yes" : "no")); root.add_property ("note-mode", enum_2_string (_note_mode)); @@ -328,7 +233,7 @@ MidiTrack::set_state_part_two () _freeze_record.processor_info.clear (); if ((prop = fnode->property (X_("playlist"))) != 0) { - boost::shared_ptr pl = _session.playlist_by_name (prop->value()); + boost::shared_ptr pl = _session.playlists->by_name (prop->value()); if (pl) { _freeze_record.playlist = boost::dynamic_pointer_cast (pl); } else { @@ -361,34 +266,19 @@ MidiTrack::set_state_part_two () } } - /* Alignment: act as a proxy for the diskstream */ - - if ((fnode = find_named_node (*pending_state, X_("Alignment"))) != 0) { - - if ((prop = fnode->property (X_("style"))) != 0) { - - /* fix for older sessions from before EnumWriter */ - - string pstr; - - if (prop->value() == "capture") { - pstr = "CaptureTime"; - } else if (prop->value() == "existing") { - pstr = "ExistingMaterial"; - } else { - pstr = prop->value(); - } - - AlignStyle as = AlignStyle (string_2_enum (pstr, as)); - _diskstream->set_persistent_align_style (as); - } + if ((fnode = find_named_node (*pending_state, X_("Diskstream"))) != 0) { + boost::shared_ptr ds (new MidiDiskstream (_session, *fnode)); + ds->do_refill_with_alloc (); + ds->set_block_size (_session.get_block_size ()); + set_diskstream (ds); } + return; } int -MidiTrack::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, int declick, - bool can_record, bool rec_monitors_input) +MidiTrack::roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, + bool can_record, bool rec_monitors_input, bool& needs_butler) { int dret; boost::shared_ptr diskstream = midi_diskstream(); @@ -419,12 +309,12 @@ MidiTrack::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, playback distance to zero, thus causing diskstream::commit to do nothing. */ - return diskstream->process (transport_frame, 0, can_record, rec_monitors_input); + return diskstream->process (transport_frame, 0, can_record, rec_monitors_input, needs_butler); } _silent = false; - if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input)) != 0) { + if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input, needs_butler)) != 0) { silence (nframes); return dret; } @@ -481,7 +371,7 @@ MidiTrack::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_fram { int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing, can_record, rec_monitors_input); - if (ret == 0 && diskstream()->record_enabled() && _step_editing) { + if (ret == 0 && _diskstream->record_enabled() && _step_editing) { push_midi_input_to_step_edit_ringbuffer (nframes); } @@ -527,7 +417,7 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, sframes_t /*start*/, sframes _immediate_events.read (buf, 0, 0, nframes - 1); // all stamps = 0 // MIDI thru: send incoming data "through" output - if (_midi_thru && _input->n_ports().n_midi()) { + if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) { buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes)); } } @@ -565,7 +455,7 @@ MidiTrack::bounce_range (nframes_t /*start*/, nframes_t /*end*/, InterThreadInfo } void -MidiTrack::freeze (InterThreadInfo& /*itt*/) +MidiTrack::freeze_me (InterThreadInfo& /*itt*/) { } @@ -630,9 +520,8 @@ MidiTrack::MidiControl::set_value(float val) } assert(val <= _list->parameter().max()); - size_t size = 3; - if ( ! automation_playback()) { + size_t size = 3; uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 }; switch(_list->parameter().type()) { case MidiCCAutomation: @@ -685,3 +574,33 @@ MidiTrack::set_midi_thru (bool yn) { _midi_thru = yn; } + +boost::shared_ptr +MidiTrack::write_source (uint32_t n) +{ + return midi_diskstream()->write_source (); +} + +void +MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask) +{ + midi_diskstream()->set_channel_mode (mode, mask); +} + +ChannelMode +MidiTrack::get_channel_mode () +{ + return midi_diskstream()->get_channel_mode (); +} + +uint16_t +MidiTrack::get_channel_mask () +{ + return midi_diskstream()->get_channel_mask (); +} + +boost::shared_ptr +MidiTrack::midi_playlist () +{ + return midi_diskstream()->midi_playlist (); +}