GUI-created MIDI regions now steal the pending MIDISource from the track's diskstream...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 24 Jun 2010 01:37:24 +0000 (01:37 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 24 Jun 2010 01:37:24 +0000 (01:37 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7295 d708f5d6-7413-0410-9779-e7cbd77b26cf

12 files changed:
gtk2_ardour/midi_time_axis.cc
libs/ardour/ardour/audio_diskstream.h
libs/ardour/ardour/midi_diskstream.h
libs/ardour/ardour/public_diskstream.h
libs/ardour/ardour/session.h
libs/ardour/ardour/track.h
libs/ardour/audio_diskstream.cc
libs/ardour/midi_diskstream.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/track.cc
libs/pbd/undo.cc

index e193f6d4253af55e422bdc6145a73f14ee1fe450..9479d2aeb88fc1192494d24c754809426374ccda 100644 (file)
@@ -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<Source> src = _session->create_midi_source_for_session (view()->trackview().track()->name());
+       boost::shared_ptr<Source> src = _session->create_midi_source_for_session (view()->trackview().track().get(),
+                                                                                  view()->trackview().track()->name());
 
        PropertyList plist; 
        
index 54ddbea14a516dc6419e57273b1d3156c0390d03..7b7cdd7e3f262b8560db50e8fe9f6ce576a9284e 100644 (file)
@@ -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<boost::shared_ptr<Source> > steal_write_sources();
        void reset_write_sources (bool, bool force = false);
        void non_realtime_input_change ();
        void non_realtime_locate (nframes_t location);
index f46688902738f7230a11a856eab616069f05ab34..69c762823b09ab9a10a8be546b08c407c7dc0dff 100644 (file)
@@ -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<boost::shared_ptr<Source> > steal_write_sources();
        void reset_write_sources (bool, bool force = false);
        void non_realtime_input_change ();
        void non_realtime_locate (nframes_t location);
index 9e25cb24c6d958cb3f31cd11e0ce6bb7425bac22..a33c43f0cdc339099692091df21766d3029e4e33 100755 (executable)
@@ -36,6 +36,7 @@ public:
        virtual bool destructive () const = 0;
        virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
        virtual void set_capture_offset () = 0;
+       virtual std::list<boost::shared_ptr<Source> > 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;
index bca65c88e4453a3cca100615804fa2b5ba88013a..8109dc08b94668f611ae647171ccfaf46793b448 100644 (file)
@@ -533,7 +533,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t, bool);
 
-       boost::shared_ptr<MidiSource> create_midi_source_for_session (std::string const &);
+       boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &);
 
        boost::shared_ptr<Source> source_by_id (const PBD::ID&);
        boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
index d72d29e563f9253020e3e1e4fd6ad42f733d40d8..60e628af79c21e69caeb2bd9d8fab08f62ef7ebb 100644 (file)
@@ -103,6 +103,7 @@ class Track : public Route, public PublicDiskstream
        bool destructive () const;
        std::list<boost::shared_ptr<Source> > & last_capture_sources ();
        void set_capture_offset ();
+        std::list<boost::shared_ptr<Source> > steal_write_sources();
        void reset_write_sources (bool, bool force = false);
        float playback_buffer_load () const;
        float capture_buffer_load () const;
index ae80690b8107f8d371c384b07f8c37c38b5739e5..d3e19dac919ab28a2445f26b00d2fc4665816e12 100644 (file)
@@ -1902,6 +1902,14 @@ AudioDiskstream::use_new_write_source (uint32_t n)
        return 0;
 }
 
+list<boost::shared_ptr<Source> > 
+AudioDiskstream::steal_write_sources()
+{
+        /* not possible to steal audio write sources */
+        list<boost::shared_ptr<Source> > ret;
+        return ret;
+}
+
 void
 AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
 {
index 444e4d378889530072baa9b84042f5bb23d83dde..f9ece16aec40478e3f7e95811f80ae6666f59bde 100644 (file)
@@ -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<Region> rx (RegionFactory::create (srcs, plist));
-
-                       region = boost::dynamic_pointer_cast<MidiRegion> (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<Region> rx (RegionFactory::create (srcs, plist));
+
+                                region = boost::dynamic_pointer_cast<MidiRegion> (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<Region> rx (RegionFactory::create (srcs, plist));
-                               region = boost::dynamic_pointer_cast<MidiRegion> (rx);
-                       }
+                                        boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
+                                        region = boost::dynamic_pointer_cast<MidiRegion> (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<SMFSource>(_session.create_midi_source_for_session (name ()));
+               _write_source = boost::dynamic_pointer_cast<SMFSource>(_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<boost::shared_ptr<Source> > 
+MidiDiskstream::steal_write_sources()
+{
+        list<boost::shared_ptr<Source> > ret;
+        ret.push_back (_write_source);
+        reset_write_sources (false);
+        return ret;
+}
+
 void
 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
 {
index 91b1e2a0f95465e1e7c2a8087b199add54fd4b11..94945b95c27f9457839bdfdfde4b0cb4d0788b1e 100644 (file)
@@ -1456,7 +1456,7 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m
                }
 
                shared_ptr<MidiTrack> 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<MidiSource>
-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*> (track);
+                assert (mt);
+                */
+
+                list<boost::shared_ptr<Source> > l = track->steal_write_sources ();
+                
+                if (!l.empty()) {
+                        assert (boost::dynamic_pointer_cast<MidiSource> (l.front()));
+                        return boost::dynamic_pointer_cast<MidiSource> (l.front());
+                }
+        }
+
        const string name = new_midi_source_name (n);
        const string path = new_source_path_from_name (DataType::MIDI, name);
 
index bcb4f3094f0b719eb60d911f09d26d706d12a7eb..f26933d8757ed364a4fcfade1e07b6aa7edeacd2 100644 (file)
@@ -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();
 }
index b2079e0a2e3cc0a7134ed9fe4a20aca07ff34327..23afe6dea2ab5fdb5e9b58ff48ffe412ece6c58a 100644 (file)
@@ -437,6 +437,12 @@ Track::set_capture_offset ()
        _diskstream->set_capture_offset ();
 }
 
+list<boost::shared_ptr<Source> > 
+Track::steal_write_sources()
+{
+        return _diskstream->steal_write_sources ();
+}
+
 void
 Track::reset_write_sources (bool r, bool force)
 {
index 120f62c3512c78d263ae48a3aa6e9990b6eea30b..71a5d1e2637aa71da846fe30b9d21486419f2278 100644 (file)
@@ -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;
        }