X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_diskstream.cc;h=fa2cdce0140e8664149e8a0fea55cf94785d0414;hb=932d6c79d01be93f491415ef1491bca17d92671f;hp=ccfaeaa5cd305ad98af39cae1d11de47a5f8200d;hpb=650c6d5824222a8879df5c5ba9645c264ed3b84f;p=ardour.git diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index ccfaeaa5cd..fa2cdce014 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -35,6 +35,7 @@ #include "pbd/xml++.h" #include "pbd/memento_command.h" #include "pbd/enumwriter.h" +#include "pbd/stateful_diff_command.h" #include "ardour/ardour.h" #include "ardour/audioengine.h" @@ -54,6 +55,7 @@ #include "ardour/smf_source.h" #include "ardour/utils.h" #include "ardour/session_playlists.h" +#include "ardour/route.h" #include "midi++/types.h" @@ -80,7 +82,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F in_set_state = true; - init(flag); + init (); use_new_playlist (); in_set_state = false; @@ -99,7 +101,7 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node) , _frames_read_from_ringbuffer(0) { in_set_state = true; - init (Recordable); + init (); if (set_state (node, Stateful::loading_state_version)) { in_set_state = false; @@ -114,10 +116,8 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node) } void -MidiDiskstream::init (Diskstream::Flag f) +MidiDiskstream::init () { - Diskstream::init(f); - /* there are no channels at this point, so these two calls just get speed_buffer_size and wrap_buffer size setup without duplicating their code. @@ -373,7 +373,7 @@ trace_midi (ostream& o, MIDI::byte *msg, size_t len) o << trace_prefix << "Channel " << (msg[0]&0xF)+1 - << " Program PropertyChange ProgNum " + << " Program Change ProgNum " << (int) msg[1] << endl; break; @@ -486,7 +486,7 @@ trace_midi (ostream& o, MIDI::byte *msg, size_t len) #endif int -MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input) +MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler) { int ret = -1; nframes_t rec_offset = 0; @@ -494,39 +494,22 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_ bool nominally_recording; bool re = record_enabled (); - /* if we've already processed the frames corresponding to this call, - just return. this allows multiple routes that are taking input - from this diskstream to call our ::process() method, but have - this stuff only happen once. more commonly, it allows both - the AudioTrack that is using this AudioDiskstream *and* the Session - to call process() without problems. - */ - - if (_processed) { - return 0; - } - - commit_should_unlock = false; + playback_distance = 0; check_record_status (transport_frame, nframes, can_record); nominally_recording = (can_record && re); if (nframes == 0) { - _processed = true; return 0; } - /* This lock is held until the end of ::commit, so these two functions - must always be called as a pair. The only exception is if this function - returns a non-zero value, in which case, ::commit should not be called. - */ + Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK); - // If we can't take the state lock return. - if (!state_lock.trylock()) { + if (!sm.locked()) { return 1; } - commit_should_unlock = true; + adjust_capture_position = 0; if (nominally_recording || (_session.get_record_enabled() && _session.config.get_punch_in())) { @@ -585,17 +568,9 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_ ret = 0; - _processed = true; - - if (ret) { - - /* we're exiting with failure, so ::commit will not - be called. unlock the state lock. - */ - - commit_should_unlock = false; - state_lock.unlock(); - } + if (commit (nframes)) { + need_butler = true; + } return ret; } @@ -626,12 +601,6 @@ MidiDiskstream::commit (nframes_t nframes) " = " << frames_written - frames_read << " + " << nframes << " < " << midi_readahead << " = " << need_butler << ")" << endl;*/ - if (commit_should_unlock) { - state_lock.unlock(); - } - - _processed = false; - return need_butler; } @@ -640,7 +609,7 @@ MidiDiskstream::set_pending_overwrite (bool yn) { /* called from audio thread, so we can use the read ptr and playback sample as we wish */ - pending_overwrite = yn; + _pending_overwrite = yn; overwrite_frame = playback_sample; } @@ -650,7 +619,7 @@ MidiDiskstream::overwrite_existing_buffers () { //read(overwrite_frame, disk_io_chunk_frames, false); overwrite_queued = false; - pending_overwrite = false; + _pending_overwrite = false; return 0; } @@ -914,7 +883,7 @@ out: } void -MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture) +MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture) { bool more_work = true; int err = 0; @@ -955,7 +924,6 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a if (_write_source) { _write_source->mark_for_remove (); - _write_source->drop_references (); _write_source.reset(); } @@ -1011,7 +979,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n"; - XMLNode &before = _playlist->get_state(); + _playlist->clear_history (); _playlist->freeze (); uint32_t buffer_position = 0; @@ -1019,7 +987,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a string region_name; - _session.region_name (region_name, _write_source->name(), false); + RegionFactory::region_name (region_name, _write_source->name(), false); // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n"; @@ -1053,8 +1021,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a } _playlist->thaw (); - XMLNode &after = _playlist->get_state(); - _session.add_command (new MementoCommand(*_playlist, &before, &after)); + _session.add_command (new StatefulDiffCommand(_playlist)); } @@ -1193,7 +1160,7 @@ MidiDiskstream::disengage_record_enable () XMLNode& MidiDiskstream::get_state () { - XMLNode* node = new XMLNode ("MidiDiskstream"); + XMLNode* node = new XMLNode ("Diskstream"); char buf[64]; LocaleGuard lg (X_("POSIX")); @@ -1309,7 +1276,7 @@ MidiDiskstream::set_state (const XMLNode& node, int /*version*/) } if (!had_playlist) { - _playlist->set_orig_diskstream_id (_id); + _playlist->set_orig_diskstream_id (id()); } if (capture_pending_node) { @@ -1354,7 +1321,12 @@ MidiDiskstream::use_new_write_source (uint32_t n) if (_write_source) { if (_write_source->is_empty ()) { + /* remove any region that is using this empty source; they can result when MIDI recordings + are made, but no MIDI data is received. + */ + _playlist->remove_region_by_source (_write_source); _write_source->mark_for_remove (); + _write_source->drop_references (); _write_source.reset(); } else { _write_source.reset(); @@ -1362,7 +1334,7 @@ MidiDiskstream::use_new_write_source (uint32_t n) } try { - _write_source = boost::dynamic_pointer_cast(_session.create_midi_source_for_session (*this)); + _write_source = boost::dynamic_pointer_cast(_session.create_midi_source_for_session (name ())); if (!_write_source) { throw failed_constructor(); }