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:
parent
d8e93be2ee
commit
fe229a830e
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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*/)
|
||||
{
|
||||
|
@ -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*/)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user