From: Paul Davis Date: Thu, 24 Jun 2010 01:37:24 +0000 (+0000) Subject: GUI-created MIDI regions now steal the pending MIDISource from the track's diskstream... X-Git-Tag: 3.0-alpha5~1921 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=fe229a830e0164e56d3aceaf3d539e4148f322a6;p=ardour.git GUI-created MIDI regions now steal the pending MIDISource from the track's diskstream, to keep numbering sane; don't create any new MIDI regions if capture collected no data (fixes a crash in my previous commit, and is just logically much more sensible git-svn-id: svn://localhost/ardour2/branches/3.0@7295 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index e193f6d425..9479d2aeb8 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -959,7 +959,8 @@ MidiTimeAxisView::add_region (nframes64_t pos) const Tempo& t = _session->tempo_map().tempo_at(start); double length = floor (m.frames_per_bar(t, _session->frame_rate())); - boost::shared_ptr src = _session->create_midi_source_for_session (view()->trackview().track()->name()); + boost::shared_ptr src = _session->create_midi_source_for_session (view()->trackview().track().get(), + view()->trackview().track()->name()); PropertyList plist; diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 54ddbea14a..7b7cdd7e3f 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -165,6 +165,7 @@ class AudioDiskstream : public Diskstream int internal_playback_seek (nframes_t distance); int can_internal_playback_seek (nframes_t distance); int rename_write_sources (); + std::list > steal_write_sources(); void reset_write_sources (bool, bool force = false); void non_realtime_input_change (); void non_realtime_locate (nframes_t location); diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index f466889027..69c762823b 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -122,6 +122,7 @@ class MidiDiskstream : public Diskstream int internal_playback_seek (nframes_t distance); int can_internal_playback_seek (nframes_t distance); int rename_write_sources (); + std::list > steal_write_sources(); void reset_write_sources (bool, bool force = false); void non_realtime_input_change (); void non_realtime_locate (nframes_t location); diff --git a/libs/ardour/ardour/public_diskstream.h b/libs/ardour/ardour/public_diskstream.h index 9e25cb24c6..a33c43f0cd 100755 --- a/libs/ardour/ardour/public_diskstream.h +++ b/libs/ardour/ardour/public_diskstream.h @@ -36,6 +36,7 @@ public: virtual bool destructive () const = 0; virtual std::list > & last_capture_sources () = 0; virtual void set_capture_offset () = 0; + virtual std::list > steal_write_sources () = 0; virtual void reset_write_sources (bool, bool force = false) = 0; virtual float playback_buffer_load () const = 0; virtual float capture_buffer_load () const = 0; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index bca65c88e4..8109dc08b9 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -533,7 +533,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr create_audio_source_for_session (size_t, std::string const &, uint32_t, bool); - boost::shared_ptr create_midi_source_for_session (std::string const &); + boost::shared_ptr create_midi_source_for_session (Track*, std::string const &); boost::shared_ptr source_by_id (const PBD::ID&); boost::shared_ptr source_by_path_and_channel (const Glib::ustring&, uint16_t); diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index d72d29e563..60e628af79 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -103,6 +103,7 @@ class Track : public Route, public PublicDiskstream bool destructive () const; std::list > & last_capture_sources (); void set_capture_offset (); + std::list > steal_write_sources(); void reset_write_sources (bool, bool force = false); float playback_buffer_load () const; float capture_buffer_load () const; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index ae80690b81..d3e19dac91 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -1902,6 +1902,14 @@ AudioDiskstream::use_new_write_source (uint32_t n) return 0; } +list > +AudioDiskstream::steal_write_sources() +{ + /* not possible to steal audio write sources */ + list > ret; + return ret; +} + void AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/) { diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 444e4d3788..f9ece16aec 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -938,85 +938,89 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen total_capture += (*ci)->frames; } - /* figure out the name for this take */ - - srcs.push_back (_write_source); - _write_source->set_timeline_position (capture_info.front()->start); - _write_source->set_captured_for (_name); - - string whole_file_region_name; - whole_file_region_name = region_name_from_path (_write_source->name(), true); - - /* Register a new region with the Session that - describes the entire source. Do this first - so that any sub-regions will obviously be - children of this one (later!) - */ - - try { - PropertyList plist; - - plist.add (Properties::name, whole_file_region_name); - plist.add (Properties::whole_file, true); - plist.add (Properties::automatic, true); - plist.add (Properties::start, 0); - plist.add (Properties::length, total_capture); - plist.add (Properties::layer, 0); - - boost::shared_ptr rx (RegionFactory::create (srcs, plist)); - - region = boost::dynamic_pointer_cast (rx); - region->special_set_position (capture_info.front()->start); - } - - - catch (failed_constructor& err) { - error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg; - /* XXX what now? */ - } - - _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end()); - - _playlist->clear_history (); - _playlist->freeze (); - - uint32_t buffer_position = 0; - for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - - string region_name; - - RegionFactory::region_name (region_name, _write_source->name(), false); - - // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n"; - - try { - PropertyList plist; + if (_write_source->length (capture_info.front()->start) != 0) { + + /* phew, we have data */ + + /* figure out the name for this take */ + + srcs.push_back (_write_source); + _write_source->set_timeline_position (capture_info.front()->start); + _write_source->set_captured_for (_name); + + string whole_file_region_name; + whole_file_region_name = region_name_from_path (_write_source->name(), true); + + /* Register a new region with the Session that + describes the entire source. Do this first + so that any sub-regions will obviously be + children of this one (later!) + */ + + try { + PropertyList plist; + + plist.add (Properties::name, whole_file_region_name); + plist.add (Properties::whole_file, true); + plist.add (Properties::automatic, true); + plist.add (Properties::start, 0); + plist.add (Properties::length, total_capture); + plist.add (Properties::layer, 0); + + boost::shared_ptr rx (RegionFactory::create (srcs, plist)); + + region = boost::dynamic_pointer_cast (rx); + region->special_set_position (capture_info.front()->start); + } + + + catch (failed_constructor& err) { + error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg; + /* XXX what now? */ + } + + _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end()); + + _playlist->clear_history (); + _playlist->freeze (); + + uint32_t buffer_position = 0; + for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) { + + string region_name; + + RegionFactory::region_name (region_name, _write_source->name(), false); + + // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n"; + + try { + PropertyList plist; - plist.add (Properties::start, buffer_position); - plist.add (Properties::length, (*ci)->frames); - plist.add (Properties::name, region_name); + plist.add (Properties::start, buffer_position); + plist.add (Properties::length, (*ci)->frames); + plist.add (Properties::name, region_name); - boost::shared_ptr rx (RegionFactory::create (srcs, plist)); - region = boost::dynamic_pointer_cast (rx); - } + boost::shared_ptr rx (RegionFactory::create (srcs, plist)); + region = boost::dynamic_pointer_cast (rx); + } - catch (failed_constructor& err) { - error << _("MidiDiskstream: could not create region for captured midi!") << endmsg; - continue; /* XXX is this OK? */ - } - - // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; + catch (failed_constructor& err) { + error << _("MidiDiskstream: could not create region for captured midi!") << endmsg; + continue; /* XXX is this OK? */ + } - i_am_the_modifier++; - _playlist->add_region (region, (*ci)->start); - i_am_the_modifier--; + // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; - buffer_position += (*ci)->frames; - } + i_am_the_modifier++; + _playlist->add_region (region, (*ci)->start); + i_am_the_modifier--; - _playlist->thaw (); - _session.add_command (new StatefulDiffCommand(_playlist)); + buffer_position += (*ci)->frames; + } + _playlist->thaw (); + _session.add_command (new StatefulDiffCommand(_playlist)); + } } mark_write_completed = true; @@ -1330,7 +1334,7 @@ MidiDiskstream::use_new_write_source (uint32_t n) } try { - _write_source = boost::dynamic_pointer_cast(_session.create_midi_source_for_session (name ())); + _write_source = boost::dynamic_pointer_cast(_session.create_midi_source_for_session (0, name ())); if (!_write_source) { throw failed_constructor(); } @@ -1348,6 +1352,15 @@ MidiDiskstream::use_new_write_source (uint32_t n) return 0; } +list > +MidiDiskstream::steal_write_sources() +{ + list > ret; + ret.push_back (_write_source); + reset_write_sources (false); + return ret; +} + void MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 91b1e2a0f9..94945b95c2 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1456,7 +1456,7 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m } shared_ptr track; - + try { MidiTrack* mt = new MidiTrack (*this, track_name, Route::Flag (0), mode); @@ -2948,8 +2948,24 @@ Session::new_midi_source_name (const string& base) /** Create a new within-session MIDI source */ boost::shared_ptr -Session::create_midi_source_for_session (string const & n) +Session::create_midi_source_for_session (Track* track, string const & n) { + /* try to use the existing write source for the track, to keep numbering sane + */ + + if (track) { + /*MidiTrack* mt = dynamic_cast (track); + assert (mt); + */ + + list > l = track->steal_write_sources (); + + if (!l.empty()) { + assert (boost::dynamic_pointer_cast (l.front())); + return boost::dynamic_pointer_cast (l.front()); + } + } + const string name = new_midi_source_name (n); const string path = new_source_path_from_name (DataType::MIDI, name); diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index bcb4f3094f..f26933d875 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2333,6 +2333,8 @@ Session::commit_reversible_command(Command *cmd) gettimeofday(&now, 0); _current_trans.top()->set_timestamp(now); + cerr << "add cmd @ " << _current_trans.top() << " to history\n"; + _history.add(_current_trans.top()); _current_trans.pop(); } diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index b2079e0a2e..23afe6dea2 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -437,6 +437,12 @@ Track::set_capture_offset () _diskstream->set_capture_offset (); } +list > +Track::steal_write_sources() +{ + return _diskstream->steal_write_sources (); +} + void Track::reset_write_sources (bool r, bool force) { diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index 120f62c351..71a5d1e263 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -47,6 +47,7 @@ UndoTransaction::UndoTransaction (const UndoTransaction& rhs) UndoTransaction::~UndoTransaction () { + cerr << "UndoTransaction destroyed\n"; drop_references (); clear (); } @@ -54,6 +55,8 @@ UndoTransaction::~UndoTransaction () void command_death (UndoTransaction* ut, Command* c) { + cerr << "Command drop ref\n"; + if (ut->clearing()) { return; }