mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
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
12 changed files with 118 additions and 65 deletions
|
|
@ -959,7 +959,8 @@ MidiTimeAxisView::add_region (nframes64_t pos)
|
||||||
const Tempo& t = _session->tempo_map().tempo_at(start);
|
const Tempo& t = _session->tempo_map().tempo_at(start);
|
||||||
double length = floor (m.frames_per_bar(t, _session->frame_rate()));
|
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;
|
PropertyList plist;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ class AudioDiskstream : public Diskstream
|
||||||
int internal_playback_seek (nframes_t distance);
|
int internal_playback_seek (nframes_t distance);
|
||||||
int can_internal_playback_seek (nframes_t distance);
|
int can_internal_playback_seek (nframes_t distance);
|
||||||
int rename_write_sources ();
|
int rename_write_sources ();
|
||||||
|
std::list<boost::shared_ptr<Source> > steal_write_sources();
|
||||||
void reset_write_sources (bool, bool force = false);
|
void reset_write_sources (bool, bool force = false);
|
||||||
void non_realtime_input_change ();
|
void non_realtime_input_change ();
|
||||||
void non_realtime_locate (nframes_t location);
|
void non_realtime_locate (nframes_t location);
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ class MidiDiskstream : public Diskstream
|
||||||
int internal_playback_seek (nframes_t distance);
|
int internal_playback_seek (nframes_t distance);
|
||||||
int can_internal_playback_seek (nframes_t distance);
|
int can_internal_playback_seek (nframes_t distance);
|
||||||
int rename_write_sources ();
|
int rename_write_sources ();
|
||||||
|
std::list<boost::shared_ptr<Source> > steal_write_sources();
|
||||||
void reset_write_sources (bool, bool force = false);
|
void reset_write_sources (bool, bool force = false);
|
||||||
void non_realtime_input_change ();
|
void non_realtime_input_change ();
|
||||||
void non_realtime_locate (nframes_t location);
|
void non_realtime_locate (nframes_t location);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public:
|
||||||
virtual bool destructive () const = 0;
|
virtual bool destructive () const = 0;
|
||||||
virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
|
virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
|
||||||
virtual void set_capture_offset () = 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 void reset_write_sources (bool, bool force = false) = 0;
|
||||||
virtual float playback_buffer_load () const = 0;
|
virtual float playback_buffer_load () const = 0;
|
||||||
virtual float capture_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<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_id (const PBD::ID&);
|
||||||
boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
|
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;
|
bool destructive () const;
|
||||||
std::list<boost::shared_ptr<Source> > & last_capture_sources ();
|
std::list<boost::shared_ptr<Source> > & last_capture_sources ();
|
||||||
void set_capture_offset ();
|
void set_capture_offset ();
|
||||||
|
std::list<boost::shared_ptr<Source> > steal_write_sources();
|
||||||
void reset_write_sources (bool, bool force = false);
|
void reset_write_sources (bool, bool force = false);
|
||||||
float playback_buffer_load () const;
|
float playback_buffer_load () const;
|
||||||
float capture_buffer_load () const;
|
float capture_buffer_load () const;
|
||||||
|
|
|
||||||
|
|
@ -1902,6 +1902,14 @@ AudioDiskstream::use_new_write_source (uint32_t n)
|
||||||
return 0;
|
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
|
void
|
||||||
AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
|
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;
|
total_capture += (*ci)->frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* figure out the name for this take */
|
if (_write_source->length (capture_info.front()->start) != 0) {
|
||||||
|
|
||||||
srcs.push_back (_write_source);
|
/* phew, we have data */
|
||||||
_write_source->set_timeline_position (capture_info.front()->start);
|
|
||||||
_write_source->set_captured_for (_name);
|
|
||||||
|
|
||||||
string whole_file_region_name;
|
/* figure out the name for this take */
|
||||||
whole_file_region_name = region_name_from_path (_write_source->name(), true);
|
|
||||||
|
|
||||||
/* Register a new region with the Session that
|
srcs.push_back (_write_source);
|
||||||
describes the entire source. Do this first
|
_write_source->set_timeline_position (capture_info.front()->start);
|
||||||
so that any sub-regions will obviously be
|
_write_source->set_captured_for (_name);
|
||||||
children of this one (later!)
|
|
||||||
*/
|
|
||||||
|
|
||||||
try {
|
string whole_file_region_name;
|
||||||
PropertyList plist;
|
whole_file_region_name = region_name_from_path (_write_source->name(), true);
|
||||||
|
|
||||||
plist.add (Properties::name, whole_file_region_name);
|
/* Register a new region with the Session that
|
||||||
plist.add (Properties::whole_file, true);
|
describes the entire source. Do this first
|
||||||
plist.add (Properties::automatic, true);
|
so that any sub-regions will obviously be
|
||||||
plist.add (Properties::start, 0);
|
children of this one (later!)
|
||||||
plist.add (Properties::length, total_capture);
|
*/
|
||||||
plist.add (Properties::layer, 0);
|
|
||||||
|
|
||||||
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
|
try {
|
||||||
|
PropertyList plist;
|
||||||
|
|
||||||
region = boost::dynamic_pointer_cast<MidiRegion> (rx);
|
plist.add (Properties::name, whole_file_region_name);
|
||||||
region->special_set_position (capture_info.front()->start);
|
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) {
|
catch (failed_constructor& err) {
|
||||||
error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
|
error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
|
||||||
/* XXX what now? */
|
/* 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->clear_history ();
|
||||||
_playlist->freeze ();
|
_playlist->freeze ();
|
||||||
|
|
||||||
uint32_t buffer_position = 0;
|
uint32_t buffer_position = 0;
|
||||||
for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
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 {
|
try {
|
||||||
PropertyList plist;
|
PropertyList plist;
|
||||||
|
|
||||||
plist.add (Properties::start, buffer_position);
|
plist.add (Properties::start, buffer_position);
|
||||||
plist.add (Properties::length, (*ci)->frames);
|
plist.add (Properties::length, (*ci)->frames);
|
||||||
plist.add (Properties::name, region_name);
|
plist.add (Properties::name, region_name);
|
||||||
|
|
||||||
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
|
boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
|
||||||
region = boost::dynamic_pointer_cast<MidiRegion> (rx);
|
region = boost::dynamic_pointer_cast<MidiRegion> (rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
|
error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
|
||||||
continue; /* XXX is this OK? */
|
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++;
|
i_am_the_modifier++;
|
||||||
_playlist->add_region (region, (*ci)->start);
|
_playlist->add_region (region, (*ci)->start);
|
||||||
i_am_the_modifier--;
|
i_am_the_modifier--;
|
||||||
|
|
||||||
buffer_position += (*ci)->frames;
|
buffer_position += (*ci)->frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
_playlist->thaw ();
|
|
||||||
_session.add_command (new StatefulDiffCommand(_playlist));
|
|
||||||
|
|
||||||
|
_playlist->thaw ();
|
||||||
|
_session.add_command (new StatefulDiffCommand(_playlist));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_write_completed = true;
|
mark_write_completed = true;
|
||||||
|
|
@ -1330,7 +1334,7 @@ MidiDiskstream::use_new_write_source (uint32_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
if (!_write_source) {
|
||||||
throw failed_constructor();
|
throw failed_constructor();
|
||||||
}
|
}
|
||||||
|
|
@ -1348,6 +1352,15 @@ MidiDiskstream::use_new_write_source (uint32_t n)
|
||||||
return 0;
|
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
|
void
|
||||||
MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
|
MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2948,8 +2948,24 @@ Session::new_midi_source_name (const string& base)
|
||||||
|
|
||||||
/** Create a new within-session MIDI source */
|
/** Create a new within-session MIDI source */
|
||||||
boost::shared_ptr<MidiSource>
|
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 name = new_midi_source_name (n);
|
||||||
const string path = new_source_path_from_name (DataType::MIDI, name);
|
const string path = new_source_path_from_name (DataType::MIDI, name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2333,6 +2333,8 @@ Session::commit_reversible_command(Command *cmd)
|
||||||
gettimeofday(&now, 0);
|
gettimeofday(&now, 0);
|
||||||
_current_trans.top()->set_timestamp(now);
|
_current_trans.top()->set_timestamp(now);
|
||||||
|
|
||||||
|
cerr << "add cmd @ " << _current_trans.top() << " to history\n";
|
||||||
|
|
||||||
_history.add(_current_trans.top());
|
_history.add(_current_trans.top());
|
||||||
_current_trans.pop();
|
_current_trans.pop();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,12 @@ Track::set_capture_offset ()
|
||||||
_diskstream->set_capture_offset ();
|
_diskstream->set_capture_offset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list<boost::shared_ptr<Source> >
|
||||||
|
Track::steal_write_sources()
|
||||||
|
{
|
||||||
|
return _diskstream->steal_write_sources ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Track::reset_write_sources (bool r, bool force)
|
Track::reset_write_sources (bool r, bool force)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
|
||||||
|
|
||||||
UndoTransaction::~UndoTransaction ()
|
UndoTransaction::~UndoTransaction ()
|
||||||
{
|
{
|
||||||
|
cerr << "UndoTransaction destroyed\n";
|
||||||
drop_references ();
|
drop_references ();
|
||||||
clear ();
|
clear ();
|
||||||
}
|
}
|
||||||
|
|
@ -54,6 +55,8 @@ UndoTransaction::~UndoTransaction ()
|
||||||
void
|
void
|
||||||
command_death (UndoTransaction* ut, Command* c)
|
command_death (UndoTransaction* ut, Command* c)
|
||||||
{
|
{
|
||||||
|
cerr << "Command drop ref\n";
|
||||||
|
|
||||||
if (ut->clearing()) {
|
if (ut->clearing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue