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
This commit is contained in:
Paul Davis 2010-06-24 01:37:24 +00:00
parent d8e93be2ee
commit fe229a830e
12 changed files with 118 additions and 65 deletions

View 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;

View 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);

View 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);

View File

@ -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;

View 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);

View 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;

View 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*/)
{

View 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 */
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;
srcs.push_back (_write_source);
_write_source->set_timeline_position (capture_info.front()->start);
_write_source->set_captured_for (_name);
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);
string whole_file_region_name;
whole_file_region_name = region_name_from_path (_write_source->name(), true);
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
/* 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);
}
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? */
}
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());
_last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
_playlist->clear_history ();
_playlist->freeze ();
_playlist->clear_history ();
_playlist->freeze ();
uint32_t buffer_position = 0;
for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
uint32_t buffer_position = 0;
for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
string region_name;
string region_name;
RegionFactory::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";
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
try {
PropertyList plist;
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? */
}
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;
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
i_am_the_modifier++;
_playlist->add_region (region, (*ci)->start);
i_am_the_modifier--;
i_am_the_modifier++;
_playlist->add_region (region, (*ci)->start);
i_am_the_modifier--;
buffer_position += (*ci)->frames;
}
_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*/)
{

View 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);

View 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();
}

View 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)
{

View 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;
}